@azure/communication-react 1.5.1-alpha-202302230015 → 1.5.1-alpha-202303010017
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/CHANGELOG.beta.md +86 -1
- package/CHANGELOG.json +686 -0
- package/dist/communication-react.d.ts +16 -0
- package/dist/dist-cjs/communication-react/index.js +663 -335
- package/dist/dist-cjs/communication-react/index.js.map +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/chat-stateful-client/src/EventSubscriber.js +10 -2
- package/dist/dist-esm/chat-stateful-client/src/EventSubscriber.js.map +1 -1
- package/dist/dist-esm/communication-react/src/index.d.ts +1 -0
- package/dist/dist-esm/communication-react/src/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/HorizontalGallery.js +1 -10
- package/dist/dist-esm/react-components/src/components/HorizontalGallery.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ResponsiveVerticalGallery.d.ts +29 -0
- package/dist/dist-esm/react-components/src/components/ResponsiveVerticalGallery.js +77 -0
- package/dist/dist-esm/react-components/src/components/ResponsiveVerticalGallery.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/VerticalGallery.d.ts +50 -0
- package/dist/dist-esm/react-components/src/components/VerticalGallery.js +85 -0
- package/dist/dist-esm/react-components/src/components/VerticalGallery.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js +19 -13
- package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideo.d.ts +10 -3
- package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideo.js +6 -8
- package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideo.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideoLayout.js +32 -16
- package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideoLayout.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/Layout.d.ts +6 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/Layout.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/{VideoGalleryResponsiveHorizontalGallery.d.ts → OverflowGallery.d.ts} +5 -3
- package/dist/dist-esm/react-components/src/components/VideoGallery/OverflowGallery.js +46 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/OverflowGallery.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/styles/FloatingLocalVideo.styles.d.ts +20 -3
- package/dist/dist-esm/react-components/src/components/VideoGallery/styles/FloatingLocalVideo.styles.js +11 -6
- package/dist/dist-esm/react-components/src/components/VideoGallery/styles/FloatingLocalVideo.styles.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/VideoGallery/styles/VideoGalleryResponsiveVerticalGallery.styles.d.ts +38 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/styles/VideoGalleryResponsiveVerticalGallery.styles.js +44 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery/styles/VideoGalleryResponsiveVerticalGallery.styles.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery.d.ts +11 -0
- package/dist/dist-esm/react-components/src/components/VideoGallery.js +7 -3
- package/dist/dist-esm/react-components/src/components/VideoGallery.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/index.d.ts +1 -0
- package/dist/dist-esm/react-components/src/components/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/VerticalGallery.styles.d.ts +32 -0
- package/dist/dist-esm/react-components/src/components/styles/VerticalGallery.styles.js +63 -0
- package/dist/dist-esm/react-components/src/components/styles/VerticalGallery.styles.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/utils/overFlowGalleriesUtils.d.ts +11 -0
- package/dist/dist-esm/react-components/src/components/utils/overFlowGalleriesUtils.js +22 -0
- package/dist/dist-esm/react-components/src/components/utils/overFlowGalleriesUtils.js.map +1 -0
- package/dist/dist-esm/react-components/src/theming/icons.d.ts +2 -0
- package/dist/dist-esm/react-components/src/theming/icons.js +5 -1
- package/dist/dist-esm/react-components/src/theming/icons.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/icons.d.ts +2 -0
- package/package.json +10 -10
- package/dist/dist-esm/react-components/src/components/VideoGallery/VideoGalleryResponsiveHorizontalGallery.js +0 -19
- package/dist/dist-esm/react-components/src/components/VideoGallery/VideoGalleryResponsiveHorizontalGallery.js.map +0 -1
@@ -161,7 +161,7 @@ const _toCommunicationIdentifier = (id) => {
|
|
161
161
|
// Copyright (c) Microsoft Corporation.
|
162
162
|
// Licensed under the MIT license.
|
163
163
|
// GENERATED FILE. DO NOT EDIT MANUALLY.
|
164
|
-
var telemetryVersion = '1.5.1-alpha-
|
164
|
+
var telemetryVersion = '1.5.1-alpha-202303010017';
|
165
165
|
|
166
166
|
// Copyright (c) Microsoft Corporation.
|
167
167
|
/**
|
@@ -5364,7 +5364,11 @@ const DEFAULT_COMPONENT_ICONS = {
|
|
5364
5364
|
/* @conditional-compile-remove(pinned-participants) */
|
5365
5365
|
PinParticipant: React__default['default'].createElement(reactIcons.Pin16Regular, null),
|
5366
5366
|
/* @conditional-compile-remove(pinned-participants) */
|
5367
|
-
UnpinParticipant: React__default['default'].createElement(reactIcons.PinOff16Regular, null)
|
5367
|
+
UnpinParticipant: React__default['default'].createElement(reactIcons.PinOff16Regular, null),
|
5368
|
+
/* @conditional-compile-remove(vertical-gallery) */
|
5369
|
+
VerticalGalleryLeftButton: React__default['default'].createElement(reactIcons.ChevronLeft20Regular, null),
|
5370
|
+
/* @conditional-compile-remove(vertical-gallery) */
|
5371
|
+
VerticalGalleryRightButton: React__default['default'].createElement(reactIcons.ChevronRight20Regular, null)
|
5368
5372
|
};
|
5369
5373
|
|
5370
5374
|
// Copyright (c) Microsoft Corporation.
|
@@ -9199,176 +9203,6 @@ const FloatingLocalCameraCycleButton = (props) => {
|
|
9199
9203
|
(localVideoCameraCycleButtonProps === null || localVideoCameraCycleButtonProps === void 0 ? void 0 : localVideoCameraCycleButtonProps.onSelectCamera) !== undefined && (React__default['default'].createElement(LocalVideoCameraCycleButton, { cameras: localVideoCameraCycleButtonProps.cameras, selectedCamera: localVideoCameraCycleButtonProps.selectedCamera, onSelectCamera: localVideoCameraCycleButtonProps.onSelectCamera, label: localVideoCameraSwitcherLabel, ariaDescription: ariaDescription }))));
|
9200
9204
|
};
|
9201
9205
|
|
9202
|
-
// Copyright (c) Microsoft Corporation.
|
9203
|
-
/**
|
9204
|
-
* @private
|
9205
|
-
*/
|
9206
|
-
react.mergeStyles({ position: 'relative', width: '100%', height: '100%' });
|
9207
|
-
/**
|
9208
|
-
* Small floating modal width and height in rem for small screen
|
9209
|
-
*/
|
9210
|
-
const SMALL_FLOATING_MODAL_SIZE_PX = { width: 58, height: 104 };
|
9211
|
-
/**
|
9212
|
-
* Large floating modal width and height in rem for large screen
|
9213
|
-
* Aspect ratio: 16:9
|
9214
|
-
*/
|
9215
|
-
const LARGE_FLOATING_MODAL_SIZE_PX = { width: 215, height: 120 };
|
9216
|
-
/**
|
9217
|
-
* @private
|
9218
|
-
* z-index to ensure that the local video tile is above the video gallery.
|
9219
|
-
*/
|
9220
|
-
const LOCAL_VIDEO_TILE_ZINDEX = 2;
|
9221
|
-
/**
|
9222
|
-
* @private
|
9223
|
-
*/
|
9224
|
-
const localVideoTileContainerStyle = (theme, isNarrow) => {
|
9225
|
-
return Object.assign({ minWidth: isNarrow ? _pxToRem(SMALL_FLOATING_MODAL_SIZE_PX.width) : _pxToRem(LARGE_FLOATING_MODAL_SIZE_PX.width), minHeight: isNarrow ? _pxToRem(SMALL_FLOATING_MODAL_SIZE_PX.height) : _pxToRem(LARGE_FLOATING_MODAL_SIZE_PX.height), position: 'absolute', bottom: _pxToRem(localVideoTileOuterPaddingPX), borderRadius: theme.effects.roundedCorner4, overflow: 'hidden' }, (theme.rtl
|
9226
|
-
? { left: _pxToRem(localVideoTileOuterPaddingPX) }
|
9227
|
-
: { right: _pxToRem(localVideoTileOuterPaddingPX) }));
|
9228
|
-
};
|
9229
|
-
/**
|
9230
|
-
* @private
|
9231
|
-
*/
|
9232
|
-
const localVideoTileWithControlsContainerStyle = (theme, isNarrow) => {
|
9233
|
-
return react.concatStyleSets(localVideoTileContainerStyle(theme, isNarrow), {
|
9234
|
-
root: { boxShadow: theme.effects.elevation8 }
|
9235
|
-
});
|
9236
|
-
};
|
9237
|
-
/**
|
9238
|
-
* @private
|
9239
|
-
*/
|
9240
|
-
const floatingLocalVideoModalStyle = (theme, isNarrow) => {
|
9241
|
-
return react.concatStyleSets({
|
9242
|
-
main: localVideoTileContainerStyle(theme, isNarrow)
|
9243
|
-
}, {
|
9244
|
-
main: {
|
9245
|
-
boxShadow: theme.effects.elevation8,
|
9246
|
-
':focus-within': {
|
9247
|
-
boxShadow: theme.effects.elevation16,
|
9248
|
-
border: `${_pxToRem(2)} solid ${theme.palette.neutralPrimary}`
|
9249
|
-
}
|
9250
|
-
}
|
9251
|
-
}, localVideoModalStyles);
|
9252
|
-
};
|
9253
|
-
/**
|
9254
|
-
* Padding equal to the amount the modal should stay inside the bounds of the container.
|
9255
|
-
* i.e. if this is 8px, the modal should always be at least 8px inside the container at all times on all sides.
|
9256
|
-
* @private
|
9257
|
-
*/
|
9258
|
-
const localVideoTileOuterPaddingPX = 8;
|
9259
|
-
/**
|
9260
|
-
* @private
|
9261
|
-
*/
|
9262
|
-
const floatingLocalVideoTileStyle = {
|
9263
|
-
root: {
|
9264
|
-
position: 'absolute',
|
9265
|
-
zIndex: LOCAL_VIDEO_TILE_ZINDEX,
|
9266
|
-
height: '100%',
|
9267
|
-
width: '100%'
|
9268
|
-
}
|
9269
|
-
};
|
9270
|
-
/**
|
9271
|
-
* Styles for the local video tile modal when it is focused, will cause keyboard move icon to appear over video
|
9272
|
-
* @private
|
9273
|
-
*/
|
9274
|
-
const localVideoModalStyles = {
|
9275
|
-
keyboardMoveIconContainer: {
|
9276
|
-
zIndex: LOCAL_VIDEO_TILE_ZINDEX + 1 // zIndex to set the keyboard movement Icon above the other layers in the video tile.
|
9277
|
-
}
|
9278
|
-
};
|
9279
|
-
|
9280
|
-
// Copyright (c) Microsoft Corporation.
|
9281
|
-
/**
|
9282
|
-
* @private
|
9283
|
-
*/
|
9284
|
-
const horizontalGalleryContainerStyle = (shouldFloatLocalVideo, isNarrow) => {
|
9285
|
-
return {
|
9286
|
-
minHeight: isNarrow
|
9287
|
-
? `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`
|
9288
|
-
: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9289
|
-
width: shouldFloatLocalVideo
|
9290
|
-
? isNarrow
|
9291
|
-
? `calc(100% - ${_pxToRem(SMALL_FLOATING_MODAL_SIZE_PX.width)})`
|
9292
|
-
: `calc(100% - ${_pxToRem(LARGE_FLOATING_MODAL_SIZE_PX.width)})`
|
9293
|
-
: '100%',
|
9294
|
-
paddingRight: '0.5rem'
|
9295
|
-
};
|
9296
|
-
};
|
9297
|
-
/**
|
9298
|
-
* @private
|
9299
|
-
*/
|
9300
|
-
const horizontalGalleryStyle = (isNarrow) => {
|
9301
|
-
return {
|
9302
|
-
children: isNarrow ? SMALL_HORIZONTAL_GALLERY_TILE_STYLE : LARGE_HORIZONTAL_GALLERY_TILE_STYLE
|
9303
|
-
};
|
9304
|
-
};
|
9305
|
-
/**
|
9306
|
-
* Small horizontal gallery tile size in rem
|
9307
|
-
* @private
|
9308
|
-
*/
|
9309
|
-
const SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM = { height: 6.5, width: 6.5 };
|
9310
|
-
/**
|
9311
|
-
* Large horizontal gallery tile size in rem
|
9312
|
-
* @private
|
9313
|
-
*/
|
9314
|
-
const LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM = { height: 7.5, width: 10 };
|
9315
|
-
/**
|
9316
|
-
* @private
|
9317
|
-
*/
|
9318
|
-
const SMALL_HORIZONTAL_GALLERY_TILE_STYLE = {
|
9319
|
-
minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9320
|
-
minWidth: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`,
|
9321
|
-
maxHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9322
|
-
maxWidth: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`
|
9323
|
-
};
|
9324
|
-
/**
|
9325
|
-
* @private
|
9326
|
-
*/
|
9327
|
-
const LARGE_HORIZONTAL_GALLERY_TILE_STYLE = {
|
9328
|
-
minHeight: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9329
|
-
minWidth: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`,
|
9330
|
-
maxHeight: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9331
|
-
maxWidth: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`
|
9332
|
-
};
|
9333
|
-
|
9334
|
-
// Copyright (c) Microsoft Corporation.
|
9335
|
-
/**
|
9336
|
-
* @private
|
9337
|
-
*/
|
9338
|
-
const scrollableHorizontalGalleryStyles = {
|
9339
|
-
root: {
|
9340
|
-
width: '100%',
|
9341
|
-
minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9342
|
-
paddingRight: '0.5rem',
|
9343
|
-
'> *': SMALL_HORIZONTAL_GALLERY_TILE_STYLE
|
9344
|
-
}
|
9345
|
-
};
|
9346
|
-
/**
|
9347
|
-
* @private
|
9348
|
-
*/
|
9349
|
-
const scrollableHorizontalGalleryContainerStyles = react.mergeStyles({
|
9350
|
-
display: 'flex',
|
9351
|
-
width: `calc(100% - ${SMALL_FLOATING_MODAL_SIZE_PX.width}px)`,
|
9352
|
-
minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9353
|
-
overflow: 'scroll',
|
9354
|
-
'-ms-overflow-style': 'none',
|
9355
|
-
'scrollbar-width': 'none',
|
9356
|
-
'::-webkit-scrollbar': { display: 'none' }
|
9357
|
-
});
|
9358
|
-
|
9359
|
-
// Copyright (c) Microsoft Corporation.
|
9360
|
-
/**
|
9361
|
-
* Component to display elements horizontally in a scrollable container
|
9362
|
-
* @private
|
9363
|
-
*/
|
9364
|
-
const ScrollableHorizontalGallery = (props) => {
|
9365
|
-
const { horizontalGalleryElements } = props;
|
9366
|
-
const ref = React.useRef();
|
9367
|
-
const { events: dragabbleEvents } = reactUseDraggableScroll.useDraggable(ref);
|
9368
|
-
return (React__default['default'].createElement("div", Object.assign({ ref: ref }, dragabbleEvents, { className: scrollableHorizontalGalleryContainerStyles }),
|
9369
|
-
React__default['default'].createElement(react.Stack, { "data-ui-id": "scrollable-horizontal-gallery", horizontal: true, styles: scrollableHorizontalGalleryStyles, tokens: { childrenGap: '0.5rem' } }, horizontalGalleryElements)));
|
9370
|
-
};
|
9371
|
-
|
9372
9206
|
// Copyright (c) Microsoft Corporation.
|
9373
9207
|
// Licensed under the MIT license.
|
9374
9208
|
/**
|
@@ -9533,168 +9367,608 @@ const _useOrganizedParticipantsWithPinnedParticipants = (props) => {
|
|
9533
9367
|
if (pinnedParticipants.length === 0) {
|
9534
9368
|
return useOrganizedParticipantsResult;
|
9535
9369
|
}
|
9536
|
-
return {
|
9537
|
-
gridParticipants: props.isScreenShareActive ? [] : pinnedParticipants,
|
9538
|
-
horizontalGalleryParticipants: props.isScreenShareActive
|
9539
|
-
? pinnedParticipants.concat(useOrganizedParticipantsResult.horizontalGalleryParticipants)
|
9540
|
-
: useOrganizedParticipantsResult.gridParticipants.concat(useOrganizedParticipantsResult.horizontalGalleryParticipants)
|
9541
|
-
};
|
9370
|
+
return {
|
9371
|
+
gridParticipants: props.isScreenShareActive ? [] : pinnedParticipants,
|
9372
|
+
horizontalGalleryParticipants: props.isScreenShareActive
|
9373
|
+
? pinnedParticipants.concat(useOrganizedParticipantsResult.horizontalGalleryParticipants)
|
9374
|
+
: useOrganizedParticipantsResult.gridParticipants.concat(useOrganizedParticipantsResult.horizontalGalleryParticipants)
|
9375
|
+
};
|
9376
|
+
};
|
9377
|
+
/**
|
9378
|
+
* Hook to determine which participants should be in grid and horizontal gallery and their order respectively
|
9379
|
+
* @private
|
9380
|
+
*/
|
9381
|
+
const useOrganizedParticipants = (args) => {
|
9382
|
+
/* @conditional-compile-remove(pinned-participants) */
|
9383
|
+
return _useOrganizedParticipantsWithPinnedParticipants(args);
|
9384
|
+
};
|
9385
|
+
|
9386
|
+
// Copyright (c) Microsoft Corporation.
|
9387
|
+
// Licensed under the MIT license.
|
9388
|
+
/**
|
9389
|
+
* Horizontal Gallery button width in rem
|
9390
|
+
*/
|
9391
|
+
const HORIZONTAL_GALLERY_BUTTON_WIDTH = 1.75;
|
9392
|
+
/**
|
9393
|
+
* @private
|
9394
|
+
*/
|
9395
|
+
const leftRightButtonStyles$1 = (theme) => {
|
9396
|
+
return {
|
9397
|
+
background: 'none',
|
9398
|
+
padding: 0,
|
9399
|
+
height: 'auto',
|
9400
|
+
minWidth: `${HORIZONTAL_GALLERY_BUTTON_WIDTH}rem`,
|
9401
|
+
maxWidth: `${HORIZONTAL_GALLERY_BUTTON_WIDTH}rem`,
|
9402
|
+
border: `1px solid ${theme.palette.neutralLight}`,
|
9403
|
+
borderRadius: theme.effects.roundedCorner4
|
9404
|
+
};
|
9405
|
+
};
|
9406
|
+
/**
|
9407
|
+
* Horizontal Gallery gap size in rem between tiles and buttons
|
9408
|
+
*/
|
9409
|
+
const HORIZONTAL_GALLERY_GAP = 0.5;
|
9410
|
+
/**
|
9411
|
+
* @private
|
9412
|
+
*/
|
9413
|
+
const rootStyle$1 = {
|
9414
|
+
height: '100%',
|
9415
|
+
width: '100%',
|
9416
|
+
gap: `${HORIZONTAL_GALLERY_GAP}rem`
|
9417
|
+
};
|
9418
|
+
/**
|
9419
|
+
* @private
|
9420
|
+
*/
|
9421
|
+
const childrenContainerStyle$1 = {
|
9422
|
+
height: '100%',
|
9423
|
+
gap: `${HORIZONTAL_GALLERY_GAP}rem`
|
9424
|
+
};
|
9425
|
+
|
9426
|
+
// Copyright (c) Microsoft Corporation.
|
9427
|
+
// Licensed under the MIT license.
|
9428
|
+
/**
|
9429
|
+
* Helper function to bucketize a given array of items into buckets of a specified size.
|
9430
|
+
*
|
9431
|
+
* @param arr array to bucketize
|
9432
|
+
* @param bucketSize number of children for each bucket
|
9433
|
+
* @returns nested array of given children
|
9434
|
+
*
|
9435
|
+
* @private
|
9436
|
+
*/
|
9437
|
+
function bucketize(arr, bucketSize) {
|
9438
|
+
const bucketArray = [];
|
9439
|
+
if (bucketSize <= 0) {
|
9440
|
+
return bucketArray;
|
9441
|
+
}
|
9442
|
+
for (let i = 0; i < arr.length; i += bucketSize) {
|
9443
|
+
bucketArray.push(arr.slice(i, i + bucketSize));
|
9444
|
+
}
|
9445
|
+
return bucketArray;
|
9446
|
+
}
|
9447
|
+
|
9448
|
+
// Copyright (c) Microsoft Corporation.
|
9449
|
+
/**
|
9450
|
+
* {@link HorizontalGallery} default children per page
|
9451
|
+
*/
|
9452
|
+
const DEFAULT_CHILDREN_PER_PAGE = 5;
|
9453
|
+
/**
|
9454
|
+
* Renders a horizontal gallery that parents children horizontally. Handles pagination based on the childrenPerPage prop.
|
9455
|
+
* @param props - HorizontalGalleryProps {@link @azure/communication-react#HorizontalGalleryProps}
|
9456
|
+
* @returns
|
9457
|
+
*/
|
9458
|
+
const HorizontalGallery = (props) => {
|
9459
|
+
var _a, _b;
|
9460
|
+
const { children, childrenPerPage = DEFAULT_CHILDREN_PER_PAGE, styles } = props;
|
9461
|
+
const ids = useIdentifiers();
|
9462
|
+
const [page, setPage] = React.useState(0);
|
9463
|
+
const numberOfChildren = React__default['default'].Children.count(children);
|
9464
|
+
const lastPage = Math.ceil(numberOfChildren / childrenPerPage) - 1;
|
9465
|
+
const paginatedChildren = React.useMemo(() => {
|
9466
|
+
return bucketize(React__default['default'].Children.toArray(children), childrenPerPage);
|
9467
|
+
}, [children, childrenPerPage]);
|
9468
|
+
// If children per page is 0 or less return empty element
|
9469
|
+
if (childrenPerPage <= 0) {
|
9470
|
+
return React__default['default'].createElement(React__default['default'].Fragment, null);
|
9471
|
+
}
|
9472
|
+
const firstIndexOfCurrentPage = page * childrenPerPage;
|
9473
|
+
const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage;
|
9474
|
+
const childrenOnCurrentPage = paginatedChildren[clippedPage];
|
9475
|
+
const showButtons = numberOfChildren > childrenPerPage;
|
9476
|
+
const disablePreviousButton = page === 0;
|
9477
|
+
const disableNextButton = page === lastPage;
|
9478
|
+
return (React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(rootStyle$1, (_a = props.styles) === null || _a === void 0 ? void 0 : _a.root) },
|
9479
|
+
showButtons && (React__default['default'].createElement(HorizontalGalleryNavigationButton, { key: "previous-nav-button", icon: React__default['default'].createElement(react.Icon, { iconName: "HorizontalGalleryLeftButton" }), styles: styles === null || styles === void 0 ? void 0 : styles.previousButton, onClick: () => setPage(Math.max(0, Math.min(lastPage, page - 1))), disabled: disablePreviousButton, identifier: ids.horizontalGalleryLeftNavButton })),
|
9480
|
+
React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(childrenContainerStyle$1, { '> *': (_b = props.styles) === null || _b === void 0 ? void 0 : _b.children }) }, childrenOnCurrentPage),
|
9481
|
+
showButtons && (React__default['default'].createElement(HorizontalGalleryNavigationButton, { key: "next-nav-button", icon: React__default['default'].createElement(react.Icon, { iconName: "HorizontalGalleryRightButton" }), styles: styles === null || styles === void 0 ? void 0 : styles.nextButton, onClick: () => setPage(Math.min(lastPage, page + 1)), disabled: disableNextButton, identifier: ids.horizontalGalleryRightNavButton }))));
|
9482
|
+
};
|
9483
|
+
const HorizontalGalleryNavigationButton = (props) => {
|
9484
|
+
const theme = useTheme();
|
9485
|
+
return (React__default['default'].createElement(react.DefaultButton, { className: react.mergeStyles(leftRightButtonStyles$1(theme), props.styles), onClick: props.onClick, disabled: props.disabled, "data-ui-id": props.identifier }, props.icon));
|
9486
|
+
};
|
9487
|
+
|
9488
|
+
// Copyright (c) Microsoft Corporation.
|
9489
|
+
/**
|
9490
|
+
* Wrapped HorizontalGallery that adjusts the number of items per page based on the
|
9491
|
+
* available width obtained from a ResizeObserver, width per child, gap width, and button width
|
9492
|
+
*/
|
9493
|
+
const ResponsiveHorizontalGallery = (props) => {
|
9494
|
+
const { childWidthRem, gapWidthRem, buttonWidthRem = 0 } = props;
|
9495
|
+
const containerRef = React.useRef(null);
|
9496
|
+
const containerWidth = _useContainerWidth(containerRef);
|
9497
|
+
const leftPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingLeft) : 0;
|
9498
|
+
const rightPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingRight) : 0;
|
9499
|
+
const childrenPerPage = calculateChildrenPerPage$1({
|
9500
|
+
numberOfChildren: React__default['default'].Children.count(props.children),
|
9501
|
+
containerWidth: (containerWidth !== null && containerWidth !== void 0 ? containerWidth : 0) - leftPadding - rightPadding,
|
9502
|
+
childWidthRem,
|
9503
|
+
gapWidthRem,
|
9504
|
+
buttonWidthRem
|
9505
|
+
});
|
9506
|
+
return (React__default['default'].createElement("div", { ref: containerRef, className: react.mergeStyles(props.containerStyles) },
|
9507
|
+
React__default['default'].createElement(HorizontalGallery, { childrenPerPage: childrenPerPage, styles: props.horizontalGalleryStyles }, props.children)));
|
9508
|
+
};
|
9509
|
+
/**
|
9510
|
+
* Helper function to calculate children per page for HorizontalGallery based on width of container, child, buttons, and
|
9511
|
+
* gaps in between
|
9512
|
+
*/
|
9513
|
+
const calculateChildrenPerPage$1 = (args) => {
|
9514
|
+
const { numberOfChildren, containerWidth, buttonWidthRem, childWidthRem, gapWidthRem } = args;
|
9515
|
+
const childWidth = _convertRemToPx(childWidthRem);
|
9516
|
+
const gapWidth = _convertRemToPx(gapWidthRem);
|
9517
|
+
/** First check how many children can fit in containerWidth.
|
9518
|
+
* __________________________________
|
9519
|
+
* | || |
|
9520
|
+
* | || |
|
9521
|
+
* |________________||________________|
|
9522
|
+
* <-----------containerWidth--------->
|
9523
|
+
* containerWidth = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
|
9524
|
+
*/
|
9525
|
+
const numberOfChildrenInContainer = Math.floor((containerWidth + gapWidth) / (childWidth + gapWidth));
|
9526
|
+
// If all children fit then return numberOfChildrenInContainer
|
9527
|
+
if (numberOfChildren <= numberOfChildrenInContainer) {
|
9528
|
+
return numberOfChildrenInContainer;
|
9529
|
+
}
|
9530
|
+
const buttonWidth = _convertRemToPx(buttonWidthRem);
|
9531
|
+
/** We know we need to paginate. So we need to subtract the buttonWidth twice and gapWidth twice from
|
9532
|
+
* containerWidth to compute childrenSpace
|
9533
|
+
* <-----------containerWidth--------->
|
9534
|
+
* __________________________________
|
9535
|
+
* | || || || |
|
9536
|
+
* |<|| || ||>|
|
9537
|
+
* |_||_____________||_____________||_|
|
9538
|
+
* <-------childrenSpace------>
|
9539
|
+
*/
|
9540
|
+
const childrenSpace = containerWidth - 2 * buttonWidth - 2 * gapWidth;
|
9541
|
+
// Now that we have childrenSpace width we can figure out how many children can fit in childrenSpace.
|
9542
|
+
// childrenSpace = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
|
9543
|
+
return Math.floor((childrenSpace + gapWidth) / (childWidth + gapWidth));
|
9544
|
+
};
|
9545
|
+
|
9546
|
+
// Copyright (c) Microsoft Corporation.
|
9547
|
+
// Licensed under the MIT license.
|
9548
|
+
/**
|
9549
|
+
* Vertical Gallery gap size in rem between tiles and buttons
|
9550
|
+
*
|
9551
|
+
* @private
|
9552
|
+
*/
|
9553
|
+
const VERTICAL_GALLERY_GAP = 0.5;
|
9554
|
+
/**
|
9555
|
+
* @private
|
9556
|
+
*/
|
9557
|
+
const childrenContainerStyle = {
|
9558
|
+
width: '100%',
|
9559
|
+
gap: `${VERTICAL_GALLERY_GAP}rem`
|
9560
|
+
};
|
9561
|
+
/**
|
9562
|
+
* @private
|
9563
|
+
*/
|
9564
|
+
const rootStyle = {
|
9565
|
+
height: '100%',
|
9566
|
+
width: '100%',
|
9567
|
+
gap: `${VERTICAL_GALLERY_GAP}rem`,
|
9568
|
+
position: 'relative'
|
9569
|
+
};
|
9570
|
+
/**
|
9571
|
+
* @private
|
9572
|
+
*/
|
9573
|
+
const pageNavigationControlBarContainerStyle = {
|
9574
|
+
height: '2rem',
|
9575
|
+
width: '100%',
|
9576
|
+
position: 'absolute',
|
9577
|
+
bottom: '0'
|
9578
|
+
};
|
9579
|
+
/**
|
9580
|
+
* @private
|
9581
|
+
*/
|
9582
|
+
const leftRightButtonStyles = (theme) => {
|
9583
|
+
return {
|
9584
|
+
background: 'none',
|
9585
|
+
padding: 0,
|
9586
|
+
height: 'auto',
|
9587
|
+
borderRadius: theme.effects.roundedCorner4,
|
9588
|
+
border: 'none',
|
9589
|
+
minWidth: '2rem'
|
9590
|
+
};
|
9591
|
+
};
|
9592
|
+
/**
|
9593
|
+
* @private
|
9594
|
+
*/
|
9595
|
+
const participantPageCounter = {
|
9596
|
+
lineHeight: '2rem',
|
9597
|
+
width: '100%',
|
9598
|
+
textAlign: 'center'
|
9599
|
+
};
|
9600
|
+
/**
|
9601
|
+
* @private
|
9602
|
+
*/
|
9603
|
+
const navIconStyles = {
|
9604
|
+
root: {
|
9605
|
+
lineHeight: '0'
|
9606
|
+
}
|
9607
|
+
};
|
9608
|
+
|
9609
|
+
// Copyright (c) Microsoft Corporation.
|
9610
|
+
/**
|
9611
|
+
* VerticalGallery is a overflow gallery for participants in the {@link VideoGallery} component. Stacks
|
9612
|
+
* participants on the Y-axis of the VideoGallery for better use of horizontal space.
|
9613
|
+
*
|
9614
|
+
* @beta
|
9615
|
+
*/
|
9616
|
+
const VerticalGallery = (props) => {
|
9617
|
+
const { children, styles, childrenPerPage } = props;
|
9618
|
+
const [page, setPage] = React.useState(0);
|
9619
|
+
const [buttonState, setButtonState] = React.useState({ previous: true, next: true });
|
9620
|
+
const numberOfChildren = React__default['default'].Children.count(children);
|
9621
|
+
const lastPage = Math.ceil(numberOfChildren / childrenPerPage) - 1;
|
9622
|
+
const paginatedChildren = React.useMemo(() => {
|
9623
|
+
return bucketize(React__default['default'].Children.toArray(children), childrenPerPage);
|
9624
|
+
}, [children, childrenPerPage]);
|
9625
|
+
const firstIndexOfCurrentPage = page * childrenPerPage;
|
9626
|
+
const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage;
|
9627
|
+
const childrenOnCurrentPage = paginatedChildren[clippedPage];
|
9628
|
+
const showButtons = numberOfChildren > childrenPerPage;
|
9629
|
+
const onPreviousButtonClick = () => {
|
9630
|
+
setPage(page - 1);
|
9631
|
+
};
|
9632
|
+
const onNextButtonClick = () => {
|
9633
|
+
setPage(page + 1);
|
9634
|
+
};
|
9635
|
+
React.useEffect(() => {
|
9636
|
+
if (page > 0 && page < lastPage && showButtons) {
|
9637
|
+
// we are somewhere in between first and last pages.
|
9638
|
+
setButtonState({ previous: false, next: false });
|
9639
|
+
}
|
9640
|
+
else if (page === 0 && showButtons) {
|
9641
|
+
// we are on the first page.
|
9642
|
+
setButtonState({ previous: true, next: false });
|
9643
|
+
}
|
9644
|
+
else if (page === lastPage && showButtons) {
|
9645
|
+
// we are on the last page.
|
9646
|
+
setButtonState({ previous: false, next: true });
|
9647
|
+
}
|
9648
|
+
}, [page, numberOfChildren, lastPage, showButtons]);
|
9649
|
+
const childContainerStyle = React.useMemo(() => {
|
9650
|
+
return { root: childrenContainerStyle };
|
9651
|
+
}, []);
|
9652
|
+
const childrenStyles = React.useMemo(() => {
|
9653
|
+
return { root: styles === null || styles === void 0 ? void 0 : styles.children };
|
9654
|
+
}, [styles === null || styles === void 0 ? void 0 : styles.children]);
|
9655
|
+
if (childrenPerPage <= 0) {
|
9656
|
+
return React__default['default'].createElement(React__default['default'].Fragment, null);
|
9657
|
+
}
|
9658
|
+
return (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(rootStyle, styles === null || styles === void 0 ? void 0 : styles.root) },
|
9659
|
+
React__default['default'].createElement(react.Stack, { styles: childContainerStyle }, childrenOnCurrentPage.map((child, i) => {
|
9660
|
+
return (React__default['default'].createElement(react.Stack.Item, { key: i, styles: childrenStyles }, child));
|
9661
|
+
})),
|
9662
|
+
showButtons && (React__default['default'].createElement(VerticalGalleryControlBar, { buttonsDisabled: buttonState, onPreviousButtonClick: onPreviousButtonClick, onNextButtonClick: onNextButtonClick, totalPages: lastPage, currentPage: page }))));
|
9663
|
+
};
|
9664
|
+
const VerticalGalleryControlBar = (props) => {
|
9665
|
+
const { onNextButtonClick, onPreviousButtonClick, buttonsDisabled, currentPage, totalPages, styles } = props;
|
9666
|
+
const theme = useTheme();
|
9667
|
+
const pageCounterContainerStyles = React.useMemo(() => {
|
9668
|
+
return react.mergeStyles(pageNavigationControlBarContainerStyle, styles === null || styles === void 0 ? void 0 : styles.root);
|
9669
|
+
}, [styles === null || styles === void 0 ? void 0 : styles.root]);
|
9670
|
+
const previousButtonSyles = React.useMemo(() => {
|
9671
|
+
return react.mergeStyles(leftRightButtonStyles(theme), styles === null || styles === void 0 ? void 0 : styles.previousButton);
|
9672
|
+
}, [styles === null || styles === void 0 ? void 0 : styles.previousButton, theme]);
|
9673
|
+
const pageCounterStyles = React.useMemo(() => {
|
9674
|
+
return react.mergeStyles(participantPageCounter, styles === null || styles === void 0 ? void 0 : styles.counter);
|
9675
|
+
}, [styles === null || styles === void 0 ? void 0 : styles.counter]);
|
9676
|
+
const nextButtonsStyles = React.useMemo(() => {
|
9677
|
+
return react.mergeStyles(leftRightButtonStyles(theme), styles === null || styles === void 0 ? void 0 : styles.nextButton);
|
9678
|
+
}, [styles === null || styles === void 0 ? void 0 : styles.nextButton, theme]);
|
9679
|
+
const controlBarSpacing = { childrenGap: '0.5rem' };
|
9680
|
+
return (React__default['default'].createElement(react.Stack, { horizontalAlign: "center", tokens: controlBarSpacing, horizontal: true, className: pageCounterContainerStyles },
|
9681
|
+
React__default['default'].createElement(react.DefaultButton, { className: previousButtonSyles, onClick: onPreviousButtonClick, disabled: buttonsDisabled === null || buttonsDisabled === void 0 ? void 0 : buttonsDisabled.previous },
|
9682
|
+
React__default['default'].createElement(react.Icon, { iconName: "VerticalGalleryLeftButton", styles: navIconStyles })),
|
9683
|
+
React__default['default'].createElement(react.Text, { className: pageCounterStyles }, `${currentPage} / ${totalPages}`),
|
9684
|
+
React__default['default'].createElement(react.DefaultButton, { className: nextButtonsStyles, onClick: onNextButtonClick, disabled: buttonsDisabled === null || buttonsDisabled === void 0 ? void 0 : buttonsDisabled.next },
|
9685
|
+
React__default['default'].createElement(react.Icon, { iconName: "VerticalGalleryRightButton", styles: navIconStyles }))));
|
9686
|
+
};
|
9687
|
+
|
9688
|
+
// Copyright (c) Microsoft Corporation.
|
9689
|
+
/**
|
9690
|
+
* @private
|
9691
|
+
*/
|
9692
|
+
react.mergeStyles({ position: 'relative', width: '100%', height: '100%' });
|
9693
|
+
/**
|
9694
|
+
* Small floating modal width and height in rem for small screen
|
9695
|
+
*/
|
9696
|
+
const SMALL_FLOATING_MODAL_SIZE_PX = { width: 58, height: 104 };
|
9697
|
+
/**
|
9698
|
+
* Large floating modal width and height in rem for large screen
|
9699
|
+
* Aspect ratio: 16:9
|
9700
|
+
*/
|
9701
|
+
const LARGE_FLOATING_MODAL_SIZE_PX = { width: 215, height: 120 };
|
9702
|
+
/**
|
9703
|
+
* Vertical gallery floating modal width and height in rem
|
9704
|
+
* Aspect ratio: 16:9
|
9705
|
+
*/
|
9706
|
+
const VERTICAL_GALLERY_FLOATING_MODAL_SIZE_PX = { width: 144, height: 81 };
|
9707
|
+
/**
|
9708
|
+
* @private
|
9709
|
+
* z-index to ensure that the local video tile is above the video gallery.
|
9710
|
+
*/
|
9711
|
+
const LOCAL_VIDEO_TILE_ZINDEX = 2;
|
9712
|
+
/**
|
9713
|
+
* @private
|
9714
|
+
*/
|
9715
|
+
const localVideoTileContainerStyle = (theme, localVideoTileSize) => {
|
9716
|
+
return Object.assign({ minWidth: _pxToRem(localVideoTileSize.width), minHeight: _pxToRem(localVideoTileSize.height), position: 'absolute', bottom: _pxToRem(localVideoTileOuterPaddingPX), borderRadius: theme.effects.roundedCorner4, overflow: 'hidden' }, (theme.rtl
|
9717
|
+
? { left: _pxToRem(localVideoTileOuterPaddingPX) }
|
9718
|
+
: { right: _pxToRem(localVideoTileOuterPaddingPX) }));
|
9719
|
+
};
|
9720
|
+
/**
|
9721
|
+
* @private
|
9722
|
+
*/
|
9723
|
+
const localVideoTileWithControlsContainerStyle = (theme, localVideoTileSize) => {
|
9724
|
+
return react.concatStyleSets(localVideoTileContainerStyle(theme, localVideoTileSize), {
|
9725
|
+
root: { boxShadow: theme.effects.elevation8 }
|
9726
|
+
});
|
9727
|
+
};
|
9728
|
+
/**
|
9729
|
+
* @private
|
9730
|
+
*/
|
9731
|
+
const floatingLocalVideoModalStyle = (theme, modalSize) => {
|
9732
|
+
return react.concatStyleSets({
|
9733
|
+
main: localVideoTileContainerStyle(theme, modalSize)
|
9734
|
+
}, {
|
9735
|
+
main: {
|
9736
|
+
boxShadow: theme.effects.elevation8,
|
9737
|
+
':focus-within': {
|
9738
|
+
boxShadow: theme.effects.elevation16,
|
9739
|
+
border: `${_pxToRem(2)} solid ${theme.palette.neutralPrimary}`
|
9740
|
+
}
|
9741
|
+
}
|
9742
|
+
}, localVideoModalStyles);
|
9743
|
+
};
|
9744
|
+
/**
|
9745
|
+
* Padding equal to the amount the modal should stay inside the bounds of the container.
|
9746
|
+
* i.e. if this is 8px, the modal should always be at least 8px inside the container at all times on all sides.
|
9747
|
+
* @private
|
9748
|
+
*/
|
9749
|
+
const localVideoTileOuterPaddingPX = 8;
|
9750
|
+
/**
|
9751
|
+
* @private
|
9752
|
+
*/
|
9753
|
+
const floatingLocalVideoTileStyle = {
|
9754
|
+
root: {
|
9755
|
+
position: 'absolute',
|
9756
|
+
zIndex: LOCAL_VIDEO_TILE_ZINDEX,
|
9757
|
+
height: '100%',
|
9758
|
+
width: '100%'
|
9759
|
+
}
|
9542
9760
|
};
|
9543
9761
|
/**
|
9544
|
-
*
|
9762
|
+
* Styles for the local video tile modal when it is focused, will cause keyboard move icon to appear over video
|
9545
9763
|
* @private
|
9546
9764
|
*/
|
9547
|
-
const
|
9548
|
-
|
9549
|
-
|
9765
|
+
const localVideoModalStyles = {
|
9766
|
+
keyboardMoveIconContainer: {
|
9767
|
+
zIndex: LOCAL_VIDEO_TILE_ZINDEX + 1 // zIndex to set the keyboard movement Icon above the other layers in the video tile.
|
9768
|
+
}
|
9550
9769
|
};
|
9551
9770
|
|
9552
9771
|
// Copyright (c) Microsoft Corporation.
|
9553
|
-
// Licensed under the MIT license.
|
9554
9772
|
/**
|
9555
|
-
*
|
9773
|
+
* VerticalGallery tile size in rem:
|
9774
|
+
*
|
9775
|
+
* min - smallest possible size of the tile (90px)
|
9776
|
+
* max - Largest size we want the vertical tiles (144px)
|
9777
|
+
*
|
9778
|
+
* @private
|
9556
9779
|
*/
|
9557
|
-
const
|
9780
|
+
const VERTICAL_GALLERY_TILE_SIZE_REM = { minHeight: 5.625, maxHeight: 9, width: 9 };
|
9558
9781
|
/**
|
9559
|
-
*
|
9782
|
+
* Styles for the VerticalGallery's container set in parent.
|
9783
|
+
*
|
9784
|
+
* width is being increased by 1rem to account for the gap width desired for the VerticalGallery.
|
9785
|
+
*
|
9786
|
+
* @param shouldFloatLocalVideo whether rendered in floating layout or not
|
9787
|
+
* @returns Style set for VerticalGallery container.
|
9560
9788
|
*/
|
9561
|
-
const
|
9789
|
+
const verticalGalleryContainerStyle = (shouldFloatLocalVideo) => {
|
9562
9790
|
return {
|
9563
|
-
|
9564
|
-
|
9565
|
-
|
9566
|
-
minWidth: `${HORIZONTAL_GALLERY_BUTTON_WIDTH}rem`,
|
9567
|
-
maxWidth: `${HORIZONTAL_GALLERY_BUTTON_WIDTH}rem`,
|
9568
|
-
border: `1px solid ${theme.palette.neutralLight}`,
|
9569
|
-
borderRadius: theme.effects.roundedCorner4
|
9791
|
+
width: `${VERTICAL_GALLERY_TILE_SIZE_REM.width}rem`,
|
9792
|
+
height: shouldFloatLocalVideo ? `calc(100% - ${_pxToRem(VERTICAL_GALLERY_FLOATING_MODAL_SIZE_PX.height)})` : '100%',
|
9793
|
+
paddingBottom: '0.5rem'
|
9570
9794
|
};
|
9571
9795
|
};
|
9572
|
-
/**
|
9573
|
-
* Horizontal Gallery gap size in rem between tiles and buttons
|
9574
|
-
*/
|
9575
|
-
const HORIZONTAL_GALLERY_GAP = 0.5;
|
9576
9796
|
/**
|
9577
9797
|
* @private
|
9578
9798
|
*/
|
9579
|
-
const
|
9580
|
-
|
9581
|
-
|
9582
|
-
|
9799
|
+
const VERTICAL_GALLERY_TILE_STYLE = {
|
9800
|
+
minHeight: `${VERTICAL_GALLERY_TILE_SIZE_REM.minHeight}rem`,
|
9801
|
+
minWidth: `${VERTICAL_GALLERY_TILE_SIZE_REM.width}rem`,
|
9802
|
+
maxHeight: `${VERTICAL_GALLERY_TILE_SIZE_REM.maxHeight}rem`,
|
9803
|
+
maxWidth: `${VERTICAL_GALLERY_TILE_SIZE_REM.width}rem`
|
9583
9804
|
};
|
9584
9805
|
/**
|
9585
9806
|
* @private
|
9586
9807
|
*/
|
9587
|
-
const
|
9588
|
-
|
9589
|
-
gap: `${HORIZONTAL_GALLERY_GAP}rem`
|
9808
|
+
const verticalGalleryStyle = {
|
9809
|
+
children: VERTICAL_GALLERY_TILE_STYLE
|
9590
9810
|
};
|
9591
9811
|
|
9592
9812
|
// Copyright (c) Microsoft Corporation.
|
9593
9813
|
/**
|
9594
|
-
*
|
9814
|
+
* Responsive container for the VerticalGallery Component. Performs calculations for number of children
|
9815
|
+
* for the VerticalGallery
|
9816
|
+
* @param props
|
9817
|
+
*
|
9818
|
+
* @beta
|
9595
9819
|
*/
|
9596
|
-
const
|
9820
|
+
const ResponsiveVerticalGallery = (props) => {
|
9821
|
+
const { children, containerStyles, verticalGalleryStyles, gapHeightRem, controlBarHeightRem } = props;
|
9822
|
+
const containerRef = React.useRef(null);
|
9823
|
+
const containerHeight = _useContainerHeight(containerRef);
|
9824
|
+
const topPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingTop) : 0;
|
9825
|
+
const bottomPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingBottom) : 0;
|
9826
|
+
const childrenPerPage = calculateChildrenPerPage({
|
9827
|
+
numberOfChildren: React__default['default'].Children.count(children),
|
9828
|
+
containerHeight: (containerHeight !== null && containerHeight !== void 0 ? containerHeight : 0) - topPadding - bottomPadding,
|
9829
|
+
gapHeightRem,
|
9830
|
+
controlBarHeight: controlBarHeightRem !== null && controlBarHeightRem !== void 0 ? controlBarHeightRem : 2
|
9831
|
+
});
|
9832
|
+
return (React__default['default'].createElement("div", { ref: containerRef, className: react.mergeStyles(containerStyles) },
|
9833
|
+
React__default['default'].createElement(VerticalGallery, { childrenPerPage: childrenPerPage, styles: verticalGalleryStyles }, children)));
|
9834
|
+
};
|
9597
9835
|
/**
|
9598
|
-
*
|
9599
|
-
* @param props - HorizontalGalleryProps {@link @azure/communication-react#HorizontalGalleryProps}
|
9600
|
-
* @returns
|
9836
|
+
* Helper function to find the number of children for the VerticalGallery on each page.
|
9601
9837
|
*/
|
9602
|
-
const
|
9603
|
-
|
9604
|
-
const
|
9605
|
-
const
|
9606
|
-
const
|
9607
|
-
|
9608
|
-
|
9609
|
-
|
9610
|
-
|
9611
|
-
|
9612
|
-
|
9613
|
-
|
9614
|
-
|
9838
|
+
const calculateChildrenPerPage = (args) => {
|
9839
|
+
const { numberOfChildren, containerHeight, gapHeightRem, controlBarHeight } = args;
|
9840
|
+
const childMinHeightPx = _convertRemToPx(VERTICAL_GALLERY_TILE_SIZE_REM.minHeight);
|
9841
|
+
const gapHeightPx = _convertRemToPx(gapHeightRem);
|
9842
|
+
const controlBarHeightPx = _convertRemToPx(controlBarHeight);
|
9843
|
+
/** First check how many children can fit in containerHeight.
|
9844
|
+
*
|
9845
|
+
* _________________
|
9846
|
+
* | |
|
9847
|
+
* | |
|
9848
|
+
* |________________|
|
9849
|
+
* _________________
|
9850
|
+
* | |
|
9851
|
+
* | |
|
9852
|
+
* |________________|
|
9853
|
+
*
|
9854
|
+
* < n/m >
|
9855
|
+
*
|
9856
|
+
* number of children = container height - (2* gap height + button height) / childMinHeight
|
9857
|
+
*
|
9858
|
+
* we want to find the maximum number of children at the smallest size we can fit in the gallery and then resize them
|
9859
|
+
* to fill in the space as much as possible
|
9860
|
+
*
|
9861
|
+
* First we will find the max number of children without any controls we can fit.
|
9862
|
+
*/
|
9863
|
+
const maxNumberOfChildrenInContainer = Math.floor((containerHeight + gapHeightPx) / (childMinHeightPx + gapHeightPx));
|
9864
|
+
// if all of the children fit in the container just return the number of children
|
9865
|
+
if (numberOfChildren <= maxNumberOfChildrenInContainer) {
|
9866
|
+
return maxNumberOfChildrenInContainer;
|
9615
9867
|
}
|
9616
|
-
|
9617
|
-
|
9618
|
-
|
9619
|
-
|
9620
|
-
|
9621
|
-
|
9622
|
-
|
9623
|
-
|
9624
|
-
|
9625
|
-
|
9626
|
-
|
9627
|
-
|
9628
|
-
const theme = useTheme();
|
9629
|
-
return (React__default['default'].createElement(react.DefaultButton, { className: react.mergeStyles(leftRightButtonStyles(theme), props.styles), onClick: props.onClick, disabled: props.disabled, "data-ui-id": props.identifier }, props.icon));
|
9868
|
+
/**
|
9869
|
+
* For the pagination we know the container height, the height of the button bar and the 2 times the gap
|
9870
|
+
* height, top tile and bottom tile above control bar. So the child space is calculated as:
|
9871
|
+
*
|
9872
|
+
* space = height - controlbar - (2 * gap)
|
9873
|
+
*/
|
9874
|
+
const childSpace = containerHeight - controlBarHeightPx - 2 * gapHeightPx;
|
9875
|
+
/**
|
9876
|
+
* Now that we have the childrenSpace height we can figure out how many Children can fir in the childrenSpace.
|
9877
|
+
* childrenSpace = n * childHeightMin + (n - 1) * gapHeight. isolate n and take the floor.
|
9878
|
+
*/
|
9879
|
+
return Math.floor((childSpace + gapHeightPx) / (childMinHeightPx + gapHeightPx));
|
9630
9880
|
};
|
9631
|
-
function bucketize(arr, bucketSize) {
|
9632
|
-
const bucketArray = [];
|
9633
|
-
if (bucketSize <= 0) {
|
9634
|
-
return bucketArray;
|
9635
|
-
}
|
9636
|
-
for (let i = 0; i < arr.length; i += bucketSize) {
|
9637
|
-
bucketArray.push(arr.slice(i, i + bucketSize));
|
9638
|
-
}
|
9639
|
-
return bucketArray;
|
9640
|
-
}
|
9641
9881
|
|
9642
9882
|
// Copyright (c) Microsoft Corporation.
|
9643
9883
|
/**
|
9644
|
-
*
|
9645
|
-
* available width obtained from a ResizeObserver, width per child, gap width, and button width
|
9884
|
+
* @private
|
9646
9885
|
*/
|
9647
|
-
const
|
9648
|
-
|
9649
|
-
|
9650
|
-
|
9651
|
-
|
9652
|
-
|
9653
|
-
|
9654
|
-
|
9655
|
-
|
9656
|
-
|
9657
|
-
|
9658
|
-
|
9659
|
-
});
|
9660
|
-
return (React__default['default'].createElement("div", { ref: containerRef, className: react.mergeStyles(props.containerStyles) },
|
9661
|
-
React__default['default'].createElement(HorizontalGallery, { childrenPerPage: childrenPerPage, styles: props.horizontalGalleryStyles }, props.children)));
|
9886
|
+
const horizontalGalleryContainerStyle = (shouldFloatLocalVideo, isNarrow) => {
|
9887
|
+
return {
|
9888
|
+
minHeight: isNarrow
|
9889
|
+
? `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`
|
9890
|
+
: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9891
|
+
width: shouldFloatLocalVideo
|
9892
|
+
? isNarrow
|
9893
|
+
? `calc(100% - ${_pxToRem(SMALL_FLOATING_MODAL_SIZE_PX.width)})`
|
9894
|
+
: `calc(100% - ${_pxToRem(LARGE_FLOATING_MODAL_SIZE_PX.width)})`
|
9895
|
+
: '100%',
|
9896
|
+
paddingRight: '0.5rem'
|
9897
|
+
};
|
9662
9898
|
};
|
9663
9899
|
/**
|
9664
|
-
*
|
9665
|
-
* gaps in between
|
9900
|
+
* @private
|
9666
9901
|
*/
|
9667
|
-
const
|
9668
|
-
|
9669
|
-
|
9670
|
-
|
9671
|
-
|
9672
|
-
|
9673
|
-
|
9674
|
-
|
9675
|
-
|
9676
|
-
|
9677
|
-
|
9678
|
-
|
9679
|
-
|
9680
|
-
|
9681
|
-
|
9682
|
-
|
9902
|
+
const horizontalGalleryStyle = (isNarrow) => {
|
9903
|
+
return {
|
9904
|
+
children: isNarrow ? SMALL_HORIZONTAL_GALLERY_TILE_STYLE : LARGE_HORIZONTAL_GALLERY_TILE_STYLE
|
9905
|
+
};
|
9906
|
+
};
|
9907
|
+
/**
|
9908
|
+
* Small horizontal gallery tile size in rem
|
9909
|
+
* @private
|
9910
|
+
*/
|
9911
|
+
const SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM = { height: 6.5, width: 6.5 };
|
9912
|
+
/**
|
9913
|
+
* Large horizontal gallery tile size in rem
|
9914
|
+
* @private
|
9915
|
+
*/
|
9916
|
+
const LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM = { height: 7.5, width: 10 };
|
9917
|
+
/**
|
9918
|
+
* @private
|
9919
|
+
*/
|
9920
|
+
const SMALL_HORIZONTAL_GALLERY_TILE_STYLE = {
|
9921
|
+
minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9922
|
+
minWidth: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`,
|
9923
|
+
maxHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9924
|
+
maxWidth: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`
|
9925
|
+
};
|
9926
|
+
/**
|
9927
|
+
* @private
|
9928
|
+
*/
|
9929
|
+
const LARGE_HORIZONTAL_GALLERY_TILE_STYLE = {
|
9930
|
+
minHeight: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9931
|
+
minWidth: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`,
|
9932
|
+
maxHeight: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9933
|
+
maxWidth: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`
|
9934
|
+
};
|
9935
|
+
|
9936
|
+
// Copyright (c) Microsoft Corporation.
|
9937
|
+
/**
|
9938
|
+
* @private
|
9939
|
+
*/
|
9940
|
+
const scrollableHorizontalGalleryStyles = {
|
9941
|
+
root: {
|
9942
|
+
width: '100%',
|
9943
|
+
minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9944
|
+
paddingRight: '0.5rem',
|
9945
|
+
'> *': SMALL_HORIZONTAL_GALLERY_TILE_STYLE
|
9683
9946
|
}
|
9684
|
-
|
9685
|
-
|
9686
|
-
|
9687
|
-
|
9688
|
-
|
9689
|
-
|
9690
|
-
|
9691
|
-
|
9692
|
-
|
9693
|
-
|
9694
|
-
|
9695
|
-
|
9696
|
-
|
9697
|
-
|
9947
|
+
};
|
9948
|
+
/**
|
9949
|
+
* @private
|
9950
|
+
*/
|
9951
|
+
const scrollableHorizontalGalleryContainerStyles = react.mergeStyles({
|
9952
|
+
display: 'flex',
|
9953
|
+
width: `calc(100% - ${SMALL_FLOATING_MODAL_SIZE_PX.width}px)`,
|
9954
|
+
minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
|
9955
|
+
overflow: 'scroll',
|
9956
|
+
'-ms-overflow-style': 'none',
|
9957
|
+
'scrollbar-width': 'none',
|
9958
|
+
'::-webkit-scrollbar': { display: 'none' }
|
9959
|
+
});
|
9960
|
+
|
9961
|
+
// Copyright (c) Microsoft Corporation.
|
9962
|
+
/**
|
9963
|
+
* Component to display elements horizontally in a scrollable container
|
9964
|
+
* @private
|
9965
|
+
*/
|
9966
|
+
const ScrollableHorizontalGallery = (props) => {
|
9967
|
+
const { horizontalGalleryElements } = props;
|
9968
|
+
const ref = React.useRef();
|
9969
|
+
const { events: dragabbleEvents } = reactUseDraggableScroll.useDraggable(ref);
|
9970
|
+
return (React__default['default'].createElement("div", Object.assign({ ref: ref }, dragabbleEvents, { className: scrollableHorizontalGalleryContainerStyles }),
|
9971
|
+
React__default['default'].createElement(react.Stack, { "data-ui-id": "scrollable-horizontal-gallery", horizontal: true, styles: scrollableHorizontalGalleryStyles, tokens: { childrenGap: '0.5rem' } }, horizontalGalleryElements)));
|
9698
9972
|
};
|
9699
9973
|
|
9700
9974
|
// Copyright (c) Microsoft Corporation.
|
@@ -9703,11 +9977,32 @@ const calculateChildrenPerPage = (args) => {
|
|
9703
9977
|
*
|
9704
9978
|
* @private
|
9705
9979
|
*/
|
9706
|
-
const
|
9707
|
-
const { shouldFloatLocalVideo = false, isNarrow = false,
|
9708
|
-
|
9709
|
-
const
|
9710
|
-
|
9980
|
+
const OverflowGallery = (props) => {
|
9981
|
+
const { shouldFloatLocalVideo = false, isNarrow = false, overflowGalleryElements, styles,
|
9982
|
+
/* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout = 'HorizontalBottom' } = props;
|
9983
|
+
const containerStyles = React.useMemo(() => {
|
9984
|
+
/* @conditional-compile-remove(vertical-gallery) */
|
9985
|
+
if (overflowGalleryLayout === 'VerticalRight') {
|
9986
|
+
return verticalGalleryContainerStyle(shouldFloatLocalVideo);
|
9987
|
+
}
|
9988
|
+
return horizontalGalleryContainerStyle(shouldFloatLocalVideo, isNarrow);
|
9989
|
+
}, [shouldFloatLocalVideo, isNarrow, /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout]);
|
9990
|
+
const galleryStyles = React.useMemo(() => {
|
9991
|
+
/* @conditional-compile-remove(vertical-gallery) */
|
9992
|
+
if (overflowGalleryLayout === 'VerticalRight') {
|
9993
|
+
return react.concatStyleSets(verticalGalleryStyle, styles);
|
9994
|
+
}
|
9995
|
+
return react.concatStyleSets(horizontalGalleryStyle(isNarrow), styles);
|
9996
|
+
}, [isNarrow, styles, /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout]);
|
9997
|
+
/* @conditional-compile-remove(vertical-gallery) */
|
9998
|
+
if (overflowGalleryLayout === 'VerticalRight') {
|
9999
|
+
return (React__default['default'].createElement(ResponsiveVerticalGallery, { key: "responsive-vertical-gallery", containerStyles: containerStyles, verticalGalleryStyles: galleryStyles, controlBarHeightRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapHeightRem: HORIZONTAL_GALLERY_GAP }, overflowGalleryElements));
|
10000
|
+
}
|
10001
|
+
/* @conditional-compile-remove(pinned-participants) */
|
10002
|
+
if (isNarrow) {
|
10003
|
+
return React__default['default'].createElement(ScrollableHorizontalGallery, { horizontalGalleryElements: overflowGalleryElements });
|
10004
|
+
}
|
10005
|
+
return (React__default['default'].createElement(ResponsiveHorizontalGallery, { key: "responsive-horizontal-gallery", containerStyles: containerStyles, horizontalGalleryStyles: galleryStyles, childWidthRem: isNarrow ? SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width : LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width, buttonWidthRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapWidthRem: HORIZONTAL_GALLERY_GAP }, overflowGalleryElements));
|
9711
10006
|
};
|
9712
10007
|
|
9713
10008
|
// Copyright (c) Microsoft Corporation.
|
@@ -9719,7 +10014,8 @@ const VideoGalleryResponsiveHorizontalGallery = (props) => {
|
|
9719
10014
|
*/
|
9720
10015
|
const DefaultLayout = (props) => {
|
9721
10016
|
const { remoteParticipants = [], dominantSpeakers, localVideoComponent, screenShareComponent, onRenderRemoteParticipant, styles, maxRemoteVideoStreams, parentWidth,
|
9722
|
-
/* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds
|
10017
|
+
/* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds,
|
10018
|
+
/* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout = 'HorizontalBottom' } = props;
|
9723
10019
|
const isNarrow = parentWidth ? isNarrowWidth(parentWidth) : false;
|
9724
10020
|
const { gridParticipants, horizontalGalleryParticipants } = useOrganizedParticipants({
|
9725
10021
|
remoteParticipants,
|
@@ -9744,19 +10040,26 @@ const DefaultLayout = (props) => {
|
|
9744
10040
|
if (localVideoComponent) {
|
9745
10041
|
gridTiles.push(localVideoComponent);
|
9746
10042
|
}
|
9747
|
-
const
|
10043
|
+
const overflowGallery = React.useMemo(() => {
|
9748
10044
|
if (horizontalGalleryTiles.length === 0) {
|
9749
10045
|
return null;
|
9750
10046
|
}
|
9751
|
-
|
9752
|
-
|
9753
|
-
|
9754
|
-
|
9755
|
-
|
9756
|
-
|
9757
|
-
|
10047
|
+
return (React__default['default'].createElement(OverflowGallery, { isNarrow: isNarrow, shouldFloatLocalVideo: false, overflowGalleryElements: horizontalGalleryTiles, styles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
|
10048
|
+
/* @conditional-compile-remove(pinned-participants) */
|
10049
|
+
overflowGalleryLayout: overflowGalleryLayout }));
|
10050
|
+
}, [
|
10051
|
+
isNarrow,
|
10052
|
+
horizontalGalleryTiles,
|
10053
|
+
styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
|
10054
|
+
/* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout
|
10055
|
+
]);
|
10056
|
+
return (React__default['default'].createElement(react.Stack
|
10057
|
+
/* @conditional-compile-remove(vertical-gallery) */
|
10058
|
+
, {
|
10059
|
+
/* @conditional-compile-remove(vertical-gallery) */
|
10060
|
+
horizontal: overflowGalleryLayout === 'VerticalRight', styles: rootLayoutStyle$1, tokens: videoGalleryLayoutGap },
|
9758
10061
|
screenShareComponent ? (screenShareComponent) : (React__default['default'].createElement(GridLayout, { key: "grid-layout", styles: styles === null || styles === void 0 ? void 0 : styles.gridLayout }, gridTiles)),
|
9759
|
-
|
10062
|
+
overflowGallery));
|
9760
10063
|
};
|
9761
10064
|
|
9762
10065
|
// Copyright (c) Microsoft Corporation.
|
@@ -10447,21 +10750,19 @@ const modalMaxDragPosition = { x: localVideoTileOuterPaddingPX, y: localVideoTil
|
|
10447
10750
|
* @private
|
10448
10751
|
*/
|
10449
10752
|
const FloatingLocalVideo = (props) => {
|
10450
|
-
const { localVideoComponent, layerHostId,
|
10753
|
+
const { localVideoComponent, layerHostId, localVideoSize, parentWidth, parentHeight } = props;
|
10451
10754
|
const theme = useTheme();
|
10452
|
-
const modalWidth = isNarrow ? SMALL_FLOATING_MODAL_SIZE_PX.width : LARGE_FLOATING_MODAL_SIZE_PX.width;
|
10453
|
-
const modalHeight = isNarrow ? SMALL_FLOATING_MODAL_SIZE_PX.height : LARGE_FLOATING_MODAL_SIZE_PX.height;
|
10454
10755
|
// The minimum drag position is the top left of the video gallery. i.e. the modal (PiP) should not be able
|
10455
10756
|
// to be dragged offscreen and these are the top and left bounds of that calculation.
|
10456
10757
|
const modalMinDragPosition = React.useMemo(() => parentWidth && parentHeight
|
10457
10758
|
? {
|
10458
10759
|
// We use -parentWidth/Height because our modal is positioned to start in the bottom right,
|
10459
10760
|
// hence (0,0) is the bottom right of the video gallery.
|
10460
|
-
x: -parentWidth +
|
10461
|
-
y: -parentHeight +
|
10761
|
+
x: -parentWidth + localVideoSize.width + localVideoTileOuterPaddingPX,
|
10762
|
+
y: -parentHeight + localVideoSize.height + localVideoTileOuterPaddingPX
|
10462
10763
|
}
|
10463
|
-
: undefined, [parentHeight, parentWidth,
|
10464
|
-
const modalStyles = React.useMemo(() => floatingLocalVideoModalStyle(theme,
|
10764
|
+
: undefined, [parentHeight, parentWidth, localVideoSize.width, localVideoSize.height]);
|
10765
|
+
const modalStyles = React.useMemo(() => floatingLocalVideoModalStyle(theme, localVideoSize), [theme, localVideoSize]);
|
10465
10766
|
const layerProps = React.useMemo(() => ({ hostId: layerHostId }), [layerHostId]);
|
10466
10767
|
return (React__default['default'].createElement(_ModalClone, { isOpen: true, isModeless: true, dragOptions: DRAG_OPTIONS$1, styles: modalStyles, layerProps: layerProps, maxDragPosition: modalMaxDragPosition, minDragPosition: modalMinDragPosition }, localVideoComponent));
|
10467
10768
|
};
|
@@ -10503,7 +10804,8 @@ const layerHostStyle = {
|
|
10503
10804
|
*/
|
10504
10805
|
const FloatingLocalVideoLayout = (props) => {
|
10505
10806
|
const { remoteParticipants = [], dominantSpeakers, localVideoComponent, screenShareComponent, onRenderRemoteParticipant, styles, maxRemoteVideoStreams, showCameraSwitcherInLocalPreview, parentWidth, parentHeight,
|
10506
|
-
/* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds
|
10807
|
+
/* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds,
|
10808
|
+
/* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout = 'HorizontalBottom' } = props;
|
10507
10809
|
const theme = useTheme();
|
10508
10810
|
const isNarrow = parentWidth ? isNarrowWidth(parentWidth) : false;
|
10509
10811
|
const { gridParticipants, horizontalGalleryParticipants } = useOrganizedParticipants({
|
@@ -10531,28 +10833,43 @@ const FloatingLocalVideoLayout = (props) => {
|
|
10531
10833
|
: (_b = p.videoStream) === null || _b === void 0 ? void 0 : _b.isAvailable);
|
10532
10834
|
});
|
10533
10835
|
const layerHostId = reactHooks.useId('layerhost');
|
10836
|
+
let localVideoSize = LARGE_FLOATING_MODAL_SIZE_PX;
|
10837
|
+
if (isNarrow) {
|
10838
|
+
localVideoSize = SMALL_FLOATING_MODAL_SIZE_PX;
|
10839
|
+
}
|
10840
|
+
/* @conditional-compile-remove(vertical-gallery) */
|
10841
|
+
if (overflowGalleryLayout === 'VerticalRight') {
|
10842
|
+
localVideoSize = VERTICAL_GALLERY_FLOATING_MODAL_SIZE_PX;
|
10843
|
+
}
|
10534
10844
|
const wrappedLocalVideoComponent = localVideoComponent && shouldFloatLocalVideo ? (
|
10535
10845
|
// When we use showCameraSwitcherInLocalPreview it disables dragging to allow keyboard navigation.
|
10536
|
-
showCameraSwitcherInLocalPreview ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileWithControlsContainerStyle(theme,
|
10846
|
+
showCameraSwitcherInLocalPreview ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileWithControlsContainerStyle(theme, localVideoSize), {
|
10537
10847
|
boxShadow: theme.effects.elevation8,
|
10538
10848
|
zIndex: LOCAL_VIDEO_TILE_ZINDEX
|
10539
|
-
}) }, localVideoComponent)) : horizontalGalleryTiles.length > 0 ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileContainerStyle(theme,
|
10540
|
-
const
|
10849
|
+
}) }, localVideoComponent)) : horizontalGalleryTiles.length > 0 ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileContainerStyle(theme, localVideoSize)) }, localVideoComponent)) : (React__default['default'].createElement(FloatingLocalVideo, { localVideoComponent: localVideoComponent, layerHostId: layerHostId, localVideoSize: localVideoSize, parentWidth: parentWidth, parentHeight: parentHeight }))) : undefined;
|
10850
|
+
const overflowGallery = React.useMemo(() => {
|
10541
10851
|
if (horizontalGalleryTiles.length === 0) {
|
10542
10852
|
return null;
|
10543
10853
|
}
|
10544
|
-
|
10545
|
-
|
10546
|
-
|
10547
|
-
|
10548
|
-
|
10549
|
-
|
10854
|
+
return (React__default['default'].createElement(OverflowGallery, { isNarrow: isNarrow, shouldFloatLocalVideo: true, overflowGalleryElements: horizontalGalleryTiles, styles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
|
10855
|
+
/* @conditional-compile-remove(vertical-gallery) */
|
10856
|
+
overflowGalleryLayout: overflowGalleryLayout }));
|
10857
|
+
}, [
|
10858
|
+
isNarrow,
|
10859
|
+
horizontalGalleryTiles,
|
10860
|
+
styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
|
10861
|
+
/* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout
|
10862
|
+
]);
|
10550
10863
|
return (React__default['default'].createElement(react.Stack, { styles: rootLayoutStyle },
|
10551
10864
|
wrappedLocalVideoComponent,
|
10552
10865
|
React__default['default'].createElement(react.LayerHost, { id: layerHostId, className: react.mergeStyles(layerHostStyle) }),
|
10553
|
-
React__default['default'].createElement(react.Stack
|
10866
|
+
React__default['default'].createElement(react.Stack
|
10867
|
+
/* @conditional-compile-remove(vertical-gallery) */
|
10868
|
+
, {
|
10869
|
+
/* @conditional-compile-remove(vertical-gallery) */
|
10870
|
+
horizontal: overflowGalleryLayout === 'VerticalRight', styles: innerLayoutStyle, tokens: videoGalleryLayoutGap },
|
10554
10871
|
screenShareComponent ? (screenShareComponent) : (React__default['default'].createElement(GridLayout, { key: "grid-layout", styles: styles === null || styles === void 0 ? void 0 : styles.gridLayout }, gridTiles)),
|
10555
|
-
|
10872
|
+
overflowGallery)));
|
10556
10873
|
};
|
10557
10874
|
|
10558
10875
|
// Copyright (c) Microsoft Corporation.
|
@@ -10588,7 +10905,9 @@ const VideoGallery = (props) => {
|
|
10588
10905
|
/* @conditional-compile-remove(pinned-participants) */
|
10589
10906
|
onUnpinParticipant: onUnpinParticipantHandler,
|
10590
10907
|
/* @conditional-compile-remove(pinned-participants) */
|
10591
|
-
remoteVideoTileMenuOptions = DEFAULT_REMOTE_VIDEO_TILE_MENU_OPTIONS
|
10908
|
+
remoteVideoTileMenuOptions = DEFAULT_REMOTE_VIDEO_TILE_MENU_OPTIONS,
|
10909
|
+
/* @conditional-compile-remove(vertical-gallery) */
|
10910
|
+
overflowGalleryLayout = 'HorizontalBottom' } = props;
|
10592
10911
|
const ids = useIdentifiers();
|
10593
10912
|
const theme = useTheme();
|
10594
10913
|
const localeStrings = useLocale$1().strings.videoGallery;
|
@@ -10748,7 +11067,8 @@ const VideoGallery = (props) => {
|
|
10748
11067
|
localVideoComponent: localVideoTile,
|
10749
11068
|
parentWidth: containerWidth,
|
10750
11069
|
parentHeight: containerHeight,
|
10751
|
-
/* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds: pinnedParticipants
|
11070
|
+
/* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds: pinnedParticipants,
|
11071
|
+
/* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout
|
10752
11072
|
}), [
|
10753
11073
|
remoteParticipants,
|
10754
11074
|
screenShareComponent,
|
@@ -10761,7 +11081,8 @@ const VideoGallery = (props) => {
|
|
10761
11081
|
containerHeight,
|
10762
11082
|
onRenderRemoteVideoTile,
|
10763
11083
|
defaultOnRenderVideoTile,
|
10764
|
-
/* @conditional-compile-remove(pinned-participants) */ pinnedParticipants
|
11084
|
+
/* @conditional-compile-remove(pinned-participants) */ pinnedParticipants,
|
11085
|
+
/* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout
|
10765
11086
|
]);
|
10766
11087
|
const videoGalleryLayout = React.useMemo(() => {
|
10767
11088
|
if (layout === 'floatingLocalVideo') {
|
@@ -14439,7 +14760,8 @@ class EventSubscriber {
|
|
14439
14760
|
});
|
14440
14761
|
this.fetchLastParticipantMessage(event.threadId, 'participantAdded');
|
14441
14762
|
};
|
14442
|
-
// This is a
|
14763
|
+
// This is a temporary fix that no participant message is received for onChatMessageReceived event, which should be handled by JS SDK.
|
14764
|
+
// Without the temporary fix, there are missing 'participant joined' and 'participant left' system messages in the chat thread.
|
14443
14765
|
this.fetchLastParticipantMessage = (threadId, actionType) => __awaiter$i(this, void 0, void 0, function* () {
|
14444
14766
|
var e_1, _a;
|
14445
14767
|
try {
|
@@ -14465,7 +14787,13 @@ class EventSubscriber {
|
|
14465
14787
|
return participant.id;
|
14466
14788
|
});
|
14467
14789
|
this.chatContext.deleteParticipants(event.threadId, participantIds);
|
14468
|
-
|
14790
|
+
// If the current user is removed from the thread, do not fetch the last participant message
|
14791
|
+
// as they no longer have access to the thread.
|
14792
|
+
const currentUserId = toFlatCommunicationIdentifier(this.chatContext.getState().userId);
|
14793
|
+
const wasCurrentUserRemoved = participantIds.find((id) => toFlatCommunicationIdentifier(id) === currentUserId);
|
14794
|
+
if (!wasCurrentUserRemoved) {
|
14795
|
+
this.fetchLastParticipantMessage(event.threadId, 'participantRemoved');
|
14796
|
+
}
|
14469
14797
|
};
|
14470
14798
|
this.onReadReceiptReceived = (event) => {
|
14471
14799
|
const readReceipt = Object.assign(Object.assign({}, event), { sender: event.sender, readOn: new Date(event.readOn) });
|