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

Sign up to get free protection for your applications and to get access to all the features.
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