@azure/communication-react 1.20.0-alpha-202410080015 → 1.20.0-alpha-202410100016
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/README.md +2 -2
- package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-BwIa2hTH.js → ChatMessageComponentAsRichTextEditBox-Dk_okMwX.js} +2 -2
- package/dist/dist-cjs/communication-react/{ChatMessageComponentAsRichTextEditBox-BwIa2hTH.js.map → ChatMessageComponentAsRichTextEditBox-Dk_okMwX.js.map} +1 -1
- package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-CMAkkxJl.js → RichTextSendBoxWrapper-C36s6eLH.js} +2 -2
- package/dist/dist-cjs/communication-react/{RichTextSendBoxWrapper-CMAkkxJl.js.map → RichTextSendBoxWrapper-C36s6eLH.js.map} +1 -1
- package/dist/dist-cjs/communication-react/{index-Bj4O6YVq.js → index-C548hWR1.js} +202 -181
- package/dist/dist-cjs/communication-react/index-C548hWR1.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/calling-component-bindings/src/baseSelectors.js +0 -1
- package/dist/dist-esm/calling-component-bindings/src/baseSelectors.js.map +1 -1
- package/dist/dist-esm/calling-stateful-client/src/CallClientState.js.map +1 -1
- package/dist/dist-esm/calling-stateful-client/src/CallContext.js +0 -3
- package/dist/dist-esm/calling-stateful-client/src/CallContext.js.map +1 -1
- package/dist/dist-esm/calling-stateful-client/src/CallDeclarativeCommon.js +0 -2
- package/dist/dist-esm/calling-stateful-client/src/CallDeclarativeCommon.js.map +1 -1
- package/dist/dist-esm/calling-stateful-client/src/CaptionsSubscriber.js +0 -7
- package/dist/dist-esm/calling-stateful-client/src/CaptionsSubscriber.js.map +1 -1
- package/dist/dist-esm/calling-stateful-client/src/Converter.js +0 -3
- package/dist/dist-esm/calling-stateful-client/src/Converter.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/Attachment/AttachmentCard.js +3 -2
- package/dist/dist-esm/react-components/src/components/Attachment/AttachmentCard.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js +6 -3
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.js +6 -4
- package/dist/dist-esm/react-components/src/components/Dialpad/Dialpad.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/GridLayout.js +3 -0
- package/dist/dist-esm/react-components/src/components/GridLayout.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/HorizontalGallery.js +4 -5
- package/dist/dist-esm/react-components/src/components/HorizontalGallery.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/LocalVideoCameraButton.js +3 -0
- package/dist/dist-esm/react-components/src/components/LocalVideoCameraButton.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/MeetingConferencePhoneInfo.js +2 -1
- package/dist/dist-esm/react-components/src/components/MeetingConferencePhoneInfo.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/MessageThread.js +3 -3
- package/dist/dist-esm/react-components/src/components/MessageThread.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ModalClone/ModalClone.js +2 -1
- package/dist/dist-esm/react-components/src/components/ModalClone/ModalClone.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ParticipantItem.js +1 -1
- package/dist/dist-esm/react-components/src/components/ParticipantItem.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ReactionButton.js +27 -35
- package/dist/dist-esm/react-components/src/components/ReactionButton.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js +9 -3
- package/dist/dist-esm/react-components/src/components/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js +1 -1
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/TextFieldWithMention.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/mentionTagUtils.js +10 -11
- package/dist/dist-esm/react-components/src/components/TextFieldWithMention/mentionTagUtils.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VerticalGallery.js +2 -1
- package/dist/dist-esm/react-components/src/components/VerticalGallery.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoEffects/VideoBackgroundEffectsPicker.js +3 -3
- package/dist/dist-esm/react-components/src/components/VideoEffects/VideoBackgroundEffectsPicker.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/RemoteContentShareReactionOverlay.js +5 -4
- package/dist/dist-esm/react-components/src/components/VideoGallery/RemoteContentShareReactionOverlay.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/utils/videoGalleryLayoutUtils.js +15 -18
- package/dist/dist-esm/react-components/src/components/VideoGallery/utils/videoGalleryLayoutUtils.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoTile.js +3 -0
- package/dist/dist-esm/react-components/src/components/VideoTile.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/ReactionButton.styles.d.ts +13 -6
- package/dist/dist-esm/react-components/src/components/styles/ReactionButton.styles.js +47 -19
- package/dist/dist-esm/react-components/src/components/styles/ReactionButton.styles.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/ReactionOverlay.style.d.ts +0 -6
- package/dist/dist-esm/react-components/src/components/styles/ReactionOverlay.style.js +6 -41
- package/dist/dist-esm/react-components/src/components/styles/ReactionOverlay.style.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.js +4 -1
- package/dist/dist-esm/react-components/src/components/utils/RichTextEditorUtils.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils/RichTextTableUtils.js +3 -0
- package/dist/dist-esm/react-components/src/components/utils/RichTextTableUtils.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils/responsive.js +6 -0
- package/dist/dist-esm/react-components/src/components/utils/responsive.js.map +1 -1
- package/dist/dist-esm/react-components/src/gallery/dominantSpeaker.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js +0 -12
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.js +16 -22
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/MediaGallery.js +9 -2
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/MediaGallery.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/baseSelectors.js +0 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/selectors/baseSelectors.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CommonCallControlBar.js +1 -2
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CommonCallControlBar.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/MoreDrawer.js +1 -3
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/MoreDrawer.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/types/CommonCallControlOptions.js.map +1 -1
- package/package.json +1 -1
- package/dist/dist-cjs/communication-react/index-Bj4O6YVq.js.map +0 -1
package/dist/dist-esm/react-components/src/components/VideoGallery/utils/videoGalleryLayoutUtils.js
CHANGED
@@ -22,13 +22,13 @@ const getOrganizedParticipants = (props) => {
|
|
22
22
|
currentParticipants: previousGridParticipants,
|
23
23
|
maxDominantSpeakers: maxGridParticipants
|
24
24
|
}).slice(0, maxGridParticipants);
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
if (layout === 'speaker') {
|
26
|
+
if (dominantSpeakers === null || dominantSpeakers === void 0 ? void 0 : dominantSpeakers[0]) {
|
27
|
+
newGridParticipants = newGridParticipants.filter((p) => p.userId === dominantSpeakers[0]);
|
28
|
+
}
|
29
|
+
else {
|
30
|
+
newGridParticipants = newGridParticipants.slice(1);
|
31
|
+
}
|
32
32
|
}
|
33
33
|
const gridParticipantSet = new Set(newGridParticipants.map((p) => p.userId));
|
34
34
|
const newOverflowGalleryParticipants = smartDominantSpeakerParticipants({
|
@@ -53,21 +53,18 @@ const getOrganizedParticipants = (props) => {
|
|
53
53
|
*/
|
54
54
|
export const useOrganizedParticipants = (props) => {
|
55
55
|
var _a, _b;
|
56
|
-
// map remote participants by userId
|
57
|
-
const remoteParticipantMap = props.remoteParticipants.reduce((map, remoteParticipant) => {
|
58
|
-
map[remoteParticipant.userId] = remoteParticipant;
|
59
|
-
return map;
|
60
|
-
}, {});
|
61
56
|
const spotlightedParticipantUserIds = (_a = props.spotlightedParticipantUserIds) !== null && _a !== void 0 ? _a : [];
|
62
57
|
const pinnedParticipantUserIds = (_b = props.pinnedParticipantUserIds) !== null && _b !== void 0 ? _b : [];
|
63
|
-
//
|
64
|
-
//
|
65
|
-
const focusedParticipantUserIdSet = new Set(spotlightedParticipantUserIds.concat(pinnedParticipantUserIds)
|
66
|
-
|
67
|
-
|
58
|
+
// Focussed participants are the participants that are either spotlighted or pinned. Ordered by spotlighted first and then pinned.
|
59
|
+
// A set is used to dedupe participants.
|
60
|
+
const focusedParticipantUserIdSet = new Set(spotlightedParticipantUserIds.concat(pinnedParticipantUserIds));
|
61
|
+
const focusedParticipants = [...focusedParticipantUserIdSet]
|
62
|
+
.map((userId) => props.remoteParticipants.find((p) => p.userId === userId))
|
63
|
+
.filter((p) => p !== undefined);
|
64
|
+
// Unfocused participants are the rest of the participants
|
65
|
+
const unfocusedParticipants = props.remoteParticipants.filter((p) => !focusedParticipantUserIdSet.has(p.userId));
|
68
66
|
const currentGridParticipants = useRef([]);
|
69
67
|
const currentOverflowGalleryParticipants = useRef([]);
|
70
|
-
const unfocusedParticipants = props.remoteParticipants.filter((p) => !focusedParticipantUserIdSet.has(p.userId));
|
71
68
|
const organizedParticipantsArgs = Object.assign(Object.assign({}, props), {
|
72
69
|
// if there are focused participants then leave no room in the grid by setting maxGridParticipants to 0
|
73
70
|
maxGridParticipants: focusedParticipants.length > 0 || props.isScreenShareActive ? 0 : props.maxGridParticipants, remoteParticipants: unfocusedParticipants, previousGridParticipants: currentGridParticipants.current, previousOverflowParticipants: currentOverflowGalleryParticipants.current });
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"videoGalleryLayoutUtils.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/VideoGallery/utils/videoGalleryLayoutUtils.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,gCAAgC,EAAE,MAAM,kBAAkB,CAAC;AAgCpE,MAAM,8CAA8C,GAAG,CAAC,CAAC;AACzD,MAAM,wBAAwB,GAAG,CAAC,CAAC;AACnC;;GAEG;AACH,MAAM,CAAC,MAAM,uCAAuC,GAAG,CAAC,CAAC;AAEzD,MAAM,wBAAwB,GAAG,CAAC,KAAgC,EAA+B,EAAE;IACjG,MAAM,EACJ,kBAAkB,GAAG,EAAE,EACvB,gBAAgB,GAAG,EAAE,EACrB,mBAAmB,GAAG,wBAAwB,EAC9C,kCAAkC,GAAG,8CAA8C,EACnF,MAAM,EACN,wBAAwB,GAAG,EAAE,EAC7B,4BAA4B,GAAG,EAAE,EAClC,GAAG,KAAK,CAAC;IAEV,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,YAAY,IAAI,SAAS,CAAC,CAAC,CAAC;IAEtG,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAEjF,MAAM,qBAAqB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAEtG,MAAM,yBAAyB,GAAG,yBAAyB,CAAC,qBAAqB,CAAC,CAAC;IACnF,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,MAAA,CAAC,CAAC,WAAW,0CAAE,WAAW,CAAA,EAAA,CAAC,CAAC;IACvF,MAAM,mBAAmB,GACvB,MAAM,KAAK,oBAAoB,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,yBAAyB,CAAC;IAElH,IAAI,mBAAmB,GAAG,gCAAgC,CAAC;QACzD,YAAY,EAAE,mBAAmB;QACjC,gBAAgB;QAChB,mBAAmB,EAAE,wBAAwB;QAC7C,mBAAmB,EAAE,mBAAmB;KACzC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAEjC,MAAM,qBAAqB,GACzB,MAAM,KAAK,SAAS;QAClB,CAAC,CAAC,gBAAgB,IAAI,gBAAgB,CAAC,CAAC,CAAC;YACvC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,gBAAgB,CAAC,CAAC,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC,CAAC,EAAE,CAAC;IAET,IAAI,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7B,mBAAmB,GAAG,qBAAqB,CAAC;IAC9C,CAAC;IAED,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAE7E,MAAM,8BAA8B,GAAG,gCAAgC,CAAC;QACtE,YAAY,EAAE,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACxF,gBAAgB,EAAE,gBAAgB;QAClC,mBAAmB,EAAE,4BAA4B;QACjD,mBAAmB,EAAE,kCAAkC;KACxD,CAAC,CAAC;IAEH,IAAI,gBAAgB,GAAG,mBAAmB,CAAC;IAC3C,IAAI,2BAA2B,GAAG,8BAA8B,CAAC;IACjE,IAAI,gBAAgB,CAAC,MAAM,GAAG,mBAAmB,CAAC,MAAM,IAAI,mBAAmB,EAAE,CAAC;QAChF,gBAAgB,GAAG,gBAAgB,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAClE,CAAC;SAAM,CAAC;QACN,2BAA2B,GAAG,2BAA2B,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACxF,CAAC;IAED,OAAO,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,CAAC;AAC3D,CAAC,CAAC;AAMF;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,KAAgC,EAA+B,EAAE;;IACxG,oCAAoC;IACpC,MAAM,oBAAoB,GAAG,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,iBAAiB,EAAE,EAAE;QACtF,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,iBAAiB,CAAC;QAClD,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAA8B,CAAC,CAAC;IAEnC,MAAM,6BAA6B,GAAG,MAAA,KAAK,CAAC,6BAA6B,mCAAI,EAAE,CAAC;IAChF,MAAM,wBAAwB,GAAG,MAAA,KAAK,CAAC,wBAAwB,mCAAI,EAAE,CAAC;IACtE,+FAA+F;IAC/F,6EAA6E;IAC7E,MAAM,2BAA2B,GAAG,IAAI,GAAG,CACzC,6BAA6B,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CACtG,CAAC;IACF,wFAAwF;IACxF,MAAM,mBAAmB,GAAoC,CAAC,GAAG,2BAA2B,CAAC,CAAC,GAAG,CAC/F,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAC/B,CAAC;IAEF,MAAM,uBAAuB,GAAG,MAAM,CAAkC,EAAE,CAAC,CAAC;IAC5E,MAAM,kCAAkC,GAAG,MAAM,CAAkC,EAAE,CAAC,CAAC;IAEvF,MAAM,qBAAqB,GAAG,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAEjH,MAAM,yBAAyB,mCAC1B,KAAK;QACR,uGAAuG;QACvG,mBAAmB,EAAE,mBAAmB,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,mBAAmB,EAChH,kBAAkB,EAAE,qBAAqB,EACzC,wBAAwB,EAAE,uBAAuB,CAAC,OAAO,EACzD,4BAA4B,EAAE,kCAAkC,CAAC,OAAO,GACzE,CAAC;IAEF,MAAM,qBAAqB,GAAG,wBAAwB,CAAC,yBAAyB,CAAC,CAAC;IAElF,uBAAuB,CAAC,OAAO,GAAG,qBAAqB,CAAC,gBAAgB,CAAC;IACzE,kCAAkC,CAAC,OAAO,GAAG,qBAAqB,CAAC,2BAA2B,CAAC;IAE/F,OAAO,mBAAmB,CAAC,MAAM,GAAG,CAAC;QACnC,CAAC,CAAC;YACE,gBAAgB,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB;YACtE,2BAA2B,EAAE,KAAK,CAAC,mBAAmB;gBACpD,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,qBAAqB,CAAC,2BAA2B,CAAC;gBAC/E,CAAC,CAAC,qBAAqB,CAAC,2BAA2B;SACtD;QACH,CAAC,CAAC,qBAAqB,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CAChC,kBAAmD,EAClB,EAAE;IACnC,MAAM,iBAAiB,GAAoC,EAAE,CAAC;IAC9D,MAAM,iBAAiB,GAAoC,EAAE,CAAC;IAC9D,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;;QAC/B,IAAI,MAAA,CAAC,CAAC,WAAW,0CAAE,WAAW,EAAE,CAAC;YAC/B,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CAAC,CAAC;IACH,MAAM,8BAA8B,GAAG,iBAAiB,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACnF,OAAO,8BAA8B,CAAC;AACxC,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,gBAA2C,EAC3C,yBAAoH,EACpH,qBAA6B,EAC7B,eAAyB,EACzB,2BAAsD,EACtD,gBAA2B,EACwC,EAAE;IACrE,MAAM,iBAAiB,GAAG,gBAAgB,aAAhB,gBAAgB,cAAhB,gBAAgB,GAAI,EAAE,CAAC;IACjD,IAAI,mBAAmB,GAAG,qBAAqB,CAAC;IAEhD,+BAA+B;IAC/B,MAAM,oCAAoC,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,MAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,WAAW,0CAAE,WAAW,CAAA,EAAA,CAAC,CAAC;IACzG,MAAM,wCAAwC,GAAG,iBAAiB;SAC/D,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,oCAAoC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,MAAM,MAAK,MAAM,CAAC,CAAC;SAC1F,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;IACjC,mBAAmB,GAAG,mBAAmB,GAAG,wCAAwC,CAAC,MAAM,CAAC;IAC5F,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;;QAC3C,OAAO,yBAAyB,CAC9B,CAAC,EACD,wCAAwC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;YACzD,CAAC,CAAA,MAAA,CAAC,CAAC,WAAW,0CAAE,WAAW,KAAI,mBAAmB,EAAE,GAAG,CAAC,CAAC,CAC5D,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,mCAAmC;IACnC,MAAM,wCAAwC,GAAG,eAAe;SAC7D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,OAAO,2BAA2B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,MAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,WAAW,0CAAE,WAAW,CAAA,EAAA,CAAC,CAAC;IAC9C,MAAM,4CAA4C,GAAG,iBAAiB;SACnE,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,wCAAwC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,MAAM,MAAK,MAAM,CAAC,CAAC;SAC9F,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;IACjC,mBAAmB,GAAG,mBAAmB,GAAG,4CAA4C,CAAC,MAAM,CAAC;IAChG,MAAM,oBAAoB,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;;QACjE,OAAO,yBAAyB,CAC9B,CAAC,EACD,4CAA4C,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;YAC7D,CAAC,CAAA,MAAA,CAAC,CAAC,WAAW,0CAAE,WAAW,KAAI,mBAAmB,EAAE,GAAG,CAAC,CAAC,CAC5D,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,CAAC;AAC7C,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,YAAoB,EAAE,iBAAoC,EAAsB,EAAE;;IACjH,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,MAAM;YACT,OAAO,MAAA,iBAAiB,CAAC,YAAY,0CAAE,GAAG,CAAC;QAC7C,KAAK,OAAO;YACV,OAAO,MAAA,iBAAiB,CAAC,aAAa,0CAAE,GAAG,CAAC;QAC9C,KAAK,OAAO;YACV,OAAO,MAAA,iBAAiB,CAAC,aAAa,0CAAE,GAAG,CAAC;QAC9C,KAAK,UAAU;YACb,OAAO,MAAA,iBAAiB,CAAC,gBAAgB,0CAAE,GAAG,CAAC;QACjD,KAAK,WAAW;YACd,OAAO,MAAA,iBAAiB,CAAC,iBAAiB,0CAAE,GAAG,CAAC;IACpD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,YAAoB,EAAE,iBAAoC,EAAU,EAAE;;IACvG,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,MAAM;YACT,OAAO,MAAA,MAAA,iBAAiB,CAAC,YAAY,0CAAE,UAAU,mCAAI,CAAC,CAAC;QACzD,KAAK,OAAO;YACV,OAAO,MAAA,MAAA,iBAAiB,CAAC,aAAa,0CAAE,UAAU,mCAAI,CAAC,CAAC;QAC1D,KAAK,OAAO;YACV,OAAO,MAAA,MAAA,iBAAiB,CAAC,aAAa,0CAAE,UAAU,mCAAI,CAAC,CAAC;QAC1D,KAAK,UAAU;YACb,OAAO,MAAA,MAAA,iBAAiB,CAAC,gBAAgB,0CAAE,UAAU,mCAAI,CAAC,CAAC;QAC7D,KAAK,WAAW;YACd,OAAO,MAAA,MAAA,iBAAiB,CAAC,iBAAiB,0CAAE,UAAU,mCAAI,CAAC,CAAC;QAC9D;YACE,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { useRef } from 'react';\nimport { smartDominantSpeakerParticipants } from '../../../gallery';\nimport { VideoGalleryParticipant, VideoGalleryRemoteParticipant } from '../../../types';\nimport { ReactionResources } from '../../..';\nimport { VideoGalleryLayout } from '../../VideoGallery';\n\n/**\n * Arguments used to determine a {@link OrganizedParticipantsResult}\n * @private\n */\nexport interface OrganizedParticipantsArgs {\n remoteParticipants: VideoGalleryRemoteParticipant[];\n localParticipant?: VideoGalleryParticipant;\n dominantSpeakers?: string[];\n maxGridParticipants?: number;\n maxOverflowGalleryDominantSpeakers?: number;\n isScreenShareActive?: boolean;\n pinnedParticipantUserIds?: string[];\n layout?: VideoGalleryLayout;\n spotlightedParticipantUserIds?: string[];\n previousGridParticipants?: VideoGalleryRemoteParticipant[];\n previousOverflowParticipants?: VideoGalleryRemoteParticipant[];\n}\n\n/**\n * A result that defines grid participants and overflow gallery participants in the VideoGallery\n * @private\n */\nexport interface OrganizedParticipantsResult {\n gridParticipants: VideoGalleryParticipant[];\n overflowGalleryParticipants: VideoGalleryParticipant[];\n}\n\nconst DEFAULT_MAX_OVERFLOW_GALLERY_DOMINANT_SPEAKERS = 6;\nconst DEFAULT_MAX_VIDEO_SREAMS = 4;\n/**\n * @private\n */\nexport const MAX_GRID_PARTICIPANTS_NOT_LARGE_GALLERY = 9;\n\nconst getOrganizedParticipants = (props: OrganizedParticipantsArgs): OrganizedParticipantsResult => {\n const {\n remoteParticipants = [],\n dominantSpeakers = [],\n maxGridParticipants = DEFAULT_MAX_VIDEO_SREAMS,\n maxOverflowGalleryDominantSpeakers = DEFAULT_MAX_OVERFLOW_GALLERY_DOMINANT_SPEAKERS,\n layout,\n previousGridParticipants = [],\n previousOverflowParticipants = []\n } = props;\n\n const callingParticipants = remoteParticipants.filter((p) => p.state === ('Connecting' || 'Ringing'));\n\n const callingParticipantsSet = new Set(callingParticipants.map((p) => p.userId));\n\n const connectedParticipants = remoteParticipants.filter((p) => !callingParticipantsSet.has(p.userId));\n\n const remoteParticipantsOrdered = putVideoParticipantsFirst(connectedParticipants);\n const videoParticipants = remoteParticipants.filter((p) => p.videoStream?.isAvailable);\n const participantsForGrid =\n layout === 'floatingLocalVideo' && videoParticipants.length > 0 ? videoParticipants : remoteParticipantsOrdered;\n\n let newGridParticipants = smartDominantSpeakerParticipants({\n participants: participantsForGrid,\n dominantSpeakers,\n currentParticipants: previousGridParticipants,\n maxDominantSpeakers: maxGridParticipants\n }).slice(0, maxGridParticipants);\n\n const dominantSpeakerToGrid =\n layout === 'speaker'\n ? dominantSpeakers && dominantSpeakers[0]\n ? newGridParticipants.filter((p) => p.userId === dominantSpeakers[0])\n : [newGridParticipants[0]]\n : [];\n\n if (dominantSpeakerToGrid[0]) {\n newGridParticipants = dominantSpeakerToGrid;\n }\n\n const gridParticipantSet = new Set(newGridParticipants.map((p) => p.userId));\n\n const newOverflowGalleryParticipants = smartDominantSpeakerParticipants({\n participants: remoteParticipantsOrdered.filter((p) => !gridParticipantSet.has(p.userId)),\n dominantSpeakers: dominantSpeakers,\n currentParticipants: previousOverflowParticipants,\n maxDominantSpeakers: maxOverflowGalleryDominantSpeakers\n });\n\n let gridParticipants = newGridParticipants;\n let overflowGalleryParticipants = newOverflowGalleryParticipants;\n if (gridParticipants.length + callingParticipants.length <= maxGridParticipants) {\n gridParticipants = gridParticipants.concat(callingParticipants);\n } else {\n overflowGalleryParticipants = overflowGalleryParticipants.concat(callingParticipants);\n }\n\n return { gridParticipants, overflowGalleryParticipants };\n};\n\ninterface SortedRemoteParticipants {\n [key: string]: VideoGalleryRemoteParticipant;\n}\n\n/**\n * Hook to determine which participants should be in grid and overflow gallery and their order respectively\n * @private\n */\nexport const useOrganizedParticipants = (props: OrganizedParticipantsArgs): OrganizedParticipantsResult => {\n // map remote participants by userId\n const remoteParticipantMap = props.remoteParticipants.reduce((map, remoteParticipant) => {\n map[remoteParticipant.userId] = remoteParticipant;\n return map;\n }, {} as SortedRemoteParticipants);\n\n const spotlightedParticipantUserIds = props.spotlightedParticipantUserIds ?? [];\n const pinnedParticipantUserIds = props.pinnedParticipantUserIds ?? [];\n // declare set of focused participant user ids as spotlighted participants user ids followed by\n // pinned participants user ids which is deduplicated while maintaining order\n const focusedParticipantUserIdSet = new Set(\n spotlightedParticipantUserIds.concat(pinnedParticipantUserIds).filter((p) => remoteParticipantMap[p])\n );\n // get focused participants from map of remote participants in the order of the user ids\n const focusedParticipants: VideoGalleryRemoteParticipant[] = [...focusedParticipantUserIdSet].map(\n (p) => remoteParticipantMap[p]\n );\n\n const currentGridParticipants = useRef<VideoGalleryRemoteParticipant[]>([]);\n const currentOverflowGalleryParticipants = useRef<VideoGalleryRemoteParticipant[]>([]);\n\n const unfocusedParticipants = props.remoteParticipants.filter((p) => !focusedParticipantUserIdSet.has(p.userId));\n\n const organizedParticipantsArgs: OrganizedParticipantsArgs = {\n ...props,\n // if there are focused participants then leave no room in the grid by setting maxGridParticipants to 0\n maxGridParticipants: focusedParticipants.length > 0 || props.isScreenShareActive ? 0 : props.maxGridParticipants,\n remoteParticipants: unfocusedParticipants,\n previousGridParticipants: currentGridParticipants.current,\n previousOverflowParticipants: currentOverflowGalleryParticipants.current\n };\n\n const organizedParticipants = getOrganizedParticipants(organizedParticipantsArgs);\n\n currentGridParticipants.current = organizedParticipants.gridParticipants;\n currentOverflowGalleryParticipants.current = organizedParticipants.overflowGalleryParticipants;\n\n return focusedParticipants.length > 0\n ? {\n gridParticipants: props.isScreenShareActive ? [] : focusedParticipants,\n overflowGalleryParticipants: props.isScreenShareActive\n ? focusedParticipants.concat(organizedParticipants.overflowGalleryParticipants)\n : organizedParticipants.overflowGalleryParticipants\n }\n : organizedParticipants;\n};\n\nconst putVideoParticipantsFirst = (\n remoteParticipants: VideoGalleryRemoteParticipant[]\n): VideoGalleryRemoteParticipant[] => {\n const videoParticipants: VideoGalleryRemoteParticipant[] = [];\n const audioParticipants: VideoGalleryRemoteParticipant[] = [];\n remoteParticipants.forEach((p) => {\n if (p.videoStream?.isAvailable) {\n videoParticipants.push(p);\n } else {\n audioParticipants.push(p);\n }\n });\n const remoteParticipantSortedByVideo = videoParticipants.concat(audioParticipants);\n return remoteParticipantSortedByVideo;\n};\n\n/**\n * @private\n */\nexport const renderTiles = (\n gridParticipants: VideoGalleryParticipant[],\n onRenderRemoteParticipant: (participant: VideoGalleryRemoteParticipant, isVideoParticipant?: boolean) => JSX.Element,\n maxRemoteVideoStreams: number,\n indexesToRender: number[],\n overflowGalleryParticipants: VideoGalleryParticipant[],\n dominantSpeakers?: string[]\n): { gridTiles: JSX.Element[]; overflowGalleryTiles: JSX.Element[] } => {\n const _dominantSpeakers = dominantSpeakers ?? [];\n let streamsLeftToRender = maxRemoteVideoStreams;\n\n // Render the grid participants\n const participantWithStreamsToRenderInGrid = gridParticipants.filter((p) => p?.videoStream?.isAvailable);\n const dominantSpeakerWithStreamsToRenderInGrid = _dominantSpeakers\n .filter((userId) => participantWithStreamsToRenderInGrid.find((p) => p?.userId === userId))\n .slice(0, streamsLeftToRender);\n streamsLeftToRender = streamsLeftToRender - dominantSpeakerWithStreamsToRenderInGrid.length;\n const gridTiles = gridParticipants.map((p) => {\n return onRenderRemoteParticipant(\n p,\n dominantSpeakerWithStreamsToRenderInGrid.includes(p.userId) ||\n (p.videoStream?.isAvailable && streamsLeftToRender-- > 0)\n );\n });\n\n // Render the overflow participants\n const participantWithStreamsToRenderInOverflow = indexesToRender\n .map((i) => {\n return overflowGalleryParticipants.at(i);\n })\n .filter((p) => p?.videoStream?.isAvailable);\n const dominantSpeakerWithStreamsToRenderInOverflow = _dominantSpeakers\n .filter((userId) => participantWithStreamsToRenderInOverflow.find((p) => p?.userId === userId))\n .slice(0, streamsLeftToRender);\n streamsLeftToRender = streamsLeftToRender - dominantSpeakerWithStreamsToRenderInOverflow.length;\n const overflowGalleryTiles = overflowGalleryParticipants.map((p) => {\n return onRenderRemoteParticipant(\n p,\n dominantSpeakerWithStreamsToRenderInOverflow.includes(p.userId) ||\n (p.videoStream?.isAvailable && streamsLeftToRender-- > 0)\n );\n });\n\n return { gridTiles, overflowGalleryTiles };\n};\n\n/**\n * @private\n */\nexport const getEmojiResource = (reactionName: string, reactionResources: ReactionResources): string | undefined => {\n switch (reactionName) {\n case 'like':\n return reactionResources.likeReaction?.url;\n case 'heart':\n return reactionResources.heartReaction?.url;\n case 'laugh':\n return reactionResources.laughReaction?.url;\n case 'applause':\n return reactionResources.applauseReaction?.url;\n case 'surprised':\n return reactionResources.surprisedReaction?.url;\n }\n return undefined;\n};\n\n/**\n * @private\n */\nexport const getEmojiFrameCount = (reactionName: string, reactionResources: ReactionResources): number => {\n switch (reactionName) {\n case 'like':\n return reactionResources.likeReaction?.frameCount ?? 0;\n case 'heart':\n return reactionResources.heartReaction?.frameCount ?? 0;\n case 'laugh':\n return reactionResources.laughReaction?.frameCount ?? 0;\n case 'applause':\n return reactionResources.applauseReaction?.frameCount ?? 0;\n case 'surprised':\n return reactionResources.surprisedReaction?.frameCount ?? 0;\n default:\n return 0;\n }\n};\n"]}
|
1
|
+
{"version":3,"file":"videoGalleryLayoutUtils.js","sourceRoot":"","sources":["../../../../../../../../react-components/src/components/VideoGallery/utils/videoGalleryLayoutUtils.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { useRef } from 'react';\nimport { smartDominantSpeakerParticipants } from '../../../gallery';\nimport { VideoGalleryParticipant, VideoGalleryRemoteParticipant } from '../../../types';\nimport { ReactionResources } from '../../..';\nimport { VideoGalleryLayout } from '../../VideoGallery';\n\n/**\n * Arguments used to determine a {@link OrganizedParticipantsResult}\n * @private\n */\nexport interface OrganizedParticipantsArgs {\n remoteParticipants: VideoGalleryRemoteParticipant[];\n localParticipant?: VideoGalleryParticipant;\n dominantSpeakers?: string[];\n maxGridParticipants?: number;\n maxOverflowGalleryDominantSpeakers?: number;\n isScreenShareActive?: boolean;\n pinnedParticipantUserIds?: string[];\n layout?: VideoGalleryLayout;\n spotlightedParticipantUserIds?: string[];\n previousGridParticipants?: VideoGalleryRemoteParticipant[];\n previousOverflowParticipants?: VideoGalleryRemoteParticipant[];\n}\n\n/**\n * A result that defines grid participants and overflow gallery participants in the VideoGallery\n * @private\n */\nexport interface OrganizedParticipantsResult {\n gridParticipants: VideoGalleryParticipant[];\n overflowGalleryParticipants: VideoGalleryParticipant[];\n}\n\nconst DEFAULT_MAX_OVERFLOW_GALLERY_DOMINANT_SPEAKERS = 6;\nconst DEFAULT_MAX_VIDEO_SREAMS = 4;\n/**\n * @private\n */\nexport const MAX_GRID_PARTICIPANTS_NOT_LARGE_GALLERY = 9;\n\nconst getOrganizedParticipants = (props: OrganizedParticipantsArgs): OrganizedParticipantsResult => {\n const {\n remoteParticipants = [],\n dominantSpeakers = [],\n maxGridParticipants = DEFAULT_MAX_VIDEO_SREAMS,\n maxOverflowGalleryDominantSpeakers = DEFAULT_MAX_OVERFLOW_GALLERY_DOMINANT_SPEAKERS,\n layout,\n previousGridParticipants = [],\n previousOverflowParticipants = []\n } = props;\n\n const callingParticipants = remoteParticipants.filter((p) => p.state === ('Connecting' || 'Ringing'));\n\n const callingParticipantsSet = new Set(callingParticipants.map((p) => p.userId));\n\n const connectedParticipants = remoteParticipants.filter((p) => !callingParticipantsSet.has(p.userId));\n\n const remoteParticipantsOrdered = putVideoParticipantsFirst(connectedParticipants);\n const videoParticipants = remoteParticipants.filter((p) => p.videoStream?.isAvailable);\n const participantsForGrid =\n layout === 'floatingLocalVideo' && videoParticipants.length > 0 ? videoParticipants : remoteParticipantsOrdered;\n\n let newGridParticipants = smartDominantSpeakerParticipants({\n participants: participantsForGrid,\n dominantSpeakers,\n currentParticipants: previousGridParticipants,\n maxDominantSpeakers: maxGridParticipants\n }).slice(0, maxGridParticipants);\n\n if (layout === 'speaker') {\n if (dominantSpeakers?.[0]) {\n newGridParticipants = newGridParticipants.filter((p) => p.userId === dominantSpeakers[0]);\n } else {\n newGridParticipants = newGridParticipants.slice(1);\n }\n }\n\n const gridParticipantSet = new Set(newGridParticipants.map((p) => p.userId));\n\n const newOverflowGalleryParticipants = smartDominantSpeakerParticipants({\n participants: remoteParticipantsOrdered.filter((p) => !gridParticipantSet.has(p.userId)),\n dominantSpeakers: dominantSpeakers,\n currentParticipants: previousOverflowParticipants,\n maxDominantSpeakers: maxOverflowGalleryDominantSpeakers\n });\n\n let gridParticipants = newGridParticipants;\n let overflowGalleryParticipants = newOverflowGalleryParticipants;\n if (gridParticipants.length + callingParticipants.length <= maxGridParticipants) {\n gridParticipants = gridParticipants.concat(callingParticipants);\n } else {\n overflowGalleryParticipants = overflowGalleryParticipants.concat(callingParticipants);\n }\n\n return { gridParticipants, overflowGalleryParticipants };\n};\n\n/**\n * Hook to determine which participants should be in grid and overflow gallery and their order respectively\n * @private\n */\nexport const useOrganizedParticipants = (props: OrganizedParticipantsArgs): OrganizedParticipantsResult => {\n const spotlightedParticipantUserIds = props.spotlightedParticipantUserIds ?? [];\n const pinnedParticipantUserIds = props.pinnedParticipantUserIds ?? [];\n\n // Focussed participants are the participants that are either spotlighted or pinned. Ordered by spotlighted first and then pinned.\n // A set is used to dedupe participants.\n const focusedParticipantUserIdSet = new Set(spotlightedParticipantUserIds.concat(pinnedParticipantUserIds));\n const focusedParticipants: VideoGalleryRemoteParticipant[] = [...focusedParticipantUserIdSet]\n .map((userId) => props.remoteParticipants.find((p) => p.userId === userId))\n .filter((p) => p !== undefined) as VideoGalleryRemoteParticipant[];\n\n // Unfocused participants are the rest of the participants\n const unfocusedParticipants = props.remoteParticipants.filter((p) => !focusedParticipantUserIdSet.has(p.userId));\n\n const currentGridParticipants = useRef<VideoGalleryRemoteParticipant[]>([]);\n const currentOverflowGalleryParticipants = useRef<VideoGalleryRemoteParticipant[]>([]);\n\n const organizedParticipantsArgs: OrganizedParticipantsArgs = {\n ...props,\n // if there are focused participants then leave no room in the grid by setting maxGridParticipants to 0\n maxGridParticipants: focusedParticipants.length > 0 || props.isScreenShareActive ? 0 : props.maxGridParticipants,\n remoteParticipants: unfocusedParticipants,\n previousGridParticipants: currentGridParticipants.current,\n previousOverflowParticipants: currentOverflowGalleryParticipants.current\n };\n\n const organizedParticipants = getOrganizedParticipants(organizedParticipantsArgs);\n\n currentGridParticipants.current = organizedParticipants.gridParticipants;\n currentOverflowGalleryParticipants.current = organizedParticipants.overflowGalleryParticipants;\n\n return focusedParticipants.length > 0\n ? {\n gridParticipants: props.isScreenShareActive ? [] : focusedParticipants,\n overflowGalleryParticipants: props.isScreenShareActive\n ? focusedParticipants.concat(organizedParticipants.overflowGalleryParticipants)\n : organizedParticipants.overflowGalleryParticipants\n }\n : organizedParticipants;\n};\n\nconst putVideoParticipantsFirst = (\n remoteParticipants: VideoGalleryRemoteParticipant[]\n): VideoGalleryRemoteParticipant[] => {\n const videoParticipants: VideoGalleryRemoteParticipant[] = [];\n const audioParticipants: VideoGalleryRemoteParticipant[] = [];\n remoteParticipants.forEach((p) => {\n if (p.videoStream?.isAvailable) {\n videoParticipants.push(p);\n } else {\n audioParticipants.push(p);\n }\n });\n const remoteParticipantSortedByVideo = videoParticipants.concat(audioParticipants);\n return remoteParticipantSortedByVideo;\n};\n\n/**\n * @private\n */\nexport const renderTiles = (\n gridParticipants: VideoGalleryParticipant[],\n onRenderRemoteParticipant: (participant: VideoGalleryRemoteParticipant, isVideoParticipant?: boolean) => JSX.Element,\n maxRemoteVideoStreams: number,\n indexesToRender: number[],\n overflowGalleryParticipants: VideoGalleryParticipant[],\n dominantSpeakers?: string[]\n): { gridTiles: JSX.Element[]; overflowGalleryTiles: JSX.Element[] } => {\n const _dominantSpeakers = dominantSpeakers ?? [];\n let streamsLeftToRender = maxRemoteVideoStreams;\n\n // Render the grid participants\n const participantWithStreamsToRenderInGrid = gridParticipants.filter((p) => p?.videoStream?.isAvailable);\n const dominantSpeakerWithStreamsToRenderInGrid = _dominantSpeakers\n .filter((userId) => participantWithStreamsToRenderInGrid.find((p) => p?.userId === userId))\n .slice(0, streamsLeftToRender);\n streamsLeftToRender = streamsLeftToRender - dominantSpeakerWithStreamsToRenderInGrid.length;\n const gridTiles = gridParticipants.map((p) => {\n return onRenderRemoteParticipant(\n p,\n dominantSpeakerWithStreamsToRenderInGrid.includes(p.userId) ||\n (p.videoStream?.isAvailable && streamsLeftToRender-- > 0)\n );\n });\n\n // Render the overflow participants\n const participantWithStreamsToRenderInOverflow = indexesToRender\n .map((i) => {\n return overflowGalleryParticipants.at(i);\n })\n .filter((p) => p?.videoStream?.isAvailable);\n const dominantSpeakerWithStreamsToRenderInOverflow = _dominantSpeakers\n .filter((userId) => participantWithStreamsToRenderInOverflow.find((p) => p?.userId === userId))\n .slice(0, streamsLeftToRender);\n streamsLeftToRender = streamsLeftToRender - dominantSpeakerWithStreamsToRenderInOverflow.length;\n const overflowGalleryTiles = overflowGalleryParticipants.map((p) => {\n return onRenderRemoteParticipant(\n p,\n dominantSpeakerWithStreamsToRenderInOverflow.includes(p.userId) ||\n (p.videoStream?.isAvailable && streamsLeftToRender-- > 0)\n );\n });\n\n return { gridTiles, overflowGalleryTiles };\n};\n\n/**\n * @private\n */\nexport const getEmojiResource = (reactionName: string, reactionResources: ReactionResources): string | undefined => {\n switch (reactionName) {\n case 'like':\n return reactionResources.likeReaction?.url;\n case 'heart':\n return reactionResources.heartReaction?.url;\n case 'laugh':\n return reactionResources.laughReaction?.url;\n case 'applause':\n return reactionResources.applauseReaction?.url;\n case 'surprised':\n return reactionResources.surprisedReaction?.url;\n }\n return undefined;\n};\n\n/**\n * @private\n */\nexport const getEmojiFrameCount = (reactionName: string, reactionResources: ReactionResources): number => {\n switch (reactionName) {\n case 'like':\n return reactionResources.likeReaction?.frameCount ?? 0;\n case 'heart':\n return reactionResources.heartReaction?.frameCount ?? 0;\n case 'laugh':\n return reactionResources.laughReaction?.frameCount ?? 0;\n case 'applause':\n return reactionResources.applauseReaction?.frameCount ?? 0;\n case 'surprised':\n return reactionResources.surprisedReaction?.frameCount ?? 0;\n default:\n return 0;\n }\n};\n"]}
|
@@ -57,6 +57,9 @@ export const VideoTile = (props) => {
|
|
57
57
|
const callingPalette = theme.callingPalette;
|
58
58
|
const isVideoRendered = !!renderElement;
|
59
59
|
const observer = useRef(new ResizeObserver((entries) => {
|
60
|
+
if (!entries[0]) {
|
61
|
+
return;
|
62
|
+
}
|
60
63
|
const { width, height } = entries[0].contentRect;
|
61
64
|
const personaCalcSize = Math.min(width, height) / 3;
|
62
65
|
// we only want to set the persona size if it has changed
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"VideoTile.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/VideoTile.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport {\n DirectionalHint,\n Icon,\n IconButton,\n IContextualMenuProps,\n IStyle,\n mergeStyles,\n Persona,\n Stack,\n Text\n} from '@fluentui/react';\nimport React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { useIdentifiers } from '../identifiers';\nimport { ComponentLocale, useLocale } from '../localization';\nimport { useTheme } from '../theming';\nimport { BaseCustomStyles, CustomAvatarOptions, OnRenderAvatarCallback } from '../types';\nimport { CallingTheme } from '../theming';\nimport { RaisedHand } from '../types';\nimport { RaisedHandIcon } from './assets/RaisedHandIcon';\n\nimport { ParticipantState } from '../types';\nimport {\n disabledVideoHint,\n displayNameStyle,\n iconContainerStyle,\n overlayContainerStyles,\n rootStyles,\n videoContainerStyles,\n tileInfoContainerStyle,\n participantStateStringStyles\n} from './styles/VideoTile.styles';\nimport { pinIconStyle } from './styles/VideoTile.styles';\nimport useLongPress from './utils/useLongPress';\nimport { moreButtonStyles } from './styles/VideoTile.styles';\nimport { raiseHandContainerStyles } from './styles/VideoTile.styles';\nimport { ReactionResources } from '../types/ReactionTypes';\n\n/**\n * Strings of {@link VideoTile} that can be overridden.\n * @public\n */\nexport interface VideoTileStrings {\n /** Aria label for announcing the remote video tile drawer menu */\n moreOptionsButtonAriaLabel: string;\n /** String for displaying the Ringing of the remote participant */\n participantStateRinging: string;\n /** String for displaying the Hold state of the remote participant */\n participantStateHold: string;\n}\n\n/**\n * Fluent styles for {@link VideoTile}.\n *\n * @public\n */\nexport interface VideoTileStylesProps extends BaseCustomStyles {\n /** Styles for video container. */\n videoContainer?: IStyle;\n /** Styles for container overlayed on the video container. */\n overlayContainer?: IStyle;\n /** Styles for displayName on the video container. */\n displayNameContainer?: IStyle;\n}\n\n/**\n * Props for {@link VideoTile}.\n *\n * @public\n */\nexport interface VideoTileProps {\n /** React Child components. Child Components will show as overlay component in the VideoTile. */\n children?: React.ReactNode;\n /**\n * Allows users to pass in an object contains custom CSS styles.\n * @Example\n * ```\n * <VideoTile styles={{ root: { background: 'blue' } }} />\n * ```\n */\n styles?: VideoTileStylesProps;\n /** user id for the VideoTile placeholder. */\n userId?: string;\n /** Component with the video stream. */\n renderElement?: JSX.Element | null;\n /**\n * Overlay component responsible for rendering reaction\n */\n overlay?: JSX.Element | null;\n /** Determines if the video is mirrored or not. */\n isMirrored?: boolean;\n /** Custom render Component function for no video is available. Render a Persona Icon if undefined. */\n onRenderPlaceholder?: OnRenderAvatarCallback;\n /**\n * Show label on the VideoTile\n * @defaultValue true\n */\n showLabel?: boolean;\n /**\n * Show label background on the VideoTile\n * @defaultValue false\n */\n alwaysShowLabelBackground?: boolean;\n /**\n * Whether to display a mute icon beside the user's display name.\n * @defaultValue true\n */\n showMuteIndicator?: boolean;\n /**\n * Whether the video is muted or not.\n */\n isMuted?: boolean;\n /**\n * If true, the video tile will show the pin icon.\n */\n isPinned?: boolean;\n /**\n * Display Name of the Participant to be shown in the label.\n * @remarks `displayName` is used to generate avatar initials if `initialsName` is not provided.\n */\n displayName?: string;\n /**\n * Name of the participant used to generate initials. For example, a name `John Doe` will display `JD` as initials.\n * @remarks `displayName` is used if this property is not specified.\n */\n initialsName?: string;\n /**\n * Minimum size of the persona avatar in px.\n * The persona avatar is the default placeholder shown when no video stream is available.\n * For more information see https://developer.microsoft.com/en-us/fluentui#/controls/web/persona\n * @defaultValue 32px\n */\n personaMinSize?: number;\n /**\n * Maximum size of the personal avatar in px.\n * The persona avatar is the default placeholder shown when no video stream is available.\n * For more information see https://developer.microsoft.com/en-us/fluentui#/controls/web/persona\n * @defaultValue 100px\n */\n personaMaxSize?: number;\n /** Optional property to set the aria label of the video tile if there is no available stream. */\n noVideoAvailableAriaLabel?: string;\n /** Whether the participant in the videoTile is speaking. Shows a speaking indicator (border). */\n isSpeaking?: boolean;\n\n /** Whether the participant is raised hand. Show a indicator (border) and icon with order */\n raisedHand?: RaisedHand;\n\n /**\n * The call connection state of the participant.\n * For example, `Hold` means the participant is on hold.\n */\n participantState?: ParticipantState;\n /**\n * Strings to override in the component.\n */\n strings?: VideoTileStrings;\n /**\n * Display custom menu items in the VideoTile's contextual menu.\n * Uses Fluent UI ContextualMenu.\n * An ellipses icon will be displayed to open the contextual menu if this prop is defined.\n */\n contextualMenu?: IContextualMenuProps;\n /**\n * Callback triggered by video tile on touch and hold.\n */\n onLongTouch?: () => void;\n /**\n * If true, the video tile will show the spotlighted icon.\n */\n isSpotlighted?: boolean;\n /**\n * Reactions resources' url and metadata.\n */\n reactionResources?: ReactionResources;\n}\n\n// Coin max size is set to PersonaSize.size100\nconst DEFAULT_PERSONA_MAX_SIZE_PX = 100;\n// Coin min size is set PersonaSize.size32\nconst DEFAULT_PERSONA_MIN_SIZE_PX = 32;\n\nconst DefaultPlaceholder = (props: CustomAvatarOptions): JSX.Element => {\n const { text, noVideoAvailableAriaLabel, coinSize, hidePersonaDetails } = props;\n\n return (\n <Stack className={mergeStyles({ position: 'absolute', height: '100%', width: '100%' })}>\n <Stack styles={defaultPersonaStyles}>\n {coinSize && (\n <Persona\n coinSize={coinSize}\n hidePersonaDetails={hidePersonaDetails}\n text={text ?? ''}\n initialsTextColor=\"white\"\n aria-label={noVideoAvailableAriaLabel ?? ''}\n showOverflowTooltip={false}\n />\n )}\n </Stack>\n </Stack>\n );\n};\n\nconst defaultPersonaStyles = { root: { margin: 'auto', maxHeight: '100%' } };\n\nconst videoTileMoreMenuIconProps = { iconName: undefined, style: { display: 'none' } };\nconst videoTileMoreMenuProps = {\n directionalHint: DirectionalHint.topLeftEdge,\n isBeakVisible: false,\n styles: { container: { maxWidth: '8rem' } }\n};\nconst VideoTileMoreOptionsButton = (props: {\n contextualMenu?: IContextualMenuProps;\n canShowContextMenuButton: boolean;\n}): JSX.Element => {\n const locale = useLocale();\n const theme = useTheme();\n const strings = { ...locale.strings.videoTile };\n\n const { contextualMenu, canShowContextMenuButton } = props;\n if (!contextualMenu) {\n return <></>;\n }\n\n const optionsIcon = canShowContextMenuButton ? 'VideoTileMoreOptions' : undefined;\n\n return (\n <IconButton\n data-ui-id=\"video-tile-more-options-button\"\n ariaLabel={strings?.moreOptionsButtonAriaLabel}\n styles={moreButtonStyles(theme)}\n menuIconProps={videoTileMoreMenuIconProps}\n menuProps={{ ...videoTileMoreMenuProps, ...contextualMenu }}\n iconProps={{ iconName: optionsIcon }}\n />\n );\n};\n\n/**\n * A component to render the video stream for a single call participant.\n *\n * Use with {@link GridLayout} in a {@link VideoGallery}.\n *\n * @public\n */\nexport const VideoTile = (props: VideoTileProps): JSX.Element => {\n const {\n children,\n displayName,\n initialsName,\n isMirrored,\n isMuted,\n isSpotlighted,\n isPinned,\n onRenderPlaceholder,\n renderElement,\n overlay: reactionOverlay,\n showLabel = true,\n showMuteIndicator = true,\n styles,\n userId,\n noVideoAvailableAriaLabel,\n isSpeaking,\n raisedHand,\n personaMinSize = DEFAULT_PERSONA_MIN_SIZE_PX,\n personaMaxSize = DEFAULT_PERSONA_MAX_SIZE_PX,\n contextualMenu\n } = props;\n\n const [isHovered, setIsHovered] = useState<boolean>(false);\n const [isFocused, setIsFocused] = useState<boolean>(false);\n // need to set a default otherwise the resizeObserver will get stuck in an infinite loop.\n const [personaSize, setPersonaSize] = useState<number>(1);\n\n const videoTileRef = useRef<HTMLDivElement>(null);\n\n const locale = useLocale();\n const theme = useTheme();\n const callingPalette = (theme as unknown as CallingTheme).callingPalette;\n\n const isVideoRendered = !!renderElement;\n\n const observer = useRef(\n new ResizeObserver((entries): void => {\n const { width, height } = entries[0].contentRect;\n const personaCalcSize = Math.min(width, height) / 3;\n // we only want to set the persona size if it has changed\n if (personaCalcSize !== personaSize) {\n setPersonaSize(Math.max(Math.min(personaCalcSize, personaMaxSize), personaMinSize));\n }\n })\n );\n\n useLayoutEffect(() => {\n if (videoTileRef.current) {\n observer.current.observe(videoTileRef.current);\n }\n const currentObserver = observer.current;\n return () => currentObserver.disconnect();\n }, [videoTileRef]);\n\n // TODO: Remove after calling sdk fix the keybaord focus\n useEffect(() => {\n // PPTLive stream id is null\n if (videoTileRef.current?.id) {\n return;\n }\n let observer: MutationObserver | undefined;\n if (videoTileRef.current) {\n observer = new MutationObserver((mutationsList) => {\n for (const mutation of mutationsList) {\n if (mutation.type === 'childList') {\n const iframe = document.querySelector('iframe');\n if (iframe) {\n if (!iframe.getAttribute('tabIndex')) {\n iframe.setAttribute('tabIndex', '-1');\n }\n }\n }\n }\n });\n\n observer.observe(videoTileRef.current, { childList: true, subtree: true });\n }\n\n return () => {\n observer?.disconnect();\n };\n }, [displayName, renderElement]);\n\n const useLongPressProps = useMemo(() => {\n return {\n onLongPress: () => {\n props.onLongTouch?.();\n },\n touchEventsOnly: true\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [props.onLongTouch]);\n const longPressHandlers = useLongPress(useLongPressProps);\n\n const hoverHandlers = useMemo(() => {\n return {\n onMouseEnter: () => setIsHovered(true),\n onMouseLeave: () => setIsHovered(false),\n onFocus: () => setIsFocused(true),\n onBlur: () => setIsFocused(false)\n };\n }, []);\n\n const placeholderOptions = {\n userId,\n text: initialsName ?? displayName,\n noVideoAvailableAriaLabel,\n coinSize: personaSize,\n styles: defaultPersonaStyles,\n hidePersonaDetails: true\n };\n\n const videoHintWithBorderRadius = mergeStyles(disabledVideoHint, {\n borderRadius: theme.effects.roundedCorner4,\n backgroundColor: callingPalette.videoTileLabelBackgroundLight\n });\n\n const tileInfoStyle = useMemo(\n () =>\n mergeStyles(\n isVideoRendered || props.alwaysShowLabelBackground ? videoHintWithBorderRadius : disabledVideoHint,\n styles?.displayNameContainer\n ),\n [isVideoRendered, videoHintWithBorderRadius, styles?.displayNameContainer, props.alwaysShowLabelBackground]\n );\n\n const ids = useIdentifiers();\n\n const canShowLabel = showLabel && (displayName || (showMuteIndicator && isMuted));\n const participantStateString = getParticipantStateString(props, locale);\n const canShowContextMenuButton = isHovered || isFocused;\n let raisedHandBackgroundColor = '';\n raisedHandBackgroundColor = callingPalette.raiseHandGold;\n\n return (\n <Stack\n data-ui-id={ids.videoTile}\n className={mergeStyles(\n rootStyles,\n {\n background: theme.palette.neutralLighter,\n borderRadius: theme.effects.roundedCorner4\n },\n (isSpeaking || raisedHand) && {\n '&::after': {\n content: `''`,\n position: 'absolute',\n border: `0.25rem solid ${isSpeaking ? theme.palette.themePrimary : raisedHandBackgroundColor}`,\n borderRadius: theme.effects.roundedCorner4,\n width: '100%',\n height: '100%',\n pointerEvents: 'none'\n }\n },\n styles?.root\n )}\n {...longPressHandlers}\n >\n <div ref={videoTileRef} style={{ width: '100%', height: '100%' }} {...hoverHandlers} data-is-focusable={true}>\n {isVideoRendered ? (\n <Stack\n className={mergeStyles(\n videoContainerStyles,\n isMirrored && { transform: 'scaleX(-1)' },\n styles?.videoContainer\n )}\n >\n {renderElement}\n </Stack>\n ) : (\n <Stack\n className={mergeStyles(videoContainerStyles, {\n opacity: participantStateString || props.participantState === 'Idle' ? 0.4 : 1\n })}\n >\n {onRenderPlaceholder ? (\n onRenderPlaceholder(userId ?? '', placeholderOptions, DefaultPlaceholder)\n ) : (\n <DefaultPlaceholder {...placeholderOptions} />\n )}\n </Stack>\n )}\n {reactionOverlay}\n {(canShowLabel || participantStateString) && (\n <Stack horizontal className={tileInfoContainerStyle} tokens={tileInfoContainerTokens}>\n <Stack horizontal className={tileInfoStyle}>\n {canShowLabel && (\n <Text\n className={mergeStyles(displayNameStyle)}\n title={displayName}\n style={{ color: participantStateString ? theme.palette.neutralSecondary : 'inherit' }}\n data-ui-id=\"video-tile-display-name\"\n >\n {displayName}\n </Text>\n )}\n {participantStateString && (\n <Text className={mergeStyles(participantStateStringStyles(theme))}>\n {bracketedParticipantString(participantStateString, !!canShowLabel)}\n </Text>\n )}\n {showMuteIndicator && isMuted && (\n <Stack className={mergeStyles(iconContainerStyle)}>\n <Icon iconName=\"VideoTileMicOff\" />\n </Stack>\n )}\n {isSpotlighted && (\n <Stack className={mergeStyles(iconContainerStyle)}>\n <Icon iconName=\"VideoTileSpotlighted\" />\n </Stack>\n )}\n {isPinned && (\n <Stack className={mergeStyles(iconContainerStyle)}>\n <Icon iconName=\"VideoTilePinned\" className={mergeStyles(pinIconStyle)} />\n </Stack>\n )}\n <VideoTileMoreOptionsButton\n contextualMenu={contextualMenu}\n canShowContextMenuButton={canShowContextMenuButton}\n />\n </Stack>\n </Stack>\n )}\n\n {children && (\n <Stack className={mergeStyles(overlayContainerStyles, styles?.overlayContainer)}>{children}</Stack>\n )}\n {raisedHand && (\n <Stack\n horizontal={true}\n tokens={{ childrenGap: '0.2rem' }}\n className={raiseHandContainerStyles(theme, !canShowLabel)}\n >\n <Stack.Item>\n <Text>{raisedHand.raisedHandOrderPosition}</Text>\n </Stack.Item>\n <Stack.Item>\n <RaisedHandIcon />\n </Stack.Item>\n </Stack>\n )}\n </div>\n </Stack>\n );\n};\n\nconst getParticipantStateString = (props: VideoTileProps, locale: ComponentLocale): string | undefined => {\n const strings = { ...locale.strings.videoTile, ...props.strings };\n return props.participantState === 'EarlyMedia' || props.participantState === 'Ringing'\n ? strings?.participantStateRinging\n : props.participantState === 'Hold'\n ? strings?.participantStateHold\n : undefined;\n};\n\nconst tileInfoContainerTokens = {\n // A horizontal Stack sets the left margin to 0 for all it's children.\n // We need to allow the children to set their own margins\n childrenGap: 'none'\n};\n\nconst bracketedParticipantString = (participantString: string, withBrackets: boolean): string => {\n return withBrackets ? `(${participantString})` : participantString;\n};\n"]}
|
1
|
+
{"version":3,"file":"VideoTile.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/VideoTile.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EACL,eAAe,EACf,IAAI,EACJ,UAAU,EAGV,WAAW,EACX,OAAO,EACP,KAAK,EACL,IAAI,EACL,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAmB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAItC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGzD,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,UAAU,EACV,oBAAoB,EACpB,sBAAsB,EACtB,4BAA4B,EAC7B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,YAAY,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AA8IrE,8CAA8C;AAC9C,MAAM,2BAA2B,GAAG,GAAG,CAAC;AACxC,0CAA0C;AAC1C,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAEvC,MAAM,kBAAkB,GAAG,CAAC,KAA0B,EAAe,EAAE;IACrE,MAAM,EAAE,IAAI,EAAE,yBAAyB,EAAE,QAAQ,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAC;IAEhF,OAAO,CACL,oBAAC,KAAK,IAAC,SAAS,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QACpF,oBAAC,KAAK,IAAC,MAAM,EAAE,oBAAoB,IAChC,QAAQ,IAAI,CACX,oBAAC,OAAO,IACN,QAAQ,EAAE,QAAQ,EAClB,kBAAkB,EAAE,kBAAkB,EACtC,IAAI,EAAE,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,EAChB,iBAAiB,EAAC,OAAO,gBACb,yBAAyB,aAAzB,yBAAyB,cAAzB,yBAAyB,GAAI,EAAE,EAC3C,mBAAmB,EAAE,KAAK,GAC1B,CACH,CACK,CACF,CACT,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;AAE7E,MAAM,0BAA0B,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;AACvF,MAAM,sBAAsB,GAAG;IAC7B,eAAe,EAAE,eAAe,CAAC,WAAW;IAC5C,aAAa,EAAE,KAAK;IACpB,MAAM,EAAE,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;CAC5C,CAAC;AACF,MAAM,0BAA0B,GAAG,CAAC,KAGnC,EAAe,EAAE;IAChB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,OAAO,qBAAQ,MAAM,CAAC,OAAO,CAAC,SAAS,CAAE,CAAC;IAEhD,MAAM,EAAE,cAAc,EAAE,wBAAwB,EAAE,GAAG,KAAK,CAAC;IAC3D,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,yCAAK,CAAC;IACf,CAAC;IAED,MAAM,WAAW,GAAG,wBAAwB,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,SAAS,CAAC;IAElF,OAAO,CACL,oBAAC,UAAU,kBACE,gCAAgC,EAC3C,SAAS,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,0BAA0B,EAC9C,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAC/B,aAAa,EAAE,0BAA0B,EACzC,SAAS,kCAAO,sBAAsB,GAAK,cAAc,GACzD,SAAS,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,GACpC,CACH,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAqB,EAAe,EAAE;IAC9D,MAAM,EACJ,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,UAAU,EACV,OAAO,EACP,aAAa,EACb,QAAQ,EACR,mBAAmB,EACnB,aAAa,EACb,OAAO,EAAE,eAAe,EACxB,SAAS,GAAG,IAAI,EAChB,iBAAiB,GAAG,IAAI,EACxB,MAAM,EACN,MAAM,EACN,yBAAyB,EACzB,UAAU,EACV,UAAU,EACV,cAAc,GAAG,2BAA2B,EAC5C,cAAc,GAAG,2BAA2B,EAC5C,cAAc,EACf,GAAG,KAAK,CAAC;IAEV,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAC3D,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAC3D,yFAAyF;IACzF,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAS,CAAC,CAAC,CAAC;IAE1D,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAElD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,cAAc,GAAI,KAAiC,CAAC,cAAc,CAAC;IAEzE,MAAM,eAAe,GAAG,CAAC,CAAC,aAAa,CAAC;IAExC,MAAM,QAAQ,GAAG,MAAM,CACrB,IAAI,cAAc,CAAC,CAAC,OAAO,EAAQ,EAAE;QACnC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;QACjD,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACpD,yDAAyD;QACzD,IAAI,eAAe,KAAK,WAAW,EAAE,CAAC;YACpC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,cAAc,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;QACtF,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,eAAe,CAAC,GAAG,EAAE;QACnB,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;YACzB,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC;QACzC,OAAO,GAAG,EAAE,CAAC,eAAe,CAAC,UAAU,EAAE,CAAC;IAC5C,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,wDAAwD;IACxD,SAAS,CAAC,GAAG,EAAE;;QACb,4BAA4B;QAC5B,IAAI,MAAA,YAAY,CAAC,OAAO,0CAAE,EAAE,EAAE,CAAC;YAC7B,OAAO;QACT,CAAC;QACD,IAAI,QAAsC,CAAC;QAC3C,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;YACzB,QAAQ,GAAG,IAAI,gBAAgB,CAAC,CAAC,aAAa,EAAE,EAAE;gBAChD,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;oBACrC,IAAI,QAAQ,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;wBAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;wBAChD,IAAI,MAAM,EAAE,CAAC;4BACX,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC;gCACrC,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;4BACxC,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,QAAQ,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7E,CAAC;QAED,OAAO,GAAG,EAAE;YACV,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,UAAU,EAAE,CAAC;QACzB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;IAEjC,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,EAAE;QACrC,OAAO;YACL,WAAW,EAAE,GAAG,EAAE;;gBAChB,MAAA,KAAK,CAAC,WAAW,qDAAI,CAAC;YACxB,CAAC;YACD,eAAe,EAAE,IAAI;SACtB,CAAC;QACF,uDAAuD;IACzD,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IACxB,MAAM,iBAAiB,GAAG,YAAY,CAAC,iBAAiB,CAAC,CAAC;IAE1D,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,EAAE;QACjC,OAAO;YACL,YAAY,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;YACtC,YAAY,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC;YACvC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC;YACjC,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC;SAClC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,kBAAkB,GAAG;QACzB,MAAM;QACN,IAAI,EAAE,YAAY,aAAZ,YAAY,cAAZ,YAAY,GAAI,WAAW;QACjC,yBAAyB;QACzB,QAAQ,EAAE,WAAW;QACrB,MAAM,EAAE,oBAAoB;QAC5B,kBAAkB,EAAE,IAAI;KACzB,CAAC;IAEF,MAAM,yBAAyB,GAAG,WAAW,CAAC,iBAAiB,EAAE;QAC/D,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,cAAc;QAC1C,eAAe,EAAE,cAAc,CAAC,6BAA6B;KAC9D,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,OAAO,CAC3B,GAAG,EAAE,CACH,WAAW,CACT,eAAe,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,iBAAiB,EAClG,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,oBAAoB,CAC7B,EACH,CAAC,eAAe,EAAE,yBAAyB,EAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,oBAAoB,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAC5G,CAAC;IAEF,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAE7B,MAAM,YAAY,GAAG,SAAS,IAAI,CAAC,WAAW,IAAI,CAAC,iBAAiB,IAAI,OAAO,CAAC,CAAC,CAAC;IAClF,MAAM,sBAAsB,GAAG,yBAAyB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxE,MAAM,wBAAwB,GAAG,SAAS,IAAI,SAAS,CAAC;IACxD,IAAI,yBAAyB,GAAG,EAAE,CAAC;IACnC,yBAAyB,GAAG,cAAc,CAAC,aAAa,CAAC;IAEzD,OAAO,CACL,oBAAC,KAAK,gCACQ,GAAG,CAAC,SAAS,EACzB,SAAS,EAAE,WAAW,CACpB,UAAU,EACV;YACE,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,cAAc;YACxC,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,cAAc;SAC3C,EACD,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI;YAC5B,UAAU,EAAE;gBACV,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,UAAU;gBACpB,MAAM,EAAE,iBAAiB,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,yBAAyB,EAAE;gBAC9F,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,cAAc;gBAC1C,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,MAAM;gBACd,aAAa,EAAE,MAAM;aACtB;SACF,EACD,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,IAAI,CACb,IACG,iBAAiB;QAErB,2CAAK,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAM,aAAa,yBAAqB,IAAI;YACzG,eAAe,CAAC,CAAC,CAAC,CACjB,oBAAC,KAAK,IACJ,SAAS,EAAE,WAAW,CACpB,oBAAoB,EACpB,UAAU,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,EACzC,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,cAAc,CACvB,IAEA,aAAa,CACR,CACT,CAAC,CAAC,CAAC,CACF,oBAAC,KAAK,IACJ,SAAS,EAAE,WAAW,CAAC,oBAAoB,EAAE;oBAC3C,OAAO,EAAE,sBAAsB,IAAI,KAAK,CAAC,gBAAgB,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;iBAC/E,CAAC,IAED,mBAAmB,CAAC,CAAC,CAAC,CACrB,mBAAmB,CAAC,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE,EAAE,kBAAkB,EAAE,kBAAkB,CAAC,CAC1E,CAAC,CAAC,CAAC,CACF,oBAAC,kBAAkB,oBAAK,kBAAkB,EAAI,CAC/C,CACK,CACT;YACA,eAAe;YACf,CAAC,YAAY,IAAI,sBAAsB,CAAC,IAAI,CAC3C,oBAAC,KAAK,IAAC,UAAU,QAAC,SAAS,EAAE,sBAAsB,EAAE,MAAM,EAAE,uBAAuB;gBAClF,oBAAC,KAAK,IAAC,UAAU,QAAC,SAAS,EAAE,aAAa;oBACvC,YAAY,IAAI,CACf,oBAAC,IAAI,IACH,SAAS,EAAE,WAAW,CAAC,gBAAgB,CAAC,EACxC,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,EAAE,KAAK,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,EAAE,gBAC1E,yBAAyB,IAEnC,WAAW,CACP,CACR;oBACA,sBAAsB,IAAI,CACzB,oBAAC,IAAI,IAAC,SAAS,EAAE,WAAW,CAAC,4BAA4B,CAAC,KAAK,CAAC,CAAC,IAC9D,0BAA0B,CAAC,sBAAsB,EAAE,CAAC,CAAC,YAAY,CAAC,CAC9D,CACR;oBACA,iBAAiB,IAAI,OAAO,IAAI,CAC/B,oBAAC,KAAK,IAAC,SAAS,EAAE,WAAW,CAAC,kBAAkB,CAAC;wBAC/C,oBAAC,IAAI,IAAC,QAAQ,EAAC,iBAAiB,GAAG,CAC7B,CACT;oBACA,aAAa,IAAI,CAChB,oBAAC,KAAK,IAAC,SAAS,EAAE,WAAW,CAAC,kBAAkB,CAAC;wBAC/C,oBAAC,IAAI,IAAC,QAAQ,EAAC,sBAAsB,GAAG,CAClC,CACT;oBACA,QAAQ,IAAI,CACX,oBAAC,KAAK,IAAC,SAAS,EAAE,WAAW,CAAC,kBAAkB,CAAC;wBAC/C,oBAAC,IAAI,IAAC,QAAQ,EAAC,iBAAiB,EAAC,SAAS,EAAE,WAAW,CAAC,YAAY,CAAC,GAAI,CACnE,CACT;oBACD,oBAAC,0BAA0B,IACzB,cAAc,EAAE,cAAc,EAC9B,wBAAwB,EAAE,wBAAwB,GAClD,CACI,CACF,CACT;YAEA,QAAQ,IAAI,CACX,oBAAC,KAAK,IAAC,SAAS,EAAE,WAAW,CAAC,sBAAsB,EAAE,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,gBAAgB,CAAC,IAAG,QAAQ,CAAS,CACpG;YACA,UAAU,IAAI,CACb,oBAAC,KAAK,IACJ,UAAU,EAAE,IAAI,EAChB,MAAM,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,EACjC,SAAS,EAAE,wBAAwB,CAAC,KAAK,EAAE,CAAC,YAAY,CAAC;gBAEzD,oBAAC,KAAK,CAAC,IAAI;oBACT,oBAAC,IAAI,QAAE,UAAU,CAAC,uBAAuB,CAAQ,CACtC;gBACb,oBAAC,KAAK,CAAC,IAAI;oBACT,oBAAC,cAAc,OAAG,CACP,CACP,CACT,CACG,CACA,CACT,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CAAC,KAAqB,EAAE,MAAuB,EAAsB,EAAE;IACvG,MAAM,OAAO,mCAAQ,MAAM,CAAC,OAAO,CAAC,SAAS,GAAK,KAAK,CAAC,OAAO,CAAE,CAAC;IAClE,OAAO,KAAK,CAAC,gBAAgB,KAAK,YAAY,IAAI,KAAK,CAAC,gBAAgB,KAAK,SAAS;QACpF,CAAC,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,uBAAuB;QAClC,CAAC,CAAC,KAAK,CAAC,gBAAgB,KAAK,MAAM;YACjC,CAAC,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,oBAAoB;YAC/B,CAAC,CAAC,SAAS,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAG;IAC9B,sEAAsE;IACtE,yDAAyD;IACzD,WAAW,EAAE,MAAM;CACpB,CAAC;AAEF,MAAM,0BAA0B,GAAG,CAAC,iBAAyB,EAAE,YAAqB,EAAU,EAAE;IAC9F,OAAO,YAAY,CAAC,CAAC,CAAC,IAAI,iBAAiB,GAAG,CAAC,CAAC,CAAC,iBAAiB,CAAC;AACrE,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport {\n DirectionalHint,\n Icon,\n IconButton,\n IContextualMenuProps,\n IStyle,\n mergeStyles,\n Persona,\n Stack,\n Text\n} from '@fluentui/react';\nimport React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { useIdentifiers } from '../identifiers';\nimport { ComponentLocale, useLocale } from '../localization';\nimport { useTheme } from '../theming';\nimport { BaseCustomStyles, CustomAvatarOptions, OnRenderAvatarCallback } from '../types';\nimport { CallingTheme } from '../theming';\nimport { RaisedHand } from '../types';\nimport { RaisedHandIcon } from './assets/RaisedHandIcon';\n\nimport { ParticipantState } from '../types';\nimport {\n disabledVideoHint,\n displayNameStyle,\n iconContainerStyle,\n overlayContainerStyles,\n rootStyles,\n videoContainerStyles,\n tileInfoContainerStyle,\n participantStateStringStyles\n} from './styles/VideoTile.styles';\nimport { pinIconStyle } from './styles/VideoTile.styles';\nimport useLongPress from './utils/useLongPress';\nimport { moreButtonStyles } from './styles/VideoTile.styles';\nimport { raiseHandContainerStyles } from './styles/VideoTile.styles';\nimport { ReactionResources } from '../types/ReactionTypes';\n\n/**\n * Strings of {@link VideoTile} that can be overridden.\n * @public\n */\nexport interface VideoTileStrings {\n /** Aria label for announcing the remote video tile drawer menu */\n moreOptionsButtonAriaLabel: string;\n /** String for displaying the Ringing of the remote participant */\n participantStateRinging: string;\n /** String for displaying the Hold state of the remote participant */\n participantStateHold: string;\n}\n\n/**\n * Fluent styles for {@link VideoTile}.\n *\n * @public\n */\nexport interface VideoTileStylesProps extends BaseCustomStyles {\n /** Styles for video container. */\n videoContainer?: IStyle;\n /** Styles for container overlayed on the video container. */\n overlayContainer?: IStyle;\n /** Styles for displayName on the video container. */\n displayNameContainer?: IStyle;\n}\n\n/**\n * Props for {@link VideoTile}.\n *\n * @public\n */\nexport interface VideoTileProps {\n /** React Child components. Child Components will show as overlay component in the VideoTile. */\n children?: React.ReactNode;\n /**\n * Allows users to pass in an object contains custom CSS styles.\n * @Example\n * ```\n * <VideoTile styles={{ root: { background: 'blue' } }} />\n * ```\n */\n styles?: VideoTileStylesProps;\n /** user id for the VideoTile placeholder. */\n userId?: string;\n /** Component with the video stream. */\n renderElement?: JSX.Element | null;\n /**\n * Overlay component responsible for rendering reaction\n */\n overlay?: JSX.Element | null;\n /** Determines if the video is mirrored or not. */\n isMirrored?: boolean;\n /** Custom render Component function for no video is available. Render a Persona Icon if undefined. */\n onRenderPlaceholder?: OnRenderAvatarCallback;\n /**\n * Show label on the VideoTile\n * @defaultValue true\n */\n showLabel?: boolean;\n /**\n * Show label background on the VideoTile\n * @defaultValue false\n */\n alwaysShowLabelBackground?: boolean;\n /**\n * Whether to display a mute icon beside the user's display name.\n * @defaultValue true\n */\n showMuteIndicator?: boolean;\n /**\n * Whether the video is muted or not.\n */\n isMuted?: boolean;\n /**\n * If true, the video tile will show the pin icon.\n */\n isPinned?: boolean;\n /**\n * Display Name of the Participant to be shown in the label.\n * @remarks `displayName` is used to generate avatar initials if `initialsName` is not provided.\n */\n displayName?: string;\n /**\n * Name of the participant used to generate initials. For example, a name `John Doe` will display `JD` as initials.\n * @remarks `displayName` is used if this property is not specified.\n */\n initialsName?: string;\n /**\n * Minimum size of the persona avatar in px.\n * The persona avatar is the default placeholder shown when no video stream is available.\n * For more information see https://developer.microsoft.com/en-us/fluentui#/controls/web/persona\n * @defaultValue 32px\n */\n personaMinSize?: number;\n /**\n * Maximum size of the personal avatar in px.\n * The persona avatar is the default placeholder shown when no video stream is available.\n * For more information see https://developer.microsoft.com/en-us/fluentui#/controls/web/persona\n * @defaultValue 100px\n */\n personaMaxSize?: number;\n /** Optional property to set the aria label of the video tile if there is no available stream. */\n noVideoAvailableAriaLabel?: string;\n /** Whether the participant in the videoTile is speaking. Shows a speaking indicator (border). */\n isSpeaking?: boolean;\n\n /** Whether the participant is raised hand. Show a indicator (border) and icon with order */\n raisedHand?: RaisedHand;\n\n /**\n * The call connection state of the participant.\n * For example, `Hold` means the participant is on hold.\n */\n participantState?: ParticipantState;\n /**\n * Strings to override in the component.\n */\n strings?: VideoTileStrings;\n /**\n * Display custom menu items in the VideoTile's contextual menu.\n * Uses Fluent UI ContextualMenu.\n * An ellipses icon will be displayed to open the contextual menu if this prop is defined.\n */\n contextualMenu?: IContextualMenuProps;\n /**\n * Callback triggered by video tile on touch and hold.\n */\n onLongTouch?: () => void;\n /**\n * If true, the video tile will show the spotlighted icon.\n */\n isSpotlighted?: boolean;\n /**\n * Reactions resources' url and metadata.\n */\n reactionResources?: ReactionResources;\n}\n\n// Coin max size is set to PersonaSize.size100\nconst DEFAULT_PERSONA_MAX_SIZE_PX = 100;\n// Coin min size is set PersonaSize.size32\nconst DEFAULT_PERSONA_MIN_SIZE_PX = 32;\n\nconst DefaultPlaceholder = (props: CustomAvatarOptions): JSX.Element => {\n const { text, noVideoAvailableAriaLabel, coinSize, hidePersonaDetails } = props;\n\n return (\n <Stack className={mergeStyles({ position: 'absolute', height: '100%', width: '100%' })}>\n <Stack styles={defaultPersonaStyles}>\n {coinSize && (\n <Persona\n coinSize={coinSize}\n hidePersonaDetails={hidePersonaDetails}\n text={text ?? ''}\n initialsTextColor=\"white\"\n aria-label={noVideoAvailableAriaLabel ?? ''}\n showOverflowTooltip={false}\n />\n )}\n </Stack>\n </Stack>\n );\n};\n\nconst defaultPersonaStyles = { root: { margin: 'auto', maxHeight: '100%' } };\n\nconst videoTileMoreMenuIconProps = { iconName: undefined, style: { display: 'none' } };\nconst videoTileMoreMenuProps = {\n directionalHint: DirectionalHint.topLeftEdge,\n isBeakVisible: false,\n styles: { container: { maxWidth: '8rem' } }\n};\nconst VideoTileMoreOptionsButton = (props: {\n contextualMenu?: IContextualMenuProps;\n canShowContextMenuButton: boolean;\n}): JSX.Element => {\n const locale = useLocale();\n const theme = useTheme();\n const strings = { ...locale.strings.videoTile };\n\n const { contextualMenu, canShowContextMenuButton } = props;\n if (!contextualMenu) {\n return <></>;\n }\n\n const optionsIcon = canShowContextMenuButton ? 'VideoTileMoreOptions' : undefined;\n\n return (\n <IconButton\n data-ui-id=\"video-tile-more-options-button\"\n ariaLabel={strings?.moreOptionsButtonAriaLabel}\n styles={moreButtonStyles(theme)}\n menuIconProps={videoTileMoreMenuIconProps}\n menuProps={{ ...videoTileMoreMenuProps, ...contextualMenu }}\n iconProps={{ iconName: optionsIcon }}\n />\n );\n};\n\n/**\n * A component to render the video stream for a single call participant.\n *\n * Use with {@link GridLayout} in a {@link VideoGallery}.\n *\n * @public\n */\nexport const VideoTile = (props: VideoTileProps): JSX.Element => {\n const {\n children,\n displayName,\n initialsName,\n isMirrored,\n isMuted,\n isSpotlighted,\n isPinned,\n onRenderPlaceholder,\n renderElement,\n overlay: reactionOverlay,\n showLabel = true,\n showMuteIndicator = true,\n styles,\n userId,\n noVideoAvailableAriaLabel,\n isSpeaking,\n raisedHand,\n personaMinSize = DEFAULT_PERSONA_MIN_SIZE_PX,\n personaMaxSize = DEFAULT_PERSONA_MAX_SIZE_PX,\n contextualMenu\n } = props;\n\n const [isHovered, setIsHovered] = useState<boolean>(false);\n const [isFocused, setIsFocused] = useState<boolean>(false);\n // need to set a default otherwise the resizeObserver will get stuck in an infinite loop.\n const [personaSize, setPersonaSize] = useState<number>(1);\n\n const videoTileRef = useRef<HTMLDivElement>(null);\n\n const locale = useLocale();\n const theme = useTheme();\n const callingPalette = (theme as unknown as CallingTheme).callingPalette;\n\n const isVideoRendered = !!renderElement;\n\n const observer = useRef(\n new ResizeObserver((entries): void => {\n if (!entries[0]) {\n return;\n }\n const { width, height } = entries[0].contentRect;\n const personaCalcSize = Math.min(width, height) / 3;\n // we only want to set the persona size if it has changed\n if (personaCalcSize !== personaSize) {\n setPersonaSize(Math.max(Math.min(personaCalcSize, personaMaxSize), personaMinSize));\n }\n })\n );\n\n useLayoutEffect(() => {\n if (videoTileRef.current) {\n observer.current.observe(videoTileRef.current);\n }\n const currentObserver = observer.current;\n return () => currentObserver.disconnect();\n }, [videoTileRef]);\n\n // TODO: Remove after calling sdk fix the keybaord focus\n useEffect(() => {\n // PPTLive stream id is null\n if (videoTileRef.current?.id) {\n return;\n }\n let observer: MutationObserver | undefined;\n if (videoTileRef.current) {\n observer = new MutationObserver((mutationsList) => {\n for (const mutation of mutationsList) {\n if (mutation.type === 'childList') {\n const iframe = document.querySelector('iframe');\n if (iframe) {\n if (!iframe.getAttribute('tabIndex')) {\n iframe.setAttribute('tabIndex', '-1');\n }\n }\n }\n }\n });\n\n observer.observe(videoTileRef.current, { childList: true, subtree: true });\n }\n\n return () => {\n observer?.disconnect();\n };\n }, [displayName, renderElement]);\n\n const useLongPressProps = useMemo(() => {\n return {\n onLongPress: () => {\n props.onLongTouch?.();\n },\n touchEventsOnly: true\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [props.onLongTouch]);\n const longPressHandlers = useLongPress(useLongPressProps);\n\n const hoverHandlers = useMemo(() => {\n return {\n onMouseEnter: () => setIsHovered(true),\n onMouseLeave: () => setIsHovered(false),\n onFocus: () => setIsFocused(true),\n onBlur: () => setIsFocused(false)\n };\n }, []);\n\n const placeholderOptions = {\n userId,\n text: initialsName ?? displayName,\n noVideoAvailableAriaLabel,\n coinSize: personaSize,\n styles: defaultPersonaStyles,\n hidePersonaDetails: true\n };\n\n const videoHintWithBorderRadius = mergeStyles(disabledVideoHint, {\n borderRadius: theme.effects.roundedCorner4,\n backgroundColor: callingPalette.videoTileLabelBackgroundLight\n });\n\n const tileInfoStyle = useMemo(\n () =>\n mergeStyles(\n isVideoRendered || props.alwaysShowLabelBackground ? videoHintWithBorderRadius : disabledVideoHint,\n styles?.displayNameContainer\n ),\n [isVideoRendered, videoHintWithBorderRadius, styles?.displayNameContainer, props.alwaysShowLabelBackground]\n );\n\n const ids = useIdentifiers();\n\n const canShowLabel = showLabel && (displayName || (showMuteIndicator && isMuted));\n const participantStateString = getParticipantStateString(props, locale);\n const canShowContextMenuButton = isHovered || isFocused;\n let raisedHandBackgroundColor = '';\n raisedHandBackgroundColor = callingPalette.raiseHandGold;\n\n return (\n <Stack\n data-ui-id={ids.videoTile}\n className={mergeStyles(\n rootStyles,\n {\n background: theme.palette.neutralLighter,\n borderRadius: theme.effects.roundedCorner4\n },\n (isSpeaking || raisedHand) && {\n '&::after': {\n content: `''`,\n position: 'absolute',\n border: `0.25rem solid ${isSpeaking ? theme.palette.themePrimary : raisedHandBackgroundColor}`,\n borderRadius: theme.effects.roundedCorner4,\n width: '100%',\n height: '100%',\n pointerEvents: 'none'\n }\n },\n styles?.root\n )}\n {...longPressHandlers}\n >\n <div ref={videoTileRef} style={{ width: '100%', height: '100%' }} {...hoverHandlers} data-is-focusable={true}>\n {isVideoRendered ? (\n <Stack\n className={mergeStyles(\n videoContainerStyles,\n isMirrored && { transform: 'scaleX(-1)' },\n styles?.videoContainer\n )}\n >\n {renderElement}\n </Stack>\n ) : (\n <Stack\n className={mergeStyles(videoContainerStyles, {\n opacity: participantStateString || props.participantState === 'Idle' ? 0.4 : 1\n })}\n >\n {onRenderPlaceholder ? (\n onRenderPlaceholder(userId ?? '', placeholderOptions, DefaultPlaceholder)\n ) : (\n <DefaultPlaceholder {...placeholderOptions} />\n )}\n </Stack>\n )}\n {reactionOverlay}\n {(canShowLabel || participantStateString) && (\n <Stack horizontal className={tileInfoContainerStyle} tokens={tileInfoContainerTokens}>\n <Stack horizontal className={tileInfoStyle}>\n {canShowLabel && (\n <Text\n className={mergeStyles(displayNameStyle)}\n title={displayName}\n style={{ color: participantStateString ? theme.palette.neutralSecondary : 'inherit' }}\n data-ui-id=\"video-tile-display-name\"\n >\n {displayName}\n </Text>\n )}\n {participantStateString && (\n <Text className={mergeStyles(participantStateStringStyles(theme))}>\n {bracketedParticipantString(participantStateString, !!canShowLabel)}\n </Text>\n )}\n {showMuteIndicator && isMuted && (\n <Stack className={mergeStyles(iconContainerStyle)}>\n <Icon iconName=\"VideoTileMicOff\" />\n </Stack>\n )}\n {isSpotlighted && (\n <Stack className={mergeStyles(iconContainerStyle)}>\n <Icon iconName=\"VideoTileSpotlighted\" />\n </Stack>\n )}\n {isPinned && (\n <Stack className={mergeStyles(iconContainerStyle)}>\n <Icon iconName=\"VideoTilePinned\" className={mergeStyles(pinIconStyle)} />\n </Stack>\n )}\n <VideoTileMoreOptionsButton\n contextualMenu={contextualMenu}\n canShowContextMenuButton={canShowContextMenuButton}\n />\n </Stack>\n </Stack>\n )}\n\n {children && (\n <Stack className={mergeStyles(overlayContainerStyles, styles?.overlayContainer)}>{children}</Stack>\n )}\n {raisedHand && (\n <Stack\n horizontal={true}\n tokens={{ childrenGap: '0.2rem' }}\n className={raiseHandContainerStyles(theme, !canShowLabel)}\n >\n <Stack.Item>\n <Text>{raisedHand.raisedHandOrderPosition}</Text>\n </Stack.Item>\n <Stack.Item>\n <RaisedHandIcon />\n </Stack.Item>\n </Stack>\n )}\n </div>\n </Stack>\n );\n};\n\nconst getParticipantStateString = (props: VideoTileProps, locale: ComponentLocale): string | undefined => {\n const strings = { ...locale.strings.videoTile, ...props.strings };\n return props.participantState === 'EarlyMedia' || props.participantState === 'Ringing'\n ? strings?.participantStateRinging\n : props.participantState === 'Hold'\n ? strings?.participantStateHold\n : undefined;\n};\n\nconst tileInfoContainerTokens = {\n // A horizontal Stack sets the left margin to 0 for all it's children.\n // We need to allow the children to set their own margins\n childrenGap: 'none'\n};\n\nconst bracketedParticipantString = (participantString: string, withBrackets: boolean): string => {\n return withBrackets ? `(${participantString})` : participantString;\n};\n"]}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { ITooltipHostStyles, IStyle } from '@fluentui/react';
|
1
|
+
import { ITooltipHostStyles, IStyle, IButtonStyles, Theme, ICalloutContentStyles } from '@fluentui/react';
|
2
2
|
import React from 'react';
|
3
3
|
/**
|
4
4
|
* @private
|
@@ -11,11 +11,6 @@ export declare const playFrames: () => string;
|
|
11
11
|
* @private
|
12
12
|
*/
|
13
13
|
export declare const emojiStyles: (backgroundImage: string, frameCount: number) => IStyle;
|
14
|
-
/**
|
15
|
-
*
|
16
|
-
* @private
|
17
|
-
*/
|
18
|
-
export declare const reactionEmojiMenuStyles: () => IStyle;
|
19
14
|
/**
|
20
15
|
*
|
21
16
|
* @private
|
@@ -33,4 +28,16 @@ export declare const mobileViewMenuItemStyle: () => React.CSSProperties;
|
|
33
28
|
* @private
|
34
29
|
*/
|
35
30
|
export declare const mobileViewEmojiStyles: (backgroundImage: string, animationPlayState: string) => React.CSSProperties;
|
31
|
+
/**
|
32
|
+
* @private
|
33
|
+
*/
|
34
|
+
export declare const reactionButtonStyles: (theme: Theme) => IButtonStyles;
|
35
|
+
/**
|
36
|
+
* @private
|
37
|
+
*/
|
38
|
+
export declare const reactionItemButtonStyles: IButtonStyles;
|
39
|
+
/**
|
40
|
+
* @private
|
41
|
+
*/
|
42
|
+
export declare const reactionButtonCalloutStyles: ICalloutContentStyles;
|
36
43
|
//# sourceMappingURL=ReactionButton.styles.d.ts.map
|
@@ -31,6 +31,7 @@ export const emojiStyles = (backgroundImage, frameCount) => {
|
|
31
31
|
alignItems: 'center',
|
32
32
|
backgroundSize: `2.75rem 133.875rem`,
|
33
33
|
transition: 'opacity 2s',
|
34
|
+
minWidth: '2.75rem',
|
34
35
|
backgroundColor: 'transparent',
|
35
36
|
transform: 'scale(0.6)',
|
36
37
|
':hover': {
|
@@ -46,24 +47,6 @@ export const emojiStyles = (backgroundImage, frameCount) => {
|
|
46
47
|
}
|
47
48
|
};
|
48
49
|
};
|
49
|
-
/**
|
50
|
-
*
|
51
|
-
* @private
|
52
|
-
*/
|
53
|
-
export const reactionEmojiMenuStyles = () => {
|
54
|
-
return {
|
55
|
-
display: 'flex',
|
56
|
-
justifyContent: 'center',
|
57
|
-
alignItems: 'center',
|
58
|
-
flexDirection: 'row',
|
59
|
-
width: '13.75rem',
|
60
|
-
height: '2.625rem',
|
61
|
-
// Ensure that when one emoji is hovered, the other emojis are partially faded out
|
62
|
-
':hover > :not(:hover)': {
|
63
|
-
opacity: '0.5'
|
64
|
-
}
|
65
|
-
};
|
66
|
-
};
|
67
50
|
/**
|
68
51
|
*
|
69
52
|
* @private
|
@@ -74,7 +57,7 @@ export const reactionToolTipHostStyle = () => {
|
|
74
57
|
display: 'flex',
|
75
58
|
flexDirection: 'column',
|
76
59
|
height: '100%',
|
77
|
-
width: '
|
60
|
+
width: '2.75rem'
|
78
61
|
}
|
79
62
|
};
|
80
63
|
};
|
@@ -120,4 +103,49 @@ export const mobileViewEmojiStyles = (backgroundImage, animationPlayState) => {
|
|
120
103
|
transform: `${animationPlayState === 'running' ? 'scale(0.8)' : 'scale(0.6)'}`
|
121
104
|
};
|
122
105
|
};
|
106
|
+
/**
|
107
|
+
* @private
|
108
|
+
*/
|
109
|
+
export const reactionButtonStyles = (theme) => ({
|
110
|
+
rootChecked: {
|
111
|
+
background: theme.palette.themePrimary,
|
112
|
+
color: theme.palette.white
|
113
|
+
},
|
114
|
+
rootCheckedHovered: {
|
115
|
+
background: theme.palette.themePrimary,
|
116
|
+
color: theme.palette.white
|
117
|
+
},
|
118
|
+
labelChecked: { color: theme.palette.white }
|
119
|
+
});
|
120
|
+
/**
|
121
|
+
* @private
|
122
|
+
*/
|
123
|
+
export const reactionItemButtonStyles = {
|
124
|
+
root: {
|
125
|
+
border: 'none',
|
126
|
+
height: '2.75rem',
|
127
|
+
width: '2.75rem'
|
128
|
+
}
|
129
|
+
};
|
130
|
+
/**
|
131
|
+
* @private
|
132
|
+
*/
|
133
|
+
export const reactionButtonCalloutStyles = {
|
134
|
+
container: {},
|
135
|
+
root: {},
|
136
|
+
beak: {},
|
137
|
+
beakCurtain: {},
|
138
|
+
calloutMain: {
|
139
|
+
display: 'flex',
|
140
|
+
justifyContent: 'center',
|
141
|
+
alignItems: 'center',
|
142
|
+
flexDirection: 'row',
|
143
|
+
width: '13.75rem',
|
144
|
+
height: '2.625rem',
|
145
|
+
// Ensure that when one emoji is hovered, the other emojis are partially faded out
|
146
|
+
':hover > :not(:hover)': {
|
147
|
+
opacity: '0.5'
|
148
|
+
}
|
149
|
+
}
|
150
|
+
};
|
123
151
|
//# sourceMappingURL=ReactionButton.styles.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ReactionButton.styles.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/styles/ReactionButton.styles.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,
|
1
|
+
{"version":3,"file":"ReactionButton.styles.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/styles/ReactionButton.styles.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport {\n ITooltipHostStyles,\n keyframes,\n memoizeFunction,\n IStyle,\n IButtonStyles,\n Theme,\n ICalloutContentStyles\n} from '@fluentui/react';\nimport React from 'react';\n\n/**\n * @private\n */\nexport const playFrames = memoizeFunction(() =>\n keyframes({\n from: {\n backgroundPosition: '0px 8568px'\n },\n to: {\n backgroundPosition: '0px 0px'\n }\n })\n);\n\n/**\n * @param backgroundImage - the uri for the reaction emoji resource\n * @param animationPlayState - the value is either 'running' or 'paused' based on the mouse hover event\n *\n * @private\n */\nexport const emojiStyles = (backgroundImage: string, frameCount: number): IStyle => {\n const imageResourceUrl = `url(${backgroundImage})`;\n const steps = frameCount ?? 51;\n return {\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n width: '100%',\n backgroundImage: imageResourceUrl,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundSize: `2.75rem 133.875rem`,\n transition: 'opacity 2s',\n minWidth: '2.75rem',\n backgroundColor: 'transparent',\n transform: 'scale(0.6)',\n ':hover': {\n transform: 'scale(0.8)',\n animationName: playFrames(),\n animationDuration: '8.12s',\n animationTimingFunction: `steps(${steps})`,\n animationIterationCount: 'infinite',\n backgroundColor: 'transparent'\n },\n ':active': {\n backgroundColor: 'transparent'\n }\n };\n};\n\n/**\n *\n * @private\n */\nexport const reactionToolTipHostStyle = (): ITooltipHostStyles => {\n return {\n root: {\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n width: '2.75rem'\n }\n };\n};\n\n/**\n *\n * @private\n */\nexport const mobileViewMenuItemStyle = (): React.CSSProperties => {\n return {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n flexDirection: 'row',\n width: '100%',\n height: '2.625rem'\n };\n};\n\n/**\n * @param backgroundImage - the uri for the reaction emoji resource\n * @param animationPlayState - the value is either 'running' or 'paused' based on the mouse hover event\n *\n * @private\n */\nexport const mobileViewEmojiStyles = (backgroundImage: string, animationPlayState: string): React.CSSProperties => {\n const imageResourceUrl = `url(${backgroundImage})`;\n return {\n display: 'flex',\n flexDirection: 'column',\n height: '100%',\n width: '2.75rem',\n backgroundImage: imageResourceUrl,\n animationName: playFrames(),\n animationDuration: '8.12s',\n animationTimingFunction: `steps(102)`,\n animationPlayState: animationPlayState,\n animationIterationCount: 'infinite',\n justifyContent: 'center',\n alignItems: 'center',\n backgroundPosition: 'center',\n backgroundSize: `2.75rem 133.875rem`,\n transition: 'opacity 2s',\n backgroundColor: 'transparent',\n transform: `${animationPlayState === 'running' ? 'scale(0.8)' : 'scale(0.6)'}`\n };\n};\n/**\n * @private\n */\nexport const reactionButtonStyles = (theme: Theme): IButtonStyles => ({\n rootChecked: {\n background: theme.palette.themePrimary,\n color: theme.palette.white\n },\n rootCheckedHovered: {\n background: theme.palette.themePrimary,\n color: theme.palette.white\n },\n labelChecked: { color: theme.palette.white }\n});\n\n/**\n * @private\n */\nexport const reactionItemButtonStyles: IButtonStyles = {\n root: {\n border: 'none',\n height: '2.75rem',\n width: '2.75rem'\n }\n};\n\n/**\n * @private\n */\nexport const reactionButtonCalloutStyles: ICalloutContentStyles = {\n container: {},\n root: {},\n beak: {},\n beakCurtain: {},\n calloutMain: {\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n flexDirection: 'row',\n width: '13.75rem',\n height: '2.625rem',\n // Ensure that when one emoji is hovered, the other emojis are partially faded out\n ':hover > :not(:hover)': {\n opacity: '0.5'\n }\n }\n};\n"]}
|
@@ -38,12 +38,6 @@ export interface IReactionStyleBucket {
|
|
38
38
|
* @private
|
39
39
|
*/
|
40
40
|
export declare function getReactionStyleBucket(): IReactionStyleBucket;
|
41
|
-
/**
|
42
|
-
* Return a style bucket for burst scenario
|
43
|
-
* We can utilize this style when we allow more than 50 reactions at a time. Can be configured through ECS.
|
44
|
-
* @private
|
45
|
-
*/
|
46
|
-
export declare function getReactionBurstStyleBucket(): IReactionStyleBucket;
|
47
41
|
/**
|
48
42
|
* @private
|
49
43
|
*/
|
@@ -106,36 +106,11 @@ function scaleStartPos(index) {
|
|
106
106
|
* It is for the ease of testing and implementation.
|
107
107
|
* @private
|
108
108
|
*/
|
109
|
-
const
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
}
|
115
|
-
];
|
116
|
-
/**
|
117
|
-
* @private
|
118
|
-
*/
|
119
|
-
const ReactionBurstStyleBuckets = [
|
120
|
-
{
|
121
|
-
sizeScale: 0.6,
|
122
|
-
opacityMax: 0.75,
|
123
|
-
heightMaxScale: 0.93,
|
124
|
-
heightMinScale: 0.27
|
125
|
-
},
|
126
|
-
{
|
127
|
-
sizeScale: 0.6,
|
128
|
-
opacityMax: 0.75,
|
129
|
-
heightMaxScale: 0.8,
|
130
|
-
heightMinScale: 0.13
|
131
|
-
},
|
132
|
-
{
|
133
|
-
sizeScale: 0.6,
|
134
|
-
opacityMax: 0.75,
|
135
|
-
heightMaxScale: 0.67,
|
136
|
-
heightMinScale: 0
|
137
|
-
}
|
138
|
-
];
|
109
|
+
const ReactionStyleBucket = {
|
110
|
+
sizeScale: 0.9,
|
111
|
+
heightMaxScale: 0.7 * 0.95,
|
112
|
+
opacityMax: 0.9
|
113
|
+
};
|
139
114
|
/**
|
140
115
|
* Return a style bucket based on the number of active sprites.
|
141
116
|
* For example, the first three reactions should appear at maximum
|
@@ -145,17 +120,7 @@ const ReactionBurstStyleBuckets = [
|
|
145
120
|
export function getReactionStyleBucket() {
|
146
121
|
// Having dynamic emoji size on rendering animation impacts performance of the animation itself.
|
147
122
|
// So we are choosing to use a fixed size for all cases.
|
148
|
-
|
149
|
-
return ReactionStyleBuckets[index];
|
150
|
-
}
|
151
|
-
/**
|
152
|
-
* Return a style bucket for burst scenario
|
153
|
-
* We can utilize this style when we allow more than 50 reactions at a time. Can be configured through ECS.
|
154
|
-
* @private
|
155
|
-
*/
|
156
|
-
export function getReactionBurstStyleBucket() {
|
157
|
-
const index = getRandomInt(0, ReactionBurstStyleBuckets.length - 1);
|
158
|
-
return ReactionBurstStyleBuckets[index];
|
123
|
+
return ReactionStyleBucket;
|
159
124
|
}
|
160
125
|
/**
|
161
126
|
* @private
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ReactionOverlay.style.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/styles/ReactionOverlay.style.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { keyframes, memoizeFunction } from '@fluentui/react';\n\n/**\n * Generate random float between two numbers, including min and max\n * @private\n */\nexport function getRandomFloat(minValue: number, maxValue: number): number {\n return minValue + Math.random() * (maxValue - minValue);\n}\n\n/**\n * Generate random int between two numbers, including min and max\n * @private\n */\nexport function getRandomInt(minValue: number, maxValue: number): number {\n return Math.floor(getRandomFloat(minValue, maxValue + 1));\n}\n\n/**\n * Calculate the start position for a new reaction in the prescriptive wave pattern\n * @private\n */\nexport function generateStartPositionWave(\n index: number,\n halfCanvasWidth: number,\n isOriginAtCanvasCenter: boolean = true\n): number {\n const midPointCoordinate = isOriginAtCanvasCenter ? halfCanvasWidth : 0;\n\n // If the # of reactions on the screen is 0 or a multiple of 25, then we set direction to 0.\n // Otherwise, every other reaction goes right, left in alternating directions.\n // To get alternating sequence, we take n % 2 (which gives 0 or 1), multiple result by 2\n // and subtract 1, which will result in -1 or 1\n const direction = index === 0 ? 0 : (index % 2) * 2 - 1;\n if (direction === 0) {\n return midPointCoordinate;\n }\n\n // Now we get how far the reaction starts from center\n const adjustment = scaleStartPos(index);\n return midPointCoordinate + direction * adjustment * halfCanvasWidth;\n}\n\n/**\n * @private\n */\nexport const reactionOverlayStyle: React.CSSProperties = {\n bottom: '0',\n height: '50%',\n pointerEvents: 'none',\n position: 'absolute',\n width: '100%'\n};\n\n/**\n * @private\n */\nexport function getReactionMovementStyle(reactionXPoint: number): React.CSSProperties {\n return {\n position: 'absolute',\n left: `${reactionXPoint}px`\n };\n}\n\n/**\n * Scale metric to determine the start position of a reaction in presentation mode to avoid overlap.\n * @private\n */\nfunction scaleStartPos(index: number): number {\n switch (index) {\n case 1:\n case 2:\n return 0.3;\n case 3:\n case 4:\n return 0.6;\n case 5:\n case 6:\n return 0.9;\n case 7:\n case 8:\n return 0.75;\n case 9:\n case 18:\n return 0.375;\n case 10:\n case 23:\n return 0.525;\n case 11:\n case 16:\n return 0.15;\n case 12:\n case 15:\n return 0.225;\n case 13:\n case 14:\n return 0.075;\n case 17:\n case 24:\n return 0.45;\n case 19:\n case 20:\n return 0.675;\n case 21:\n case 22:\n return 0.825;\n default:\n return 0;\n }\n}\n\n/**\n * We have only one bucket item for presentation style of the reaction animation.\n * We are choosing to keep the array so that, in future, with styles needed to get updated, one\n * can add new styles and apply from here, rather than updating over the same style. Later we can remove\n * the old ones.\n * It is for the ease of testing and implementation.\n * @private\n */\nconst ReactionStyleBuckets: Array<IReactionStyleBucket> = [\n {\n sizeScale: 0.9,\n heightMaxScale: 0.7 * 0.95,\n opacityMax: 0.9\n }\n];\n\n/**\n * @private\n */\nconst ReactionBurstStyleBuckets: Array<IReactionStyleBucket> = [\n {\n sizeScale: 0.6,\n opacityMax: 0.75,\n heightMaxScale: 0.93,\n heightMinScale: 0.27\n },\n {\n sizeScale: 0.6,\n opacityMax: 0.75,\n heightMaxScale: 0.8,\n heightMinScale: 0.13\n },\n {\n sizeScale: 0.6,\n opacityMax: 0.75,\n heightMaxScale: 0.67,\n heightMinScale: 0\n }\n];\n\n/**\n * @private\n */\nexport interface IReactionStyleBucket {\n sizeScale: number;\n opacityMax: number;\n heightMaxScale: number;\n heightMinScale?: number;\n}\n\n/**\n * Return a style bucket based on the number of active sprites.\n * For example, the first three reactions should appear at maximum\n * height, width, and opacity.\n * @private\n */\nexport function getReactionStyleBucket(): IReactionStyleBucket {\n // Having dynamic emoji size on rendering animation impacts performance of the animation itself.\n // So we are choosing to use a fixed size for all cases.\n const index = 0;\n return ReactionStyleBuckets[index];\n}\n\n/**\n * Return a style bucket for burst scenario\n * We can utilize this style when we allow more than 50 reactions at a time. Can be configured through ECS.\n * @private\n */\nexport function getReactionBurstStyleBucket(): IReactionStyleBucket {\n const index = getRandomInt(0, ReactionBurstStyleBuckets.length - 1);\n return ReactionBurstStyleBuckets[index];\n}\n\n/**\n * @private\n */\nexport const moveFrames = memoizeFunction((maxHeight, travelHeight) =>\n keyframes({\n '0%': {\n transform: `translateY(${maxHeight}px)`\n },\n '100%': {\n transform: `translateY(${travelHeight}px)`\n }\n })\n);\n\n/**\n * @private\n */\nexport const moveAnimationStyles = (maxHeight: number, travelHeight: number): React.CSSProperties => {\n return {\n animationName: moveFrames(maxHeight, travelHeight),\n animationFillMode: 'forwards',\n animationDuration: `4.133s`,\n animationTimingFunction: 'cubic-bezier(0, 0.83, 0.19, 1.09)'\n };\n};\n\n/**\n * @private\n */\nexport const opacityTransition = memoizeFunction((maxOpacity) =>\n keyframes({\n '0%': {\n opacity: 0\n },\n '31.2%': {\n opacity: maxOpacity\n },\n '67.2%': {\n opacity: maxOpacity\n },\n '100%': {\n opacity: 0,\n display: 'none',\n visibility: 'hidden'\n }\n })\n);\n\n/**\n * @private\n */\nexport const opacityAnimationStyles = (maxOpacity: number): React.CSSProperties => {\n return {\n animationName: opacityTransition(maxOpacity),\n animationFillMode: 'forwards',\n animationDuration: `4.133s`\n };\n};\n\n/**\n * @private\n */\nexport const spriteFrames = memoizeFunction((numOfFrames, displaySizePx) =>\n keyframes({\n from: {\n backgroundPosition: '0px 0px'\n },\n to: {\n backgroundPosition: `0px -${numOfFrames * displaySizePx}px`\n }\n })\n);\n\n/**\n * @private\n */\nexport const spriteAnimationStyles = (\n numOfFrames: number,\n displaySizePx: number,\n imageUrl: string\n): React.CSSProperties => {\n return {\n height: `${displaySizePx}px`,\n width: `${displaySizePx}px`,\n backgroundImage: `url(${imageUrl})`,\n backgroundRepeat: 'no-repeat',\n animationName: spriteFrames(numOfFrames, displaySizePx),\n animationDuration: `${numOfFrames / 24}s`,\n animationFillMode: `forwards`,\n animationIterationCount: 'infinite',\n animationTimingFunction: `steps(${numOfFrames})`,\n backgroundSize: `${displaySizePx}px ${numOfFrames * displaySizePx}px`,\n transform: `scale(${displaySizePx}/128)`\n };\n};\n"]}
|
1
|
+
{"version":3,"file":"ReactionOverlay.style.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/styles/ReactionOverlay.style.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { keyframes, memoizeFunction } from '@fluentui/react';\n\n/**\n * Generate random float between two numbers, including min and max\n * @private\n */\nexport function getRandomFloat(minValue: number, maxValue: number): number {\n return minValue + Math.random() * (maxValue - minValue);\n}\n\n/**\n * Generate random int between two numbers, including min and max\n * @private\n */\nexport function getRandomInt(minValue: number, maxValue: number): number {\n return Math.floor(getRandomFloat(minValue, maxValue + 1));\n}\n\n/**\n * Calculate the start position for a new reaction in the prescriptive wave pattern\n * @private\n */\nexport function generateStartPositionWave(\n index: number,\n halfCanvasWidth: number,\n isOriginAtCanvasCenter: boolean = true\n): number {\n const midPointCoordinate = isOriginAtCanvasCenter ? halfCanvasWidth : 0;\n\n // If the # of reactions on the screen is 0 or a multiple of 25, then we set direction to 0.\n // Otherwise, every other reaction goes right, left in alternating directions.\n // To get alternating sequence, we take n % 2 (which gives 0 or 1), multiple result by 2\n // and subtract 1, which will result in -1 or 1\n const direction = index === 0 ? 0 : (index % 2) * 2 - 1;\n if (direction === 0) {\n return midPointCoordinate;\n }\n\n // Now we get how far the reaction starts from center\n const adjustment = scaleStartPos(index);\n return midPointCoordinate + direction * adjustment * halfCanvasWidth;\n}\n\n/**\n * @private\n */\nexport const reactionOverlayStyle: React.CSSProperties = {\n bottom: '0',\n height: '50%',\n pointerEvents: 'none',\n position: 'absolute',\n width: '100%'\n};\n\n/**\n * @private\n */\nexport function getReactionMovementStyle(reactionXPoint: number): React.CSSProperties {\n return {\n position: 'absolute',\n left: `${reactionXPoint}px`\n };\n}\n\n/**\n * Scale metric to determine the start position of a reaction in presentation mode to avoid overlap.\n * @private\n */\nfunction scaleStartPos(index: number): number {\n switch (index) {\n case 1:\n case 2:\n return 0.3;\n case 3:\n case 4:\n return 0.6;\n case 5:\n case 6:\n return 0.9;\n case 7:\n case 8:\n return 0.75;\n case 9:\n case 18:\n return 0.375;\n case 10:\n case 23:\n return 0.525;\n case 11:\n case 16:\n return 0.15;\n case 12:\n case 15:\n return 0.225;\n case 13:\n case 14:\n return 0.075;\n case 17:\n case 24:\n return 0.45;\n case 19:\n case 20:\n return 0.675;\n case 21:\n case 22:\n return 0.825;\n default:\n return 0;\n }\n}\n\n/**\n * We have only one bucket item for presentation style of the reaction animation.\n * We are choosing to keep the array so that, in future, with styles needed to get updated, one\n * can add new styles and apply from here, rather than updating over the same style. Later we can remove\n * the old ones.\n * It is for the ease of testing and implementation.\n * @private\n */\nconst ReactionStyleBucket: IReactionStyleBucket = {\n sizeScale: 0.9,\n heightMaxScale: 0.7 * 0.95,\n opacityMax: 0.9\n};\n\n/**\n * @private\n */\nexport interface IReactionStyleBucket {\n sizeScale: number;\n opacityMax: number;\n heightMaxScale: number;\n heightMinScale?: number;\n}\n\n/**\n * Return a style bucket based on the number of active sprites.\n * For example, the first three reactions should appear at maximum\n * height, width, and opacity.\n * @private\n */\nexport function getReactionStyleBucket(): IReactionStyleBucket {\n // Having dynamic emoji size on rendering animation impacts performance of the animation itself.\n // So we are choosing to use a fixed size for all cases.\n return ReactionStyleBucket;\n}\n\n/**\n * @private\n */\nexport const moveFrames = memoizeFunction((maxHeight, travelHeight) =>\n keyframes({\n '0%': {\n transform: `translateY(${maxHeight}px)`\n },\n '100%': {\n transform: `translateY(${travelHeight}px)`\n }\n })\n);\n\n/**\n * @private\n */\nexport const moveAnimationStyles = (maxHeight: number, travelHeight: number): React.CSSProperties => {\n return {\n animationName: moveFrames(maxHeight, travelHeight),\n animationFillMode: 'forwards',\n animationDuration: `4.133s`,\n animationTimingFunction: 'cubic-bezier(0, 0.83, 0.19, 1.09)'\n };\n};\n\n/**\n * @private\n */\nexport const opacityTransition = memoizeFunction((maxOpacity) =>\n keyframes({\n '0%': {\n opacity: 0\n },\n '31.2%': {\n opacity: maxOpacity\n },\n '67.2%': {\n opacity: maxOpacity\n },\n '100%': {\n opacity: 0,\n display: 'none',\n visibility: 'hidden'\n }\n })\n);\n\n/**\n * @private\n */\nexport const opacityAnimationStyles = (maxOpacity: number): React.CSSProperties => {\n return {\n animationName: opacityTransition(maxOpacity),\n animationFillMode: 'forwards',\n animationDuration: `4.133s`\n };\n};\n\n/**\n * @private\n */\nexport const spriteFrames = memoizeFunction((numOfFrames, displaySizePx) =>\n keyframes({\n from: {\n backgroundPosition: '0px 0px'\n },\n to: {\n backgroundPosition: `0px -${numOfFrames * displaySizePx}px`\n }\n })\n);\n\n/**\n * @private\n */\nexport const spriteAnimationStyles = (\n numOfFrames: number,\n displaySizePx: number,\n imageUrl: string\n): React.CSSProperties => {\n return {\n height: `${displaySizePx}px`,\n width: `${displaySizePx}px`,\n backgroundImage: `url(${imageUrl})`,\n backgroundRepeat: 'no-repeat',\n animationName: spriteFrames(numOfFrames, displaySizePx),\n animationDuration: `${numOfFrames / 24}s`,\n animationFillMode: `forwards`,\n animationIterationCount: 'infinite',\n animationTimingFunction: `steps(${numOfFrames})`,\n backgroundSize: `${displaySizePx}px ${numOfFrames * displaySizePx}px`,\n transform: `scale(${displaySizePx}/128)`\n };\n};\n"]}
|
@@ -82,7 +82,7 @@ export const getPreviousInlineImages = (content) => {
|
|
82
82
|
export const getRemovedInlineImages = (content, previousInlineImages) => {
|
83
83
|
const document = new DOMParser().parseFromString(content !== null && content !== void 0 ? content : '', 'text/html');
|
84
84
|
const currentContentIds = Array.from(document.querySelectorAll('img')).map((img) => img.id);
|
85
|
-
previousInlineImages = previousInlineImages === null || previousInlineImages === void 0 ? void 0 : previousInlineImages.filter((img) => !(currentContentIds === null || currentContentIds === void 0 ? void 0 : currentContentIds.includes(img.id)));
|
85
|
+
previousInlineImages = previousInlineImages === null || previousInlineImages === void 0 ? void 0 : previousInlineImages.filter((img) => !!img.id && !(currentContentIds === null || currentContentIds === void 0 ? void 0 : currentContentIds.includes(img.id)));
|
86
86
|
const removedInlineImages = [...previousInlineImages];
|
87
87
|
return removedInlineImages;
|
88
88
|
};
|
@@ -158,6 +158,9 @@ export const scrollToBottomRichTextEditor = () => {
|
|
158
158
|
*/
|
159
159
|
export const removeLocalBlobs = (currentLocalBlobMap, removedInlineImages) => {
|
160
160
|
removedInlineImages.forEach((image) => {
|
161
|
+
if (!image.id) {
|
162
|
+
return;
|
163
|
+
}
|
161
164
|
removeSingleLocalBlob(currentLocalBlobMap, image.id);
|
162
165
|
});
|
163
166
|
};
|