@100mslive/roomkit-react 0.1.6-alpha.0 → 0.1.6-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/dist/{HLSView-PY2FKWX3.js → HLSView-HNVYG5VE.js} +208 -118
  2. package/dist/HLSView-HNVYG5VE.js.map +7 -0
  3. package/dist/Prebuilt/AppContext.d.ts +1 -1
  4. package/dist/Prebuilt/components/Chat/ChatFooter.d.ts +7 -0
  5. package/dist/Prebuilt/components/Connection/ConnectionIndicator.d.ts +6 -0
  6. package/dist/Prebuilt/components/Connection/TileConnection.d.ts +10 -0
  7. package/dist/Prebuilt/components/Footer/ChatToggle.d.ts +4 -0
  8. package/dist/Prebuilt/components/Footer/RoleAccordion.d.ts +14 -0
  9. package/dist/Prebuilt/components/Footer/RoleOptions.d.ts +6 -0
  10. package/dist/Prebuilt/components/Header/StreamActions.d.ts +11 -0
  11. package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +4 -3
  12. package/dist/Prebuilt/components/Leave/EndSessionContent.d.ts +4 -3
  13. package/dist/Prebuilt/components/Leave/LeaveCard.d.ts +1 -2
  14. package/dist/Prebuilt/components/Leave/LeaveSessionContent.d.ts +3 -1
  15. package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +4 -3
  16. package/dist/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.d.ts +6 -0
  17. package/dist/Prebuilt/components/Preview/PreviewContainer.d.ts +3 -0
  18. package/dist/Prebuilt/components/Preview/PreviewJoin.d.ts +16 -0
  19. package/dist/Prebuilt/components/RoleChangeRequestModal.d.ts +2 -0
  20. package/dist/Prebuilt/components/SecondaryTiles.d.ts +1 -1
  21. package/dist/Prebuilt/components/VideoLayouts/EqualProminence.d.ts +1 -1
  22. package/dist/Prebuilt/components/VideoLayouts/Grid.d.ts +1 -0
  23. package/dist/Prebuilt/components/VideoLayouts/GridLayout.d.ts +5 -3
  24. package/dist/Prebuilt/components/VideoLayouts/ProminenceLayout.d.ts +6 -3
  25. package/dist/Prebuilt/components/VideoLayouts/RoleProminence.d.ts +1 -1
  26. package/dist/Prebuilt/components/VideoLayouts/ScreenshareLayout.d.ts +1 -1
  27. package/dist/Prebuilt/components/VideoLayouts/interface.d.ts +1 -0
  28. package/dist/Prebuilt/components/hooks/useAutoStartStreaming.d.ts +1 -0
  29. package/dist/Prebuilt/components/hooks/useRedirectToLeave.d.ts +3 -0
  30. package/dist/Prebuilt/components/hooks/useTileLayout.d.ts +2 -1
  31. package/dist/Prebuilt/components/hooks/useVideoTileLayout.d.ts +2 -0
  32. package/dist/Prebuilt/layouts/SidePane.d.ts +4 -1
  33. package/dist/Prebuilt/layouts/VideoStreamingSection.d.ts +2 -1
  34. package/dist/{VirtualBackground-AYDHYLIZ.js → VirtualBackground-UM2FOUHQ.js} +3 -3
  35. package/dist/{chunk-E2M2ZSOL.js → chunk-364HP22I.js} +2 -2
  36. package/dist/{chunk-RXTHJUMZ.js → chunk-LYSAET4G.js} +946 -390
  37. package/dist/chunk-LYSAET4G.js.map +7 -0
  38. package/dist/{chunk-GQD2AGWW.js → chunk-POE7H4IE.js} +12 -2
  39. package/dist/{chunk-GQD2AGWW.js.map → chunk-POE7H4IE.js.map} +2 -2
  40. package/dist/{conference-V2XZGTKU.js → conference-UWLJHMB2.js} +1116 -1316
  41. package/dist/conference-UWLJHMB2.js.map +7 -0
  42. package/dist/index.cjs.js +6080 -5631
  43. package/dist/index.cjs.js.map +4 -4
  44. package/dist/index.js +2 -2
  45. package/dist/meta.cjs.json +741 -493
  46. package/dist/meta.esbuild.json +782 -529
  47. package/package.json +8 -7
  48. package/src/Prebuilt/App.tsx +10 -21
  49. package/src/Prebuilt/AppContext.tsx +1 -1
  50. package/src/Prebuilt/IconButton.jsx +10 -0
  51. package/src/Prebuilt/common/PeersSorter.ts +1 -1
  52. package/src/Prebuilt/common/constants.js +1 -2
  53. package/src/Prebuilt/common/utils.js +1 -1
  54. package/src/Prebuilt/components/AppData/AppData.jsx +8 -2
  55. package/src/Prebuilt/components/AppData/useUISettings.js +6 -6
  56. package/src/Prebuilt/components/AudioVideoToggle.jsx +8 -6
  57. package/src/Prebuilt/components/Chat/Chat.jsx +23 -6
  58. package/src/Prebuilt/components/Chat/ChatBody.jsx +20 -21
  59. package/src/Prebuilt/components/Chat/{ChatFooter.jsx → ChatFooter.tsx} +38 -13
  60. package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +38 -27
  61. package/src/Prebuilt/components/Chat/useEmojiPickerStyles.js +5 -4
  62. package/src/Prebuilt/components/Connection/{ConnectionIndicator.jsx → ConnectionIndicator.tsx} +12 -4
  63. package/src/Prebuilt/components/Connection/{TileConnection.jsx → TileConnection.tsx} +20 -6
  64. package/src/Prebuilt/components/EmojiReaction.jsx +2 -6
  65. package/src/Prebuilt/components/Footer/{ChatToggle.jsx → ChatToggle.tsx} +13 -3
  66. package/src/Prebuilt/components/Footer/Footer.tsx +15 -6
  67. package/src/Prebuilt/components/Footer/ParticipantList.jsx +15 -47
  68. package/src/Prebuilt/components/Footer/{RoleAccordion.jsx → RoleAccordion.tsx} +33 -17
  69. package/src/Prebuilt/components/Footer/RoleOptions.tsx +155 -0
  70. package/src/Prebuilt/components/FullPageProgress.jsx +3 -3
  71. package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -0
  72. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +39 -17
  73. package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +2 -2
  74. package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +5 -6
  75. package/src/Prebuilt/components/HMSVideo/VolumeControl.jsx +1 -1
  76. package/src/Prebuilt/components/Header/{StreamActions.jsx → StreamActions.tsx} +23 -9
  77. package/src/Prebuilt/components/Header/common.jsx +5 -2
  78. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +6 -1
  79. package/src/Prebuilt/components/InsetTile.tsx +14 -8
  80. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +21 -11
  81. package/src/Prebuilt/components/Leave/EndSessionContent.tsx +2 -5
  82. package/src/Prebuilt/components/Leave/LeaveCard.tsx +1 -3
  83. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +28 -25
  84. package/src/Prebuilt/components/Leave/LeaveSessionContent.tsx +8 -2
  85. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +8 -8
  86. package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +4 -0
  87. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +1 -1
  88. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +9 -23
  89. package/src/Prebuilt/components/MoreSettings/SplitComponents/{MwebOptions.jsx → MwebOptions.tsx} +88 -27
  90. package/src/Prebuilt/components/Notifications/Notifications.jsx +30 -21
  91. package/src/Prebuilt/components/Notifications/ReconnectNotifications.jsx +5 -11
  92. package/src/Prebuilt/components/Pagination.tsx +14 -12
  93. package/src/Prebuilt/components/Preview/{PreviewContainer.jsx → PreviewContainer.tsx} +11 -2
  94. package/src/Prebuilt/components/Preview/PreviewForm.tsx +6 -8
  95. package/src/Prebuilt/components/Preview/{PreviewJoin.jsx → PreviewJoin.tsx} +43 -19
  96. package/src/Prebuilt/components/{RoleChangeRequestModal.jsx → RoleChangeRequestModal.tsx} +32 -15
  97. package/src/Prebuilt/components/ScreenshareTile.jsx +6 -7
  98. package/src/Prebuilt/components/SecondaryTiles.tsx +12 -10
  99. package/src/Prebuilt/components/TileMenu/TileMenu.jsx +1 -1
  100. package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +14 -10
  101. package/src/Prebuilt/components/Toast/ToastConfig.jsx +5 -4
  102. package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +13 -10
  103. package/src/Prebuilt/components/VideoLayouts/Grid.tsx +36 -34
  104. package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +33 -15
  105. package/src/Prebuilt/components/VideoLayouts/ProminenceLayout.tsx +45 -31
  106. package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +12 -9
  107. package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +25 -9
  108. package/src/Prebuilt/components/VideoLayouts/interface.ts +1 -0
  109. package/src/Prebuilt/components/VideoTile.jsx +45 -53
  110. package/src/Prebuilt/components/conference.jsx +71 -74
  111. package/src/Prebuilt/components/hooks/useAutoStartStreaming.tsx +57 -0
  112. package/src/Prebuilt/components/hooks/useMetadata.jsx +12 -3
  113. package/src/Prebuilt/components/hooks/useRedirectToLeave.tsx +34 -0
  114. package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +1 -1
  115. package/src/Prebuilt/components/hooks/useTileLayout.tsx +24 -18
  116. package/src/Prebuilt/components/hooks/useVideoTileLayout.ts +4 -0
  117. package/src/Prebuilt/layouts/EmbedView.jsx +1 -11
  118. package/src/Prebuilt/layouts/HLSView.jsx +152 -82
  119. package/src/Prebuilt/layouts/SidePane.tsx +15 -3
  120. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +11 -47
  121. package/src/Prebuilt/plugins/FlyingEmoji.jsx +14 -2
  122. package/src/Prebuilt/services/FeatureFlags.jsx +0 -1
  123. package/src/VideoTile/StyledVideoTile.tsx +1 -0
  124. package/dist/HLSView-PY2FKWX3.js.map +0 -7
  125. package/dist/chunk-RXTHJUMZ.js.map +0 -7
  126. package/dist/conference-V2XZGTKU.js.map +0 -7
  127. package/src/Prebuilt/components/AudioLevel/BeamSpeakerLabelsLogging.jsx +0 -16
  128. package/src/Prebuilt/components/VideoList.jsx +0 -73
  129. /package/dist/{VirtualBackground-AYDHYLIZ.js.map → VirtualBackground-UM2FOUHQ.js.map} +0 -0
  130. /package/dist/{chunk-E2M2ZSOL.js.map → chunk-364HP22I.js.map} +0 -0
@@ -1,13 +1,17 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react';
1
+ import React, { ReactNode, useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import data from '@emoji-mart/data';
4
4
  import Picker from '@emoji-mart/react';
5
5
  import { useHMSActions } from '@100mslive/react-sdk';
6
6
  import { EmojiIcon, SendIcon } from '@100mslive/react-icons';
7
- import { Box, config as cssConfig, Flex, IconButton as BaseIconButton, Popover, styled } from '../../../';
7
+ import { Box, config as cssConfig, Flex, IconButton as BaseIconButton, Popover, styled } from '../../..';
8
+ // @ts-ignore
8
9
  import { ToastManager } from '../Toast/ToastManager';
10
+ import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
9
11
  // import { ChatSelectorContainer } from './ChatSelectorContainer';
12
+ // @ts-ignore
10
13
  import { useChatDraftMessage } from '../AppData/useChatState';
14
+ // @ts-ignore
11
15
  import { useEmojiPickerStyles } from './useEmojiPickerStyles';
12
16
 
13
17
  const TextArea = styled('textarea', {
@@ -28,7 +32,7 @@ const TextArea = styled('textarea', {
28
32
  },
29
33
  });
30
34
 
31
- function EmojiPicker({ onSelect }) {
35
+ function EmojiPicker({ onSelect }: { onSelect: (emoji: any) => void }) {
32
36
  const [showEmoji, setShowEmoji] = useState(false);
33
37
  const ref = useEmojiPickerStyles(showEmoji);
34
38
  return (
@@ -62,14 +66,26 @@ function EmojiPicker({ onSelect }) {
62
66
  );
63
67
  }
64
68
 
65
- export const ChatFooter = ({ role, peerId, onSend, children /* onSelect, selection, screenType */ }) => {
69
+ export const ChatFooter = ({
70
+ role,
71
+ peerId,
72
+ onSend,
73
+ children /* onSelect, selection, screenType */,
74
+ }: {
75
+ role: any;
76
+ peerId: string;
77
+ onSend: any;
78
+ children: ReactNode;
79
+ }) => {
66
80
  const hmsActions = useHMSActions();
67
- const inputRef = useRef(null);
81
+ const inputRef = useRef<HTMLTextAreaElement>(null);
68
82
  const [draftMessage, setDraftMessage] = useChatDraftMessage();
69
83
  const isMobile = useMedia(cssConfig.media.md);
84
+ const { elements } = useRoomLayoutConferencingScreen();
85
+ const isOverlayChat = elements?.chat?.is_overlay;
70
86
 
71
87
  const sendMessage = useCallback(async () => {
72
- const message = inputRef.current.value;
88
+ const message = inputRef?.current?.value;
73
89
  if (!message || !message.trim().length) {
74
90
  return;
75
91
  }
@@ -86,7 +102,8 @@ export const ChatFooter = ({ role, peerId, onSend, children /* onSelect, selecti
86
102
  onSend();
87
103
  }, 0);
88
104
  } catch (error) {
89
- ToastManager.addToast({ title: error.message });
105
+ const err = error as Error;
106
+ ToastManager.addToast({ title: err.message });
90
107
  }
91
108
  }, [role, peerId, hmsActions, onSend]);
92
109
 
@@ -113,7 +130,7 @@ export const ChatFooter = ({ role, peerId, onSend, children /* onSelect, selecti
113
130
  <Flex
114
131
  align="center"
115
132
  css={{
116
- bg: isMobile ? '$surface_dim' : '$surface_default',
133
+ bg: isOverlayChat && isMobile ? '$surface_dim' : '$surface_default',
117
134
  minHeight: '$16',
118
135
  maxHeight: '$24',
119
136
  position: 'relative',
@@ -130,9 +147,15 @@ export const ChatFooter = ({ role, peerId, onSend, children /* onSelect, selecti
130
147
  >
131
148
  {children}
132
149
  <TextArea
150
+ css={{
151
+ c: '$on_surface_high',
152
+ '&:valid ~ .send-msg': { color: '$on_surface_high' },
153
+ '& ~ .send-msg': { color: '$on_surface_low' },
154
+ }}
133
155
  placeholder="Send a message...."
134
156
  ref={inputRef}
135
- autoFocus
157
+ required
158
+ autoFocus={!isMobile}
136
159
  onKeyPress={async event => {
137
160
  if (event.key === 'Enter') {
138
161
  if (!event.shiftKey) {
@@ -149,19 +172,21 @@ export const ChatFooter = ({ role, peerId, onSend, children /* onSelect, selecti
149
172
  />
150
173
  {!isMobile ? (
151
174
  <EmojiPicker
152
- onSelect={emoji => {
153
- inputRef.current.value += ` ${emoji.native} `;
175
+ onSelect={(emoji: any) => {
176
+ if (inputRef.current) {
177
+ inputRef.current.value += ` ${emoji.native} `;
178
+ }
154
179
  }}
155
180
  />
156
181
  ) : null}
157
182
  <BaseIconButton
183
+ className="send-msg"
158
184
  onClick={sendMessage}
159
185
  css={{
160
186
  ml: 'auto',
161
187
  height: 'max-content',
162
188
  mr: '$4',
163
- color: '$on_surface_low',
164
- '&:hover': { c: '$on_surface_high' },
189
+ '&:hover': { c: isMobile ? '' : '$on_surface_medium' },
165
190
  }}
166
191
  data-testid="send_msg_btn"
167
192
  >
@@ -1,7 +1,8 @@
1
1
  import React, { useState } from 'react';
2
2
  import { selectPeerCount, useHMSStore } from '@100mslive/react-sdk';
3
3
  import { CrossIcon } from '@100mslive/react-icons';
4
- import { Flex, IconButton, Tabs } from '../../..';
4
+ import { Flex, IconButton, Tabs, Text } from '../../..';
5
+ import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
5
6
  import { useSidepaneToggle } from '../AppData/useSidepane';
6
7
  import { SIDE_PANE_OPTIONS } from '../../common/constants';
7
8
 
@@ -19,6 +20,10 @@ export const ChatParticipantHeader = React.memo(({ activeTabValue = SIDE_PANE_OP
19
20
  const toggleParticipants = useSidepaneToggle(SIDE_PANE_OPTIONS.PARTICIPANTS);
20
21
  const [activeTab, setActiveTab] = useState(activeTabValue);
21
22
  const peerCount = useHMSStore(selectPeerCount);
23
+ const { elements } = useRoomLayoutConferencingScreen();
24
+ const showChat = !!elements?.chat;
25
+ const showParticipants = !!elements?.participant_list;
26
+ const hideTabs = !(showChat && showParticipants);
22
27
 
23
28
  return (
24
29
  <Flex
@@ -28,32 +33,38 @@ export const ChatParticipantHeader = React.memo(({ activeTabValue = SIDE_PANE_OP
28
33
  h: '$16',
29
34
  }}
30
35
  >
31
- <Flex css={{ w: '100%', bg: '$surface_default', borderRadius: '$2' }}>
32
- <Tabs.Root value={activeTab} onValueChange={setActiveTab} css={{ w: '100%' }}>
33
- <Tabs.List css={{ w: '100%', p: '$2' }}>
34
- <Tabs.Trigger
35
- value={SIDE_PANE_OPTIONS.CHAT}
36
- onClick={toggleChat}
37
- css={{
38
- ...tabTriggerCSS,
39
- color: activeTab !== SIDE_PANE_OPTIONS.CHAT ? '$on_surface_low' : '$on_surface_high',
40
- }}
41
- >
42
- Chat
43
- </Tabs.Trigger>
44
- <Tabs.Trigger
45
- value={SIDE_PANE_OPTIONS.PARTICIPANTS}
46
- onClick={toggleParticipants}
47
- css={{
48
- ...tabTriggerCSS,
49
- color: activeTab !== SIDE_PANE_OPTIONS.PARTICIPANTS ? '$on_surface_low' : '$on_surface_high',
50
- }}
51
- >
52
- Participants ({peerCount})
53
- </Tabs.Trigger>
54
- </Tabs.List>
55
- </Tabs.Root>
56
- </Flex>
36
+ {hideTabs ? (
37
+ <Text variant="sm" css={{ fontWeight: '$semiBold', c: '$on_surface_high' }}>
38
+ {showChat ? 'Chat' : `Participants (${peerCount})`}
39
+ </Text>
40
+ ) : (
41
+ <Flex css={{ w: '100%', bg: '$surface_default', borderRadius: '$2' }}>
42
+ <Tabs.Root value={activeTab} onValueChange={setActiveTab} css={{ w: '100%' }}>
43
+ <Tabs.List css={{ w: '100%', p: '$2' }}>
44
+ <Tabs.Trigger
45
+ value={SIDE_PANE_OPTIONS.CHAT}
46
+ onClick={toggleChat}
47
+ css={{
48
+ ...tabTriggerCSS,
49
+ color: activeTab !== SIDE_PANE_OPTIONS.CHAT ? '$on_surface_low' : '$on_surface_high',
50
+ }}
51
+ >
52
+ Chat
53
+ </Tabs.Trigger>
54
+ <Tabs.Trigger
55
+ value={SIDE_PANE_OPTIONS.PARTICIPANTS}
56
+ onClick={toggleParticipants}
57
+ css={{
58
+ ...tabTriggerCSS,
59
+ color: activeTab !== SIDE_PANE_OPTIONS.PARTICIPANTS ? '$on_surface_low' : '$on_surface_high',
60
+ }}
61
+ >
62
+ Participants ({peerCount})
63
+ </Tabs.Trigger>
64
+ </Tabs.List>
65
+ </Tabs.Root>
66
+ </Flex>
67
+ )}
57
68
  <IconButton
58
69
  css={{ ml: 'auto' }}
59
70
  onClick={e => {
@@ -9,16 +9,17 @@ export const useEmojiPickerStyles = showing => {
9
9
  const style = document.createElement('style');
10
10
  style.textContent = `
11
11
  #root {
12
- --em-rgb-color: var(--hms-ui-colors-on_primary_high);
12
+ --em-rgb-color: var(--hms-ui-colors-on_surface_high);
13
13
  --em-rgb-input: var(--hms-ui-colors-on_primary_high);
14
- --em-color-border: var(--hms-ui-colors-surface_default);
15
- --color-b: var(--hms-ui-colors-on_primary_high);
14
+ --em-color-border: var(--hms-ui-colors-surface_bright);
15
+ --color-b: var(--hms-ui-colors-on_surface_high);
16
16
  --rgb-background: transparent;
17
- color: var(--hms-ui-colors-on_primary_high);
17
+ color: var(--hms-ui-colors-on_surface_high);
18
18
  font-family: var(--hms-ui-fonts-sans);
19
19
  }
20
20
  .sticky {
21
21
  background-color: var(--hms-ui-colors-surface_bright);
22
+ margin-top: 0.5rem;
22
23
  }
23
24
  `;
24
25
  root?.appendChild(style);
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import { selectConnectionQualityByPeerID, useHMSStore } from '@100mslive/react-sdk';
3
3
  import { PoorConnectivityIcon } from '@100mslive/react-icons';
4
- import { styled, Tooltip, useTheme } from '../../../';
4
+ import { styled, Tooltip, useTheme } from '../../..';
5
+ // @ts-ignore
5
6
  import { getColor, getTooltipText } from './connectionQualityUtils';
6
7
 
7
8
  const Wrapper = styled('span', {
@@ -10,7 +11,6 @@ const Wrapper = styled('span', {
10
11
  display: 'flex',
11
12
  alignItems: 'center',
12
13
  justifyContent: 'center',
13
- backgroundColor: '$background_dim',
14
14
  borderRadius: '$round',
15
15
  variants: {
16
16
  isTile: {
@@ -22,7 +22,15 @@ const Wrapper = styled('span', {
22
22
  },
23
23
  });
24
24
 
25
- export const ConnectionIndicator = ({ peerId, isTile = false }) => {
25
+ export const ConnectionIndicator = ({
26
+ peerId,
27
+ isTile = false,
28
+ hideBg = false,
29
+ }: {
30
+ peerId: string;
31
+ isTile?: boolean;
32
+ hideBg?: boolean;
33
+ }) => {
26
34
  const downlinkQuality = useHMSStore(selectConnectionQualityByPeerID(peerId))?.downlinkQuality;
27
35
  const { theme } = useTheme();
28
36
  const defaultColor = theme.colors.surface_brighter;
@@ -41,7 +49,7 @@ export const ConnectionIndicator = ({ peerId, isTile = false }) => {
41
49
  const size = isTile ? 12 : 16;
42
50
  return (
43
51
  <Tooltip title={getTooltipText(downlinkQuality)}>
44
- <Wrapper isTile={isTile} data-testid="tile_network">
52
+ <Wrapper isTile={isTile} data-testid="tile_network" css={{ backgroundColor: hideBg ? '' : '$surface_bright' }}>
45
53
  <svg
46
54
  width={size}
47
55
  height={size}
@@ -1,9 +1,23 @@
1
1
  import React from 'react';
2
2
  import { PinIcon, SpotlightIcon } from '@100mslive/react-icons';
3
- import { Flex, styled, Text, textEllipsis } from '../../../';
3
+ import { Flex, styled, Text, textEllipsis } from '../../..';
4
4
  import { ConnectionIndicator } from './ConnectionIndicator';
5
5
 
6
- const TileConnection = ({ name, peerId, hideLabel, width, spotlighted, pinned }) => {
6
+ const TileConnection = ({
7
+ name,
8
+ peerId,
9
+ hideLabel,
10
+ width,
11
+ spotlighted,
12
+ pinned,
13
+ }: {
14
+ name: string;
15
+ peerId: string;
16
+ hideLabel: boolean;
17
+ width?: number;
18
+ spotlighted?: boolean;
19
+ pinned?: boolean;
20
+ }) => {
7
21
  return (
8
22
  <Wrapper>
9
23
  {!hideLabel ? (
@@ -11,26 +25,26 @@ const TileConnection = ({ name, peerId, hideLabel, width, spotlighted, pinned })
11
25
  <Flex align="center">
12
26
  {pinned && (
13
27
  <IconWrapper>
14
- <PinIcon width="15" height="15" css={{ display: 'block' }} />
28
+ <PinIcon width="15" height="15" />
15
29
  </IconWrapper>
16
30
  )}
17
31
  {spotlighted && (
18
32
  <IconWrapper>
19
- <SpotlightIcon width="15" height="15" css={{ display: 'block' }} />
33
+ <SpotlightIcon width="15" height="15" />
20
34
  </IconWrapper>
21
35
  )}
22
36
  <Text
23
37
  css={{
24
38
  c: '$on_surface_high',
25
39
  verticalAlign: 'baseline',
26
- ...textEllipsis(width - 60),
40
+ ...(width ? textEllipsis(width - 60) : {}),
27
41
  }}
28
42
  variant="xs"
29
43
  >
30
44
  {name}
31
45
  </Text>
32
46
  </Flex>
33
- <ConnectionIndicator isTile peerId={peerId} />
47
+ <ConnectionIndicator isTile peerId={peerId} hideBg />
34
48
  </>
35
49
  ) : null}
36
50
  </Wrapper>
@@ -1,4 +1,4 @@
1
- import React, { Fragment, useCallback, useState } from 'react';
1
+ import React, { Fragment, useState } from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import data from '@emoji-mart/data/sets/14/apple.json';
4
4
  import { init } from 'emoji-mart';
@@ -34,13 +34,8 @@ export const EmojiReaction = () => {
34
34
  // const { isStreamingOn } = useRecordingStreaming();
35
35
  const isMobile = useMedia(cssConfig.media.md);
36
36
 
37
- const onEmojiEvent = useCallback(data => {
38
- window.showFlyingEmoji(data?.emojiId, data?.senderId);
39
- }, []);
40
-
41
37
  const { sendEvent } = useCustomEvent({
42
38
  type: EMOJI_REACTION_TYPE,
43
- onEvent: onEmojiEvent,
44
39
  });
45
40
 
46
41
  const sendReaction = async emojiId => {
@@ -51,6 +46,7 @@ export const EmojiReaction = () => {
51
46
  };
52
47
  // TODO: RT find a way to figure out hls-viewer roles
53
48
  sendEvent(data, { roleNames: roles });
49
+ window.showFlyingEmoji?.({ emojiId, senderId: localPeerId });
54
50
  /* if (isStreamingOn) {
55
51
  try {
56
52
  await hmsActions.sendHLSTimedMetadata([
@@ -1,16 +1,26 @@
1
- import React from 'react';
1
+ import React, { useEffect } from 'react';
2
2
  import { selectUnreadHMSMessagesCount, useHMSStore } from '@100mslive/react-sdk';
3
3
  import { ChatIcon, ChatUnreadIcon } from '@100mslive/react-icons';
4
- import { Tooltip } from '../../../';
4
+ import { Tooltip } from '../../..';
5
+ // @ts-ignore: No implicit Any
5
6
  import IconButton from '../../IconButton';
7
+ // @ts-ignore: No implicit Any
6
8
  import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane';
9
+ // @ts-ignore: No implicit Any
7
10
  import { SIDE_PANE_OPTIONS } from '../../common/constants';
8
11
 
9
- export const ChatToggle = () => {
12
+ export const ChatToggle = ({ openByDefault }: { openByDefault: boolean }) => {
10
13
  const countUnreadMessages = useHMSStore(selectUnreadHMSMessagesCount);
11
14
  const isChatOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.CHAT);
12
15
  const toggleChat = useSidepaneToggle(SIDE_PANE_OPTIONS.CHAT);
13
16
 
17
+ useEffect(() => {
18
+ if (!isChatOpen && openByDefault) {
19
+ toggleChat();
20
+ }
21
+ // eslint-disable-next-line react-hooks/exhaustive-deps
22
+ }, [toggleChat, openByDefault]);
23
+
14
24
  return (
15
25
  <Tooltip key="chat" title={`${isChatOpen ? 'Close' : 'Open'} chat`}>
16
26
  <IconButton onClick={toggleChat} active={!isChatOpen} data-testid="chat_btn">
@@ -1,10 +1,12 @@
1
- import React from 'react';
1
+ import React, { Suspense } from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import {
4
4
  ConferencingScreen,
5
5
  DefaultConferencingScreen_Elements,
6
6
  HLSLiveStreamingScreen_Elements,
7
7
  } from '@100mslive/types-prebuilt';
8
+ import { Chat_ChatState } from '@100mslive/types-prebuilt/elements/chat';
9
+ import { selectIsLocalVideoEnabled, useHMSStore } from '@100mslive/react-sdk';
8
10
  import { config as cssConfig, Footer as AppFooter } from '../../..';
9
11
  // @ts-ignore: No implicit Any
10
12
  import { AudioVideoToggle } from '../AudioVideoToggle';
@@ -22,6 +24,8 @@ import { ScreenshareToggle } from '../ScreenShareToggle';
22
24
  import { ChatToggle } from './ChatToggle';
23
25
  // @ts-ignore: No implicit Any
24
26
  import { ParticipantCount } from './ParticipantList';
27
+ // @ts-ignore: No implicit Any
28
+ const VirtualBackground = React.lazy(() => import('../../plugins/VirtualBackground/VirtualBackground'));
25
29
 
26
30
  export const Footer = ({
27
31
  screenType,
@@ -31,6 +35,9 @@ export const Footer = ({
31
35
  elements: DefaultConferencingScreen_Elements | HLSLiveStreamingScreen_Elements;
32
36
  }) => {
33
37
  const isMobile = useMedia(cssConfig.media.md);
38
+ const isOverlayChat = !!elements?.chat?.is_overlay;
39
+ const openByDefault = elements?.chat?.initial_state === Chat_ChatState.CHAT_STATE_OPEN;
40
+ const isVideoOn = useHMSStore(selectIsLocalVideoEnabled);
34
41
 
35
42
  return (
36
43
  <AppFooter.Root
@@ -40,7 +47,8 @@ export const Footer = ({
40
47
  justifyContent: 'center',
41
48
  gap: '$10',
42
49
  position: 'relative',
43
- zIndex: 20,
50
+ // To prevent it from showing over the sidepane if chat type is not overlay
51
+ zIndex: isOverlayChat ? 20 : 1,
44
52
  },
45
53
  }}
46
54
  >
@@ -55,6 +63,7 @@ export const Footer = ({
55
63
  >
56
64
  {isMobile ? <LeaveRoom screenType={screenType} /> : null}
57
65
  <AudioVideoToggle />
66
+ {isMobile ? null : <Suspense fallback={<></>}>{isVideoOn ? <VirtualBackground /> : null}</Suspense>}
58
67
  </AppFooter.Left>
59
68
  <AppFooter.Center
60
69
  css={{
@@ -67,21 +76,21 @@ export const Footer = ({
67
76
  {isMobile ? (
68
77
  <>
69
78
  {screenType === 'hls_live_streaming' ? <RaiseHand /> : null}
70
- {elements?.chat && <ChatToggle />}
79
+ {elements?.chat && <ChatToggle openByDefault={openByDefault} />}
71
80
  <MoreSettings elements={elements} screenType={screenType} />
72
81
  </>
73
82
  ) : (
74
83
  <>
75
84
  <ScreenshareToggle />
76
- {screenType === 'hls_live_streaming' ? <RaiseHand /> : null}
85
+ <RaiseHand />
77
86
  {elements?.emoji_reactions && <EmojiReaction />}
78
87
  <LeaveRoom screenType={screenType} />
79
88
  </>
80
89
  )}
81
90
  </AppFooter.Center>
82
91
  <AppFooter.Right>
83
- {elements?.chat && <ChatToggle />}
84
- <ParticipantCount />
92
+ {!isMobile && elements?.chat && <ChatToggle openByDefault={openByDefault} />}
93
+ {elements?.participant_list && <ParticipantCount />}
85
94
  <MoreSettings elements={elements} screenType={screenType} />
86
95
  </AppFooter.Right>
87
96
  </AppFooter.Root>
@@ -21,12 +21,11 @@ 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 { useRoomLayout } from '../../provider/roomLayoutProvider';
25
24
  import { ChatParticipantHeader } from '../Chat/ChatParticipantHeader';
26
25
  import { ConnectionIndicator } from '../Connection/ConnectionIndicator';
27
- import { RoleChangeModal } from '../RoleChangeModal';
28
26
  import { ToastManager } from '../Toast/ToastManager';
29
27
  import { RoleAccordion } from './RoleAccordion';
28
+ import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
30
29
  import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane';
31
30
  import { useParticipants } from '../../common/hooks';
32
31
  import { isInternalRole } from '../../common/utils';
@@ -46,7 +45,6 @@ export const ParticipantList = () => {
46
45
  peersOrderedByRoles[participant.roleName].push(participant);
47
46
  });
48
47
 
49
- const [selectedPeerId, setSelectedPeerId] = useState(null);
50
48
  const onSearch = useCallback(value => {
51
49
  setFilter(filterValue => {
52
50
  if (!filterValue) {
@@ -75,16 +73,7 @@ export const ParticipantList = () => {
75
73
  handRaisedList={handRaisedPeers}
76
74
  isConnected={isConnected}
77
75
  filter={filter}
78
- setSelectedPeerId={setSelectedPeerId}
79
76
  />
80
- {selectedPeerId && (
81
- <RoleChangeModal
82
- peerId={selectedPeerId}
83
- onOpenChange={value => {
84
- !value && setSelectedPeerId(null);
85
- }}
86
- />
87
- )}
88
77
  </Flex>
89
78
  </Fragment>
90
79
  );
@@ -126,13 +115,7 @@ export const ParticipantCount = () => {
126
115
  );
127
116
  };
128
117
 
129
- const VirtualizedParticipants = ({
130
- peersOrderedByRoles = {},
131
- isConnected,
132
- setSelectedPeerId,
133
- filter,
134
- handRaisedList = [],
135
- }) => {
118
+ const VirtualizedParticipants = ({ peersOrderedByRoles = {}, isConnected, filter, handRaisedList = [] }) => {
136
119
  return (
137
120
  <Flex
138
121
  direction="column"
@@ -149,7 +132,6 @@ const VirtualizedParticipants = ({
149
132
  roleName="Hand Raised"
150
133
  filter={filter}
151
134
  isConnected={isConnected}
152
- setSelectedPeerId={setSelectedPeerId}
153
135
  isHandRaisedAccordion
154
136
  />
155
137
  {Object.keys(peersOrderedByRoles).map(role => (
@@ -158,7 +140,6 @@ const VirtualizedParticipants = ({
158
140
  peerList={peersOrderedByRoles[role]}
159
141
  roleName={role}
160
142
  isConnected={isConnected}
161
- setSelectedPeerId={setSelectedPeerId}
162
143
  filter={filter}
163
144
  />
164
145
  ))}
@@ -166,7 +147,7 @@ const VirtualizedParticipants = ({
166
147
  );
167
148
  };
168
149
 
169
- export const Participant = ({ peer, isConnected, setSelectedPeerId }) => {
150
+ export const Participant = ({ peer, isConnected }) => {
170
151
  const localPeerId = useHMSStore(selectLocalPeerID);
171
152
  return (
172
153
  <Flex
@@ -186,14 +167,7 @@ export const Participant = ({ peer, isConnected, setSelectedPeerId }) => {
186
167
  {peer.name} {localPeerId === peer.id ? '(You)' : ''}
187
168
  </Text>
188
169
  {isConnected ? (
189
- <ParticipantActions
190
- peerId={peer.id}
191
- isLocal={peer.id === localPeerId}
192
- role={peer.roleName}
193
- onSettings={() => {
194
- setSelectedPeerId(peer.id);
195
- }}
196
- />
170
+ <ParticipantActions peerId={peer.id} isLocal={peer.id === localPeerId} role={peer.roleName} />
197
171
  ) : null}
198
172
  </Flex>
199
173
  );
@@ -202,7 +176,7 @@ export const Participant = ({ peer, isConnected, setSelectedPeerId }) => {
202
176
  /**
203
177
  * shows settings to change for a participant like changing their role
204
178
  */
205
- const ParticipantActions = React.memo(({ onSettings, peerId, role, isLocal }) => {
179
+ const ParticipantActions = React.memo(({ peerId, role, isLocal }) => {
206
180
  const isHandRaised = useHMSStore(selectPeerMetadata(peerId))?.isHandRaised;
207
181
  const canChangeRole = useHMSStore(selectPermissions)?.changeRole;
208
182
  const shouldShowMoreActions = canChangeRole;
@@ -214,7 +188,6 @@ const ParticipantActions = React.memo(({ onSettings, peerId, role, isLocal }) =>
214
188
  css={{
215
189
  flexShrink: 0,
216
190
  gap: '$8',
217
- mt: '$2',
218
191
  }}
219
192
  >
220
193
  <ConnectionIndicator peerId={peerId} />
@@ -238,24 +211,26 @@ const ParticipantActions = React.memo(({ onSettings, peerId, role, isLocal }) =>
238
211
  ) : null}
239
212
 
240
213
  {shouldShowMoreActions && !isInternalRole(role) && !isLocal ? (
241
- <ParticipantMoreActions onRoleChange={onSettings} peerId={peerId} role={role} />
214
+ <ParticipantMoreActions peerId={peerId} role={role} />
242
215
  ) : null}
243
216
  </Flex>
244
217
  );
245
218
  });
246
219
 
247
- const ParticipantMoreActions = ({ onRoleChange, peerId, role }) => {
220
+ const ParticipantMoreActions = ({ peerId, role }) => {
248
221
  const hmsActions = useHMSActions();
249
222
  const { changeRole: canChangeRole, removeOthers: canRemoveOthers } = useHMSStore(selectPermissions);
250
- const layout = useRoomLayout();
223
+ const { elements } = useRoomLayoutConferencingScreen();
251
224
  const {
252
225
  bring_to_stage_label,
253
226
  remove_from_stage_label,
254
227
  on_stage_role,
255
228
  off_stage_roles = [],
256
- } = layout?.screens?.conferencing?.default?.elements.on_stage_exp || {};
257
- const canBringToStage = off_stage_roles.includes(role);
229
+ } = elements.on_stage_exp || {};
258
230
  const isInStage = role === on_stage_role;
231
+ const shouldShowStageRoleChange =
232
+ canChangeRole &&
233
+ ((isInStage && remove_from_stage_label) || (off_stage_roles?.includes(role) && bring_to_stage_label));
259
234
  const prevRole = useHMSStore(selectPeerMetadata(peerId))?.prevRole;
260
235
  const localPeerId = useHMSStore(selectLocalPeerID);
261
236
  const isLocal = localPeerId === peerId;
@@ -263,7 +238,7 @@ const ParticipantMoreActions = ({ onRoleChange, peerId, role }) => {
263
238
 
264
239
  const handleStageAction = async () => {
265
240
  if (isInStage) {
266
- hmsActions.changeRoleOfPeer(peerId, prevRole || off_stage_roles[0]);
241
+ prevRole && hmsActions.changeRoleOfPeer(peerId, prevRole, true);
267
242
  } else {
268
243
  await hmsActions.changeRoleOfPeer(peerId, on_stage_role);
269
244
  }
@@ -296,21 +271,14 @@ const ParticipantMoreActions = ({ onRoleChange, peerId, role }) => {
296
271
  </Dropdown.Trigger>
297
272
  <Dropdown.Portal>
298
273
  <Dropdown.Content align="end" sideOffset={8} css={{ w: '$64', bg: '$surface_default' }}>
299
- {canChangeRole && canBringToStage ? (
274
+ {shouldShowStageRoleChange ? (
300
275
  <Dropdown.Item css={{ bg: '$surface_default' }} onClick={() => handleStageAction()}>
301
276
  <ChangeRoleIcon />
302
277
  <Text variant="sm" css={{ ml: '$4', fontWeight: '$semiBold', c: '$on_surface_high' }}>
303
278
  {isInStage ? remove_from_stage_label : bring_to_stage_label}
304
279
  </Text>
305
280
  </Dropdown.Item>
306
- ) : (
307
- <Dropdown.Item css={{ bg: '$surface_default' }} onClick={() => onRoleChange(peerId)}>
308
- <ChangeRoleIcon />
309
- <Text variant="sm" css={{ ml: '$4', fontWeight: '$semiBold', c: '$on_surface_high' }}>
310
- Change Role
311
- </Text>
312
- </Dropdown.Item>
313
- )}
281
+ ) : null}
314
282
 
315
283
  {!isLocal && canRemoveOthers && (
316
284
  <Dropdown.Item