@100mslive/roomkit-react 0.1.6-alpha.1 → 0.1.6-alpha.2
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/{HLSView-HNVYG5VE.js → HLSView-QMU5JK7U.js} +3 -3
- package/dist/Prebuilt/components/Footer/ChatToggle.d.ts +1 -3
- package/dist/Prebuilt/components/SidePaneTabs.d.ts +7 -0
- package/dist/{VirtualBackground-UM2FOUHQ.js → VirtualBackground-37FXUPYO.js} +6 -6
- package/dist/VirtualBackground-37FXUPYO.js.map +7 -0
- package/dist/{chunk-POE7H4IE.js → chunk-KBVIZGYW.js} +2 -2
- package/dist/{chunk-POE7H4IE.js.map → chunk-KBVIZGYW.js.map} +1 -1
- package/dist/{chunk-LYSAET4G.js → chunk-WVGGQZK4.js} +100 -106
- package/dist/{chunk-LYSAET4G.js.map → chunk-WVGGQZK4.js.map} +3 -3
- package/dist/{chunk-364HP22I.js → chunk-ZKE2N5LH.js} +2 -2
- package/dist/{conference-UWLJHMB2.js → conference-FJJQ4TXX.js} +419 -384
- package/dist/conference-FJJQ4TXX.js.map +7 -0
- package/dist/index.cjs.js +594 -570
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +2 -2
- package/dist/meta.cjs.json +127 -127
- package/dist/meta.esbuild.json +161 -160
- package/package.json +6 -6
- package/src/Prebuilt/components/Chat/Chat.jsx +2 -6
- package/src/Prebuilt/components/Footer/ChatToggle.tsx +2 -9
- package/src/Prebuilt/components/Footer/Footer.tsx +22 -6
- package/src/Prebuilt/components/Footer/ParticipantList.jsx +0 -2
- package/src/Prebuilt/components/Header/HeaderComponents.jsx +8 -1
- package/src/Prebuilt/components/InsetTile.tsx +1 -0
- package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +1 -1
- package/src/Prebuilt/components/Notifications/Notifications.jsx +14 -7
- package/src/Prebuilt/components/Preview/PreviewJoin.tsx +2 -3
- package/src/Prebuilt/components/RoleChangeRequestModal.tsx +6 -4
- package/src/Prebuilt/components/SidePaneTabs.tsx +120 -0
- package/src/Prebuilt/components/hooks/useMetadata.jsx +7 -25
- package/src/Prebuilt/layouts/SidePane.tsx +12 -10
- package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +3 -3
- package/src/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.ts +2 -2
- package/dist/VirtualBackground-UM2FOUHQ.js.map +0 -7
- package/dist/conference-UWLJHMB2.js.map +0 -7
- package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +0 -84
- /package/dist/{HLSView-HNVYG5VE.js.map → HLSView-QMU5JK7U.js.map} +0 -0
- /package/dist/{chunk-364HP22I.js.map → chunk-ZKE2N5LH.js.map} +0 -0
package/package.json
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
"prebuilt",
|
11
11
|
"roomkit"
|
12
12
|
],
|
13
|
-
"version": "0.1.6-alpha.
|
13
|
+
"version": "0.1.6-alpha.2",
|
14
14
|
"author": "100ms",
|
15
15
|
"license": "MIT",
|
16
16
|
"files": [
|
@@ -76,10 +76,10 @@
|
|
76
76
|
"react": ">=17.0.2 <19.0.0"
|
77
77
|
},
|
78
78
|
"dependencies": {
|
79
|
-
"@100mslive/hls-player": "0.1.15-alpha.
|
80
|
-
"@100mslive/hms-virtual-background": "1.11.15-alpha.
|
81
|
-
"@100mslive/react-icons": "0.8.15-alpha.
|
82
|
-
"@100mslive/react-sdk": "0.8.15-alpha.
|
79
|
+
"@100mslive/hls-player": "0.1.15-alpha.2",
|
80
|
+
"@100mslive/hms-virtual-background": "1.11.15-alpha.2",
|
81
|
+
"@100mslive/react-icons": "0.8.15-alpha.2",
|
82
|
+
"@100mslive/react-sdk": "0.8.15-alpha.2",
|
83
83
|
"@100mslive/types-prebuilt": "0.12.0",
|
84
84
|
"@emoji-mart/data": "^1.0.6",
|
85
85
|
"@emoji-mart/react": "^1.0.1",
|
@@ -115,5 +115,5 @@
|
|
115
115
|
"uuid": "^8.3.2",
|
116
116
|
"worker-timers": "^7.0.40"
|
117
117
|
},
|
118
|
-
"gitHead": "
|
118
|
+
"gitHead": "e9017621fb9f9594f985d47483ccab4bed324a35"
|
119
119
|
}
|
@@ -17,7 +17,6 @@ import { Text } from '../../../Text';
|
|
17
17
|
import { config as cssConfig } from '../../../Theme';
|
18
18
|
import { AnnotisedMessage, ChatBody } from './ChatBody';
|
19
19
|
import { ChatFooter } from './ChatFooter';
|
20
|
-
import { ChatParticipantHeader } from './ChatParticipantHeader';
|
21
20
|
import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
22
21
|
import { useSetSubscribedChatSelector } from '../AppData/useUISettings';
|
23
22
|
import { useSetPinnedMessage } from '../hooks/useSetPinnedMessage';
|
@@ -77,7 +76,7 @@ export const Chat = ({ screenType, hideControls = false }) => {
|
|
77
76
|
peerId: peerSelector && peerName ? peerSelector : '',
|
78
77
|
selection: roleSelector ? roleSelector : peerSelector && peerName ? peerName : 'Everyone',
|
79
78
|
});
|
80
|
-
const [isSelectorOpen
|
79
|
+
const [isSelectorOpen] = useState(false);
|
81
80
|
const listRef = useRef(null);
|
82
81
|
const hmsActions = useHMSActions();
|
83
82
|
const { setPinnedMessage } = useSetPinnedMessage();
|
@@ -128,10 +127,7 @@ export const Chat = ({ screenType, hideControls = false }) => {
|
|
128
127
|
}}
|
129
128
|
>
|
130
129
|
{isMobile && elements?.chat?.is_overlay ? null : (
|
131
|
-
<>
|
132
|
-
<ChatParticipantHeader selectorOpen={isSelectorOpen} onToggle={() => setSelectorOpen(value => !value)} />
|
133
|
-
{elements?.chat?.allow_pinning_messages ? <PinnedMessage clearPinnedMessage={setPinnedMessage} /> : null}
|
134
|
-
</>
|
130
|
+
<>{elements?.chat?.allow_pinning_messages ? <PinnedMessage clearPinnedMessage={setPinnedMessage} /> : null}</>
|
135
131
|
)}
|
136
132
|
|
137
133
|
<ChatBody
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import React
|
1
|
+
import React from 'react';
|
2
2
|
import { selectUnreadHMSMessagesCount, useHMSStore } from '@100mslive/react-sdk';
|
3
3
|
import { ChatIcon, ChatUnreadIcon } from '@100mslive/react-icons';
|
4
4
|
import { Tooltip } from '../../..';
|
@@ -9,18 +9,11 @@ import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane
|
|
9
9
|
// @ts-ignore: No implicit Any
|
10
10
|
import { SIDE_PANE_OPTIONS } from '../../common/constants';
|
11
11
|
|
12
|
-
export const ChatToggle = (
|
12
|
+
export const ChatToggle = () => {
|
13
13
|
const countUnreadMessages = useHMSStore(selectUnreadHMSMessagesCount);
|
14
14
|
const isChatOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.CHAT);
|
15
15
|
const toggleChat = useSidepaneToggle(SIDE_PANE_OPTIONS.CHAT);
|
16
16
|
|
17
|
-
useEffect(() => {
|
18
|
-
if (!isChatOpen && openByDefault) {
|
19
|
-
toggleChat();
|
20
|
-
}
|
21
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
22
|
-
}, [toggleChat, openByDefault]);
|
23
|
-
|
24
17
|
return (
|
25
18
|
<Tooltip key="chat" title={`${isChatOpen ? 'Close' : 'Open'} chat`}>
|
26
19
|
<IconButton onClick={toggleChat} active={!isChatOpen} data-testid="chat_btn">
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { Suspense } from 'react';
|
1
|
+
import React, { Suspense, useEffect } from 'react';
|
2
2
|
import { useMedia } from 'react-use';
|
3
3
|
import {
|
4
4
|
ConferencingScreen,
|
@@ -6,7 +6,6 @@ import {
|
|
6
6
|
HLSLiveStreamingScreen_Elements,
|
7
7
|
} from '@100mslive/types-prebuilt';
|
8
8
|
import { Chat_ChatState } from '@100mslive/types-prebuilt/elements/chat';
|
9
|
-
import { selectIsLocalVideoEnabled, useHMSStore } from '@100mslive/react-sdk';
|
10
9
|
import { config as cssConfig, Footer as AppFooter } from '../../..';
|
11
10
|
// @ts-ignore: No implicit Any
|
12
11
|
import { AudioVideoToggle } from '../AudioVideoToggle';
|
@@ -25,6 +24,10 @@ import { ChatToggle } from './ChatToggle';
|
|
25
24
|
// @ts-ignore: No implicit Any
|
26
25
|
import { ParticipantCount } from './ParticipantList';
|
27
26
|
// @ts-ignore: No implicit Any
|
27
|
+
import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane';
|
28
|
+
// @ts-ignore: No implicit Any
|
29
|
+
import { SIDE_PANE_OPTIONS } from '../../common/constants';
|
30
|
+
// @ts-ignore: No implicit Any
|
28
31
|
const VirtualBackground = React.lazy(() => import('../../plugins/VirtualBackground/VirtualBackground'));
|
29
32
|
|
30
33
|
export const Footer = ({
|
@@ -37,7 +40,16 @@ export const Footer = ({
|
|
37
40
|
const isMobile = useMedia(cssConfig.media.md);
|
38
41
|
const isOverlayChat = !!elements?.chat?.is_overlay;
|
39
42
|
const openByDefault = elements?.chat?.initial_state === Chat_ChatState.CHAT_STATE_OPEN;
|
40
|
-
|
43
|
+
|
44
|
+
const isChatOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.CHAT);
|
45
|
+
const toggleChat = useSidepaneToggle(SIDE_PANE_OPTIONS.CHAT);
|
46
|
+
|
47
|
+
useEffect(() => {
|
48
|
+
if (!isChatOpen && openByDefault) {
|
49
|
+
toggleChat();
|
50
|
+
}
|
51
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
52
|
+
}, [toggleChat, openByDefault]);
|
41
53
|
|
42
54
|
return (
|
43
55
|
<AppFooter.Root
|
@@ -63,7 +75,11 @@ export const Footer = ({
|
|
63
75
|
>
|
64
76
|
{isMobile ? <LeaveRoom screenType={screenType} /> : null}
|
65
77
|
<AudioVideoToggle />
|
66
|
-
{isMobile ? null :
|
78
|
+
{isMobile ? null : (
|
79
|
+
<Suspense fallback={<></>}>
|
80
|
+
<VirtualBackground />
|
81
|
+
</Suspense>
|
82
|
+
)}
|
67
83
|
</AppFooter.Left>
|
68
84
|
<AppFooter.Center
|
69
85
|
css={{
|
@@ -76,7 +92,7 @@ export const Footer = ({
|
|
76
92
|
{isMobile ? (
|
77
93
|
<>
|
78
94
|
{screenType === 'hls_live_streaming' ? <RaiseHand /> : null}
|
79
|
-
{elements?.chat && <ChatToggle
|
95
|
+
{elements?.chat && <ChatToggle />}
|
80
96
|
<MoreSettings elements={elements} screenType={screenType} />
|
81
97
|
</>
|
82
98
|
) : (
|
@@ -89,7 +105,7 @@ export const Footer = ({
|
|
89
105
|
)}
|
90
106
|
</AppFooter.Center>
|
91
107
|
<AppFooter.Right>
|
92
|
-
{!isMobile && elements?.chat && <ChatToggle
|
108
|
+
{!isMobile && elements?.chat && <ChatToggle />}
|
93
109
|
{elements?.participant_list && <ParticipantCount />}
|
94
110
|
<MoreSettings elements={elements} screenType={screenType} />
|
95
111
|
</AppFooter.Right>
|
@@ -21,7 +21,6 @@ import {
|
|
21
21
|
} from '@100mslive/react-icons';
|
22
22
|
import { Box, config as cssConfig, Dropdown, Flex, Input, Text, textEllipsis } from '../../..';
|
23
23
|
import IconButton from '../../IconButton';
|
24
|
-
import { ChatParticipantHeader } from '../Chat/ChatParticipantHeader';
|
25
24
|
import { ConnectionIndicator } from '../Connection/ConnectionIndicator';
|
26
25
|
import { ToastManager } from '../Toast/ToastManager';
|
27
26
|
import { RoleAccordion } from './RoleAccordion';
|
@@ -61,7 +60,6 @@ export const ParticipantList = () => {
|
|
61
60
|
return (
|
62
61
|
<Fragment>
|
63
62
|
<Flex direction="column" css={{ size: '100%', gap: '$4' }}>
|
64
|
-
<ChatParticipantHeader activeTabValue={SIDE_PANE_OPTIONS.PARTICIPANTS} />
|
65
63
|
{!filter?.search && participants.length === 0 ? null : <ParticipantSearch onSearch={onSearch} inSidePane />}
|
66
64
|
{participants.length === 0 ? (
|
67
65
|
<Flex align="center" justify="center" css={{ w: '100%', p: '$8 0' }}>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { useState } from 'react';
|
1
|
+
import React, { useEffect, useState } from 'react';
|
2
2
|
import { useMedia } from 'react-use';
|
3
3
|
import { selectDominantSpeaker, selectIsConnectedToRoom, useHMSStore } from '@100mslive/react-sdk';
|
4
4
|
import { VolumeOneIcon } from '@100mslive/react-icons';
|
@@ -41,6 +41,13 @@ export const Logo = () => {
|
|
41
41
|
const isConnected = useHMSStore(selectIsConnectedToRoom);
|
42
42
|
const [hideImage, setHideImage] = useState(false);
|
43
43
|
// Hide logo for now as there is not enough space
|
44
|
+
useEffect(() => {
|
45
|
+
if (hideImage) {
|
46
|
+
setHideImage(false);
|
47
|
+
}
|
48
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
49
|
+
}, [logo]);
|
50
|
+
|
44
51
|
if (isConnected && isMobile) {
|
45
52
|
return null;
|
46
53
|
}
|
@@ -266,7 +266,7 @@ export const MwebOptions = ({
|
|
266
266
|
</Box>
|
267
267
|
</Sheet.Content>
|
268
268
|
</Sheet.Root>
|
269
|
-
<SettingsModal open={openSettingsSheet} onOpenChange={setOpenSettingsSheet} />
|
269
|
+
<SettingsModal open={openSettingsSheet} onOpenChange={setOpenSettingsSheet} screenType={screenType} />
|
270
270
|
{openModals.has(MODALS.MUTE_ALL) && (
|
271
271
|
<MuteAllModal onOpenChange={(value: boolean) => updateState(MODALS.MUTE_ALL, value)} isMobile />
|
272
272
|
)}
|
@@ -4,10 +4,12 @@ import { useNavigate, useParams } from 'react-router-dom';
|
|
4
4
|
import {
|
5
5
|
HMSNotificationTypes,
|
6
6
|
HMSRoomState,
|
7
|
+
selectPeerMetadata,
|
7
8
|
selectRoomState,
|
8
9
|
useCustomEvent,
|
9
10
|
useHMSNotifications,
|
10
11
|
useHMSStore,
|
12
|
+
useHMSVanillaStore,
|
11
13
|
} from '@100mslive/react-sdk';
|
12
14
|
import { Button } from '../../../';
|
13
15
|
import { useUpdateRoomLayout } from '../../provider/roomLayoutProvider';
|
@@ -29,6 +31,7 @@ export function Notifications() {
|
|
29
31
|
const notification = useHMSNotifications();
|
30
32
|
const navigate = useNavigate();
|
31
33
|
const params = useParams();
|
34
|
+
const vanillaStore = useHMSVanillaStore();
|
32
35
|
const subscribedNotifications = useSubscribedNotifications() || {};
|
33
36
|
const roomState = useHMSStore(selectRoomState);
|
34
37
|
const updateRoomLayoutForRole = useUpdateRoomLayout();
|
@@ -53,8 +56,8 @@ export function Notifications() {
|
|
53
56
|
if (roomState !== HMSRoomState.Connected) {
|
54
57
|
return;
|
55
58
|
}
|
56
|
-
// Don't toast message when metadata is updated and raiseHand is false.
|
57
|
-
// Don't toast message in case of local peer.
|
59
|
+
// Don't show toast message when metadata is updated and raiseHand is false.
|
60
|
+
// Don't show toast message in case of local peer.
|
58
61
|
const metadata = getMetadata(notification.data?.metadata);
|
59
62
|
if (!metadata?.isHandRaised || notification.data.isLocal) return;
|
60
63
|
|
@@ -108,14 +111,18 @@ export function Notifications() {
|
|
108
111
|
title: `Error: ${notification.data?.message} - ${notification.data?.description}`,
|
109
112
|
});
|
110
113
|
break;
|
111
|
-
case HMSNotificationTypes.ROLE_UPDATED:
|
114
|
+
case HMSNotificationTypes.ROLE_UPDATED: {
|
112
115
|
if (notification.data?.isLocal) {
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
116
|
+
const { prevRole } = vanillaStore.getState(selectPeerMetadata(notification.data?.id));
|
117
|
+
if (prevRole !== notification?.data?.roleName) {
|
118
|
+
ToastManager.addToast({
|
119
|
+
title: `You are now a ${notification.data.roleName}`,
|
120
|
+
});
|
121
|
+
updateRoomLayoutForRole(notification.data.roleName);
|
122
|
+
}
|
117
123
|
}
|
118
124
|
break;
|
125
|
+
}
|
119
126
|
case HMSNotificationTypes.CHANGE_TRACK_STATE_REQUEST:
|
120
127
|
const track = notification.data?.track;
|
121
128
|
if (!notification.data.enabled) {
|
@@ -246,7 +246,6 @@ export const PreviewTile = ({ name, error }: { name: string; error?: boolean })
|
|
246
246
|
};
|
247
247
|
|
248
248
|
export const PreviewControls = ({ hideSettings }: { hideSettings: boolean }) => {
|
249
|
-
const isVideoOn = useHMSStore(selectIsLocalVideoEnabled);
|
250
249
|
const isMobile = useMedia(cssConfig.media.md);
|
251
250
|
|
252
251
|
return (
|
@@ -258,8 +257,8 @@ export const PreviewControls = ({ hideSettings }: { hideSettings: boolean }) =>
|
|
258
257
|
}}
|
259
258
|
>
|
260
259
|
<Flex css={{ gap: '$4' }}>
|
261
|
-
<AudioVideoToggle
|
262
|
-
<Suspense fallback="">{
|
260
|
+
<AudioVideoToggle />
|
261
|
+
<Suspense fallback="">{!isMobile ? <VirtualBackground /> : null}</Suspense>
|
263
262
|
</Flex>
|
264
263
|
{!hideSettings ? <PreviewSettings /> : null}
|
265
264
|
</Flex>
|
@@ -27,9 +27,11 @@ export const RoleChangeRequestModal = () => {
|
|
27
27
|
if (!roleChangeRequest?.role) {
|
28
28
|
return;
|
29
29
|
}
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
(async () => {
|
31
|
+
await updateMetaData({ prevRole: currentRole });
|
32
|
+
await hmsActions.preview({ asRole: roleChangeRequest.role.name });
|
33
|
+
})();
|
34
|
+
}, [hmsActions, roleChangeRequest, currentRole, updateMetaData]);
|
33
35
|
|
34
36
|
if (!roleChangeRequest?.role) {
|
35
37
|
return null;
|
@@ -69,7 +71,7 @@ export const RoleChangeRequestModal = () => {
|
|
69
71
|
body={body}
|
70
72
|
onAction={async () => {
|
71
73
|
await hmsActions.acceptChangeRole(roleChangeRequest);
|
72
|
-
await updateMetaData({ isHandRaised: false
|
74
|
+
await updateMetaData({ isHandRaised: false });
|
73
75
|
}}
|
74
76
|
actionText="Accept"
|
75
77
|
/>
|
@@ -0,0 +1,120 @@
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
2
|
+
import { ConferencingScreen } from '@100mslive/types-prebuilt';
|
3
|
+
import { selectPeerCount, useHMSStore } from '@100mslive/react-sdk';
|
4
|
+
import { CrossIcon } from '@100mslive/react-icons';
|
5
|
+
// @ts-ignore: No implicit Any
|
6
|
+
import { Chat } from './Chat/Chat';
|
7
|
+
// @ts-ignore: No implicit Any
|
8
|
+
import { ParticipantList } from './Footer/ParticipantList';
|
9
|
+
import { Flex, IconButton, Tabs, Text } from '../..';
|
10
|
+
import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
11
|
+
// @ts-ignore: No implicit Any
|
12
|
+
import { useSidepaneReset, useSidepaneToggle } from './AppData/useSidepane';
|
13
|
+
// @ts-ignore: No implicit Any
|
14
|
+
import { SIDE_PANE_OPTIONS } from '../common/constants';
|
15
|
+
|
16
|
+
const tabTriggerCSS = {
|
17
|
+
color: '$on_surface_high',
|
18
|
+
p: '$4',
|
19
|
+
fontWeight: '$semiBold',
|
20
|
+
fontSize: '$sm',
|
21
|
+
w: '100%',
|
22
|
+
justifyContent: 'center',
|
23
|
+
};
|
24
|
+
|
25
|
+
export const SidePaneTabs = React.memo<{
|
26
|
+
active: 'Participants | Chat';
|
27
|
+
screenType: keyof ConferencingScreen;
|
28
|
+
hideControls?: boolean;
|
29
|
+
}>(({ active = SIDE_PANE_OPTIONS.CHAT, screenType, hideControls }) => {
|
30
|
+
const toggleChat = useSidepaneToggle(SIDE_PANE_OPTIONS.CHAT);
|
31
|
+
const toggleParticipants = useSidepaneToggle(SIDE_PANE_OPTIONS.PARTICIPANTS);
|
32
|
+
const resetSidePane = useSidepaneReset();
|
33
|
+
const [activeTab, setActiveTab] = useState(active);
|
34
|
+
const peerCount = useHMSStore(selectPeerCount);
|
35
|
+
const { elements } = useRoomLayoutConferencingScreen();
|
36
|
+
const showChat = !!elements?.chat;
|
37
|
+
const showParticipants = !!elements?.participant_list;
|
38
|
+
const hideTabs = !(showChat && showParticipants);
|
39
|
+
|
40
|
+
useEffect(() => {
|
41
|
+
if (activeTab === SIDE_PANE_OPTIONS.CHAT && !showChat && showParticipants) {
|
42
|
+
setActiveTab(SIDE_PANE_OPTIONS.PARTICIPANTS);
|
43
|
+
} else if (activeTab === SIDE_PANE_OPTIONS.PARTICIPANTS && showChat && !showParticipants) {
|
44
|
+
setActiveTab(SIDE_PANE_OPTIONS.CHAT);
|
45
|
+
} else if (!showChat && !showParticipants) {
|
46
|
+
resetSidePane();
|
47
|
+
}
|
48
|
+
}, [showChat, activeTab, showParticipants, resetSidePane]);
|
49
|
+
|
50
|
+
return (
|
51
|
+
<Flex
|
52
|
+
direction="column"
|
53
|
+
css={{
|
54
|
+
color: '$on_primary_high',
|
55
|
+
h: '100%',
|
56
|
+
}}
|
57
|
+
>
|
58
|
+
{hideTabs ? (
|
59
|
+
<>
|
60
|
+
<Text variant="sm" css={{ fontWeight: '$semiBold', p: '$4', c: '$on_surface_high', pr: '$12' }}>
|
61
|
+
{showChat ? 'Chat' : `Participants (${peerCount})`}
|
62
|
+
</Text>
|
63
|
+
{showChat ? <Chat screenType={screenType} hideControls={hideControls} /> : <ParticipantList />}
|
64
|
+
</>
|
65
|
+
) : (
|
66
|
+
<Tabs.Root
|
67
|
+
value={activeTab}
|
68
|
+
onValueChange={setActiveTab}
|
69
|
+
css={{
|
70
|
+
flexDirection: 'column',
|
71
|
+
size: '100%',
|
72
|
+
}}
|
73
|
+
>
|
74
|
+
<Tabs.List css={{ w: 'calc(100% - $12)', p: '$2', borderRadius: '$2', bg: '$surface_default' }}>
|
75
|
+
<Tabs.Trigger
|
76
|
+
value={SIDE_PANE_OPTIONS.CHAT}
|
77
|
+
onClick={toggleChat}
|
78
|
+
css={{
|
79
|
+
...tabTriggerCSS,
|
80
|
+
color: activeTab !== SIDE_PANE_OPTIONS.CHAT ? '$on_surface_low' : '$on_surface_high',
|
81
|
+
}}
|
82
|
+
>
|
83
|
+
Chat
|
84
|
+
</Tabs.Trigger>
|
85
|
+
<Tabs.Trigger
|
86
|
+
value={SIDE_PANE_OPTIONS.PARTICIPANTS}
|
87
|
+
onClick={toggleParticipants}
|
88
|
+
css={{
|
89
|
+
...tabTriggerCSS,
|
90
|
+
color: activeTab !== SIDE_PANE_OPTIONS.PARTICIPANTS ? '$on_surface_low' : '$on_surface_high',
|
91
|
+
}}
|
92
|
+
>
|
93
|
+
Participants ({peerCount})
|
94
|
+
</Tabs.Trigger>
|
95
|
+
</Tabs.List>
|
96
|
+
<Tabs.Content value={SIDE_PANE_OPTIONS.PARTICIPANTS} css={{ p: 0 }}>
|
97
|
+
<ParticipantList />
|
98
|
+
</Tabs.Content>
|
99
|
+
<Tabs.Content value={SIDE_PANE_OPTIONS.CHAT} css={{ p: 0 }}>
|
100
|
+
<Chat screenType={screenType} hideControls={hideControls} />
|
101
|
+
</Tabs.Content>
|
102
|
+
</Tabs.Root>
|
103
|
+
)}
|
104
|
+
<IconButton
|
105
|
+
css={{ position: 'absolute', right: '$10', top: '$11' }}
|
106
|
+
onClick={e => {
|
107
|
+
e.stopPropagation();
|
108
|
+
if (activeTab === SIDE_PANE_OPTIONS.CHAT) {
|
109
|
+
toggleChat();
|
110
|
+
} else {
|
111
|
+
toggleParticipants();
|
112
|
+
}
|
113
|
+
}}
|
114
|
+
data-testid="close_chat"
|
115
|
+
>
|
116
|
+
<CrossIcon />
|
117
|
+
</IconButton>
|
118
|
+
</Flex>
|
119
|
+
);
|
120
|
+
});
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { useCallback
|
1
|
+
import { useCallback } from 'react';
|
2
2
|
import {
|
3
3
|
selectLocalPeerID,
|
4
4
|
selectPeerMetadata,
|
@@ -12,8 +12,6 @@ export const useMyMetadata = () => {
|
|
12
12
|
const localPeerId = useHMSStore(selectLocalPeerID);
|
13
13
|
const vanillaStore = useHMSVanillaStore();
|
14
14
|
const metaData = useHMSStore(selectPeerMetadata(localPeerId));
|
15
|
-
const [isHandRaised, setHandRaised] = useState(metaData?.isHandRaised || false);
|
16
|
-
const [isBRBOn, setBRBOn] = useState(metaData?.isBRBOn || false); // BRB = be right back
|
17
15
|
|
18
16
|
const update = async updatedFields => {
|
19
17
|
try {
|
@@ -27,28 +25,12 @@ export const useMyMetadata = () => {
|
|
27
25
|
};
|
28
26
|
|
29
27
|
const toggleHandRaise = useCallback(async () => {
|
30
|
-
|
31
|
-
|
32
|
-
isHandRaised: !isHandRaised,
|
33
|
-
isBRBOn: brbUpdate,
|
34
|
-
});
|
35
|
-
if (success) {
|
36
|
-
setBRBOn(brbUpdate);
|
37
|
-
setHandRaised(!isHandRaised);
|
38
|
-
}
|
39
|
-
}, [isHandRaised, isBRBOn]); //eslint-disable-line
|
28
|
+
await update({ isHandRaised: !metaData?.isHandRaised, isBRBOn: false });
|
29
|
+
}, [metaData?.isHandRaised]); //eslint-disable-line
|
40
30
|
|
41
31
|
const toggleBRB = useCallback(async () => {
|
42
|
-
|
43
|
-
|
44
|
-
isHandRaised: handRaiseUpdate,
|
45
|
-
isBRBOn: !isBRBOn,
|
46
|
-
});
|
47
|
-
if (success) {
|
48
|
-
setBRBOn(!isBRBOn);
|
49
|
-
setHandRaised(handRaiseUpdate);
|
50
|
-
}
|
51
|
-
}, [isHandRaised, isBRBOn]); //eslint-disable-line
|
32
|
+
await update({ isBRBOn: !metaData?.isBRBOn, isHandRaised: false });
|
33
|
+
}, [metaData?.isBRBOn]); //eslint-disable-line
|
52
34
|
|
53
35
|
const setPrevRole = async role => {
|
54
36
|
await update({
|
@@ -57,8 +39,8 @@ export const useMyMetadata = () => {
|
|
57
39
|
};
|
58
40
|
|
59
41
|
return {
|
60
|
-
isHandRaised,
|
61
|
-
isBRBOn,
|
42
|
+
isHandRaised: !!metaData?.isHandRaised,
|
43
|
+
isBRBOn: !!metaData?.isBRBOn,
|
62
44
|
metaData,
|
63
45
|
updateMetaData: update,
|
64
46
|
toggleHandRaise,
|
@@ -2,10 +2,7 @@ import React from 'react';
|
|
2
2
|
import { useMedia } from 'react-use';
|
3
3
|
import { ConferencingScreen } from '@100mslive/types-prebuilt';
|
4
4
|
import { selectAppData, selectVideoTrackByPeerID, useHMSStore } from '@100mslive/react-sdk';
|
5
|
-
|
6
|
-
import { Chat } from '../components/Chat/Chat';
|
7
|
-
// @ts-ignore: No implicit Any
|
8
|
-
import { ParticipantList } from '../components/Footer/ParticipantList';
|
5
|
+
import { SidePaneTabs } from '../components/SidePaneTabs';
|
9
6
|
// @ts-ignore: No implicit Any
|
10
7
|
import { StreamingLanding } from '../components/Streaming/StreamingLanding';
|
11
8
|
import { TileCustomisationProps } from '../components/VideoLayouts/GridLayout';
|
@@ -32,10 +29,8 @@ const SidePane = ({
|
|
32
29
|
const trackId = useHMSStore(selectVideoTrackByPeerID(activeScreensharePeerId))?.id;
|
33
30
|
const { elements } = useRoomLayoutConferencingScreen();
|
34
31
|
let ViewComponent;
|
35
|
-
if (sidepane === SIDE_PANE_OPTIONS.PARTICIPANTS) {
|
36
|
-
ViewComponent = <
|
37
|
-
} else if (sidepane === SIDE_PANE_OPTIONS.CHAT) {
|
38
|
-
ViewComponent = <Chat screenType={screenType} hideControls={hideControls} />;
|
32
|
+
if (sidepane === SIDE_PANE_OPTIONS.PARTICIPANTS || sidepane === SIDE_PANE_OPTIONS.CHAT) {
|
33
|
+
ViewComponent = <SidePaneTabs screenType={screenType} hideControls={hideControls} active={sidepane} />;
|
39
34
|
} else if (sidepane === SIDE_PANE_OPTIONS.STREAMING) {
|
40
35
|
ViewComponent = <StreamingLanding />;
|
41
36
|
}
|
@@ -43,6 +38,14 @@ const SidePane = ({
|
|
43
38
|
return null;
|
44
39
|
}
|
45
40
|
|
41
|
+
const tileLayout = {
|
42
|
+
hideParticipantNameOnTile: tileProps?.hide_participant_name_on_tile,
|
43
|
+
roundedVideoTile: tileProps?.rounded_video_tile,
|
44
|
+
hideAudioMuteOnTile: tileProps?.hide_audio_mute_on_tile,
|
45
|
+
hideMetadataOnTile: tileProps?.hide_metadata_on_tile,
|
46
|
+
objectFit: tileProps?.video_object_fit,
|
47
|
+
};
|
48
|
+
|
46
49
|
const mwebStreamingChat = isMobile && sidepane === SIDE_PANE_OPTIONS.CHAT && elements?.chat?.is_overlay;
|
47
50
|
|
48
51
|
return (
|
@@ -64,8 +67,7 @@ const SidePane = ({
|
|
64
67
|
width="100%"
|
65
68
|
height={225}
|
66
69
|
rootCSS={{ p: 0, alignSelf: 'start', flexShrink: 0 }}
|
67
|
-
|
68
|
-
{...tileProps}
|
70
|
+
{...tileLayout}
|
69
71
|
/>
|
70
72
|
)}
|
71
73
|
{!!ViewComponent && (
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import React, { useEffect, useRef, useState } from 'react';
|
2
2
|
import { HMSVirtualBackgroundTypes } from '@100mslive/hms-virtual-background';
|
3
3
|
import {
|
4
|
-
|
4
|
+
selectIsLocalVideoEnabled,
|
5
5
|
selectIsLocalVideoPluginPresent,
|
6
6
|
selectLocalPeerRole,
|
7
7
|
selectLocalVideoTrackID,
|
@@ -23,8 +23,8 @@ export const VirtualBackground = ({
|
|
23
23
|
}) => {
|
24
24
|
const pluginRef = useRef(null);
|
25
25
|
const hmsActions = useHMSActions();
|
26
|
-
const isAllowedToPublish = useHMSStore(selectIsAllowedToPublish);
|
27
26
|
const role = useHMSStore(selectLocalPeerRole);
|
27
|
+
const isVideoOn = useHMSStore(selectIsLocalVideoEnabled);
|
28
28
|
const [isVBLoading, setIsVBLoading] = useState(false);
|
29
29
|
const [isVBSupported, setIsVBSupported] = useState(false);
|
30
30
|
const [isVBOn, setIsVBOn] = useState(false);
|
@@ -69,7 +69,7 @@ export const VirtualBackground = ({
|
|
69
69
|
}
|
70
70
|
}
|
71
71
|
|
72
|
-
if (!
|
72
|
+
if (!isVBSupported || !isVideoOn) {
|
73
73
|
return null;
|
74
74
|
}
|
75
75
|
if (asActionTile) {
|
@@ -29,7 +29,7 @@ export type useFetchRoomLayoutResponse = {
|
|
29
29
|
};
|
30
30
|
|
31
31
|
export const useFetchRoomLayout = ({
|
32
|
-
endpoint = '
|
32
|
+
endpoint = '',
|
33
33
|
authToken = '',
|
34
34
|
}: useFetchRoomLayoutProps): useFetchRoomLayoutResponse => {
|
35
35
|
const [layout, setLayout] = useState<Layout | undefined>(undefined);
|
@@ -51,7 +51,7 @@ export const useFetchRoomLayout = ({
|
|
51
51
|
}
|
52
52
|
isFetchInProgress.current = true;
|
53
53
|
try {
|
54
|
-
const resp = await fetchWithRetry(endpoint, {
|
54
|
+
const resp = await fetchWithRetry(endpoint || 'https://api.100ms.live/v2/layouts/ui', {
|
55
55
|
headers: {
|
56
56
|
Authorization: `Bearer ${authToken}`,
|
57
57
|
},
|
@@ -1,7 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"version": 3,
|
3
|
-
"sources": ["../src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx", "../src/Prebuilt/plugins/VirtualBackground/vbutils.js"],
|
4
|
-
"sourcesContent": ["import React, { useEffect, useRef, useState } from 'react';\nimport { HMSVirtualBackgroundTypes } from '@100mslive/hms-virtual-background';\nimport {\n selectIsAllowedToPublish,\n selectIsLocalVideoPluginPresent,\n selectLocalPeerRole,\n selectLocalVideoTrackID,\n useHMSActions,\n useHMSStore,\n} from '@100mslive/react-sdk';\nimport { VirtualBackgroundIcon } from '@100mslive/react-icons';\nimport { ActionTile } from '../../components/MoreSettings/ActionTile';\nimport { Loading } from '../../../Loading';\nimport { Tooltip } from '../../../Tooltip';\nimport IconButton from '../../IconButton';\nimport { getRandomVirtualBackground } from './vbutils';\n\nexport const VirtualBackground = ({\n asActionTile = false,\n onVBClick = () => {\n return;\n },\n}) => {\n const pluginRef = useRef(null);\n const hmsActions = useHMSActions();\n const isAllowedToPublish = useHMSStore(selectIsAllowedToPublish);\n const role = useHMSStore(selectLocalPeerRole);\n const [isVBLoading, setIsVBLoading] = useState(false);\n const [isVBSupported, setIsVBSupported] = useState(false);\n const [isVBOn, setIsVBOn] = useState(false);\n const localPeerVideoTrackID = useHMSStore(selectLocalVideoTrackID);\n const isVBPresent = useHMSStore(selectIsLocalVideoPluginPresent('HMSVB'));\n\n async function createPlugin() {\n if (!pluginRef.current) {\n const { HMSVBPlugin } = await import('@100mslive/hms-virtual-background');\n pluginRef.current = new HMSVBPlugin(HMSVirtualBackgroundTypes.NONE, HMSVirtualBackgroundTypes.NONE);\n }\n }\n useEffect(() => {\n if (!localPeerVideoTrackID) {\n return;\n }\n createPlugin().then(() => {\n //check support of plugin\n const pluginSupport = hmsActions.validateVideoPluginSupport(pluginRef.current);\n setIsVBSupported(pluginSupport.isSupported);\n });\n }, [hmsActions, localPeerVideoTrackID]);\n\n async function addPlugin() {\n setIsVBLoading(true);\n try {\n await createPlugin();\n window.HMS.virtualBackground = pluginRef.current;\n const { background, backgroundType } = getRandomVirtualBackground();\n await pluginRef.current.setBackground(background, backgroundType);\n await hmsActions.addPluginToVideoTrack(pluginRef.current, Math.floor(role.publishParams.video.frameRate / 2));\n } catch (err) {\n console.error('add virtual background plugin failed', err);\n }\n setIsVBLoading(false);\n }\n\n async function removePlugin() {\n if (pluginRef.current) {\n await hmsActions.removePluginFromVideoTrack(pluginRef.current);\n pluginRef.current = null;\n }\n }\n\n if (!isAllowedToPublish.video || !isVBSupported) {\n return null;\n }\n if (asActionTile) {\n return (\n <ActionTile.Root\n data-testid=\"virtual_bg_btn\"\n active={isVBPresent}\n disabled={isVBLoading}\n onClick={() => {\n setIsVBOn(!isVBOn);\n !isVBPresent ? addPlugin() : removePlugin();\n onVBClick();\n }}\n >\n <VirtualBackgroundIcon />\n <ActionTile.Title>Virtual Background</ActionTile.Title>\n </ActionTile.Root>\n );\n }\n\n return (\n <Tooltip\n boxCss={{ zIndex: '100' }}\n title={isVBLoading ? 'Adding virtual background' : `Turn ${!isVBPresent ? 'on' : 'off'} virtual background`}\n >\n <IconButton\n active={!isVBPresent}\n disabled={isVBLoading}\n onClick={() => {\n !isVBPresent ? addPlugin() : removePlugin();\n }}\n data-testid=\"virtual_bg_btn\"\n >\n {isVBLoading ? <Loading /> : <VirtualBackgroundIcon />}\n </IconButton>\n </Tooltip>\n );\n};\n\nexport default VirtualBackground;\n", "/* eslint-disable no-case-declarations */\nimport { HMSVirtualBackgroundTypes } from '@100mslive/hms-virtual-background';\nexport function getRandomVirtualBackground() {\n const backgroundList = [\n {\n background: HMSVirtualBackgroundTypes.BLUR,\n backgroundType: HMSVirtualBackgroundTypes.BLUR,\n },\n ];\n\n const images = [\n 'https://www.100ms.live/images/vb-1.jpeg',\n 'https://www.100ms.live/images/vb-2.jpg',\n 'https://www.100ms.live/images/vb-3.png',\n 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/hms1.png',\n 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/hms2.png',\n 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/hms3.png',\n 'https://d2qi07yyjujoxr.cloudfront.net/webapp/vb/hms4.png',\n ].map(url => ({\n background: url,\n backgroundType: HMSVirtualBackgroundTypes.IMAGE,\n }));\n\n backgroundList.push(...images);\n\n /* \n //TODO: update with a better quality gif.\n const gifList = [\n {\n background: \"https://www.100ms.live/images/vb-1.gif\",\n backgroundType: HMSVirtualBackgroundTypes.GIF,\n },\n ];\n backgroundList.push(...gifList); \n */\n\n const videoList = [\n 'https://www.100ms.live/images/video-1.mp4',\n 'https://www.100ms.live/images/video-2.mp4',\n 'https://www.100ms.live/images/video-5.mp4',\n 'https://www.100ms.live/images/video-7.mp4',\n 'https://www.100ms.live/images/video-8.mp4',\n ].map(url => ({\n background: url,\n backgroundType: HMSVirtualBackgroundTypes.VIDEO,\n }));\n backgroundList.push(...videoList);\n\n const randomIdx = Math.floor(Math.random() * backgroundList.length);\n const virtualBackground = backgroundList[randomIdx];\n switch (virtualBackground.backgroundType) {\n case HMSVirtualBackgroundTypes.IMAGE:\n const img = document.createElement('img');\n img.alt = 'VB';\n img.src = backgroundList[randomIdx].background;\n virtualBackground.background = img;\n return virtualBackground;\n case HMSVirtualBackgroundTypes.VIDEO:\n const videoEl = document.createElement('video');\n videoEl.src = backgroundList[randomIdx].background;\n virtualBackground.background = videoEl;\n return virtualBackground;\n default:\n return virtualBackground;\n }\n}\n"],
|
5
|
-
"mappings": "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",
|
6
|
-
"names": ["HMSVirtualBackgroundTypes", "HMSVirtualBackgroundTypes"]
|
7
|
-
}
|