@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.
Files changed (38) hide show
  1. package/dist/{HLSView-HNVYG5VE.js → HLSView-QMU5JK7U.js} +3 -3
  2. package/dist/Prebuilt/components/Footer/ChatToggle.d.ts +1 -3
  3. package/dist/Prebuilt/components/SidePaneTabs.d.ts +7 -0
  4. package/dist/{VirtualBackground-UM2FOUHQ.js → VirtualBackground-37FXUPYO.js} +6 -6
  5. package/dist/VirtualBackground-37FXUPYO.js.map +7 -0
  6. package/dist/{chunk-POE7H4IE.js → chunk-KBVIZGYW.js} +2 -2
  7. package/dist/{chunk-POE7H4IE.js.map → chunk-KBVIZGYW.js.map} +1 -1
  8. package/dist/{chunk-LYSAET4G.js → chunk-WVGGQZK4.js} +100 -106
  9. package/dist/{chunk-LYSAET4G.js.map → chunk-WVGGQZK4.js.map} +3 -3
  10. package/dist/{chunk-364HP22I.js → chunk-ZKE2N5LH.js} +2 -2
  11. package/dist/{conference-UWLJHMB2.js → conference-FJJQ4TXX.js} +419 -384
  12. package/dist/conference-FJJQ4TXX.js.map +7 -0
  13. package/dist/index.cjs.js +594 -570
  14. package/dist/index.cjs.js.map +4 -4
  15. package/dist/index.js +2 -2
  16. package/dist/meta.cjs.json +127 -127
  17. package/dist/meta.esbuild.json +161 -160
  18. package/package.json +6 -6
  19. package/src/Prebuilt/components/Chat/Chat.jsx +2 -6
  20. package/src/Prebuilt/components/Footer/ChatToggle.tsx +2 -9
  21. package/src/Prebuilt/components/Footer/Footer.tsx +22 -6
  22. package/src/Prebuilt/components/Footer/ParticipantList.jsx +0 -2
  23. package/src/Prebuilt/components/Header/HeaderComponents.jsx +8 -1
  24. package/src/Prebuilt/components/InsetTile.tsx +1 -0
  25. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +1 -1
  26. package/src/Prebuilt/components/Notifications/Notifications.jsx +14 -7
  27. package/src/Prebuilt/components/Preview/PreviewJoin.tsx +2 -3
  28. package/src/Prebuilt/components/RoleChangeRequestModal.tsx +6 -4
  29. package/src/Prebuilt/components/SidePaneTabs.tsx +120 -0
  30. package/src/Prebuilt/components/hooks/useMetadata.jsx +7 -25
  31. package/src/Prebuilt/layouts/SidePane.tsx +12 -10
  32. package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +3 -3
  33. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.ts +2 -2
  34. package/dist/VirtualBackground-UM2FOUHQ.js.map +0 -7
  35. package/dist/conference-UWLJHMB2.js.map +0 -7
  36. package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +0 -84
  37. /package/dist/{HLSView-HNVYG5VE.js.map → HLSView-QMU5JK7U.js.map} +0 -0
  38. /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.1",
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.1",
80
- "@100mslive/hms-virtual-background": "1.11.15-alpha.1",
81
- "@100mslive/react-icons": "0.8.15-alpha.1",
82
- "@100mslive/react-sdk": "0.8.15-alpha.1",
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": "d3f042d48bb30f16c6c63f2a75c406611c0f2831"
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, setSelectorOpen] = useState(false);
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, { useEffect } from '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 = ({ openByDefault }: { openByDefault: boolean }) => {
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
- const isVideoOn = useHMSStore(selectIsLocalVideoEnabled);
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 : <Suspense fallback={<></>}>{isVideoOn ? <VirtualBackground /> : null}</Suspense>}
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 openByDefault={openByDefault} />}
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 openByDefault={openByDefault} />}
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
  }
@@ -120,6 +120,7 @@ export const InsetTile = () => {
120
120
  canMinimise
121
121
  isDragabble
122
122
  {...videoTileProps}
123
+ hideParticipantNameOnTile
123
124
  />
124
125
  )}
125
126
  </Box>
@@ -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
- ToastManager.addToast({
114
- title: `You are now a ${notification.data.roleName}`,
115
- });
116
- updateRoomLayoutForRole(notification.data.roleName);
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 compact />
262
- <Suspense fallback="">{isVideoOn && !isMobile ? <VirtualBackground /> : null}</Suspense>
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
- hmsActions.preview({ asRole: roleChangeRequest.role.name });
32
- }, [hmsActions, roleChangeRequest]);
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, prevRole: currentRole });
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, useState } from 'react';
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
- const brbUpdate = !isHandRaised ? false : isBRBOn;
31
- const success = await update({
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
- const handRaiseUpdate = !isBRBOn ? false : isHandRaised;
43
- const success = await update({
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
- // @ts-ignore: No implicit Any
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 = <ParticipantList />;
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
- objectFit="contain"
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
- selectIsAllowedToPublish,
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 (!isAllowedToPublish.video || !isVBSupported) {
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 = 'https://api.100ms.live/v2/layouts/ui',
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
- }