@100mslive/roomkit-react 0.2.8-alpha.2 → 0.2.8-alpha.4

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 (62) hide show
  1. package/dist/{HLSView-CEPQ23TO.js → HLSView-UIPDGADR.js} +509 -234
  2. package/dist/HLSView-UIPDGADR.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-2Y4FJB25.js → chunk-J4NOQ2YL.js} +562 -450
  21. package/dist/chunk-J4NOQ2YL.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-CEPQ23TO.js.map +0 -7
  57. package/dist/chunk-2Y4FJB25.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