@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
@@ -1,9 +1,9 @@
1
1
  import React, { Fragment, useState } from 'react';
2
- import { ConferencingScreen } from '@100mslive/types-prebuilt';
3
2
  // @ts-ignore: No implicit Any
4
3
  import { selectIsConnectedToRoom, selectPermissions, useHMSStore, useRecordingStreaming } from '@100mslive/react-sdk';
5
4
  // @ts-ignore: No implicit Any
6
- import { ExitIcon, StopIcon } from '@100mslive/react-icons';
5
+ import { CrossIcon, ExitIcon, StopIcon } from '@100mslive/react-icons';
6
+ import { IconButton } from '../../../IconButton';
7
7
  import { Box } from '../../../Layout';
8
8
  import { Sheet } from '../../../Sheet';
9
9
  import { Tooltip } from '../../../Tooltip';
@@ -11,19 +11,22 @@ import { EndSessionContent } from './EndSessionContent';
11
11
  import { LeaveIconButton } from './LeaveAtoms';
12
12
  import { LeaveCard } from './LeaveCard';
13
13
  import { LeaveSessionContent } from './LeaveSessionContent';
14
+ import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
14
15
  // @ts-ignore: No implicit Any
15
16
  import { useDropdownList } from '../hooks/useDropdownList';
17
+ import { useLandscapeHLSStream, useMobileHLSStream } from '../../common/hooks';
16
18
 
17
19
  export const MwebLeaveRoom = ({
18
20
  leaveRoom,
19
- screenType,
20
21
  endRoom,
22
+ container,
21
23
  }: {
22
24
  leaveRoom: (options?: { endStream?: boolean }) => Promise<void>;
23
- screenType: keyof ConferencingScreen;
24
25
  endRoom: () => Promise<void>;
26
+ container?: HTMLElement;
25
27
  }) => {
26
28
  const [open, setOpen] = useState(false);
29
+ const { screenType } = useRoomLayoutConferencingScreen();
27
30
  const [showLeaveRoomAlert, setShowLeaveRoomAlert] = useState(false);
28
31
  const [showEndStreamAlert, setShowEndStreamAlert] = useState(false);
29
32
  const isConnected = useHMSStore(selectIsConnectedToRoom);
@@ -43,22 +46,13 @@ export const MwebLeaveRoom = ({
43
46
  {showLeaveOptions ? (
44
47
  <Sheet.Root open={open} onOpenChange={setOpen}>
45
48
  <Sheet.Trigger asChild>
46
- <LeaveIconButton
47
- key="LeaveRoom"
48
- data-testid="leave_room_btn"
49
- css={{
50
- borderTopRightRadius: '$1',
51
- borderBottomRightRadius: '$1',
49
+ <LeaveButton
50
+ onClick={() => {
51
+ setOpen(open => !open);
52
52
  }}
53
- >
54
- <Tooltip title="Leave Room">
55
- <Box>
56
- <ExitIcon style={{ transform: 'rotate(180deg)' }} />
57
- </Box>
58
- </Tooltip>
59
- </LeaveIconButton>
53
+ />
60
54
  </Sheet.Trigger>
61
- <Sheet.Content>
55
+ <Sheet.Content container={container}>
62
56
  <LeaveCard
63
57
  title={showStream ? 'Leave Stream' : 'Leave Session'}
64
58
  subtitle={`Others will continue after you leave. You can join the ${
@@ -88,16 +82,10 @@ export const MwebLeaveRoom = ({
88
82
  </Sheet.Content>
89
83
  </Sheet.Root>
90
84
  ) : (
91
- <LeaveIconButton key="LeaveRoom" data-testid="leave_room_btn" onClick={() => setShowLeaveRoomAlert(true)}>
92
- <Tooltip title="Leave Room">
93
- <Box>
94
- <ExitIcon style={{ transform: 'rotate(180deg)' }} />
95
- </Box>
96
- </Tooltip>
97
- </LeaveIconButton>
85
+ <LeaveButton onClick={() => setShowLeaveRoomAlert(true)} />
98
86
  )}
99
87
  <Sheet.Root open={showEndStreamAlert} onOpenChange={setShowEndStreamAlert}>
100
- <Sheet.Content css={{ bg: '$surface_dim', p: '$10', pb: '$12' }}>
88
+ <Sheet.Content css={{ bg: '$surface_dim', p: '$10', pb: '$12' }} container={container}>
101
89
  <EndSessionContent
102
90
  setShowEndStreamAlert={setShowEndStreamAlert}
103
91
  leaveRoom={isStreamingOn ? leaveRoom : endRoom}
@@ -107,10 +95,41 @@ export const MwebLeaveRoom = ({
107
95
  </Sheet.Root>
108
96
 
109
97
  <Sheet.Root open={showLeaveRoomAlert} onOpenChange={setShowLeaveRoomAlert}>
110
- <Sheet.Content css={{ bg: '$surface_dim', p: '$10', pb: '$12' }}>
98
+ <Sheet.Content css={{ bg: '$surface_dim', p: '$10', pb: '$12' }} container={container}>
111
99
  <LeaveSessionContent setShowLeaveRoomAlert={setShowLeaveRoomAlert} leaveRoom={leaveRoom} />
112
100
  </Sheet.Content>
113
101
  </Sheet.Root>
114
102
  </Fragment>
115
103
  );
116
104
  };
105
+
106
+ const LeaveButton = ({ onClick }: { onClick: () => void }) => {
107
+ const isMobileHLSStream = useMobileHLSStream();
108
+ const isLandscapeHLSStream = useLandscapeHLSStream();
109
+
110
+ return isMobileHLSStream || isLandscapeHLSStream ? (
111
+ <IconButton key="LeaveRoom" data-testid="leave_room_btn" onClick={onClick}>
112
+ <Tooltip title="Leave Room">
113
+ <Box>
114
+ <CrossIcon />
115
+ </Box>
116
+ </Tooltip>
117
+ </IconButton>
118
+ ) : (
119
+ <LeaveIconButton
120
+ key="LeaveRoom"
121
+ data-testid="leave_room_btn"
122
+ css={{
123
+ borderTopRightRadius: '$1',
124
+ borderBottomRightRadius: '$1',
125
+ }}
126
+ onClick={onClick}
127
+ >
128
+ <Tooltip title="Leave Room">
129
+ <Box>
130
+ <ExitIcon style={{ transform: 'rotate(180deg)' }} />
131
+ </Box>
132
+ </Tooltip>
133
+ </LeaveIconButton>
134
+ );
135
+ };
@@ -10,6 +10,7 @@ import { DesktopOptions } from './SplitComponents/DesktopOptions';
10
10
  // @ts-ignore: No implicit Any
11
11
  import { MwebOptions } from './SplitComponents/MwebOptions';
12
12
  import { config as cssConfig } from '../../..';
13
+ import { useLandscapeHLSStream } from '../../common/hooks';
13
14
 
14
15
  export const MoreSettings = ({
15
16
  elements,
@@ -19,7 +20,8 @@ export const MoreSettings = ({
19
20
  screenType: keyof ConferencingScreen;
20
21
  }) => {
21
22
  const isMobile = useMedia(cssConfig.media.md);
22
- return isMobile ? (
23
+ const isLandscapeHLSStream = useLandscapeHLSStream();
24
+ return isMobile || isLandscapeHLSStream ? (
23
25
  <MwebOptions elements={elements} screenType={screenType} />
24
26
  ) : (
25
27
  <DesktopOptions elements={elements} screenType={screenType} />
@@ -5,6 +5,7 @@ import {
5
5
  DefaultConferencingScreen_Elements,
6
6
  HLSLiveStreamingScreen_Elements,
7
7
  } from '@100mslive/types-prebuilt';
8
+ import { match } from 'ts-pattern';
8
9
  import { selectAppData, selectLocalPeerID, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
9
10
  import { BrbIcon, CheckIcon, HamburgerMenuIcon, InfoIcon, PipIcon, SettingsIcon } from '@100mslive/react-icons';
10
11
  import { Checkbox, Dropdown, Flex, Text, Tooltip } from '../../../..';
@@ -143,41 +144,46 @@ export const DesktopOptions = ({
143
144
  Settings
144
145
  </Text>
145
146
  </Dropdown.Item>
147
+ {match({ screenType, isSupported: HMSHLSPlayer.isSupported() })
148
+ .with({ screenType: 'hls_live_streaming', isSupported: false }, () => null)
149
+ .with({ screenType: 'hls_live_streaming', isSupported: true }, () => {
150
+ return (
151
+ <Dropdown.Item
152
+ onClick={() => hmsActions.setAppData(APP_DATA.hlsStats, !enablHlsStats)}
153
+ data-testid="hls_stats"
154
+ >
155
+ <Checkbox.Root
156
+ css={{ margin: '$2' }}
157
+ checked={enablHlsStats}
158
+ onCheckedChange={() => hmsActions.setAppData(APP_DATA.hlsStats, !enablHlsStats)}
159
+ >
160
+ <Checkbox.Indicator>
161
+ <CheckIcon width={16} height={16} />
162
+ </Checkbox.Indicator>
163
+ </Checkbox.Root>
164
+ <Flex justify="between" css={{ width: '100%' }}>
165
+ <Text variant="sm" css={{ ml: '$4' }}>
166
+ Show HLS Stats
167
+ </Text>
146
168
 
147
- {screenType === 'hls_live_streaming' ? (
148
- HMSHLSPlayer.isSupported() ? (
169
+ <Text variant="sm" css={{ ml: '$4' }}>
170
+ {`${isMacOS ? '⌘' : 'ctrl'} + ]`}
171
+ </Text>
172
+ </Flex>
173
+ </Dropdown.Item>
174
+ );
175
+ })
176
+ .otherwise(() => (
149
177
  <Dropdown.Item
150
- onClick={() => hmsActions.setAppData(APP_DATA.hlsStats, !enablHlsStats)}
151
- data-testid="hls_stats"
178
+ onClick={() => updateState(MODALS.STATS_FOR_NERDS, true)}
179
+ data-testid="stats_for_nerds_btn"
152
180
  >
153
- <Checkbox.Root
154
- css={{ margin: '$2' }}
155
- checked={enablHlsStats}
156
- onCheckedChange={() => hmsActions.setAppData(APP_DATA.hlsStats, !enablHlsStats)}
157
- >
158
- <Checkbox.Indicator>
159
- <CheckIcon width={16} height={16} />
160
- </Checkbox.Indicator>
161
- </Checkbox.Root>
162
- <Flex justify="between" css={{ width: '100%' }}>
163
- <Text variant="sm" css={{ ml: '$4' }}>
164
- Show HLS Stats
165
- </Text>
166
-
167
- <Text variant="sm" css={{ ml: '$4' }}>
168
- {`${isMacOS ? '⌘' : 'ctrl'} + ]`}
169
- </Text>
170
- </Flex>
181
+ <InfoIcon />
182
+ <Text variant="sm" css={{ ml: '$4' }}>
183
+ Stats for Nerds
184
+ </Text>
171
185
  </Dropdown.Item>
172
- ) : null
173
- ) : (
174
- <Dropdown.Item onClick={() => updateState(MODALS.STATS_FOR_NERDS, true)} data-testid="stats_for_nreds_btn">
175
- <InfoIcon />
176
- <Text variant="sm" css={{ ml: '$4' }}>
177
- Stats for Nerds
178
- </Text>
179
- </Dropdown.Item>
180
- )}
186
+ ))}
181
187
  </Dropdown.Content>
182
188
  </Dropdown.Root>
183
189
  {openModals.has(MODALS.BULK_ROLE_CHANGE) && (
@@ -1,6 +1,7 @@
1
1
  import React, { useRef, useState } from 'react';
2
2
  import { useClickAway } from 'react-use';
3
3
  import { ConferencingScreen, DefaultConferencingScreen_Elements } from '@100mslive/types-prebuilt';
4
+ import { match } from 'ts-pattern';
4
5
  import {
5
6
  selectIsConnectedToRoom,
6
7
  selectPeerCount,
@@ -53,6 +54,7 @@ import { useDropdownList } from '../../hooks/useDropdownList';
53
54
  // @ts-ignore: No implicit any
54
55
  import { useMyMetadata } from '../../hooks/useMetadata';
55
56
  import { useUnreadPollQuizPresent } from '../../hooks/useUnreadPollQuizPresent';
57
+ import { useLandscapeHLSStream, useMobileHLSStream } from '../../../common/hooks';
56
58
  // @ts-ignore: No implicit any
57
59
  import { getFormattedCount } from '../../../common/utils';
58
60
  // @ts-ignore: No implicit any
@@ -98,6 +100,8 @@ export const MwebOptions = ({
98
100
  const { unreadPollQuiz, setUnreadPollQuiz } = useUnreadPollQuizPresent();
99
101
  const { title, description } = useRoomLayoutHeader();
100
102
  const toggleDetailsSheet = useSheetToggle(SHEET_OPTIONS.ROOM_DETAILS);
103
+ const isMobileHLSStream = useMobileHLSStream();
104
+ const isLandscapeHLSStream = useLandscapeHLSStream();
101
105
 
102
106
  useDropdownList({ open: openModals.size > 0 || openOptionsSheet || openSettingsSheet, name: 'MoreSettings' });
103
107
 
@@ -120,7 +124,7 @@ export const MwebOptions = ({
120
124
  <Sheet.Root open={openOptionsSheet} onOpenChange={setOpenOptionsSheet}>
121
125
  <Tooltip title="More options">
122
126
  <Sheet.Trigger asChild data-testid="more_settings_btn">
123
- <IconButton>
127
+ <IconButton css={{ bg: isMobileHLSStream || isLandscapeHLSStream ? '$surface_default' : '' }}>
124
128
  <HamburgerMenuIcon />
125
129
  </IconButton>
126
130
  </Sheet.Trigger>
@@ -196,7 +200,7 @@ export const MwebOptions = ({
196
200
  </ActionTile.Root>
197
201
  ) : null} */}
198
202
 
199
- {elements?.emoji_reactions && (
203
+ {elements?.emoji_reactions && !(isLandscapeHLSStream || isMobileHLSStream) && (
200
204
  <ActionTile.Root
201
205
  onClick={() => {
202
206
  setShowEmojiCard(true);
@@ -287,11 +291,11 @@ export const MwebOptions = ({
287
291
  >
288
292
  {isRecordingLoading ? <Loading /> : <RecordIcon />}
289
293
  <ActionTile.Title>
290
- {isBrowserRecordingOn
291
- ? 'Recording On'
292
- : isRecordingLoading
293
- ? 'Starting Recording'
294
- : 'Start Recording'}
294
+ {match({ isBrowserRecordingOn, isRecordingLoading })
295
+ .with({ isBrowserRecordingOn: true, isRecordingLoading: false }, () => 'Recording On')
296
+ .with({ isRecordingLoading: true }, () => 'Starting Recording')
297
+ .with({ isRecordingLoading: false }, () => 'Start Recording')
298
+ .otherwise(() => null)}
295
299
  </ActionTile.Title>
296
300
  </ActionTile.Root>
297
301
  ) : null}
@@ -339,7 +343,7 @@ export const MwebOptions = ({
339
343
  mx: '$4',
340
344
  }}
341
345
  >
342
- <EmojiReaction />
346
+ <EmojiReaction showCard />
343
347
  </Box>
344
348
  )}
345
349
  {showRecordingOn && (
@@ -1,17 +1,20 @@
1
1
  import React, { useEffect, useState } from 'react';
2
2
  import { useMedia } from 'react-use';
3
+ import { match, P } from 'ts-pattern';
3
4
  import { RefreshIcon } from '@100mslive/react-icons';
4
5
  import { Button } from '../../Button';
5
6
  import { Box, Flex } from '../../Layout';
6
7
  import { Dialog } from '../../Modal';
7
8
  import { Text } from '../../Text';
8
9
  import { config as cssConfig } from '../../Theme';
10
+ import { useLandscapeHLSStream } from '../common/hooks';
9
11
  // @ts-ignore
10
12
  import { isMobileUserAgent } from '../common/utils';
11
13
 
12
14
  export const MwebLandscapePrompt = () => {
13
15
  const [showMwebLandscapePrompt, setShowMwebLandscapePrompt] = useState(false);
14
16
  const isLandscape = useMedia(cssConfig.media.ls);
17
+ const isLandscapeHLSStream = useLandscapeHLSStream();
15
18
 
16
19
  useEffect(() => {
17
20
  if (!isMobileUserAgent) {
@@ -20,22 +23,30 @@ export const MwebLandscapePrompt = () => {
20
23
  }
21
24
 
22
25
  if (!window.screen?.orientation) {
23
- setShowMwebLandscapePrompt(isLandscape);
26
+ setShowMwebLandscapePrompt(isLandscape && !isLandscapeHLSStream);
24
27
  return;
25
28
  }
26
29
  const handleRotation = () => {
27
30
  const angle = window.screen.orientation.angle;
28
31
  const type = window.screen.orientation.type || '';
29
32
  // Angle check needed to diff bw mobile and desktop
30
- setShowMwebLandscapePrompt(angle ? angle >= 90 && type.includes('landscape') : isLandscape);
33
+ setShowMwebLandscapePrompt(
34
+ match({ angle, isLandscapeHLSStream, isLandscape, type })
35
+ .with({ isLandscapeHLSStream }, () => false)
36
+ .with({ angle: P.when(angle => angle && angle >= 90) }, ({ type }) => type.includes('landscape'))
37
+ .otherwise(() => isLandscape),
38
+ );
31
39
  };
32
40
  handleRotation();
33
41
  window.screen.orientation.addEventListener('change', handleRotation);
34
42
  return () => {
35
43
  window.screen.orientation.removeEventListener('change', handleRotation);
36
44
  };
37
- }, [isLandscape]);
45
+ }, [isLandscape, isLandscapeHLSStream]);
38
46
 
47
+ if (isLandscapeHLSStream) {
48
+ return null;
49
+ }
39
50
  return (
40
51
  <Dialog.Root open={showMwebLandscapePrompt} onOpenChange={setShowMwebLandscapePrompt}>
41
52
  <Dialog.Portal>
@@ -3,6 +3,7 @@ import {
3
3
  HMSNotificationTypes,
4
4
  HMSRoomState,
5
5
  selectHasPeerHandRaised,
6
+ selectPeerByID,
6
7
  selectRoomState,
7
8
  useHMSNotifications,
8
9
  useHMSStore,
@@ -28,12 +29,14 @@ export const HandRaisedNotifications = () => {
28
29
  }
29
30
 
30
31
  // Don't show toast message in case of local peer.
31
- if (roomState !== HMSRoomState.Connected || notification.data.isLocal || !on_stage_exp || !isSubscribing) {
32
+ if (roomState !== HMSRoomState.Connected || notification.data.isLocal || !isSubscribing) {
32
33
  return;
33
34
  }
34
35
  const hasPeerHandRaised = vanillaStore.getState(selectHasPeerHandRaised(notification.data.id));
36
+ const peer = vanillaStore.getState(selectPeerByID(notification.data.id));
35
37
  if (hasPeerHandRaised) {
36
- ToastBatcher.showToast({ notification, type: 'RAISE_HAND' });
38
+ const showCTA = peer?.roleName && (on_stage_exp?.off_stage_roles || [])?.includes(peer.roleName);
39
+ ToastBatcher.showToast({ notification, type: showCTA ? 'RAISE_HAND_HLS' : 'RAISE_HAND' });
37
40
  console.debug('Metadata updated', notification.data);
38
41
  }
39
42
  }, [isSubscribing, notification, on_stage_exp, roomState, vanillaStore]);
@@ -49,7 +49,7 @@ export const PeerNotifications = () => {
49
49
  }
50
50
 
51
51
  ToastBatcher.showToast({ notification });
52
- }, [notification, isPeerJoinSubscribed, isPeerLeftSubscribed]);
52
+ }, [notification, isPeerJoinSubscribed, isPeerLeftSubscribed, selectedPeer.id, setPeerSelector]);
53
53
 
54
54
  return null;
55
55
  };
@@ -1,5 +1,6 @@
1
1
  // @ts-check
2
2
  import React, { useCallback, useMemo, useRef, useState } from 'react';
3
+ import { match } from 'ts-pattern';
3
4
  import { selectLocalPeer, selectLocalPeerRoleName, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
4
5
  import { CheckCircleIcon, ChevronDownIcon, CrossCircleIcon } from '@100mslive/react-icons';
5
6
  import { Box, Button, Flex, Text } from '../../../../';
@@ -92,20 +93,30 @@ export const QuestionCard = ({
92
93
  <Text
93
94
  variant="caption"
94
95
  css={{
95
- color:
96
- respondedToQuiz && !isLive
97
- ? isCorrectAnswer
98
- ? '$alert_success'
99
- : '$alert_error_default'
100
- : '$on_surface_low',
96
+ color: match({ respondedToQuiz, isLive, isCorrectAnswer })
97
+ .when(
98
+ ({ respondedToQuiz, isLive }) => respondedToQuiz && !isLive,
99
+ ({ isCorrectAnswer }) => (isCorrectAnswer ? '$alert_success' : '$alert_error_default'),
100
+ )
101
+ .otherwise(() => '$on_surface_low'),
101
102
  fontWeight: '$semiBold',
102
103
  display: 'flex',
103
104
  alignItems: 'center',
104
105
  gap: '$4',
105
106
  }}
106
107
  >
107
- {respondedToQuiz && isCorrectAnswer && pollEnded ? <CheckCircleIcon height={16} width={16} /> : null}
108
- {respondedToQuiz && !isCorrectAnswer && pollEnded ? <CrossCircleIcon height={16} width={16} /> : null}
108
+ {match({ respondedToQuiz, pollEnded, isCorrectAnswer })
109
+ .when(
110
+ ({ respondedToQuiz, pollEnded }) => respondedToQuiz && pollEnded,
111
+ ({ isCorrectAnswer }) => {
112
+ return isCorrectAnswer ? (
113
+ <CheckCircleIcon height={16} width={16} />
114
+ ) : (
115
+ <CrossCircleIcon height={16} width={16} />
116
+ );
117
+ },
118
+ )
119
+ .otherwise(() => null)}
109
120
  QUESTION {index} OF {totalQuestions}: {type.toUpperCase()}
110
121
  </Text>
111
122
  </Flex>
@@ -38,9 +38,9 @@ export const Voting = ({ id, toggleVoting }: { id: string; toggleVoting: () => v
38
38
  <Flex
39
39
  align="center"
40
40
  css={{
41
- gap: '$6',
41
+ gap: '$4',
42
42
  py: '$6',
43
- px: '$10',
43
+ px: '$8',
44
44
  my: '$4',
45
45
  w: '100%',
46
46
  color: '$on_surface_high',
@@ -60,6 +60,7 @@ export const Voting = ({ id, toggleVoting }: { id: string; toggleVoting: () => v
60
60
  marginLeft: 'auto',
61
61
  cursor: 'pointer',
62
62
  '&:hover': { opacity: '0.8' },
63
+ height: 'fit-content',
63
64
  }}
64
65
  >
65
66
  <CrossIcon onClick={toggleVoting} />
@@ -29,7 +29,7 @@ export const OptionInputWithDelete = ({
29
29
  key={index}
30
30
  onChange={event => handleOptionTextChange(index, event.target.value)}
31
31
  />
32
- <IconButton onClick={() => removeOption(index)} css={{ bg: '$transparent', border: 'none' }}>
32
+ <IconButton onClick={() => removeOption(index)} css={{ bg: 'transparent', border: 'none' }}>
33
33
  <TrashIcon />
34
34
  </IconButton>
35
35
  </>
@@ -4,7 +4,7 @@ export const getFormattedTime = (milliseconds: number | undefined, precise = tru
4
4
  const totalSeconds = milliseconds / 1000;
5
5
  const hours = Math.floor(totalSeconds / 3600);
6
6
  const minutes = Math.floor((totalSeconds % 3600) / 60);
7
- const seconds = precise ? totalSeconds % 60 : Math.floor(totalSeconds % 60);
7
+ const seconds = totalSeconds % 60;
8
8
 
9
9
  let formattedTime = '';
10
10
  if (hours) {
@@ -16,7 +16,7 @@ export const getFormattedTime = (milliseconds: number | undefined, precise = tru
16
16
  if (!precise && (hours || minutes)) {
17
17
  return formattedTime;
18
18
  }
19
- formattedTime += `${seconds}s`;
19
+ formattedTime += `${precise ? seconds.toFixed(3) : Math.floor(seconds)}s`;
20
20
 
21
21
  return formattedTime;
22
22
  };
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { HandIcon, HandRaiseSlashedIcon } from '@100mslive/react-icons';
3
+ import { CSS } from '../../Theme';
4
+ import { Tooltip } from '../../Tooltip';
5
+ // @ts-ignore: No implicit Any
6
+ import IconButton from '../IconButton';
7
+ // @ts-ignore: No implicit Any
8
+ import { useMyMetadata } from './hooks/useMetadata';
9
+
10
+ export const RaiseHand = ({ css }: { css?: CSS }) => {
11
+ const { isHandRaised, toggleHandRaise } = useMyMetadata();
12
+ return (
13
+ <Tooltip title={isHandRaised ? 'Lower hand' : 'Raise hand'}>
14
+ <IconButton
15
+ data-testid="hand_raise_btn"
16
+ css={css}
17
+ active={!isHandRaised}
18
+ onClick={async () => await toggleHandRaise()}
19
+ >
20
+ {isHandRaised ? <HandRaiseSlashedIcon /> : <HandIcon />}
21
+ </IconButton>
22
+ </Tooltip>
23
+ );
24
+ };
@@ -2,31 +2,32 @@ import React from 'react';
2
2
  import { CrossIcon } from '@100mslive/react-icons';
3
3
  import { Box, Flex } from '../../../Layout';
4
4
  import { Text } from '../../../Text';
5
+ // @ts-ignore: No implicit any
6
+ import { Logo } from '../Header/HeaderComponents';
5
7
  import { RoomDetailsRow } from './RoomDetailsRow';
6
8
  import { useRoomLayoutHeader } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
7
9
  // @ts-ignore
8
10
  import { useSidepaneToggle } from '../AppData/useSidepane';
11
+ import { useMobileHLSStream } from '../../common/hooks';
9
12
  import { SIDE_PANE_OPTIONS } from '../../common/constants';
10
13
 
11
14
  export const RoomDetailsPane = () => {
12
- const { title, description, details } = useRoomLayoutHeader();
13
- const toggleDetailsPane = useSidepaneToggle(SIDE_PANE_OPTIONS.ROOM_DETAILS);
15
+ const { description } = useRoomLayoutHeader();
16
+ const isMwebHLSStream = useMobileHLSStream();
14
17
  return (
15
18
  <Box css={{ flex: '1 1 0' }}>
16
- <Flex justify="between" align="center" css={{ w: '100%' }}>
17
- <Text variant="h6">{title}</Text>
18
- <Flex
19
- onClick={toggleDetailsPane}
20
- css={{ color: '$on_surface_high', cursor: 'pointer', '&:hover': { opacity: '0.8' } }}
21
- >
22
- <CrossIcon />
19
+ {isMwebHLSStream ? (
20
+ <Flex direction="row" align="center" gap="2">
21
+ <Logo />
22
+ <ShowRoomDetailHeader />
23
23
  </Flex>
24
- </Flex>
25
-
26
- <RoomDetailsRow details={details} />
27
-
24
+ ) : (
25
+ <ShowRoomDetailHeader />
26
+ )}
28
27
  <Box css={{ mt: '$10' }}>
29
- <Text css={{ color: '$on_surface_high', fontWeight: '$semiBold' }}>Description</Text>
28
+ <Text css={{ color: '$on_surface_high', fontWeight: '$semiBold', display: isMwebHLSStream ? 'none' : '' }}>
29
+ Description
30
+ </Text>
30
31
  <Text variant="sm" css={{ c: '$on_surface_medium' }}>
31
32
  {description}
32
33
  </Text>
@@ -34,3 +35,29 @@ export const RoomDetailsPane = () => {
34
35
  </Box>
35
36
  );
36
37
  };
38
+
39
+ const ShowRoomDetailHeader = () => {
40
+ const { title, details } = useRoomLayoutHeader();
41
+ const toggleDetailsPane = useSidepaneToggle(SIDE_PANE_OPTIONS.ROOM_DETAILS);
42
+ const isMwebHLSStream = useMobileHLSStream();
43
+ return (
44
+ <Flex direction="column">
45
+ <Flex justify="between" align="center" css={{ w: '100%' }}>
46
+ <Text variant="h6">{title}</Text>
47
+ {!isMwebHLSStream && (
48
+ <Flex
49
+ onClick={toggleDetailsPane}
50
+ css={{
51
+ color: '$on_surface_high',
52
+ cursor: 'pointer',
53
+ '&:hover': { opacity: '0.8' },
54
+ }}
55
+ >
56
+ <CrossIcon />
57
+ </Flex>
58
+ )}
59
+ </Flex>
60
+ <RoomDetailsRow details={details} />
61
+ </Flex>
62
+ );
63
+ };