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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) 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-72B32WVR.js → chunk-R2JJJQR3.js} +1684 -1316
  27. package/dist/chunk-R2JJJQR3.js.map +7 -0
  28. package/dist/index.cjs.js +2866 -2053
  29. package/dist/index.cjs.js.map +4 -4
  30. package/dist/index.js +1 -1
  31. package/dist/meta.cjs.json +786 -299
  32. package/dist/meta.esbuild.json +805 -307
  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/AudioVideoToggle.tsx +2 -1
  42. package/src/Prebuilt/components/AuthToken.jsx +1 -1
  43. package/src/Prebuilt/components/Chat/Chat.tsx +41 -1
  44. package/src/Prebuilt/components/Chat/ChatFooter.tsx +33 -13
  45. package/src/Prebuilt/components/Chat/MwebChatOption.tsx +1 -1
  46. package/src/Prebuilt/components/ConferenceScreen.tsx +48 -7
  47. package/src/Prebuilt/components/EmojiReaction.jsx +33 -23
  48. package/src/Prebuilt/components/Footer/Footer.tsx +0 -1
  49. package/src/Prebuilt/components/Footer/RoleOptions.tsx +138 -125
  50. package/src/Prebuilt/components/HMSVideo/Controls.jsx +1 -1
  51. package/src/Prebuilt/components/HMSVideo/FullscreenButton.tsx +13 -0
  52. package/src/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.tsx +72 -0
  53. package/src/Prebuilt/components/HMSVideo/HLSCaptionSelector.tsx +4 -2
  54. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.tsx +248 -0
  55. package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +17 -7
  56. package/src/Prebuilt/components/HMSVideo/MwebHLSViewTitle.tsx +84 -0
  57. package/src/Prebuilt/components/HMSVideo/PlayButton.tsx +27 -0
  58. package/src/Prebuilt/components/HMSVideo/PlayPauseButton.tsx +27 -0
  59. package/src/Prebuilt/components/HMSVideo/PlayerContext.tsx +15 -0
  60. package/src/Prebuilt/components/HMSVideo/SeekControls.tsx +22 -0
  61. package/src/Prebuilt/components/HMSVideo/VideoProgress.tsx +95 -0
  62. package/src/Prebuilt/components/HMSVideo/VideoTime.tsx +43 -0
  63. package/src/Prebuilt/components/HMSVideo/{VolumeControl.jsx → VolumeControl.tsx} +6 -4
  64. package/src/Prebuilt/components/HMSVideo/{index.js → index.ts} +6 -2
  65. package/src/Prebuilt/components/HMSVideo/{HMSVIdeoUtils.js → utils.ts} +5 -5
  66. package/src/Prebuilt/components/Header/StreamActions.tsx +1 -1
  67. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.tsx +1 -1
  68. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +50 -46
  69. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +15 -4
  70. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +46 -27
  71. package/src/Prebuilt/components/MoreSettings/MoreSettings.tsx +3 -1
  72. package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +37 -31
  73. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +12 -8
  74. package/src/Prebuilt/components/MwebLandscapePrompt.tsx +14 -3
  75. package/src/Prebuilt/components/Notifications/HandRaisedNotifications.tsx +5 -2
  76. package/src/Prebuilt/components/Notifications/PeerNotifications.tsx +1 -1
  77. package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +19 -8
  78. package/src/Prebuilt/components/Polls/Voting/Voting.tsx +3 -2
  79. package/src/Prebuilt/components/Polls/common/OptionInputWithDelete.tsx +1 -1
  80. package/src/Prebuilt/components/Polls/common/utils.ts +2 -2
  81. package/src/Prebuilt/components/RaiseHand.tsx +24 -0
  82. package/src/Prebuilt/components/RoomDetails/RoomDetailsPane.tsx +41 -14
  83. package/src/Prebuilt/components/SidePaneTabs.tsx +56 -48
  84. package/src/Prebuilt/components/StatsForNerds.jsx +14 -6
  85. package/src/Prebuilt/components/Streaming/Common.jsx +1 -1
  86. package/src/Prebuilt/components/TileMenu/TileMenuContent.tsx +2 -2
  87. package/src/Prebuilt/components/Toast/ToastBatcher.js +8 -1
  88. package/src/Prebuilt/components/Toast/ToastConfig.jsx +17 -0
  89. package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +1 -1
  90. package/src/Prebuilt/components/hooks/useRoleProminencePeers.tsx +2 -1
  91. package/src/Prebuilt/components/pdfAnnotator/shareScreenOptions.jsx +2 -2
  92. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +1 -1
  93. package/src/Prebuilt/layouts/HLSView.jsx +359 -178
  94. package/src/Prebuilt/layouts/SidePane.tsx +145 -59
  95. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +22 -2
  96. package/src/Prebuilt/primitives/DialogContent.jsx +1 -1
  97. package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +1 -1
  98. package/src/Sheet/Sheet.tsx +7 -3
  99. package/dist/HLSView-37B2YVTC.js +0 -987
  100. package/dist/HLSView-37B2YVTC.js.map +0 -7
  101. package/dist/chunk-72B32WVR.js.map +0 -7
  102. package/src/Prebuilt/components/HMSVideo/FullscreenButton.jsx +0 -18
  103. package/src/Prebuilt/components/HMSVideo/HLSAutoplayBlockedPrompt.jsx +0 -35
  104. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.jsx +0 -127
  105. package/src/Prebuilt/components/HMSVideo/PlayButton.jsx +0 -13
  106. package/src/Prebuilt/components/HMSVideo/VideoProgress.jsx +0 -76
  107. package/src/Prebuilt/components/HMSVideo/VideoTime.jsx +0 -33
  108. 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
  };