@100mslive/roomkit-react 0.1.8 → 0.1.9-alpha.1
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/{HLSView-DDGPZHA2.js → HLSView-4JC65BAY.js} +3 -3
- package/dist/Modal/Dialog.d.ts +402 -1706
- package/dist/Prebuilt/App.d.ts +5 -0
- package/dist/Prebuilt/AppContext.d.ts +1 -0
- package/dist/Prebuilt/AppStateContext.d.ts +16 -0
- package/dist/Prebuilt/components/ConferenceScreen.d.ts +2 -0
- package/dist/Prebuilt/components/Footer/PollsToggle.d.ts +2 -0
- package/dist/Prebuilt/components/LeaveScreen.d.ts +2 -0
- package/dist/Prebuilt/components/MwebLandscapePrompt.d.ts +2 -0
- package/dist/Prebuilt/components/Notifications/AutoplayBlockedModal.d.ts +2 -0
- package/dist/Prebuilt/components/Notifications/HLSFailureModal.d.ts +2 -0
- package/dist/Prebuilt/components/Notifications/InitErrorModal.d.ts +2 -0
- package/dist/Prebuilt/components/Notifications/Notifications.d.ts +2 -0
- package/dist/Prebuilt/components/Notifications/PeerNotifications.d.ts +1 -0
- package/dist/Prebuilt/components/Notifications/PermissionErrorModal.d.ts +2 -0
- package/dist/Prebuilt/components/Notifications/ReconnectNotifications.d.ts +2 -0
- package/dist/Prebuilt/components/Notifications/TrackBulkUnmuteModal.d.ts +2 -0
- package/dist/Prebuilt/components/Notifications/TrackNotifications.d.ts +1 -0
- package/dist/Prebuilt/components/Notifications/TrackUnmuteModal.d.ts +2 -0
- package/dist/Prebuilt/components/Polls/Polls.d.ts +2 -0
- package/dist/Prebuilt/components/Preview/PreviewJoin.d.ts +1 -2
- package/dist/Prebuilt/components/Preview/PreviewScreen.d.ts +2 -0
- package/dist/Prebuilt/components/hooks/useRedirectToLeave.d.ts +1 -1
- package/dist/{VirtualBackground-UVZJVOA2.js → VirtualBackground-MIRXD2HZ.js} +3 -5
- package/dist/{VirtualBackground-UVZJVOA2.js.map → VirtualBackground-MIRXD2HZ.js.map} +1 -1
- package/dist/chunk-322YFA55.js +14441 -0
- package/dist/chunk-322YFA55.js.map +7 -0
- package/dist/{chunk-6SQTFOK6.js → chunk-6UGU3UJL.js} +66 -3
- package/dist/chunk-6UGU3UJL.js.map +7 -0
- package/dist/context/DialogContext.d.ts +6 -0
- package/dist/hooks/useDialogContainerSelector.d.ts +1 -0
- package/dist/index.cjs.js +10944 -9974
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -2
- package/dist/meta.cjs.json +3871 -3188
- package/dist/meta.esbuild.json +4303 -3728
- package/dist/utils/animations.d.ts +11 -0
- package/package.json +6 -7
- package/src/Modal/Dialog.tsx +31 -3
- package/src/Prebuilt/App.tsx +46 -99
- package/src/Prebuilt/AppContext.tsx +4 -0
- package/src/Prebuilt/AppStateContext.tsx +71 -0
- package/src/Prebuilt/common/constants.js +35 -0
- package/src/Prebuilt/common/utils.js +47 -0
- package/src/Prebuilt/components/AppData/AppData.jsx +5 -0
- package/src/Prebuilt/components/AppData/useSidepane.js +23 -1
- package/src/Prebuilt/components/AppData/useUISettings.js +48 -4
- package/src/Prebuilt/components/{conference.jsx → ConferenceScreen.tsx} +30 -43
- package/src/Prebuilt/components/Footer/Footer.tsx +5 -0
- package/src/Prebuilt/components/Footer/PaginatedParticipants.tsx +63 -32
- package/src/Prebuilt/components/Footer/ParticipantList.jsx +2 -1
- package/src/Prebuilt/components/Footer/PollsToggle.tsx +22 -0
- package/src/Prebuilt/components/Footer/RoleAccordion.tsx +2 -2
- package/src/Prebuilt/components/Header/StreamActions.tsx +5 -3
- package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +4 -5
- package/src/Prebuilt/components/Leave/LeaveRoom.tsx +0 -4
- package/src/Prebuilt/components/{PostLeave.jsx → LeaveScreen.tsx} +6 -13
- package/src/Prebuilt/components/MoreSettings/ChangeNameModal.jsx +2 -3
- package/src/Prebuilt/components/MoreSettings/EmbedUrl.jsx +2 -3
- package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +18 -1
- package/src/Prebuilt/components/{MwebLandscapePrompt.jsx → MwebLandscapePrompt.tsx} +10 -11
- package/src/Prebuilt/components/Notifications/{AutoplayBlockedModal.jsx → AutoplayBlockedModal.tsx} +2 -1
- package/src/Prebuilt/components/Notifications/{HLSFailureModal.jsx → HLSFailureModal.tsx} +10 -8
- package/src/Prebuilt/components/Notifications/{InitErrorModal.jsx → InitErrorModal.tsx} +5 -2
- package/src/Prebuilt/components/Notifications/{Notifications.jsx → Notifications.tsx} +41 -27
- package/src/Prebuilt/components/Notifications/{PeerNotifications.jsx → PeerNotifications.tsx} +3 -0
- package/src/Prebuilt/components/Notifications/{PermissionErrorModal.jsx → PermissionErrorModal.tsx} +6 -4
- package/src/Prebuilt/components/Notifications/{ReconnectNotifications.jsx → ReconnectNotifications.tsx} +11 -6
- package/src/Prebuilt/components/Notifications/{TrackBulkUnmuteModal.jsx → TrackBulkUnmuteModal.tsx} +9 -3
- package/src/Prebuilt/components/Notifications/{TrackUnmuteModal.jsx → TrackUnmuteModal.tsx} +9 -3
- package/src/Prebuilt/components/Notifications/index.tsx +1 -0
- package/src/Prebuilt/components/Polls/CreatePollQuiz/PollsQuizMenu.jsx +229 -0
- package/src/Prebuilt/components/Polls/CreatePollQuiz/Timer.jsx +71 -0
- package/src/Prebuilt/components/Polls/CreateQuestions/CreateQuestions.jsx +132 -0
- package/src/Prebuilt/components/Polls/CreateQuestions/DeleteQuestionModal.jsx +66 -0
- package/src/Prebuilt/components/Polls/CreateQuestions/QuestionForm.jsx +251 -0
- package/src/Prebuilt/components/Polls/CreateQuestions/SavedQuestion.jsx +57 -0
- package/src/Prebuilt/components/Polls/Polls.tsx +28 -0
- package/src/Prebuilt/components/Polls/Voting/PollResultSummary.jsx +125 -0
- package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +249 -0
- package/src/Prebuilt/components/Polls/Voting/StandardVoting.jsx +40 -0
- package/src/Prebuilt/components/Polls/Voting/TimedVoting.jsx +36 -0
- package/src/Prebuilt/components/Polls/Voting/Voting.jsx +99 -0
- package/src/Prebuilt/components/Polls/common/MultipleChoiceOptions.jsx +101 -0
- package/src/Prebuilt/components/Polls/common/OptionInputWithDelete.jsx +25 -0
- package/src/Prebuilt/components/Polls/common/SingleChoiceOptions.jsx +125 -0
- package/src/Prebuilt/components/Polls/common/StatusIndicator.jsx +47 -0
- package/src/Prebuilt/components/Polls/common/VoteCount.jsx +28 -0
- package/src/Prebuilt/components/Polls/common/VoteProgress.jsx +17 -0
- package/src/Prebuilt/components/Polls/common/VoterList.jsx +22 -0
- package/src/Prebuilt/components/Polls/common/Votes.jsx +72 -0
- package/src/Prebuilt/components/Preview/PreviewForm.tsx +3 -2
- package/src/Prebuilt/components/Preview/PreviewJoin.tsx +32 -27
- package/src/Prebuilt/components/Preview/{PreviewContainer.tsx → PreviewScreen.tsx} +2 -19
- package/src/Prebuilt/components/RaiseHand.jsx +1 -1
- package/src/Prebuilt/components/RoleChangeModal.jsx +2 -3
- package/src/Prebuilt/components/RoleChangeRequest/RequestPrompt.tsx +2 -3
- package/src/Prebuilt/components/Settings/SettingsModal.jsx +2 -3
- package/src/Prebuilt/components/Settings/StartRecording.jsx +15 -4
- package/src/Prebuilt/components/SidePaneTabs.tsx +1 -1
- package/src/Prebuilt/components/StatsForNerds.jsx +2 -3
- package/src/Prebuilt/components/Streaming/Common.jsx +31 -21
- package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +8 -9
- package/src/Prebuilt/components/VideoTile.jsx +37 -33
- package/src/Prebuilt/components/hooks/useAutoStartStreaming.tsx +3 -3
- package/src/Prebuilt/components/hooks/useRedirectToLeave.tsx +9 -17
- package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +2 -3
- package/src/Prebuilt/components/pdfAnnotator/submitPdf.jsx +1 -1
- package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +2 -3
- package/src/Prebuilt/layouts/EmbedView.jsx +47 -60
- package/src/Prebuilt/layouts/PDFView.jsx +49 -99
- package/src/Prebuilt/layouts/SidePane.tsx +8 -4
- package/src/Prebuilt/layouts/VideoStreamingSection.tsx +2 -2
- package/src/Prebuilt/primitives/DialogContent.jsx +4 -5
- package/src/context/DialogContext.tsx +13 -0
- package/src/hooks/useDialogContainerSelector.tsx +7 -0
- package/src/index.ts +1 -0
- package/src/utils/animations.ts +6 -0
- package/dist/Prebuilt/components/Notifications/HeadlessEndRoomListener.d.ts +0 -2
- package/dist/Prebuilt/components/PrebuiltDialogPortal.d.ts +0 -4
- package/dist/Prebuilt/components/PrebuiltTileElements.d.ts +0 -2198
- package/dist/Prebuilt/components/Preview/PreviewContainer.d.ts +0 -3
- package/dist/chunk-6SQTFOK6.js.map +0 -7
- package/dist/chunk-HUMNPIYI.js +0 -70
- package/dist/chunk-HUMNPIYI.js.map +0 -7
- package/dist/chunk-PRM33R4R.js +0 -7160
- package/dist/chunk-PRM33R4R.js.map +0 -7
- package/dist/conference-N7S47TDK.js +0 -6602
- package/dist/conference-N7S47TDK.js.map +0 -7
- package/src/Prebuilt/components/GoLiveButton.jsx +0 -42
- package/src/Prebuilt/components/Notifications/HeadlessEndRoomListener.tsx +0 -23
- package/src/Prebuilt/components/PrebuiltDialogPortal.tsx +0 -6
- package/src/Prebuilt/components/PrebuiltTileElements.tsx +0 -5
- package/src/Prebuilt/components/Streaming/HLSStreaming.jsx +0 -220
- package/src/Prebuilt/components/Streaming/RTMPStreaming.jsx +0 -334
- package/src/Prebuilt/components/Streaming/StreamingLanding.jsx +0 -76
- /package/dist/{HLSView-DDGPZHA2.js.map → HLSView-4JC65BAY.js.map} +0 -0
- /package/{src/Prebuilt/components/Notifications/index.jsx → dist/Prebuilt/components/Notifications/index.d.ts} +0 -0
- /package/src/Prebuilt/components/Notifications/{TrackNotifications.jsx → TrackNotifications.tsx} +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Flex, Text } from '../../../../';
|
|
4
|
+
|
|
5
|
+
export const StatusIndicator = ({ isLive, shouldShowTimer }) => {
|
|
6
|
+
return (
|
|
7
|
+
<Flex align="center">
|
|
8
|
+
<Flex
|
|
9
|
+
css={{
|
|
10
|
+
backgroundColor: isLive ? '$alert_error_default' : '$secondary_default',
|
|
11
|
+
p: '$2 $4',
|
|
12
|
+
borderRadius: shouldShowTimer ? '$0 0 0 $0' : '$0',
|
|
13
|
+
}}
|
|
14
|
+
>
|
|
15
|
+
<Text
|
|
16
|
+
variant="caption"
|
|
17
|
+
css={{
|
|
18
|
+
fontWeight: '$semiBold',
|
|
19
|
+
color: '$on_surface_high',
|
|
20
|
+
}}
|
|
21
|
+
>
|
|
22
|
+
{isLive ? 'LIVE' : 'ENDED'}
|
|
23
|
+
</Text>
|
|
24
|
+
</Flex>
|
|
25
|
+
|
|
26
|
+
{shouldShowTimer ? (
|
|
27
|
+
<Flex
|
|
28
|
+
css={{
|
|
29
|
+
borderRadius: '0 $0 $0 0',
|
|
30
|
+
p: '$2 $4',
|
|
31
|
+
backgroundColor: '$background_default',
|
|
32
|
+
}}
|
|
33
|
+
>
|
|
34
|
+
<Text
|
|
35
|
+
variant="caption"
|
|
36
|
+
css={{
|
|
37
|
+
fontWeight: '$semiBold',
|
|
38
|
+
color: '$on_surface_high',
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
0:32
|
|
42
|
+
</Text>
|
|
43
|
+
</Flex>
|
|
44
|
+
) : null}
|
|
45
|
+
</Flex>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Flex, Text } from '../../../../';
|
|
4
|
+
|
|
5
|
+
export const VoteCount = ({ isQuiz, voteCount, isCorrectAnswer }) => {
|
|
6
|
+
return (
|
|
7
|
+
<Flex css={{ alignItems: 'center' }}>
|
|
8
|
+
{isQuiz && (
|
|
9
|
+
<Text
|
|
10
|
+
variant="xs"
|
|
11
|
+
css={{
|
|
12
|
+
p: '$2',
|
|
13
|
+
mr: '$2',
|
|
14
|
+
color: isCorrectAnswer ? '$alert_success' : '$alert_error_default',
|
|
15
|
+
borderRadius: '$1',
|
|
16
|
+
border: `1px solid ${isCorrectAnswer ? '$alert_success' : '$alert_error_default'}`,
|
|
17
|
+
}}
|
|
18
|
+
>
|
|
19
|
+
{isCorrectAnswer ? 'Correct' : 'Incorrect'}
|
|
20
|
+
</Text>
|
|
21
|
+
)}
|
|
22
|
+
<Text variant="sm" css={{ color: '$on_surface_medium' }}>
|
|
23
|
+
{voteCount}
|
|
24
|
+
{voteCount === 1 ? 'vote' : 'votes'}
|
|
25
|
+
</Text>
|
|
26
|
+
</Flex>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Progress } from '../../../../';
|
|
3
|
+
|
|
4
|
+
export const VoteProgress = ({ option, totalResponses }) => {
|
|
5
|
+
const showProgress = typeof option.voteCount === 'number' && typeof totalResponses === 'number' && totalResponses > 0;
|
|
6
|
+
const progressValue = (100 * option.voteCount) / totalResponses;
|
|
7
|
+
|
|
8
|
+
return showProgress ? (
|
|
9
|
+
<Progress.Root value={progressValue}>
|
|
10
|
+
<Progress.Content
|
|
11
|
+
style={{
|
|
12
|
+
transform: `translateX(-${100 - progressValue}%)`,
|
|
13
|
+
}}
|
|
14
|
+
/>
|
|
15
|
+
</Progress.Root>
|
|
16
|
+
) : null;
|
|
17
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Avatar, Flex, Text } from '../../../../';
|
|
3
|
+
|
|
4
|
+
export const VoterList = ({ voters }) => {
|
|
5
|
+
return voters.map((voter, index) => (
|
|
6
|
+
<Flex align="center" key={`${voter}-${index}`} css={{ gap: '$4', py: '$2' }}>
|
|
7
|
+
<Avatar
|
|
8
|
+
name={voter}
|
|
9
|
+
css={{
|
|
10
|
+
position: 'relative',
|
|
11
|
+
transform: 'unset',
|
|
12
|
+
fontSize: '$tiny',
|
|
13
|
+
size: '$9',
|
|
14
|
+
p: '$4',
|
|
15
|
+
}}
|
|
16
|
+
/>
|
|
17
|
+
<Text variant="xs" css={{ color: '$on_surface_medium', fontWeight: '$semiBold' }}>
|
|
18
|
+
{voter}
|
|
19
|
+
</Text>
|
|
20
|
+
</Flex>
|
|
21
|
+
));
|
|
22
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Avatar, Box, Flex, Text, Tooltip } from '../../../../';
|
|
3
|
+
import { VoterList } from './VoterList';
|
|
4
|
+
|
|
5
|
+
// Shows number of votes, avatars of voters and list of voters on hover
|
|
6
|
+
export const Votes = ({ voters }) => {
|
|
7
|
+
const hiddenVotersCount = voters.length > 2 ? voters.length - 2 : 0;
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<Flex align="center" css={{ gap: '$4' }}>
|
|
11
|
+
<Text variant="sm" css={{ color: '$on_surface_medium' }}>
|
|
12
|
+
{voters.length}
|
|
13
|
+
{voters.length && voters.length !== 1 ? 'votes' : 'votes'}
|
|
14
|
+
</Text>
|
|
15
|
+
<Tooltip
|
|
16
|
+
side="bottom"
|
|
17
|
+
align="start"
|
|
18
|
+
disabled={hiddenVotersCount === 0}
|
|
19
|
+
boxCss={{
|
|
20
|
+
backgroundColor: '$surface_brighter',
|
|
21
|
+
borderRadius: '$1',
|
|
22
|
+
p: '$4 $6',
|
|
23
|
+
top: '$2',
|
|
24
|
+
zIndex: '20',
|
|
25
|
+
minWidth: '$44',
|
|
26
|
+
}}
|
|
27
|
+
title={<VoterList voters={voters} />}
|
|
28
|
+
>
|
|
29
|
+
<Flex align="center">
|
|
30
|
+
{voters.length
|
|
31
|
+
? voters.slice(0, 2).map((voter, index) => (
|
|
32
|
+
<Avatar
|
|
33
|
+
name={voter}
|
|
34
|
+
css={{
|
|
35
|
+
position: 'relative',
|
|
36
|
+
transform: 'unset',
|
|
37
|
+
left: `${index * -1}px`,
|
|
38
|
+
fontSize: '$tiny',
|
|
39
|
+
size: '$9',
|
|
40
|
+
p: '$4',
|
|
41
|
+
zIndex: '5',
|
|
42
|
+
}}
|
|
43
|
+
/>
|
|
44
|
+
))
|
|
45
|
+
: null}
|
|
46
|
+
{hiddenVotersCount ? (
|
|
47
|
+
<Box
|
|
48
|
+
css={{
|
|
49
|
+
backgroundColor: '$secondary_default',
|
|
50
|
+
borderRadius: '$round',
|
|
51
|
+
position: 'relative',
|
|
52
|
+
left: '-$2',
|
|
53
|
+
p: '$2 $3',
|
|
54
|
+
}}
|
|
55
|
+
>
|
|
56
|
+
<Text
|
|
57
|
+
variant="caption"
|
|
58
|
+
css={{
|
|
59
|
+
fontWeight: '$semiBold',
|
|
60
|
+
color: '$on_surface_high',
|
|
61
|
+
fontSize: '$tiny',
|
|
62
|
+
}}
|
|
63
|
+
>
|
|
64
|
+
+{hiddenVotersCount}
|
|
65
|
+
</Text>
|
|
66
|
+
</Box>
|
|
67
|
+
) : null}
|
|
68
|
+
</Flex>
|
|
69
|
+
</Tooltip>
|
|
70
|
+
</Flex>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
@@ -27,10 +27,11 @@ const PreviewForm = ({
|
|
|
27
27
|
e.preventDefault();
|
|
28
28
|
};
|
|
29
29
|
const isMobile = useMedia(cssConfig.media.md);
|
|
30
|
-
const { isHLSRunning } = useRecordingStreaming();
|
|
30
|
+
const { isHLSRunning, isRTMPRunning } = useRecordingStreaming();
|
|
31
31
|
const layout = useRoomLayout();
|
|
32
32
|
const { join_form: joinForm = {} } = layout?.screens?.preview?.default?.elements || {};
|
|
33
|
-
const showGoLive =
|
|
33
|
+
const showGoLive =
|
|
34
|
+
joinForm?.join_btn_type === JoinForm_JoinBtnType.JOIN_BTN_TYPE_JOIN_AND_GO_LIVE && !isHLSRunning && !isRTMPRunning;
|
|
34
35
|
|
|
35
36
|
return (
|
|
36
37
|
<Form
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React, { Fragment, Suspense, useCallback, useEffect, useState } from 'react';
|
|
2
|
-
import { useMedia } from 'react-use';
|
|
1
|
+
import React, { Fragment, Suspense, useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import { useMeasure, useMedia } from 'react-use';
|
|
3
3
|
import {
|
|
4
4
|
HMSRoomState,
|
|
5
5
|
selectIsLocalVideoEnabled,
|
|
@@ -11,9 +11,7 @@ import {
|
|
|
11
11
|
useParticipants,
|
|
12
12
|
usePreviewJoin,
|
|
13
13
|
useRecordingStreaming,
|
|
14
|
-
// @ts-ignore: No implicit Any
|
|
15
14
|
} from '@100mslive/react-sdk';
|
|
16
|
-
// @ts-ignore: No implicit Any
|
|
17
15
|
import { MicOffIcon, SettingsIcon } from '@100mslive/react-icons';
|
|
18
16
|
import { Avatar, Box, config as cssConfig, Flex, flexCenter, styled, StyledVideoTile, Text, Video } from '../../..';
|
|
19
17
|
import { AudioLevel } from '../../../AudioLevel';
|
|
@@ -31,7 +29,6 @@ import TileConnection from '../Connection/TileConnection';
|
|
|
31
29
|
import FullPageProgress from '../FullPageProgress';
|
|
32
30
|
// @ts-ignore: No implicit Any
|
|
33
31
|
import { Logo } from '../Header/HeaderComponents';
|
|
34
|
-
import { PrebuiltAudioIndicator } from '../PrebuiltTileElements';
|
|
35
32
|
// @ts-ignore: No implicit Any
|
|
36
33
|
import SettingsModal from '../Settings/SettingsModal';
|
|
37
34
|
// @ts-ignore: No implicit Any
|
|
@@ -41,7 +38,7 @@ import { useAuthToken, useUISettings } from '../AppData/useUISettings';
|
|
|
41
38
|
// @ts-ignore: No implicit Any
|
|
42
39
|
import { defaultPreviewPreference, UserPreferencesKeys, useUserPreferences } from '../hooks/useUserPreferences';
|
|
43
40
|
// @ts-ignore: No implicit Any
|
|
44
|
-
import { getFormattedCount } from '../../common/utils';
|
|
41
|
+
import { calculateAvatarAndAttribBoxSize, getFormattedCount } from '../../common/utils';
|
|
45
42
|
// @ts-ignore: No implicit Any
|
|
46
43
|
import { UI_SETTINGS } from '../../common/constants';
|
|
47
44
|
|
|
@@ -56,13 +53,24 @@ const getParticipantChipContent = (peerCount = 0) => {
|
|
|
56
53
|
return `${formattedNum} other${parseInt(formattedNum) === 1 ? '' : 's'} in the session`;
|
|
57
54
|
};
|
|
58
55
|
|
|
56
|
+
const useLocalTileAspectRatio = () => {
|
|
57
|
+
const localPeer = useHMSStore(selectLocalPeer);
|
|
58
|
+
const videoTrack = useHMSStore(selectVideoTrackByID(localPeer?.videoTrack));
|
|
59
|
+
const isMobile = useMedia(cssConfig.media.md);
|
|
60
|
+
let aspectRatio = 0;
|
|
61
|
+
if (videoTrack?.width && videoTrack?.height) {
|
|
62
|
+
aspectRatio = videoTrack.width / videoTrack.height;
|
|
63
|
+
} else {
|
|
64
|
+
aspectRatio = isMobile ? 9 / 16 : 16 / 9;
|
|
65
|
+
}
|
|
66
|
+
return aspectRatio;
|
|
67
|
+
};
|
|
68
|
+
|
|
59
69
|
const PreviewJoin = ({
|
|
60
|
-
onJoin,
|
|
61
70
|
skipPreview,
|
|
62
71
|
initialName,
|
|
63
72
|
asRole,
|
|
64
73
|
}: {
|
|
65
|
-
onJoin: () => void;
|
|
66
74
|
skipPreview?: boolean;
|
|
67
75
|
initialName?: string;
|
|
68
76
|
asRole?: string;
|
|
@@ -102,16 +110,11 @@ const PreviewJoin = ({
|
|
|
102
110
|
name,
|
|
103
111
|
});
|
|
104
112
|
join();
|
|
105
|
-
|
|
106
|
-
}, [join, name, setPreviewPreference, onJoin]);
|
|
113
|
+
}, [join, name, setPreviewPreference]);
|
|
107
114
|
const roomLayout = useRoomLayout();
|
|
108
115
|
|
|
109
116
|
const { preview_header: previewHeader = {} } = roomLayout?.screens?.preview?.default?.elements || {};
|
|
110
|
-
const
|
|
111
|
-
const videoTrack = useHMSStore(selectVideoTrackByID(localPeer?.videoTrack));
|
|
112
|
-
const isMobile = useMedia(cssConfig.media.md);
|
|
113
|
-
const aspectRatio =
|
|
114
|
-
videoTrack?.width && videoTrack?.height ? videoTrack.width / videoTrack.height : isMobile ? 9 / 16 : 16 / 9;
|
|
117
|
+
const aspectRatio = useLocalTileAspectRatio();
|
|
115
118
|
useEffect(() => {
|
|
116
119
|
if (authToken) {
|
|
117
120
|
if (skipPreview) {
|
|
@@ -204,13 +207,16 @@ export const PreviewTile = ({ name, error }: { name: string; error?: boolean })
|
|
|
204
207
|
const trackSelector = selectVideoTrackByID(localPeer?.videoTrack);
|
|
205
208
|
const track = useHMSStore(trackSelector);
|
|
206
209
|
const showMuteIcon = !isLocalAudioEnabled || !toggleAudio;
|
|
207
|
-
const
|
|
208
|
-
const
|
|
209
|
-
const
|
|
210
|
-
|
|
210
|
+
const aspectRatio = useLocalTileAspectRatio();
|
|
211
|
+
const [ref, { width: calculatedWidth, height: calculatedHeight }] = useMeasure<HTMLDivElement>();
|
|
212
|
+
const [avatarSize, attribBoxSize] = useMemo(
|
|
213
|
+
() => calculateAvatarAndAttribBoxSize(calculatedWidth, calculatedHeight),
|
|
214
|
+
[calculatedWidth, calculatedHeight],
|
|
215
|
+
);
|
|
211
216
|
|
|
212
217
|
return (
|
|
213
218
|
<StyledVideoTile.Container
|
|
219
|
+
ref={ref}
|
|
214
220
|
css={{
|
|
215
221
|
bg: '$surface_default',
|
|
216
222
|
aspectRatio,
|
|
@@ -235,22 +241,21 @@ export const PreviewTile = ({ name, error }: { name: string; error?: boolean })
|
|
|
235
241
|
|
|
236
242
|
{!isVideoOn ? (
|
|
237
243
|
<StyledVideoTile.AvatarContainer>
|
|
238
|
-
<Avatar name={name} data-testid="preview_avatar_tile" size=
|
|
244
|
+
<Avatar name={name} data-testid="preview_avatar_tile" size={avatarSize} />
|
|
239
245
|
</StyledVideoTile.AvatarContainer>
|
|
240
246
|
) : null}
|
|
241
247
|
</>
|
|
242
|
-
) : !error ? (
|
|
243
|
-
<FullPageProgress />
|
|
244
248
|
) : null}
|
|
249
|
+
{!localPeer && !error ? <FullPageProgress /> : null}
|
|
245
250
|
|
|
246
251
|
{showMuteIcon ? (
|
|
247
|
-
<
|
|
248
|
-
<MicOffIcon
|
|
249
|
-
</
|
|
252
|
+
<StyledVideoTile.AudioIndicator size={attribBoxSize}>
|
|
253
|
+
<MicOffIcon />
|
|
254
|
+
</StyledVideoTile.AudioIndicator>
|
|
250
255
|
) : (
|
|
251
|
-
<
|
|
256
|
+
<StyledVideoTile.AudioIndicator size={attribBoxSize}>
|
|
252
257
|
<AudioLevel trackId={localPeer?.audioTrack} />
|
|
253
|
-
</
|
|
258
|
+
</StyledVideoTile.AudioIndicator>
|
|
254
259
|
)}
|
|
255
260
|
</StyledVideoTile.Container>
|
|
256
261
|
);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { useNavigate, useParams } from 'react-router-dom';
|
|
3
2
|
import { useSearchParam } from 'react-use';
|
|
4
3
|
import { Flex } from '../../..';
|
|
5
4
|
import { useHMSPrebuiltContext } from '../../AppContext';
|
|
@@ -14,25 +13,16 @@ import { useAuthToken } from '../AppData/useUISettings';
|
|
|
14
13
|
// @ts-ignore: No implicit Any
|
|
15
14
|
import { QUERY_PARAM_PREVIEW_AS_ROLE } from '../../common/constants';
|
|
16
15
|
|
|
17
|
-
const
|
|
18
|
-
const navigate = useNavigate();
|
|
16
|
+
export const PreviewScreen = () => {
|
|
19
17
|
const { isPreviewScreenEnabled } = useRoomLayoutPreviewScreen();
|
|
20
18
|
const skipPreview = !isPreviewScreenEnabled;
|
|
21
19
|
const previewAsRole = useSearchParam(QUERY_PARAM_PREVIEW_AS_ROLE);
|
|
22
20
|
const { userName } = useHMSPrebuiltContext();
|
|
23
21
|
const initialName = userName || (skipPreview ? 'Beam' : '');
|
|
24
|
-
const { roomId: urlRoomId, role: userRole } = useParams(); // from the url
|
|
25
22
|
const authToken = useAuthToken();
|
|
26
23
|
const roomLayout = useRoomLayout();
|
|
27
24
|
const { preview_header: previewHeader = {} } = roomLayout?.screens?.preview?.default?.elements || {};
|
|
28
25
|
|
|
29
|
-
const onJoin = () => {
|
|
30
|
-
let meetingURL = `/meeting/${urlRoomId}`;
|
|
31
|
-
if (userRole) {
|
|
32
|
-
meetingURL += `/${userRole}`;
|
|
33
|
-
}
|
|
34
|
-
navigate(meetingURL);
|
|
35
|
-
};
|
|
36
26
|
return (
|
|
37
27
|
<Flex direction="column" css={{ size: '100%' }}>
|
|
38
28
|
<Flex
|
|
@@ -41,12 +31,7 @@ const PreviewContainer = () => {
|
|
|
41
31
|
align="center"
|
|
42
32
|
>
|
|
43
33
|
{authToken && Object.keys(previewHeader).length > 0 ? (
|
|
44
|
-
<PreviewJoin
|
|
45
|
-
initialName={initialName}
|
|
46
|
-
skipPreview={skipPreview}
|
|
47
|
-
asRole={previewAsRole ?? undefined}
|
|
48
|
-
onJoin={onJoin}
|
|
49
|
-
/>
|
|
34
|
+
<PreviewJoin initialName={initialName} skipPreview={skipPreview} asRole={previewAsRole ?? undefined} />
|
|
50
35
|
) : (
|
|
51
36
|
<FullPageProgress />
|
|
52
37
|
)}
|
|
@@ -54,5 +39,3 @@ const PreviewContainer = () => {
|
|
|
54
39
|
</Flex>
|
|
55
40
|
);
|
|
56
41
|
};
|
|
57
|
-
|
|
58
|
-
export default PreviewContainer;
|
|
@@ -9,7 +9,7 @@ export const RaiseHand = () => {
|
|
|
9
9
|
const { isHandRaised, toggleHandRaise } = useMyMetadata();
|
|
10
10
|
return (
|
|
11
11
|
<Tooltip title={isHandRaised ? 'Lower hand' : 'Raise hand'}>
|
|
12
|
-
<IconButton active={!isHandRaised} onClick={async () => await toggleHandRaise()}>
|
|
12
|
+
<IconButton data-testid="hand_raise_btn" active={!isHandRaised} onClick={async () => await toggleHandRaise()}>
|
|
13
13
|
<HandIcon />
|
|
14
14
|
</IconButton>
|
|
15
15
|
</Tooltip>
|
|
@@ -9,7 +9,6 @@ import { Box, Flex } from '../../Layout';
|
|
|
9
9
|
import { Dialog } from '../../Modal';
|
|
10
10
|
import { Text } from '../../Text';
|
|
11
11
|
import { Tooltip } from '../../Tooltip';
|
|
12
|
-
import { PrebuiltDialogPortal } from './PrebuiltDialogPortal';
|
|
13
12
|
import { useDropdownSelection } from './hooks/useDropdownSelection';
|
|
14
13
|
import { useFilteredRoles } from '../common/hooks';
|
|
15
14
|
import { textEllipsis } from '../../utils';
|
|
@@ -48,7 +47,7 @@ export const RoleChangeModal = ({ peerId, onOpenChange }) => {
|
|
|
48
47
|
const peerNameMaxWidth = 200;
|
|
49
48
|
return (
|
|
50
49
|
<Dialog.Root defaultOpen onOpenChange={onOpenChange}>
|
|
51
|
-
<
|
|
50
|
+
<Dialog.Portal>
|
|
52
51
|
<Dialog.Overlay />
|
|
53
52
|
<Dialog.Content css={{ width: 'min(400px,80%)', p: '$10' }}>
|
|
54
53
|
<Dialog.Title css={{ p: 0 }} asChild>
|
|
@@ -180,7 +179,7 @@ export const RoleChangeModal = ({ peerId, onOpenChange }) => {
|
|
|
180
179
|
</Box>
|
|
181
180
|
</Flex>
|
|
182
181
|
</Dialog.Content>
|
|
183
|
-
</
|
|
182
|
+
</Dialog.Portal>
|
|
184
183
|
</Dialog.Root>
|
|
185
184
|
);
|
|
186
185
|
};
|
|
@@ -2,7 +2,6 @@ import React from 'react';
|
|
|
2
2
|
import { useMedia } from 'react-use';
|
|
3
3
|
import { Box, Button, config as cssConfig, Dialog, Flex, Text } from '../../..';
|
|
4
4
|
import { Sheet } from '../../../Sheet';
|
|
5
|
-
import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
|
|
6
5
|
|
|
7
6
|
export const RequestPrompt = ({
|
|
8
7
|
open = true,
|
|
@@ -35,7 +34,7 @@ export const RequestPrompt = ({
|
|
|
35
34
|
|
|
36
35
|
return (
|
|
37
36
|
<Dialog.Root open={open} onOpenChange={onOpenChange}>
|
|
38
|
-
<
|
|
37
|
+
<Dialog.Portal>
|
|
39
38
|
<Dialog.Overlay />
|
|
40
39
|
<Dialog.Content css={{ p: '$10' }}>
|
|
41
40
|
<Dialog.Title css={{ p: 0, display: 'flex', flexDirection: 'row', gap: '$md', justifyContent: 'center' }}>
|
|
@@ -44,7 +43,7 @@ export const RequestPrompt = ({
|
|
|
44
43
|
<Box css={{ mt: '$4', mb: '$10' }}>{body}</Box>
|
|
45
44
|
<RequestActions actionText={actionText} onAction={onAction} />
|
|
46
45
|
</Dialog.Content>
|
|
47
|
-
</
|
|
46
|
+
</Dialog.Portal>
|
|
48
47
|
</Dialog.Root>
|
|
49
48
|
);
|
|
50
49
|
};
|
|
@@ -9,7 +9,6 @@ import { Sheet } from '../../../Sheet';
|
|
|
9
9
|
import { Tabs } from '../../../Tabs';
|
|
10
10
|
import { Text } from '../../../Text';
|
|
11
11
|
import { config as cssConfig } from '../../../Theme';
|
|
12
|
-
import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
|
|
13
12
|
import { settingContent, settingsList } from './common.js';
|
|
14
13
|
|
|
15
14
|
const SettingsModal = ({ open, onOpenChange, screenType, children = <></> }) => {
|
|
@@ -187,7 +186,7 @@ const DesktopSettingModal = ({
|
|
|
187
186
|
return (
|
|
188
187
|
<Dialog.Root open={open} onOpenChange={onOpenChange}>
|
|
189
188
|
<Dialog.Trigger asChild>{children}</Dialog.Trigger>
|
|
190
|
-
<
|
|
189
|
+
<Dialog.Portal>
|
|
191
190
|
<Dialog.Overlay />
|
|
192
191
|
<Dialog.Content
|
|
193
192
|
css={{
|
|
@@ -257,7 +256,7 @@ const DesktopSettingModal = ({
|
|
|
257
256
|
</IconButton>
|
|
258
257
|
</Dialog.Close>
|
|
259
258
|
</Dialog.Content>
|
|
260
|
-
</
|
|
259
|
+
</Dialog.Portal>
|
|
261
260
|
</Dialog.Root>
|
|
262
261
|
);
|
|
263
262
|
};
|
|
@@ -2,13 +2,24 @@ import React, { useState } from 'react';
|
|
|
2
2
|
import { selectPermissions, useHMSActions, useHMSStore, useRecordingStreaming } from '@100mslive/react-sdk';
|
|
3
3
|
import { AlertTriangleIcon } from '@100mslive/react-icons';
|
|
4
4
|
import { Button, Dialog, Flex, Text } from '../../../';
|
|
5
|
-
import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
|
|
6
5
|
import { ResolutionInput } from '../Streaming/ResolutionInput';
|
|
7
|
-
import { getResolution } from '../Streaming/RTMPStreaming';
|
|
8
6
|
import { ToastManager } from '../Toast/ToastManager';
|
|
9
7
|
import { useSetAppDataByKey } from '../AppData/useUISettings';
|
|
10
8
|
import { APP_DATA, RTMP_RECORD_DEFAULT_RESOLUTION } from '../../common/constants';
|
|
11
9
|
|
|
10
|
+
export function getResolution(recordingResolution) {
|
|
11
|
+
const resolution = {};
|
|
12
|
+
if (recordingResolution.width) {
|
|
13
|
+
resolution.width = recordingResolution.width;
|
|
14
|
+
}
|
|
15
|
+
if (recordingResolution.height) {
|
|
16
|
+
resolution.height = recordingResolution.height;
|
|
17
|
+
}
|
|
18
|
+
if (Object.keys(resolution).length > 0) {
|
|
19
|
+
return resolution;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
12
23
|
const StartRecording = ({ open, onOpenChange }) => {
|
|
13
24
|
const permissions = useHMSStore(selectPermissions);
|
|
14
25
|
const [resolution, setResolution] = useState(RTMP_RECORD_DEFAULT_RESOLUTION);
|
|
@@ -22,7 +33,7 @@ const StartRecording = ({ open, onOpenChange }) => {
|
|
|
22
33
|
if (isBrowserRecordingOn) {
|
|
23
34
|
return (
|
|
24
35
|
<Dialog.Root open={open} onOpenChange={onOpenChange}>
|
|
25
|
-
<
|
|
36
|
+
<Dialog.Portal>
|
|
26
37
|
<Dialog.Content
|
|
27
38
|
css={{
|
|
28
39
|
width: 'min(400px,80%)',
|
|
@@ -67,7 +78,7 @@ const StartRecording = ({ open, onOpenChange }) => {
|
|
|
67
78
|
</Button>
|
|
68
79
|
</Flex>
|
|
69
80
|
</Dialog.Content>
|
|
70
|
-
</
|
|
81
|
+
</Dialog.Portal>
|
|
71
82
|
</Dialog.Root>
|
|
72
83
|
);
|
|
73
84
|
}
|
|
@@ -151,7 +151,7 @@ export const SidePaneTabs = React.memo<{
|
|
|
151
151
|
color: activeTab !== SIDE_PANE_OPTIONS.PARTICIPANTS ? '$on_surface_low' : '$on_surface_high',
|
|
152
152
|
}}
|
|
153
153
|
>
|
|
154
|
-
Participants <ParticipantCount count={peerCount} />
|
|
154
|
+
Participants <ParticipantCount count={peerCount} />
|
|
155
155
|
</Tabs.Trigger>
|
|
156
156
|
</Tabs.List>
|
|
157
157
|
<Tabs.Content value={SIDE_PANE_OPTIONS.PARTICIPANTS} css={{ p: 0 }}>
|
|
@@ -15,7 +15,6 @@ import { Dialog } from '../../Modal';
|
|
|
15
15
|
import { Switch } from '../../Switch';
|
|
16
16
|
import { Text } from '../../Text';
|
|
17
17
|
import { DialogDropdownTrigger } from '../primitives/DropdownTrigger';
|
|
18
|
-
import { PrebuiltDialogPortal } from './PrebuiltDialogPortal';
|
|
19
18
|
import { useSetUiSettings } from './AppData/useUISettings';
|
|
20
19
|
import { useDropdownSelection } from './hooks/useDropdownSelection';
|
|
21
20
|
import { UI_SETTINGS } from '../common/constants';
|
|
@@ -40,7 +39,7 @@ export const StatsForNerds = ({ onOpenChange }) => {
|
|
|
40
39
|
|
|
41
40
|
return (
|
|
42
41
|
<Dialog.Root defaultOpen onOpenChange={onOpenChange}>
|
|
43
|
-
<
|
|
42
|
+
<Dialog.Portal>
|
|
44
43
|
<Dialog.Overlay />
|
|
45
44
|
<Dialog.Content
|
|
46
45
|
css={{
|
|
@@ -119,7 +118,7 @@ export const StatsForNerds = ({ onOpenChange }) => {
|
|
|
119
118
|
<TrackStats trackID={selectedStat.id} layer={selectedStat.layer} local={selectedStat.local} />
|
|
120
119
|
)}
|
|
121
120
|
</Dialog.Content>
|
|
122
|
-
</
|
|
121
|
+
</Dialog.Portal>
|
|
123
122
|
</Dialog.Root>
|
|
124
123
|
);
|
|
125
124
|
};
|
|
@@ -37,36 +37,46 @@ export const StreamCard = ({ title, subtitle, Icon, imgSrc = '', css = {}, onCli
|
|
|
37
37
|
);
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
export const ContentHeader = ({ onBack, title, content }) => {
|
|
40
|
+
export const ContentHeader = ({ onBack, onClose, title = '', content }) => {
|
|
41
41
|
return (
|
|
42
|
-
<Flex
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
data-testid="go_back"
|
|
47
|
-
>
|
|
48
|
-
<ChevronLeftIcon width={16} height={16} />
|
|
49
|
-
</Text>
|
|
50
|
-
<Box css={{ flex: '1 1 0', mx: '$8' }}>
|
|
42
|
+
<Flex
|
|
43
|
+
css={{ w: '100%', py: '$8', px: '$10', cursor: 'pointer', borderBottom: '1px solid $border_bright', mb: '$8' }}
|
|
44
|
+
>
|
|
45
|
+
{onBack ? (
|
|
51
46
|
<Text
|
|
52
|
-
variant="tiny"
|
|
53
47
|
css={{
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
color: '$on_surface_medium',
|
|
48
|
+
alignSelf: 'center',
|
|
49
|
+
mr: '$8',
|
|
57
50
|
}}
|
|
51
|
+
onClick={onBack}
|
|
52
|
+
data-testid="go_back"
|
|
58
53
|
>
|
|
59
|
-
|
|
54
|
+
<ChevronLeftIcon />
|
|
60
55
|
</Text>
|
|
56
|
+
) : null}
|
|
57
|
+
<Box css={{ flex: '1 1 0' }}>
|
|
58
|
+
{title ? (
|
|
59
|
+
<Text
|
|
60
|
+
variant="tiny"
|
|
61
|
+
css={{
|
|
62
|
+
textTransform: 'uppercase',
|
|
63
|
+
fontWeight: '$semiBold',
|
|
64
|
+
color: '$on_surface_medium',
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
{title}
|
|
68
|
+
</Text>
|
|
69
|
+
) : null}
|
|
61
70
|
<Text variant="h6">{content}</Text>
|
|
62
71
|
</Box>
|
|
63
|
-
|
|
64
|
-
<
|
|
65
|
-
|
|
72
|
+
{onClose ? (
|
|
73
|
+
<IconButton onClick={onClose} css={{ alignSelf: 'flex-start' }} data-testid="close_stream_section">
|
|
74
|
+
<CrossIcon />
|
|
75
|
+
</IconButton>
|
|
76
|
+
) : null}
|
|
66
77
|
</Flex>
|
|
67
78
|
);
|
|
68
79
|
};
|
|
69
|
-
|
|
70
80
|
export const Container = ({ children, rounded = false }) => {
|
|
71
81
|
return (
|
|
72
82
|
<Box
|
|
@@ -76,7 +86,7 @@ export const Container = ({ children, rounded = false }) => {
|
|
|
76
86
|
position: 'absolute',
|
|
77
87
|
top: 0,
|
|
78
88
|
left: 0,
|
|
79
|
-
bg: '$
|
|
89
|
+
bg: '$surface_dim',
|
|
80
90
|
transform: 'translateX(10%)',
|
|
81
91
|
animation: `${slideLeftAndFade('10%')} 100ms ease-out forwards`,
|
|
82
92
|
display: 'flex',
|
|
@@ -125,7 +135,7 @@ export const ErrorText = ({ error }) => {
|
|
|
125
135
|
return null;
|
|
126
136
|
}
|
|
127
137
|
return (
|
|
128
|
-
<Text variant="sm" css={{
|
|
138
|
+
<Text variant="sm" css={{ my: '$4', color: '$alert_error_default' }}>
|
|
129
139
|
{error}
|
|
130
140
|
</Text>
|
|
131
141
|
);
|
|
@@ -19,15 +19,14 @@ export const ScreenshareLayout = ({ peers, onPageChange, onPageSize, edgeToEdge
|
|
|
19
19
|
const [page, setPage] = useState(0);
|
|
20
20
|
const activeSharePeer = peersSharing[page];
|
|
21
21
|
const isMobile = useMedia(cssConfig.media.md);
|
|
22
|
-
const secondaryPeers = useMemo(
|
|
23
|
-
()
|
|
24
|
-
|
|
25
|
-
? activeSharePeer
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
);
|
|
22
|
+
const secondaryPeers = useMemo(() => {
|
|
23
|
+
if (isMobile) {
|
|
24
|
+
return activeSharePeer
|
|
25
|
+
? [activeSharePeer, ...peers.filter(p => p.id !== activeSharePeer?.id)] //keep active sharing peer as first tile
|
|
26
|
+
: peers;
|
|
27
|
+
}
|
|
28
|
+
return peers.filter(p => p.id !== activeSharePeer?.id);
|
|
29
|
+
}, [activeSharePeer, peers, isMobile]);
|
|
31
30
|
useEffect(() => {
|
|
32
31
|
setActiveScreenSharePeer(isMobile ? '' : activeSharePeer?.id);
|
|
33
32
|
return () => {
|