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

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 (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}