@100mslive/roomkit-react 0.2.8-alpha.3 → 0.2.8-alpha.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. package/dist/{HLSView-PACDZWJN.js → HLSView-CVNJNDUQ.js} +509 -234
  2. package/dist/HLSView-CVNJNDUQ.js.map +7 -0
  3. package/dist/Prebuilt/common/hooks.d.ts +3 -0
  4. package/dist/Prebuilt/components/HMSVideo/FullscreenButton.d.ts +5 -0
  5. package/dist/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.d.ts +5 -0
  6. package/dist/Prebuilt/components/HMSVideo/HLSCaptionSelector.d.ts +1 -2
  7. package/dist/Prebuilt/components/HMSVideo/HLSQualitySelector.d.ts +12 -0
  8. package/dist/Prebuilt/components/HMSVideo/MwebHLSViewTitle.d.ts +2 -0
  9. package/dist/Prebuilt/components/HMSVideo/PlayButton.d.ts +6 -0
  10. package/dist/Prebuilt/components/HMSVideo/PlayerContext.d.ts +8 -0
  11. package/dist/Prebuilt/components/HMSVideo/VideoProgress.d.ts +2 -0
  12. package/dist/Prebuilt/components/HMSVideo/VideoTime.d.ts +2 -0
  13. package/dist/Prebuilt/components/HMSVideo/VolumeControl.d.ts +2 -0
  14. package/dist/Prebuilt/components/HMSVideo/index.d.ts +17 -0
  15. package/dist/Prebuilt/components/HMSVideo/utils.d.ts +9 -0
  16. package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +1 -3
  17. package/dist/Prebuilt/components/MwebLandscapePrompt.d.ts +1 -1
  18. package/dist/Prebuilt/components/RaiseHand.d.ts +2 -0
  19. package/dist/Prebuilt/components/SidePaneTabs.d.ts +1 -0
  20. package/dist/{chunk-2QHBD2VO.js → chunk-25HZFDG5.js} +562 -450
  21. package/dist/chunk-25HZFDG5.js.map +7 -0
  22. package/dist/index.cjs.js +1556 -1145
  23. package/dist/index.cjs.js.map +4 -4
  24. package/dist/index.js +1 -1
  25. package/dist/meta.cjs.json +429 -156
  26. package/dist/meta.esbuild.json +445 -164
  27. package/package.json +6 -6
  28. package/src/Prebuilt/common/hooks.ts +21 -0
  29. package/src/Prebuilt/components/Chat/ChatFooter.tsx +26 -10
  30. package/src/Prebuilt/components/ConferenceScreen.tsx +34 -2
  31. package/src/Prebuilt/components/Footer/Footer.tsx +0 -1
  32. package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -1
  33. package/src/Prebuilt/components/HMSVideo/FullscreenButton.tsx +13 -0
  34. package/src/Prebuilt/components/HMSVideo/{HLSAutoplayBlockedPrompt.jsx → HLSAutoplayBlockedPrompt.tsx} +13 -6
  35. package/src/Prebuilt/components/HMSVideo/HLSCaptionSelector.tsx +4 -2
  36. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.tsx +241 -0
  37. package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +3 -0
  38. package/src/Prebuilt/components/HMSVideo/MwebHLSViewTitle.tsx +91 -0
  39. package/src/Prebuilt/components/HMSVideo/PlayButton.tsx +27 -0
  40. package/src/Prebuilt/components/HMSVideo/PlayerContext.tsx +15 -0
  41. package/src/Prebuilt/components/HMSVideo/VideoProgress.tsx +81 -0
  42. package/src/Prebuilt/components/HMSVideo/VideoTime.tsx +42 -0
  43. package/src/Prebuilt/components/HMSVideo/{VolumeControl.jsx → VolumeControl.tsx} +7 -5
  44. package/src/Prebuilt/components/HMSVideo/{index.js → index.ts} +2 -0
  45. package/src/Prebuilt/components/HMSVideo/utils.ts +35 -0
  46. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +7 -1
  47. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +38 -25
  48. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +3 -1
  49. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +1 -1
  50. package/src/Prebuilt/components/MwebLandscapePrompt.tsx +5 -0
  51. package/src/Prebuilt/components/{RaiseHand.jsx → RaiseHand.tsx} +3 -2
  52. package/src/Prebuilt/components/SidePaneTabs.tsx +29 -10
  53. package/src/Prebuilt/layouts/HLSView.jsx +272 -156
  54. package/src/Prebuilt/layouts/SidePane.tsx +21 -10
  55. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +11 -1
  56. package/dist/HLSView-PACDZWJN.js.map +0 -7
  57. package/dist/chunk-2QHBD2VO.js.map +0 -7
  58. package/src/Prebuilt/components/HMSVideo/FullscreenButton.jsx +0 -18
  59. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +0 -127
  60. package/src/Prebuilt/components/HMSVideo/HMSVIdeoUtils.js +0 -27
  61. package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +0 -76
  62. package/src/Prebuilt/components/HMSVideo/VideoTime.jsx +0 -33
@@ -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,23 +14,28 @@ 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 { ColoredHandIcon, GoLiveIcon, PauseIcon, PlayIcon } 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';
23
27
  import { ToastManager } from '../components/Toast/ToastManager';
24
28
  import { Button } from '../../Button';
25
29
  import { IconButton } from '../../IconButton';
26
30
  import { Box, Flex } from '../../Layout';
27
31
  import { Loading } from '../../Loading';
28
32
  import { Text } from '../../Text';
29
- import { config, useTheme } from '../../Theme';
33
+ import { config, theme, useTheme } from '../../Theme';
30
34
  import { Tooltip } from '../../Tooltip';
31
- import { usePollViewToggle } from '../components/AppData/useSidepane';
32
- import { APP_DATA, EMOJI_REACTION_TYPE } from '../common/constants';
35
+ import { usePollViewToggle, useSidepaneToggle } from '../components/AppData/useSidepane';
36
+ import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
37
+ import { useIsLandscape } from '../common/hooks';
38
+ import { APP_DATA, EMOJI_REACTION_TYPE, SIDE_PANE_OPTIONS } from '../common/constants';
33
39
 
34
40
  let hlsPlayer;
35
41
  const toastMap = {};
@@ -39,35 +45,49 @@ const HLSView = () => {
39
45
  const hlsViewRef = useRef(null);
40
46
  const hlsState = useHMSStore(selectHLSState);
41
47
  const enablHlsStats = useHMSStore(selectAppData(APP_DATA.hlsStats));
48
+ const { elements, screenType } = useRoomLayoutConferencingScreen();
42
49
  const notification = useHMSNotifications(HMSNotificationTypes.POLL_STOPPED);
43
50
  const hmsActions = useHMSActions();
44
- const { themeType, theme } = useTheme();
51
+ const { themeType } = useTheme();
45
52
  const [streamEnded, setStreamEnded] = useState(false);
46
53
  let [hlsStatsState, setHlsStatsState] = useState(null);
47
54
  const hlsUrl = hlsState.variants[0]?.url;
48
55
  const [availableLayers, setAvailableLayers] = useState([]);
49
56
  const [isVideoLive, setIsVideoLive] = useState(true);
50
- const [isUserSelectedAuto, setIsUserSelectedAuto] = useState(true);
51
57
  const [isCaptionEnabled, setIsCaptionEnabled] = useState(true);
52
58
  const [hasCaptions, setHasCaptions] = useState(false);
53
59
  const [currentSelectedQuality, setCurrentSelectedQuality] = useState(null);
54
60
  const [isHlsAutoplayBlocked, setIsHlsAutoplayBlocked] = useState(false);
55
61
  const [isPaused, setIsPaused] = useState(false);
56
- const isFullScreenSupported = screenfull.isEnabled;
57
62
  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
63
  const lastHlsUrl = usePrevious(hlsUrl);
63
64
  const togglePollView = usePollViewToggle();
64
65
  const vanillaStore = useHMSVanillaStore();
66
+ const [controlsVisible, setControlsVisible] = useState(true);
67
+ const [isUserSelectedAuto, setIsUserSelectedAuto] = useState(true);
68
+ const [qualityDropDownOpen, setQualityDropDownOpen] = useState(false);
69
+ const controlsRef = useRef(null);
70
+ const controlsTimerRef = useRef();
71
+ const sidepane = useHMSStore(selectAppData(APP_DATA.sidePane));
72
+ const toggleChat = useSidepaneToggle(SIDE_PANE_OPTIONS.CHAT);
73
+ const showChat = !!elements?.chat;
74
+ const isFullScreenSupported = screenfull.isEnabled;
65
75
 
66
76
  const isMobile = useMedia(config.media.md);
77
+ const isLandscape = useIsLandscape();
78
+
67
79
  const isFullScreen = useFullscreen(hlsViewRef, show, {
68
80
  onClose: () => toggle(false),
69
81
  });
70
82
  const [showLoader, setShowLoader] = useState(false);
83
+
84
+ const isMwebHLSStream = screenType === 'hls_live_streaming' && isMobile;
85
+
86
+ useEffect(() => {
87
+ if (sidepane === '' && isMwebHLSStream && showChat) {
88
+ toggleChat();
89
+ }
90
+ }, [sidepane, isMwebHLSStream, toggleChat, showChat]);
71
91
  // FIXME: move this logic to player controller in next release
72
92
  useEffect(() => {
73
93
  /**
@@ -111,6 +131,15 @@ const HLSView = () => {
111
131
  };
112
132
  }, [hlsUrl]);
113
133
 
134
+ const handleQuality = useCallback(
135
+ quality => {
136
+ if (hlsPlayer) {
137
+ setIsUserSelectedAuto(quality.height?.toString().toLowerCase() === 'auto');
138
+ hlsPlayer?.setLayer(quality);
139
+ }
140
+ },
141
+ [availableLayers], //eslint-disable-line
142
+ );
114
143
  /**
115
144
  * initialize HMSHLSPlayer and add event listeners.
116
145
  */
@@ -210,10 +239,9 @@ const HLSView = () => {
210
239
  hlsPlayer.off(HMSHLSPlayerEvents.MANIFEST_LOADED, manifestLoadedHandler);
211
240
  hlsPlayer.off(HMSHLSPlayerEvents.LAYER_UPDATED, layerUpdatedHandler);
212
241
  hlsPlayer.reset();
213
- hlsPlayer = null;
214
242
  };
215
243
  }
216
- }, [hlsUrl]);
244
+ }, [hlsUrl, togglePollView, vanillaStore]);
217
245
 
218
246
  /**
219
247
  * initialize and subscribe to hlsState
@@ -239,16 +267,6 @@ const HLSView = () => {
239
267
  }
240
268
  };
241
269
 
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
270
  const sfnOverlayClose = () => {
253
271
  hmsActions.setAppData(APP_DATA.hlsStats, !enablHlsStats);
254
272
  };
@@ -272,8 +290,31 @@ const HLSView = () => {
272
290
  };
273
291
  }, [controlsVisible, isFullScreen, qualityDropDownOpen]);
274
292
 
293
+ const onTouchHandler = useCallback(
294
+ event => {
295
+ event.preventDefault();
296
+ // logic for invisible when tapping
297
+ if (event.type === 'ontouchstart' && controlsVisible) {
298
+ setControlsVisible(false);
299
+ return;
300
+ }
301
+ // normal scemnario
302
+ if (event.type === 'ontouchstart' || qualityDropDownOpen) {
303
+ setControlsVisible(true);
304
+ return;
305
+ }
306
+ if (isFullScreen && !controlsVisible && event.type === 'touchmove') {
307
+ setControlsVisible(true);
308
+ if (controlsTimerRef.current) {
309
+ clearTimeout(controlsTimerRef.current);
310
+ }
311
+ }
312
+ },
313
+ [controlsVisible, isFullScreen, qualityDropDownOpen],
314
+ );
275
315
  const onHoverHandler = useCallback(
276
316
  event => {
317
+ // normal scemnario
277
318
  if (event.type === 'mouseenter' || qualityDropDownOpen) {
278
319
  setControlsVisible(true);
279
320
  return;
@@ -295,157 +336,232 @@ const HLSView = () => {
295
336
  key="hls-viewer"
296
337
  id={`hls-viewer-${themeType}`}
297
338
  ref={hlsViewRef}
339
+ direction={isMobile || isLandscape ? 'column' : 'row'}
298
340
  css={{
299
- size: '100%',
341
+ w: sidepane !== '' && isLandscape ? '55%' : '100%',
342
+ h: sidepane !== '' && isMobile ? '36%' : '100%',
300
343
  }}
301
344
  >
302
- {hlsStatsState?.url && enablHlsStats ? (
303
- <HlsStatsOverlay hlsStatsState={hlsStatsState} onClose={sfnOverlayClose} />
304
- ) : null}
305
345
  {hlsUrl && !streamEnded ? (
306
- <Flex
307
- id="hls-player-container"
308
- align="center"
309
- justify="center"
310
- css={{
311
- width: '100%',
312
- margin: '0 auto',
313
- height: '100%',
314
- }}
315
- >
316
- <HLSAutoplayBlockedPrompt open={isHlsAutoplayBlocked} unblockAutoPlay={unblockAutoPlay} />
317
- {showLoader && (
346
+ <>
347
+ <HMSPlayerContext.Provider value={{ hlsPlayer }}>
348
+ {hlsStatsState?.url && enablHlsStats && !(isMobile || isLandscape) ? (
349
+ <HlsStatsOverlay hlsStatsState={hlsStatsState} onClose={sfnOverlayClose} />
350
+ ) : null}
318
351
  <Flex
352
+ id="hls-player-container"
319
353
  align="center"
320
354
  justify="center"
321
355
  css={{
322
- position: 'absolute',
356
+ size: '100%',
357
+ margin: '0 auto',
323
358
  }}
324
359
  >
325
- <Loading width={72} height={72} />
326
- </Flex>
327
- )}
328
- <HMSVideoPlayer.Root
329
- ref={videoRef}
330
- onMouseEnter={onHoverHandler}
331
- onMouseMove={onHoverHandler}
332
- onMouseLeave={onHoverHandler}
333
- >
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
360
+ <HLSAutoplayBlockedPrompt open={isHlsAutoplayBlocked} unblockAutoPlay={unblockAutoPlay} />
361
+ {showLoader && (
362
+ <Flex
363
+ align="center"
364
+ justify="center"
374
365
  css={{
375
- p: '$4 $8',
366
+ position: 'absolute',
376
367
  }}
377
368
  >
378
- <HMSVideoPlayer.Controls.Left>
379
- <HMSVideoPlayer.PlayButton
380
- onClick={async () => {
381
- isPaused ? await hlsPlayer?.play() : hlsPlayer?.pause();
382
- }}
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);
369
+ <Loading width={72} height={72} />
370
+ </Flex>
371
+ )}
372
+ <HMSVideoPlayer.Root
373
+ ref={videoRef}
374
+ onMouseEnter={onHoverHandler}
375
+ onMouseMove={onHoverHandler}
376
+ onMouseLeave={onHoverHandler}
377
+ onTouchStart={onTouchHandler}
378
+ onTouchMove={onTouchHandler}
379
+ >
380
+ <>
381
+ {isMobile || isLandscape ? (
382
+ <>
383
+ {!showLoader && (
384
+ <Box
385
+ css={{
386
+ position: 'absolute',
387
+ top: '40%',
388
+ left: '50%',
389
+ transform: 'translateY(-40%) translateX(-50%)',
390
+ padding: '$4',
391
+ display: 'inline-flex',
392
+ r: '$round',
393
+ gap: '$1',
394
+ bg: 'rgba(0, 0, 0, 0.6)',
395
+ zIndex: 1,
396
+ visibility: controlsVisible ? `` : `hidden`,
397
+ opacity: controlsVisible ? `1` : '0',
398
+ }}
399
+ >
400
+ {isPaused ? (
401
+ <IconButton
402
+ onClick={async () => {
403
+ await hlsPlayer?.play();
404
+ }}
405
+ data-testid="play_btn"
406
+ >
407
+ <PlayIcon width="48px" height="48px" />
408
+ </IconButton>
409
+ ) : (
410
+ <IconButton
411
+ onClick={async () => {
412
+ await hlsPlayer?.pause();
413
+ }}
414
+ data-testid="pause_btn"
415
+ >
416
+ <PauseIcon width="48px" height="48px" />
417
+ </IconButton>
418
+ )}
419
+ </Box>
420
+ )}
421
+ <Flex
422
+ ref={controlsRef}
423
+ direction="column"
424
+ justify="start"
425
+ align="start"
426
+ css={{
427
+ position: 'absolute',
428
+ top: '0',
429
+ left: '0',
430
+ width: '100%',
431
+ flexShrink: 0,
432
+ visibility: controlsVisible ? `` : `hidden`,
433
+ opacity: controlsVisible ? `1` : '0',
434
+ }}
435
+ >
436
+ <HMSVideoPlayer.Controls.Root
437
+ css={{
438
+ p: '$4 $8',
439
+ }}
440
+ >
441
+ <HMSVideoPlayer.Controls.Right>
442
+ {isLandscape && <ChatToggle />}
443
+ {hasCaptions && <HLSCaptionSelector isEnabled={isCaptionEnabled} />}
444
+ {availableLayers.length > 0 ? (
445
+ <HLSQualitySelector
446
+ layers={availableLayers}
447
+ onOpenChange={setQualityDropDownOpen}
448
+ open={qualityDropDownOpen}
449
+ selection={currentSelectedQuality}
450
+ onQualityChange={handleQuality}
451
+ isAuto={isUserSelectedAuto}
452
+ />
453
+ ) : null}
454
+ </HMSVideoPlayer.Controls.Right>
455
+ </HMSVideoPlayer.Controls.Root>
456
+ </Flex>
457
+ </>
458
+ ) : null}
459
+ <Flex
460
+ ref={controlsRef}
461
+ direction="column"
462
+ justify="end"
463
+ align="start"
464
+ css={{
465
+ position: 'absolute',
466
+ bottom: '0',
467
+ left: '0',
468
+ background:
469
+ isMobile || isLandscape
470
+ ? ''
471
+ : `linear-gradient(180deg, ${theme.colors.background_dim.value}00 29.46%, ${theme.colors.background_dim.value}A3 100%);`,
472
+ width: '100%',
473
+ pt: '$8',
474
+ flexShrink: 0,
475
+ transition: 'visibility 0s 0.5s, opacity 0.5s linear',
476
+ visibility: controlsVisible ? `` : `hidden`,
477
+ opacity: controlsVisible ? `1` : '0',
478
+ }}
479
+ >
480
+ {!(isMobile || isLandscape) && hlsState?.variants[0]?.playlist_type === HLSPlaylistType.DVR && (
481
+ <HMSVideoPlayer.Progress />
482
+ )}
483
+ <HMSVideoPlayer.Controls.Root
484
+ css={{
485
+ p: '$4 $8',
393
486
  }}
394
- key="jump-to-live_btn"
395
- data-testid="jump-to-live_btn"
396
487
  >
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
- }}
406
- />
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>
488
+ <HMSVideoPlayer.Controls.Left>
489
+ {!(isMobile || isLandscape) && (
490
+ <>
491
+ <HMSVideoPlayer.PlayButton
492
+ onClick={async () => {
493
+ isPaused ? await hlsPlayer?.play() : hlsPlayer?.pause();
494
+ }}
495
+ isPaused={isPaused}
496
+ />
497
+ {!isVideoLive ? <HMSVideoPlayer.Duration /> : null}
498
+ <HMSVideoPlayer.Volume />
499
+ </>
500
+ )}
501
+ <IconButton
502
+ css={{ px: '$2' }}
503
+ onClick={async () => {
504
+ await hlsPlayer?.seekToLivePosition();
505
+ setIsVideoLive(true);
506
+ }}
507
+ key="jump-to-live_btn"
508
+ data-testid="jump-to-live_btn"
509
+ >
510
+ <Tooltip title={isVideoLive ? 'Live' : 'Go to Live'} side="top">
511
+ <Flex justify="center" gap={2} align="center">
512
+ <Box
513
+ css={{
514
+ height: '$4',
515
+ width: '$4',
516
+ background: isVideoLive ? '$alert_error_default' : '$on_primary_medium',
517
+ r: '$1',
518
+ }}
519
+ />
520
+ <Text
521
+ variant="$body1"
522
+ css={{
523
+ c: isVideoLive ? '$on_surface_high' : '$on_surface_medium',
524
+ fontWeight: '$semiBold',
525
+ }}
526
+ >
527
+ {isVideoLive ? 'LIVE' : 'GO LIVE'}
528
+ </Text>
529
+ </Flex>
530
+ </Tooltip>
531
+ </IconButton>
532
+ {(isMobile || isLandscape) && !isVideoLive ? <HMSVideoPlayer.Duration /> : null}
533
+ </HMSVideoPlayer.Controls.Left>
421
534
 
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
- />
535
+ <HMSVideoPlayer.Controls.Right>
536
+ {hasCaptions && !(isMobile || isLandscape) && (
537
+ <HLSCaptionSelector isEnabled={isCaptionEnabled} />
538
+ )}
539
+ {availableLayers.length > 0 && !(isMobile || isLandscape) ? (
540
+ <HLSQualitySelector
541
+ layers={availableLayers}
542
+ onOpenChange={setQualityDropDownOpen}
543
+ open={qualityDropDownOpen}
544
+ selection={currentSelectedQuality}
545
+ onQualityChange={handleQuality}
546
+ isAuto={isUserSelectedAuto}
547
+ />
548
+ ) : null}
549
+ {isFullScreenSupported ? (
550
+ <FullScreenButton isFullScreen={isFullScreen} onToggle={toggle} />
551
+ ) : null}
552
+ </HMSVideoPlayer.Controls.Right>
553
+ </HMSVideoPlayer.Controls.Root>
554
+ {(isMobile || isLandscape) && hlsState?.variants[0]?.playlist_type === HLSPlaylistType.DVR ? (
555
+ <HMSVideoPlayer.Progress />
442
556
  ) : null}
443
- </HMSVideoPlayer.Controls.Right>
444
- </HMSVideoPlayer.Controls.Root>
445
- )}
557
+ </Flex>
558
+ </>
559
+ </HMSVideoPlayer.Root>
446
560
  </Flex>
447
- </HMSVideoPlayer.Root>
448
- </Flex>
561
+ </HMSPlayerContext.Provider>
562
+
563
+ {isMobile && !isFullScreen && <HLSViewTitle />}
564
+ </>
449
565
  ) : (
450
566
  <Flex align="center" justify="center" direction="column" css={{ size: '100%', px: '$10' }}>
451
567
  <Flex css={{ c: '$on_surface_high', r: '$round', bg: '$surface_default', p: '$2' }}>
@@ -20,6 +20,7 @@ import {
20
20
  useRoomLayoutConferencingScreen,
21
21
  useRoomLayoutPreviewScreen,
22
22
  } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
23
+ import { useIsLandscape, useLandscapeHLSStream, useMobileHLSStream } from '../common/hooks';
23
24
  import { translateAcross } from '../../utils';
24
25
  import { APP_DATA, SIDE_PANE_OPTIONS, UI_SETTINGS } from '../common/constants';
25
26
 
@@ -31,6 +32,7 @@ const SidePane = ({
31
32
  hideControls?: boolean;
32
33
  }) => {
33
34
  const isMobile = useMedia(cssConfig.media.md);
35
+ const isLandscape = useIsLandscape();
34
36
  const sidepane = useHMSStore(selectAppData(APP_DATA.sidePane));
35
37
  const activeScreensharePeerId = useHMSStore(selectAppData(APP_DATA.activeScreensharePeerId));
36
38
  const trackId = useHMSStore(selectVideoTrackByPeerID(activeScreensharePeerId))?.id;
@@ -38,6 +40,9 @@ const SidePane = ({
38
40
  const { elements: preview_elements } = useRoomLayoutPreviewScreen();
39
41
  const layoutMode = useUISettings(UI_SETTINGS.layoutMode);
40
42
 
43
+ const isLandscapeHLSStream = useLandscapeHLSStream();
44
+ const isMobileHLSStream = useMobileHLSStream();
45
+
41
46
  const backgroundMedia = preview_elements?.virtual_background?.background_media?.length
42
47
  ? preview_elements?.virtual_background?.background_media
43
48
  : elements?.virtual_background?.background_media || [];
@@ -48,7 +53,9 @@ const SidePane = ({
48
53
  ViewComponent = <Polls />;
49
54
  }
50
55
  if (sidepane === SIDE_PANE_OPTIONS.PARTICIPANTS || sidepane === SIDE_PANE_OPTIONS.CHAT) {
51
- ViewComponent = <SidePaneTabs hideControls={hideControls} active={sidepane} />;
56
+ ViewComponent = (
57
+ <SidePaneTabs hideControls={hideControls} active={sidepane} hideTab={isMobileHLSStream || isLandscapeHLSStream} />
58
+ );
52
59
  }
53
60
  if (sidepane === SIDE_PANE_OPTIONS.VB) {
54
61
  ViewComponent = <VBPicker backgroundMedia={backgroundMedia} />;
@@ -82,11 +89,11 @@ const SidePane = ({
82
89
  justify="center"
83
90
  css={{
84
91
  w: '$100',
85
- h: '100%',
92
+ h: isMobileHLSStream ? '64%' : '100%',
86
93
  flexShrink: 0,
87
94
  gap: '$4',
88
95
  position: 'relative',
89
- '@md': { position: mwebStreamingChat ? 'absolute' : '', zIndex: 12 },
96
+ '@md': { position: mwebStreamingChat || isLandscape ? 'absolute' : '', zIndex: 12 },
90
97
  }}
91
98
  >
92
99
  {trackId && layoutMode === LayoutMode.GALLERY && (
@@ -103,14 +110,15 @@ const SidePane = ({
103
110
  <Box
104
111
  css={{
105
112
  w: '$100',
106
- h: mwebStreamingChat ? '0' : '100%',
113
+ h: mwebStreamingChat || isLandscape ? '0' : '100%',
107
114
  p: VB ? '$10 $6 $10 $10' : '$10',
108
115
  flex: '1 1 0',
109
116
  minHeight: 0,
110
- maxHeight: mwebStreamingChat ? '300px' : 'unset',
111
- background: mwebStreamingChat
112
- ? 'linear-gradient(180deg, rgba(0, 0, 0, 0.00) 35.94%, rgba(0, 0, 0, 0.64) 100%)'
113
- : '$surface_dim',
117
+ maxHeight: mwebStreamingChat || isLandscape ? '300px' : 'unset',
118
+ background:
119
+ mwebStreamingChat || isLandscape
120
+ ? 'linear-gradient(180deg, rgba(0, 0, 0, 0.00) 35.94%, rgba(0, 0, 0, 0.64) 100%)'
121
+ : '$surface_dim',
114
122
  r: '$1',
115
123
  position: 'relative',
116
124
  '@lg': {
@@ -118,14 +126,17 @@ const SidePane = ({
118
126
  h: '100%',
119
127
  ml: 0,
120
128
  right: 0,
121
- position: 'fixed',
129
+ position: isLandscapeHLSStream ? '' : 'fixed',
130
+ minHeight: isLandscapeHLSStream ? '100%' : '',
122
131
  bottom: 0,
123
132
  borderRadius: 0,
124
133
  zIndex: 10,
125
134
  },
126
135
  '@md': {
127
136
  p: '$6 $8',
128
- pb: mwebStreamingChat ? '$20' : '$12',
137
+ h: isMobileHLSStream ? '64%' : '100%',
138
+ pb: '$12',
139
+ minHeight: isMobileHLSStream ? '64%' : '',
129
140
  borderTopLeftRadius: sidepane === SIDE_PANE_OPTIONS.POLLS ? '$2' : '0',
130
141
  borderTopRightRadius: sidepane === SIDE_PANE_OPTIONS.POLLS ? '$2' : '0',
131
142
  animation: `${translateAcross({ yFrom: '100%' })} 150ms cubic-bezier(0.22, 1, 0.36, 1)`,
@@ -31,6 +31,7 @@ import {
31
31
  // @ts-ignore: No implicit Any
32
32
  } from '../components/AppData/useUISettings';
33
33
  import { useCloseScreenshareWhiteboard } from '../components/hooks/useCloseScreenshareWhiteboard';
34
+ import { useMobileHLSStream } from '../common/hooks';
34
35
  // @ts-ignore: No implicit Any
35
36
  import { SESSION_STORE_KEY } from '../common/constants';
36
37
 
@@ -55,6 +56,7 @@ export const VideoStreamingSection = ({
55
56
  const waitingViewerRole = useWaitingViewerRole();
56
57
  const urlToIframe = useUrlToEmbed();
57
58
  const pdfAnnotatorActive = usePDFConfig();
59
+ const isMobileHLSStream = useMobileHLSStream();
58
60
  useCloseScreenshareWhiteboard();
59
61
 
60
62
  useEffect(() => {
@@ -104,9 +106,17 @@ export const VideoStreamingSection = ({
104
106
  position: 'relative',
105
107
  gap: '$4',
106
108
  }}
109
+ direction={isMobileHLSStream ? 'column' : 'row'}
107
110
  >
108
111
  {ViewComponent}
109
- <Box css={{ height: '100%', maxHeight: '100%', overflowY: 'clip', '&:empty': { display: 'none' } }}>
112
+ <Box
113
+ css={{
114
+ height: isMobileHLSStream ? '50%' : '100%',
115
+ maxHeight: '100%',
116
+ '&:empty': { display: 'none' },
117
+ overflowY: 'clip',
118
+ }}
119
+ >
110
120
  <SidePane
111
121
  screenType={screenType}
112
122
  // @ts-ignore