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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. package/dist/{HLSView-PY2FKWX3.js → HLSView-QMU5JK7U.js} +208 -118
  2. package/dist/HLSView-QMU5JK7U.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 +2 -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/SidePaneTabs.d.ts +7 -0
  22. package/dist/Prebuilt/components/VideoLayouts/EqualProminence.d.ts +1 -1
  23. package/dist/Prebuilt/components/VideoLayouts/Grid.d.ts +1 -0
  24. package/dist/Prebuilt/components/VideoLayouts/GridLayout.d.ts +5 -3
  25. package/dist/Prebuilt/components/VideoLayouts/ProminenceLayout.d.ts +6 -3
  26. package/dist/Prebuilt/components/VideoLayouts/RoleProminence.d.ts +1 -1
  27. package/dist/Prebuilt/components/VideoLayouts/ScreenshareLayout.d.ts +1 -1
  28. package/dist/Prebuilt/components/VideoLayouts/interface.d.ts +1 -0
  29. package/dist/Prebuilt/components/hooks/useAutoStartStreaming.d.ts +1 -0
  30. package/dist/Prebuilt/components/hooks/useRedirectToLeave.d.ts +3 -0
  31. package/dist/Prebuilt/components/hooks/useTileLayout.d.ts +2 -1
  32. package/dist/Prebuilt/components/hooks/useVideoTileLayout.d.ts +2 -0
  33. package/dist/Prebuilt/layouts/SidePane.d.ts +4 -1
  34. package/dist/Prebuilt/layouts/VideoStreamingSection.d.ts +2 -1
  35. package/dist/{VirtualBackground-AYDHYLIZ.js → VirtualBackground-37FXUPYO.js} +6 -6
  36. package/dist/VirtualBackground-37FXUPYO.js.map +7 -0
  37. package/dist/{chunk-GQD2AGWW.js → chunk-KBVIZGYW.js} +12 -2
  38. package/dist/{chunk-GQD2AGWW.js.map → chunk-KBVIZGYW.js.map} +2 -2
  39. package/dist/{chunk-RXTHJUMZ.js → chunk-WVGGQZK4.js} +986 -436
  40. package/dist/chunk-WVGGQZK4.js.map +7 -0
  41. package/dist/{chunk-E2M2ZSOL.js → chunk-ZKE2N5LH.js} +2 -2
  42. package/dist/{conference-V2XZGTKU.js → conference-FJJQ4TXX.js} +1136 -1301
  43. package/dist/conference-FJJQ4TXX.js.map +7 -0
  44. package/dist/index.cjs.js +3565 -3092
  45. package/dist/index.cjs.js.map +4 -4
  46. package/dist/index.js +2 -2
  47. package/dist/meta.cjs.json +773 -525
  48. package/dist/meta.esbuild.json +833 -579
  49. package/package.json +8 -7
  50. package/src/Prebuilt/App.tsx +10 -21
  51. package/src/Prebuilt/AppContext.tsx +1 -1
  52. package/src/Prebuilt/IconButton.jsx +10 -0
  53. package/src/Prebuilt/common/PeersSorter.ts +1 -1
  54. package/src/Prebuilt/common/constants.js +1 -2
  55. package/src/Prebuilt/common/utils.js +1 -1
  56. package/src/Prebuilt/components/AppData/AppData.jsx +8 -2
  57. package/src/Prebuilt/components/AppData/useUISettings.js +6 -6
  58. package/src/Prebuilt/components/AudioVideoToggle.jsx +8 -6
  59. package/src/Prebuilt/components/Chat/Chat.jsx +24 -11
  60. package/src/Prebuilt/components/Chat/ChatBody.jsx +20 -21
  61. package/src/Prebuilt/components/Chat/{ChatFooter.jsx → ChatFooter.tsx} +38 -13
  62. package/src/Prebuilt/components/Chat/useEmojiPickerStyles.js +5 -4
  63. package/src/Prebuilt/components/Connection/{ConnectionIndicator.jsx → ConnectionIndicator.tsx} +12 -4
  64. package/src/Prebuilt/components/Connection/{TileConnection.jsx → TileConnection.tsx} +20 -6
  65. package/src/Prebuilt/components/EmojiReaction.jsx +2 -6
  66. package/src/Prebuilt/components/Footer/{ChatToggle.jsx → ChatToggle.tsx} +4 -1
  67. package/src/Prebuilt/components/Footer/Footer.tsx +30 -5
  68. package/src/Prebuilt/components/Footer/ParticipantList.jsx +15 -49
  69. package/src/Prebuilt/components/Footer/{RoleAccordion.jsx → RoleAccordion.tsx} +33 -17
  70. package/src/Prebuilt/components/Footer/RoleOptions.tsx +155 -0
  71. package/src/Prebuilt/components/FullPageProgress.jsx +3 -3
  72. package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -0
  73. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +39 -17
  74. package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +2 -2
  75. package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +5 -6
  76. package/src/Prebuilt/components/HMSVideo/VolumeControl.jsx +1 -1
  77. package/src/Prebuilt/components/Header/HeaderComponents.jsx +8 -1
  78. package/src/Prebuilt/components/Header/{StreamActions.jsx → StreamActions.tsx} +23 -9
  79. package/src/Prebuilt/components/Header/common.jsx +5 -2
  80. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +6 -1
  81. package/src/Prebuilt/components/InsetTile.tsx +15 -8
  82. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +21 -11
  83. package/src/Prebuilt/components/Leave/EndSessionContent.tsx +2 -5
  84. package/src/Prebuilt/components/Leave/LeaveCard.tsx +1 -3
  85. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +28 -25
  86. package/src/Prebuilt/components/Leave/LeaveSessionContent.tsx +8 -2
  87. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +8 -8
  88. package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +4 -0
  89. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +1 -1
  90. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +9 -23
  91. package/src/Prebuilt/components/MoreSettings/SplitComponents/{MwebOptions.jsx → MwebOptions.tsx} +89 -28
  92. package/src/Prebuilt/components/Notifications/Notifications.jsx +44 -28
  93. package/src/Prebuilt/components/Notifications/ReconnectNotifications.jsx +5 -11
  94. package/src/Prebuilt/components/Pagination.tsx +14 -12
  95. package/src/Prebuilt/components/Preview/{PreviewContainer.jsx → PreviewContainer.tsx} +11 -2
  96. package/src/Prebuilt/components/Preview/PreviewForm.tsx +6 -8
  97. package/src/Prebuilt/components/Preview/{PreviewJoin.jsx → PreviewJoin.tsx} +44 -21
  98. package/src/Prebuilt/components/{RoleChangeRequestModal.jsx → RoleChangeRequestModal.tsx} +36 -17
  99. package/src/Prebuilt/components/ScreenshareTile.jsx +6 -7
  100. package/src/Prebuilt/components/SecondaryTiles.tsx +12 -10
  101. package/src/Prebuilt/components/SidePaneTabs.tsx +120 -0
  102. package/src/Prebuilt/components/TileMenu/TileMenu.jsx +1 -1
  103. package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +14 -10
  104. package/src/Prebuilt/components/Toast/ToastConfig.jsx +5 -4
  105. package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +13 -10
  106. package/src/Prebuilt/components/VideoLayouts/Grid.tsx +36 -34
  107. package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +33 -15
  108. package/src/Prebuilt/components/VideoLayouts/ProminenceLayout.tsx +45 -31
  109. package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +12 -9
  110. package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +25 -9
  111. package/src/Prebuilt/components/VideoLayouts/interface.ts +1 -0
  112. package/src/Prebuilt/components/VideoTile.jsx +45 -53
  113. package/src/Prebuilt/components/conference.jsx +71 -74
  114. package/src/Prebuilt/components/hooks/useAutoStartStreaming.tsx +57 -0
  115. package/src/Prebuilt/components/hooks/useMetadata.jsx +19 -28
  116. package/src/Prebuilt/components/hooks/useRedirectToLeave.tsx +34 -0
  117. package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +1 -1
  118. package/src/Prebuilt/components/hooks/useTileLayout.tsx +24 -18
  119. package/src/Prebuilt/components/hooks/useVideoTileLayout.ts +4 -0
  120. package/src/Prebuilt/layouts/EmbedView.jsx +1 -11
  121. package/src/Prebuilt/layouts/HLSView.jsx +152 -82
  122. package/src/Prebuilt/layouts/SidePane.tsx +25 -11
  123. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +11 -47
  124. package/src/Prebuilt/plugins/FlyingEmoji.jsx +14 -2
  125. package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +3 -3
  126. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.ts +2 -2
  127. package/src/Prebuilt/services/FeatureFlags.jsx +0 -1
  128. package/src/VideoTile/StyledVideoTile.tsx +1 -0
  129. package/dist/HLSView-PY2FKWX3.js.map +0 -7
  130. package/dist/VirtualBackground-AYDHYLIZ.js.map +0 -7
  131. package/dist/chunk-RXTHJUMZ.js.map +0 -7
  132. package/dist/conference-V2XZGTKU.js.map +0 -7
  133. package/src/Prebuilt/components/AudioLevel/BeamSpeakerLabelsLogging.jsx +0 -16
  134. package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +0 -73
  135. package/src/Prebuilt/components/VideoList.jsx +0 -73
  136. /package/dist/{chunk-E2M2ZSOL.js.map → chunk-ZKE2N5LH.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
  >
@@ -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,9 +1,12 @@
1
1
  import React 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
12
  export const ChatToggle = () => {
@@ -1,10 +1,11 @@
1
- import React from 'react';
1
+ import React, { Suspense, useEffect } 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';
8
9
  import { config as cssConfig, Footer as AppFooter } from '../../..';
9
10
  // @ts-ignore: No implicit Any
10
11
  import { AudioVideoToggle } from '../AudioVideoToggle';
@@ -22,6 +23,12 @@ import { ScreenshareToggle } from '../ScreenShareToggle';
22
23
  import { ChatToggle } from './ChatToggle';
23
24
  // @ts-ignore: No implicit Any
24
25
  import { ParticipantCount } from './ParticipantList';
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
31
+ const VirtualBackground = React.lazy(() => import('../../plugins/VirtualBackground/VirtualBackground'));
25
32
 
26
33
  export const Footer = ({
27
34
  screenType,
@@ -31,6 +38,18 @@ export const Footer = ({
31
38
  elements: DefaultConferencingScreen_Elements | HLSLiveStreamingScreen_Elements;
32
39
  }) => {
33
40
  const isMobile = useMedia(cssConfig.media.md);
41
+ const isOverlayChat = !!elements?.chat?.is_overlay;
42
+ const openByDefault = elements?.chat?.initial_state === Chat_ChatState.CHAT_STATE_OPEN;
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]);
34
53
 
35
54
  return (
36
55
  <AppFooter.Root
@@ -40,7 +59,8 @@ export const Footer = ({
40
59
  justifyContent: 'center',
41
60
  gap: '$10',
42
61
  position: 'relative',
43
- zIndex: 20,
62
+ // To prevent it from showing over the sidepane if chat type is not overlay
63
+ zIndex: isOverlayChat ? 20 : 1,
44
64
  },
45
65
  }}
46
66
  >
@@ -55,6 +75,11 @@ export const Footer = ({
55
75
  >
56
76
  {isMobile ? <LeaveRoom screenType={screenType} /> : null}
57
77
  <AudioVideoToggle />
78
+ {isMobile ? null : (
79
+ <Suspense fallback={<></>}>
80
+ <VirtualBackground />
81
+ </Suspense>
82
+ )}
58
83
  </AppFooter.Left>
59
84
  <AppFooter.Center
60
85
  css={{
@@ -73,15 +98,15 @@ export const Footer = ({
73
98
  ) : (
74
99
  <>
75
100
  <ScreenshareToggle />
76
- {screenType === 'hls_live_streaming' ? <RaiseHand /> : null}
101
+ <RaiseHand />
77
102
  {elements?.emoji_reactions && <EmojiReaction />}
78
103
  <LeaveRoom screenType={screenType} />
79
104
  </>
80
105
  )}
81
106
  </AppFooter.Center>
82
107
  <AppFooter.Right>
83
- {elements?.chat && <ChatToggle />}
84
- <ParticipantCount />
108
+ {!isMobile && elements?.chat && <ChatToggle />}
109
+ {elements?.participant_list && <ParticipantCount />}
85
110
  <MoreSettings elements={elements} screenType={screenType} />
86
111
  </AppFooter.Right>
87
112
  </AppFooter.Root>
@@ -21,12 +21,10 @@ 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
- import { ChatParticipantHeader } from '../Chat/ChatParticipantHeader';
26
24
  import { ConnectionIndicator } from '../Connection/ConnectionIndicator';
27
- import { RoleChangeModal } from '../RoleChangeModal';
28
25
  import { ToastManager } from '../Toast/ToastManager';
29
26
  import { RoleAccordion } from './RoleAccordion';
27
+ import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
30
28
  import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane';
31
29
  import { useParticipants } from '../../common/hooks';
32
30
  import { isInternalRole } from '../../common/utils';
@@ -46,7 +44,6 @@ export const ParticipantList = () => {
46
44
  peersOrderedByRoles[participant.roleName].push(participant);
47
45
  });
48
46
 
49
- const [selectedPeerId, setSelectedPeerId] = useState(null);
50
47
  const onSearch = useCallback(value => {
51
48
  setFilter(filterValue => {
52
49
  if (!filterValue) {
@@ -63,7 +60,6 @@ export const ParticipantList = () => {
63
60
  return (
64
61
  <Fragment>
65
62
  <Flex direction="column" css={{ size: '100%', gap: '$4' }}>
66
- <ChatParticipantHeader activeTabValue={SIDE_PANE_OPTIONS.PARTICIPANTS} />
67
63
  {!filter?.search && participants.length === 0 ? null : <ParticipantSearch onSearch={onSearch} inSidePane />}
68
64
  {participants.length === 0 ? (
69
65
  <Flex align="center" justify="center" css={{ w: '100%', p: '$8 0' }}>
@@ -75,16 +71,7 @@ export const ParticipantList = () => {
75
71
  handRaisedList={handRaisedPeers}
76
72
  isConnected={isConnected}
77
73
  filter={filter}
78
- setSelectedPeerId={setSelectedPeerId}
79
74
  />
80
- {selectedPeerId && (
81
- <RoleChangeModal
82
- peerId={selectedPeerId}
83
- onOpenChange={value => {
84
- !value && setSelectedPeerId(null);
85
- }}
86
- />
87
- )}
88
75
  </Flex>
89
76
  </Fragment>
90
77
  );
@@ -126,13 +113,7 @@ export const ParticipantCount = () => {
126
113
  );
127
114
  };
128
115
 
129
- const VirtualizedParticipants = ({
130
- peersOrderedByRoles = {},
131
- isConnected,
132
- setSelectedPeerId,
133
- filter,
134
- handRaisedList = [],
135
- }) => {
116
+ const VirtualizedParticipants = ({ peersOrderedByRoles = {}, isConnected, filter, handRaisedList = [] }) => {
136
117
  return (
137
118
  <Flex
138
119
  direction="column"
@@ -149,7 +130,6 @@ const VirtualizedParticipants = ({
149
130
  roleName="Hand Raised"
150
131
  filter={filter}
151
132
  isConnected={isConnected}
152
- setSelectedPeerId={setSelectedPeerId}
153
133
  isHandRaisedAccordion
154
134
  />
155
135
  {Object.keys(peersOrderedByRoles).map(role => (
@@ -158,7 +138,6 @@ const VirtualizedParticipants = ({
158
138
  peerList={peersOrderedByRoles[role]}
159
139
  roleName={role}
160
140
  isConnected={isConnected}
161
- setSelectedPeerId={setSelectedPeerId}
162
141
  filter={filter}
163
142
  />
164
143
  ))}
@@ -166,7 +145,7 @@ const VirtualizedParticipants = ({
166
145
  );
167
146
  };
168
147
 
169
- export const Participant = ({ peer, isConnected, setSelectedPeerId }) => {
148
+ export const Participant = ({ peer, isConnected }) => {
170
149
  const localPeerId = useHMSStore(selectLocalPeerID);
171
150
  return (
172
151
  <Flex
@@ -186,14 +165,7 @@ export const Participant = ({ peer, isConnected, setSelectedPeerId }) => {
186
165
  {peer.name} {localPeerId === peer.id ? '(You)' : ''}
187
166
  </Text>
188
167
  {isConnected ? (
189
- <ParticipantActions
190
- peerId={peer.id}
191
- isLocal={peer.id === localPeerId}
192
- role={peer.roleName}
193
- onSettings={() => {
194
- setSelectedPeerId(peer.id);
195
- }}
196
- />
168
+ <ParticipantActions peerId={peer.id} isLocal={peer.id === localPeerId} role={peer.roleName} />
197
169
  ) : null}
198
170
  </Flex>
199
171
  );
@@ -202,7 +174,7 @@ export const Participant = ({ peer, isConnected, setSelectedPeerId }) => {
202
174
  /**
203
175
  * shows settings to change for a participant like changing their role
204
176
  */
205
- const ParticipantActions = React.memo(({ onSettings, peerId, role, isLocal }) => {
177
+ const ParticipantActions = React.memo(({ peerId, role, isLocal }) => {
206
178
  const isHandRaised = useHMSStore(selectPeerMetadata(peerId))?.isHandRaised;
207
179
  const canChangeRole = useHMSStore(selectPermissions)?.changeRole;
208
180
  const shouldShowMoreActions = canChangeRole;
@@ -214,7 +186,6 @@ const ParticipantActions = React.memo(({ onSettings, peerId, role, isLocal }) =>
214
186
  css={{
215
187
  flexShrink: 0,
216
188
  gap: '$8',
217
- mt: '$2',
218
189
  }}
219
190
  >
220
191
  <ConnectionIndicator peerId={peerId} />
@@ -238,24 +209,26 @@ const ParticipantActions = React.memo(({ onSettings, peerId, role, isLocal }) =>
238
209
  ) : null}
239
210
 
240
211
  {shouldShowMoreActions && !isInternalRole(role) && !isLocal ? (
241
- <ParticipantMoreActions onRoleChange={onSettings} peerId={peerId} role={role} />
212
+ <ParticipantMoreActions peerId={peerId} role={role} />
242
213
  ) : null}
243
214
  </Flex>
244
215
  );
245
216
  });
246
217
 
247
- const ParticipantMoreActions = ({ onRoleChange, peerId, role }) => {
218
+ const ParticipantMoreActions = ({ peerId, role }) => {
248
219
  const hmsActions = useHMSActions();
249
220
  const { changeRole: canChangeRole, removeOthers: canRemoveOthers } = useHMSStore(selectPermissions);
250
- const layout = useRoomLayout();
221
+ const { elements } = useRoomLayoutConferencingScreen();
251
222
  const {
252
223
  bring_to_stage_label,
253
224
  remove_from_stage_label,
254
225
  on_stage_role,
255
226
  off_stage_roles = [],
256
- } = layout?.screens?.conferencing?.default?.elements.on_stage_exp || {};
257
- const canBringToStage = off_stage_roles.includes(role);
227
+ } = elements.on_stage_exp || {};
258
228
  const isInStage = role === on_stage_role;
229
+ const shouldShowStageRoleChange =
230
+ canChangeRole &&
231
+ ((isInStage && remove_from_stage_label) || (off_stage_roles?.includes(role) && bring_to_stage_label));
259
232
  const prevRole = useHMSStore(selectPeerMetadata(peerId))?.prevRole;
260
233
  const localPeerId = useHMSStore(selectLocalPeerID);
261
234
  const isLocal = localPeerId === peerId;
@@ -263,7 +236,7 @@ const ParticipantMoreActions = ({ onRoleChange, peerId, role }) => {
263
236
 
264
237
  const handleStageAction = async () => {
265
238
  if (isInStage) {
266
- hmsActions.changeRoleOfPeer(peerId, prevRole || off_stage_roles[0]);
239
+ prevRole && hmsActions.changeRoleOfPeer(peerId, prevRole, true);
267
240
  } else {
268
241
  await hmsActions.changeRoleOfPeer(peerId, on_stage_role);
269
242
  }
@@ -296,21 +269,14 @@ const ParticipantMoreActions = ({ onRoleChange, peerId, role }) => {
296
269
  </Dropdown.Trigger>
297
270
  <Dropdown.Portal>
298
271
  <Dropdown.Content align="end" sideOffset={8} css={{ w: '$64', bg: '$surface_default' }}>
299
- {canChangeRole && canBringToStage ? (
272
+ {shouldShowStageRoleChange ? (
300
273
  <Dropdown.Item css={{ bg: '$surface_default' }} onClick={() => handleStageAction()}>
301
274
  <ChangeRoleIcon />
302
275
  <Text variant="sm" css={{ ml: '$4', fontWeight: '$semiBold', c: '$on_surface_high' }}>
303
276
  {isInStage ? remove_from_stage_label : bring_to_stage_label}
304
277
  </Text>
305
278
  </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
- )}
279
+ ) : null}
314
280
 
315
281
  {!isLocal && canRemoveOthers && (
316
282
  <Dropdown.Item
@@ -1,53 +1,61 @@
1
1
  import React from 'react';
2
2
  import { useMeasure } from 'react-use';
3
3
  import { FixedSizeList } from 'react-window';
4
+ import { HMSPeer } from '@100mslive/react-sdk';
4
5
  import { Accordion } from '../../../Accordion';
5
6
  import { Box, Flex } from '../../../Layout';
7
+ import { Text } from '../../../Text';
8
+ // @ts-ignore: No implicit Any
6
9
  import { Participant } from './ParticipantList';
10
+ import { RoleOptions } from './RoleOptions';
11
+ // @ts-ignore: No implicit Any
7
12
  import { getFormattedCount } from '../../common/utils';
8
13
 
9
14
  const ROW_HEIGHT = 50;
10
15
 
11
- function itemKey(index, data) {
16
+ interface ItemData {
17
+ peerList: HMSPeer[];
18
+ isConnected: boolean;
19
+ }
20
+
21
+ function itemKey(index: number, data: ItemData) {
12
22
  return data.peerList[index].id;
13
23
  }
14
24
 
15
- const VirtualizedParticipantItem = React.memo(({ index, data }) => {
16
- return (
17
- <Participant
18
- key={data.peerList[index].id}
19
- peer={data.peerList[index]}
20
- isConnected={data.isConnected}
21
- setSelectedPeerId={data.setSelectedPeerId}
22
- />
23
- );
25
+ const VirtualizedParticipantItem = React.memo(({ index, data }: { index: number; data: ItemData }) => {
26
+ return <Participant key={data.peerList[index].id} peer={data.peerList[index]} isConnected={data.isConnected} />;
24
27
  });
25
28
 
26
29
  export const RoleAccordion = ({
27
30
  peerList = [],
28
31
  roleName,
29
- setSelectedPeerId,
30
32
  isConnected,
31
33
  filter,
32
34
  isHandRaisedAccordion = false,
35
+ }: ItemData & {
36
+ roleName: string;
37
+ isHandRaisedAccordion?: boolean;
38
+ filter?: { search: string };
33
39
  }) => {
34
- const [ref, { width }] = useMeasure();
35
- const height = ROW_HEIGHT * peerList.length;
40
+ const [ref, { width }] = useMeasure<HTMLDivElement>();
36
41
  const showAcordion = filter?.search ? peerList.some(peer => peer.name.toLowerCase().includes(filter.search)) : true;
42
+
37
43
  if (!showAcordion || (isHandRaisedAccordion && filter?.search) || peerList.length === 0) {
38
44
  return null;
39
45
  }
46
+ const height = ROW_HEIGHT * peerList.length;
40
47
 
41
48
  return (
42
- <Flex direction="column" css={{ flexGrow: 1 }} ref={ref}>
49
+ <Flex direction="column" css={{ flexGrow: 1, '&:hover .role_actions': { visibility: 'visible' } }} ref={ref}>
43
50
  <Accordion.Root
44
51
  type="single"
45
52
  collapsible
46
53
  defaultValue={roleName}
47
- css={{ borderRadius: '$3', border: '1px solid $border_bright' }}
54
+ css={{ borderRadius: '$1', border: '1px solid $border_bright' }}
48
55
  >
49
56
  <Accordion.Item value={roleName}>
50
57
  <Accordion.Header
58
+ iconStyles={{ c: '$on_surface_high' }}
51
59
  css={{
52
60
  textTransform: 'capitalize',
53
61
  p: '$6 $8',
@@ -56,13 +64,21 @@ export const RoleAccordion = ({
56
64
  c: '$on_surface_medium',
57
65
  }}
58
66
  >
59
- {roleName} {`(${getFormattedCount(peerList.length)})`}
67
+ <Flex justify="between" css={{ flexGrow: 1, pr: '$6' }}>
68
+ <Text
69
+ variant="sm"
70
+ css={{ fontWeight: '$semiBold', textTransform: 'capitalize', color: '$on_surface_medium' }}
71
+ >
72
+ {roleName} {`(${getFormattedCount(peerList.length)})`}
73
+ </Text>
74
+ <RoleOptions roleName={roleName} peerList={peerList} />
75
+ </Flex>
60
76
  </Accordion.Header>
61
77
  <Accordion.Content>
62
78
  <Box css={{ borderTop: '1px solid $border_default' }} />
63
79
  <FixedSizeList
64
80
  itemSize={ROW_HEIGHT}
65
- itemData={{ peerList, isConnected, setSelectedPeerId }}
81
+ itemData={{ peerList, isConnected }}
66
82
  itemKey={itemKey}
67
83
  itemCount={peerList.length}
68
84
  width={width}