@100mslive/roomkit-react 0.1.8-alpha.0 → 0.1.9-alpha.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/{HLSView-IQRPLYNH.js → HLSView-U53QN3AC.js} +3 -3
- package/dist/Modal/Dialog.d.ts +402 -1706
- package/dist/Prebuilt/App.d.ts +6 -0
- package/dist/Prebuilt/AppContext.d.ts +2 -0
- package/dist/Prebuilt/AppStateContext.d.ts +16 -0
- package/dist/Prebuilt/components/ConferenceScreen.d.ts +2 -0
- package/dist/Prebuilt/components/Footer/PaginatedParticipants.d.ts +5 -0
- package/dist/Prebuilt/components/Footer/PollsToggle.d.ts +2 -0
- package/dist/Prebuilt/components/Footer/RoleAccordion.d.ts +10 -3
- 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-GP4ATXD3.js → VirtualBackground-PMLQPJB6.js} +3 -5
- package/dist/{VirtualBackground-GP4ATXD3.js.map → VirtualBackground-PMLQPJB6.js.map} +1 -1
- package/dist/chunk-ANQRGVIX.js +14441 -0
- package/dist/chunk-ANQRGVIX.js.map +7 -0
- package/dist/{chunk-Z3O2WGWV.js → chunk-XQ2NRKIW.js} +66 -3
- package/dist/chunk-XQ2NRKIW.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 +10956 -9818
- 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 +4076 -3201
- package/dist/meta.esbuild.json +4391 -3623
- package/dist/utils/animations.d.ts +11 -0
- package/package.json +6 -7
- package/src/AudioLevel/AudioLevel.tsx +1 -1
- package/src/Modal/Dialog.tsx +31 -3
- package/src/Prebuilt/App.tsx +49 -97
- package/src/Prebuilt/AppContext.tsx +6 -0
- package/src/Prebuilt/AppStateContext.tsx +71 -0
- package/src/Prebuilt/common/constants.js +36 -1
- package/src/Prebuilt/common/utils.js +47 -0
- package/src/Prebuilt/components/AppData/AppData.jsx +6 -1
- package/src/Prebuilt/components/AppData/useSidepane.js +23 -1
- package/src/Prebuilt/components/AppData/useUISettings.js +49 -5
- package/src/Prebuilt/components/Chip.tsx +6 -2
- package/src/Prebuilt/components/{conference.jsx → ConferenceScreen.tsx} +34 -46
- package/src/Prebuilt/components/Footer/Footer.tsx +5 -0
- package/src/Prebuilt/components/Footer/PaginatedParticipants.tsx +125 -0
- package/src/Prebuilt/components/Footer/ParticipantList.jsx +55 -24
- package/src/Prebuilt/components/Footer/PollsToggle.tsx +22 -0
- package/src/Prebuilt/components/Footer/RoleAccordion.tsx +87 -85
- package/src/Prebuilt/components/Footer/RoleOptions.tsx +1 -1
- 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 +29 -21
- 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 +32 -6
- 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 +28 -39
- package/src/Prebuilt/components/hooks/useAutoStartStreaming.tsx +3 -3
- package/src/Prebuilt/components/hooks/useDropdownSelection.jsx +1 -1
- 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 +9 -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/PrebuiltDialogPortal.d.ts +0 -4
- package/dist/Prebuilt/components/Preview/PreviewContainer.d.ts +0 -3
- package/dist/chunk-2H5NIZB7.js +0 -70
- package/dist/chunk-2H5NIZB7.js.map +0 -7
- package/dist/chunk-GLYGPYNS.js +0 -7125
- package/dist/chunk-GLYGPYNS.js.map +0 -7
- package/dist/chunk-Z3O2WGWV.js.map +0 -7
- package/dist/conference-JD35TNH4.js +0 -6503
- package/dist/conference-JD35TNH4.js.map +0 -7
- package/src/Prebuilt/components/GoLiveButton.jsx +0 -42
- package/src/Prebuilt/components/PrebuiltDialogPortal.tsx +0 -6
- 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-IQRPLYNH.js.map → HLSView-U53QN3AC.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
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
selectAppData,
|
|
4
4
|
selectAppDataByPath,
|
|
5
5
|
selectAudioTrackByPeerID,
|
|
6
|
+
selectPermissions,
|
|
7
|
+
selectPolls,
|
|
6
8
|
selectSessionStore,
|
|
7
9
|
selectTrackByID,
|
|
8
10
|
selectVideoTrackByPeerID,
|
|
@@ -11,7 +13,7 @@ import {
|
|
|
11
13
|
useHMSVanillaStore,
|
|
12
14
|
} from '@100mslive/react-sdk';
|
|
13
15
|
import { UserPreferencesKeys, useUserPreferences } from '../hooks/useUserPreferences';
|
|
14
|
-
import { APP_DATA, SESSION_STORE_KEY } from '../../common/constants';
|
|
16
|
+
import { APP_DATA, POLL_STATE, SESSION_STORE_KEY } from '../../common/constants';
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* fields saved related to UI settings in store's app data can be
|
|
@@ -69,8 +71,18 @@ export const useUrlToEmbed = () => {
|
|
|
69
71
|
return useHMSStore(selectAppData(APP_DATA.embedConfig))?.url;
|
|
70
72
|
};
|
|
71
73
|
|
|
72
|
-
export const
|
|
73
|
-
return useHMSStore(selectAppData(APP_DATA.pdfConfig))
|
|
74
|
+
export const usePDFConfig = () => {
|
|
75
|
+
return useHMSStore(selectAppData(APP_DATA.pdfConfig));
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const useResetPDFConfig = () => {
|
|
79
|
+
const [, setPDFConfig] = useSetAppDataByKey(APP_DATA.pdfConfig);
|
|
80
|
+
return useCallback(() => setPDFConfig(), [setPDFConfig]);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const useResetEmbedConfig = () => {
|
|
84
|
+
const [, setEmbedConfig] = useSetAppDataByKey(APP_DATA.embedConfig);
|
|
85
|
+
return () => setEmbedConfig();
|
|
74
86
|
};
|
|
75
87
|
export const usePinnedTrack = () => {
|
|
76
88
|
const pinnedTrackId = useHMSStore(selectAppData(APP_DATA.pinnedTrackId));
|
|
@@ -86,7 +98,7 @@ export const useSubscribedNotifications = notificationKey => {
|
|
|
86
98
|
};
|
|
87
99
|
|
|
88
100
|
export const useIsNotificationDisabled = () => {
|
|
89
|
-
const notificationPreference = useHMSStore(selectAppDataByPath(APP_DATA.
|
|
101
|
+
const notificationPreference = useHMSStore(selectAppDataByPath(APP_DATA.disableNotifications));
|
|
90
102
|
return notificationPreference;
|
|
91
103
|
};
|
|
92
104
|
|
|
@@ -153,3 +165,35 @@ const useSetAppData = ({ key1, key2 }) => {
|
|
|
153
165
|
);
|
|
154
166
|
return setValue;
|
|
155
167
|
};
|
|
168
|
+
|
|
169
|
+
export const useShowPolls = () => {
|
|
170
|
+
const permissions = useHMSStore(selectPermissions);
|
|
171
|
+
const polls = useHMSStore(selectPolls)?.filter(poll => poll.state === 'started' || poll.state === 'stopped');
|
|
172
|
+
|
|
173
|
+
const showPolls = useMemo(() => {
|
|
174
|
+
return permissions?.pollWrite || (permissions?.pollRead && polls?.length > 0);
|
|
175
|
+
}, [permissions?.pollRead, permissions?.pollWrite, polls?.length]);
|
|
176
|
+
|
|
177
|
+
return { showPolls };
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export const usePollViewState = () => {
|
|
181
|
+
const [pollState, setPollState] = useSetAppDataByKey(APP_DATA.pollState);
|
|
182
|
+
|
|
183
|
+
const setPollView = useCallback(
|
|
184
|
+
view => {
|
|
185
|
+
setPollState({
|
|
186
|
+
[POLL_STATE.pollInView]: pollState?.pollInView,
|
|
187
|
+
[POLL_STATE.view]: view,
|
|
188
|
+
});
|
|
189
|
+
},
|
|
190
|
+
[pollState?.pollInView, setPollState],
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
setPollState,
|
|
195
|
+
setPollView,
|
|
196
|
+
pollInView: pollState?.pollInView,
|
|
197
|
+
view: pollState?.view,
|
|
198
|
+
};
|
|
199
|
+
};
|
|
@@ -24,9 +24,13 @@ const Chip = ({
|
|
|
24
24
|
return null;
|
|
25
25
|
}
|
|
26
26
|
return (
|
|
27
|
-
<Flex
|
|
27
|
+
<Flex
|
|
28
|
+
align="center"
|
|
29
|
+
css={{ backgroundColor, p: '$4 $6', gap: '$2', borderRadius: '$4', ...css }}
|
|
30
|
+
onClick={() => onClick?.()}
|
|
31
|
+
>
|
|
28
32
|
{icon}
|
|
29
|
-
<Text variant="sm" css={{ fontWeight: '$semiBold', color: textColor
|
|
33
|
+
<Text variant="sm" css={{ fontWeight: '$semiBold', color: textColor }}>
|
|
30
34
|
{content}
|
|
31
35
|
</Text>
|
|
32
36
|
</Flex>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { usePrevious } from 'react-use';
|
|
2
|
+
import { DefaultConferencingScreen_Elements } from '@100mslive/types-prebuilt';
|
|
4
3
|
import {
|
|
5
4
|
HMSRoomState,
|
|
6
5
|
selectAppData,
|
|
@@ -11,38 +10,40 @@ import {
|
|
|
11
10
|
} from '@100mslive/react-sdk';
|
|
12
11
|
import { Footer } from './Footer/Footer';
|
|
13
12
|
import { HLSFailureModal } from './Notifications/HLSFailureModal';
|
|
13
|
+
// @ts-ignore: No implicit Any
|
|
14
14
|
import { ActivatedPIP } from './PIP/PIPComponent';
|
|
15
|
+
// @ts-ignore: No implicit Any
|
|
15
16
|
import { PictureInPicture } from './PIP/PIPManager';
|
|
16
17
|
import { RoleChangeRequestModal } from './RoleChangeRequest/RoleChangeRequestModal';
|
|
17
18
|
import { Box, Flex } from '../../Layout';
|
|
18
19
|
import { useHMSPrebuiltContext } from '../AppContext';
|
|
19
20
|
import { VideoStreamingSection } from '../layouts/VideoStreamingSection';
|
|
21
|
+
// @ts-ignore: No implicit Any
|
|
20
22
|
import FullPageProgress from './FullPageProgress';
|
|
21
23
|
import { Header } from './Header';
|
|
22
24
|
import {
|
|
23
25
|
useRoomLayoutConferencingScreen,
|
|
24
26
|
useRoomLayoutPreviewScreen,
|
|
25
27
|
} from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
|
28
|
+
// @ts-ignore: No implicit Any
|
|
26
29
|
import { useAuthToken, useSetAppDataByKey } from './AppData/useUISettings';
|
|
30
|
+
// @ts-ignore: No implicit Any
|
|
27
31
|
import { APP_DATA, isAndroid, isIOS, isIPadOS } from '../common/constants';
|
|
28
32
|
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const { roomId, role } = useParams();
|
|
32
|
-
const { userName, endpoints } = useHMSPrebuiltContext();
|
|
33
|
+
export const ConferenceScreen = () => {
|
|
34
|
+
const { userName, endpoints, onJoin: onJoinFunc } = useHMSPrebuiltContext();
|
|
33
35
|
const screenProps = useRoomLayoutConferencingScreen();
|
|
34
36
|
const { isPreviewScreenEnabled } = useRoomLayoutPreviewScreen();
|
|
35
37
|
const roomState = useHMSStore(selectRoomState);
|
|
36
|
-
const prevState = usePrevious(roomState);
|
|
37
38
|
const isConnectedToRoom = useHMSStore(selectIsConnectedToRoom);
|
|
38
39
|
const hmsActions = useHMSActions();
|
|
39
40
|
const [hideControls, setHideControls] = useState(false);
|
|
40
41
|
const dropdownList = useHMSStore(selectAppData(APP_DATA.dropdownList));
|
|
41
42
|
const authTokenInAppData = useAuthToken();
|
|
42
|
-
const headerRef = useRef();
|
|
43
|
-
const footerRef = useRef();
|
|
43
|
+
const headerRef = useRef<HTMLDivElement | null>(null);
|
|
44
|
+
const footerRef = useRef<HTMLDivElement | null>(null);
|
|
44
45
|
const isMobileDevice = isAndroid || isIOS || isIPadOS;
|
|
45
|
-
const dropdownListRef = useRef();
|
|
46
|
+
const dropdownListRef = useRef<string[]>();
|
|
46
47
|
const [isHLSStarted] = useSetAppDataByKey(APP_DATA.hlsStarted);
|
|
47
48
|
const toggleControls = () => {
|
|
48
49
|
if (dropdownListRef.current?.length === 0 && isMobileDevice) {
|
|
@@ -52,12 +53,12 @@ const Conference = () => {
|
|
|
52
53
|
const autoRoomJoined = useRef(isPreviewScreenEnabled);
|
|
53
54
|
|
|
54
55
|
useEffect(() => {
|
|
55
|
-
let timeout
|
|
56
|
+
let timeout: undefined | ReturnType<typeof setTimeout>;
|
|
56
57
|
dropdownListRef.current = dropdownList || [];
|
|
57
|
-
if (dropdownListRef.current.length === 0) {
|
|
58
|
+
if (dropdownListRef.current && dropdownListRef.current.length === 0) {
|
|
58
59
|
clearTimeout(timeout);
|
|
59
60
|
timeout = setTimeout(() => {
|
|
60
|
-
if (dropdownListRef.current.length === 0) {
|
|
61
|
+
if (dropdownListRef.current && dropdownListRef.current.length === 0) {
|
|
61
62
|
setHideControls(isMobileDevice);
|
|
62
63
|
}
|
|
63
64
|
}, 5000);
|
|
@@ -67,23 +68,6 @@ const Conference = () => {
|
|
|
67
68
|
};
|
|
68
69
|
}, [dropdownList, hideControls, isMobileDevice]);
|
|
69
70
|
|
|
70
|
-
useEffect(() => {
|
|
71
|
-
if (!roomId) {
|
|
72
|
-
navigate(`/`);
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
if (!isPreviewScreenEnabled) {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (
|
|
79
|
-
!prevState &&
|
|
80
|
-
!(roomState === HMSRoomState.Connecting || roomState === HMSRoomState.Reconnecting || isConnectedToRoom)
|
|
81
|
-
) {
|
|
82
|
-
if (role) navigate(`/preview/${roomId || ''}/${role}`);
|
|
83
|
-
else navigate(`/preview/${roomId || ''}`);
|
|
84
|
-
}
|
|
85
|
-
}, [isConnectedToRoom, prevState, roomState, navigate, role, roomId, isPreviewScreenEnabled]);
|
|
86
|
-
|
|
87
71
|
useEffect(() => {
|
|
88
72
|
if (
|
|
89
73
|
authTokenInAppData &&
|
|
@@ -94,10 +78,10 @@ const Conference = () => {
|
|
|
94
78
|
) {
|
|
95
79
|
hmsActions
|
|
96
80
|
.join({
|
|
97
|
-
userName,
|
|
81
|
+
userName: userName || '',
|
|
98
82
|
authToken: authTokenInAppData,
|
|
99
83
|
initEndpoint: endpoints?.init,
|
|
100
|
-
|
|
84
|
+
settings: {
|
|
101
85
|
isAudioMuted: !isPreviewScreenEnabled,
|
|
102
86
|
isVideoMuted: !isPreviewScreenEnabled,
|
|
103
87
|
speakerAutoSelectionBlacklist: ['Yeti Stereo Microphone'],
|
|
@@ -109,13 +93,14 @@ const Conference = () => {
|
|
|
109
93
|
}, [authTokenInAppData, endpoints?.init, hmsActions, isConnectedToRoom, isPreviewScreenEnabled, roomState, userName]);
|
|
110
94
|
|
|
111
95
|
useEffect(() => {
|
|
96
|
+
onJoinFunc?.();
|
|
112
97
|
return () => {
|
|
113
|
-
PictureInPicture.stop().catch(error => console.error('stopping pip', error));
|
|
98
|
+
PictureInPicture.stop().catch((error: unknown) => console.error('stopping pip', (error as Error).message));
|
|
114
99
|
};
|
|
115
|
-
}, []);
|
|
100
|
+
}, [onJoinFunc]);
|
|
116
101
|
|
|
117
|
-
if (!isConnectedToRoom) {
|
|
118
|
-
return <FullPageProgress text=
|
|
102
|
+
if (!isConnectedToRoom && ![HMSRoomState.Reconnecting, HMSRoomState.Disconnected].includes(roomState)) {
|
|
103
|
+
return <FullPageProgress text={roomState === HMSRoomState.Connecting ? 'Joining...' : ''} />;
|
|
119
104
|
}
|
|
120
105
|
|
|
121
106
|
return (
|
|
@@ -139,7 +124,7 @@ const Conference = () => {
|
|
|
139
124
|
}}
|
|
140
125
|
data-testid="header"
|
|
141
126
|
>
|
|
142
|
-
<Header
|
|
127
|
+
<Header />
|
|
143
128
|
</Box>
|
|
144
129
|
)}
|
|
145
130
|
<Box
|
|
@@ -147,7 +132,10 @@ const Conference = () => {
|
|
|
147
132
|
w: '100%',
|
|
148
133
|
flex: '1 1 0',
|
|
149
134
|
minHeight: 0,
|
|
150
|
-
|
|
135
|
+
// @ts-ignore
|
|
136
|
+
px: (screenProps?.elements as DefaultConferencingScreen_Elements)?.video_tile_layout?.grid?.edge_to_edge
|
|
137
|
+
? 0
|
|
138
|
+
: '$10', // TODO: padding to be controlled by section/element
|
|
151
139
|
paddingBottom: 'env(safe-area-inset-bottom)',
|
|
152
140
|
'@lg': {
|
|
153
141
|
px: 0,
|
|
@@ -157,13 +145,15 @@ const Conference = () => {
|
|
|
157
145
|
data-testid="conferencing"
|
|
158
146
|
onClick={toggleControls}
|
|
159
147
|
>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
148
|
+
{screenProps.elements ? (
|
|
149
|
+
<VideoStreamingSection
|
|
150
|
+
screenType={screenProps.screenType}
|
|
151
|
+
elements={screenProps.elements}
|
|
152
|
+
hideControls={hideControls}
|
|
153
|
+
/>
|
|
154
|
+
) : null}
|
|
165
155
|
</Box>
|
|
166
|
-
{!screenProps.hideSections.includes('footer') && (
|
|
156
|
+
{!screenProps.hideSections.includes('footer') && screenProps.elements && (
|
|
167
157
|
<Box
|
|
168
158
|
ref={footerRef}
|
|
169
159
|
css={{
|
|
@@ -189,5 +179,3 @@ const Conference = () => {
|
|
|
189
179
|
</>
|
|
190
180
|
);
|
|
191
181
|
};
|
|
192
|
-
|
|
193
|
-
export default Conference;
|
|
@@ -24,9 +24,12 @@ import { ScreenshareToggle } from '../ScreenShareToggle';
|
|
|
24
24
|
import { ChatToggle } from './ChatToggle';
|
|
25
25
|
// @ts-ignore: No implicit Any
|
|
26
26
|
import { ParticipantCount } from './ParticipantList';
|
|
27
|
+
import { PollsToggle } from './PollsToggle';
|
|
27
28
|
// @ts-ignore: No implicit Any
|
|
28
29
|
import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane';
|
|
29
30
|
// @ts-ignore: No implicit Any
|
|
31
|
+
import { useShowPolls } from '../AppData/useUISettings';
|
|
32
|
+
// @ts-ignore: No implicit Any
|
|
30
33
|
import { SIDE_PANE_OPTIONS } from '../../common/constants';
|
|
31
34
|
// @ts-ignore: No implicit Any
|
|
32
35
|
const VirtualBackground = React.lazy(() => import('../../plugins/VirtualBackground/VirtualBackground'));
|
|
@@ -46,6 +49,7 @@ export const Footer = ({
|
|
|
46
49
|
const noAVPermissions = !(toggleAudio || toggleVideo);
|
|
47
50
|
const isChatOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.CHAT);
|
|
48
51
|
const toggleChat = useSidepaneToggle(SIDE_PANE_OPTIONS.CHAT);
|
|
52
|
+
const { showPolls } = useShowPolls();
|
|
49
53
|
|
|
50
54
|
useEffect(() => {
|
|
51
55
|
if (!isChatOpen && openByDefault) {
|
|
@@ -108,6 +112,7 @@ export const Footer = ({
|
|
|
108
112
|
)}
|
|
109
113
|
</AppFooter.Center>
|
|
110
114
|
<AppFooter.Right>
|
|
115
|
+
{showPolls && <PollsToggle />}
|
|
111
116
|
{!isMobile && elements?.chat && <ChatToggle />}
|
|
112
117
|
{elements?.participant_list && <ParticipantCount />}
|
|
113
118
|
<MoreSettings elements={elements} screenType={screenType} />
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { useInView } from 'react-intersection-observer';
|
|
3
|
+
import { useMeasure } from 'react-use';
|
|
4
|
+
import { VariableSizeList } from 'react-window';
|
|
5
|
+
import { selectIsConnectedToRoom, useHMSStore, usePaginatedParticipants } from '@100mslive/react-sdk';
|
|
6
|
+
import { ChevronLeftIcon, CrossIcon } from '@100mslive/react-icons';
|
|
7
|
+
import { IconButton } from '../../../IconButton';
|
|
8
|
+
import { Box, Flex } from '../../../Layout';
|
|
9
|
+
import { Loading } from '../../../Loading';
|
|
10
|
+
import { Text } from '../../../Text';
|
|
11
|
+
// @ts-ignore: No implicit Any
|
|
12
|
+
import { Participant, ParticipantSearch } from './ParticipantList';
|
|
13
|
+
import { ItemData, itemKey, ROW_HEIGHT } from './RoleAccordion';
|
|
14
|
+
// @ts-ignore: No implicit Any
|
|
15
|
+
import { useSidepaneReset } from '../AppData/useSidepane';
|
|
16
|
+
// @ts-ignore: No implicit Any
|
|
17
|
+
import { getFormattedCount } from '../../common/utils';
|
|
18
|
+
|
|
19
|
+
const LoadMoreParticipants = ({
|
|
20
|
+
hasNext,
|
|
21
|
+
loadMore,
|
|
22
|
+
style,
|
|
23
|
+
}: {
|
|
24
|
+
hasNext: boolean;
|
|
25
|
+
loadMore: () => Promise<void>;
|
|
26
|
+
style: React.CSSProperties;
|
|
27
|
+
}) => {
|
|
28
|
+
const { ref, inView } = useInView();
|
|
29
|
+
const [inProgress, setInProgress] = useState(false);
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (hasNext && inView && !inProgress) {
|
|
33
|
+
setInProgress(true);
|
|
34
|
+
loadMore()
|
|
35
|
+
.catch(console.error)
|
|
36
|
+
.finally(() => setInProgress(false));
|
|
37
|
+
}
|
|
38
|
+
}, [hasNext, loadMore, inView, inProgress]);
|
|
39
|
+
return (
|
|
40
|
+
<Flex ref={ref} style={style} align="center" justify="center">
|
|
41
|
+
{inProgress ? <Loading size={16} /> : null}
|
|
42
|
+
</Flex>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const VirtualizedParticipantItem = React.memo(
|
|
47
|
+
({
|
|
48
|
+
index,
|
|
49
|
+
data,
|
|
50
|
+
style,
|
|
51
|
+
}: {
|
|
52
|
+
index: number;
|
|
53
|
+
data: ItemData & { hasNext: boolean; loadMorePeers: () => Promise<void> };
|
|
54
|
+
style: React.CSSProperties;
|
|
55
|
+
}) => {
|
|
56
|
+
if (!data.peerList[index]) {
|
|
57
|
+
return <LoadMoreParticipants hasNext={data.hasNext} loadMore={data.loadMorePeers} style={style} />;
|
|
58
|
+
}
|
|
59
|
+
return (
|
|
60
|
+
<Participant
|
|
61
|
+
key={data.peerList[index].id}
|
|
62
|
+
peer={data.peerList[index]}
|
|
63
|
+
isConnected={data.isConnected}
|
|
64
|
+
style={style}
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
export const PaginatedParticipants = ({ roleName, onBack }: { roleName: string; onBack: () => void }) => {
|
|
71
|
+
const { peers, total, hasNext, loadPeers, loadMorePeers } = usePaginatedParticipants({ role: roleName, limit: 20 });
|
|
72
|
+
const [search, setSearch] = useState<string>('');
|
|
73
|
+
const filteredPeers = peers.filter(p => p.name?.toLowerCase().includes(search));
|
|
74
|
+
const isConnected = useHMSStore(selectIsConnectedToRoom);
|
|
75
|
+
const [ref, { width }] = useMeasure<HTMLDivElement>();
|
|
76
|
+
const height = ROW_HEIGHT * (filteredPeers.length + 1);
|
|
77
|
+
const resetSidePane = useSidepaneReset();
|
|
78
|
+
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
loadPeers();
|
|
81
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
82
|
+
}, []);
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<Flex ref={ref} direction="column" css={{ size: '100%', gap: '$4' }}>
|
|
86
|
+
<Flex align="center">
|
|
87
|
+
<Flex align="center" css={{ flex: '1 1 0', cursor: 'pointer' }} onClick={onBack}>
|
|
88
|
+
<ChevronLeftIcon />
|
|
89
|
+
<Text variant="lg" css={{ flex: '1 1 0' }}>
|
|
90
|
+
Participants
|
|
91
|
+
</Text>
|
|
92
|
+
</Flex>
|
|
93
|
+
<IconButton
|
|
94
|
+
onClick={e => {
|
|
95
|
+
e.stopPropagation();
|
|
96
|
+
resetSidePane();
|
|
97
|
+
}}
|
|
98
|
+
data-testid="close_sidepane"
|
|
99
|
+
>
|
|
100
|
+
<CrossIcon />
|
|
101
|
+
</IconButton>
|
|
102
|
+
</Flex>
|
|
103
|
+
<ParticipantSearch onSearch={(search: string) => setSearch(search)} placeholder={`Search for ${roleName}`} />
|
|
104
|
+
<Flex direction="column" css={{ border: '1px solid $border_default', borderRadius: '$1', flex: '1 1 0' }}>
|
|
105
|
+
<Flex align="center" css={{ height: ROW_HEIGHT, borderBottom: '1px solid $border_default', px: '$8' }}>
|
|
106
|
+
<Text css={{ fontSize: '$space$7' }}>
|
|
107
|
+
{roleName}({getFormattedCount(peers.length)}/{getFormattedCount(total)})
|
|
108
|
+
</Text>
|
|
109
|
+
</Flex>
|
|
110
|
+
<Box css={{ flex: '1 1 0', overflowY: 'auto', overflowX: 'hidden', mr: '-$10' }}>
|
|
111
|
+
<VariableSizeList
|
|
112
|
+
itemSize={index => (index === filteredPeers.length + 1 ? 16 : ROW_HEIGHT)}
|
|
113
|
+
itemData={{ peerList: filteredPeers, hasNext: hasNext(), loadMorePeers, isConnected: isConnected === true }}
|
|
114
|
+
itemKey={itemKey}
|
|
115
|
+
itemCount={filteredPeers.length + 1}
|
|
116
|
+
width={width}
|
|
117
|
+
height={height}
|
|
118
|
+
>
|
|
119
|
+
{VirtualizedParticipantItem}
|
|
120
|
+
</VariableSizeList>
|
|
121
|
+
</Box>
|
|
122
|
+
</Flex>
|
|
123
|
+
</Flex>
|
|
124
|
+
);
|
|
125
|
+
};
|
|
@@ -3,6 +3,7 @@ import { useDebounce, useMedia } from 'react-use';
|
|
|
3
3
|
import {
|
|
4
4
|
selectHandRaisedPeers,
|
|
5
5
|
selectHasPeerHandRaised,
|
|
6
|
+
selectIsLargeRoom,
|
|
6
7
|
selectIsPeerAudioEnabled,
|
|
7
8
|
selectLocalPeerID,
|
|
8
9
|
selectPeerCount,
|
|
@@ -20,7 +21,7 @@ import {
|
|
|
20
21
|
SearchIcon,
|
|
21
22
|
VerticalMenuIcon,
|
|
22
23
|
} from '@100mslive/react-icons';
|
|
23
|
-
import { Box, config as cssConfig, Dropdown, Flex, Input, Text, textEllipsis } from '../../..';
|
|
24
|
+
import { Accordion, Box, config as cssConfig, Dropdown, Flex, Input, Text, textEllipsis } from '../../..';
|
|
24
25
|
import IconButton from '../../IconButton';
|
|
25
26
|
import { ConnectionIndicator } from '../Connection/ConnectionIndicator';
|
|
26
27
|
import { ToastManager } from '../Toast/ToastManager';
|
|
@@ -31,9 +32,10 @@ import { useParticipants } from '../../common/hooks';
|
|
|
31
32
|
import { getFormattedCount } from '../../common/utils';
|
|
32
33
|
import { SIDE_PANE_OPTIONS } from '../../common/constants';
|
|
33
34
|
|
|
34
|
-
export const ParticipantList = () => {
|
|
35
|
+
export const ParticipantList = ({ offStageRoles = [], onActive }) => {
|
|
35
36
|
const [filter, setFilter] = useState();
|
|
36
37
|
const { participants, isConnected, peerCount } = useParticipants(filter);
|
|
38
|
+
const isLargeRoom = useHMSStore(selectIsLargeRoom);
|
|
37
39
|
const peersOrderedByRoles = {};
|
|
38
40
|
|
|
39
41
|
const handRaisedPeers = useHMSStore(selectHandRaisedPeers);
|
|
@@ -45,6 +47,15 @@ export const ParticipantList = () => {
|
|
|
45
47
|
peersOrderedByRoles[participant.roleName].push(participant);
|
|
46
48
|
});
|
|
47
49
|
|
|
50
|
+
// prefill off_stage roles of large rooms to load more peers
|
|
51
|
+
if (isLargeRoom) {
|
|
52
|
+
offStageRoles.forEach(role => {
|
|
53
|
+
if (!peersOrderedByRoles[role]) {
|
|
54
|
+
peersOrderedByRoles[role] = [];
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
48
59
|
const onSearch = useCallback(value => {
|
|
49
60
|
setFilter(filterValue => {
|
|
50
61
|
if (!filterValue) {
|
|
@@ -72,6 +83,9 @@ export const ParticipantList = () => {
|
|
|
72
83
|
handRaisedList={handRaisedPeers}
|
|
73
84
|
isConnected={isConnected}
|
|
74
85
|
filter={filter}
|
|
86
|
+
offStageRoles={offStageRoles}
|
|
87
|
+
isLargeRoom={isLargeRoom}
|
|
88
|
+
onActive={onActive}
|
|
75
89
|
/>
|
|
76
90
|
</Flex>
|
|
77
91
|
</Fragment>
|
|
@@ -114,7 +128,15 @@ export const ParticipantCount = () => {
|
|
|
114
128
|
);
|
|
115
129
|
};
|
|
116
130
|
|
|
117
|
-
const VirtualizedParticipants = ({
|
|
131
|
+
const VirtualizedParticipants = ({
|
|
132
|
+
peersOrderedByRoles = {},
|
|
133
|
+
isConnected,
|
|
134
|
+
filter,
|
|
135
|
+
handRaisedList = [],
|
|
136
|
+
offStageRoles,
|
|
137
|
+
isLargeRoom,
|
|
138
|
+
onActive,
|
|
139
|
+
}) => {
|
|
118
140
|
return (
|
|
119
141
|
<Flex
|
|
120
142
|
direction="column"
|
|
@@ -127,29 +149,34 @@ const VirtualizedParticipants = ({ peersOrderedByRoles = {}, isConnected, filter
|
|
|
127
149
|
flex: '1 1 0',
|
|
128
150
|
}}
|
|
129
151
|
>
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
152
|
+
<Accordion.Root type={isLargeRoom ? 'single' : 'multiple'} collapsible>
|
|
153
|
+
{handRaisedList.length > 0 ? (
|
|
154
|
+
<RoleAccordion
|
|
155
|
+
peerList={handRaisedList}
|
|
156
|
+
roleName="Hand Raised"
|
|
157
|
+
filter={filter}
|
|
158
|
+
isConnected={isConnected}
|
|
159
|
+
isHandRaisedAccordion
|
|
160
|
+
offStageRoles={offStageRoles}
|
|
161
|
+
/>
|
|
162
|
+
) : null}
|
|
163
|
+
{Object.keys(peersOrderedByRoles).map(role => (
|
|
164
|
+
<RoleAccordion
|
|
165
|
+
key={role}
|
|
166
|
+
peerList={peersOrderedByRoles[role]}
|
|
167
|
+
roleName={role}
|
|
168
|
+
isConnected={isConnected}
|
|
169
|
+
filter={filter}
|
|
170
|
+
offStageRoles={offStageRoles}
|
|
171
|
+
onActive={onActive}
|
|
172
|
+
/>
|
|
173
|
+
))}
|
|
174
|
+
</Accordion.Root>
|
|
148
175
|
</Flex>
|
|
149
176
|
);
|
|
150
177
|
};
|
|
151
178
|
|
|
152
|
-
export const Participant = ({ peer, isConnected }) => {
|
|
179
|
+
export const Participant = ({ peer, isConnected, style }) => {
|
|
153
180
|
const localPeerId = useHMSStore(selectLocalPeerID);
|
|
154
181
|
return (
|
|
155
182
|
<Flex
|
|
@@ -164,8 +191,12 @@ export const Participant = ({ peer, isConnected }) => {
|
|
|
164
191
|
align="center"
|
|
165
192
|
justify="between"
|
|
166
193
|
data-testid={'participant_' + peer.name}
|
|
194
|
+
style={style}
|
|
167
195
|
>
|
|
168
|
-
<Text
|
|
196
|
+
<Text
|
|
197
|
+
variant="sm"
|
|
198
|
+
css={{ ...textEllipsis('100%'), flex: '1 1 0', mr: '$8', fontWeight: '$semiBold', color: '$on_surface_high' }}
|
|
199
|
+
>
|
|
169
200
|
{peer.name} {localPeerId === peer.id ? '(You)' : ''}
|
|
170
201
|
</Text>
|
|
171
202
|
{isConnected ? (
|
|
@@ -338,7 +369,7 @@ export const ParticipantSearch = ({ onSearch, placeholder, inSidePane = false })
|
|
|
338
369
|
<Input
|
|
339
370
|
type="text"
|
|
340
371
|
placeholder={placeholder || 'Search for participants'}
|
|
341
|
-
css={{ w: '100%', p: '$6', pl: '$
|
|
372
|
+
css={{ w: '100%', p: '$6', pl: '$14', bg: inSidePane ? '$surface_default' : '$surface_dim' }}
|
|
342
373
|
value={value}
|
|
343
374
|
onKeyDown={event => {
|
|
344
375
|
event.stopPropagation();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { QuizIcon } from '@100mslive/react-icons';
|
|
3
|
+
import { Tooltip } from '../../..';
|
|
4
|
+
// @ts-ignore: No implicit Any
|
|
5
|
+
import IconButton from '../../IconButton';
|
|
6
|
+
// @ts-ignore: No implicit Any
|
|
7
|
+
import { useIsSidepaneTypeOpen, usePollViewToggle } from '../AppData/useSidepane';
|
|
8
|
+
// @ts-ignore: No implicit Any
|
|
9
|
+
import { SIDE_PANE_OPTIONS } from '../../common/constants';
|
|
10
|
+
|
|
11
|
+
export const PollsToggle = () => {
|
|
12
|
+
const isPollsOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.POLLS);
|
|
13
|
+
const togglePollView = usePollViewToggle();
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<Tooltip key="polls" title={`${isPollsOpen ? 'Close' : 'Open'} polls and quizzes`}>
|
|
17
|
+
<IconButton onClick={togglePollView} active={!isPollsOpen} data-testid="polls_btn">
|
|
18
|
+
<QuizIcon />
|
|
19
|
+
</IconButton>
|
|
20
|
+
</Tooltip>
|
|
21
|
+
);
|
|
22
|
+
};
|