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

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 (197) hide show
  1. package/dist/{HLSView-CTAJQUU4.js → HLSView-PY2FKWX3.js} +191 -123
  2. package/dist/HLSView-PY2FKWX3.js.map +7 -0
  3. package/dist/Prebuilt/App.d.ts +3 -0
  4. package/dist/Prebuilt/AppContext.d.ts +13 -0
  5. package/dist/Prebuilt/common/PeersSorter.d.ts +21 -0
  6. package/dist/Prebuilt/components/Footer/Footer.d.ts +6 -0
  7. package/dist/Prebuilt/components/Header/Header.d.ts +2 -0
  8. package/dist/Prebuilt/components/InsetTile.d.ts +2 -0
  9. package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +7 -0
  10. package/dist/Prebuilt/components/Leave/EndSessionContent.d.ts +8 -0
  11. package/dist/Prebuilt/components/Leave/LeaveAtoms.d.ts +2196 -0
  12. package/dist/Prebuilt/components/Leave/LeaveCard.d.ts +12 -0
  13. package/dist/Prebuilt/components/Leave/LeaveRoom.d.ts +5 -0
  14. package/dist/Prebuilt/components/Leave/LeaveSessionContent.d.ts +6 -0
  15. package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +7 -0
  16. package/dist/Prebuilt/components/MoreSettings/MoreSettings.d.ts +6 -0
  17. package/dist/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.d.ts +6 -0
  18. package/dist/Prebuilt/components/Pagination.d.ts +6 -0
  19. package/dist/Prebuilt/components/Preview/PreviewForm.d.ts +10 -0
  20. package/dist/Prebuilt/components/SecondaryTiles.d.ts +3 -0
  21. package/dist/Prebuilt/components/VideoLayouts/EqualProminence.d.ts +3 -0
  22. package/dist/Prebuilt/components/VideoLayouts/Grid.d.ts +5 -0
  23. package/dist/Prebuilt/components/VideoLayouts/GridLayout.d.ts +10 -0
  24. package/dist/Prebuilt/components/VideoLayouts/ProminenceLayout.d.ts +12 -0
  25. package/dist/Prebuilt/components/VideoLayouts/RoleProminence.d.ts +3 -0
  26. package/dist/Prebuilt/components/VideoLayouts/ScreenshareLayout.d.ts +3 -0
  27. package/dist/Prebuilt/components/VideoLayouts/interface.d.ts +8 -0
  28. package/dist/Prebuilt/components/hooks/useRoleProminencePeers.d.ts +5 -0
  29. package/dist/Prebuilt/components/hooks/useTileLayout.d.ts +12 -0
  30. package/dist/Prebuilt/components/hooks/useVideoTileLayout.d.ts +11 -0
  31. package/dist/Prebuilt/layouts/SidePane.d.ts +6 -0
  32. package/dist/Prebuilt/layouts/VideoStreamingSection.d.ts +6 -0
  33. package/dist/Prebuilt/plugins/whiteboard/ToggleWhiteboard.d.ts +5 -0
  34. package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.d.ts +1 -0
  35. package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useInsetEnabled.d.ts +1 -0
  36. package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useRoomLayoutScreen.d.ts +17 -0
  37. package/dist/Prebuilt/provider/roomLayoutProvider/index.d.ts +6 -1
  38. package/dist/{VirtualBackground-GGGBJYVY.js → VirtualBackground-AYDHYLIZ.js} +5 -11
  39. package/dist/VirtualBackground-AYDHYLIZ.js.map +7 -0
  40. package/dist/{chunk-TJNDX446.js → chunk-E2M2ZSOL.js} +8 -5
  41. package/dist/chunk-E2M2ZSOL.js.map +7 -0
  42. package/dist/chunk-GQD2AGWW.js +888 -0
  43. package/dist/chunk-GQD2AGWW.js.map +7 -0
  44. package/dist/{chunk-L2SX7GBO.js → chunk-RXTHJUMZ.js} +2462 -4738
  45. package/dist/chunk-RXTHJUMZ.js.map +7 -0
  46. package/dist/conference-V2XZGTKU.js +5927 -0
  47. package/dist/conference-V2XZGTKU.js.map +7 -0
  48. package/dist/index.cjs.js +9414 -15534
  49. package/dist/index.cjs.js.map +4 -4
  50. package/dist/index.js +2 -2
  51. package/dist/meta.cjs.json +2156 -3347
  52. package/dist/meta.esbuild.json +2601 -3885
  53. package/package.json +7 -7
  54. package/src/Button/Button.tsx +2 -2
  55. package/src/Prebuilt/App.tsx +49 -33
  56. package/src/Prebuilt/{AppContext.jsx → AppContext.tsx} +11 -3
  57. package/src/Prebuilt/IconButton.jsx +1 -0
  58. package/src/Prebuilt/Prebuilt.stories.tsx +1 -0
  59. package/src/Prebuilt/common/{PeersSorter.js → PeersSorter.ts} +15 -10
  60. package/src/Prebuilt/common/constants.js +3 -112
  61. package/src/Prebuilt/common/hooks.js +34 -1
  62. package/src/Prebuilt/common/utils.js +0 -8
  63. package/src/Prebuilt/components/AppData/AppData.jsx +3 -13
  64. package/src/Prebuilt/components/AppData/useUISettings.js +0 -4
  65. package/src/Prebuilt/components/AudioVideoToggle.jsx +6 -0
  66. package/src/Prebuilt/components/AuthToken.jsx +11 -42
  67. package/src/Prebuilt/components/Chat/Chat.jsx +57 -26
  68. package/src/Prebuilt/components/Chat/ChatBody.jsx +92 -32
  69. package/src/Prebuilt/components/Chat/ChatFooter.jsx +72 -48
  70. package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +73 -0
  71. package/src/Prebuilt/components/Chat/ChatSelector.jsx +16 -17
  72. package/src/Prebuilt/components/Chat/ChatSelectorContainer.jsx +81 -0
  73. package/src/Prebuilt/components/Connection/TileConnection.jsx +30 -12
  74. package/src/Prebuilt/components/EmojiReaction.jsx +18 -17
  75. package/src/Prebuilt/components/Footer/ChatToggle.jsx +1 -7
  76. package/src/Prebuilt/components/Footer/Footer.tsx +89 -0
  77. package/src/Prebuilt/components/Footer/ParticipantList.jsx +213 -173
  78. package/src/Prebuilt/components/Footer/RoleAccordion.jsx +78 -0
  79. package/src/Prebuilt/components/HMSVideo/Controls.jsx +2 -2
  80. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +33 -10
  81. package/src/Prebuilt/components/HMSVideo/PlayButton.jsx +1 -1
  82. package/src/Prebuilt/components/HMSVideo/VideoTime.jsx +3 -3
  83. package/src/Prebuilt/components/HMSVideo/VolumeControl.jsx +38 -9
  84. package/src/Prebuilt/components/Header/{ConferencingHeader.jsx → Header.tsx} +9 -7
  85. package/src/Prebuilt/components/Header/HeaderComponents.jsx +13 -4
  86. package/src/Prebuilt/components/Header/StreamActions.jsx +33 -60
  87. package/src/Prebuilt/components/Header/index.tsx +1 -0
  88. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +17 -3
  89. package/src/Prebuilt/components/InsetTile.tsx +122 -0
  90. package/src/Prebuilt/components/{MoreSettings/SplitComponents/DesktopLeaveRoom.jsx → Leave/DesktopLeaveRoom.tsx} +50 -18
  91. package/src/Prebuilt/components/{EndSessionContent.jsx → Leave/EndSessionContent.tsx} +19 -9
  92. package/src/Prebuilt/components/Leave/LeaveAtoms.tsx +26 -0
  93. package/src/Prebuilt/components/{LeaveCard.jsx → Leave/LeaveCard.tsx} +22 -3
  94. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +63 -0
  95. package/src/Prebuilt/components/{LeaveSessionContent.jsx → Leave/LeaveSessionContent.tsx} +13 -5
  96. package/src/Prebuilt/components/{MoreSettings/SplitComponents/MwebLeaveRoom.jsx → Leave/MwebLeaveRoom.tsx} +38 -13
  97. package/src/Prebuilt/components/MetaActions.jsx +15 -23
  98. package/src/Prebuilt/components/MoreSettings/ActionTile.jsx +5 -0
  99. package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +12 -7
  100. package/src/Prebuilt/components/MoreSettings/ChangeNameModal.jsx +1 -1
  101. package/src/Prebuilt/components/MoreSettings/FullScreenItem.jsx +1 -4
  102. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +27 -0
  103. package/src/Prebuilt/components/MoreSettings/SplitComponents/{DesktopOptions.jsx → DesktopOptions.tsx} +86 -75
  104. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.jsx +20 -19
  105. package/src/Prebuilt/components/Notifications/HLSFailureModal.jsx +3 -1
  106. package/src/Prebuilt/components/Notifications/Notifications.jsx +18 -11
  107. package/src/Prebuilt/components/Notifications/PeerNotifications.jsx +14 -2
  108. package/src/Prebuilt/components/Notifications/PermissionErrorModal.jsx +10 -4
  109. package/src/Prebuilt/components/PIP/PIPComponent.jsx +7 -16
  110. package/src/Prebuilt/components/PIP/PIPManager.js +1 -0
  111. package/src/Prebuilt/components/{Pagination.jsx → Pagination.tsx} +35 -6
  112. package/src/Prebuilt/components/Playlist/Playlist.jsx +1 -6
  113. package/src/Prebuilt/components/PostLeave.jsx +7 -7
  114. package/src/Prebuilt/components/Preview/PreviewContainer.jsx +5 -13
  115. package/src/Prebuilt/components/Preview/{PreviewForm.jsx → PreviewForm.tsx} +14 -4
  116. package/src/Prebuilt/components/Preview/PreviewJoin.jsx +9 -7
  117. package/src/Prebuilt/components/RaiseHand.jsx +0 -7
  118. package/src/Prebuilt/components/RoleChangeRequestModal.jsx +82 -6
  119. package/src/Prebuilt/components/ScreenshareDisplay.jsx +4 -10
  120. package/src/Prebuilt/components/ScreenshareTile.jsx +41 -33
  121. package/src/Prebuilt/components/SecondaryTiles.tsx +34 -0
  122. package/src/Prebuilt/components/Settings/LayoutSettings.jsx +2 -12
  123. package/src/Prebuilt/components/Settings/NotificationSettings.jsx +3 -9
  124. package/src/Prebuilt/components/Settings/SettingsModal.jsx +3 -9
  125. package/src/Prebuilt/components/StatsForNerds.jsx +3 -1
  126. package/src/Prebuilt/components/TileMenu/TileMenu.jsx +15 -16
  127. package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +21 -19
  128. package/src/Prebuilt/components/Toast/ToastConfig.jsx +53 -11
  129. package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +62 -0
  130. package/src/Prebuilt/components/VideoLayouts/Grid.tsx +41 -0
  131. package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +92 -0
  132. package/src/Prebuilt/components/VideoLayouts/ProminenceLayout.tsx +60 -0
  133. package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +56 -0
  134. package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +36 -0
  135. package/src/Prebuilt/components/VideoLayouts/interface.ts +9 -0
  136. package/src/Prebuilt/components/VideoTile.jsx +93 -43
  137. package/src/Prebuilt/components/conference.jsx +24 -20
  138. package/src/Prebuilt/components/hooks/useMetadata.jsx +7 -0
  139. package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +38 -0
  140. package/src/Prebuilt/components/hooks/useTileLayout.tsx +121 -0
  141. package/src/Prebuilt/components/hooks/useVideoTileLayout.ts +22 -0
  142. package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +5 -72
  143. package/src/Prebuilt/components/pdfAnnotator/submitPdf.jsx +4 -45
  144. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +2 -17
  145. package/src/Prebuilt/components/peerTileUtils.jsx +1 -1
  146. package/src/Prebuilt/images/empty-chat.svg +12 -0
  147. package/src/Prebuilt/layouts/EmbedView.jsx +17 -40
  148. package/src/Prebuilt/layouts/HLSView.jsx +83 -66
  149. package/src/Prebuilt/layouts/PDFView.jsx +1 -11
  150. package/src/Prebuilt/layouts/SidePane.tsx +96 -0
  151. package/src/Prebuilt/layouts/{mainView.jsx → VideoStreamingSection.tsx} +38 -47
  152. package/src/Prebuilt/layouts/WhiteboardView.jsx +10 -34
  153. package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +1 -4
  154. package/src/Prebuilt/plugins/whiteboard/{ToggleWhiteboard.jsx → ToggleWhiteboard.tsx} +5 -9
  155. package/src/Prebuilt/primitives/DialogContent.jsx +15 -11
  156. package/src/Prebuilt/provider/roomLayoutProvider/constants/index.ts +17 -2
  157. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.ts +36 -13
  158. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useInsetEnabled.ts +10 -0
  159. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useRoomLayoutScreen.ts +65 -0
  160. package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +17 -6
  161. package/dist/HLSView-CTAJQUU4.js.map +0 -7
  162. package/dist/PinnedTrackView-CQKONH4O.js +0 -102
  163. package/dist/PinnedTrackView-CQKONH4O.js.map +0 -7
  164. package/dist/VirtualBackground-GGGBJYVY.js.map +0 -7
  165. package/dist/chunk-I2FJWE74.js +0 -827
  166. package/dist/chunk-I2FJWE74.js.map +0 -7
  167. package/dist/chunk-L2SX7GBO.js.map +0 -7
  168. package/dist/chunk-NOKIGB6Y.js +0 -1100
  169. package/dist/chunk-NOKIGB6Y.js.map +0 -7
  170. package/dist/chunk-TJNDX446.js.map +0 -7
  171. package/dist/conference-OEO7VOJD.js +0 -8995
  172. package/dist/conference-OEO7VOJD.js.map +0 -7
  173. package/src/Prebuilt/components/Chat/ChatHeader.jsx +0 -67
  174. package/src/Prebuilt/components/EqualProminence.jsx +0 -180
  175. package/src/Prebuilt/components/FirstPersonDisplay.jsx +0 -50
  176. package/src/Prebuilt/components/Footer/Footer.jsx +0 -73
  177. package/src/Prebuilt/components/Header/Header.jsx +0 -8
  178. package/src/Prebuilt/components/Header/StreamingHeader.jsx +0 -54
  179. package/src/Prebuilt/components/LeaveRoom.jsx +0 -94
  180. package/src/Prebuilt/components/MoreSettings/MoreSettings.jsx +0 -10
  181. package/src/Prebuilt/components/Notifications/MessageNotifications.jsx +0 -25
  182. package/src/Prebuilt/components/gridView.jsx +0 -85
  183. package/src/Prebuilt/components/hooks/useFeatures.js +0 -22
  184. package/src/Prebuilt/components/hooks/useNavigation.js +0 -19
  185. package/src/Prebuilt/components/hooks/useSkipPreview.jsx +0 -20
  186. package/src/Prebuilt/components/pdfAnnotator/pdfErrorView.jsx +0 -29
  187. package/src/Prebuilt/images/Logo.svg +0 -8
  188. package/src/Prebuilt/layouts/ActiveSpeakerView.jsx +0 -34
  189. package/src/Prebuilt/layouts/InsetView.jsx +0 -260
  190. package/src/Prebuilt/layouts/PinnedTrackView.jsx +0 -59
  191. package/src/Prebuilt/layouts/SidePane.jsx +0 -52
  192. package/src/Prebuilt/layouts/mainGridView.jsx +0 -98
  193. package/src/Prebuilt/layouts/screenShareView.jsx +0 -183
  194. /package/{src/Prebuilt/components/Header/index.jsx → dist/Prebuilt/components/Header/index.d.ts} +0 -0
  195. /package/src/Prebuilt/components/{ScreenShare.jsx → ScreenShareToggle.jsx} +0 -0
  196. /package/src/{assets → Prebuilt/images}/android-perm-1.png +0 -0
  197. /package/src/{assets → Prebuilt/images}/ios-perm-0.png +0 -0
@@ -1,4 +1,4 @@
1
- import React, { Fragment, useCallback, useMemo, useState } from 'react';
1
+ import React, { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import {
4
4
  selectAudioTrackByPeerID,
@@ -6,24 +6,25 @@ import {
6
6
  selectLocalPeerID,
7
7
  selectPeerMetadata,
8
8
  selectPeerNameByID,
9
+ selectSessionStore,
10
+ selectTrackAudioByID,
9
11
  selectVideoTrackByID,
10
12
  selectVideoTrackByPeerID,
11
13
  useHMSStore,
14
+ useHMSVanillaStore,
12
15
  } from '@100mslive/react-sdk';
13
16
  import { BrbTileIcon, HandIcon, MicOffIcon } from '@100mslive/react-icons';
14
17
  import TileConnection from './Connection/TileConnection';
15
- import TileMenu from './TileMenu/TileMenu';
16
- import { useBorderAudioLevel } from '../../AudioLevel';
18
+ import TileMenu, { isSameTile } from './TileMenu/TileMenu';
17
19
  import { Avatar } from '../../Avatar';
20
+ import { Box, Flex } from '../../Layout';
18
21
  import { VideoTileStats } from '../../Stats';
19
- import { config as cssConfig } from '../../Theme';
22
+ import { config as cssConfig, keyframes } from '../../Theme';
20
23
  import { Video } from '../../Video';
21
24
  import { StyledVideoTile } from '../../VideoTile';
22
25
  import { getVideoTileLabel } from './peerTileUtils';
23
- import { useAppConfig } from './AppData/useAppConfig';
24
- import { useIsHeadless, useUISettings } from './AppData/useUISettings';
25
- import { useShowStreamingUI } from '../common/hooks';
26
- import { UI_SETTINGS } from '../common/constants';
26
+ import { useSetAppDataByKey, useUISettings } from './AppData/useUISettings';
27
+ import { APP_DATA, SESSION_STORE_KEY, UI_SETTINGS } from '../common/constants';
27
28
 
28
29
  const Tile = ({
29
30
  peerId,
@@ -35,6 +36,10 @@ const Tile = ({
35
36
  isDragabble = false,
36
37
  rootCSS = {},
37
38
  containerCSS = {},
39
+ enableSpotlightingPeer = true,
40
+ hideParticipantNameOnTile = false,
41
+ roundedVideoTile = true,
42
+ hideAudioMuteOnTile = false,
38
43
  }) => {
39
44
  const trackSelector = trackId ? selectVideoTrackByID(trackId) : selectVideoTrackByPeerID(peerId);
40
45
  const track = useHMSStore(trackSelector);
@@ -44,15 +49,18 @@ const Tile = ({
44
49
  const isAudioOnly = useUISettings(UI_SETTINGS.isAudioOnly);
45
50
  const mirrorLocalVideo = useUISettings(UI_SETTINGS.mirrorLocalVideo);
46
51
  const showStatsOnTiles = useUISettings(UI_SETTINGS.showStatsOnTiles);
47
- const isHeadless = useIsHeadless();
48
52
  const isAudioMuted = !useHMSStore(selectIsPeerAudioEnabled(peerId));
49
53
  const isVideoMuted = !track?.enabled;
50
54
  const [isMouseHovered, setIsMouseHovered] = useState(false);
51
- const borderAudioRef = useBorderAudioLevel(audioTrack?.id);
52
55
  const isVideoDegraded = track?.degraded;
53
56
  const isLocal = localPeerID === peerId;
54
- const isMobile = useMedia(cssConfig.media.md);
55
- const showStreamingUI = useShowStreamingUI();
57
+ const [pinnedTrackId] = useSetAppDataByKey(APP_DATA.pinnedTrackId);
58
+ const pinned = isSameTile({
59
+ trackId: pinnedTrackId,
60
+ videoTrackID: track?.id,
61
+ audioTrackID: audioTrack?.id,
62
+ });
63
+ const spotlighted = useHMSStore(selectSessionStore(SESSION_STORE_KEY.SPOTLIGHT)) === peerId;
56
64
  const label = getVideoTileLabel({
57
65
  peerName,
58
66
  track,
@@ -61,8 +69,6 @@ const Tile = ({
61
69
  const onHoverHandler = useCallback(event => {
62
70
  setIsMouseHovered(event.type === 'mouseenter');
63
71
  }, []);
64
- const headlessConfig = useAppConfig('headlessConfig');
65
- const hideLabel = isHeadless && headlessConfig?.hideTileName;
66
72
  const isTileBigEnoughToShowStats = height >= 180 && width >= 180;
67
73
  const avatarSize = useMemo(() => {
68
74
  if (!width || !height) {
@@ -75,17 +81,13 @@ const Tile = ({
75
81
  }
76
82
  return 'large';
77
83
  }, [width, height]);
84
+ const isMobile = useMedia(cssConfig.media.md);
78
85
 
79
86
  return (
80
87
  <StyledVideoTile.Root
81
88
  css={{
82
89
  width,
83
90
  height,
84
- padding: getPadding({
85
- isHeadless,
86
- tileOffset: headlessConfig?.tileOffset,
87
- hideAudioLevel: headlessConfig?.hideAudioLevel,
88
- }),
89
91
  ...rootCSS,
90
92
  }}
91
93
  data-testid={`participant_tile_${peerName}`}
@@ -94,8 +96,7 @@ const Tile = ({
94
96
  <StyledVideoTile.Container
95
97
  onMouseEnter={onHoverHandler}
96
98
  onMouseLeave={onHoverHandler}
97
- ref={isHeadless && headlessConfig?.hideAudioLevel ? undefined : borderAudioRef}
98
- noRadius={isHeadless && Number(headlessConfig?.tileOffset) === 0}
99
+ noRadius={!roundedVideoTile}
99
100
  css={containerCSS}
100
101
  >
101
102
  {showStatsOnTiles && isTileBigEnoughToShowStats ? (
@@ -112,23 +113,23 @@ const Tile = ({
112
113
  track?.source === 'regular' &&
113
114
  track?.facingMode !== 'environment'
114
115
  }
115
- degraded={isVideoDegraded}
116
- noRadius={isHeadless && Number(headlessConfig?.tileOffset) === 0}
116
+ noRadius={!roundedVideoTile}
117
117
  data-testid="participant_video_tile"
118
118
  css={{
119
119
  objectFit,
120
+ filter: isVideoDegraded ? 'blur($space$2)' : undefined,
121
+ bg: 'transparent',
120
122
  }}
121
123
  />
122
124
  ) : null}
123
- {isVideoMuted || isVideoDegraded || (!isLocal && isAudioOnly) ? (
125
+ {isVideoMuted || (!isLocal && isAudioOnly) ? (
124
126
  <StyledVideoTile.AvatarContainer>
125
127
  <Avatar name={peerName || ''} data-testid="participant_avatar_icon" size={avatarSize} />
126
128
  </StyledVideoTile.AvatarContainer>
127
129
  ) : null}
128
130
 
129
131
  {showAudioMuted({
130
- hideTileAudioMute: headlessConfig?.hideTileAudioMute,
131
- isHeadless,
132
+ hideAudioMute: hideAudioMuteOnTile,
132
133
  isAudioMuted,
133
134
  }) ? (
134
135
  <StyledVideoTile.AudioIndicator
@@ -137,18 +138,29 @@ const Tile = ({
137
138
  >
138
139
  <MicOffIcon />
139
140
  </StyledVideoTile.AudioIndicator>
140
- ) : null}
141
- {(isMouseHovered || isDragabble) && !isHeadless ? (
141
+ ) : (
142
+ <AudioLevel trackId={audioTrack?.id} />
143
+ )}
144
+ {isMouseHovered || isDragabble ? (
142
145
  <TileMenu
143
146
  peerID={peerId}
144
147
  audioTrackID={audioTrack?.id}
145
148
  videoTrackID={track?.id}
146
149
  canMinimise={canMinimise}
150
+ enableSpotlightingPeer={enableSpotlightingPeer}
147
151
  />
148
152
  ) : null}
149
153
  <PeerMetadata peerId={peerId} />
150
- {showStreamingUI && isMobile ? null : (
151
- <TileConnection hideLabel={hideLabel} name={label} isTile peerId={peerId} width={width} />
154
+ {isMobile ? null : (
155
+ <TileConnection
156
+ hideLabel={hideParticipantNameOnTile}
157
+ name={label}
158
+ isTile
159
+ peerId={peerId}
160
+ width={width}
161
+ pinned={pinned}
162
+ spotlighted={spotlighted}
163
+ />
152
164
  )}
153
165
  </StyledVideoTile.Container>
154
166
  ) : null}
@@ -158,6 +170,55 @@ const Tile = ({
158
170
 
159
171
  const metaStyles = { top: '$4', left: '$4' };
160
172
 
173
+ const heightAnimation = value =>
174
+ keyframes({
175
+ '50%': {
176
+ transform: `scale3d(1,${value},1)`,
177
+ },
178
+ '100%': {
179
+ transform: `scale3d(1,1,1)`,
180
+ },
181
+ });
182
+
183
+ const AudioLevelIndicator = ({ trackId, value, delay }) => {
184
+ const vanillaStore = useHMSVanillaStore();
185
+ const ref = useRef();
186
+
187
+ useEffect(() => {
188
+ const unsubscribe = vanillaStore.subscribe(audioLevel => {
189
+ if (ref.current) {
190
+ ref.current.style['animation'] = `${heightAnimation(
191
+ audioLevel ? value : 1,
192
+ )} 0.3s cubic-bezier(0.61, 1, 0.88, 1) infinite ${delay}s`;
193
+ }
194
+ }, selectTrackAudioByID(trackId));
195
+ return unsubscribe;
196
+ }, [vanillaStore, trackId, value, delay]);
197
+ return (
198
+ <Box
199
+ ref={ref}
200
+ css={{
201
+ w: 4,
202
+ height: 6,
203
+ r: 2,
204
+ bg: '$on_primary_high',
205
+ }}
206
+ />
207
+ );
208
+ };
209
+
210
+ export const AudioLevel = ({ trackId }) => {
211
+ return (
212
+ <StyledVideoTile.AudioIndicator>
213
+ <Flex align="center" justify="center" css={{ gap: '$2' }}>
214
+ {[3, 2, 3].map((v, i) => (
215
+ <AudioLevelIndicator trackId={trackId} value={v} delay={i * 0.15} key={i} />
216
+ ))}
217
+ </Flex>
218
+ </StyledVideoTile.AudioIndicator>
219
+ );
220
+ };
221
+
161
222
  const PeerMetadata = ({ peerId }) => {
162
223
  const metaData = useHMSStore(selectPeerMetadata(peerId));
163
224
  const isHandRaised = metaData?.isHandRaised || false;
@@ -181,19 +242,8 @@ const PeerMetadata = ({ peerId }) => {
181
242
 
182
243
  const VideoTile = React.memo(Tile);
183
244
 
184
- const showAudioMuted = ({ hideTileAudioMute, isHeadless, isAudioMuted }) => {
185
- if (!isHeadless) {
186
- return isAudioMuted;
187
- }
188
- return isAudioMuted && !hideTileAudioMute;
189
- };
190
-
191
- const getPadding = ({ isHeadless, tileOffset, hideAudioLevel }) => {
192
- if (!isHeadless || isNaN(Number(tileOffset))) {
193
- return undefined;
194
- }
195
- // Adding extra padding of 3px to ensure that the audio border is visible properly between tiles when tileOffset is 0.
196
- return Number(tileOffset) === 0 ? (hideAudioLevel ? 0 : 3) : undefined;
245
+ const showAudioMuted = ({ hideAudioMute, isAudioMuted }) => {
246
+ return isAudioMuted && !hideAudioMute;
197
247
  };
198
248
 
199
249
  export default VideoTile;
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useRef, useState } from 'react';
2
- import { useParams } from 'react-router-dom';
2
+ import { useNavigate, useParams } from 'react-router-dom';
3
3
  import { usePrevious } from 'react-use';
4
4
  import {
5
5
  HMSRoomState,
@@ -15,34 +15,36 @@ import { ActivatedPIP } from './PIP/PIPComponent';
15
15
  import { PictureInPicture } from './PIP/PIPManager';
16
16
  import { Box, Flex } from '../../Layout';
17
17
  import { useHMSPrebuiltContext } from '../AppContext';
18
- import { ConferenceMainView } from '../layouts/mainView';
18
+ import { VideoStreamingSection } from '../layouts/VideoStreamingSection';
19
19
  import FullPageProgress from './FullPageProgress';
20
20
  import { Header } from './Header';
21
21
  import { RoleChangeRequestModal } from './RoleChangeRequestModal';
22
+ import {
23
+ useRoomLayoutConferencingScreen,
24
+ useRoomLayoutPreviewScreen,
25
+ } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
22
26
  import { useAuthToken, useIsHeadless, useSetAppDataByKey } from './AppData/useUISettings';
23
- import { useNavigation } from './hooks/useNavigation';
24
- import { useSkipPreview } from './hooks/useSkipPreview';
25
27
  import { APP_DATA, EMOJI_REACTION_TYPE, isAndroid, isIOS, isIPadOS } from '../common/constants';
26
28
 
27
29
  const Conference = () => {
28
- const navigate = useNavigation();
30
+ const navigate = useNavigate();
29
31
  const { roomId, role } = useParams();
30
32
  const isHeadless = useIsHeadless();
33
+ const { userName } = useHMSPrebuiltContext();
34
+ const screenProps = useRoomLayoutConferencingScreen();
35
+ const { isPreviewScreenEnabled } = useRoomLayoutPreviewScreen();
31
36
  const roomState = useHMSStore(selectRoomState);
32
37
  const prevState = usePrevious(roomState);
33
38
  const isConnectedToRoom = useHMSStore(selectIsConnectedToRoom);
34
39
  const hmsActions = useHMSActions();
35
40
  const [hideControls, setHideControls] = useState(false);
36
41
  const dropdownList = useHMSStore(selectAppData(APP_DATA.dropdownList));
37
- const skipPreview = useSkipPreview();
38
- const { showPreview } = useHMSPrebuiltContext();
39
42
  const authTokenInAppData = useAuthToken();
40
43
  const headerRef = useRef();
41
44
  const footerRef = useRef();
42
45
  const dropdownListRef = useRef();
43
46
  const performAutoHide = hideControls && (isAndroid || isIOS || isIPadOS);
44
47
  const [isHLSStarted] = useSetAppDataByKey(APP_DATA.hlsStarted);
45
-
46
48
  const toggleControls = () => {
47
49
  if (dropdownListRef.current?.length === 0) {
48
50
  setHideControls(value => !value);
@@ -70,7 +72,7 @@ const Conference = () => {
70
72
  navigate(`/`);
71
73
  return;
72
74
  }
73
- if (!showPreview) {
75
+ if (!isPreviewScreenEnabled) {
74
76
  return;
75
77
  }
76
78
  if (
@@ -80,26 +82,26 @@ const Conference = () => {
80
82
  if (role) navigate(`/preview/${roomId || ''}/${role}`);
81
83
  else navigate(`/preview/${roomId || ''}`);
82
84
  }
83
- }, [isConnectedToRoom, prevState, roomState, navigate, role, roomId, showPreview]);
85
+ }, [isConnectedToRoom, prevState, roomState, navigate, role, roomId, isPreviewScreenEnabled]);
84
86
 
85
87
  useEffect(() => {
86
- if (authTokenInAppData && !isConnectedToRoom && !showPreview && roomState !== HMSRoomState.Connecting) {
88
+ if (authTokenInAppData && !isConnectedToRoom && !isPreviewScreenEnabled && roomState !== HMSRoomState.Connecting) {
87
89
  hmsActions
88
90
  .join({
89
- userName: 'Test',
91
+ userName,
90
92
  authToken: authTokenInAppData,
91
93
  initEndpoint: process.env.REACT_APP_ENV
92
94
  ? `https://${process.env.REACT_APP_ENV}-init.100ms.live/init`
93
95
  : undefined,
94
96
  initialSettings: {
95
- isAudioMuted: skipPreview,
96
- isVideoMuted: skipPreview,
97
+ isAudioMuted: !isPreviewScreenEnabled,
98
+ isVideoMuted: !isPreviewScreenEnabled,
97
99
  speakerAutoSelectionBlacklist: ['Yeti Stereo Microphone'],
98
100
  },
99
101
  })
100
102
  .catch(console.error);
101
103
  }
102
- }, [authTokenInAppData, skipPreview, hmsActions, isConnectedToRoom, showPreview, roomState]);
104
+ }, [authTokenInAppData, hmsActions, isConnectedToRoom, isPreviewScreenEnabled, roomState, userName]);
103
105
 
104
106
  useEffect(() => {
105
107
  // beam doesn't need to store messages, saves on unnecessary store updates in large calls
@@ -124,7 +126,7 @@ const Conference = () => {
124
126
 
125
127
  return (
126
128
  <Flex css={{ size: '100%', overflow: 'hidden' }} direction="column">
127
- {!isHeadless && (
129
+ {!screenProps.hideSections.includes('header') && (
128
130
  <Box
129
131
  ref={headerRef}
130
132
  css={{
@@ -137,7 +139,7 @@ const Conference = () => {
137
139
  }}
138
140
  data-testid="header"
139
141
  >
140
- <Header />
142
+ <Header elements={screenProps.elements} screenType={screenProps.screenType} />
141
143
  </Box>
142
144
  )}
143
145
  <Box
@@ -155,23 +157,25 @@ const Conference = () => {
155
157
  data-testid="conferencing"
156
158
  onClick={toggleControls}
157
159
  >
158
- <ConferenceMainView />
160
+ <VideoStreamingSection screenType={screenProps.screenType} elements={screenProps.elements} />
159
161
  </Box>
160
- {!isHeadless && (
162
+ {!screenProps.hideSections.includes('footer') && (
161
163
  <Box
162
164
  ref={footerRef}
163
165
  css={{
164
166
  flexShrink: 0,
165
167
  maxHeight: '$24',
166
168
  transition: 'margin 0.3s ease-in-out',
169
+ bg: '$background_dim',
167
170
  marginBottom: performAutoHide ? `-${footerRef.current?.clientHeight}px` : undefined,
168
171
  '@md': {
169
172
  maxHeight: 'unset',
173
+ bg: screenProps.screenType === 'hls_live_streaming' ? 'transparent' : '$background_dim',
170
174
  },
171
175
  }}
172
176
  data-testid="footer"
173
177
  >
174
- <Footer />
178
+ <Footer elements={screenProps.elements} screenType={screenProps.screenType} />
175
179
  </Box>
176
180
  )}
177
181
  <RoleChangeRequestModal />
@@ -41,6 +41,12 @@ export const useMyMetadata = () => {
41
41
  }
42
42
  }, [isHandRaised, isBRBOn]); //eslint-disable-line
43
43
 
44
+ const setPrevRole = async role => {
45
+ await update({
46
+ prevRole: role,
47
+ });
48
+ };
49
+
44
50
  return {
45
51
  isHandRaised,
46
52
  isBRBOn,
@@ -48,5 +54,6 @@ export const useMyMetadata = () => {
48
54
  updateMetaData: update,
49
55
  toggleHandRaise,
50
56
  toggleBRB,
57
+ setPrevRole,
51
58
  };
52
59
  };
@@ -0,0 +1,38 @@
1
+ import { useMemo } from 'react';
2
+ import { HMSPeer } from '@100mslive/react-sdk';
3
+ // @ts-ignore: No implicit Any
4
+ import { usePinnedTrack } from '../AppData/useUISettings';
5
+
6
+ export const useRoleProminencePeers = (prominentRoles: string[], peers: HMSPeer[], isInsetEnabled: boolean) => {
7
+ const pinnedTrack = usePinnedTrack();
8
+
9
+ const [prominentPeers, secondaryPeers] = useMemo(() => {
10
+ return peers.reduce<[HMSPeer[], HMSPeer[]]>(
11
+ (acc, peer) => {
12
+ if (pinnedTrack) {
13
+ if (pinnedTrack.peerId === peer.id) {
14
+ acc[0].push(peer);
15
+ } else {
16
+ acc[1].push(peer);
17
+ }
18
+ return acc;
19
+ }
20
+ if (peer.isLocal && isInsetEnabled) {
21
+ return acc;
22
+ }
23
+ if (prominentRoles?.includes(peer.roleName || '')) {
24
+ acc[0].push(peer);
25
+ } else {
26
+ acc[1].push(peer);
27
+ }
28
+ return acc;
29
+ },
30
+ [[], []],
31
+ );
32
+ }, [peers, isInsetEnabled, prominentRoles, pinnedTrack]);
33
+
34
+ return {
35
+ prominentPeers,
36
+ secondaryPeers,
37
+ };
38
+ };
@@ -0,0 +1,121 @@
1
+ import { useEffect, useMemo, useState } from 'react';
2
+ import { useMeasure, useMedia } from 'react-use';
3
+ import {
4
+ getPeersWithTiles,
5
+ HMSPeer,
6
+ selectTracksMap,
7
+ TrackWithPeerAndDimensions,
8
+ useHMSVanillaStore,
9
+ } from '@100mslive/react-sdk';
10
+ import { config as cssConfig } from '../../../Theme';
11
+
12
+ const aspectRatioConfig = { default: [1 / 1, 4 / 3, 16 / 9], mobile: [1 / 1, 3 / 4, 9 / 16] };
13
+ const gap = 8; // gap between flex items
14
+
15
+ export const usePagesWithTiles = ({ peers, maxTileCount }: { peers: HMSPeer[]; maxTileCount: number }) => {
16
+ const vanillaStore = useHMSVanillaStore();
17
+ const tracksMap = vanillaStore.getState(selectTracksMap);
18
+ const peersWithTiles = useMemo(
19
+ () => getPeersWithTiles(peers, tracksMap, () => false) as TrackWithPeerAndDimensions[],
20
+ [peers, tracksMap],
21
+ );
22
+ const noOfPages = Math.ceil(peersWithTiles.length / maxTileCount);
23
+ const pagesList = useMemo(() => {
24
+ let sliceStart = 0;
25
+ let remaining = peersWithTiles.length;
26
+ const list = [];
27
+ // split into pages
28
+ for (let i = 0; i < noOfPages; i++) {
29
+ const count = Math.min(remaining, maxTileCount);
30
+ list.push(peersWithTiles.slice(sliceStart, sliceStart + count));
31
+ remaining = remaining - count;
32
+ sliceStart += count;
33
+ }
34
+ return list;
35
+ }, [peersWithTiles, noOfPages, maxTileCount]);
36
+ return pagesList;
37
+ };
38
+
39
+ export const useTileLayout = ({
40
+ pageList,
41
+ maxTileCount,
42
+ }: {
43
+ pageList: TrackWithPeerAndDimensions[][];
44
+ maxTileCount: number;
45
+ }) => {
46
+ const vanillaStore = useHMSVanillaStore();
47
+ const [ref, { width, height }] = useMeasure<HTMLDivElement>();
48
+ const isMobile = useMedia(cssConfig.media.lg);
49
+ const [pagesWithTiles, setPagesWithTiles] = useState<TrackWithPeerAndDimensions[][]>([]);
50
+
51
+ useEffect(() => {
52
+ if (width === 0 || height === 0) {
53
+ return;
54
+ }
55
+ // calculate dimesions for each page
56
+ for (const page of pageList) {
57
+ const noOfTilesInPage = page.length;
58
+ let maxCols =
59
+ noOfTilesInPage > 2 && noOfTilesInPage < 9
60
+ ? Math.ceil(noOfTilesInPage / 2)
61
+ : Math.ceil(Math.sqrt(noOfTilesInPage));
62
+ if (isMobile) {
63
+ maxCols = noOfTilesInPage < 4 ? 1 : Math.min(maxCols, 2);
64
+ }
65
+ const maxRows = Math.ceil(noOfTilesInPage / maxCols);
66
+ let index = 0;
67
+ // convert the current page to a matrix(grid)
68
+ const matrix = new Array(maxRows).fill(null).map((_, i) => {
69
+ const numCols = Math.min(maxCols, noOfTilesInPage - i * maxCols);
70
+ const rowElements = [];
71
+ for (let j = 0; j < numCols; j++) {
72
+ if (index < page.length) {
73
+ rowElements.push(page[index++]);
74
+ }
75
+ }
76
+ return rowElements;
77
+ });
78
+
79
+ const maxHeight = height - (maxRows - 1) * gap;
80
+ const maxRowHeight = maxHeight / matrix.length;
81
+ const aspectRatios =
82
+ isMobile && (noOfTilesInPage === 1 || noOfTilesInPage > 3)
83
+ ? aspectRatioConfig.mobile
84
+ : aspectRatioConfig.default;
85
+ // calculate height and width of each tile in a row
86
+ for (const row of matrix) {
87
+ let tileWidth = (width - (row.length - 1) * gap) / row.length;
88
+ let tileHeight = 0;
89
+ const calcHeights = aspectRatios.map(aR => tileWidth / aR);
90
+ for (const h of calcHeights) {
91
+ if (h < maxRowHeight) {
92
+ if (tileHeight < h) {
93
+ tileHeight = h;
94
+ }
95
+ }
96
+ }
97
+
98
+ // tileHeight is not calculated as it could be exceeding the max possible height
99
+ // find the max possible width instead
100
+ if (tileHeight === 0) {
101
+ tileHeight = maxRowHeight;
102
+ const calcWidths = aspectRatios.map(aR => tileHeight * aR);
103
+ tileWidth = 0;
104
+ for (const w of calcWidths) {
105
+ if (w < width) {
106
+ if (tileWidth < w) {
107
+ tileWidth = w;
108
+ }
109
+ }
110
+ }
111
+ }
112
+ for (let i = 0; i < row.length; i++) {
113
+ row[i].width = tileWidth;
114
+ row[i].height = tileHeight;
115
+ }
116
+ }
117
+ }
118
+ setPagesWithTiles([...pageList]);
119
+ }, [width, height, maxTileCount, pageList, vanillaStore, isMobile]);
120
+ return { pagesWithTiles, ref };
121
+ };
@@ -0,0 +1,22 @@
1
+ import React, { useContext } from 'react';
2
+
3
+ type TileContextType = {
4
+ enableSpotlightingPeer: boolean;
5
+ hideParticipantNameOnTile?: boolean;
6
+ roundedVideoTile?: boolean;
7
+ hideAudioMuteOnTile?: boolean;
8
+ objectFit?: 'cover' | 'contain';
9
+ };
10
+
11
+ export const VideoTileContext = React.createContext<TileContextType>({
12
+ enableSpotlightingPeer: true,
13
+ hideParticipantNameOnTile: false,
14
+ roundedVideoTile: true,
15
+ hideAudioMuteOnTile: false,
16
+ objectFit: 'contain',
17
+ });
18
+
19
+ export const useVideoTileContext = () => {
20
+ const context = useContext(VideoTileContext);
21
+ return context;
22
+ };
@@ -1,17 +1,12 @@
1
1
  import React, { useState } from 'react';
2
- import { Dialog, Flex, HorizontalDivider, Input, Text } from '../../../';
3
- import { DialogInputFile, DialogRow } from '../../primitives/DialogContent';
4
- import { PdfErrorView } from './pdfErrorView';
2
+ import { Dialog, Flex } from '../../../';
3
+ import { DialogInputFile } from '../../primitives/DialogContent';
5
4
  import { PDFHeader } from './pdfHeader';
6
- import { PDFInfo } from './pdfInfo';
7
5
  import { SubmitPDF } from './submitPdf';
8
6
  import { UploadedFile } from './uploadedFile';
9
7
 
10
8
  export function PDFFileOptions({ onOpenChange }) {
11
- const [isPDFUrlValid, setIsPDFUrlValid] = useState(true);
12
- const [isValidateProgress, setIsValidateProgress] = useState(false);
13
9
  const [pdfFile, setPDFFile] = useState(null);
14
- const [pdfURL, setPDFURL] = useState('');
15
10
 
16
11
  return !pdfFile ? (
17
12
  <Dialog.Root defaultOpen onOpenChange={onOpenChange}>
@@ -35,75 +30,13 @@ export function PDFFileOptions({ onOpenChange }) {
35
30
  type="file"
36
31
  accept=".pdf"
37
32
  />
38
- <DialogRow
39
- css={{
40
- m: '$10 0',
41
- }}
42
- >
43
- <HorizontalDivider
44
- css={{
45
- mr: '$4',
46
- }}
47
- />
48
- <Text
49
- variant="tiny"
50
- css={{
51
- color: '$on_surface_low',
52
- }}
53
- >
54
- OR
55
- </Text>
56
- <HorizontalDivider
57
- css={{
58
- ml: '$4',
59
- }}
60
- />
61
- </DialogRow>
62
- <Text
63
- variant="sm"
64
- css={{
65
- py: '$2',
66
- }}
67
- >
68
- Import from URL
69
- </Text>
70
- <Input
71
- css={{ w: '100%', mb: '$10' }}
72
- value={pdfURL}
73
- onFocus={() => {
74
- setIsPDFUrlValid(true);
75
- setIsValidateProgress(false);
76
- }}
77
- onChange={e => {
78
- setPDFURL(e.target.value);
79
- }}
80
- placeholder="Paste PDF URL"
81
- type="text"
82
- error={!isPDFUrlValid}
83
- />
84
- {!isPDFUrlValid && <PdfErrorView isPDFUrlValid={isPDFUrlValid} />}
85
- <PDFInfo />
86
- <SubmitPDF
87
- pdfFile={pdfFile}
88
- pdfURL={pdfURL}
89
- isValidateProgress={isValidateProgress}
90
- setIsPDFUrlValid={setIsPDFUrlValid}
91
- setIsValidateProgress={setIsValidateProgress}
92
- onOpenChange={onOpenChange}
93
- />
33
+
34
+ <SubmitPDF pdfFile={pdfFile} onOpenChange={onOpenChange} />
94
35
  </Flex>
95
36
  </Dialog.Content>
96
37
  </Dialog.Portal>
97
38
  </Dialog.Root>
98
39
  ) : (
99
- <UploadedFile
100
- pdfFile={pdfFile}
101
- pdfURL={pdfURL}
102
- isValidateProgress={isValidateProgress}
103
- setPDFFile={setPDFFile}
104
- setIsPDFUrlValid={setIsPDFUrlValid}
105
- setIsValidateProgress={setIsValidateProgress}
106
- onOpenChange={onOpenChange}
107
- />
40
+ <UploadedFile pdfFile={pdfFile} setPDFFile={setPDFFile} onOpenChange={onOpenChange} />
108
41
  );
109
42
  }