@100mslive/roomkit-react 0.1.5 → 0.1.6-alpha.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/{HLSView-P57IRMAR.js → HLSView-PY2FKWX3.js} +191 -123
- package/dist/HLSView-PY2FKWX3.js.map +7 -0
- package/dist/Prebuilt/App.d.ts +3 -0
- package/dist/Prebuilt/AppContext.d.ts +13 -0
- package/dist/Prebuilt/common/PeersSorter.d.ts +21 -0
- package/dist/Prebuilt/components/Footer/Footer.d.ts +6 -0
- package/dist/Prebuilt/components/Header/Header.d.ts +2 -0
- package/dist/Prebuilt/components/InsetTile.d.ts +2 -0
- package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +7 -0
- package/dist/Prebuilt/components/Leave/EndSessionContent.d.ts +8 -0
- package/dist/Prebuilt/components/Leave/LeaveAtoms.d.ts +2196 -0
- package/dist/Prebuilt/components/Leave/LeaveCard.d.ts +12 -0
- package/dist/Prebuilt/components/Leave/LeaveRoom.d.ts +5 -0
- package/dist/Prebuilt/components/Leave/LeaveSessionContent.d.ts +6 -0
- package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +7 -0
- package/dist/Prebuilt/components/MoreSettings/MoreSettings.d.ts +6 -0
- package/dist/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.d.ts +6 -0
- package/dist/Prebuilt/components/Pagination.d.ts +6 -0
- package/dist/Prebuilt/components/Preview/PreviewForm.d.ts +10 -0
- package/dist/Prebuilt/components/SecondaryTiles.d.ts +3 -0
- package/dist/Prebuilt/components/VideoLayouts/EqualProminence.d.ts +3 -0
- package/dist/Prebuilt/components/VideoLayouts/Grid.d.ts +5 -0
- package/dist/Prebuilt/components/VideoLayouts/GridLayout.d.ts +10 -0
- package/dist/Prebuilt/components/VideoLayouts/ProminenceLayout.d.ts +12 -0
- package/dist/Prebuilt/components/VideoLayouts/RoleProminence.d.ts +3 -0
- package/dist/Prebuilt/components/VideoLayouts/ScreenshareLayout.d.ts +3 -0
- package/dist/Prebuilt/components/VideoLayouts/interface.d.ts +8 -0
- package/dist/Prebuilt/components/hooks/useRoleProminencePeers.d.ts +5 -0
- package/dist/Prebuilt/components/hooks/useTileLayout.d.ts +12 -0
- package/dist/Prebuilt/components/hooks/useVideoTileLayout.d.ts +11 -0
- package/dist/Prebuilt/layouts/SidePane.d.ts +6 -0
- package/dist/Prebuilt/layouts/VideoStreamingSection.d.ts +6 -0
- package/dist/Prebuilt/plugins/whiteboard/ToggleWhiteboard.d.ts +5 -0
- package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.d.ts +1 -0
- package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useInsetEnabled.d.ts +1 -0
- package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useRoomLayoutScreen.d.ts +17 -0
- package/dist/Prebuilt/provider/roomLayoutProvider/index.d.ts +6 -1
- package/dist/{VirtualBackground-GGCQJ5JM.js → VirtualBackground-AYDHYLIZ.js} +5 -11
- package/dist/VirtualBackground-AYDHYLIZ.js.map +7 -0
- package/dist/{chunk-P5X32KOD.js → chunk-E2M2ZSOL.js} +8 -5
- package/dist/chunk-E2M2ZSOL.js.map +7 -0
- package/dist/chunk-GQD2AGWW.js +888 -0
- package/dist/chunk-GQD2AGWW.js.map +7 -0
- package/dist/{chunk-OSM4QEQG.js → chunk-RXTHJUMZ.js} +2462 -4738
- package/dist/chunk-RXTHJUMZ.js.map +7 -0
- package/dist/conference-V2XZGTKU.js +5927 -0
- package/dist/conference-V2XZGTKU.js.map +7 -0
- package/dist/index.cjs.js +9414 -15534
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +2 -2
- package/dist/meta.cjs.json +2156 -3347
- package/dist/meta.esbuild.json +2601 -3885
- package/package.json +7 -7
- package/src/Button/Button.tsx +2 -2
- package/src/Prebuilt/App.tsx +49 -33
- package/src/Prebuilt/{AppContext.jsx → AppContext.tsx} +11 -3
- package/src/Prebuilt/IconButton.jsx +1 -0
- package/src/Prebuilt/Prebuilt.stories.tsx +1 -0
- package/src/Prebuilt/common/{PeersSorter.js → PeersSorter.ts} +15 -10
- package/src/Prebuilt/common/constants.js +3 -112
- package/src/Prebuilt/common/hooks.js +34 -1
- package/src/Prebuilt/common/utils.js +0 -8
- package/src/Prebuilt/components/AppData/AppData.jsx +3 -13
- package/src/Prebuilt/components/AppData/useUISettings.js +0 -4
- package/src/Prebuilt/components/AudioVideoToggle.jsx +6 -0
- package/src/Prebuilt/components/AuthToken.jsx +11 -42
- package/src/Prebuilt/components/Chat/Chat.jsx +57 -26
- package/src/Prebuilt/components/Chat/ChatBody.jsx +92 -32
- package/src/Prebuilt/components/Chat/ChatFooter.jsx +72 -48
- package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +73 -0
- package/src/Prebuilt/components/Chat/ChatSelector.jsx +16 -17
- package/src/Prebuilt/components/Chat/ChatSelectorContainer.jsx +81 -0
- package/src/Prebuilt/components/Connection/TileConnection.jsx +30 -12
- package/src/Prebuilt/components/EmojiReaction.jsx +18 -17
- package/src/Prebuilt/components/Footer/ChatToggle.jsx +1 -7
- package/src/Prebuilt/components/Footer/Footer.tsx +89 -0
- package/src/Prebuilt/components/Footer/ParticipantList.jsx +213 -173
- package/src/Prebuilt/components/Footer/RoleAccordion.jsx +78 -0
- package/src/Prebuilt/components/HMSVideo/Controls.jsx +2 -2
- package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +33 -10
- package/src/Prebuilt/components/HMSVideo/PlayButton.jsx +1 -1
- package/src/Prebuilt/components/HMSVideo/VideoTime.jsx +3 -3
- package/src/Prebuilt/components/HMSVideo/VolumeControl.jsx +38 -9
- package/src/Prebuilt/components/Header/{ConferencingHeader.jsx → Header.tsx} +9 -7
- package/src/Prebuilt/components/Header/HeaderComponents.jsx +13 -4
- package/src/Prebuilt/components/Header/StreamActions.jsx +33 -60
- package/src/Prebuilt/components/Header/index.tsx +1 -0
- package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +17 -3
- package/src/Prebuilt/components/InsetTile.tsx +122 -0
- package/src/Prebuilt/components/{MoreSettings/SplitComponents/DesktopLeaveRoom.jsx → Leave/DesktopLeaveRoom.tsx} +50 -18
- package/src/Prebuilt/components/{EndSessionContent.jsx → Leave/EndSessionContent.tsx} +19 -9
- package/src/Prebuilt/components/Leave/LeaveAtoms.tsx +26 -0
- package/src/Prebuilt/components/{LeaveCard.jsx → Leave/LeaveCard.tsx} +22 -3
- package/src/Prebuilt/components/Leave/LeaveRoom.tsx +63 -0
- package/src/Prebuilt/components/{LeaveSessionContent.jsx → Leave/LeaveSessionContent.tsx} +13 -5
- package/src/Prebuilt/components/{MoreSettings/SplitComponents/MwebLeaveRoom.jsx → Leave/MwebLeaveRoom.tsx} +38 -13
- package/src/Prebuilt/components/MetaActions.jsx +15 -23
- package/src/Prebuilt/components/MoreSettings/ActionTile.jsx +5 -0
- package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +12 -7
- package/src/Prebuilt/components/MoreSettings/ChangeNameModal.jsx +1 -1
- package/src/Prebuilt/components/MoreSettings/FullScreenItem.jsx +1 -4
- package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +27 -0
- package/src/Prebuilt/components/MoreSettings/SplitComponents/{DesktopOptions.jsx → DesktopOptions.tsx} +86 -75
- package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.jsx +20 -19
- package/src/Prebuilt/components/Notifications/HLSFailureModal.jsx +3 -1
- package/src/Prebuilt/components/Notifications/Notifications.jsx +18 -11
- package/src/Prebuilt/components/Notifications/PeerNotifications.jsx +14 -2
- package/src/Prebuilt/components/Notifications/PermissionErrorModal.jsx +10 -4
- package/src/Prebuilt/components/PIP/PIPComponent.jsx +7 -16
- package/src/Prebuilt/components/PIP/PIPManager.js +1 -0
- package/src/Prebuilt/components/{Pagination.jsx → Pagination.tsx} +35 -6
- package/src/Prebuilt/components/Playlist/Playlist.jsx +1 -6
- package/src/Prebuilt/components/PostLeave.jsx +7 -7
- package/src/Prebuilt/components/Preview/PreviewContainer.jsx +5 -13
- package/src/Prebuilt/components/Preview/{PreviewForm.jsx → PreviewForm.tsx} +14 -4
- package/src/Prebuilt/components/Preview/PreviewJoin.jsx +9 -7
- package/src/Prebuilt/components/RaiseHand.jsx +0 -7
- package/src/Prebuilt/components/RoleChangeRequestModal.jsx +82 -6
- package/src/Prebuilt/components/ScreenshareDisplay.jsx +4 -10
- package/src/Prebuilt/components/ScreenshareTile.jsx +41 -33
- package/src/Prebuilt/components/SecondaryTiles.tsx +34 -0
- package/src/Prebuilt/components/Settings/LayoutSettings.jsx +2 -12
- package/src/Prebuilt/components/Settings/NotificationSettings.jsx +3 -9
- package/src/Prebuilt/components/Settings/SettingsModal.jsx +3 -9
- package/src/Prebuilt/components/StatsForNerds.jsx +3 -1
- package/src/Prebuilt/components/TileMenu/TileMenu.jsx +15 -16
- package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +21 -19
- package/src/Prebuilt/components/Toast/ToastConfig.jsx +53 -11
- package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +62 -0
- package/src/Prebuilt/components/VideoLayouts/Grid.tsx +41 -0
- package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +92 -0
- package/src/Prebuilt/components/VideoLayouts/ProminenceLayout.tsx +60 -0
- package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +56 -0
- package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +36 -0
- package/src/Prebuilt/components/VideoLayouts/interface.ts +9 -0
- package/src/Prebuilt/components/VideoTile.jsx +93 -43
- package/src/Prebuilt/components/conference.jsx +24 -20
- package/src/Prebuilt/components/hooks/useMetadata.jsx +7 -0
- package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +38 -0
- package/src/Prebuilt/components/hooks/useTileLayout.tsx +121 -0
- package/src/Prebuilt/components/hooks/useVideoTileLayout.ts +22 -0
- package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +5 -72
- package/src/Prebuilt/components/pdfAnnotator/submitPdf.jsx +4 -45
- package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +2 -17
- package/src/Prebuilt/components/peerTileUtils.jsx +1 -1
- package/src/Prebuilt/images/empty-chat.svg +12 -0
- package/src/Prebuilt/layouts/EmbedView.jsx +17 -40
- package/src/Prebuilt/layouts/HLSView.jsx +83 -66
- package/src/Prebuilt/layouts/PDFView.jsx +1 -11
- package/src/Prebuilt/layouts/SidePane.tsx +96 -0
- package/src/Prebuilt/layouts/{mainView.jsx → VideoStreamingSection.tsx} +38 -47
- package/src/Prebuilt/layouts/WhiteboardView.jsx +10 -34
- package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +1 -4
- package/src/Prebuilt/plugins/whiteboard/{ToggleWhiteboard.jsx → ToggleWhiteboard.tsx} +5 -9
- package/src/Prebuilt/primitives/DialogContent.jsx +15 -11
- package/src/Prebuilt/provider/roomLayoutProvider/constants/index.ts +17 -2
- package/src/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.ts +36 -13
- package/src/Prebuilt/provider/roomLayoutProvider/hooks/useInsetEnabled.ts +10 -0
- package/src/Prebuilt/provider/roomLayoutProvider/hooks/useRoomLayoutScreen.ts +65 -0
- package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +17 -6
- package/dist/HLSView-P57IRMAR.js.map +0 -7
- package/dist/PinnedTrackView-4FYJEBTB.js +0 -102
- package/dist/PinnedTrackView-4FYJEBTB.js.map +0 -7
- package/dist/VirtualBackground-GGCQJ5JM.js.map +0 -7
- package/dist/chunk-IVTWKQI3.js +0 -827
- package/dist/chunk-IVTWKQI3.js.map +0 -7
- package/dist/chunk-OSM4QEQG.js.map +0 -7
- package/dist/chunk-P5X32KOD.js.map +0 -7
- package/dist/chunk-RVCZPPTL.js +0 -1100
- package/dist/chunk-RVCZPPTL.js.map +0 -7
- package/dist/conference-P6I6ESVF.js +0 -8995
- package/dist/conference-P6I6ESVF.js.map +0 -7
- package/src/Prebuilt/components/Chat/ChatHeader.jsx +0 -67
- package/src/Prebuilt/components/EqualProminence.jsx +0 -180
- package/src/Prebuilt/components/FirstPersonDisplay.jsx +0 -50
- package/src/Prebuilt/components/Footer/Footer.jsx +0 -73
- package/src/Prebuilt/components/Header/Header.jsx +0 -8
- package/src/Prebuilt/components/Header/StreamingHeader.jsx +0 -54
- package/src/Prebuilt/components/LeaveRoom.jsx +0 -94
- package/src/Prebuilt/components/MoreSettings/MoreSettings.jsx +0 -10
- package/src/Prebuilt/components/Notifications/MessageNotifications.jsx +0 -25
- package/src/Prebuilt/components/gridView.jsx +0 -85
- package/src/Prebuilt/components/hooks/useFeatures.js +0 -22
- package/src/Prebuilt/components/hooks/useNavigation.js +0 -19
- package/src/Prebuilt/components/hooks/useSkipPreview.jsx +0 -20
- package/src/Prebuilt/components/pdfAnnotator/pdfErrorView.jsx +0 -29
- package/src/Prebuilt/images/Logo.svg +0 -8
- package/src/Prebuilt/layouts/ActiveSpeakerView.jsx +0 -34
- package/src/Prebuilt/layouts/InsetView.jsx +0 -260
- package/src/Prebuilt/layouts/PinnedTrackView.jsx +0 -59
- package/src/Prebuilt/layouts/SidePane.jsx +0 -52
- package/src/Prebuilt/layouts/mainGridView.jsx +0 -98
- package/src/Prebuilt/layouts/screenShareView.jsx +0 -183
- /package/{src/Prebuilt/components/Header/index.jsx → dist/Prebuilt/components/Header/index.d.ts} +0 -0
- /package/src/Prebuilt/components/{ScreenShare.jsx → ScreenShareToggle.jsx} +0 -0
- /package/src/{assets → Prebuilt/images}/android-perm-1.png +0 -0
- /package/src/{assets → Prebuilt/images}/ios-perm-0.png +0 -0
@@ -1,46 +1,58 @@
|
|
1
1
|
import React, { Fragment, useCallback, useEffect, useState } from 'react';
|
2
|
-
import { useDebounce,
|
3
|
-
import { FixedSizeList } from 'react-window';
|
2
|
+
import { useDebounce, useMedia } from 'react-use';
|
4
3
|
import {
|
5
|
-
|
4
|
+
selectIsPeerAudioEnabled,
|
6
5
|
selectLocalPeerID,
|
7
6
|
selectPeerCount,
|
8
7
|
selectPeerMetadata,
|
8
|
+
selectPeersByCondition,
|
9
9
|
selectPermissions,
|
10
10
|
useHMSActions,
|
11
11
|
useHMSStore,
|
12
|
-
useParticipants,
|
13
12
|
} from '@100mslive/react-sdk';
|
14
13
|
import {
|
15
14
|
ChangeRoleIcon,
|
16
|
-
|
17
|
-
|
15
|
+
HandIcon,
|
16
|
+
MicOffIcon,
|
18
17
|
PeopleIcon,
|
19
|
-
|
18
|
+
PeopleRemoveIcon,
|
20
19
|
SearchIcon,
|
21
|
-
SpeakerIcon,
|
22
20
|
VerticalMenuIcon,
|
23
21
|
} from '@100mslive/react-icons';
|
24
|
-
import {
|
22
|
+
import { Box, config as cssConfig, Dropdown, Flex, Input, Text, textEllipsis } from '../../..';
|
25
23
|
import IconButton from '../../IconButton';
|
24
|
+
import { useRoomLayout } from '../../provider/roomLayoutProvider';
|
25
|
+
import { ChatParticipantHeader } from '../Chat/ChatParticipantHeader';
|
26
26
|
import { ConnectionIndicator } from '../Connection/ConnectionIndicator';
|
27
|
-
import { ParticipantFilter } from '../Header/ParticipantFilter';
|
28
27
|
import { RoleChangeModal } from '../RoleChangeModal';
|
28
|
+
import { ToastManager } from '../Toast/ToastManager';
|
29
|
+
import { RoleAccordion } from './RoleAccordion';
|
29
30
|
import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane';
|
31
|
+
import { useParticipants } from '../../common/hooks';
|
30
32
|
import { isInternalRole } from '../../common/utils';
|
31
33
|
import { SIDE_PANE_OPTIONS } from '../../common/constants';
|
32
34
|
|
33
35
|
export const ParticipantList = () => {
|
34
36
|
const [filter, setFilter] = useState();
|
35
|
-
const { participants, isConnected, peerCount
|
37
|
+
const { participants, isConnected, peerCount } = useParticipants(filter);
|
38
|
+
const peersOrderedByRoles = {};
|
39
|
+
|
40
|
+
const handRaisedPeers = useHMSStore(selectPeersByCondition(peer => JSON.parse(peer.metadata || '{}')?.isHandRaised));
|
41
|
+
|
42
|
+
participants.forEach(participant => {
|
43
|
+
if (peersOrderedByRoles[participant.roleName] === undefined) {
|
44
|
+
peersOrderedByRoles[participant.roleName] = [];
|
45
|
+
}
|
46
|
+
peersOrderedByRoles[participant.roleName].push(participant);
|
47
|
+
});
|
48
|
+
|
36
49
|
const [selectedPeerId, setSelectedPeerId] = useState(null);
|
37
|
-
const toggleSidepane = useSidepaneToggle(SIDE_PANE_OPTIONS.PARTICIPANTS);
|
38
50
|
const onSearch = useCallback(value => {
|
39
51
|
setFilter(filterValue => {
|
40
52
|
if (!filterValue) {
|
41
53
|
filterValue = {};
|
42
54
|
}
|
43
|
-
filterValue.search = value;
|
55
|
+
filterValue.search = value.toLowerCase();
|
44
56
|
return { ...filterValue };
|
45
57
|
});
|
46
58
|
}, []);
|
@@ -50,39 +62,30 @@ export const ParticipantList = () => {
|
|
50
62
|
|
51
63
|
return (
|
52
64
|
<Fragment>
|
53
|
-
<Flex direction="column" css={{ size: '100%' }}>
|
54
|
-
<
|
55
|
-
|
56
|
-
|
57
|
-
selection={filter}
|
58
|
-
onSelection={setFilter}
|
59
|
-
isConnected={isConnected}
|
60
|
-
roles={rolesWithParticipants}
|
61
|
-
/>
|
62
|
-
<IconButton onClick={toggleSidepane} css={{ w: '$11', h: '$11', ml: 'auto' }}>
|
63
|
-
<CrossIcon />
|
64
|
-
</IconButton>
|
65
|
-
</Flex>
|
66
|
-
{!filter?.search && participants.length === 0 ? null : <ParticipantSearch onSearch={onSearch} />}
|
67
|
-
{participants.length === 0 && (
|
65
|
+
<Flex direction="column" css={{ size: '100%', gap: '$4' }}>
|
66
|
+
<ChatParticipantHeader activeTabValue={SIDE_PANE_OPTIONS.PARTICIPANTS} />
|
67
|
+
{!filter?.search && participants.length === 0 ? null : <ParticipantSearch onSearch={onSearch} inSidePane />}
|
68
|
+
{participants.length === 0 ? (
|
68
69
|
<Flex align="center" justify="center" css={{ w: '100%', p: '$8 0' }}>
|
69
70
|
<Text variant="sm">{!filter ? 'No participants' : 'No matching participants'}</Text>
|
70
71
|
</Flex>
|
71
|
-
)}
|
72
|
+
) : null}
|
72
73
|
<VirtualizedParticipants
|
73
|
-
|
74
|
+
peersOrderedByRoles={peersOrderedByRoles}
|
75
|
+
handRaisedList={handRaisedPeers}
|
74
76
|
isConnected={isConnected}
|
77
|
+
filter={filter}
|
75
78
|
setSelectedPeerId={setSelectedPeerId}
|
76
79
|
/>
|
80
|
+
{selectedPeerId && (
|
81
|
+
<RoleChangeModal
|
82
|
+
peerId={selectedPeerId}
|
83
|
+
onOpenChange={value => {
|
84
|
+
!value && setSelectedPeerId(null);
|
85
|
+
}}
|
86
|
+
/>
|
87
|
+
)}
|
77
88
|
</Flex>
|
78
|
-
{selectedPeerId && (
|
79
|
-
<RoleChangeModal
|
80
|
-
peerId={selectedPeerId}
|
81
|
-
onOpenChange={value => {
|
82
|
-
!value && setSelectedPeerId(null);
|
83
|
-
}}
|
84
|
-
/>
|
85
|
-
)}
|
86
89
|
</Fragment>
|
87
90
|
);
|
88
91
|
};
|
@@ -123,142 +126,207 @@ export const ParticipantCount = () => {
|
|
123
126
|
);
|
124
127
|
};
|
125
128
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
129
|
+
const VirtualizedParticipants = ({
|
130
|
+
peersOrderedByRoles = {},
|
131
|
+
isConnected,
|
132
|
+
setSelectedPeerId,
|
133
|
+
filter,
|
134
|
+
handRaisedList = [],
|
135
|
+
}) => {
|
132
136
|
return (
|
133
|
-
<
|
134
|
-
|
137
|
+
<Flex
|
138
|
+
direction="column"
|
135
139
|
css={{
|
136
|
-
|
137
|
-
|
140
|
+
gap: '$8',
|
141
|
+
maxHeight: '100%',
|
142
|
+
overflowY: 'auto',
|
143
|
+
overflowX: 'hidden',
|
144
|
+
pr: '$3',
|
138
145
|
}}
|
139
146
|
>
|
140
|
-
<
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
>
|
148
|
-
{VirtualisedParticipantListItem}
|
149
|
-
</FixedSizeList>
|
150
|
-
</Box>
|
151
|
-
);
|
152
|
-
};
|
153
|
-
|
154
|
-
const VirtualisedParticipantListItem = React.memo(({ style, index, data }) => {
|
155
|
-
return (
|
156
|
-
<div style={style} key={data.participants[index].id}>
|
157
|
-
<Participant
|
158
|
-
peer={data.participants[index]}
|
159
|
-
isConnected={data.isConnected}
|
160
|
-
setSelectedPeerId={data.setSelectedPeerId}
|
147
|
+
<RoleAccordion
|
148
|
+
peerList={handRaisedList}
|
149
|
+
roleName="Hand Raised"
|
150
|
+
filter={filter}
|
151
|
+
isConnected={isConnected}
|
152
|
+
setSelectedPeerId={setSelectedPeerId}
|
153
|
+
isHandRaisedAccordion
|
161
154
|
/>
|
162
|
-
|
155
|
+
{Object.keys(peersOrderedByRoles).map(role => (
|
156
|
+
<RoleAccordion
|
157
|
+
key={role}
|
158
|
+
peerList={peersOrderedByRoles[role]}
|
159
|
+
roleName={role}
|
160
|
+
isConnected={isConnected}
|
161
|
+
setSelectedPeerId={setSelectedPeerId}
|
162
|
+
filter={filter}
|
163
|
+
/>
|
164
|
+
))}
|
165
|
+
</Flex>
|
163
166
|
);
|
164
|
-
}
|
167
|
+
};
|
165
168
|
|
166
|
-
const Participant = ({ peer, isConnected, setSelectedPeerId }) => {
|
169
|
+
export const Participant = ({ peer, isConnected, setSelectedPeerId }) => {
|
170
|
+
const localPeerId = useHMSStore(selectLocalPeerID);
|
167
171
|
return (
|
168
|
-
<
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
172
|
+
<Flex
|
173
|
+
key={peer.id}
|
174
|
+
css={{
|
175
|
+
w: '100%',
|
176
|
+
p: '$4 $8',
|
177
|
+
pr: '$6',
|
178
|
+
h: '$16',
|
179
|
+
'&:hover .participant_item': { display: 'flex' },
|
180
|
+
}}
|
181
|
+
align="center"
|
182
|
+
justify="between"
|
183
|
+
data-testid={'participant_' + peer.name}
|
184
|
+
>
|
185
|
+
<Text variant="sm" css={{ ...textEllipsis(150), fontWeight: '$semiBold', color: '$on_surface_high' }}>
|
186
|
+
{peer.name} {localPeerId === peer.id ? '(You)' : ''}
|
187
|
+
</Text>
|
188
|
+
{isConnected ? (
|
189
|
+
<ParticipantActions
|
190
|
+
peerId={peer.id}
|
191
|
+
isLocal={peer.id === localPeerId}
|
192
|
+
role={peer.roleName}
|
193
|
+
onSettings={() => {
|
194
|
+
setSelectedPeerId(peer.id);
|
184
195
|
}}
|
185
196
|
/>
|
186
|
-
|
187
|
-
|
188
|
-
{peer.name}
|
189
|
-
</Text>
|
190
|
-
<Text variant="sub2">{peer.roleName}</Text>
|
191
|
-
</Flex>
|
192
|
-
{isConnected && (
|
193
|
-
<ParticipantActions
|
194
|
-
peerId={peer.id}
|
195
|
-
role={peer.roleName}
|
196
|
-
onSettings={() => {
|
197
|
-
setSelectedPeerId(peer.id);
|
198
|
-
}}
|
199
|
-
/>
|
200
|
-
)}
|
201
|
-
</Flex>
|
202
|
-
</Fragment>
|
197
|
+
) : null}
|
198
|
+
</Flex>
|
203
199
|
);
|
204
200
|
};
|
205
201
|
|
206
202
|
/**
|
207
203
|
* shows settings to change for a participant like changing their role
|
208
204
|
*/
|
209
|
-
const ParticipantActions = React.memo(({ onSettings, peerId, role }) => {
|
205
|
+
const ParticipantActions = React.memo(({ onSettings, peerId, role, isLocal }) => {
|
210
206
|
const isHandRaised = useHMSStore(selectPeerMetadata(peerId))?.isHandRaised;
|
211
207
|
const canChangeRole = useHMSStore(selectPermissions)?.changeRole;
|
212
|
-
const
|
213
|
-
const
|
214
|
-
const canChangeVolume = peerId !== localPeerId && audioTrack;
|
215
|
-
const shouldShowMoreActions = canChangeRole || canChangeVolume;
|
208
|
+
const shouldShowMoreActions = canChangeRole;
|
209
|
+
const isAudioMuted = !useHMSStore(selectIsPeerAudioEnabled(peerId));
|
216
210
|
|
217
211
|
return (
|
218
|
-
<Flex
|
212
|
+
<Flex
|
213
|
+
align="center"
|
214
|
+
css={{
|
215
|
+
flexShrink: 0,
|
216
|
+
gap: '$8',
|
217
|
+
mt: '$2',
|
218
|
+
}}
|
219
|
+
>
|
219
220
|
<ConnectionIndicator peerId={peerId} />
|
220
|
-
{isHandRaised &&
|
221
|
-
|
222
|
-
|
221
|
+
{isHandRaised && (
|
222
|
+
<Flex
|
223
|
+
align="center"
|
224
|
+
justify="center"
|
225
|
+
css={{ p: '$1', c: '$on_surface_high', bg: '$surface_bright', borderRadius: '$round' }}
|
226
|
+
>
|
227
|
+
<HandIcon height={19} width={19} />
|
228
|
+
</Flex>
|
223
229
|
)}
|
230
|
+
{isAudioMuted ? (
|
231
|
+
<Flex
|
232
|
+
align="center"
|
233
|
+
justify="center"
|
234
|
+
css={{ p: '$2', c: '$on_surface_high', bg: '$surface_bright', borderRadius: '$round' }}
|
235
|
+
>
|
236
|
+
<MicOffIcon height={19} width={19} />
|
237
|
+
</Flex>
|
238
|
+
) : null}
|
239
|
+
|
240
|
+
{shouldShowMoreActions && !isInternalRole(role) && !isLocal ? (
|
241
|
+
<ParticipantMoreActions onRoleChange={onSettings} peerId={peerId} role={role} />
|
242
|
+
) : null}
|
224
243
|
</Flex>
|
225
244
|
);
|
226
245
|
});
|
227
246
|
|
228
|
-
const ParticipantMoreActions = ({ onRoleChange, peerId }) => {
|
247
|
+
const ParticipantMoreActions = ({ onRoleChange, peerId, role }) => {
|
248
|
+
const hmsActions = useHMSActions();
|
229
249
|
const { changeRole: canChangeRole, removeOthers: canRemoveOthers } = useHMSStore(selectPermissions);
|
250
|
+
const layout = useRoomLayout();
|
251
|
+
const {
|
252
|
+
bring_to_stage_label,
|
253
|
+
remove_from_stage_label,
|
254
|
+
on_stage_role,
|
255
|
+
off_stage_roles = [],
|
256
|
+
} = layout?.screens?.conferencing?.default?.elements.on_stage_exp || {};
|
257
|
+
const canBringToStage = off_stage_roles.includes(role);
|
258
|
+
const isInStage = role === on_stage_role;
|
259
|
+
const prevRole = useHMSStore(selectPeerMetadata(peerId))?.prevRole;
|
230
260
|
const localPeerId = useHMSStore(selectLocalPeerID);
|
231
261
|
const isLocal = localPeerId === peerId;
|
232
|
-
const actions = useHMSActions();
|
233
262
|
const [open, setOpen] = useState(false);
|
263
|
+
|
264
|
+
const handleStageAction = async () => {
|
265
|
+
if (isInStage) {
|
266
|
+
hmsActions.changeRoleOfPeer(peerId, prevRole || off_stage_roles[0]);
|
267
|
+
} else {
|
268
|
+
await hmsActions.changeRoleOfPeer(peerId, on_stage_role);
|
269
|
+
}
|
270
|
+
setOpen(false);
|
271
|
+
};
|
272
|
+
|
234
273
|
return (
|
235
274
|
<Dropdown.Root open={open} onOpenChange={value => setOpen(value)} modal={false}>
|
236
|
-
<Dropdown.Trigger
|
237
|
-
|
275
|
+
<Dropdown.Trigger
|
276
|
+
asChild
|
277
|
+
data-testid="participant_more_actions"
|
278
|
+
className="participant_item"
|
279
|
+
css={{
|
280
|
+
p: '$1',
|
281
|
+
r: '$0',
|
282
|
+
c: '$on_surface_high',
|
283
|
+
display: open ? 'flex' : 'none',
|
284
|
+
'&:hover': {
|
285
|
+
bg: '$surface_bright',
|
286
|
+
},
|
287
|
+
'@md': {
|
288
|
+
display: 'flex',
|
289
|
+
},
|
290
|
+
}}
|
291
|
+
tabIndex={0}
|
292
|
+
>
|
293
|
+
<Box css={{ my: 'auto' }}>
|
238
294
|
<VerticalMenuIcon />
|
239
|
-
</
|
295
|
+
</Box>
|
240
296
|
</Dropdown.Trigger>
|
241
297
|
<Dropdown.Portal>
|
242
|
-
<Dropdown.Content align="end" sideOffset={8} css={{ w: '$64' }}>
|
243
|
-
{canChangeRole && (
|
244
|
-
<Dropdown.Item onClick={() =>
|
298
|
+
<Dropdown.Content align="end" sideOffset={8} css={{ w: '$64', bg: '$surface_default' }}>
|
299
|
+
{canChangeRole && canBringToStage ? (
|
300
|
+
<Dropdown.Item css={{ bg: '$surface_default' }} onClick={() => handleStageAction()}>
|
301
|
+
<ChangeRoleIcon />
|
302
|
+
<Text variant="sm" css={{ ml: '$4', fontWeight: '$semiBold', c: '$on_surface_high' }}>
|
303
|
+
{isInStage ? remove_from_stage_label : bring_to_stage_label}
|
304
|
+
</Text>
|
305
|
+
</Dropdown.Item>
|
306
|
+
) : (
|
307
|
+
<Dropdown.Item css={{ bg: '$surface_default' }} onClick={() => onRoleChange(peerId)}>
|
245
308
|
<ChangeRoleIcon />
|
246
|
-
<Text css={{ ml: '$4' }}>
|
309
|
+
<Text variant="sm" css={{ ml: '$4', fontWeight: '$semiBold', c: '$on_surface_high' }}>
|
310
|
+
Change Role
|
311
|
+
</Text>
|
247
312
|
</Dropdown.Item>
|
248
313
|
)}
|
249
|
-
|
314
|
+
|
250
315
|
{!isLocal && canRemoveOthers && (
|
251
316
|
<Dropdown.Item
|
317
|
+
css={{ color: '$alert_error_default', bg: '$surface_default' }}
|
252
318
|
onClick={async () => {
|
253
319
|
try {
|
254
|
-
await
|
320
|
+
await hmsActions.removePeer(peerId, '');
|
255
321
|
} catch (error) {
|
256
|
-
|
322
|
+
ToastManager.addToast({ title: error.message, variant: 'error' });
|
257
323
|
}
|
258
324
|
}}
|
259
325
|
>
|
260
|
-
<
|
261
|
-
<Text css={{ ml: '$4', color: '$
|
326
|
+
<PeopleRemoveIcon />
|
327
|
+
<Text variant="sm" css={{ ml: '$4', color: 'inherit', fontWeight: '$semiBold' }}>
|
328
|
+
Remove Participant
|
329
|
+
</Text>
|
262
330
|
</Dropdown.Item>
|
263
331
|
)}
|
264
332
|
</Dropdown.Content>
|
@@ -267,37 +335,10 @@ const ParticipantMoreActions = ({ onRoleChange, peerId }) => {
|
|
267
335
|
);
|
268
336
|
};
|
269
337
|
|
270
|
-
const
|
271
|
-
const audioTrack = useHMSStore(selectAudioTrackByPeerID(peerId));
|
272
|
-
const localPeerId = useHMSStore(selectLocalPeerID);
|
273
|
-
const hmsActions = useHMSActions();
|
274
|
-
// No volume control for local peer or non audio publishing role
|
275
|
-
if (peerId === localPeerId || !audioTrack) {
|
276
|
-
return null;
|
277
|
-
}
|
278
|
-
|
279
|
-
return (
|
280
|
-
<Dropdown.Item css={{ h: 'auto' }}>
|
281
|
-
<Flex direction="column" css={{ w: '100%' }}>
|
282
|
-
<Flex align="center">
|
283
|
-
<SpeakerIcon />
|
284
|
-
<Text css={{ ml: '$4' }}>Volume{audioTrack.volume ? `(${audioTrack.volume})` : ''}</Text>
|
285
|
-
</Flex>
|
286
|
-
<Slider
|
287
|
-
css={{ my: '0.5rem' }}
|
288
|
-
step={5}
|
289
|
-
value={[audioTrack.volume]}
|
290
|
-
onValueChange={e => {
|
291
|
-
hmsActions.setVolume(e[0], audioTrack?.id);
|
292
|
-
}}
|
293
|
-
/>
|
294
|
-
</Flex>
|
295
|
-
</Dropdown.Item>
|
296
|
-
);
|
297
|
-
};
|
298
|
-
|
299
|
-
export const ParticipantSearch = ({ onSearch, placeholder }) => {
|
338
|
+
export const ParticipantSearch = ({ onSearch, placeholder, inSidePane = false }) => {
|
300
339
|
const [value, setValue] = React.useState('');
|
340
|
+
const isMobile = useMedia(cssConfig.media.md);
|
341
|
+
|
301
342
|
useDebounce(
|
302
343
|
() => {
|
303
344
|
onSearch(value);
|
@@ -306,22 +347,21 @@ export const ParticipantSearch = ({ onSearch, placeholder }) => {
|
|
306
347
|
[value, onSearch],
|
307
348
|
);
|
308
349
|
return (
|
309
|
-
<
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
</Box>
|
350
|
+
<Flex
|
351
|
+
align="center"
|
352
|
+
css={{
|
353
|
+
p: isMobile ? '$0 $6' : '$2 0',
|
354
|
+
mb: '$2',
|
355
|
+
position: 'relative',
|
356
|
+
color: '$on_surface_medium',
|
357
|
+
mt: inSidePane ? '$4' : '',
|
358
|
+
}}
|
359
|
+
>
|
360
|
+
<SearchIcon style={{ position: 'absolute', left: isMobile ? '1.25rem' : '0.5rem' }} />
|
321
361
|
<Input
|
322
362
|
type="text"
|
323
|
-
placeholder={placeholder || 'Search
|
324
|
-
css={{ w: '100%', pl: '$14', bg: '$
|
363
|
+
placeholder={placeholder || 'Search for participants'}
|
364
|
+
css={{ w: '100%', p: '$6', pl: '$14', mr: '$4', bg: inSidePane ? '$surface_default' : '$surface_dim' }}
|
325
365
|
value={value}
|
326
366
|
onKeyDown={event => {
|
327
367
|
event.stopPropagation();
|
@@ -332,6 +372,6 @@ export const ParticipantSearch = ({ onSearch, placeholder }) => {
|
|
332
372
|
autoComplete="off"
|
333
373
|
aria-autocomplete="none"
|
334
374
|
/>
|
335
|
-
</
|
375
|
+
</Flex>
|
336
376
|
);
|
337
377
|
};
|
@@ -0,0 +1,78 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { useMeasure } from 'react-use';
|
3
|
+
import { FixedSizeList } from 'react-window';
|
4
|
+
import { Accordion } from '../../../Accordion';
|
5
|
+
import { Box, Flex } from '../../../Layout';
|
6
|
+
import { Participant } from './ParticipantList';
|
7
|
+
import { getFormattedCount } from '../../common/utils';
|
8
|
+
|
9
|
+
const ROW_HEIGHT = 50;
|
10
|
+
|
11
|
+
function itemKey(index, data) {
|
12
|
+
return data.peerList[index].id;
|
13
|
+
}
|
14
|
+
|
15
|
+
const VirtualizedParticipantItem = React.memo(({ index, data }) => {
|
16
|
+
return (
|
17
|
+
<Participant
|
18
|
+
key={data.peerList[index].id}
|
19
|
+
peer={data.peerList[index]}
|
20
|
+
isConnected={data.isConnected}
|
21
|
+
setSelectedPeerId={data.setSelectedPeerId}
|
22
|
+
/>
|
23
|
+
);
|
24
|
+
});
|
25
|
+
|
26
|
+
export const RoleAccordion = ({
|
27
|
+
peerList = [],
|
28
|
+
roleName,
|
29
|
+
setSelectedPeerId,
|
30
|
+
isConnected,
|
31
|
+
filter,
|
32
|
+
isHandRaisedAccordion = false,
|
33
|
+
}) => {
|
34
|
+
const [ref, { width }] = useMeasure();
|
35
|
+
const height = ROW_HEIGHT * peerList.length;
|
36
|
+
const showAcordion = filter?.search ? peerList.some(peer => peer.name.toLowerCase().includes(filter.search)) : true;
|
37
|
+
if (!showAcordion || (isHandRaisedAccordion && filter?.search) || peerList.length === 0) {
|
38
|
+
return null;
|
39
|
+
}
|
40
|
+
|
41
|
+
return (
|
42
|
+
<Flex direction="column" css={{ flexGrow: 1 }} ref={ref}>
|
43
|
+
<Accordion.Root
|
44
|
+
type="single"
|
45
|
+
collapsible
|
46
|
+
defaultValue={roleName}
|
47
|
+
css={{ borderRadius: '$3', border: '1px solid $border_bright' }}
|
48
|
+
>
|
49
|
+
<Accordion.Item value={roleName}>
|
50
|
+
<Accordion.Header
|
51
|
+
css={{
|
52
|
+
textTransform: 'capitalize',
|
53
|
+
p: '$6 $8',
|
54
|
+
fontSize: '$sm',
|
55
|
+
fontWeight: '$semiBold',
|
56
|
+
c: '$on_surface_medium',
|
57
|
+
}}
|
58
|
+
>
|
59
|
+
{roleName} {`(${getFormattedCount(peerList.length)})`}
|
60
|
+
</Accordion.Header>
|
61
|
+
<Accordion.Content>
|
62
|
+
<Box css={{ borderTop: '1px solid $border_default' }} />
|
63
|
+
<FixedSizeList
|
64
|
+
itemSize={ROW_HEIGHT}
|
65
|
+
itemData={{ peerList, isConnected, setSelectedPeerId }}
|
66
|
+
itemKey={itemKey}
|
67
|
+
itemCount={peerList.length}
|
68
|
+
width={width}
|
69
|
+
height={height}
|
70
|
+
>
|
71
|
+
{VirtualizedParticipantItem}
|
72
|
+
</FixedSizeList>
|
73
|
+
</Accordion.Content>
|
74
|
+
</Accordion.Item>
|
75
|
+
</Accordion.Root>
|
76
|
+
</Flex>
|
77
|
+
);
|
78
|
+
};
|
@@ -11,11 +11,11 @@ export const LeftControls = styled(Flex, {
|
|
11
11
|
justifyContent: 'flex-start',
|
12
12
|
alignItems: 'center',
|
13
13
|
width: '100%',
|
14
|
-
gap: '$
|
14
|
+
gap: '$4',
|
15
15
|
});
|
16
16
|
export const RightControls = styled(Flex, {
|
17
17
|
justifyContent: 'flex-end',
|
18
18
|
alignItems: 'center',
|
19
19
|
width: '100%',
|
20
|
-
gap: '$
|
20
|
+
gap: '$4',
|
21
21
|
});
|
@@ -34,7 +34,7 @@ export function HLSQualitySelector({ layers, onQualityChange, selection, isAuto
|
|
34
34
|
'@sm': 'xs',
|
35
35
|
'@xs': 'tiny',
|
36
36
|
}}
|
37
|
-
css={{ display: 'flex', alignItems: 'center', ml: '$2' }}
|
37
|
+
css={{ display: 'flex', alignItems: 'center', ml: '$2', c: '$on_surface_medium' }}
|
38
38
|
>
|
39
39
|
{isAuto && (
|
40
40
|
<>
|
@@ -57,26 +57,49 @@ export function HLSQualitySelector({ layers, onQualityChange, selection, isAuto
|
|
57
57
|
</Flex>
|
58
58
|
</Dropdown.Trigger>
|
59
59
|
{layers.length > 0 && (
|
60
|
-
<Dropdown.Content
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
60
|
+
<Dropdown.Content
|
61
|
+
sideOffset={5}
|
62
|
+
align="end"
|
63
|
+
css={{ height: 'auto', maxHeight: '$96', w: '$64', bg: '$surface_bright' }}
|
64
|
+
>
|
65
65
|
{layers.map(layer => {
|
66
66
|
return (
|
67
|
-
<Dropdown.Item
|
68
|
-
|
67
|
+
<Dropdown.Item
|
68
|
+
onClick={() => onQualityChange(layer)}
|
69
|
+
key={layer.width}
|
70
|
+
css={{
|
71
|
+
bg: '$surface_bright',
|
72
|
+
'&:hover': {
|
73
|
+
bg: '$surface_default',
|
74
|
+
},
|
75
|
+
}}
|
76
|
+
>
|
77
|
+
<Text>{getQualityText(layer)}</Text>
|
78
|
+
<Text css={{ flex: '1 1 0', c: '$on_surface_low', pl: '$2' }}>{getBitrateText(layer)}</Text>
|
69
79
|
{!isAuto && layer.width === selection?.width && layer.height === selection?.height && (
|
70
80
|
<CheckCircleIcon />
|
71
81
|
)}
|
72
82
|
</Dropdown.Item>
|
73
83
|
);
|
74
84
|
})}
|
85
|
+
<Dropdown.Item
|
86
|
+
onClick={() => onQualityChange({ height: 'auto' })}
|
87
|
+
key="auto"
|
88
|
+
css={{
|
89
|
+
bg: '$surface_bright',
|
90
|
+
'&:hover': {
|
91
|
+
bg: '$surface_default',
|
92
|
+
},
|
93
|
+
}}
|
94
|
+
>
|
95
|
+
<Text css={{ flex: '1 1 0' }}>Auto</Text>
|
96
|
+
{isAuto && <CheckCircleIcon />}
|
97
|
+
</Dropdown.Item>
|
75
98
|
</Dropdown.Content>
|
76
99
|
)}
|
77
100
|
</Dropdown.Root>
|
78
101
|
);
|
79
102
|
}
|
80
103
|
|
81
|
-
const getQualityText = layer =>
|
82
|
-
|
104
|
+
const getQualityText = layer => `${Math.min(layer.height, layer.width)}p `;
|
105
|
+
const getBitrateText = layer => `(${(Number(layer.bitrate / 1000) / 1000).toFixed(2)} Mbps)`;
|