@whereby.com/browser-sdk 2.7.0-beta.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn/v2-embed.js +18 -0
- package/dist/cdn/v2-react.js +3 -0
- package/dist/embed/index.esm.js +1 -1
- package/dist/react/index.d.ts +8 -25
- package/dist/react/index.esm.js +8 -712
- package/package.json +2 -1
- package/dist/cdn/v2-embed-beta.js +0 -16
- package/dist/cdn/v2-react-beta.js +0 -3
package/dist/react/index.esm.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { useState, useEffect, useCallback } from 'react';
|
|
3
|
-
import { debounce } from '@whereby.com/core
|
|
4
|
-
import { selectChatMessages, selectCloudRecordingRaw, selectLocalParticipantRaw, selectLocalMediaStream, selectRemoteParticipants, selectScreenshares, selectRoomConnectionStatus, selectStreamingRaw, selectWaitingParticipants, createServices, createStore, observeStore, doAppJoin, sdkVersion, appLeft, doRtcReportStreamResolution, doSendChatMessage, doKnockRoom, doSetDisplayName, toggleCameraEnabled, toggleMicrophoneEnabled, doAcceptWaitingParticipant, doRejectWaitingParticipant, doStartCloudRecording, doStartScreenshare, doStopCloudRecording, doStopScreenshare, selectCameraDeviceError, selectCameraDevices, selectCurrentCameraDeviceId, selectCurrentMicrophoneDeviceId, selectIsSettingCameraDevice, selectIsSettingMicrophoneDevice, selectIsLocalMediaStarting, selectMicrophoneDeviceError, selectMicrophoneDevices, selectSpeakerDevices, selectLocalMediaStartError, doStartLocalMedia, doStopLocalMedia, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId } from '@whereby.com/core';
|
|
3
|
+
import { debounce, selectChatMessages, selectCloudRecordingRaw, selectLocalParticipantRaw, selectLocalMediaStream, selectRemoteParticipants, selectScreenshares, selectRoomConnectionStatus, selectStreamingRaw, selectWaitingParticipants, createServices, createStore, observeStore, doAppJoin, appLeft, doRtcReportStreamResolution, doSendChatMessage, doKnockRoom, doSetDisplayName, toggleCameraEnabled, toggleMicrophoneEnabled, doAcceptWaitingParticipant, doRejectWaitingParticipant, doStartCloudRecording, doStartScreenshare, doStopCloudRecording, doStopScreenshare, doLockRoom, selectCameraDeviceError, selectCameraDevices, selectCurrentCameraDeviceId, selectCurrentMicrophoneDeviceId, selectIsSettingCameraDevice, selectIsSettingMicrophoneDevice, selectIsLocalMediaStarting, selectMicrophoneDeviceError, selectMicrophoneDevices, selectSpeakerDevices, selectLocalMediaStartError, doStartLocalMedia, doStopLocalMedia, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId } from '@whereby.com/core';
|
|
5
4
|
import { createSelector } from '@reduxjs/toolkit';
|
|
6
5
|
|
|
7
6
|
/******************************************************************************
|
|
@@ -100,6 +99,8 @@ const selectRoomConnectionState = createSelector(selectChatMessages, selectCloud
|
|
|
100
99
|
return state;
|
|
101
100
|
});
|
|
102
101
|
|
|
102
|
+
const browserSdkVersion = "2.7.0";
|
|
103
|
+
|
|
103
104
|
const initialState$1 = {
|
|
104
105
|
chatMessages: [],
|
|
105
106
|
remoteParticipants: [],
|
|
@@ -127,7 +128,7 @@ function useRoomConnection(roomUrl, roomConnectionOptions = defaultRoomConnectio
|
|
|
127
128
|
const unsubscribe = observeStore(store, selectRoomConnectionState, setRoomConnectionState);
|
|
128
129
|
const url = new URL(roomUrl);
|
|
129
130
|
const searchParams = new URLSearchParams(url.search);
|
|
130
|
-
const roomKey = searchParams.get("roomKey");
|
|
131
|
+
const roomKey = roomConnectionOptions.roomKey || searchParams.get("roomKey");
|
|
131
132
|
store.dispatch(doAppJoin({
|
|
132
133
|
displayName: roomConnectionOptions.displayName || "Guest",
|
|
133
134
|
localMediaOptions: roomConnectionOptions.localMedia
|
|
@@ -135,7 +136,7 @@ function useRoomConnection(roomUrl, roomConnectionOptions = defaultRoomConnectio
|
|
|
135
136
|
: roomConnectionOptions.localMediaOptions,
|
|
136
137
|
roomKey,
|
|
137
138
|
roomUrl,
|
|
138
|
-
|
|
139
|
+
userAgent: `browser-sdk:${browserSdkVersion}`,
|
|
139
140
|
externalId: roomConnectionOptions.externalId || null,
|
|
140
141
|
}));
|
|
141
142
|
return () => {
|
|
@@ -169,11 +170,13 @@ function useRoomConnection(roomUrl, roomConnectionOptions = defaultRoomConnectio
|
|
|
169
170
|
const startScreenshare = React.useCallback(() => store.dispatch(doStartScreenshare()), [store]);
|
|
170
171
|
const stopCloudRecording = React.useCallback(() => store.dispatch(doStopCloudRecording()), [store]);
|
|
171
172
|
const stopScreenshare = React.useCallback(() => store.dispatch(doStopScreenshare()), [store]);
|
|
173
|
+
const lockRoom = React.useCallback((locked) => store.dispatch(doLockRoom({ locked })), [store]);
|
|
172
174
|
return {
|
|
173
175
|
state: roomConnectionState,
|
|
174
176
|
actions: {
|
|
175
177
|
sendChatMessage,
|
|
176
178
|
knock,
|
|
179
|
+
lockRoom,
|
|
177
180
|
setDisplayName,
|
|
178
181
|
toggleCamera,
|
|
179
182
|
toggleMicrophone,
|
|
@@ -250,711 +253,4 @@ function useLocalMedia(optionsOrStream = { audio: true, video: true }) {
|
|
|
250
253
|
};
|
|
251
254
|
}
|
|
252
255
|
|
|
253
|
-
|
|
254
|
-
var layoutConstants = {
|
|
255
|
-
MIN_WINDOW_HEIGHT: 320,
|
|
256
|
-
MIN_WINDOW_WIDTH: 320,
|
|
257
|
-
DESKTOP_BREAKPOINT: 1025,
|
|
258
|
-
TABLET_BREAKPOINT: 750,
|
|
259
|
-
PHONE_BREAKPOINT: 500,
|
|
260
|
-
TOP_TOOLBAR_HEIGHT: 40 + 8 * 2,
|
|
261
|
-
BOTTOM_TOOLBAR_HEIGHT: 70 + 4 * 3,
|
|
262
|
-
SIDEBAR_WIDTH: 375,
|
|
263
|
-
VIDEO_CONTROLS_MIN_WIDTH: VIDEO_CONTROLS_MIN_WIDTH$1,
|
|
264
|
-
ROOM_FOOTER_MIN_WIDTH: 60 * 3 + VIDEO_CONTROLS_MIN_WIDTH$1,
|
|
265
|
-
FLOATING_VIDEO_CONTROLS_BOTTOM_MARGIN: 20,
|
|
266
|
-
WATERMARK_BAR_HEIGHT: 32,
|
|
267
|
-
BREAKOUT_STAGE_BACKDROP_HEADER_HEIGHT: 20 + 8,
|
|
268
|
-
BREAKOUT_STAGE_BACKDROP_FOOTER_HEIGHT: 8 + 40 + 8,
|
|
269
|
-
SUBGRID_EMPTY_STAGE_MAX_WIDTH: 800,
|
|
270
|
-
GROUPS_CELL_MARGIN: 8,
|
|
271
|
-
GROUPS_CELL_PADDING: 12,
|
|
272
|
-
GROUPS_CELL_NAV_HEIGHT: 48 + 8,
|
|
273
|
-
GROUPS_CELL_AVATAR_WRAPPER_BOTTOM_MARGIN: 8,
|
|
274
|
-
GROUPS_CELL_AVATAR_GRID_GAP: 8,
|
|
275
|
-
GROUPS_CELL_MIN_WIDTH: 360,
|
|
276
|
-
GROUPS_CELL_MAX_WIDTH: 600,
|
|
277
|
-
GROUPS_ROW_HEIGHT: 72,
|
|
278
|
-
GROUPS_ROW_GAP: 1,
|
|
279
|
-
FOLDABLE_SCREEN_STAGE_PADDING: 8,
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
function makeOrigin({ top = 0, left = 0 } = {}) {
|
|
283
|
-
return {
|
|
284
|
-
top,
|
|
285
|
-
left,
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
function makeBounds({ width = 0, height = 0 } = {}) {
|
|
289
|
-
return {
|
|
290
|
-
width: Math.max(width, 0),
|
|
291
|
-
height: Math.max(height, 0),
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
function makeFrame({ top = 0, left = 0, width = 0, height = 0 } = {}) {
|
|
295
|
-
return {
|
|
296
|
-
bounds: makeBounds({ width, height }),
|
|
297
|
-
origin: makeOrigin({ top, left }),
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
function makeBox({ top = 0, left = 0, bottom = 0, right = 0 } = {}) {
|
|
301
|
-
return {
|
|
302
|
-
top,
|
|
303
|
-
left,
|
|
304
|
-
bottom,
|
|
305
|
-
right,
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
function fitToBounds(aspectRatio, containerSize) {
|
|
310
|
-
const { width, height } = containerSize;
|
|
311
|
-
const contentHeight = height;
|
|
312
|
-
const contentWidth = contentHeight * aspectRatio;
|
|
313
|
-
const scale = Math.min(width / contentWidth, height / contentHeight);
|
|
314
|
-
const adjustedWidth = contentWidth * scale;
|
|
315
|
-
const adjustedHeight = contentHeight * scale;
|
|
316
|
-
return { width: adjustedWidth, height: adjustedHeight };
|
|
317
|
-
}
|
|
318
|
-
const cellContentArea = ({ width, height, rows, cols, aspectRatio, }) => {
|
|
319
|
-
const bounds = fitToBounds(aspectRatio, { width: width / cols, height: height / rows });
|
|
320
|
-
return Math.round(bounds.width * bounds.height);
|
|
321
|
-
};
|
|
322
|
-
const getWeightedSplitCount = ({ vertical, width, height, count, aspectRatio, }) => {
|
|
323
|
-
const choices = [1, 2, 3].map((rowCols) => cellContentArea({
|
|
324
|
-
width,
|
|
325
|
-
height,
|
|
326
|
-
rows: vertical ? Math.ceil(count / rowCols) : rowCols,
|
|
327
|
-
cols: vertical ? rowCols : Math.ceil(count / rowCols),
|
|
328
|
-
aspectRatio,
|
|
329
|
-
}));
|
|
330
|
-
const closest = Math.max(...choices);
|
|
331
|
-
const splits = choices.indexOf(closest) + 1;
|
|
332
|
-
return { splits, weight: closest };
|
|
333
|
-
};
|
|
334
|
-
const getGridSplits = ({ width, height, count, aspectRatio, }) => {
|
|
335
|
-
const verticalPick = getWeightedSplitCount({ vertical: true, width, height, count, aspectRatio });
|
|
336
|
-
const horizontalPick = getWeightedSplitCount({ vertical: false, width, height, count, aspectRatio });
|
|
337
|
-
if (verticalPick.weight > horizontalPick.weight) {
|
|
338
|
-
return { splits: verticalPick.splits, vertical: true };
|
|
339
|
-
}
|
|
340
|
-
return { splits: horizontalPick.splits, vertical: false };
|
|
341
|
-
};
|
|
342
|
-
function getGridSizeForCount({ count, width, height, aspectRatio, }) {
|
|
343
|
-
if (count <= 1) {
|
|
344
|
-
return {
|
|
345
|
-
rows: 1,
|
|
346
|
-
cols: 1,
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
const { splits, vertical } = getGridSplits({ width, height, count, aspectRatio });
|
|
350
|
-
if (vertical) {
|
|
351
|
-
return {
|
|
352
|
-
rows: Math.ceil(count / splits),
|
|
353
|
-
cols: splits,
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
return {
|
|
357
|
-
rows: splits,
|
|
358
|
-
cols: Math.ceil(count / splits),
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
const WIDE_AR = 16 / 9;
|
|
363
|
-
const NORMAL_AR = 4 / 3;
|
|
364
|
-
const clamp = ({ value, min, max }) => Math.min(Math.max(value, min), max);
|
|
365
|
-
function hasDuplicates(...array) {
|
|
366
|
-
return new Set(array).size !== array.length;
|
|
367
|
-
}
|
|
368
|
-
function findMostCommon(arr) {
|
|
369
|
-
return arr.sort((a, b) => arr.filter((v) => v === a).length - arr.filter((v) => v === b).length).pop();
|
|
370
|
-
}
|
|
371
|
-
function pickCellAspectRatio({ choices = [] }) {
|
|
372
|
-
const minAr = Math.min(...choices);
|
|
373
|
-
const maxAr = Math.max(...choices);
|
|
374
|
-
let chosenAr = null;
|
|
375
|
-
if (minAr === maxAr) {
|
|
376
|
-
chosenAr = minAr;
|
|
377
|
-
}
|
|
378
|
-
else {
|
|
379
|
-
const dominantAr = hasDuplicates(choices) ? findMostCommon(choices) : maxAr;
|
|
380
|
-
chosenAr = clamp({ value: dominantAr || maxAr, min: NORMAL_AR, max: WIDE_AR });
|
|
381
|
-
}
|
|
382
|
-
return {
|
|
383
|
-
minAr,
|
|
384
|
-
maxAr,
|
|
385
|
-
chosenAr,
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
function getCenterPadding({ rows, cols, cellWidth, index, cellCount, gridGap, }) {
|
|
389
|
-
const max = rows * cols;
|
|
390
|
-
const leftOver = max - cellCount;
|
|
391
|
-
if (!leftOver) {
|
|
392
|
-
return 0;
|
|
393
|
-
}
|
|
394
|
-
const lastIndex = max - leftOver - 1;
|
|
395
|
-
const firstIndex = lastIndex - (cols - leftOver) + 1;
|
|
396
|
-
const lastRowPadding = (leftOver * cellWidth) / 2 + gridGap;
|
|
397
|
-
return index >= firstIndex && index <= lastIndex ? lastRowPadding : 0;
|
|
398
|
-
}
|
|
399
|
-
function getCellBounds({ width, height, rows, cols, gridGap, aspectRatio, }) {
|
|
400
|
-
const cellWidth = (width - (cols - 1) * gridGap) / cols;
|
|
401
|
-
const cellHeight = (height - (rows - 1) * gridGap) / rows;
|
|
402
|
-
const ar = cellWidth / cellHeight;
|
|
403
|
-
let horizontalCorrection = 0;
|
|
404
|
-
let verticalCorrection = 0;
|
|
405
|
-
if (aspectRatio < ar) {
|
|
406
|
-
horizontalCorrection = cellWidth - cellHeight * aspectRatio;
|
|
407
|
-
}
|
|
408
|
-
else if (aspectRatio > ar) {
|
|
409
|
-
verticalCorrection = cellHeight - cellWidth / aspectRatio;
|
|
410
|
-
}
|
|
411
|
-
const totalHorizontalCorrection = horizontalCorrection * cols;
|
|
412
|
-
const totalVerticalCorrection = verticalCorrection * rows;
|
|
413
|
-
return {
|
|
414
|
-
cellWidth: cellWidth - horizontalCorrection,
|
|
415
|
-
cellHeight: cellHeight - verticalCorrection,
|
|
416
|
-
extraHorizontalPadding: totalHorizontalCorrection / 2,
|
|
417
|
-
extraVerticalPadding: totalVerticalCorrection / 2,
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
function calculateLayout$1({ width, height, cellCount, gridGap, cellAspectRatios = [NORMAL_AR], paddings = makeBox(), }) {
|
|
421
|
-
if (!cellCount) {
|
|
422
|
-
return {
|
|
423
|
-
cellCount,
|
|
424
|
-
cellHeight: 0,
|
|
425
|
-
cellWidth: 0,
|
|
426
|
-
cols: 0,
|
|
427
|
-
rows: 0,
|
|
428
|
-
extraHorizontalPadding: 0,
|
|
429
|
-
extraVerticalPadding: 0,
|
|
430
|
-
gridGap,
|
|
431
|
-
paddings,
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
const contentWidth = width - (paddings.left + paddings.right);
|
|
435
|
-
const contentHeight = height - (paddings.top + paddings.bottom);
|
|
436
|
-
const cellAspectRatioTuple = pickCellAspectRatio({
|
|
437
|
-
choices: cellAspectRatios,
|
|
438
|
-
});
|
|
439
|
-
let cellAspectRatio = cellAspectRatioTuple.chosenAr;
|
|
440
|
-
const { rows, cols } = getGridSizeForCount({
|
|
441
|
-
count: cellCount,
|
|
442
|
-
width: contentWidth,
|
|
443
|
-
height: contentHeight,
|
|
444
|
-
aspectRatio: cellAspectRatio,
|
|
445
|
-
});
|
|
446
|
-
if (rows === 1) {
|
|
447
|
-
cellAspectRatio = clamp({
|
|
448
|
-
value: contentWidth / cols / contentHeight,
|
|
449
|
-
min: Math.min(cellAspectRatioTuple.chosenAr, cellAspectRatioTuple.maxAr),
|
|
450
|
-
max: Math.max(cellAspectRatioTuple.chosenAr, cellAspectRatioTuple.maxAr),
|
|
451
|
-
});
|
|
452
|
-
}
|
|
453
|
-
else if (cols === 1) {
|
|
454
|
-
cellAspectRatio = clamp({
|
|
455
|
-
value: contentWidth / (contentHeight / rows),
|
|
456
|
-
min: Math.min(cellAspectRatioTuple.chosenAr, cellAspectRatioTuple.maxAr),
|
|
457
|
-
max: Math.max(cellAspectRatioTuple.chosenAr, cellAspectRatioTuple.maxAr),
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
const { cellWidth, cellHeight, extraHorizontalPadding, extraVerticalPadding } = getCellBounds({
|
|
461
|
-
width: contentWidth,
|
|
462
|
-
height: contentHeight,
|
|
463
|
-
rows,
|
|
464
|
-
cols,
|
|
465
|
-
gridGap,
|
|
466
|
-
aspectRatio: cellAspectRatio,
|
|
467
|
-
});
|
|
468
|
-
return {
|
|
469
|
-
cellCount,
|
|
470
|
-
cellHeight,
|
|
471
|
-
cellWidth,
|
|
472
|
-
cols,
|
|
473
|
-
rows,
|
|
474
|
-
extraHorizontalPadding,
|
|
475
|
-
extraVerticalPadding,
|
|
476
|
-
gridGap,
|
|
477
|
-
paddings,
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
function getCellPropsAtIndexForLayout({ index, layout, }) {
|
|
481
|
-
const { cellWidth, cellHeight, rows, cols, cellCount, gridGap } = layout;
|
|
482
|
-
const top = Math.floor(index / cols);
|
|
483
|
-
const left = Math.floor(index % cols);
|
|
484
|
-
const leftPadding = getCenterPadding({ rows, cols, cellWidth, index, cellCount, gridGap });
|
|
485
|
-
return {
|
|
486
|
-
top: top * cellHeight + top * gridGap,
|
|
487
|
-
left: left * cellWidth + left * gridGap + leftPadding,
|
|
488
|
-
width: cellWidth,
|
|
489
|
-
height: cellHeight,
|
|
490
|
-
};
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
const { BOTTOM_TOOLBAR_HEIGHT, VIDEO_CONTROLS_MIN_WIDTH, TABLET_BREAKPOINT } = layoutConstants;
|
|
494
|
-
const MIN_GRID_HEIGHT = 200;
|
|
495
|
-
const MIN_GRID_WIDTH = 300;
|
|
496
|
-
const FLOATING_VIDEO_SIZE = 200;
|
|
497
|
-
const CONSTRAINED_OVERFLOW_TRIGGER = 12;
|
|
498
|
-
function getMinGridBounds({ cellCount }) {
|
|
499
|
-
const isSmallGrid = cellCount <= 6;
|
|
500
|
-
const minGridHeight = isSmallGrid ? MIN_GRID_HEIGHT - 50 : MIN_GRID_HEIGHT;
|
|
501
|
-
const minGridWidth = isSmallGrid ? MIN_GRID_WIDTH - 50 : MIN_GRID_WIDTH;
|
|
502
|
-
return makeBounds({ width: minGridWidth, height: minGridHeight });
|
|
503
|
-
}
|
|
504
|
-
function fitSupersizedContent({ bounds, aspectRatio, minGridContainerBounds, hasPresentationGrid, }) {
|
|
505
|
-
const { width, height } = bounds;
|
|
506
|
-
const hasVideoGrid = minGridContainerBounds.width > 0;
|
|
507
|
-
if (!hasVideoGrid) {
|
|
508
|
-
return {
|
|
509
|
-
isPortrait: width <= height,
|
|
510
|
-
supersizedContentBounds: bounds,
|
|
511
|
-
};
|
|
512
|
-
}
|
|
513
|
-
const minHorizontalSupersizedContentWidth = Math.round(width / 2);
|
|
514
|
-
const minVerticalSupersizedContentHeight = Math.round(height / 2);
|
|
515
|
-
const maxHorizontalSupersizedContentWidth = Math.max(width - minGridContainerBounds.width, 0);
|
|
516
|
-
const maxVerticalSupersizedContentHeight = Math.max(height - minGridContainerBounds.height, 0);
|
|
517
|
-
let isPortrait = maxHorizontalSupersizedContentWidth <= maxVerticalSupersizedContentHeight;
|
|
518
|
-
let horizontalCorrection = 0;
|
|
519
|
-
let verticalCorrection = 0;
|
|
520
|
-
if (aspectRatio) {
|
|
521
|
-
const horizontalContentBounds = fitToBounds(aspectRatio, {
|
|
522
|
-
width: maxHorizontalSupersizedContentWidth,
|
|
523
|
-
height,
|
|
524
|
-
});
|
|
525
|
-
const verticalContentBounds = fitToBounds(aspectRatio, {
|
|
526
|
-
width,
|
|
527
|
-
height: maxVerticalSupersizedContentHeight,
|
|
528
|
-
});
|
|
529
|
-
const isPortraitContent = aspectRatio <= 1.0;
|
|
530
|
-
isPortrait = isPortraitContent
|
|
531
|
-
? verticalContentBounds.height > horizontalContentBounds.height
|
|
532
|
-
: verticalContentBounds.width > horizontalContentBounds.width;
|
|
533
|
-
if (isPortrait) {
|
|
534
|
-
const wastedSpace = maxVerticalSupersizedContentHeight -
|
|
535
|
-
Math.max(verticalContentBounds.height, minVerticalSupersizedContentHeight);
|
|
536
|
-
verticalCorrection = Math.max(wastedSpace, 0);
|
|
537
|
-
}
|
|
538
|
-
else {
|
|
539
|
-
const wastedSpace = maxHorizontalSupersizedContentWidth -
|
|
540
|
-
Math.max(horizontalContentBounds.width, minHorizontalSupersizedContentWidth);
|
|
541
|
-
horizontalCorrection = Math.max(wastedSpace, 0);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
else if (hasPresentationGrid) {
|
|
545
|
-
isPortrait = maxHorizontalSupersizedContentWidth / maxVerticalSupersizedContentHeight >= 5;
|
|
546
|
-
}
|
|
547
|
-
const supersizedContentBounds = {
|
|
548
|
-
width: isPortrait ? width : maxHorizontalSupersizedContentWidth - horizontalCorrection,
|
|
549
|
-
height: isPortrait ? maxVerticalSupersizedContentHeight - verticalCorrection : height,
|
|
550
|
-
};
|
|
551
|
-
return {
|
|
552
|
-
isPortrait,
|
|
553
|
-
supersizedContentBounds,
|
|
554
|
-
};
|
|
555
|
-
}
|
|
556
|
-
function calculateStageLayout({ containerBounds, containerOrigin, hasConstrainedOverflow, hasPresentationContent, hasVideoContent, isPortrait, }) {
|
|
557
|
-
const hasVideos = hasPresentationContent || hasVideoContent;
|
|
558
|
-
if (!hasVideos) {
|
|
559
|
-
return {
|
|
560
|
-
isPortrait,
|
|
561
|
-
videosContainer: makeFrame(),
|
|
562
|
-
hasOverflow: false,
|
|
563
|
-
};
|
|
564
|
-
}
|
|
565
|
-
return {
|
|
566
|
-
isPortrait,
|
|
567
|
-
videosContainer: makeFrame(Object.assign(Object.assign({}, containerBounds), containerOrigin)),
|
|
568
|
-
hasOverflow: hasConstrainedOverflow,
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
function calculateVideosContainerLayout({ containerBounds, containerOrigin, gridGap, supersizedContentAspectRatio, hasPresentationContent, hasPresentationGrid, hasVideoContent, minGridBounds, }) {
|
|
572
|
-
const { width, height } = containerBounds;
|
|
573
|
-
let isPortrait = width <= height;
|
|
574
|
-
let presentationGridBounds = makeBounds();
|
|
575
|
-
let presentationGridOrigin = makeOrigin();
|
|
576
|
-
let videoGridBounds = hasVideoContent ? Object.assign({}, containerBounds) : makeBounds();
|
|
577
|
-
let videoGridOrigin = hasVideoContent ? Object.assign({}, containerOrigin) : makeOrigin();
|
|
578
|
-
if (hasPresentationContent) {
|
|
579
|
-
const minGridContainerBounds = makeBounds({
|
|
580
|
-
width: hasVideoContent ? minGridBounds.width + gridGap : 0,
|
|
581
|
-
height: hasVideoContent ? minGridBounds.height + gridGap : 0,
|
|
582
|
-
});
|
|
583
|
-
const supersizedContentLayout = fitSupersizedContent({
|
|
584
|
-
bounds: containerBounds,
|
|
585
|
-
aspectRatio: supersizedContentAspectRatio,
|
|
586
|
-
minGridContainerBounds,
|
|
587
|
-
hasPresentationGrid,
|
|
588
|
-
});
|
|
589
|
-
isPortrait = supersizedContentLayout.isPortrait;
|
|
590
|
-
presentationGridBounds = supersizedContentLayout.supersizedContentBounds;
|
|
591
|
-
presentationGridOrigin = Object.assign({}, containerOrigin);
|
|
592
|
-
if (hasVideoContent) {
|
|
593
|
-
videoGridBounds = makeBounds({
|
|
594
|
-
width: isPortrait
|
|
595
|
-
? containerBounds.width
|
|
596
|
-
: containerBounds.width - presentationGridBounds.width - gridGap,
|
|
597
|
-
height: isPortrait
|
|
598
|
-
? containerBounds.height - presentationGridBounds.height - gridGap
|
|
599
|
-
: containerBounds.height,
|
|
600
|
-
});
|
|
601
|
-
videoGridOrigin = makeOrigin({
|
|
602
|
-
top: isPortrait ? containerOrigin.top + presentationGridBounds.height + gridGap : containerOrigin.top,
|
|
603
|
-
left: isPortrait ? containerOrigin.left : containerOrigin.left + presentationGridBounds.width + gridGap,
|
|
604
|
-
});
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
return {
|
|
608
|
-
isPortrait,
|
|
609
|
-
presentationGrid: Object.assign({}, makeFrame(Object.assign(Object.assign({}, presentationGridBounds), presentationGridOrigin))),
|
|
610
|
-
videoGrid: makeFrame(Object.assign(Object.assign({}, videoGridBounds), videoGridOrigin)),
|
|
611
|
-
};
|
|
612
|
-
}
|
|
613
|
-
function calculateGridLayout({ containerBounds, paddings = makeBox(), videos, isConstrained, maxGridWidth, gridGap, }) {
|
|
614
|
-
const { width, height } = containerBounds;
|
|
615
|
-
const cappedWidth = maxGridWidth ? Math.min(width, maxGridWidth) : width;
|
|
616
|
-
const cellCount = videos.length;
|
|
617
|
-
let videoCells = null;
|
|
618
|
-
const cellAspectRatios = videos.map((video) => video.aspectRatio);
|
|
619
|
-
const minGridBounds = getMinGridBounds({ cellCount });
|
|
620
|
-
const gridLayout = calculateLayout$1({
|
|
621
|
-
width: cappedWidth,
|
|
622
|
-
height,
|
|
623
|
-
cellCount,
|
|
624
|
-
gridGap,
|
|
625
|
-
cellAspectRatios,
|
|
626
|
-
paddings,
|
|
627
|
-
});
|
|
628
|
-
videoCells = videos.map((video, index) => {
|
|
629
|
-
const cellProps = getCellPropsAtIndexForLayout({ index, layout: gridLayout });
|
|
630
|
-
const isSmallCell = gridLayout.cellWidth < minGridBounds.width;
|
|
631
|
-
const shouldZoom = isConstrained || isSmallCell;
|
|
632
|
-
const aspectRatio = shouldZoom ? gridLayout.cellWidth / gridLayout.cellHeight : video.aspectRatio;
|
|
633
|
-
return {
|
|
634
|
-
clientId: video.clientId,
|
|
635
|
-
isDraggable: video.isDraggable,
|
|
636
|
-
origin: makeOrigin({
|
|
637
|
-
top: cellProps.top,
|
|
638
|
-
left: cellProps.left,
|
|
639
|
-
}),
|
|
640
|
-
bounds: makeBounds({
|
|
641
|
-
width: cellProps.width,
|
|
642
|
-
height: cellProps.height,
|
|
643
|
-
}),
|
|
644
|
-
aspectRatio,
|
|
645
|
-
isSmallCell,
|
|
646
|
-
};
|
|
647
|
-
});
|
|
648
|
-
return {
|
|
649
|
-
videoCells,
|
|
650
|
-
extraHorizontalPadding: width !== cappedWidth
|
|
651
|
-
? gridLayout.extraHorizontalPadding + (width - cappedWidth) / 2
|
|
652
|
-
: gridLayout.extraHorizontalPadding,
|
|
653
|
-
extraVerticalPadding: gridLayout.extraVerticalPadding,
|
|
654
|
-
paddings: gridLayout.paddings,
|
|
655
|
-
gridGap,
|
|
656
|
-
};
|
|
657
|
-
}
|
|
658
|
-
function calculateFloatingLayout({ roomBounds, containerFrame, floatingVideo, videoControlsHeight, margin = 8, }) {
|
|
659
|
-
if (!floatingVideo) {
|
|
660
|
-
return null;
|
|
661
|
-
}
|
|
662
|
-
const bounds = fitToBounds(floatingVideo.aspectRatio, {
|
|
663
|
-
width: FLOATING_VIDEO_SIZE,
|
|
664
|
-
height: FLOATING_VIDEO_SIZE,
|
|
665
|
-
});
|
|
666
|
-
const isFloating = !(roomBounds.height - containerFrame.bounds.height - containerFrame.origin.top);
|
|
667
|
-
const isConstrained = containerFrame.bounds.width - (bounds.width + margin) * 2 < VIDEO_CONTROLS_MIN_WIDTH;
|
|
668
|
-
let verticalOffset = 0;
|
|
669
|
-
if (isFloating && isConstrained) {
|
|
670
|
-
verticalOffset = videoControlsHeight * -1;
|
|
671
|
-
}
|
|
672
|
-
else if (!isFloating && !isConstrained) {
|
|
673
|
-
verticalOffset = videoControlsHeight;
|
|
674
|
-
}
|
|
675
|
-
const origin = makeOrigin({
|
|
676
|
-
top: containerFrame.origin.top + (containerFrame.bounds.height - bounds.height - margin) + verticalOffset,
|
|
677
|
-
left: containerFrame.origin.left + (containerFrame.bounds.width - bounds.width - margin),
|
|
678
|
-
});
|
|
679
|
-
const videoCell = {
|
|
680
|
-
clientId: floatingVideo.clientId,
|
|
681
|
-
isDraggable: floatingVideo.isDraggable,
|
|
682
|
-
origin,
|
|
683
|
-
bounds,
|
|
684
|
-
aspectRatio: floatingVideo.aspectRatio,
|
|
685
|
-
isSmallCell: true,
|
|
686
|
-
};
|
|
687
|
-
return videoCell;
|
|
688
|
-
}
|
|
689
|
-
function rebalanceLayoutPaddedAreas({ a, b, gridGap, isPortrait, }) {
|
|
690
|
-
const aPad = isPortrait ? a.vertical : a.horizontal;
|
|
691
|
-
const bPad = isPortrait ? b.vertical : b.horizontal;
|
|
692
|
-
if (aPad === bPad) {
|
|
693
|
-
return { a: 0, b: 0 };
|
|
694
|
-
}
|
|
695
|
-
const sArea = aPad < bPad ? a : b;
|
|
696
|
-
const sAreaPad = isPortrait ? sArea.vertical : sArea.horizontal;
|
|
697
|
-
const spaceBetween = gridGap + (aPad + bPad);
|
|
698
|
-
const offset = (spaceBetween + sAreaPad) / 2 - sAreaPad;
|
|
699
|
-
return {
|
|
700
|
-
a: sArea === a ? offset : 0,
|
|
701
|
-
b: sArea === b ? offset : 0,
|
|
702
|
-
};
|
|
703
|
-
}
|
|
704
|
-
function rebalanceLayoutInPlace({ videosContainerLayout, gridLayout, presentationGridLayout, gridGap, }) {
|
|
705
|
-
const hasPresentationGrid = videosContainerLayout.presentationGrid.bounds.width > 0;
|
|
706
|
-
const hasVideoGrid = videosContainerLayout.videoGrid.bounds.width > 0;
|
|
707
|
-
if (hasPresentationGrid && hasVideoGrid) {
|
|
708
|
-
const correction = rebalanceLayoutPaddedAreas({
|
|
709
|
-
a: {
|
|
710
|
-
horizontal: presentationGridLayout.extraHorizontalPadding,
|
|
711
|
-
vertical: presentationGridLayout.extraVerticalPadding,
|
|
712
|
-
},
|
|
713
|
-
b: {
|
|
714
|
-
horizontal: gridLayout.extraHorizontalPadding,
|
|
715
|
-
vertical: gridLayout.extraVerticalPadding,
|
|
716
|
-
},
|
|
717
|
-
gridGap,
|
|
718
|
-
isPortrait: videosContainerLayout.isPortrait,
|
|
719
|
-
});
|
|
720
|
-
if (videosContainerLayout.isPortrait) {
|
|
721
|
-
videosContainerLayout.presentationGrid.origin.top += correction.a;
|
|
722
|
-
videosContainerLayout.videoGrid.origin.top -= correction.b;
|
|
723
|
-
correction.b;
|
|
724
|
-
}
|
|
725
|
-
else {
|
|
726
|
-
videosContainerLayout.presentationGrid.origin.left += correction.a;
|
|
727
|
-
videosContainerLayout.videoGrid.origin.left -= correction.b;
|
|
728
|
-
correction.b;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
function calculateGridLayouts({ gridGap, isConstrained, presentationVideos, videos, videosContainerLayout, gridLayoutPaddings = makeBox(), presentationGridLayoutPaddings = makeBox(), maxGridWidth, }) {
|
|
733
|
-
const gridLayout = calculateGridLayout({
|
|
734
|
-
containerBounds: videosContainerLayout.videoGrid.bounds,
|
|
735
|
-
gridGap,
|
|
736
|
-
isConstrained,
|
|
737
|
-
maxGridWidth,
|
|
738
|
-
paddings: gridLayoutPaddings,
|
|
739
|
-
videos,
|
|
740
|
-
});
|
|
741
|
-
const presentationGridLayout = calculateGridLayout({
|
|
742
|
-
containerBounds: videosContainerLayout.presentationGrid.bounds,
|
|
743
|
-
gridGap,
|
|
744
|
-
isConstrained,
|
|
745
|
-
maxGridWidth,
|
|
746
|
-
paddings: presentationGridLayoutPaddings,
|
|
747
|
-
videos: presentationVideos,
|
|
748
|
-
});
|
|
749
|
-
return { gridLayout, presentationGridLayout };
|
|
750
|
-
}
|
|
751
|
-
function calculateLayout({ floatingVideo = null, frame, gridGap = 0, isConstrained = false, isMaximizeMode = false, paddings = makeBox(), presentationVideos = [], rebalanceLayout = false, roomBounds, roomLayoutHasOverlow = false, videoControlsHeight = 0, videos = [], videoGridGap = 0, }) {
|
|
752
|
-
const hasPresentationContent = !!presentationVideos.length;
|
|
753
|
-
const hasPresentationGrid = presentationVideos.length > 1;
|
|
754
|
-
const supersizedContentAspectRatio = hasPresentationContent && !hasPresentationGrid ? presentationVideos[0].aspectRatio : 1;
|
|
755
|
-
const hasVideoContent = !!videos.length;
|
|
756
|
-
const width = frame.bounds.width - paddings.left - paddings.right;
|
|
757
|
-
let height = frame.bounds.height - paddings.top - paddings.bottom;
|
|
758
|
-
const maxGridWidth = Math.max(25 * 88, (80 / 100) * width);
|
|
759
|
-
const hasConstrainedOverflow = (isConstrained && videos.length > CONSTRAINED_OVERFLOW_TRIGGER) || false;
|
|
760
|
-
const lineHeight = height / 4;
|
|
761
|
-
const extraLines = Math.ceil((videos.length - CONSTRAINED_OVERFLOW_TRIGGER) / 3);
|
|
762
|
-
height = hasConstrainedOverflow ? height + lineHeight * extraLines : height;
|
|
763
|
-
const stageBounds = makeBounds({ width, height });
|
|
764
|
-
const stageOrigin = makeOrigin({ top: paddings.top, left: paddings.left });
|
|
765
|
-
const _minBounds = getMinGridBounds({ cellCount: videos.length });
|
|
766
|
-
const minGridBounds = _minBounds;
|
|
767
|
-
const isSmallScreen = roomBounds.width < TABLET_BREAKPOINT || roomBounds.height < TABLET_BREAKPOINT;
|
|
768
|
-
const forceStageLayoutPortrait = isMaximizeMode;
|
|
769
|
-
const stageLayoutIsPortrait = forceStageLayoutPortrait ||
|
|
770
|
-
!(hasPresentationContent || hasVideoContent) ||
|
|
771
|
-
stageBounds.width <= stageBounds.height;
|
|
772
|
-
const stableStageLayoutProps = {
|
|
773
|
-
cellPaddings: { top: 4, left: 4, bottom: 4, right: 4 },
|
|
774
|
-
containerBounds: stageBounds,
|
|
775
|
-
containerOrigin: stageOrigin,
|
|
776
|
-
gridGap,
|
|
777
|
-
hasPresentationContent,
|
|
778
|
-
hasVideoContent,
|
|
779
|
-
isConstrained,
|
|
780
|
-
isMaximizeMode,
|
|
781
|
-
isSmallScreen,
|
|
782
|
-
maxGridWidth,
|
|
783
|
-
};
|
|
784
|
-
let stageLayout = calculateStageLayout(Object.assign(Object.assign({}, stableStageLayoutProps), { isPortrait: stageLayoutIsPortrait, hasConstrainedOverflow }));
|
|
785
|
-
let forceRerunAsOverflow = false;
|
|
786
|
-
if (roomLayoutHasOverlow && !stageLayout.hasOverflow) {
|
|
787
|
-
const _stageLayout = calculateStageLayout(Object.assign(Object.assign({}, stableStageLayoutProps), { containerBounds: makeBounds({
|
|
788
|
-
width: stageBounds.width,
|
|
789
|
-
height: stageBounds.height - BOTTOM_TOOLBAR_HEIGHT,
|
|
790
|
-
}), isPortrait: stageLayoutIsPortrait, hasConstrainedOverflow }));
|
|
791
|
-
if (_stageLayout.hasOverflow) {
|
|
792
|
-
forceRerunAsOverflow = true;
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
if (forceRerunAsOverflow || stageLayout.hasOverflow) {
|
|
796
|
-
stageLayout = calculateStageLayout(Object.assign(Object.assign({}, stableStageLayoutProps), { isPortrait: true, hasConstrainedOverflow }));
|
|
797
|
-
}
|
|
798
|
-
const videosContainerLayout = calculateVideosContainerLayout({
|
|
799
|
-
containerBounds: stageLayout.videosContainer.bounds,
|
|
800
|
-
containerOrigin: stageLayout.videosContainer.origin,
|
|
801
|
-
gridGap,
|
|
802
|
-
supersizedContentAspectRatio,
|
|
803
|
-
hasPresentationContent,
|
|
804
|
-
hasPresentationGrid,
|
|
805
|
-
hasVideoContent,
|
|
806
|
-
minGridBounds,
|
|
807
|
-
});
|
|
808
|
-
const { gridLayout, presentationGridLayout } = calculateGridLayouts({
|
|
809
|
-
gridGap: videoGridGap,
|
|
810
|
-
isConstrained,
|
|
811
|
-
presentationVideos,
|
|
812
|
-
videos,
|
|
813
|
-
videosContainerLayout,
|
|
814
|
-
maxGridWidth,
|
|
815
|
-
});
|
|
816
|
-
const floatingLayout = calculateFloatingLayout({
|
|
817
|
-
roomBounds,
|
|
818
|
-
containerFrame: frame,
|
|
819
|
-
floatingVideo,
|
|
820
|
-
videoControlsHeight,
|
|
821
|
-
});
|
|
822
|
-
if (rebalanceLayout) {
|
|
823
|
-
rebalanceLayoutInPlace({
|
|
824
|
-
videosContainerLayout,
|
|
825
|
-
gridLayout,
|
|
826
|
-
presentationGridLayout,
|
|
827
|
-
gridGap,
|
|
828
|
-
});
|
|
829
|
-
}
|
|
830
|
-
return {
|
|
831
|
-
isPortrait: stageLayout.isPortrait,
|
|
832
|
-
hasOverflow: stageLayout.hasOverflow,
|
|
833
|
-
bounds: makeBounds({
|
|
834
|
-
height: frame.bounds.height,
|
|
835
|
-
width: frame.bounds.width,
|
|
836
|
-
}),
|
|
837
|
-
gridGap,
|
|
838
|
-
presentationGrid: Object.assign(Object.assign({}, videosContainerLayout.presentationGrid), { cells: presentationGridLayout.videoCells, paddings: makeBox({
|
|
839
|
-
top: presentationGridLayout.paddings.top + presentationGridLayout.extraVerticalPadding,
|
|
840
|
-
bottom: presentationGridLayout.paddings.bottom + presentationGridLayout.extraVerticalPadding,
|
|
841
|
-
left: presentationGridLayout.paddings.left + presentationGridLayout.extraHorizontalPadding,
|
|
842
|
-
right: presentationGridLayout.paddings.right + presentationGridLayout.extraHorizontalPadding,
|
|
843
|
-
}) }),
|
|
844
|
-
videoGrid: Object.assign(Object.assign({}, videosContainerLayout.videoGrid), { cells: gridLayout.videoCells, paddings: makeBox({
|
|
845
|
-
top: gridLayout.paddings.top + gridLayout.extraVerticalPadding,
|
|
846
|
-
bottom: gridLayout.paddings.bottom + gridLayout.extraVerticalPadding,
|
|
847
|
-
left: gridLayout.paddings.left + gridLayout.extraHorizontalPadding,
|
|
848
|
-
right: gridLayout.paddings.right + gridLayout.extraHorizontalPadding,
|
|
849
|
-
}) }),
|
|
850
|
-
floatingContent: Object.assign(Object.assign({}, floatingLayout), floatingVideo),
|
|
851
|
-
};
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
function makeVideoCellView({ aspectRatio, avatarSize, cellPaddings, client = undefined, isDraggable = true, isPlaceholder = false, isSubgrid = false, }) {
|
|
855
|
-
return {
|
|
856
|
-
aspectRatio: aspectRatio || 16 / 9,
|
|
857
|
-
avatarSize,
|
|
858
|
-
cellPaddings,
|
|
859
|
-
client,
|
|
860
|
-
clientId: (client === null || client === void 0 ? void 0 : client.id) || "",
|
|
861
|
-
isDraggable,
|
|
862
|
-
isPlaceholder,
|
|
863
|
-
isSubgrid,
|
|
864
|
-
type: "video",
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
function GridVideoCellView({ cell, participant, render, onSetAspectRatio, onResize, }) {
|
|
869
|
-
const handleAspectRatioChange = React.useCallback(({ ar }) => {
|
|
870
|
-
if (ar !== cell.aspectRatio) {
|
|
871
|
-
onSetAspectRatio({ aspectRatio: ar });
|
|
872
|
-
}
|
|
873
|
-
}, [cell.aspectRatio, onSetAspectRatio]);
|
|
874
|
-
return (React.createElement("div", { style: {
|
|
875
|
-
position: "absolute",
|
|
876
|
-
width: cell.bounds.width,
|
|
877
|
-
height: cell.bounds.height,
|
|
878
|
-
boxSizing: "border-box",
|
|
879
|
-
top: cell.origin.top,
|
|
880
|
-
left: cell.origin.left,
|
|
881
|
-
} }, render ? (render()) : participant.stream ? (React.createElement(VideoView, { stream: participant.stream, onSetAspectRatio: ({ aspectRatio }) => handleAspectRatioChange({ ar: aspectRatio }), onResize: onResize })) : null));
|
|
882
|
-
}
|
|
883
|
-
function Grid({ roomConnection, renderParticipant, videoGridGap = 0 }) {
|
|
884
|
-
const { remoteParticipants, localParticipant } = roomConnection.state;
|
|
885
|
-
const gridRef = React.useRef(null);
|
|
886
|
-
const [containerFrame, setContainerFrame] = React.useState(null);
|
|
887
|
-
const [aspectRatios, setAspectRatios] = React.useState([]);
|
|
888
|
-
React.useEffect(() => {
|
|
889
|
-
if (!gridRef.current) {
|
|
890
|
-
return;
|
|
891
|
-
}
|
|
892
|
-
const resizeObserver = new ResizeObserver(debounce(() => {
|
|
893
|
-
var _a, _b;
|
|
894
|
-
setContainerFrame(makeFrame({
|
|
895
|
-
width: (_a = gridRef.current) === null || _a === void 0 ? void 0 : _a.clientWidth,
|
|
896
|
-
height: (_b = gridRef.current) === null || _b === void 0 ? void 0 : _b.clientHeight,
|
|
897
|
-
}));
|
|
898
|
-
}, { delay: 60 }));
|
|
899
|
-
resizeObserver.observe(gridRef.current);
|
|
900
|
-
return () => {
|
|
901
|
-
resizeObserver.disconnect();
|
|
902
|
-
};
|
|
903
|
-
}, []);
|
|
904
|
-
const participants = React.useMemo(() => {
|
|
905
|
-
return [...(localParticipant ? [localParticipant] : []), ...remoteParticipants];
|
|
906
|
-
}, [remoteParticipants, localParticipant]);
|
|
907
|
-
const videoCells = React.useMemo(() => {
|
|
908
|
-
return participants.map((participant) => {
|
|
909
|
-
var _a;
|
|
910
|
-
const aspectRatio = (_a = aspectRatios.find((item) => item.clientId === (participant === null || participant === void 0 ? void 0 : participant.id))) === null || _a === void 0 ? void 0 : _a.aspectRatio;
|
|
911
|
-
return makeVideoCellView({
|
|
912
|
-
aspectRatio: aspectRatio !== null && aspectRatio !== void 0 ? aspectRatio : 16 / 9,
|
|
913
|
-
avatarSize: 0,
|
|
914
|
-
cellPaddings: 10,
|
|
915
|
-
client: participant,
|
|
916
|
-
});
|
|
917
|
-
});
|
|
918
|
-
}, [participants, aspectRatios]);
|
|
919
|
-
const stageLayout = React.useMemo(() => {
|
|
920
|
-
if (!containerFrame)
|
|
921
|
-
return null;
|
|
922
|
-
return calculateLayout({
|
|
923
|
-
frame: containerFrame,
|
|
924
|
-
gridGap: 0,
|
|
925
|
-
isConstrained: false,
|
|
926
|
-
roomBounds: containerFrame.bounds,
|
|
927
|
-
videos: videoCells,
|
|
928
|
-
videoGridGap,
|
|
929
|
-
});
|
|
930
|
-
}, [containerFrame, videoCells, videoGridGap]);
|
|
931
|
-
const handleResize = React.useCallback(({ width, height, stream }) => {
|
|
932
|
-
if (!roomConnection._ref)
|
|
933
|
-
return;
|
|
934
|
-
roomConnection._ref.dispatch(doRtcReportStreamResolution({ streamId: stream.id, width, height }));
|
|
935
|
-
}, [localParticipant, roomConnection._ref]);
|
|
936
|
-
return (React.createElement("div", { ref: gridRef, style: {
|
|
937
|
-
width: "100%",
|
|
938
|
-
height: "100%",
|
|
939
|
-
position: "relative",
|
|
940
|
-
} }, participants.map((participant, i) => {
|
|
941
|
-
const cell = stageLayout === null || stageLayout === void 0 ? void 0 : stageLayout.videoGrid.cells[i];
|
|
942
|
-
if (!cell || !participant || !participant.stream || !cell.clientId)
|
|
943
|
-
return null;
|
|
944
|
-
return (React.createElement(GridVideoCellView, { key: cell.clientId, cell: cell, participant: participant, render: renderParticipant ? () => renderParticipant({ cell, participant }) : undefined, onResize: handleResize, onSetAspectRatio: ({ aspectRatio }) => {
|
|
945
|
-
setAspectRatios((prev) => {
|
|
946
|
-
const index = prev.findIndex((item) => item.clientId === cell.clientId);
|
|
947
|
-
if (index === -1) {
|
|
948
|
-
return [...prev, { clientId: cell.clientId, aspectRatio }];
|
|
949
|
-
}
|
|
950
|
-
return [
|
|
951
|
-
...prev.slice(0, index),
|
|
952
|
-
{ clientId: cell.clientId, aspectRatio },
|
|
953
|
-
...prev.slice(index + 1),
|
|
954
|
-
];
|
|
955
|
-
});
|
|
956
|
-
} }));
|
|
957
|
-
})));
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
export { Grid as VideoGrid, VideoView, useLocalMedia, useRoomConnection };
|
|
256
|
+
export { VideoView, useLocalMedia, useRoomConnection };
|