@100mslive/roomkit-react 0.2.8-alpha.1 → 0.2.8-alpha.10

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 (105) hide show
  1. package/dist/HLSView-FBEGJ3L7.js +1396 -0
  2. package/dist/HLSView-FBEGJ3L7.js.map +7 -0
  3. package/dist/Prebuilt/common/hooks.d.ts +3 -0
  4. package/dist/Prebuilt/components/Chat/MwebChatOption.d.ts +1 -1
  5. package/dist/Prebuilt/components/HMSVideo/FullscreenButton.d.ts +5 -0
  6. package/dist/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.d.ts +5 -0
  7. package/dist/Prebuilt/components/HMSVideo/HLSCaptionSelector.d.ts +1 -2
  8. package/dist/Prebuilt/components/HMSVideo/HLSQualitySelector.d.ts +13 -0
  9. package/dist/Prebuilt/components/HMSVideo/MwebHLSViewTitle.d.ts +2 -0
  10. package/dist/Prebuilt/components/HMSVideo/PlayButton.d.ts +6 -0
  11. package/dist/Prebuilt/components/HMSVideo/PlayPauseButton.d.ts +6 -0
  12. package/dist/Prebuilt/components/HMSVideo/PlayerContext.d.ts +8 -0
  13. package/dist/Prebuilt/components/HMSVideo/SeekControls.d.ts +7 -0
  14. package/dist/Prebuilt/components/HMSVideo/VideoProgress.d.ts +5 -0
  15. package/dist/Prebuilt/components/HMSVideo/VideoTime.d.ts +2 -0
  16. package/dist/Prebuilt/components/HMSVideo/VolumeControl.d.ts +2 -0
  17. package/dist/Prebuilt/components/HMSVideo/index.d.ts +26 -0
  18. package/dist/Prebuilt/components/HMSVideo/utils.d.ts +8 -0
  19. package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +2 -1
  20. package/dist/Prebuilt/components/Leave/LeaveRoom.d.ts +2 -1
  21. package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +2 -3
  22. package/dist/Prebuilt/components/MwebLandscapePrompt.d.ts +1 -1
  23. package/dist/Prebuilt/components/RaiseHand.d.ts +5 -0
  24. package/dist/Prebuilt/components/SidePaneTabs.d.ts +1 -1
  25. package/dist/Sheet/Sheet.d.ts +1 -0
  26. package/dist/{chunk-ERIM35YN.js → chunk-R2JJJQR3.js} +1539 -1173
  27. package/dist/chunk-R2JJJQR3.js.map +7 -0
  28. package/dist/index.cjs.js +2709 -1898
  29. package/dist/index.cjs.js.map +4 -4
  30. package/dist/index.js +1 -1
  31. package/dist/meta.cjs.json +777 -290
  32. package/dist/meta.esbuild.json +796 -298
  33. package/package.json +7 -6
  34. package/src/Button/Button.tsx +4 -4
  35. package/src/Fieldset/Fieldset.tsx +1 -1
  36. package/src/Input/PasswordInput.stories.tsx +1 -1
  37. package/src/Pagination/StyledPagination.stories.tsx +2 -2
  38. package/src/Prebuilt/IconButton.tsx +1 -1
  39. package/src/Prebuilt/common/hooks.ts +21 -0
  40. package/src/Prebuilt/components/AppData/useSidepane.js +34 -7
  41. package/src/Prebuilt/components/AuthToken.jsx +1 -1
  42. package/src/Prebuilt/components/Chat/Chat.tsx +41 -1
  43. package/src/Prebuilt/components/Chat/ChatFooter.tsx +33 -13
  44. package/src/Prebuilt/components/Chat/MwebChatOption.tsx +1 -1
  45. package/src/Prebuilt/components/ConferenceScreen.tsx +48 -7
  46. package/src/Prebuilt/components/EmojiReaction.jsx +33 -23
  47. package/src/Prebuilt/components/Footer/Footer.tsx +0 -1
  48. package/src/Prebuilt/components/Footer/RoleOptions.tsx +138 -125
  49. package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -1
  50. package/src/Prebuilt/components/HMSVideo/FullscreenButton.tsx +13 -0
  51. package/src/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.tsx +72 -0
  52. package/src/Prebuilt/components/HMSVideo/HLSCaptionSelector.tsx +4 -2
  53. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.tsx +248 -0
  54. package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +17 -7
  55. package/src/Prebuilt/components/HMSVideo/MwebHLSViewTitle.tsx +84 -0
  56. package/src/Prebuilt/components/HMSVideo/PlayButton.tsx +27 -0
  57. package/src/Prebuilt/components/HMSVideo/PlayPauseButton.tsx +27 -0
  58. package/src/Prebuilt/components/HMSVideo/PlayerContext.tsx +15 -0
  59. package/src/Prebuilt/components/HMSVideo/SeekControls.tsx +22 -0
  60. package/src/Prebuilt/components/HMSVideo/VideoProgress.tsx +95 -0
  61. package/src/Prebuilt/components/HMSVideo/VideoTime.tsx +43 -0
  62. package/src/Prebuilt/components/HMSVideo/{VolumeControl.jsx → VolumeControl.tsx} +6 -4
  63. package/src/Prebuilt/components/HMSVideo/{index.js → index.ts} +6 -2
  64. package/src/Prebuilt/components/HMSVideo/{HMSVIdeoUtils.js → utils.ts} +5 -5
  65. package/src/Prebuilt/components/Header/StreamActions.tsx +1 -1
  66. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.tsx +1 -1
  67. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +50 -46
  68. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +15 -4
  69. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +46 -27
  70. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +3 -1
  71. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +37 -31
  72. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +12 -8
  73. package/src/Prebuilt/components/MwebLandscapePrompt.tsx +14 -3
  74. package/src/Prebuilt/components/Notifications/HandRaisedNotifications.tsx +5 -2
  75. package/src/Prebuilt/components/Notifications/PeerNotifications.tsx +1 -1
  76. package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +19 -8
  77. package/src/Prebuilt/components/Polls/Voting/Voting.tsx +3 -2
  78. package/src/Prebuilt/components/Polls/common/OptionInputWithDelete.tsx +1 -1
  79. package/src/Prebuilt/components/Polls/common/utils.ts +2 -2
  80. package/src/Prebuilt/components/RaiseHand.tsx +24 -0
  81. package/src/Prebuilt/components/RoomDetails/RoomDetailsPane.tsx +41 -14
  82. package/src/Prebuilt/components/SidePaneTabs.tsx +56 -48
  83. package/src/Prebuilt/components/StatsForNerds.jsx +14 -6
  84. package/src/Prebuilt/components/Streaming/Common.jsx +1 -1
  85. package/src/Prebuilt/components/TileMenu/TileMenuContent.tsx +2 -2
  86. package/src/Prebuilt/components/Toast/ToastBatcher.js +8 -1
  87. package/src/Prebuilt/components/Toast/ToastConfig.jsx +17 -0
  88. package/src/Prebuilt/components/pdfAnnotator/shareScreenOptions.jsx +2 -2
  89. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +1 -1
  90. package/src/Prebuilt/layouts/HLSView.jsx +359 -178
  91. package/src/Prebuilt/layouts/SidePane.tsx +145 -59
  92. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +22 -2
  93. package/src/Prebuilt/primitives/DialogContent.jsx +1 -1
  94. package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +1 -1
  95. package/src/Sheet/Sheet.tsx +7 -3
  96. package/dist/HLSView-SJCF34GE.js +0 -987
  97. package/dist/HLSView-SJCF34GE.js.map +0 -7
  98. package/dist/chunk-ERIM35YN.js.map +0 -7
  99. package/src/Prebuilt/components/HMSVideo/FullscreenButton.jsx +0 -18
  100. package/src/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.jsx +0 -35
  101. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +0 -127
  102. package/src/Prebuilt/components/HMSVideo/PlayButton.jsx +0 -13
  103. package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +0 -76
  104. package/src/Prebuilt/components/HMSVideo/VideoTime.jsx +0 -33
  105. package/src/Prebuilt/components/RaiseHand.jsx +0 -17
@@ -3,6 +3,7 @@ import { useFullscreen, useMedia, usePrevious, useToggle } from 'react-use';
3
3
  import { HLSPlaybackState, HMSHLSPlayer, HMSHLSPlayerEvents } from '@100mslive/hls-player';
4
4
  import screenfull from 'screenfull';
5
5
  import {
6
+ HLSPlaylistType,
6
7
  HMSNotificationTypes,
7
8
  selectAppData,
8
9
  selectHLSState,
@@ -13,61 +14,83 @@ import {
13
14
  useHMSStore,
14
15
  useHMSVanillaStore,
15
16
  } from '@100mslive/react-sdk';
16
- import { ColoredHandIcon, ExpandIcon, GoLiveIcon, PlayIcon, ShrinkIcon } from '@100mslive/react-icons';
17
+ import { BackwardArrowIcon, ColoredHandIcon, ForwardArrowIcon, GoLiveIcon } from '@100mslive/react-icons';
18
+ import { ChatToggle } from '../components/Footer/ChatToggle';
17
19
  import { HlsStatsOverlay } from '../components/HlsStatsOverlay';
18
20
  import { HMSVideoPlayer } from '../components/HMSVideo';
19
21
  import { FullScreenButton } from '../components/HMSVideo/FullscreenButton';
20
22
  import { HLSAutoplayBlockedPrompt } from '../components/HMSVideo/HLSAutoplayBlockedPrompt';
21
23
  import { HLSCaptionSelector } from '../components/HMSVideo/HLSCaptionSelector';
22
24
  import { HLSQualitySelector } from '../components/HMSVideo/HLSQualitySelector';
25
+ import { HLSViewTitle } from '../components/HMSVideo/MwebHLSViewTitle';
26
+ import { HMSPlayerContext } from '../components/HMSVideo/PlayerContext';
27
+ import { LeaveRoom } from '../components/Leave/LeaveRoom';
23
28
  import { ToastManager } from '../components/Toast/ToastManager';
24
29
  import { Button } from '../../Button';
25
30
  import { IconButton } from '../../IconButton';
26
31
  import { Box, Flex } from '../../Layout';
27
32
  import { Loading } from '../../Loading';
28
33
  import { Text } from '../../Text';
29
- import { config, useTheme } from '../../Theme';
34
+ import { config, theme, useTheme } from '../../Theme';
30
35
  import { Tooltip } from '../../Tooltip';
31
- import { usePollViewToggle } from '../components/AppData/useSidepane';
32
- import { APP_DATA, EMOJI_REACTION_TYPE } from '../common/constants';
36
+ import { usePollViewToggle, useSidepaneToggle } from '../components/AppData/useSidepane';
37
+ import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
38
+ import { useIsLandscape } from '../common/hooks';
39
+ import { APP_DATA, EMOJI_REACTION_TYPE, SIDE_PANE_OPTIONS } from '../common/constants';
33
40
 
34
41
  let hlsPlayer;
35
42
  const toastMap = {};
36
43
 
37
44
  const HLSView = () => {
38
45
  const videoRef = useRef(null);
39
- const hlsViewRef = useRef(null);
46
+ const hlsViewRef = useRef();
40
47
  const hlsState = useHMSStore(selectHLSState);
41
48
  const enablHlsStats = useHMSStore(selectAppData(APP_DATA.hlsStats));
49
+ const { elements, screenType } = useRoomLayoutConferencingScreen();
42
50
  const notification = useHMSNotifications(HMSNotificationTypes.POLL_STOPPED);
43
51
  const hmsActions = useHMSActions();
44
- const { themeType, theme } = useTheme();
52
+ const { themeType } = useTheme();
45
53
  const [streamEnded, setStreamEnded] = useState(false);
46
54
  let [hlsStatsState, setHlsStatsState] = useState(null);
47
55
  const hlsUrl = hlsState.variants[0]?.url;
48
56
  const [availableLayers, setAvailableLayers] = useState([]);
49
57
  const [isVideoLive, setIsVideoLive] = useState(true);
50
- const [isUserSelectedAuto, setIsUserSelectedAuto] = useState(true);
51
58
  const [isCaptionEnabled, setIsCaptionEnabled] = useState(true);
52
59
  const [hasCaptions, setHasCaptions] = useState(false);
53
60
  const [currentSelectedQuality, setCurrentSelectedQuality] = useState(null);
54
61
  const [isHlsAutoplayBlocked, setIsHlsAutoplayBlocked] = useState(false);
62
+ const [isSeekEnabled, setIsSeekEnabled] = useState(false);
55
63
  const [isPaused, setIsPaused] = useState(false);
56
- const isFullScreenSupported = screenfull.isEnabled;
57
64
  const [show, toggle] = useToggle(false);
58
- const [controlsVisible, setControlsVisible] = useState(true);
59
- const controlsRef = useRef();
60
- const controlsTimerRef = useRef();
61
- const [qualityDropDownOpen, setQualityDropDownOpen] = useState(false);
62
65
  const lastHlsUrl = usePrevious(hlsUrl);
63
66
  const togglePollView = usePollViewToggle();
64
67
  const vanillaStore = useHMSVanillaStore();
68
+ const [controlsVisible, setControlsVisible] = useState(true);
69
+ const [isUserSelectedAuto, setIsUserSelectedAuto] = useState(true);
70
+ const [qualityDropDownOpen, setQualityDropDownOpen] = useState(false);
71
+ const controlsRef = useRef(null);
72
+ const controlsTimerRef = useRef();
73
+ const sidepane = useHMSStore(selectAppData(APP_DATA.sidePane));
74
+ const toggleChat = useSidepaneToggle(SIDE_PANE_OPTIONS.CHAT);
75
+ const [seekProgress, setSeekProgress] = useState(false);
76
+ const showChat = !!elements?.chat;
77
+ const isFullScreenSupported = screenfull.isEnabled;
65
78
 
66
79
  const isMobile = useMedia(config.media.md);
80
+ const isLandscape = useIsLandscape();
81
+
67
82
  const isFullScreen = useFullscreen(hlsViewRef, show, {
68
83
  onClose: () => toggle(false),
69
84
  });
70
85
  const [showLoader, setShowLoader] = useState(false);
86
+
87
+ const isMwebHLSStream = screenType === 'hls_live_streaming' && isMobile;
88
+
89
+ useEffect(() => {
90
+ if (sidepane === '' && isMwebHLSStream && showChat) {
91
+ toggleChat();
92
+ }
93
+ }, [sidepane, isMwebHLSStream, toggleChat, showChat]);
71
94
  // FIXME: move this logic to player controller in next release
72
95
  useEffect(() => {
73
96
  /**
@@ -111,6 +134,15 @@ const HLSView = () => {
111
134
  };
112
135
  }, [hlsUrl]);
113
136
 
137
+ const handleQuality = useCallback(
138
+ quality => {
139
+ if (hlsPlayer) {
140
+ setIsUserSelectedAuto(quality.height?.toString().toLowerCase() === 'auto');
141
+ hlsPlayer?.setLayer(quality);
142
+ }
143
+ },
144
+ [availableLayers], //eslint-disable-line
145
+ );
114
146
  /**
115
147
  * initialize HMSHLSPlayer and add event listeners.
116
148
  */
@@ -139,25 +171,27 @@ const HLSView = () => {
139
171
  const poll = vanillaStore.getState(selectPollByID(pollId));
140
172
  const pollStartedBy = vanillaStore.getState(selectPeerNameByID(poll.startedBy)) || 'Participant';
141
173
  // launch poll
142
- const toastID = ToastManager.addToast({
143
- title: `${pollStartedBy} started a ${poll.type}: ${poll.title}`,
144
- action: (
145
- <Button
146
- onClick={() => togglePollView(pollId)}
147
- variant="standard"
148
- css={{
149
- backgroundColor: '$surface_bright',
150
- fontWeight: '$semiBold',
151
- color: '$on_surface_high',
152
- p: '$xs $md',
153
- }}
154
- >
155
- {poll.type === 'quiz' ? 'Answer' : 'Vote'}
156
- </Button>
157
- ),
158
- duration: Infinity,
159
- });
160
- toastMap[pollId] = toastID;
174
+ if (!toastMap[pollId]) {
175
+ const toastID = ToastManager.addToast({
176
+ title: `${pollStartedBy} started a ${poll.type}: ${poll.title}`,
177
+ action: (
178
+ <Button
179
+ onClick={() => togglePollView(pollId)}
180
+ variant="standard"
181
+ css={{
182
+ backgroundColor: '$surface_bright',
183
+ fontWeight: '$semiBold',
184
+ color: '$on_surface_high',
185
+ p: '$xs $md',
186
+ }}
187
+ >
188
+ {poll.type === 'quiz' ? 'Answer' : 'Vote'}
189
+ </Button>
190
+ ),
191
+ duration: Infinity,
192
+ });
193
+ toastMap[pollId] = toastID;
194
+ }
161
195
  return;
162
196
  }
163
197
  switch (parsedPayload.type) {
@@ -210,10 +244,9 @@ const HLSView = () => {
210
244
  hlsPlayer.off(HMSHLSPlayerEvents.MANIFEST_LOADED, manifestLoadedHandler);
211
245
  hlsPlayer.off(HMSHLSPlayerEvents.LAYER_UPDATED, layerUpdatedHandler);
212
246
  hlsPlayer.reset();
213
- hlsPlayer = null;
214
247
  };
215
248
  }
216
- }, [hlsUrl]);
249
+ }, [hlsUrl, togglePollView, vanillaStore]);
217
250
 
218
251
  /**
219
252
  * initialize and subscribe to hlsState
@@ -239,16 +272,6 @@ const HLSView = () => {
239
272
  }
240
273
  };
241
274
 
242
- const handleQuality = useCallback(
243
- quality => {
244
- if (hlsPlayer) {
245
- setIsUserSelectedAuto(quality.height.toString().toLowerCase() === 'auto');
246
- hlsPlayer.setLayer(quality);
247
- }
248
- },
249
- [availableLayers], //eslint-disable-line
250
- );
251
-
252
275
  const sfnOverlayClose = () => {
253
276
  hmsActions.setAppData(APP_DATA.hlsStats, !enablHlsStats);
254
277
  };
@@ -258,62 +281,137 @@ const HLSView = () => {
258
281
  if (controlsTimerRef.current) {
259
282
  clearTimeout(controlsTimerRef.current);
260
283
  }
261
- controlsTimerRef.current = setTimeout(() => {
262
- setControlsVisible(false);
263
- }, 5000);
264
284
  }
265
285
  if (!isFullScreen && controlsTimerRef.current) {
266
286
  clearTimeout(controlsTimerRef.current);
267
287
  }
288
+ controlsTimerRef.current = setTimeout(() => {
289
+ if (!seekProgress) {
290
+ setControlsVisible(false);
291
+ }
292
+ }, 5000);
268
293
  return () => {
269
294
  if (controlsTimerRef.current) {
270
295
  clearTimeout(controlsTimerRef.current);
271
296
  }
272
297
  };
273
- }, [controlsVisible, isFullScreen, qualityDropDownOpen]);
298
+ }, [controlsVisible, isFullScreen, seekProgress, qualityDropDownOpen]);
274
299
 
300
+ const onSeekTo = useCallback(seek => {
301
+ hlsPlayer?.seekTo(videoRef.current?.currentTime + seek);
302
+ }, []);
303
+ const onDoubleClickHandler = useCallback(
304
+ event => {
305
+ if (!(isMobile || isLandscape) || hlsState?.variants[0]?.playlist_type !== HLSPlaylistType.DVR) {
306
+ return;
307
+ }
308
+ const sidePercentage = (event.screenX * 100) / event.target.clientWidth;
309
+ setIsSeekEnabled(true);
310
+ // there is space for pause/unpause button
311
+ if (sidePercentage < 45) {
312
+ onSeekTo(-10);
313
+ } else {
314
+ onSeekTo(10);
315
+ }
316
+ setTimeout(() => {
317
+ setIsSeekEnabled(false);
318
+ }, 200);
319
+ },
320
+ [hlsState?.variants, isLandscape, isMobile, onSeekTo],
321
+ );
322
+ const onClickHandler = useCallback(() => {
323
+ if (!(isMobile || isLandscape)) {
324
+ return;
325
+ }
326
+ setControlsVisible(value => !value);
327
+ if (controlsTimerRef.current) {
328
+ clearTimeout(controlsTimerRef.current);
329
+ }
330
+ }, [isLandscape, isMobile]);
275
331
  const onHoverHandler = useCallback(
276
332
  event => {
333
+ event.preventDefault();
334
+ if (isMobile || isLandscape) {
335
+ return;
336
+ }
277
337
  if (event.type === 'mouseenter' || qualityDropDownOpen) {
278
338
  setControlsVisible(true);
279
339
  return;
280
340
  }
281
- if (event.type === 'mouseleave') {
341
+ if (event.type === 'mouseleave' && !seekProgress) {
282
342
  setControlsVisible(false);
283
- } else if (isFullScreen && !controlsVisible && event.type === 'mousemove') {
343
+ } else if (!controlsVisible && event.type === 'mousemove') {
284
344
  setControlsVisible(true);
285
345
  if (controlsTimerRef.current) {
286
346
  clearTimeout(controlsTimerRef.current);
287
347
  }
288
348
  }
289
349
  },
290
- [controlsVisible, isFullScreen, qualityDropDownOpen],
350
+ [controlsVisible, isLandscape, isMobile, qualityDropDownOpen, seekProgress],
291
351
  );
292
352
 
353
+ if (!hlsUrl || streamEnded) {
354
+ return (
355
+ <Flex
356
+ key="hls-viewer"
357
+ id={`hls-viewer-${themeType}`}
358
+ ref={hlsViewRef}
359
+ direction={isMobile || isLandscape ? 'column' : 'row'}
360
+ justify="center"
361
+ css={{
362
+ flex: isLandscape ? '2 1 0' : '1 1 0',
363
+ }}
364
+ >
365
+ <Flex align="center" justify="center" direction="column" css={{ size: '100%', px: '$10' }}>
366
+ <Flex css={{ c: '$on_surface_high', r: '$round', bg: '$surface_default', p: '$2' }}>
367
+ {streamEnded ? <ColoredHandIcon height={56} width={56} /> : <GoLiveIcon height={56} width={56} />}
368
+ </Flex>
369
+ <Text variant="h5" css={{ c: '$on_surface_high', mt: '$10', mb: 0, textAlign: 'center' }}>
370
+ {streamEnded ? 'Stream has ended' : 'Stream yet to start'}
371
+ </Text>
372
+ <Text variant="md" css={{ textAlign: 'center', mt: '$4', c: '$on_surface_medium' }}>
373
+ {streamEnded ? 'Have a nice day!' : 'Sit back and relax'}
374
+ </Text>
375
+ </Flex>
376
+ </Flex>
377
+ );
378
+ }
293
379
  return (
294
380
  <Flex
295
381
  key="hls-viewer"
296
382
  id={`hls-viewer-${themeType}`}
297
383
  ref={hlsViewRef}
384
+ direction={isMobile || isLandscape ? 'column' : 'row'}
385
+ justify="center"
298
386
  css={{
299
- size: '100%',
387
+ flex: isLandscape ? '2 1 0' : '1 1 0',
300
388
  }}
301
389
  >
302
- {hlsStatsState?.url && enablHlsStats ? (
303
- <HlsStatsOverlay hlsStatsState={hlsStatsState} onClose={sfnOverlayClose} />
304
- ) : null}
305
- {hlsUrl && !streamEnded ? (
390
+ {hlsViewRef.current && (isMobile || isLandscape) && (
391
+ <Box css={{ position: 'fixed', left: '$4', top: '$4', zIndex: 11 }}>
392
+ <LeaveRoom screenType={screenType} container={hlsViewRef.current} />
393
+ </Box>
394
+ )}
395
+
396
+ <HMSPlayerContext.Provider value={{ hlsPlayer }}>
397
+ {hlsStatsState?.url && enablHlsStats && !(isMobile || isLandscape) ? (
398
+ <HlsStatsOverlay hlsStatsState={hlsStatsState} onClose={sfnOverlayClose} />
399
+ ) : null}
306
400
  <Flex
307
401
  id="hls-player-container"
308
402
  align="center"
309
403
  justify="center"
310
404
  css={{
311
- width: '100%',
405
+ size: '100%',
312
406
  margin: '0 auto',
313
- height: '100%',
407
+ '@md': {
408
+ height: 'auto',
409
+ },
314
410
  }}
315
411
  >
316
- <HLSAutoplayBlockedPrompt open={isHlsAutoplayBlocked} unblockAutoPlay={unblockAutoPlay} />
412
+ {!(isMobile || isLandscape) && (
413
+ <HLSAutoplayBlockedPrompt open={isHlsAutoplayBlocked} unblockAutoPlay={unblockAutoPlay} />
414
+ )}
317
415
  {showLoader && (
318
416
  <Flex
319
417
  align="center"
@@ -330,135 +428,218 @@ const HLSView = () => {
330
428
  onMouseEnter={onHoverHandler}
331
429
  onMouseMove={onHoverHandler}
332
430
  onMouseLeave={onHoverHandler}
431
+ onClick={onClickHandler}
432
+ onDoubleClick={e => {
433
+ onDoubleClickHandler(e);
434
+ }}
333
435
  >
334
- {isMobile && isPaused && (
335
- <Box
336
- css={{
337
- position: 'absolute',
338
- top: '40%',
339
- left: '50%',
340
- transform: 'translateY(-40%) translateX(-50%)',
341
- padding: '$8 14px $8 18px',
342
- display: 'inline-flex',
343
- r: '50%',
344
- gap: '$1',
345
- bg: '$primary_default',
346
- zIndex: 21,
347
- }}
348
- >
349
- <IconButton onClick={async () => await hlsPlayer?.play()} data-testid="play_btn">
350
- <PlayIcon width="60px" height="60px" />
351
- </IconButton>
352
- </Box>
353
- )}
354
- <Flex
355
- ref={controlsRef}
356
- direction="column"
357
- justify="flex-end"
358
- align="flex-start"
359
- css={{
360
- position: 'absolute',
361
- bottom: '0',
362
- left: '0',
363
- background: `linear-gradient(180deg, ${theme.colors.background_dim.value}00 29.46%, ${theme.colors.background_dim.value}A3 100%);`,
364
- width: '100%',
365
- pt: '$8',
366
- flexShrink: 0,
367
- transition: 'visibility 0s 0.5s, opacity 0.5s linear',
368
- visibility: controlsVisible ? `` : `hidden`,
369
- opacity: controlsVisible ? `1` : '0',
370
- }}
371
- >
372
- {!isMobile && (
373
- <HMSVideoPlayer.Controls.Root
374
- css={{
375
- p: '$4 $8',
376
- }}
377
- >
378
- <HMSVideoPlayer.Controls.Left>
379
- <HMSVideoPlayer.PlayButton
380
- onClick={async () => {
381
- isPaused ? await hlsPlayer?.play() : hlsPlayer?.pause();
436
+ <>
437
+ {isMobile || isLandscape ? (
438
+ <>
439
+ {!showLoader && hlsState?.variants[0]?.playlist_type === HLSPlaylistType.DVR && (
440
+ <Flex
441
+ align="center"
442
+ justify="center"
443
+ css={{
444
+ position: 'absolute',
445
+ bg: '#00000066',
446
+ display: 'inline-flex',
447
+ gap: '$2',
448
+ zIndex: 1,
449
+ size: '100%',
450
+ visibility: controlsVisible ? `` : `hidden`,
451
+ opacity: controlsVisible ? `1` : '0',
382
452
  }}
383
- isPaused={isPaused}
384
- />
385
- <HMSVideoPlayer.Duration hlsPlayer={hlsPlayer} />
386
- <HMSVideoPlayer.Volume hlsPlayer={hlsPlayer} />
387
- <IconButton
388
- variant="standard"
389
- css={{ px: '$2' }}
390
- onClick={async () => {
391
- await hlsPlayer.seekToLivePosition();
392
- setIsVideoLive(true);
453
+ >
454
+ <HMSVideoPlayer.Seeker
455
+ title="backward"
456
+ css={{
457
+ visibility: isSeekEnabled ? `` : `hidden`,
458
+ opacity: isSeekEnabled ? `1` : '0',
459
+ }}
460
+ >
461
+ <BackwardArrowIcon width={32} height={32} />
462
+ </HMSVideoPlayer.Seeker>
463
+ <Box
464
+ css={{
465
+ bg: 'rgba(0, 0, 0, 0.6)',
466
+ r: '$round',
467
+ }}
468
+ >
469
+ <HMSVideoPlayer.PlayPauseButton isPaused={isPaused} width={48} height={48} />
470
+ </Box>
471
+ <HMSVideoPlayer.Seeker
472
+ title="forward"
473
+ css={{
474
+ visibility: isSeekEnabled ? `` : `hidden`,
475
+ opacity: isSeekEnabled ? `1` : '0',
476
+ }}
477
+ >
478
+ <ForwardArrowIcon width={32} height={32} />
479
+ </HMSVideoPlayer.Seeker>
480
+ </Flex>
481
+ )}
482
+ <Flex
483
+ ref={controlsRef}
484
+ direction="column"
485
+ justify="start"
486
+ align="start"
487
+ css={{
488
+ position: 'absolute',
489
+ top: '0',
490
+ left: '0',
491
+ width: '100%',
492
+ flexShrink: 0,
493
+ zIndex: 1,
494
+ visibility: controlsVisible ? `` : `hidden`,
495
+ opacity: controlsVisible ? `1` : '0',
496
+ }}
497
+ >
498
+ <HMSVideoPlayer.Controls.Root
499
+ css={{
500
+ p: '$4 $8',
393
501
  }}
394
- key="jump-to-live_btn"
395
- data-testid="jump-to-live_btn"
396
502
  >
397
- <Tooltip title="Go to Live" side="top">
398
- <Flex justify="center" gap={2} align="center">
399
- <Box
400
- css={{
401
- height: '$4',
402
- width: '$4',
403
- background: isVideoLive ? '$alert_error_default' : '$on_primary_medium',
404
- r: '$1',
405
- }}
503
+ <HMSVideoPlayer.Controls.Right>
504
+ {isLandscape && <ChatToggle />}
505
+ {hasCaptions && !isHlsAutoplayBlocked && <HLSCaptionSelector isEnabled={isCaptionEnabled} />}
506
+ {hlsViewRef.current && availableLayers.length > 0 && !isHlsAutoplayBlocked ? (
507
+ <HLSQualitySelector
508
+ layers={availableLayers}
509
+ onOpenChange={setQualityDropDownOpen}
510
+ open={qualityDropDownOpen}
511
+ selection={currentSelectedQuality}
512
+ onQualityChange={handleQuality}
513
+ isAuto={isUserSelectedAuto}
514
+ containerRef={hlsViewRef.current}
406
515
  />
407
- <Text
408
- variant={{
409
- '@sm': 'xs',
410
- }}
411
- css={{
412
- c: isVideoLive ? '$on_surface_high' : '$on_surface_medium',
413
- }}
414
- >
415
- {isVideoLive ? 'LIVE' : 'GO LIVE'}
416
- </Text>
417
- </Flex>
418
- </Tooltip>
419
- </IconButton>
420
- </HMSVideoPlayer.Controls.Left>
516
+ ) : null}
517
+ <HLSAutoplayBlockedPrompt open={isHlsAutoplayBlocked} unblockAutoPlay={unblockAutoPlay} />
518
+ </HMSVideoPlayer.Controls.Right>
519
+ </HMSVideoPlayer.Controls.Root>
520
+ </Flex>
521
+ </>
522
+ ) : null}
523
+ {controlsVisible && (
524
+ <Flex
525
+ ref={controlsRef}
526
+ direction={isMobile ? 'columnReverse' : 'column'}
527
+ justify="end"
528
+ align="start"
529
+ css={{
530
+ position: 'absolute',
531
+ bottom: isFullScreen && hlsState?.variants[0]?.playlist_type === HLSPlaylistType.DVR ? '$8' : '0',
532
+ left: '0',
533
+ zIndex: 1,
534
+ background:
535
+ isMobile || isLandscape
536
+ ? ''
537
+ : `linear-gradient(180deg, ${theme.colors.background_dim.value}00 29.46%, ${theme.colors.background_dim.value}A3 100%);`,
538
+ width: '100%',
539
+ pt: '$8',
540
+ flexShrink: 0,
541
+ transition: 'visibility 0s 0.5s, opacity 0.5s linear',
542
+ }}
543
+ >
544
+ {hlsState?.variants[0]?.playlist_type === HLSPlaylistType.DVR ? (
545
+ <HMSVideoPlayer.Progress seekProgress={seekProgress} setSeekProgress={setSeekProgress} />
546
+ ) : null}
547
+ <HMSVideoPlayer.Controls.Root
548
+ css={{
549
+ p: '$4 $8',
550
+ }}
551
+ >
552
+ <HMSVideoPlayer.Controls.Left>
553
+ {!(isMobile || isLandscape) && (
554
+ <>
555
+ {hlsState?.variants[0]?.playlist_type === HLSPlaylistType.DVR ? (
556
+ <>
557
+ <HMSVideoPlayer.Seeker
558
+ onClick={() => {
559
+ onSeekTo(-10);
560
+ }}
561
+ title="backward"
562
+ >
563
+ <BackwardArrowIcon width={20} height={20} />
564
+ </HMSVideoPlayer.Seeker>
565
+ <HMSVideoPlayer.PlayPauseButton isPaused={isPaused} />
566
+ <HMSVideoPlayer.Seeker
567
+ onClick={() => {
568
+ onSeekTo(10);
569
+ }}
570
+ title="forward"
571
+ >
572
+ <ForwardArrowIcon width={20} height={20} />
573
+ </HMSVideoPlayer.Seeker>
574
+ {!isVideoLive ? <HMSVideoPlayer.Duration /> : null}
575
+ </>
576
+ ) : null}
577
+ <HMSVideoPlayer.Volume />
578
+ </>
579
+ )}
580
+ <IconButton
581
+ css={{ px: '$2' }}
582
+ onClick={async () => {
583
+ await hlsPlayer?.seekToLivePosition();
584
+ setIsVideoLive(true);
585
+ }}
586
+ key="jump-to-live_btn"
587
+ data-testid="jump-to-live_btn"
588
+ >
589
+ <Tooltip title={isVideoLive ? 'Live' : 'Go to Live'} side="top">
590
+ <Flex justify="center" gap={2} align="center">
591
+ <Box
592
+ css={{
593
+ height: '$4',
594
+ width: '$4',
595
+ background: isVideoLive ? '$alert_error_default' : '$on_primary_medium',
596
+ r: '$1',
597
+ }}
598
+ />
599
+ <Text
600
+ variant="$body1"
601
+ css={{
602
+ c: isVideoLive ? '$on_surface_high' : '$on_surface_medium',
603
+ fontWeight: '$semiBold',
604
+ }}
605
+ >
606
+ {isVideoLive ? 'LIVE' : 'GO LIVE'}
607
+ </Text>
608
+ </Flex>
609
+ </Tooltip>
610
+ </IconButton>
611
+ {(isMobile || isLandscape) &&
612
+ !isVideoLive &&
613
+ hlsState?.variants[0]?.playlist_type === HLSPlaylistType.DVR ? (
614
+ <HMSVideoPlayer.Duration />
615
+ ) : null}
616
+ </HMSVideoPlayer.Controls.Left>
421
617
 
422
- <HMSVideoPlayer.Controls.Right>
423
- {hasCaptions && (
424
- <HLSCaptionSelector onClick={() => hlsPlayer?.toggleCaption()} isEnabled={isCaptionEnabled} />
425
- )}
426
- {availableLayers.length > 0 ? (
427
- <HLSQualitySelector
428
- layers={availableLayers}
429
- onOpen={setQualityDropDownOpen}
430
- open={qualityDropDownOpen}
431
- selection={currentSelectedQuality}
432
- onQualityChange={handleQuality}
433
- isAuto={isUserSelectedAuto}
434
- />
435
- ) : null}
436
- {isFullScreenSupported ? (
437
- <FullScreenButton
438
- isFullScreen={isFullScreen}
439
- onToggle={toggle}
440
- icon={isFullScreen ? <ShrinkIcon /> : <ExpandIcon />}
441
- />
442
- ) : null}
443
- </HMSVideoPlayer.Controls.Right>
444
- </HMSVideoPlayer.Controls.Root>
618
+ <HMSVideoPlayer.Controls.Right>
619
+ {hasCaptions && !(isMobile || isLandscape) && <HLSCaptionSelector isEnabled={isCaptionEnabled} />}
620
+ {availableLayers.length > 0 && !(isMobile || isLandscape) ? (
621
+ <HLSQualitySelector
622
+ layers={availableLayers}
623
+ onOpenChange={setQualityDropDownOpen}
624
+ open={qualityDropDownOpen}
625
+ selection={currentSelectedQuality}
626
+ onQualityChange={handleQuality}
627
+ isAuto={isUserSelectedAuto}
628
+ />
629
+ ) : null}
630
+ {isFullScreenSupported ? (
631
+ <FullScreenButton isFullScreen={isFullScreen} onToggle={toggle} />
632
+ ) : null}
633
+ </HMSVideoPlayer.Controls.Right>
634
+ </HMSVideoPlayer.Controls.Root>
635
+ </Flex>
445
636
  )}
446
- </Flex>
637
+ </>
447
638
  </HMSVideoPlayer.Root>
448
639
  </Flex>
449
- ) : (
450
- <Flex align="center" justify="center" direction="column" css={{ size: '100%', px: '$10' }}>
451
- <Flex css={{ c: '$on_surface_high', r: '$round', bg: '$surface_default', p: '$2' }}>
452
- {streamEnded ? <ColoredHandIcon height={56} width={56} /> : <GoLiveIcon height={56} width={56} />}
453
- </Flex>
454
- <Text variant="h5" css={{ c: '$on_surface_high', mt: '$10', mb: 0, textAlign: 'center' }}>
455
- {streamEnded ? 'Stream has ended' : 'Stream yet to start'}
456
- </Text>
457
- <Text variant="md" css={{ textAlign: 'center', mt: '$4', c: '$on_surface_medium' }}>
458
- {streamEnded ? 'Have a nice day!' : 'Sit back and relax'}
459
- </Text>
460
- </Flex>
461
- )}
640
+ </HMSPlayerContext.Provider>
641
+
642
+ {isMobile && !isFullScreen && <HLSViewTitle />}
462
643
  </Flex>
463
644
  );
464
645
  };