@azure/communication-react 1.23.0-alpha-202501110016 → 1.23.0-alpha-202501160016
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/communication-react.d.ts +82 -21
- package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-B8K83_JO.js → ChatMessageComponentAsRichTextEditBox-R5C_P0J9.js} +2 -2
- package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-B8K83_JO.js.map → ChatMessageComponentAsRichTextEditBox-R5C_P0J9.js.map} +1 -1
- package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-BfbHGYVY.js → RichTextSendBoxWrapper-D0KlP9qO.js} +2 -2
- package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-BfbHGYVY.js.map → RichTextSendBoxWrapper-D0KlP9qO.js.map} +1 -1
- package/dist/dist-cjs/communication-react/{index-C9oi1qJA.js → index-iq0jAnxX.js} +527 -34
- package/dist/dist-cjs/communication-react/index-iq0jAnxX.js.map +1 -0
- package/dist/dist-cjs/communication-react/index.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
- package/dist/dist-esm/communication-react/src/index.d.ts +1 -0
- package/dist/dist-esm/communication-react/src/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/CaptionsBanner.d.ts +44 -8
- package/dist/dist-esm/react-components/src/components/CaptionsBanner.js +42 -13
- package/dist/dist-esm/react-components/src/components/CaptionsBanner.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/MeetingReactionOverlay.d.ts +2 -0
- package/dist/dist-esm/react-components/src/components/MeetingReactionOverlay.js +12 -1
- package/dist/dist-esm/react-components/src/components/MeetingReactionOverlay.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RealTimeText.d.ts +3 -3
- package/dist/dist-esm/react-components/src/components/RealTimeText.js +2 -2
- package/dist/dist-esm/react-components/src/components/RealTimeText.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RealTimeTextModal.d.ts +5 -2
- package/dist/dist-esm/react-components/src/components/RealTimeTextModal.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/StartRealTimeTextButton.d.ts +3 -3
- package/dist/dist-esm/react-components/src/components/StartRealTimeTextButton.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/TogetherModeOverlay.d.ts +15 -0
- package/dist/dist-esm/react-components/src/components/TogetherModeOverlay.js +123 -0
- package/dist/dist-esm/react-components/src/components/TogetherModeOverlay.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/Layout.d.ts +5 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/Layout.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/TogetherModeLayout.d.ts +9 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/TogetherModeLayout.js +85 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/TogetherModeLayout.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/TogetherModeStream.d.ts +24 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/TogetherModeStream.js +53 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/TogetherModeStream.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery.d.ts +11 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery.js +61 -3
- package/dist/dist-esm/react-components/src/components/VideoGallery.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/TogetherMode.styles.d.ts +89 -0
- package/dist/dist-esm/react-components/src/components/styles/TogetherMode.styles.js +173 -0
- package/dist/dist-esm/react-components/src/components/styles/TogetherMode.styles.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/utils/sortCaptionsAndRealTimeTexts.d.ts +8 -0
- package/dist/dist-esm/react-components/src/components/utils/sortCaptionsAndRealTimeTexts.js +25 -0
- package/dist/dist-esm/react-components/src/components/utils/sortCaptionsAndRealTimeTexts.js.map +1 -0
- package/dist/dist-esm/react-components/src/types/ReactionTypes.d.ts +1 -1
- package/dist/dist-esm/react-components/src/types/ReactionTypes.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.d.ts +12 -0
- package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/localization/locales/en-US/strings.json +6 -0
- package/package.json +1 -1
- package/dist/dist-cjs/communication-react/index-C9oi1qJA.js.map +0 -1
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"RealTimeTextModal.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/RealTimeTextModal.tsx"],"names":[],"mappings":";;;;;;;;;AAAA,uCAAuC;AACvC,kCAAkC;AAClC,sCAAsC;AACtC,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAC3C,sCAAsC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,sCAAsC;AACtC,OAAO,EAAgB,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGvH,sCAAsC;AACtC,OAAO,EACL,yBAAyB,EACzB,YAAY,EACZ,gCAAgC,EAChC,cAAc,EACd,uBAAuB,EACxB,MAAM,uCAAuC,CAAC;AAC/C,sCAAsC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
1
|
+
{"version":3,"file":"RealTimeTextModal.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/RealTimeTextModal.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n/* @conditional-compile-remove(rtt) */\nimport React, { useCallback } from 'react';\n/* @conditional-compile-remove(rtt) */\nimport { useMemo } from 'react';\n/* @conditional-compile-remove(rtt) */\nimport { IModalStyles, Modal, Stack, useTheme, Text, IconButton, DefaultButton, PrimaryButton } from '@fluentui/react';\n/* @conditional-compile-remove(rtt) */\nimport { _preventDismissOnEvent } from '@internal/acs-ui-common';\n/* @conditional-compile-remove(rtt) */\nimport {\n buttonsContainerClassName,\n buttonStyles,\n themedCaptionsSettingsModalStyle,\n titleClassName,\n titleContainerClassName\n} from './styles/CaptionsSettingsModal.styles';\n/* @conditional-compile-remove(rtt) */\nimport { useLocale } from '../localization';\n\n/* @conditional-compile-remove(rtt) */\n/**\n * @beta\n * strings for realTimeText modal\n */\nexport interface RealTimeTextModalStrings {\n /** The title of the RealTimeText modal */\n realTimeTextModalTitle?: string;\n /** The text of the RealTimeText modal */\n realTimeTextModalText?: string;\n /** The label for the confirm button */\n realTimeTextConfirmButtonLabel?: string;\n /** The label for the cancel button */\n realTimeTextCancelButtonLabel?: string;\n /** The aria label for the modal */\n realTimeTextModalAriaLabel?: string;\n /** The aria label for the close button */\n realTimeTextCloseModalButtonAriaLabel?: string;\n}\n/* @conditional-compile-remove(rtt) */\n/**\n * @beta\n * RealTimeTextModal Component Props.\n */\nexport interface RealTimeTextModalProps {\n /** The strings for the RealTimeText modal */\n strings?: RealTimeTextModalStrings;\n /** The flag to show the modal */\n showModal?: boolean;\n /** The function to dismiss the modal */\n onDismissModal?: () => void;\n /**\n * Use this function to show RealTimeText UI in the calling experience.\n * Note that real time text should not be started for everyone in the call until the first real time text is received.\n */\n onStartRealTimeText?: () => void;\n}\n/* @conditional-compile-remove(rtt) */\n/**\n * @beta\n * a component for realTimeText modal\n */\nexport const RealTimeTextModal = (props: RealTimeTextModalProps): JSX.Element => {\n const { showModal, onDismissModal, onStartRealTimeText } = props;\n const localeStrings = useLocale().strings.realTimeTextModal;\n const strings = { ...localeStrings, ...props.strings };\n\n const theme = useTheme();\n\n const onDismiss = useCallback((): void => {\n if (onDismissModal) {\n onDismissModal();\n }\n }, [onDismissModal]);\n\n const onConfirm = useCallback(async (): Promise<void> => {\n if (onStartRealTimeText) {\n await onStartRealTimeText();\n }\n onDismiss();\n }, [onDismiss, onStartRealTimeText]);\n\n const RealTimeTextModalStyle: Partial<IModalStyles> = useMemo(() => themedCaptionsSettingsModalStyle(theme), [theme]);\n\n return (\n <>\n {\n <Modal\n titleAriaId={strings?.realTimeTextModalAriaLabel}\n isOpen={showModal}\n onDismiss={onDismiss}\n isBlocking={true}\n styles={RealTimeTextModalStyle}\n >\n <Stack horizontal horizontalAlign=\"space-between\" verticalAlign=\"center\" className={titleContainerClassName}>\n <Text className={titleClassName}>{strings?.realTimeTextModalTitle}</Text>\n <IconButton\n iconProps={{ iconName: 'Cancel' }}\n ariaLabel={strings?.realTimeTextCloseModalButtonAriaLabel}\n onClick={onDismiss}\n style={{ color: theme.palette.black }}\n />\n </Stack>\n <Text>{strings?.realTimeTextModalText}</Text>\n\n <Stack horizontal horizontalAlign=\"end\" className={buttonsContainerClassName}>\n <PrimaryButton styles={buttonStyles(theme)} onClick={onConfirm}>\n <span>{strings?.realTimeTextConfirmButtonLabel}</span>\n </PrimaryButton>\n <DefaultButton onClick={onDismiss} styles={buttonStyles(theme)}>\n <span>{strings?.realTimeTextCancelButtonLabel}</span>\n </DefaultButton>\n </Stack>\n </Modal>\n }\n </>\n );\n};\n"]}
|
@@ -6,10 +6,10 @@ import { ControlBarButtonProps } from './ControlBarButton';
|
|
6
6
|
*/
|
7
7
|
export interface StartRealTimeTextButtonProps extends ControlBarButtonProps {
|
8
8
|
/**
|
9
|
-
*
|
10
|
-
*
|
9
|
+
* Use this function to show RealTimeText UI in the calling experience.
|
10
|
+
* Note that real time text should not be started for everyone in the call until the first real time text is received.
|
11
11
|
*/
|
12
|
-
onStartRealTimeText: () =>
|
12
|
+
onStartRealTimeText: () => void;
|
13
13
|
/**
|
14
14
|
* If RealTimeText is on
|
15
15
|
*/
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"StartRealTimeTextButton.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/StartRealTimeTextButton.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;
|
1
|
+
{"version":3,"file":"StartRealTimeTextButton.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/StartRealTimeTextButton.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,sCAAsC;AACtC,OAAO,EAAE,gBAAgB,EAAyB,MAAM,oBAAoB,CAAC;AAC7E,sCAAsC;AACtC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,sCAAsC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjE,sCAAsC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAuC5C,sCAAsC;AACtC;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,KAAmC,EAAe,EAAE;IAC1F,MAAM,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC;IACxD,MAAM,aAAa,GAAG,SAAS,EAAE,CAAC,OAAO,CAAC,uBAAuB,CAAC;IAClE,MAAM,OAAO,mCAAQ,aAAa,GAAK,KAAK,CAAC,OAAO,CAAE,CAAC;IACvD,MAAM,iBAAiB,GAAG,GAAgB,EAAE;QAC1C,OAAO,oBAAC,sBAAsB,IAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,QAAQ,EAAC,kBAAkB,GAAG,CAAC;IAC1F,CAAC,CAAC;IAEF,OAAO,CACL,oBAAC,gBAAgB,oBACX,KAAK,IACT,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,mBAAmB,EAC5B,eAAe,EAAE,iBAAiB,EAClC,QAAQ,EAAE,gBAAgB,IAC1B,CACH,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/* @conditional-compile-remove(rtt) */\nimport { ControlBarButton, ControlBarButtonProps } from './ControlBarButton';\n/* @conditional-compile-remove(rtt) */\nimport React from 'react';\n/* @conditional-compile-remove(rtt) */\nimport { _HighContrastAwareIcon } from './HighContrastAwareIcon';\n/* @conditional-compile-remove(rtt) */\nimport { useLocale } from '../localization';\n\n/* @conditional-compile-remove(rtt) */\n/**\n * Props for the StartRealTimeTextButton component\n * @beta\n */\nexport interface StartRealTimeTextButtonProps extends ControlBarButtonProps {\n /**\n * Use this function to show RealTimeText UI in the calling experience.\n * Note that real time text should not be started for everyone in the call until the first real time text is received.\n */\n onStartRealTimeText: () => void;\n /**\n * If RealTimeText is on\n */\n isRealTimeTextOn: boolean;\n /**\n * Optional strings to override in component\n */\n strings?: StartRealTimeTextButtonStrings;\n}\n\n/* @conditional-compile-remove(rtt) */\n/**\n * Strings for the hold button labels\n * @beta\n */\nexport interface StartRealTimeTextButtonStrings {\n /**\n * Label for when action is to start RealTimeText\n */\n onLabel: string;\n /**\n * Content for when button is checked, RealTimeText is on\n */\n tooltipOnContent: string;\n}\n\n/* @conditional-compile-remove(rtt) */\n/**\n * a button to start RealTimeText\n * based on accessibility requirement, real time text cannot be turned off once it is on\n *\n * Can be used with {@link ControlBar}\n *\n * @param props - properties for the start RealTimeText button.\n * @beta\n */\nexport const StartRealTimeTextButton = (props: StartRealTimeTextButtonProps): JSX.Element => {\n const { onStartRealTimeText, isRealTimeTextOn } = props;\n const localeStrings = useLocale().strings.startRealTimeTextButton;\n const strings = { ...localeStrings, ...props.strings };\n const onRenderStartIcon = (): JSX.Element => {\n return <_HighContrastAwareIcon disabled={props.disabled} iconName=\"RealTimeTextIcon\" />;\n };\n\n return (\n <ControlBarButton\n {...props}\n strings={strings}\n onClick={onStartRealTimeText}\n onRenderOffIcon={onRenderStartIcon}\n disabled={isRealTimeTextOn}\n />\n );\n};\n\nexport {};\n"]}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { ReactionResources, VideoGalleryTogetherModeParticipantPosition, VideoGalleryLocalParticipant, VideoGalleryRemoteParticipant } from '../types';
|
3
|
+
/**
|
4
|
+
* TogetherModeOverlay component renders an empty JSX element.
|
5
|
+
*
|
6
|
+
* @returns {JSX.Element} An empty JSX element.
|
7
|
+
*/
|
8
|
+
export declare const TogetherModeOverlay: React.MemoExoticComponent<(props: {
|
9
|
+
emojiSize: number;
|
10
|
+
reactionResources: ReactionResources;
|
11
|
+
localParticipant: VideoGalleryLocalParticipant;
|
12
|
+
remoteParticipants: VideoGalleryRemoteParticipant[];
|
13
|
+
togetherModeSeatPositions: VideoGalleryTogetherModeParticipantPosition;
|
14
|
+
}) => React.JSX.Element>;
|
15
|
+
//# sourceMappingURL=TogetherModeOverlay.d.ts.map
|
@@ -0,0 +1,123 @@
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
2
|
+
// Licensed under the MIT License.
|
3
|
+
/* @conditional-compile-remove(together-mode) */
|
4
|
+
import React, { useMemo, useState, memo } from 'react';
|
5
|
+
/* @conditional-compile-remove(together-mode) */
|
6
|
+
import { moveAnimationStyles, spriteAnimationStyles } from './styles/ReactionOverlay.style';
|
7
|
+
/* @conditional-compile-remove(together-mode) */
|
8
|
+
import { REACTION_NUMBER_OF_ANIMATION_FRAMES } from './VideoGallery/utils/reactionUtils';
|
9
|
+
/* @conditional-compile-remove(together-mode) */
|
10
|
+
import { Icon, mergeStyles, Stack, Text } from '@fluentui/react';
|
11
|
+
/* @conditional-compile-remove(together-mode) */
|
12
|
+
import { getEmojiResource } from './VideoGallery/utils/videoGalleryLayoutUtils';
|
13
|
+
/* @conditional-compile-remove(together-mode) */
|
14
|
+
import { useLocale } from '../localization';
|
15
|
+
/* @conditional-compile-remove(together-mode) */
|
16
|
+
import { calculateScaledSize, getTogetherModeParticipantOverlayStyle, REACTION_MAX_TRAVEL_HEIGHT, REACTION_TRAVEL_HEIGHT, setTogetherModeSeatPositionStyle, togetherModeIconStyle, togetherModeParticipantDisplayName, togetherModeParticipantEmojiSpriteStyle, togetherModeParticipantStatusContainer } from './styles/TogetherMode.styles';
|
17
|
+
/* @conditional-compile-remove(together-mode) */
|
18
|
+
import { useTheme } from '../theming';
|
19
|
+
/* @conditional-compile-remove(together-mode) */
|
20
|
+
import { RaisedHandIcon } from './assets/RaisedHandIcon';
|
21
|
+
/* @conditional-compile-remove(together-mode) */
|
22
|
+
/**
|
23
|
+
* TogetherModeOverlay component renders an empty JSX element.
|
24
|
+
*
|
25
|
+
* @returns {JSX.Element} An empty JSX element.
|
26
|
+
*/
|
27
|
+
export const TogetherModeOverlay = memo((props) => {
|
28
|
+
const locale = useLocale();
|
29
|
+
const theme = useTheme();
|
30
|
+
const callingPalette = theme.callingPalette;
|
31
|
+
const { emojiSize, reactionResources, remoteParticipants, localParticipant, togetherModeSeatPositions } = props;
|
32
|
+
const [togetherModeParticipantStatus, setTogetherModeParticipantStatus] = useState({});
|
33
|
+
const [hoveredParticipantID, setHoveredParticipantID] = useState('');
|
34
|
+
/*
|
35
|
+
* The useMemo hook is used to calculate the participant status for the Together Mode overlay.
|
36
|
+
* It updates the togetherModeParticipantStatus state when there's a change in the remoteParticipants, localParticipant,
|
37
|
+
* raisedHand, spotlight, isMuted, displayName, or hoveredParticipantID.
|
38
|
+
*/
|
39
|
+
useMemo(() => {
|
40
|
+
const allParticipants = [...remoteParticipants, localParticipant];
|
41
|
+
const participantsWithVideoAvailable = allParticipants.filter((p) => { var _a; return ((_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable) && togetherModeSeatPositions[p.userId]; });
|
42
|
+
const updatedSignals = {};
|
43
|
+
for (const p of participantsWithVideoAvailable) {
|
44
|
+
const { userId, reaction, raisedHand, spotlight, isMuted, displayName } = p;
|
45
|
+
const seatingPosition = togetherModeSeatPositions[userId];
|
46
|
+
if (seatingPosition) {
|
47
|
+
updatedSignals[userId] = {
|
48
|
+
id: userId,
|
49
|
+
reaction: reactionResources && reaction,
|
50
|
+
isHandRaised: !!raisedHand,
|
51
|
+
isSpotlighted: !!spotlight,
|
52
|
+
isMuted,
|
53
|
+
displayName: displayName || locale.strings.videoGallery.displayNamePlaceholder,
|
54
|
+
showDisplayName: !!(spotlight || raisedHand || hoveredParticipantID === userId),
|
55
|
+
scaledSize: calculateScaledSize(seatingPosition.width, seatingPosition.height),
|
56
|
+
seatPositionStyle: setTogetherModeSeatPositionStyle(seatingPosition)
|
57
|
+
};
|
58
|
+
}
|
59
|
+
}
|
60
|
+
// This is used to remove the participants bounding box from the DOM when they are no longer in the stream
|
61
|
+
const participantsNotInTogetherModeStream = Object.keys(togetherModeParticipantStatus).filter((id) => !updatedSignals[id]);
|
62
|
+
setTogetherModeParticipantStatus((prevSignals) => {
|
63
|
+
const newSignals = Object.assign(Object.assign({}, prevSignals), updatedSignals);
|
64
|
+
const newSignalsLength = Object.keys(newSignals).length;
|
65
|
+
participantsNotInTogetherModeStream.forEach((id) => {
|
66
|
+
delete newSignals[id];
|
67
|
+
});
|
68
|
+
const hasChanges = Object.keys(newSignals).some((key) => JSON.stringify(newSignals[key]) !== JSON.stringify(prevSignals[key]) ||
|
69
|
+
newSignalsLength !== Object.keys(prevSignals).length);
|
70
|
+
return hasChanges ? newSignals : prevSignals;
|
71
|
+
});
|
72
|
+
}, [
|
73
|
+
remoteParticipants,
|
74
|
+
localParticipant,
|
75
|
+
togetherModeParticipantStatus,
|
76
|
+
togetherModeSeatPositions,
|
77
|
+
reactionResources,
|
78
|
+
locale.strings.videoGallery.displayNamePlaceholder,
|
79
|
+
hoveredParticipantID
|
80
|
+
]);
|
81
|
+
/*
|
82
|
+
* When a larger participant scene switches to a smaller group in Together Mode,
|
83
|
+
* participant video streams remain available because their video is still active,
|
84
|
+
* even though they are not visible in the Together Mode stream.
|
85
|
+
* Therefore, we rely on the updated seating position values to identify who is included in the Together Mode stream.
|
86
|
+
* The Together mode seat position will only contain seat coordinates of participants who are visible in the Together Mode stream.
|
87
|
+
*/
|
88
|
+
useMemo(() => {
|
89
|
+
const removedVisibleParticipants = Object.keys(togetherModeParticipantStatus).filter((participantId) => !togetherModeSeatPositions[participantId]);
|
90
|
+
setTogetherModeParticipantStatus((prevSignals) => {
|
91
|
+
const newSignals = Object.assign({}, prevSignals);
|
92
|
+
removedVisibleParticipants.forEach((participantId) => {
|
93
|
+
delete newSignals[participantId];
|
94
|
+
});
|
95
|
+
// Trigger a re-render only if changes occurred
|
96
|
+
const hasChanges = Object.keys(newSignals).length !== Object.keys(prevSignals).length;
|
97
|
+
return hasChanges ? newSignals : prevSignals;
|
98
|
+
});
|
99
|
+
}, [togetherModeParticipantStatus, togetherModeSeatPositions]);
|
100
|
+
return (React.createElement("div", { style: { position: 'absolute', width: '100%', height: '100%' } }, Object.values(togetherModeParticipantStatus).map((participantStatus) => {
|
101
|
+
var _a, _b;
|
102
|
+
return participantStatus.id && (React.createElement("div", { key: participantStatus.id, style: Object.assign({}, getTogetherModeParticipantOverlayStyle(participantStatus.seatPositionStyle)), onMouseEnter: () => setHoveredParticipantID(participantStatus.id), onMouseLeave: () => setHoveredParticipantID('') },
|
103
|
+
React.createElement("div", null,
|
104
|
+
((_a = participantStatus.reaction) === null || _a === void 0 ? void 0 : _a.reactionType) && (
|
105
|
+
// First div - Section that fixes the travel height and applies the movement animation
|
106
|
+
// Second div - Responsible for ensuring the sprite emoji is always centered in the participant seat position
|
107
|
+
// Third div - Play Animation as the other animation applies on the base play animation for the sprite
|
108
|
+
React.createElement("div", { style: moveAnimationStyles(parseFloat(participantStatus.seatPositionStyle.seatPosition.height) *
|
109
|
+
REACTION_MAX_TRAVEL_HEIGHT, parseFloat(participantStatus.seatPositionStyle.seatPosition.height) * REACTION_TRAVEL_HEIGHT) },
|
110
|
+
React.createElement("div", { style: Object.assign({}, togetherModeParticipantEmojiSpriteStyle(emojiSize, participantStatus.scaledSize || 1, participantStatus.seatPositionStyle.seatPosition.width)) },
|
111
|
+
React.createElement("div", { style: spriteAnimationStyles(REACTION_NUMBER_OF_ANIMATION_FRAMES, participantStatus.scaledSize || 1, (_b = (participantStatus.reaction &&
|
112
|
+
getEmojiResource(participantStatus === null || participantStatus === void 0 ? void 0 : participantStatus.reaction.reactionType, reactionResources))) !== null && _b !== void 0 ? _b : '') })))),
|
113
|
+
participantStatus.showDisplayName && (React.createElement("div", null,
|
114
|
+
React.createElement("div", { style: Object.assign({}, togetherModeParticipantStatusContainer(callingPalette.videoTileLabelBackgroundLight, theme.effects.roundedCorner4)) },
|
115
|
+
participantStatus.isHandRaised && React.createElement(RaisedHandIcon, null),
|
116
|
+
participantStatus.showDisplayName && (React.createElement(Text, { style: Object.assign({}, togetherModeParticipantDisplayName(hoveredParticipantID === participantStatus.id, parseFloat(participantStatus.seatPositionStyle.seatPosition.width), participantStatus.displayName ? theme.palette.neutralSecondary : 'inherit')) }, participantStatus.displayName)),
|
117
|
+
participantStatus.isMuted && (React.createElement(Stack, { className: mergeStyles(togetherModeIconStyle) },
|
118
|
+
React.createElement(Icon, { iconName: "VideoTileMicOff" }))),
|
119
|
+
participantStatus.isSpotlighted && (React.createElement(Stack, { className: mergeStyles(togetherModeIconStyle) },
|
120
|
+
React.createElement(Icon, { iconName: "VideoTileSpotlighted" })))))))));
|
121
|
+
})));
|
122
|
+
});
|
123
|
+
//# sourceMappingURL=TogetherModeOverlay.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"TogetherModeOverlay.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/TogetherModeOverlay.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/* @conditional-compile-remove(together-mode) */\nimport React, { useMemo, useState, memo } from 'react';\n/* @conditional-compile-remove(together-mode) */\nimport {\n Reaction,\n ReactionResources,\n VideoGalleryTogetherModeParticipantPosition,\n VideoGalleryLocalParticipant,\n VideoGalleryRemoteParticipant\n} from '../types';\n/* @conditional-compile-remove(together-mode) */\nimport { moveAnimationStyles, spriteAnimationStyles } from './styles/ReactionOverlay.style';\n/* @conditional-compile-remove(together-mode) */\nimport { REACTION_NUMBER_OF_ANIMATION_FRAMES } from './VideoGallery/utils/reactionUtils';\n/* @conditional-compile-remove(together-mode) */\nimport { Icon, mergeStyles, Stack, Text } from '@fluentui/react';\n/* @conditional-compile-remove(together-mode) */\nimport { getEmojiResource } from './VideoGallery/utils/videoGalleryLayoutUtils';\n/* @conditional-compile-remove(together-mode) */\nimport { useLocale } from '../localization';\n/* @conditional-compile-remove(together-mode) */\nimport { _HighContrastAwareIcon } from './HighContrastAwareIcon';\n/* @conditional-compile-remove(together-mode) */\nimport {\n calculateScaledSize,\n getTogetherModeParticipantOverlayStyle,\n REACTION_MAX_TRAVEL_HEIGHT,\n REACTION_TRAVEL_HEIGHT,\n setTogetherModeSeatPositionStyle,\n togetherModeIconStyle,\n togetherModeParticipantDisplayName,\n togetherModeParticipantEmojiSpriteStyle,\n togetherModeParticipantStatusContainer,\n TogetherModeSeatStyle\n} from './styles/TogetherMode.styles';\n/* @conditional-compile-remove(together-mode) */\nimport { CallingTheme, useTheme } from '../theming';\n/* @conditional-compile-remove(together-mode) */\nimport { RaisedHandIcon } from './assets/RaisedHandIcon';\n/* @conditional-compile-remove(together-mode) */\nimport { _pxToRem } from '@internal/acs-ui-common';\n\n/* @conditional-compile-remove(together-mode) */\n/**\n * Signaling action overlay component props\n * @internal\n */\ntype TogetherModeParticipantStatus = {\n reaction?: Reaction;\n scaledSize?: number;\n isHandRaised?: boolean;\n isSpotlighted?: boolean;\n isMuted?: boolean;\n id: string;\n seatPositionStyle: TogetherModeSeatStyle;\n displayName: string;\n showDisplayName: boolean;\n};\n\n/* @conditional-compile-remove(together-mode) */\n/**\n * TogetherModeOverlay component renders an empty JSX element.\n *\n * @returns {JSX.Element} An empty JSX element.\n */\nexport const TogetherModeOverlay = memo(\n (props: {\n emojiSize: number;\n reactionResources: ReactionResources;\n localParticipant: VideoGalleryLocalParticipant;\n remoteParticipants: VideoGalleryRemoteParticipant[];\n togetherModeSeatPositions: VideoGalleryTogetherModeParticipantPosition;\n }) => {\n const locale = useLocale();\n const theme = useTheme();\n const callingPalette = (theme as unknown as CallingTheme).callingPalette;\n\n const { emojiSize, reactionResources, remoteParticipants, localParticipant, togetherModeSeatPositions } = props;\n const [togetherModeParticipantStatus, setTogetherModeParticipantStatus] = useState<{\n [key: string]: TogetherModeParticipantStatus;\n }>({});\n const [hoveredParticipantID, setHoveredParticipantID] = useState('');\n\n /*\n * The useMemo hook is used to calculate the participant status for the Together Mode overlay.\n * It updates the togetherModeParticipantStatus state when there's a change in the remoteParticipants, localParticipant,\n * raisedHand, spotlight, isMuted, displayName, or hoveredParticipantID.\n */\n useMemo(() => {\n const allParticipants = [...remoteParticipants, localParticipant];\n\n const participantsWithVideoAvailable = allParticipants.filter(\n (p) => p.videoStream?.isAvailable && togetherModeSeatPositions[p.userId]\n );\n\n const updatedSignals: { [key: string]: TogetherModeParticipantStatus } = {};\n for (const p of participantsWithVideoAvailable) {\n const { userId, reaction, raisedHand, spotlight, isMuted, displayName } = p;\n const seatingPosition = togetherModeSeatPositions[userId];\n if (seatingPosition) {\n updatedSignals[userId] = {\n id: userId,\n reaction: reactionResources && reaction,\n isHandRaised: !!raisedHand,\n isSpotlighted: !!spotlight,\n isMuted,\n displayName: displayName || locale.strings.videoGallery.displayNamePlaceholder,\n showDisplayName: !!(spotlight || raisedHand || hoveredParticipantID === userId),\n scaledSize: calculateScaledSize(seatingPosition.width, seatingPosition.height),\n seatPositionStyle: setTogetherModeSeatPositionStyle(seatingPosition)\n };\n }\n }\n\n // This is used to remove the participants bounding box from the DOM when they are no longer in the stream\n const participantsNotInTogetherModeStream = Object.keys(togetherModeParticipantStatus).filter(\n (id) => !updatedSignals[id]\n );\n\n setTogetherModeParticipantStatus((prevSignals) => {\n const newSignals = { ...prevSignals, ...updatedSignals };\n const newSignalsLength = Object.keys(newSignals).length;\n\n participantsNotInTogetherModeStream.forEach((id) => {\n delete newSignals[id];\n });\n\n const hasChanges = Object.keys(newSignals).some(\n (key) =>\n JSON.stringify(newSignals[key]) !== JSON.stringify(prevSignals[key]) ||\n newSignalsLength !== Object.keys(prevSignals).length\n );\n\n return hasChanges ? newSignals : prevSignals;\n });\n }, [\n remoteParticipants,\n localParticipant,\n togetherModeParticipantStatus,\n togetherModeSeatPositions,\n reactionResources,\n locale.strings.videoGallery.displayNamePlaceholder,\n hoveredParticipantID\n ]);\n\n /*\n * When a larger participant scene switches to a smaller group in Together Mode,\n * participant video streams remain available because their video is still active,\n * even though they are not visible in the Together Mode stream.\n * Therefore, we rely on the updated seating position values to identify who is included in the Together Mode stream.\n * The Together mode seat position will only contain seat coordinates of participants who are visible in the Together Mode stream.\n */\n useMemo(() => {\n const removedVisibleParticipants = Object.keys(togetherModeParticipantStatus).filter(\n (participantId) => !togetherModeSeatPositions[participantId]\n );\n\n setTogetherModeParticipantStatus((prevSignals) => {\n const newSignals = { ...prevSignals };\n removedVisibleParticipants.forEach((participantId) => {\n delete newSignals[participantId];\n });\n\n // Trigger a re-render only if changes occurred\n const hasChanges = Object.keys(newSignals).length !== Object.keys(prevSignals).length;\n return hasChanges ? newSignals : prevSignals;\n });\n }, [togetherModeParticipantStatus, togetherModeSeatPositions]);\n\n return (\n <div style={{ position: 'absolute', width: '100%', height: '100%' }}>\n {Object.values(togetherModeParticipantStatus).map(\n (participantStatus) =>\n participantStatus.id && (\n <div\n key={participantStatus.id}\n style={{\n ...getTogetherModeParticipantOverlayStyle(participantStatus.seatPositionStyle)\n }}\n onMouseEnter={() => setHoveredParticipantID(participantStatus.id)}\n onMouseLeave={() => setHoveredParticipantID('')}\n >\n <div>\n {participantStatus.reaction?.reactionType && (\n // First div - Section that fixes the travel height and applies the movement animation\n // Second div - Responsible for ensuring the sprite emoji is always centered in the participant seat position\n // Third div - Play Animation as the other animation applies on the base play animation for the sprite\n <div\n style={moveAnimationStyles(\n parseFloat(participantStatus.seatPositionStyle.seatPosition.height) *\n REACTION_MAX_TRAVEL_HEIGHT,\n parseFloat(participantStatus.seatPositionStyle.seatPosition.height) * REACTION_TRAVEL_HEIGHT\n )}\n >\n <div\n style={{\n ...togetherModeParticipantEmojiSpriteStyle(\n emojiSize,\n participantStatus.scaledSize || 1,\n participantStatus.seatPositionStyle.seatPosition.width\n )\n }}\n >\n <div\n style={spriteAnimationStyles(\n REACTION_NUMBER_OF_ANIMATION_FRAMES,\n participantStatus.scaledSize || 1,\n (participantStatus.reaction &&\n getEmojiResource(participantStatus?.reaction.reactionType, reactionResources)) ??\n ''\n )}\n />\n </div>\n </div>\n )}\n\n {participantStatus.showDisplayName && (\n <div>\n <div\n style={{\n ...togetherModeParticipantStatusContainer(\n callingPalette.videoTileLabelBackgroundLight,\n theme.effects.roundedCorner4\n )\n }}\n >\n {participantStatus.isHandRaised && <RaisedHandIcon />}\n {participantStatus.showDisplayName && (\n <Text\n style={{\n ...togetherModeParticipantDisplayName(\n hoveredParticipantID === participantStatus.id,\n parseFloat(participantStatus.seatPositionStyle.seatPosition.width),\n participantStatus.displayName ? theme.palette.neutralSecondary : 'inherit'\n )\n }}\n >\n {participantStatus.displayName}\n </Text>\n )}\n {participantStatus.isMuted && (\n <Stack className={mergeStyles(togetherModeIconStyle)}>\n <Icon iconName=\"VideoTileMicOff\" />\n </Stack>\n )}\n {participantStatus.isSpotlighted && (\n <Stack className={mergeStyles(togetherModeIconStyle)}>\n <Icon iconName=\"VideoTileSpotlighted\" />\n </Stack>\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n )\n )}\n </div>\n );\n }\n);\n"]}
|
@@ -50,5 +50,10 @@ export interface LayoutProps {
|
|
50
50
|
* List of spotlighted participant userIds
|
51
51
|
*/
|
52
52
|
spotlightedParticipantUserIds?: string[];
|
53
|
+
/**
|
54
|
+
* Props for a layout component
|
55
|
+
*
|
56
|
+
*/
|
57
|
+
togetherModeStreamComponent?: JSX.Element;
|
53
58
|
}
|
54
59
|
//# sourceMappingURL=Layout.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"Layout.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/VideoGallery/Layout.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { VideoGalleryParticipant, VideoGalleryRemoteParticipant } from '../../types';\nimport { VideoGalleryStyles } from '../VideoGallery';\nimport { OverflowGalleryPosition } from '../VideoGallery';\n\n/**\n * Props for a layout component\n *\n * @private\n */\nexport interface LayoutProps {\n /**\n * Styles for the {@link DefaultLayout}\n */\n styles?: Omit<VideoGalleryStyles, 'root'>;\n /** List of remote video particpants */\n remoteParticipants?: VideoGalleryRemoteParticipant[];\n /** Local participant information */\n localParticipant?: VideoGalleryParticipant;\n /** Callback to render each remote participant */\n onRenderRemoteParticipant: (participant: VideoGalleryRemoteParticipant, isVideoParticipant?: boolean) => JSX.Element;\n /** List of dominant speaker userIds in the order of their dominance. 0th index is the most dominant. */\n dominantSpeakers?: string[];\n /** Component that contains local video content */\n localVideoComponent?: JSX.Element;\n /** Component that contains screen share content */\n screenShareComponent?: JSX.Element;\n /**\n * Maximum number of participant remote video streams that is rendered.\n * @defaultValue 4\n */\n maxRemoteVideoStreams: number;\n /**\n * Width of parent element\n */\n parentWidth?: number;\n /**\n * Height of parent element\n */\n parentHeight?: number;\n /**\n * List of pinned participant userIds\n */\n pinnedParticipantUserIds?: string[];\n /**\n * Determines the layout of the overflowGallery.\n * @defaultValue 'horizontalBottom'\n */\n overflowGalleryPosition?: OverflowGalleryPosition;\n /**\n * List of spotlighted participant userIds\n */\n spotlightedParticipantUserIds?: string[];\n}\n"]}
|
1
|
+
{"version":3,"file":"Layout.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/VideoGallery/Layout.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { VideoGalleryParticipant, VideoGalleryRemoteParticipant } from '../../types';\nimport { VideoGalleryStyles } from '../VideoGallery';\nimport { OverflowGalleryPosition } from '../VideoGallery';\n\n/**\n * Props for a layout component\n *\n * @private\n */\nexport interface LayoutProps {\n /**\n * Styles for the {@link DefaultLayout}\n */\n styles?: Omit<VideoGalleryStyles, 'root'>;\n /** List of remote video particpants */\n remoteParticipants?: VideoGalleryRemoteParticipant[];\n /** Local participant information */\n localParticipant?: VideoGalleryParticipant;\n /** Callback to render each remote participant */\n onRenderRemoteParticipant: (participant: VideoGalleryRemoteParticipant, isVideoParticipant?: boolean) => JSX.Element;\n /** List of dominant speaker userIds in the order of their dominance. 0th index is the most dominant. */\n dominantSpeakers?: string[];\n /** Component that contains local video content */\n localVideoComponent?: JSX.Element;\n /** Component that contains screen share content */\n screenShareComponent?: JSX.Element;\n /**\n * Maximum number of participant remote video streams that is rendered.\n * @defaultValue 4\n */\n maxRemoteVideoStreams: number;\n /**\n * Width of parent element\n */\n parentWidth?: number;\n /**\n * Height of parent element\n */\n parentHeight?: number;\n /**\n * List of pinned participant userIds\n */\n pinnedParticipantUserIds?: string[];\n /**\n * Determines the layout of the overflowGallery.\n * @defaultValue 'horizontalBottom'\n */\n overflowGalleryPosition?: OverflowGalleryPosition;\n /**\n * List of spotlighted participant userIds\n */\n spotlightedParticipantUserIds?: string[];\n /* @conditional-compile-remove(together-mode) */\n /**\n * Props for a layout component\n *\n */\n togetherModeStreamComponent?: JSX.Element;\n}\n"]}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/// <reference types="react" />
|
2
|
+
import { LayoutProps } from './Layout';
|
3
|
+
/**
|
4
|
+
* A memoized version of local screen share component. React.memo is used for a performance
|
5
|
+
* boost by memoizing the same rendered component to avoid rerendering this when the parent component rerenders.
|
6
|
+
* https://reactjs.org/docs/react-api.html#reactmemo
|
7
|
+
*/
|
8
|
+
export declare const TogetherModeLayout: (props: LayoutProps) => JSX.Element;
|
9
|
+
//# sourceMappingURL=TogetherModeLayout.d.ts.map
|
@@ -0,0 +1,85 @@
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
2
|
+
// Licensed under the MIT License.
|
3
|
+
/* @conditional-compile-remove(together-mode) */
|
4
|
+
import React, { useMemo, useRef, useState } from 'react';
|
5
|
+
/* @conditional-compile-remove(together-mode) */
|
6
|
+
import { useId } from '@fluentui/react-hooks';
|
7
|
+
/* @conditional-compile-remove(together-mode) */
|
8
|
+
import { LayerHost, mergeStyles, Stack } from '@fluentui/react';
|
9
|
+
/* @conditional-compile-remove(together-mode) */
|
10
|
+
import { renderTiles, useOrganizedParticipants } from './utils/videoGalleryLayoutUtils';
|
11
|
+
/* @conditional-compile-remove(together-mode) */
|
12
|
+
import { OverflowGallery } from './OverflowGallery';
|
13
|
+
/* @conditional-compile-remove(together-mode) */
|
14
|
+
import { rootLayoutStyle } from './styles/DefaultLayout.styles';
|
15
|
+
/* @conditional-compile-remove(together-mode) */
|
16
|
+
import { isNarrowWidth, isShortHeight } from '../utils/responsive';
|
17
|
+
/* @conditional-compile-remove(together-mode) */
|
18
|
+
import { innerLayoutStyle, layerHostStyle } from './styles/FloatingLocalVideoLayout.styles';
|
19
|
+
/* @conditional-compile-remove(together-mode) */
|
20
|
+
import { videoGalleryLayoutGap } from './styles/Layout.styles';
|
21
|
+
/* @conditional-compile-remove(together-mode) */
|
22
|
+
/**
|
23
|
+
* A memoized version of local screen share component. React.memo is used for a performance
|
24
|
+
* boost by memoizing the same rendered component to avoid rerendering this when the parent component rerenders.
|
25
|
+
* https://reactjs.org/docs/react-api.html#reactmemo
|
26
|
+
*/
|
27
|
+
export const TogetherModeLayout = (props) => {
|
28
|
+
const { remoteParticipants = [], dominantSpeakers, screenShareComponent, onRenderRemoteParticipant, styles, maxRemoteVideoStreams, parentWidth, parentHeight, overflowGalleryPosition = 'horizontalBottom', pinnedParticipantUserIds = [], togetherModeStreamComponent } = props;
|
29
|
+
const isNarrow = parentWidth ? isNarrowWidth(parentWidth) : false;
|
30
|
+
const isShort = parentHeight ? isShortHeight(parentHeight) : false;
|
31
|
+
const [indexesToRender, setIndexesToRender] = useState([]);
|
32
|
+
const childrenPerPage = useRef(4);
|
33
|
+
const { gridParticipants, overflowGalleryParticipants } = useOrganizedParticipants({
|
34
|
+
remoteParticipants,
|
35
|
+
dominantSpeakers,
|
36
|
+
maxGridParticipants: maxRemoteVideoStreams,
|
37
|
+
isScreenShareActive: !!screenShareComponent,
|
38
|
+
maxOverflowGalleryDominantSpeakers: screenShareComponent
|
39
|
+
? childrenPerPage.current - (pinnedParticipantUserIds.length % childrenPerPage.current)
|
40
|
+
: childrenPerPage.current,
|
41
|
+
pinnedParticipantUserIds,
|
42
|
+
layout: 'floatingLocalVideo'
|
43
|
+
});
|
44
|
+
const { gridTiles, overflowGalleryTiles } = renderTiles(gridParticipants, onRenderRemoteParticipant, maxRemoteVideoStreams, indexesToRender, overflowGalleryParticipants, dominantSpeakers);
|
45
|
+
const layerHostId = useId('layerhost');
|
46
|
+
const togetherModeOverFlowGalleryTiles = useMemo(() => {
|
47
|
+
let newTiles = overflowGalleryTiles;
|
48
|
+
if (togetherModeStreamComponent) {
|
49
|
+
if (screenShareComponent) {
|
50
|
+
newTiles = gridTiles.concat(overflowGalleryTiles);
|
51
|
+
}
|
52
|
+
}
|
53
|
+
return newTiles;
|
54
|
+
}, [gridTiles, overflowGalleryTiles, screenShareComponent, togetherModeStreamComponent]);
|
55
|
+
const overflowGallery = useMemo(() => {
|
56
|
+
if (overflowGalleryTiles.length === 0 && !props.screenShareComponent) {
|
57
|
+
return null;
|
58
|
+
}
|
59
|
+
return (React.createElement(OverflowGallery, { isShort: isShort, onFetchTilesToRender: setIndexesToRender, isNarrow: isNarrow, shouldFloatLocalVideo: false, overflowGalleryElements: togetherModeOverFlowGalleryTiles, horizontalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery, verticalGalleryStyles: styles === null || styles === void 0 ? void 0 : styles.verticalGallery, overflowGalleryPosition: overflowGalleryPosition, onChildrenPerPageChange: (n) => {
|
60
|
+
childrenPerPage.current = n;
|
61
|
+
}, parentWidth: parentWidth }));
|
62
|
+
}, [
|
63
|
+
overflowGalleryTiles.length,
|
64
|
+
props.screenShareComponent,
|
65
|
+
isShort,
|
66
|
+
isNarrow,
|
67
|
+
togetherModeOverFlowGalleryTiles,
|
68
|
+
styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
|
69
|
+
styles === null || styles === void 0 ? void 0 : styles.verticalGallery,
|
70
|
+
overflowGalleryPosition,
|
71
|
+
parentWidth
|
72
|
+
]);
|
73
|
+
return screenShareComponent ? (React.createElement(Stack, { styles: rootLayoutStyle },
|
74
|
+
React.createElement(LayerHost, { id: layerHostId, className: mergeStyles(layerHostStyle) }),
|
75
|
+
React.createElement(Stack, { horizontal: overflowGalleryPosition === 'verticalRight', styles: innerLayoutStyle, tokens: videoGalleryLayoutGap },
|
76
|
+
props.overflowGalleryPosition === 'horizontalTop' ? overflowGallery : React.createElement(React.Fragment, null),
|
77
|
+
screenShareComponent,
|
78
|
+
overflowGalleryTrampoline(overflowGallery, props.overflowGalleryPosition)))) : (React.createElement(Stack, null, props.togetherModeStreamComponent));
|
79
|
+
};
|
80
|
+
/* @conditional-compile-remove(together-mode) */
|
81
|
+
const overflowGalleryTrampoline = (gallery, galleryPosition) => {
|
82
|
+
return galleryPosition !== 'horizontalTop' ? gallery : React.createElement(React.Fragment, null);
|
83
|
+
return gallery;
|
84
|
+
};
|
85
|
+
//# sourceMappingURL=TogetherModeLayout.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"TogetherModeLayout.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/VideoGallery/TogetherModeLayout.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/* @conditional-compile-remove(together-mode) */\nimport React, { useMemo, useRef, useState } from 'react';\n/* @conditional-compile-remove(together-mode) */\nimport { useId } from '@fluentui/react-hooks';\n/* @conditional-compile-remove(together-mode) */\nimport { _formatString } from '@internal/acs-ui-common';\n/* @conditional-compile-remove(together-mode) */\nimport { LayoutProps } from './Layout';\n/* @conditional-compile-remove(together-mode) */\nimport { LayerHost, mergeStyles, Stack } from '@fluentui/react';\n/* @conditional-compile-remove(together-mode) */\nimport { renderTiles, useOrganizedParticipants } from './utils/videoGalleryLayoutUtils';\n/* @conditional-compile-remove(together-mode) */\nimport { OverflowGallery } from './OverflowGallery';\n/* @conditional-compile-remove(together-mode) */\nimport { rootLayoutStyle } from './styles/DefaultLayout.styles';\n/* @conditional-compile-remove(together-mode) */\nimport { isNarrowWidth, isShortHeight } from '../utils/responsive';\n/* @conditional-compile-remove(together-mode) */\nimport { innerLayoutStyle, layerHostStyle } from './styles/FloatingLocalVideoLayout.styles';\n/* @conditional-compile-remove(together-mode) */\nimport { videoGalleryLayoutGap } from './styles/Layout.styles';\n\n/* @conditional-compile-remove(together-mode) */\n/**\n * A memoized version of local screen share component. React.memo is used for a performance\n * boost by memoizing the same rendered component to avoid rerendering this when the parent component rerenders.\n * https://reactjs.org/docs/react-api.html#reactmemo\n */\nexport const TogetherModeLayout = (props: LayoutProps): JSX.Element => {\n const {\n remoteParticipants = [],\n dominantSpeakers,\n screenShareComponent,\n onRenderRemoteParticipant,\n styles,\n maxRemoteVideoStreams,\n parentWidth,\n parentHeight,\n overflowGalleryPosition = 'horizontalBottom',\n pinnedParticipantUserIds = [],\n togetherModeStreamComponent\n } = props;\n const isNarrow = parentWidth ? isNarrowWidth(parentWidth) : false;\n\n const isShort = parentHeight ? isShortHeight(parentHeight) : false;\n\n const [indexesToRender, setIndexesToRender] = useState<number[]>([]);\n const childrenPerPage = useRef(4);\n\n const { gridParticipants, overflowGalleryParticipants } = useOrganizedParticipants({\n remoteParticipants,\n dominantSpeakers,\n maxGridParticipants: maxRemoteVideoStreams,\n isScreenShareActive: !!screenShareComponent,\n maxOverflowGalleryDominantSpeakers: screenShareComponent\n ? childrenPerPage.current - (pinnedParticipantUserIds.length % childrenPerPage.current)\n : childrenPerPage.current,\n pinnedParticipantUserIds,\n layout: 'floatingLocalVideo'\n });\n const { gridTiles, overflowGalleryTiles } = renderTiles(\n gridParticipants,\n onRenderRemoteParticipant,\n maxRemoteVideoStreams,\n indexesToRender,\n overflowGalleryParticipants,\n dominantSpeakers\n );\n\n const layerHostId = useId('layerhost');\n const togetherModeOverFlowGalleryTiles = useMemo(() => {\n let newTiles = overflowGalleryTiles;\n if (togetherModeStreamComponent) {\n if (screenShareComponent) {\n newTiles = gridTiles.concat(overflowGalleryTiles);\n }\n }\n return newTiles;\n }, [gridTiles, overflowGalleryTiles, screenShareComponent, togetherModeStreamComponent]);\n\n const overflowGallery = useMemo(() => {\n if (overflowGalleryTiles.length === 0 && !props.screenShareComponent) {\n return null;\n }\n return (\n <OverflowGallery\n isShort={isShort}\n onFetchTilesToRender={setIndexesToRender}\n isNarrow={isNarrow}\n shouldFloatLocalVideo={false}\n overflowGalleryElements={togetherModeOverFlowGalleryTiles}\n horizontalGalleryStyles={styles?.horizontalGallery}\n verticalGalleryStyles={styles?.verticalGallery}\n overflowGalleryPosition={overflowGalleryPosition}\n onChildrenPerPageChange={(n: number) => {\n childrenPerPage.current = n;\n }}\n parentWidth={parentWidth}\n />\n );\n }, [\n overflowGalleryTiles.length,\n props.screenShareComponent,\n isShort,\n isNarrow,\n togetherModeOverFlowGalleryTiles,\n styles?.horizontalGallery,\n styles?.verticalGallery,\n overflowGalleryPosition,\n parentWidth\n ]);\n\n return screenShareComponent ? (\n <Stack styles={rootLayoutStyle}>\n <LayerHost id={layerHostId} className={mergeStyles(layerHostStyle)} />\n <Stack\n horizontal={overflowGalleryPosition === 'verticalRight'}\n styles={innerLayoutStyle}\n tokens={videoGalleryLayoutGap}\n >\n {props.overflowGalleryPosition === 'horizontalTop' ? overflowGallery : <></>}\n {screenShareComponent}\n {overflowGalleryTrampoline(overflowGallery, props.overflowGalleryPosition)}\n </Stack>\n </Stack>\n ) : (\n <Stack>{props.togetherModeStreamComponent}</Stack>\n );\n};\n\n/* @conditional-compile-remove(together-mode) */\nconst overflowGalleryTrampoline = (\n gallery: JSX.Element | null,\n galleryPosition?: 'horizontalBottom' | 'verticalRight' | 'horizontalTop'\n): JSX.Element | null => {\n return galleryPosition !== 'horizontalTop' ? gallery : <></>;\n return gallery;\n};\n"]}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { ReactionResources, VideoGalleryTogetherModeParticipantPosition, VideoGalleryTogetherModeStreams, TogetherModeStreamViewResult, VideoGalleryLocalParticipant, VideoGalleryRemoteParticipant, VideoStreamOptions } from '../../types';
|
3
|
+
/**
|
4
|
+
* A memoized version of local screen share component. React.memo is used for a performance
|
5
|
+
* boost by memoizing the same rendered component to avoid rerendering this when the parent component rerenders.
|
6
|
+
* https://reactjs.org/docs/react-api.html#reactmemo
|
7
|
+
*/
|
8
|
+
export declare const TogetherModeStream: React.MemoExoticComponent<(props: {
|
9
|
+
startTogetherModeEnabled?: boolean;
|
10
|
+
isTogetherModeActive?: boolean;
|
11
|
+
onCreateTogetherModeStreamView?: (options?: VideoStreamOptions) => Promise<void | TogetherModeStreamViewResult>;
|
12
|
+
onStartTogetherMode?: (options?: VideoStreamOptions) => Promise<void | TogetherModeStreamViewResult>;
|
13
|
+
onDisposeTogetherModeStreamView?: () => Promise<void>;
|
14
|
+
onSetTogetherModeSceneSize?: (width: number, height: number) => void;
|
15
|
+
togetherModeStreams?: VideoGalleryTogetherModeStreams;
|
16
|
+
seatingCoordinates?: VideoGalleryTogetherModeParticipantPosition;
|
17
|
+
reactionResources?: ReactionResources;
|
18
|
+
localParticipant?: VideoGalleryLocalParticipant;
|
19
|
+
remoteParticipants?: VideoGalleryRemoteParticipant[];
|
20
|
+
screenShareComponent?: JSX.Element;
|
21
|
+
containerWidth?: number;
|
22
|
+
containerHeight?: number;
|
23
|
+
}) => JSX.Element>;
|
24
|
+
//# sourceMappingURL=TogetherModeStream.d.ts.map
|
@@ -0,0 +1,53 @@
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
2
|
+
// Licensed under the MIT License.
|
3
|
+
/* @conditional-compile-remove(together-mode) */
|
4
|
+
import React, { useEffect, useMemo, memo } from 'react';
|
5
|
+
/* @conditional-compile-remove(together-mode) */
|
6
|
+
import { StreamMedia } from '../StreamMedia';
|
7
|
+
/* @conditional-compile-remove(together-mode) */
|
8
|
+
import { MeetingReactionOverlay } from '../MeetingReactionOverlay';
|
9
|
+
/* @conditional-compile-remove(together-mode) */
|
10
|
+
import { Stack } from '@fluentui/react';
|
11
|
+
/* @conditional-compile-remove(together-mode) */
|
12
|
+
import { togetherModeStreamRootStyle } from '../styles/TogetherMode.styles';
|
13
|
+
/* @conditional-compile-remove(together-mode) */
|
14
|
+
/**
|
15
|
+
* A memoized version of local screen share component. React.memo is used for a performance
|
16
|
+
* boost by memoizing the same rendered component to avoid rerendering this when the parent component rerenders.
|
17
|
+
* https://reactjs.org/docs/react-api.html#reactmemo
|
18
|
+
*/
|
19
|
+
export const TogetherModeStream = memo((props) => {
|
20
|
+
var _a, _b;
|
21
|
+
const { startTogetherModeEnabled, isTogetherModeActive, onCreateTogetherModeStreamView, onStartTogetherMode, onSetTogetherModeSceneSize, onDisposeTogetherModeStreamView, togetherModeStreams, containerWidth, containerHeight } = props;
|
22
|
+
useEffect(() => {
|
23
|
+
return () => {
|
24
|
+
// TODO: Isolate disposing behaviors for screenShare and videoStream
|
25
|
+
onDisposeTogetherModeStreamView && onDisposeTogetherModeStreamView();
|
26
|
+
};
|
27
|
+
}, [onDisposeTogetherModeStreamView]);
|
28
|
+
// Trigger startTogetherMode only when needed
|
29
|
+
useEffect(() => {
|
30
|
+
if (startTogetherModeEnabled && !isTogetherModeActive) {
|
31
|
+
onStartTogetherMode === null || onStartTogetherMode === void 0 ? void 0 : onStartTogetherMode();
|
32
|
+
}
|
33
|
+
}, [startTogetherModeEnabled, isTogetherModeActive, onStartTogetherMode]);
|
34
|
+
// Create stream view if not already created
|
35
|
+
useEffect(() => {
|
36
|
+
var _a;
|
37
|
+
if (!((_a = togetherModeStreams === null || togetherModeStreams === void 0 ? void 0 : togetherModeStreams.mainVideoStream) === null || _a === void 0 ? void 0 : _a.renderElement)) {
|
38
|
+
onCreateTogetherModeStreamView === null || onCreateTogetherModeStreamView === void 0 ? void 0 : onCreateTogetherModeStreamView();
|
39
|
+
}
|
40
|
+
}, [(_a = togetherModeStreams === null || togetherModeStreams === void 0 ? void 0 : togetherModeStreams.mainVideoStream) === null || _a === void 0 ? void 0 : _a.renderElement, onCreateTogetherModeStreamView]);
|
41
|
+
// Update scene size only when container dimensions change
|
42
|
+
useMemo(() => {
|
43
|
+
if (onSetTogetherModeSceneSize && containerWidth && containerHeight) {
|
44
|
+
onSetTogetherModeSceneSize(containerWidth, containerHeight);
|
45
|
+
}
|
46
|
+
}, [onSetTogetherModeSceneSize, containerWidth, containerHeight]);
|
47
|
+
const stream = (_b = props.togetherModeStreams) === null || _b === void 0 ? void 0 : _b.mainVideoStream;
|
48
|
+
const showLoadingIndicator = !(stream && stream.isAvailable && stream.isReceiving);
|
49
|
+
return containerWidth && containerHeight ? (React.createElement(Stack, { styles: togetherModeStreamRootStyle, horizontalAlign: "center", verticalAlign: "center" },
|
50
|
+
React.createElement(StreamMedia, { videoStreamElement: (stream === null || stream === void 0 ? void 0 : stream.renderElement) || null, isMirrored: true, loadingState: showLoadingIndicator ? 'loading' : 'none' }),
|
51
|
+
React.createElement(MeetingReactionOverlay, { reactionResources: props.reactionResources || {}, localParticipant: props.localParticipant, remoteParticipants: props.remoteParticipants, togetherModeSeatPositions: props.seatingCoordinates, overlayMode: "together-mode" }))) : (React.createElement(React.Fragment, null));
|
52
|
+
});
|
53
|
+
//# sourceMappingURL=TogetherModeStream.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"TogetherModeStream.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/VideoGallery/TogetherModeStream.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/* @conditional-compile-remove(together-mode) */\nimport React, { useEffect, useMemo, memo } from 'react';\n/* @conditional-compile-remove(together-mode) */\nimport { _formatString, _pxToRem } from '@internal/acs-ui-common';\n/* @conditional-compile-remove(together-mode) */\nimport {\n ReactionResources,\n VideoGalleryTogetherModeParticipantPosition,\n VideoGalleryTogetherModeStreams,\n TogetherModeStreamViewResult,\n VideoGalleryLocalParticipant,\n VideoGalleryRemoteParticipant,\n VideoStreamOptions\n} from '../../types';\n/* @conditional-compile-remove(together-mode) */\nimport { StreamMedia } from '../StreamMedia';\n/* @conditional-compile-remove(together-mode) */\nimport { MeetingReactionOverlay } from '../MeetingReactionOverlay';\n/* @conditional-compile-remove(together-mode) */\nimport { Stack } from '@fluentui/react';\n/* @conditional-compile-remove(together-mode) */\nimport { togetherModeStreamRootStyle } from '../styles/TogetherMode.styles';\n/* @conditional-compile-remove(together-mode) */\n/**\n * A memoized version of local screen share component. React.memo is used for a performance\n * boost by memoizing the same rendered component to avoid rerendering this when the parent component rerenders.\n * https://reactjs.org/docs/react-api.html#reactmemo\n */\nexport const TogetherModeStream = memo(\n (props: {\n startTogetherModeEnabled?: boolean;\n isTogetherModeActive?: boolean;\n onCreateTogetherModeStreamView?: (options?: VideoStreamOptions) => Promise<void | TogetherModeStreamViewResult>;\n onStartTogetherMode?: (options?: VideoStreamOptions) => Promise<void | TogetherModeStreamViewResult>;\n onDisposeTogetherModeStreamView?: () => Promise<void>;\n onSetTogetherModeSceneSize?: (width: number, height: number) => void;\n togetherModeStreams?: VideoGalleryTogetherModeStreams;\n seatingCoordinates?: VideoGalleryTogetherModeParticipantPosition;\n reactionResources?: ReactionResources;\n localParticipant?: VideoGalleryLocalParticipant;\n remoteParticipants?: VideoGalleryRemoteParticipant[];\n screenShareComponent?: JSX.Element;\n containerWidth?: number;\n containerHeight?: number;\n }): JSX.Element => {\n const {\n startTogetherModeEnabled,\n isTogetherModeActive,\n onCreateTogetherModeStreamView,\n onStartTogetherMode,\n onSetTogetherModeSceneSize,\n onDisposeTogetherModeStreamView,\n togetherModeStreams,\n containerWidth,\n containerHeight\n } = props;\n\n useEffect(() => {\n return () => {\n // TODO: Isolate disposing behaviors for screenShare and videoStream\n onDisposeTogetherModeStreamView && onDisposeTogetherModeStreamView();\n };\n }, [onDisposeTogetherModeStreamView]);\n\n // Trigger startTogetherMode only when needed\n useEffect(() => {\n if (startTogetherModeEnabled && !isTogetherModeActive) {\n onStartTogetherMode?.();\n }\n }, [startTogetherModeEnabled, isTogetherModeActive, onStartTogetherMode]);\n\n // Create stream view if not already created\n useEffect(() => {\n if (!togetherModeStreams?.mainVideoStream?.renderElement) {\n onCreateTogetherModeStreamView?.();\n }\n }, [togetherModeStreams?.mainVideoStream?.renderElement, onCreateTogetherModeStreamView]);\n\n // Update scene size only when container dimensions change\n useMemo(() => {\n if (onSetTogetherModeSceneSize && containerWidth && containerHeight) {\n onSetTogetherModeSceneSize(containerWidth, containerHeight);\n }\n }, [onSetTogetherModeSceneSize, containerWidth, containerHeight]);\n\n const stream = props.togetherModeStreams?.mainVideoStream;\n const showLoadingIndicator = !(stream && stream.isAvailable && stream.isReceiving);\n\n return containerWidth && containerHeight ? (\n <Stack styles={togetherModeStreamRootStyle} horizontalAlign=\"center\" verticalAlign=\"center\">\n <StreamMedia\n videoStreamElement={stream?.renderElement || null}\n isMirrored={true}\n loadingState={showLoadingIndicator ? 'loading' : 'none'}\n />\n <MeetingReactionOverlay\n reactionResources={props.reactionResources || ({} as ReactionResources)}\n localParticipant={props.localParticipant}\n remoteParticipants={props.remoteParticipants}\n togetherModeSeatPositions={props.seatingCoordinates}\n overlayMode=\"together-mode\"\n />\n </Stack>\n ) : (\n <></>\n );\n }\n);\n"]}
|
@@ -2,6 +2,7 @@
|
|
2
2
|
import { IStyle } from '@fluentui/react';
|
3
3
|
import { GridLayoutStyles } from '.';
|
4
4
|
import { BaseCustomStyles, OnRenderAvatarCallback, VideoGalleryLocalParticipant, VideoGalleryRemoteParticipant, VideoStreamOptions, CreateVideoStreamViewResult } from '../types';
|
5
|
+
import { VideoGalleryTogetherModeParticipantPosition, VideoGalleryTogetherModeStreams, TogetherModeStreamViewResult } from '../types/TogetherModeTypes';
|
5
6
|
import { HorizontalGalleryStyles } from './HorizontalGallery';
|
6
7
|
import { LocalVideoCameraCycleButtonProps } from './LocalVideoCameraButton';
|
7
8
|
import { VerticalGalleryStyles } from './VerticalGallery';
|
@@ -99,7 +100,7 @@ export interface VideoGalleryStrings {
|
|
99
100
|
/**
|
100
101
|
* @public
|
101
102
|
*/
|
102
|
-
export type VideoGalleryLayout = 'default' | 'floatingLocalVideo' | 'speaker' | /* @conditional-compile-remove(large-gallery) */ 'largeGallery' | 'focusedContent';
|
103
|
+
export type VideoGalleryLayout = 'default' | 'floatingLocalVideo' | 'speaker' | /* @conditional-compile-remove(large-gallery) */ 'largeGallery' | /* @conditional-compile-remove(together-mode) */ 'togetherMode' | 'focusedContent';
|
103
104
|
/**
|
104
105
|
* {@link VideoGallery} Component Styles.
|
105
106
|
* @public
|
@@ -263,6 +264,15 @@ export interface VideoGalleryProps {
|
|
263
264
|
* This callback is to mute a remote participant
|
264
265
|
*/
|
265
266
|
onMuteParticipant?: (userId: string) => Promise<void>;
|
267
|
+
startTogetherModeEnabled?: boolean;
|
268
|
+
isTogetherModeActive?: boolean;
|
269
|
+
onCreateTogetherModeStreamView?: (options?: VideoStreamOptions) => Promise<void | TogetherModeStreamViewResult>;
|
270
|
+
/** Callback to create the local video stream view */
|
271
|
+
onStartTogetherMode?: () => Promise<void>;
|
272
|
+
onSetTogetherModeSceneSize?: (width: number, height: number) => void;
|
273
|
+
togetherModeStreams?: VideoGalleryTogetherModeStreams;
|
274
|
+
togetherModeSeatingCoordinates?: VideoGalleryTogetherModeParticipantPosition;
|
275
|
+
onDisposeTogetherModeStreamView?: () => Promise<void>;
|
266
276
|
/**
|
267
277
|
* This callback is to forbid audio for remote participant(s)
|
268
278
|
*/
|