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

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