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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. package/dist/{HLSView-PY2FKWX3.js → HLSView-QMU5JK7U.js} +208 -118
  2. package/dist/HLSView-QMU5JK7U.js.map +7 -0
  3. package/dist/Prebuilt/AppContext.d.ts +1 -1
  4. package/dist/Prebuilt/components/Chat/ChatFooter.d.ts +7 -0
  5. package/dist/Prebuilt/components/Connection/ConnectionIndicator.d.ts +6 -0
  6. package/dist/Prebuilt/components/Connection/TileConnection.d.ts +10 -0
  7. package/dist/Prebuilt/components/Footer/ChatToggle.d.ts +2 -0
  8. package/dist/Prebuilt/components/Footer/RoleAccordion.d.ts +14 -0
  9. package/dist/Prebuilt/components/Footer/RoleOptions.d.ts +6 -0
  10. package/dist/Prebuilt/components/Header/StreamActions.d.ts +11 -0
  11. package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +4 -3
  12. package/dist/Prebuilt/components/Leave/EndSessionContent.d.ts +4 -3
  13. package/dist/Prebuilt/components/Leave/LeaveCard.d.ts +1 -2
  14. package/dist/Prebuilt/components/Leave/LeaveSessionContent.d.ts +3 -1
  15. package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +4 -3
  16. package/dist/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.d.ts +6 -0
  17. package/dist/Prebuilt/components/Preview/PreviewContainer.d.ts +3 -0
  18. package/dist/Prebuilt/components/Preview/PreviewJoin.d.ts +16 -0
  19. package/dist/Prebuilt/components/RoleChangeRequestModal.d.ts +2 -0
  20. package/dist/Prebuilt/components/SecondaryTiles.d.ts +1 -1
  21. package/dist/Prebuilt/components/SidePaneTabs.d.ts +7 -0
  22. package/dist/Prebuilt/components/VideoLayouts/EqualProminence.d.ts +1 -1
  23. package/dist/Prebuilt/components/VideoLayouts/Grid.d.ts +1 -0
  24. package/dist/Prebuilt/components/VideoLayouts/GridLayout.d.ts +5 -3
  25. package/dist/Prebuilt/components/VideoLayouts/ProminenceLayout.d.ts +6 -3
  26. package/dist/Prebuilt/components/VideoLayouts/RoleProminence.d.ts +1 -1
  27. package/dist/Prebuilt/components/VideoLayouts/ScreenshareLayout.d.ts +1 -1
  28. package/dist/Prebuilt/components/VideoLayouts/interface.d.ts +1 -0
  29. package/dist/Prebuilt/components/hooks/useAutoStartStreaming.d.ts +1 -0
  30. package/dist/Prebuilt/components/hooks/useRedirectToLeave.d.ts +3 -0
  31. package/dist/Prebuilt/components/hooks/useTileLayout.d.ts +2 -1
  32. package/dist/Prebuilt/components/hooks/useVideoTileLayout.d.ts +2 -0
  33. package/dist/Prebuilt/layouts/SidePane.d.ts +4 -1
  34. package/dist/Prebuilt/layouts/VideoStreamingSection.d.ts +2 -1
  35. package/dist/{VirtualBackground-AYDHYLIZ.js → VirtualBackground-37FXUPYO.js} +6 -6
  36. package/dist/VirtualBackground-37FXUPYO.js.map +7 -0
  37. package/dist/{chunk-GQD2AGWW.js → chunk-KBVIZGYW.js} +12 -2
  38. package/dist/{chunk-GQD2AGWW.js.map → chunk-KBVIZGYW.js.map} +2 -2
  39. package/dist/{chunk-RXTHJUMZ.js → chunk-WVGGQZK4.js} +986 -436
  40. package/dist/chunk-WVGGQZK4.js.map +7 -0
  41. package/dist/{chunk-E2M2ZSOL.js → chunk-ZKE2N5LH.js} +2 -2
  42. package/dist/{conference-V2XZGTKU.js → conference-FJJQ4TXX.js} +1136 -1301
  43. package/dist/conference-FJJQ4TXX.js.map +7 -0
  44. package/dist/index.cjs.js +3565 -3092
  45. package/dist/index.cjs.js.map +4 -4
  46. package/dist/index.js +2 -2
  47. package/dist/meta.cjs.json +773 -525
  48. package/dist/meta.esbuild.json +833 -579
  49. package/package.json +8 -7
  50. package/src/Prebuilt/App.tsx +10 -21
  51. package/src/Prebuilt/AppContext.tsx +1 -1
  52. package/src/Prebuilt/IconButton.jsx +10 -0
  53. package/src/Prebuilt/common/PeersSorter.ts +1 -1
  54. package/src/Prebuilt/common/constants.js +1 -2
  55. package/src/Prebuilt/common/utils.js +1 -1
  56. package/src/Prebuilt/components/AppData/AppData.jsx +8 -2
  57. package/src/Prebuilt/components/AppData/useUISettings.js +6 -6
  58. package/src/Prebuilt/components/AudioVideoToggle.jsx +8 -6
  59. package/src/Prebuilt/components/Chat/Chat.jsx +24 -11
  60. package/src/Prebuilt/components/Chat/ChatBody.jsx +20 -21
  61. package/src/Prebuilt/components/Chat/{ChatFooter.jsx → ChatFooter.tsx} +38 -13
  62. package/src/Prebuilt/components/Chat/useEmojiPickerStyles.js +5 -4
  63. package/src/Prebuilt/components/Connection/{ConnectionIndicator.jsx → ConnectionIndicator.tsx} +12 -4
  64. package/src/Prebuilt/components/Connection/{TileConnection.jsx → TileConnection.tsx} +20 -6
  65. package/src/Prebuilt/components/EmojiReaction.jsx +2 -6
  66. package/src/Prebuilt/components/Footer/{ChatToggle.jsx → ChatToggle.tsx} +4 -1
  67. package/src/Prebuilt/components/Footer/Footer.tsx +30 -5
  68. package/src/Prebuilt/components/Footer/ParticipantList.jsx +15 -49
  69. package/src/Prebuilt/components/Footer/{RoleAccordion.jsx → RoleAccordion.tsx} +33 -17
  70. package/src/Prebuilt/components/Footer/RoleOptions.tsx +155 -0
  71. package/src/Prebuilt/components/FullPageProgress.jsx +3 -3
  72. package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -0
  73. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +39 -17
  74. package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +2 -2
  75. package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +5 -6
  76. package/src/Prebuilt/components/HMSVideo/VolumeControl.jsx +1 -1
  77. package/src/Prebuilt/components/Header/HeaderComponents.jsx +8 -1
  78. package/src/Prebuilt/components/Header/{StreamActions.jsx → StreamActions.tsx} +23 -9
  79. package/src/Prebuilt/components/Header/common.jsx +5 -2
  80. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +6 -1
  81. package/src/Prebuilt/components/InsetTile.tsx +15 -8
  82. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +21 -11
  83. package/src/Prebuilt/components/Leave/EndSessionContent.tsx +2 -5
  84. package/src/Prebuilt/components/Leave/LeaveCard.tsx +1 -3
  85. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +28 -25
  86. package/src/Prebuilt/components/Leave/LeaveSessionContent.tsx +8 -2
  87. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +8 -8
  88. package/src/Prebuilt/components/MoreSettings/ChangeNameContent.jsx +4 -0
  89. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +1 -1
  90. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +9 -23
  91. package/src/Prebuilt/components/MoreSettings/SplitComponents/{MwebOptions.jsx → MwebOptions.tsx} +89 -28
  92. package/src/Prebuilt/components/Notifications/Notifications.jsx +44 -28
  93. package/src/Prebuilt/components/Notifications/ReconnectNotifications.jsx +5 -11
  94. package/src/Prebuilt/components/Pagination.tsx +14 -12
  95. package/src/Prebuilt/components/Preview/{PreviewContainer.jsx → PreviewContainer.tsx} +11 -2
  96. package/src/Prebuilt/components/Preview/PreviewForm.tsx +6 -8
  97. package/src/Prebuilt/components/Preview/{PreviewJoin.jsx → PreviewJoin.tsx} +44 -21
  98. package/src/Prebuilt/components/{RoleChangeRequestModal.jsx → RoleChangeRequestModal.tsx} +36 -17
  99. package/src/Prebuilt/components/ScreenshareTile.jsx +6 -7
  100. package/src/Prebuilt/components/SecondaryTiles.tsx +12 -10
  101. package/src/Prebuilt/components/SidePaneTabs.tsx +120 -0
  102. package/src/Prebuilt/components/TileMenu/TileMenu.jsx +1 -1
  103. package/src/Prebuilt/components/TileMenu/TileMenuContent.jsx +14 -10
  104. package/src/Prebuilt/components/Toast/ToastConfig.jsx +5 -4
  105. package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +13 -10
  106. package/src/Prebuilt/components/VideoLayouts/Grid.tsx +36 -34
  107. package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +33 -15
  108. package/src/Prebuilt/components/VideoLayouts/ProminenceLayout.tsx +45 -31
  109. package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +12 -9
  110. package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +25 -9
  111. package/src/Prebuilt/components/VideoLayouts/interface.ts +1 -0
  112. package/src/Prebuilt/components/VideoTile.jsx +45 -53
  113. package/src/Prebuilt/components/conference.jsx +71 -74
  114. package/src/Prebuilt/components/hooks/useAutoStartStreaming.tsx +57 -0
  115. package/src/Prebuilt/components/hooks/useMetadata.jsx +19 -28
  116. package/src/Prebuilt/components/hooks/useRedirectToLeave.tsx +34 -0
  117. package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +1 -1
  118. package/src/Prebuilt/components/hooks/useTileLayout.tsx +24 -18
  119. package/src/Prebuilt/components/hooks/useVideoTileLayout.ts +4 -0
  120. package/src/Prebuilt/layouts/EmbedView.jsx +1 -11
  121. package/src/Prebuilt/layouts/HLSView.jsx +152 -82
  122. package/src/Prebuilt/layouts/SidePane.tsx +25 -11
  123. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +11 -47
  124. package/src/Prebuilt/plugins/FlyingEmoji.jsx +14 -2
  125. package/src/Prebuilt/plugins/VirtualBackground/VirtualBackground.jsx +3 -3
  126. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useFetchRoomLayout.ts +2 -2
  127. package/src/Prebuilt/services/FeatureFlags.jsx +0 -1
  128. package/src/VideoTile/StyledVideoTile.tsx +1 -0
  129. package/dist/HLSView-PY2FKWX3.js.map +0 -7
  130. package/dist/VirtualBackground-AYDHYLIZ.js.map +0 -7
  131. package/dist/chunk-RXTHJUMZ.js.map +0 -7
  132. package/dist/conference-V2XZGTKU.js.map +0 -7
  133. package/src/Prebuilt/components/AudioLevel/BeamSpeakerLabelsLogging.jsx +0 -16
  134. package/src/Prebuilt/components/Chat/ChatParticipantHeader.jsx +0 -73
  135. package/src/Prebuilt/components/VideoList.jsx +0 -73
  136. /package/dist/{chunk-E2M2ZSOL.js.map → chunk-ZKE2N5LH.js.map} +0 -0
@@ -10,7 +10,6 @@ import {
10
10
  import { config as cssConfig } from '../../../Theme';
11
11
 
12
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
13
 
15
14
  export const usePagesWithTiles = ({ peers, maxTileCount }: { peers: HMSPeer[]; maxTileCount: number }) => {
16
15
  const vanillaStore = useHMSVanillaStore();
@@ -39,9 +38,11 @@ export const usePagesWithTiles = ({ peers, maxTileCount }: { peers: HMSPeer[]; m
39
38
  export const useTileLayout = ({
40
39
  pageList,
41
40
  maxTileCount,
41
+ edgeToEdge = false,
42
42
  }: {
43
43
  pageList: TrackWithPeerAndDimensions[][];
44
44
  maxTileCount: number;
45
+ edgeToEdge?: boolean;
45
46
  }) => {
46
47
  const vanillaStore = useHMSVanillaStore();
47
48
  const [ref, { width, height }] = useMeasure<HTMLDivElement>();
@@ -76,6 +77,7 @@ export const useTileLayout = ({
76
77
  return rowElements;
77
78
  });
78
79
 
80
+ const gap = edgeToEdge && isMobile ? 0 : 8; // gap between flex items
79
81
  const maxHeight = height - (maxRows - 1) * gap;
80
82
  const maxRowHeight = maxHeight / matrix.length;
81
83
  const aspectRatios =
@@ -86,25 +88,29 @@ export const useTileLayout = ({
86
88
  for (const row of matrix) {
87
89
  let tileWidth = (width - (row.length - 1) * gap) / row.length;
88
90
  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;
91
+ if (edgeToEdge) {
92
+ tileHeight = maxRowHeight;
93
+ } else {
94
+ const calcHeights = aspectRatios.map(aR => tileWidth / aR);
95
+ for (const h of calcHeights) {
96
+ if (h < maxRowHeight) {
97
+ if (tileHeight < h) {
98
+ tileHeight = h;
99
+ }
94
100
  }
95
101
  }
96
- }
97
102
 
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;
103
+ // tileHeight is not calculated as it could be exceeding the max possible height
104
+ // find the max possible width instead
105
+ if (tileHeight === 0) {
106
+ tileHeight = maxRowHeight;
107
+ const calcWidths = aspectRatios.map(aR => tileHeight * aR);
108
+ tileWidth = 0;
109
+ for (const w of calcWidths) {
110
+ if (w < width) {
111
+ if (tileWidth < w) {
112
+ tileWidth = w;
113
+ }
108
114
  }
109
115
  }
110
116
  }
@@ -116,6 +122,6 @@ export const useTileLayout = ({
116
122
  }
117
123
  }
118
124
  setPagesWithTiles([...pageList]);
119
- }, [width, height, maxTileCount, pageList, vanillaStore, isMobile]);
125
+ }, [width, height, maxTileCount, pageList, vanillaStore, isMobile, edgeToEdge]);
120
126
  return { pagesWithTiles, ref };
121
127
  };
@@ -5,7 +5,9 @@ type TileContextType = {
5
5
  hideParticipantNameOnTile?: boolean;
6
6
  roundedVideoTile?: boolean;
7
7
  hideAudioMuteOnTile?: boolean;
8
+ hideAudioLevelOnTile?: boolean;
8
9
  objectFit?: 'cover' | 'contain';
10
+ hideMetadataOnTile?: boolean;
9
11
  };
10
12
 
11
13
  export const VideoTileContext = React.createContext<TileContextType>({
@@ -13,7 +15,9 @@ export const VideoTileContext = React.createContext<TileContextType>({
13
15
  hideParticipantNameOnTile: false,
14
16
  roundedVideoTile: true,
15
17
  hideAudioMuteOnTile: false,
18
+ hideAudioLevelOnTile: false,
16
19
  objectFit: 'contain',
20
+ hideMetadataOnTile: false,
17
21
  });
18
22
 
19
23
  export const useVideoTileContext = () => {
@@ -1,7 +1,5 @@
1
1
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import {
3
- selectLocalPeerID,
4
- selectLocalPeerRoleName,
5
3
  selectPeers,
6
4
  selectPeerScreenSharing,
7
5
  throwErrorHandler,
@@ -25,21 +23,13 @@ export const EmbedView = () => {
25
23
  export const EmbebScreenShareView = ({ children }) => {
26
24
  const peers = useHMSStore(selectPeers);
27
25
 
28
- const localPeerID = useHMSStore(selectLocalPeerID);
29
- const localPeerRole = useHMSStore(selectLocalPeerRoleName);
30
26
  const peerPresenting = useHMSStore(selectPeerScreenSharing);
31
- const isPresenterFromMyRole = peerPresenting?.roleName?.toLowerCase() === localPeerRole?.toLowerCase();
32
- const amIPresenting = localPeerID === peerPresenting?.id;
33
- const showPresenterInSmallTile = amIPresenting || isPresenterFromMyRole;
34
27
  const [, setActiveScreenSharePeer] = useSetAppDataByKey(APP_DATA.activeScreensharePeerId);
35
28
 
36
29
  const smallTilePeers = useMemo(() => {
37
30
  const smallTilePeers = peers.filter(peer => peer.id !== peerPresenting?.id);
38
- if (showPresenterInSmallTile && peerPresenting) {
39
- smallTilePeers.unshift(peerPresenting); // put presenter on first page
40
- }
41
31
  return smallTilePeers;
42
- }, [peers, peerPresenting, showPresenterInSmallTile]);
32
+ }, [peers, peerPresenting]);
43
33
 
44
34
  useEffect(() => {
45
35
  setActiveScreenSharePeer(peerPresenting?.id);
@@ -1,9 +1,9 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
- import { useFullscreen, useToggle } from 'react-use';
2
+ import { useFullscreen, useMedia, useToggle } from 'react-use';
3
3
  import { HLSPlaybackState, HMSHLSPlayer, HMSHLSPlayerEvents } from '@100mslive/hls-player';
4
4
  import screenfull from 'screenfull';
5
5
  import { selectAppData, selectHLSState, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
6
- import { ExpandIcon, RadioIcon, ShrinkIcon } from '@100mslive/react-icons';
6
+ import { ColoredHandIcon, ExpandIcon, RadioIcon, ShrinkIcon } from '@100mslive/react-icons';
7
7
  import { HlsStatsOverlay } from '../components/HlsStatsOverlay';
8
8
  import { HMSVideoPlayer } from '../components/HMSVideo';
9
9
  import { FullScreenButton } from '../components/HMSVideo/FullscreenButton';
@@ -14,7 +14,7 @@ import { IconButton } from '../../IconButton';
14
14
  import { Box, Flex } from '../../Layout';
15
15
  import { Loading } from '../../Loading';
16
16
  import { Text } from '../../Text';
17
- import { useTheme } from '../../Theme';
17
+ import { config, useTheme } from '../../Theme';
18
18
  import { Tooltip } from '../../Tooltip';
19
19
  import { APP_DATA, EMOJI_REACTION_TYPE } from '../common/constants';
20
20
 
@@ -26,7 +26,8 @@ const HLSView = () => {
26
26
  const hlsState = useHMSStore(selectHLSState);
27
27
  const enablHlsStats = useHMSStore(selectAppData(APP_DATA.hlsStats));
28
28
  const hmsActions = useHMSActions();
29
- const { themeType } = useTheme();
29
+ const { themeType, theme } = useTheme();
30
+ const [streamEnded, setStreamEnded] = useState(false);
30
31
  let [hlsStatsState, setHlsStatsState] = useState(null);
31
32
  const hlsUrl = hlsState.variants[0]?.url;
32
33
  const [availableLayers, setAvailableLayers] = useState([]);
@@ -37,6 +38,12 @@ const HLSView = () => {
37
38
  const [isPaused, setIsPaused] = useState(false);
38
39
  const isFullScreenSupported = screenfull.isEnabled;
39
40
  const [show, toggle] = useToggle(false);
41
+ const [controlsVisible, setControlsVisible] = useState(true);
42
+ const controlsRef = useRef();
43
+ const controlsTimerRef = useRef();
44
+ const [qualityDropDownOpen, setQualityDropDownOpen] = useState(false);
45
+
46
+ const isMobile = useMedia(config.media.md);
40
47
  const isFullScreen = useFullscreen(hlsViewRef, show, {
41
48
  onClose: () => toggle(false),
42
49
  });
@@ -58,6 +65,19 @@ const HLSView = () => {
58
65
  };
59
66
  }, []);
60
67
 
68
+ useEffect(() => {
69
+ const videoElem = videoRef.current;
70
+ const setStreamEndedCallback = () => {
71
+ setStreamEnded(true);
72
+ // no point keeping the callback attached once the streaming is ended
73
+ videoElem?.removeEventListener('ended', setStreamEndedCallback);
74
+ };
75
+ videoElem?.addEventListener('ended', setStreamEndedCallback);
76
+ return () => {
77
+ videoElem?.removeEventListener('ended', setStreamEndedCallback);
78
+ };
79
+ }, [hlsUrl]);
80
+
61
81
  /**
62
82
  * initialize HMSHLSPlayer and add event listeners.
63
83
  */
@@ -82,7 +102,7 @@ const HLSView = () => {
82
102
  const parsedPayload = parsePayload(payload);
83
103
  switch (parsedPayload.type) {
84
104
  case EMOJI_REACTION_TYPE:
85
- window.showFlyingEmoji(parsedPayload?.emojiId, parsedPayload?.senderId);
105
+ window.showFlyingEmoji?.({ emojiId: parsedPayload?.emojiId, senderId: parsedPayload?.senderId });
86
106
  break;
87
107
  default: {
88
108
  const toast = {
@@ -167,6 +187,43 @@ const HLSView = () => {
167
187
  hmsActions.setAppData(APP_DATA.hlsStats, !enablHlsStats);
168
188
  };
169
189
 
190
+ useEffect(() => {
191
+ if (controlsVisible && isFullScreen && !qualityDropDownOpen) {
192
+ if (controlsTimerRef.current) {
193
+ clearTimeout(controlsTimerRef.current);
194
+ }
195
+ controlsTimerRef.current = setTimeout(() => {
196
+ setControlsVisible(false);
197
+ }, 5000);
198
+ }
199
+ if (!isFullScreen && controlsTimerRef.current) {
200
+ clearTimeout(controlsTimerRef.current);
201
+ }
202
+ return () => {
203
+ if (controlsTimerRef.current) {
204
+ clearTimeout(controlsTimerRef.current);
205
+ }
206
+ };
207
+ }, [controlsVisible, isFullScreen, qualityDropDownOpen]);
208
+
209
+ const onHoverHandler = useCallback(
210
+ event => {
211
+ if (event.type === 'mouseenter' || qualityDropDownOpen) {
212
+ setControlsVisible(true);
213
+ return;
214
+ }
215
+ if (event.type === 'mouseleave') {
216
+ setControlsVisible(false);
217
+ } else if (isFullScreen && !controlsVisible && event.type === 'mousemove') {
218
+ setControlsVisible(true);
219
+ if (controlsTimerRef.current) {
220
+ clearTimeout(controlsTimerRef.current);
221
+ }
222
+ }
223
+ },
224
+ [controlsVisible, isFullScreen, qualityDropDownOpen],
225
+ );
226
+
170
227
  return (
171
228
  <Flex
172
229
  key="hls-viewer"
@@ -179,7 +236,7 @@ const HLSView = () => {
179
236
  {hlsStatsState?.url && enablHlsStats ? (
180
237
  <HlsStatsOverlay hlsStatsState={hlsStatsState} onClose={sfnOverlayClose} />
181
238
  ) : null}
182
- {hlsUrl && hlsState.running ? (
239
+ {hlsUrl && !streamEnded ? (
183
240
  <Flex
184
241
  id="hls-player-container"
185
242
  align="center"
@@ -188,7 +245,6 @@ const HLSView = () => {
188
245
  width: '100%',
189
246
  margin: '0 auto',
190
247
  height: '100%',
191
- background: 'linear-gradient(180deg, rgba(0, 0, 0, 0.00) 0%, #000 100%)',
192
248
  }}
193
249
  >
194
250
  <HLSAutoplayBlockedPrompt open={isHlsAutoplayBlocked} unblockAutoPlay={unblockAutoPlay} />
@@ -203,100 +259,114 @@ const HLSView = () => {
203
259
  <Loading width={72} height={72} />
204
260
  </Flex>
205
261
  )}
206
- <HMSVideoPlayer.Root ref={videoRef}>
262
+ <HMSVideoPlayer.Root
263
+ ref={videoRef}
264
+ onMouseEnter={onHoverHandler}
265
+ onMouseMove={onHoverHandler}
266
+ onMouseLeave={onHoverHandler}
267
+ >
207
268
  <Flex
269
+ ref={controlsRef}
208
270
  direction="column"
209
271
  justify="flex-end"
210
272
  align="flex-start"
211
273
  css={{
212
- background: 'linear-gradient(180deg, rgba(0, 0, 0, 0.00) 0%, #000 100%)',
274
+ position: 'absolute',
275
+ bottom: '0',
276
+ left: '0',
277
+ background: `linear-gradient(180deg, ${theme.colors.background_dim.value}00 29.46%, ${theme.colors.background_dim.value}A3 100%);`,
278
+ width: '100%',
279
+ pt: '$8',
280
+ flexShrink: 0,
281
+ transition: 'visibility 0s 0.5s, opacity 0.5s linear',
282
+ visibility: controlsVisible ? `` : `hidden`,
283
+ opacity: controlsVisible ? `1` : '0',
213
284
  }}
214
285
  >
215
- {hlsPlayer && (
216
- <HMSVideoPlayer.Progress
217
- onValueChange={currentTime => {
218
- hlsPlayer.seekTo(currentTime);
286
+ {!isMobile && (
287
+ <HMSVideoPlayer.Controls.Root
288
+ css={{
289
+ p: '$4 $8',
219
290
  }}
220
- hlsPlayer={hlsPlayer}
221
- />
222
- )}
223
-
224
- <HMSVideoPlayer.Controls.Root css={{ p: '$4 $8' }}>
225
- <HMSVideoPlayer.Controls.Left>
226
- <HMSVideoPlayer.PlayButton
227
- onClick={async () => {
228
- isPaused ? await hlsPlayer?.play() : hlsPlayer?.pause();
229
- }}
230
- isPaused={isPaused}
231
- />
232
- <HMSVideoPlayer.Duration hlsPlayer={hlsPlayer} />
233
- <HMSVideoPlayer.Volume hlsPlayer={hlsPlayer} />
234
- <IconButton
235
- variant="standard"
236
- css={{ px: '$2' }}
237
- onClick={async () => {
238
- await hlsPlayer.seekToLivePosition();
239
- setIsVideoLive(true);
240
- }}
241
- key="jump-to-live_btn"
242
- data-testid="jump-to-live_btn"
243
- >
244
- <Tooltip title="Go to Live" side="top">
245
- <Flex justify="center" gap={2} align="center">
246
- <Box
247
- css={{
248
- height: '$4',
249
- width: '$4',
250
- background: isVideoLive ? '$alert_error_default' : '$on_primary_medium',
251
- r: '$1',
252
- }}
253
- />
254
- <Text
255
- variant={{
256
- '@sm': 'xs',
257
- }}
258
- css={{
259
- c: isVideoLive ? '$on_primary_high' : '$on_primary_medium',
260
- }}
261
- >
262
- {isVideoLive ? 'LIVE' : 'GO LIVE'}
263
- </Text>
264
- </Flex>
265
- </Tooltip>
266
- </IconButton>
267
- </HMSVideoPlayer.Controls.Left>
268
-
269
- <HMSVideoPlayer.Controls.Right>
270
- {availableLayers.length > 0 ? (
271
- <HLSQualitySelector
272
- layers={availableLayers}
273
- selection={currentSelectedQuality}
274
- onQualityChange={handleQuality}
275
- isAuto={isUserSelectedAuto}
291
+ >
292
+ <HMSVideoPlayer.Controls.Left>
293
+ <HMSVideoPlayer.PlayButton
294
+ onClick={async () => {
295
+ isPaused ? await hlsPlayer?.play() : hlsPlayer?.pause();
296
+ }}
297
+ isPaused={isPaused}
276
298
  />
277
- ) : null}
278
- {isFullScreenSupported ? (
279
- <FullScreenButton
280
- isFullScreen={isFullScreen}
281
- onToggle={toggle}
282
- icon={isFullScreen ? <ShrinkIcon /> : <ExpandIcon />}
283
- />
284
- ) : null}
285
- </HMSVideoPlayer.Controls.Right>
286
- </HMSVideoPlayer.Controls.Root>
299
+ <HMSVideoPlayer.Duration hlsPlayer={hlsPlayer} />
300
+ <HMSVideoPlayer.Volume hlsPlayer={hlsPlayer} />
301
+ <IconButton
302
+ variant="standard"
303
+ css={{ px: '$2' }}
304
+ onClick={async () => {
305
+ await hlsPlayer.seekToLivePosition();
306
+ setIsVideoLive(true);
307
+ }}
308
+ key="jump-to-live_btn"
309
+ data-testid="jump-to-live_btn"
310
+ >
311
+ <Tooltip title="Go to Live" side="top">
312
+ <Flex justify="center" gap={2} align="center">
313
+ <Box
314
+ css={{
315
+ height: '$4',
316
+ width: '$4',
317
+ background: isVideoLive ? '$alert_error_default' : '$on_primary_medium',
318
+ r: '$1',
319
+ }}
320
+ />
321
+ <Text
322
+ variant={{
323
+ '@sm': 'xs',
324
+ }}
325
+ css={{
326
+ c: isVideoLive ? '$on_surface_high' : '$on_surface_medium',
327
+ }}
328
+ >
329
+ {isVideoLive ? 'LIVE' : 'GO LIVE'}
330
+ </Text>
331
+ </Flex>
332
+ </Tooltip>
333
+ </IconButton>
334
+ </HMSVideoPlayer.Controls.Left>
335
+
336
+ <HMSVideoPlayer.Controls.Right>
337
+ {availableLayers.length > 0 ? (
338
+ <HLSQualitySelector
339
+ layers={availableLayers}
340
+ onOpen={setQualityDropDownOpen}
341
+ open={qualityDropDownOpen}
342
+ selection={currentSelectedQuality}
343
+ onQualityChange={handleQuality}
344
+ isAuto={isUserSelectedAuto}
345
+ />
346
+ ) : null}
347
+ {isFullScreenSupported ? (
348
+ <FullScreenButton
349
+ isFullScreen={isFullScreen}
350
+ onToggle={toggle}
351
+ icon={isFullScreen ? <ShrinkIcon /> : <ExpandIcon />}
352
+ />
353
+ ) : null}
354
+ </HMSVideoPlayer.Controls.Right>
355
+ </HMSVideoPlayer.Controls.Root>
356
+ )}
287
357
  </Flex>
288
358
  </HMSVideoPlayer.Root>
289
359
  </Flex>
290
360
  ) : (
291
361
  <Flex align="center" justify="center" direction="column" css={{ size: '100%', px: '$10' }}>
292
362
  <Flex css={{ c: '$on_surface_high', r: '$round', bg: '$surface_default', p: '$2' }}>
293
- <RadioIcon height={56} width={56} />
363
+ {streamEnded ? <ColoredHandIcon height={56} width={56} /> : <RadioIcon height={56} width={56} />}
294
364
  </Flex>
295
365
  <Text variant="h5" css={{ c: '$on_surface_high', mt: '$10', mb: 0, textAlign: 'center' }}>
296
- Stream yet to start
366
+ {streamEnded ? 'Stream has ended' : 'Stream yet to start'}
297
367
  </Text>
298
368
  <Text variant="md" css={{ textAlign: 'center', mt: '$4', c: '$on_surface_medium' }}>
299
- Sit back and relax
369
+ {streamEnded ? 'Have a nice day!' : 'Sit back and relax'}
300
370
  </Text>
301
371
  </Flex>
302
372
  )}
@@ -2,29 +2,35 @@ import React from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import { ConferencingScreen } from '@100mslive/types-prebuilt';
4
4
  import { selectAppData, selectVideoTrackByPeerID, useHMSStore } from '@100mslive/react-sdk';
5
- // @ts-ignore: No implicit Any
6
- import { Chat } from '../components/Chat/Chat';
7
- // @ts-ignore: No implicit Any
8
- import { ParticipantList } from '../components/Footer/ParticipantList';
5
+ import { SidePaneTabs } from '../components/SidePaneTabs';
9
6
  // @ts-ignore: No implicit Any
10
7
  import { StreamingLanding } from '../components/Streaming/StreamingLanding';
8
+ import { TileCustomisationProps } from '../components/VideoLayouts/GridLayout';
11
9
  // @ts-ignore: No implicit Any
12
10
  import VideoTile from '../components/VideoTile';
13
11
  import { Box, Flex } from '../../Layout';
14
12
  import { config as cssConfig } from '../../Theme';
13
+ import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
15
14
  // @ts-ignore: No implicit Any
16
15
  import { APP_DATA, SIDE_PANE_OPTIONS } from '../common/constants';
17
16
 
18
- const SidePane = ({ screenType }: { screenType: keyof ConferencingScreen }) => {
17
+ const SidePane = ({
18
+ screenType,
19
+ tileProps,
20
+ hideControls = false,
21
+ }: {
22
+ screenType: keyof ConferencingScreen;
23
+ tileProps: TileCustomisationProps;
24
+ hideControls: boolean;
25
+ }) => {
19
26
  const isMobile = useMedia(cssConfig.media.md);
20
27
  const sidepane = useHMSStore(selectAppData(APP_DATA.sidePane));
21
28
  const activeScreensharePeerId = useHMSStore(selectAppData(APP_DATA.activeScreensharePeerId));
22
29
  const trackId = useHMSStore(selectVideoTrackByPeerID(activeScreensharePeerId))?.id;
30
+ const { elements } = useRoomLayoutConferencingScreen();
23
31
  let ViewComponent;
24
- if (sidepane === SIDE_PANE_OPTIONS.PARTICIPANTS) {
25
- ViewComponent = <ParticipantList />;
26
- } else if (sidepane === SIDE_PANE_OPTIONS.CHAT) {
27
- ViewComponent = <Chat screenType={screenType} />;
32
+ if (sidepane === SIDE_PANE_OPTIONS.PARTICIPANTS || sidepane === SIDE_PANE_OPTIONS.CHAT) {
33
+ ViewComponent = <SidePaneTabs screenType={screenType} hideControls={hideControls} active={sidepane} />;
28
34
  } else if (sidepane === SIDE_PANE_OPTIONS.STREAMING) {
29
35
  ViewComponent = <StreamingLanding />;
30
36
  }
@@ -32,7 +38,15 @@ const SidePane = ({ screenType }: { screenType: keyof ConferencingScreen }) => {
32
38
  return null;
33
39
  }
34
40
 
35
- const mwebStreamingChat = isMobile && sidepane === SIDE_PANE_OPTIONS.CHAT;
41
+ const tileLayout = {
42
+ hideParticipantNameOnTile: tileProps?.hide_participant_name_on_tile,
43
+ roundedVideoTile: tileProps?.rounded_video_tile,
44
+ hideAudioMuteOnTile: tileProps?.hide_audio_mute_on_tile,
45
+ hideMetadataOnTile: tileProps?.hide_metadata_on_tile,
46
+ objectFit: tileProps?.video_object_fit,
47
+ };
48
+
49
+ const mwebStreamingChat = isMobile && sidepane === SIDE_PANE_OPTIONS.CHAT && elements?.chat?.is_overlay;
36
50
 
37
51
  return (
38
52
  <Flex
@@ -53,7 +67,7 @@ const SidePane = ({ screenType }: { screenType: keyof ConferencingScreen }) => {
53
67
  width="100%"
54
68
  height={225}
55
69
  rootCSS={{ p: 0, alignSelf: 'start', flexShrink: 0 }}
56
- objectFit="contain"
70
+ {...tileLayout}
57
71
  />
58
72
  )}
59
73
  {!!ViewComponent && (
@@ -1,43 +1,30 @@
1
- import React, { Suspense, useCallback, useEffect } from 'react';
2
- import { HMSException } from '@100mslive/hms-video';
1
+ import React, { Suspense, useEffect } from 'react';
3
2
  import {
4
3
  ConferencingScreen,
5
4
  DefaultConferencingScreen_Elements,
6
5
  HLSLiveStreamingScreen_Elements,
7
6
  } from '@100mslive/types-prebuilt';
8
- import {
9
- selectIsConnectedToRoom,
10
- selectLocalPeerRoleName,
11
- selectPermissions,
12
- useHMSActions,
13
- useHMSStore,
14
- useRecordingStreaming,
15
- } from '@100mslive/react-sdk';
7
+ import { selectIsConnectedToRoom, selectLocalPeerRoleName, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
16
8
  // @ts-ignore: No implicit Any
17
9
  import FullPageProgress from '../components/FullPageProgress';
18
- // @ts-ignore: No implicit Any
19
10
  import { GridLayout } from '../components/VideoLayouts/GridLayout';
20
11
  import { Flex } from '../../Layout';
21
12
  // @ts-ignore: No implicit Any
22
13
  import { EmbedView } from './EmbedView';
23
14
  // @ts-ignore: No implicit Any
24
15
  import { PDFView } from './PDFView';
25
- // @ts-ignore: No implicit Any
26
16
  import SidePane from './SidePane';
27
17
  // @ts-ignore: No implicit Any
28
18
  import { WaitingView } from './WaitingView';
29
19
  // import { useWhiteboardMetadata } from '../plugins/whiteboard';
30
20
  import {
31
21
  usePDFAnnotator,
32
- useSetAppDataByKey,
33
22
  useUrlToEmbed,
34
23
  useWaitingViewerRole,
35
24
  // @ts-ignore: No implicit Any
36
25
  } from '../components/AppData/useUISettings';
37
26
  // @ts-ignore: No implicit Any
38
- import { useShowStreamingUI } from '../common/hooks';
39
- // @ts-ignore: No implicit Any
40
- import { APP_DATA, SESSION_STORE_KEY } from '../common/constants';
27
+ import { SESSION_STORE_KEY } from '../common/constants';
41
28
 
42
29
  // const WhiteboardView = React.lazy(() => import("./WhiteboardView"));
43
30
  // @ts-ignore: No implicit Any
@@ -46,9 +33,11 @@ const HLSView = React.lazy(() => import('./HLSView'));
46
33
  export const VideoStreamingSection = ({
47
34
  screenType,
48
35
  elements,
36
+ hideControls = false,
49
37
  }: {
50
38
  screenType: keyof ConferencingScreen;
51
39
  elements: DefaultConferencingScreen_Elements | HLSLiveStreamingScreen_Elements;
40
+ hideControls: boolean;
52
41
  }) => {
53
42
  const localPeerRole = useHMSStore(selectLocalPeerRoleName);
54
43
  // const { whiteboardOwner: whiteboardShared } = useWhiteboardMetadata();
@@ -57,36 +46,6 @@ export const VideoStreamingSection = ({
57
46
  const waitingViewerRole = useWaitingViewerRole();
58
47
  const urlToIframe = useUrlToEmbed();
59
48
  const pdfAnnotatorActive = usePDFAnnotator();
60
- const { isHLSRunning } = useRecordingStreaming();
61
- const [isHLSStarted, setHLSStarted] = useSetAppDataByKey(APP_DATA.hlsStarted);
62
- const permissions = useHMSStore(selectPermissions);
63
- const showStreamingUI = useShowStreamingUI();
64
-
65
- const startHLS = useCallback(async () => {
66
- try {
67
- if (isHLSStarted) {
68
- return;
69
- }
70
- setHLSStarted(true);
71
- await hmsActions.startHLSStreaming();
72
- } catch (error) {
73
- if ((error as HMSException).message?.includes('beam already started')) {
74
- return;
75
- }
76
- setHLSStarted(false);
77
- }
78
- }, [hmsActions, isHLSStarted, setHLSStarted]);
79
-
80
- useEffect(() => {
81
- if (!isConnected) {
82
- return;
83
- }
84
- // Is a streaming kit and broadcaster joins
85
- if (permissions?.hlsStreaming && !isHLSRunning && showStreamingUI) {
86
- startHLS();
87
- }
88
- // eslint-disable-next-line react-hooks/exhaustive-deps
89
- }, [isConnected]);
90
49
 
91
50
  useEffect(() => {
92
51
  if (!isConnected) {
@@ -125,7 +84,12 @@ export const VideoStreamingSection = ({
125
84
  }}
126
85
  >
127
86
  {ViewComponent}
128
- <SidePane screenType={screenType} />
87
+ <SidePane
88
+ screenType={screenType}
89
+ // @ts-ignore
90
+ tileProps={(elements as DefaultConferencingScreen_Elements)?.video_tile_layout?.grid}
91
+ hideControls={hideControls}
92
+ />
129
93
  </Flex>
130
94
  </Suspense>
131
95
  );
@@ -1,9 +1,16 @@
1
1
  import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
2
  import { useMedia } from 'react-use';
3
- import { selectLocalPeerID, selectPeerNameByID, useHMSStore, useHMSVanillaStore } from '@100mslive/react-sdk';
3
+ import {
4
+ selectLocalPeerID,
5
+ selectPeerNameByID,
6
+ useCustomEvent,
7
+ useHMSStore,
8
+ useHMSVanillaStore,
9
+ } from '@100mslive/react-sdk';
4
10
  import { Box, Flex } from '../../Layout';
5
11
  import { Text } from '../../Text';
6
12
  import { config as cssConfig, keyframes } from '../../Theme';
13
+ import { EMOJI_REACTION_TYPE } from '../common/constants';
7
14
 
8
15
  let emojiCount = 1;
9
16
 
@@ -42,7 +49,7 @@ export function FlyingEmoji() {
42
49
  const startingPoints = useMemo(() => getStartingPoints(isMobile), [isMobile]);
43
50
 
44
51
  const showFlyingEmoji = useCallback(
45
- (emojiId, senderId) => {
52
+ ({ emojiId, senderId }) => {
46
53
  if (!emojiId || !senderId || document.hidden) {
47
54
  return;
48
55
  }
@@ -67,6 +74,11 @@ export function FlyingEmoji() {
67
74
  [localPeerId, vanillaStore, startingPoints],
68
75
  );
69
76
 
77
+ useCustomEvent({
78
+ type: EMOJI_REACTION_TYPE,
79
+ onEvent: showFlyingEmoji,
80
+ });
81
+
70
82
  useEffect(() => {
71
83
  window.showFlyingEmoji = showFlyingEmoji;
72
84
  }, [showFlyingEmoji]);