@azure/communication-react
Version:
React library for building modern communication user experiences utilizing Azure Communication Services
105 lines • 7.69 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { Spinner, SpinnerSize, Stack, Text, mergeStyles } from '@fluentui/react';
import { toFlatCommunicationIdentifier } from "../../../../../acs-ui-common/src";
import { ErrorBar } from "../../../../../react-components/src";
import { Announcer } from "../../../../../react-components/src";
import React, { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { useEffect } from 'react';
import { AvatarPersona } from '../../common/AvatarPersona';
import { useLocale } from '../../localization';
import { CallArrangement } from '../components/CallArrangement';
import { usePropsFor } from '../hooks/usePropsFor';
import { useSelector } from '../hooks/useSelector';
import { getRemoteParticipants } from '../selectors/baseSelectors';
import { getTransferCall } from '../selectors/baseSelectors';
import { avatarStyles, defaultPersonaStyles, displayNameStyles, pageContainer, spinnerStyles, statusTextStyles, tileContainerStyles, tileContentStyles } from '../styles/TransferPage.styles';
import { reduceCallControlsForMobile } from '../utils';
/**
* @private
*/
export const TransferPage = (props) => {
var _a, _b, _c, _d, _e, _f, _g;
const errorBarProps = usePropsFor(ErrorBar);
const strings = useLocale().strings.call;
const remoteParticipants = useSelector(getRemoteParticipants);
const transferCall = useSelector(getTransferCall);
const [announcerString, setAnnouncerString] = useState(undefined);
// Reduce the controls shown when mobile view is enabled.
const callControlOptions = props.mobileView ? reduceCallControlsForMobile((_a = props.options) === null || _a === void 0 ? void 0 : _a.callControls) : (_b = props.options) === null || _b === void 0 ? void 0 : _b.callControls;
const transferor = useMemo(() => { var _a; return remoteParticipants ? (_a = Object.values(remoteParticipants)) === null || _a === void 0 ? void 0 : _a[0] : undefined; }, [remoteParticipants]);
const transferTarget = useMemo(() => { var _a; return (transferCall === null || transferCall === void 0 ? void 0 : transferCall.remoteParticipants) ? (_a = Object.values(transferCall.remoteParticipants)) === null || _a === void 0 ? void 0 : _a[0] : undefined; }, [transferCall]);
const pageSubject = useMemo(() => {
if (transferCall && (transferTarget === null || transferTarget === void 0 ? void 0 : transferTarget.displayName)) {
return 'transferTarget';
}
return 'transferor';
}, [transferCall, transferTarget === null || transferTarget === void 0 ? void 0 : transferTarget.displayName]);
useEffect(() => {
setAnnouncerString(strings.transferPageNoticeString);
}, [strings.transferPageNoticeString]);
let transferTileParticipant = transferor;
if (pageSubject === 'transferTarget') {
transferTileParticipant = transferTarget;
}
let transferParticipantDisplayName = (_c = transferor === null || transferor === void 0 ? void 0 : transferor.displayName) !== null && _c !== void 0 ? _c : strings.transferPageUnknownTransferorDisplayName;
if (pageSubject === 'transferTarget') {
transferParticipantDisplayName = (_d = transferTarget === null || transferTarget === void 0 ? void 0 : transferTarget.displayName) !== null && _d !== void 0 ? _d : strings.transferPageUnknownTransferTargetDisplayName;
}
return React.createElement(Stack, { className: mergeStyles(pageContainer) },
React.createElement(Announcer, { announcementString: announcerString, ariaLive: "polite" }),
React.createElement(CallArrangement, { complianceBannerProps: {
strings
},
// Ignore errors from before current call. This avoids old errors from showing up when a user re-joins a call.
errorBarProps: ((_e = props.options) === null || _e === void 0 ? void 0 : _e.errorBar) !== false && errorBarProps, showErrorNotifications: (_g = (_f = props.options) === null || _f === void 0 ? void 0 : _f.errorBar) !== null && _g !== void 0 ? _g : true, callControlProps: {
options: callControlOptions,
increaseFlyoutItemSize: props.mobileView
}, mobileView: props.mobileView, modalLayerHostId: props.modalLayerHostId, onRenderGalleryContent: () => React.createElement(TransferTile, { userId: transferTileParticipant ? toFlatCommunicationIdentifier(transferTileParticipant === null || transferTileParticipant === void 0 ? void 0 : transferTileParticipant.identifier) : undefined, displayName: transferParticipantDisplayName, initialsName: transferParticipantDisplayName, statusText: pageSubject === 'transferTarget' ? strings.transferPageTransferTargetText : strings.transferPageTransferorText, onFetchAvatarPersonaData: props.onFetchAvatarPersonaData }), dataUiId: 'transfer-page', updateSidePaneRenderer: props.updateSidePaneRenderer, mobileChatTabHeader: props.mobileChatTabHeader, latestErrors: props.latestErrors, onDismissError: props.onDismissError, onDismissNotification: props.onDismissNotification, latestNotifications: props.latestNotifications }));
};
const TransferTile = (props) => {
const { displayName, initialsName, userId, onFetchAvatarPersonaData, statusText } = props;
const [personaSize, setPersonaSize] = useState();
const tileRef = useRef(null);
const observer = useRef(new ResizeObserver((entries) => {
if (!entries[0]) {
return;
}
const { width, height } = entries[0].contentRect;
const personaSize = Math.min(width, height) / 2;
setPersonaSize(Math.max(Math.min(personaSize, 150), 32));
}));
useLayoutEffect(() => {
if (tileRef.current) {
observer.current.observe(tileRef.current);
}
const currentObserver = observer.current;
return () => currentObserver.disconnect();
}, [observer, tileRef]);
const placeholderOptions = useMemo(() => ({
userId,
text: initialsName !== null && initialsName !== void 0 ? initialsName : displayName,
coinSize: personaSize,
styles: defaultPersonaStyles,
hidePersonaDetails: true
}), [userId, initialsName, displayName, personaSize]);
const defaultOnRenderAvatar = useCallback(() => {
return personaSize ? React.createElement(AvatarPersona, Object.assign({}, placeholderOptions, { dataProvider: onFetchAvatarPersonaData, className: mergeStyles(avatarStyles) })) : React.createElement(React.Fragment, null);
}, [placeholderOptions, onFetchAvatarPersonaData, personaSize]);
const defaultAvatar = useMemo(() => defaultOnRenderAvatar(), [defaultOnRenderAvatar]);
return React.createElement("div", { ref: tileRef, className: mergeStyles(tileContainerStyles), "data-is-focusable": true },
React.createElement(Stack, { className: mergeStyles(tileContentStyles), tokens: {
childrenGap: '1rem'
} },
React.createElement(Stack, { horizontalAlign: "center", tokens: {
childrenGap: '0.5rem'
} },
defaultAvatar,
React.createElement(Text, { className: mergeStyles(displayNameStyles) }, displayName)),
React.createElement(Stack, { horizontal: true, horizontalAlign: "center", verticalAlign: "center", tokens: {
childrenGap: '0.5rem'
} },
React.createElement(Spinner, { size: SpinnerSize.large, className: mergeStyles(spinnerStyles) }),
React.createElement(Text, { className: mergeStyles(statusTextStyles) }, statusText))));
};
//# sourceMappingURL=TransferPage.js.map