@100mslive/roomkit-react 0.1.7-alpha.0 → 0.1.7

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 (39) hide show
  1. package/dist/{HLSView-F5BDZVT2.js → HLSView-3S74KF3A.js} +6 -5
  2. package/dist/{HLSView-F5BDZVT2.js.map → HLSView-3S74KF3A.js.map} +2 -2
  3. package/dist/Prebuilt/components/RoleChangeRequest/RequestPrompt.d.ts +9 -0
  4. package/dist/VideoTile/StyledVideoTile.d.ts +445 -3
  5. package/dist/{VirtualBackground-THDRYDRA.js → VirtualBackground-3TI5NA4V.js} +3 -3
  6. package/dist/{chunk-JSH7SKEH.js → chunk-36X4ZCLC.js} +2 -2
  7. package/dist/{chunk-U3G743OY.js → chunk-5DQ3WTED.js} +2 -2
  8. package/dist/{chunk-U3G743OY.js.map → chunk-5DQ3WTED.js.map} +1 -1
  9. package/dist/{chunk-CDYRVICT.js → chunk-Z7P5WITU.js} +40 -32
  10. package/dist/chunk-Z7P5WITU.js.map +7 -0
  11. package/dist/{conference-6IVZHILI.js → conference-JNABIZBG.js} +506 -490
  12. package/dist/conference-JNABIZBG.js.map +7 -0
  13. package/dist/index.cjs.js +826 -790
  14. package/dist/index.cjs.js.map +4 -4
  15. package/dist/index.js +2 -2
  16. package/dist/meta.cjs.json +185 -126
  17. package/dist/meta.esbuild.json +221 -162
  18. package/package.json +6 -6
  19. package/src/Input/Input.tsx +1 -1
  20. package/src/Prebuilt/common/utils.js +7 -0
  21. package/src/Prebuilt/components/Chat/ChatBody.jsx +125 -106
  22. package/src/Prebuilt/components/Footer/ParticipantList.jsx +1 -1
  23. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +36 -44
  24. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +23 -35
  25. package/src/Prebuilt/components/Preview/PreviewJoin.tsx +5 -3
  26. package/src/Prebuilt/components/RaiseHand.jsx +4 -11
  27. package/src/Prebuilt/components/RoleChangeRequest/RequestPrompt.tsx +66 -0
  28. package/src/Prebuilt/components/{RoleChangeRequestModal.tsx → RoleChangeRequest/RoleChangeRequestModal.tsx} +18 -50
  29. package/src/Prebuilt/components/VideoTile.jsx +18 -12
  30. package/src/Prebuilt/components/conference.jsx +1 -1
  31. package/src/Prebuilt/components/hooks/useMetadata.jsx +2 -1
  32. package/src/Prebuilt/layouts/HLSView.jsx +3 -2
  33. package/src/Prebuilt/layouts/SidePane.tsx +0 -1
  34. package/src/VideoTile/StyledVideoTile.tsx +10 -14
  35. package/dist/chunk-CDYRVICT.js.map +0 -7
  36. package/dist/conference-6IVZHILI.js.map +0 -7
  37. /package/dist/Prebuilt/components/{RoleChangeRequestModal.d.ts → RoleChangeRequest/RoleChangeRequestModal.d.ts} +0 -0
  38. /package/dist/{VirtualBackground-THDRYDRA.js.map → VirtualBackground-3TI5NA4V.js.map} +0 -0
  39. /package/dist/{chunk-JSH7SKEH.js.map → chunk-36X4ZCLC.js.map} +0 -0
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "prebuilt",
11
11
  "roomkit"
12
12
  ],
13
- "version": "0.1.7-alpha.0",
13
+ "version": "0.1.7",
14
14
  "author": "100ms",
15
15
  "license": "MIT",
16
16
  "files": [
@@ -76,10 +76,10 @@
76
76
  "react": ">=17.0.2 <19.0.0"
77
77
  },
78
78
  "dependencies": {
79
- "@100mslive/hls-player": "0.1.16-alpha.0",
80
- "@100mslive/hms-virtual-background": "1.11.16-alpha.0",
81
- "@100mslive/react-icons": "0.8.16-alpha.0",
82
- "@100mslive/react-sdk": "0.8.16-alpha.0",
79
+ "@100mslive/hls-player": "0.1.16",
80
+ "@100mslive/hms-virtual-background": "1.11.16",
81
+ "@100mslive/react-icons": "0.8.16",
82
+ "@100mslive/react-sdk": "0.8.16",
83
83
  "@100mslive/types-prebuilt": "0.12.0",
84
84
  "@emoji-mart/data": "^1.0.6",
85
85
  "@emoji-mart/react": "^1.0.1",
@@ -115,5 +115,5 @@
115
115
  "uuid": "^8.3.2",
116
116
  "worker-timers": "^7.0.40"
117
117
  },
118
- "gitHead": "02a796684045c2468c14db4cb894c56a17c6c2ba"
118
+ "gitHead": "c06edac3e71481de08e948ffe0affaf705564ad1"
119
119
  }
@@ -20,7 +20,7 @@ export const Input = styled('input', {
20
20
  border: '1px solid transparent',
21
21
  },
22
22
  '&::placeholder': {
23
- color: '$on_surface_low',
23
+ color: '$on_surface_medium',
24
24
  },
25
25
  variants: {
26
26
  alert_error_default: {
@@ -88,3 +88,10 @@ export const formatTime = timeInSeconds => {
88
88
  const hour = hours !== 0 ? `${hours < 10 ? '0' : ''}${hours}:` : '';
89
89
  return `${hour}${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
90
90
  };
91
+
92
+ export const getAttributeBoxSize = (width, height) => {
93
+ if (!width || !height) {
94
+ return '';
95
+ }
96
+ return width < 180 || height < 180 ? 'small' : 'medium';
97
+ };
@@ -24,6 +24,7 @@ import { Tooltip } from '../../../Tooltip';
24
24
  import emptyChat from '../../images/empty-chat.svg';
25
25
  import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
26
26
  import { useSetPinnedMessage } from '../hooks/useSetPinnedMessage';
27
+ import { useUnreadCount } from './useUnreadCount';
27
28
 
28
29
  const formatTime = date => {
29
30
  if (!(date instanceof Date)) {
@@ -192,119 +193,127 @@ const SenderName = styled(Text, {
192
193
  fontWeight: '$semiBold',
193
194
  });
194
195
 
195
- const ChatMessage = React.memo(({ index, style = {}, message, setRowHeight, onPin }) => {
196
- const { ref, inView } = useInView({ threshold: 0.5, triggerOnce: true });
197
- const rowRef = useRef(null);
198
- useEffect(() => {
199
- if (rowRef.current) {
200
- setRowHeight(index, rowRef.current.clientHeight);
201
- }
202
- }, [index, setRowHeight]);
203
- const isMobile = useMedia(cssConfig.media.md);
204
- const { elements } = useRoomLayoutConferencingScreen();
205
- const isOverlay = elements?.chat?.is_overlay && isMobile;
206
- const hmsActions = useHMSActions();
207
- const localPeerId = useHMSStore(selectLocalPeerID);
208
- const permissions = useHMSStore(selectPermissions);
209
- const messageType = getMessageType({
210
- roles: message.recipientRoles,
211
- receiver: message.recipientPeer,
212
- });
213
- // show pin action only if peer has remove others permission and the message is of broadcast type
214
- const showPinAction = permissions.removeOthers && !messageType && elements?.chat?.allow_pinning_messages;
196
+ const ChatMessage = React.memo(
197
+ ({ index, style = {}, message, setRowHeight, isLast = false, unreadCount = 0, scrollToBottom, onPin }) => {
198
+ const { ref, inView } = useInView({ threshold: 0.5, triggerOnce: true });
199
+ const rowRef = useRef(null);
200
+ useEffect(() => {
201
+ if (rowRef.current) {
202
+ setRowHeight(index, rowRef.current.clientHeight);
203
+ }
204
+ }, [index, setRowHeight]);
205
+ const isMobile = useMedia(cssConfig.media.md);
206
+ const { elements } = useRoomLayoutConferencingScreen();
207
+ const isOverlay = elements?.chat?.is_overlay && isMobile;
208
+ const hmsActions = useHMSActions();
209
+ const localPeerId = useHMSStore(selectLocalPeerID);
210
+ const permissions = useHMSStore(selectPermissions);
211
+ const messageType = getMessageType({
212
+ roles: message.recipientRoles,
213
+ receiver: message.recipientPeer,
214
+ });
215
+ // show pin action only if peer has remove others permission and the message is of broadcast type
216
+ const showPinAction = permissions.removeOthers && !messageType && elements?.chat?.allow_pinning_messages;
215
217
 
216
- useEffect(() => {
217
- if (message.id && !message.read && inView) {
218
- hmsActions.setMessageRead(true, message.id);
219
- }
220
- }, [message.read, hmsActions, inView, message.id]);
218
+ useEffect(() => {
219
+ if (message.id && !message.read && inView) {
220
+ hmsActions.setMessageRead(true, message.id);
221
+ }
222
+ }, [message.read, hmsActions, inView, message.id]);
221
223
 
222
- return (
223
- <Box
224
- ref={ref}
225
- as="div"
226
- css={{ mb: '$10', pr: '$10', mt: '$8', '&:hover .chat_actions': { opacity: 1 } }}
227
- style={style}
228
- >
229
- <Flex
230
- ref={rowRef}
231
- align="center"
232
- css={{
233
- flexWrap: 'wrap',
234
- // Theme independent color, token should not be used for transparent chat
235
- bg: messageType ? (isOverlay ? 'rgba(0, 0, 0, 0.64)' : '$surface_default') : undefined,
236
- r: messageType ? '$1' : undefined,
237
- px: messageType ? '$4' : '$2',
238
- py: messageType ? '$4' : 0,
239
- userSelect: 'none',
240
- }}
241
- key={message.time}
242
- data-testid="chat_msg"
224
+ useEffect(() => {
225
+ if (isLast && inView && unreadCount >= 1) {
226
+ scrollToBottom(1);
227
+ }
228
+ }, [inView, isLast, scrollToBottom, unreadCount]);
229
+
230
+ return (
231
+ <Box
232
+ ref={ref}
233
+ as="div"
234
+ css={{ mb: '$10', pr: '$10', mt: '$8', '&:hover .chat_actions': { opacity: 1 } }}
235
+ style={style}
243
236
  >
244
- <Text
237
+ <Flex
238
+ ref={rowRef}
239
+ align="center"
245
240
  css={{
246
- color: isOverlay ? '#FFF' : '$on_surface_high',
247
- fontWeight: '$semiBold',
248
- display: 'inline-flex',
249
- alignItems: 'center',
250
- justifyContent: 'space-between',
251
- width: '100%',
241
+ flexWrap: 'wrap',
242
+ // Theme independent color, token should not be used for transparent chat
243
+ bg: messageType ? (isOverlay ? 'rgba(0, 0, 0, 0.64)' : '$surface_default') : undefined,
244
+ r: messageType ? '$1' : undefined,
245
+ px: messageType ? '$4' : '$2',
246
+ py: messageType ? '$4' : 0,
247
+ userSelect: 'none',
252
248
  }}
253
- as="div"
249
+ key={message.time}
250
+ data-testid="chat_msg"
254
251
  >
255
- <Flex align="baseline">
256
- {message.senderName === 'You' || !message.senderName ? (
257
- <SenderName as="span" variant="sm" css={{ color: isOverlay ? '#FFF' : '$on_surface_high' }}>
258
- {message.senderName || 'Anonymous'}
259
- </SenderName>
260
- ) : (
261
- <Tooltip title={message.senderName} side="top" align="start">
252
+ <Text
253
+ css={{
254
+ color: isOverlay ? '#FFF' : '$on_surface_high',
255
+ fontWeight: '$semiBold',
256
+ display: 'inline-flex',
257
+ alignItems: 'center',
258
+ justifyContent: 'space-between',
259
+ width: '100%',
260
+ }}
261
+ as="div"
262
+ >
263
+ <Flex align="baseline">
264
+ {message.senderName === 'You' || !message.senderName ? (
262
265
  <SenderName as="span" variant="sm" css={{ color: isOverlay ? '#FFF' : '$on_surface_high' }}>
263
- {message.senderName}
266
+ {message.senderName || 'Anonymous'}
264
267
  </SenderName>
265
- </Tooltip>
266
- )}
267
- {!isOverlay ? (
268
- <Text
269
- as="span"
270
- variant="xs"
271
- css={{
272
- ml: '$4',
273
- color: '$on_surface_medium',
274
- flexShrink: 0,
275
- }}
276
- >
277
- {formatTime(message.time)}
278
- </Text>
279
- ) : null}
280
- </Flex>
281
- <MessageType
282
- hasCurrentUserSent={message.sender === localPeerId}
283
- receiver={message.recipientPeer}
284
- roles={message.recipientRoles}
285
- />
286
- {!isOverlay ? <ChatActions onPin={onPin} showPinAction={showPinAction} /> : null}
287
- </Text>
288
- <Text
289
- variant="sm"
290
- css={{
291
- w: '100%',
292
- mt: '$2',
293
- wordBreak: 'break-word',
294
- whiteSpace: 'pre-wrap',
295
- userSelect: 'all',
296
- color: isOverlay ? '#FFF' : '$on_surface_high',
297
- }}
298
- onClick={e => e.stopPropagation()}
299
- >
300
- <AnnotisedMessage message={message.message} />
301
- </Text>
302
- </Flex>
303
- </Box>
304
- );
305
- });
268
+ ) : (
269
+ <Tooltip title={message.senderName} side="top" align="start">
270
+ <SenderName as="span" variant="sm" css={{ color: isOverlay ? '#FFF' : '$on_surface_high' }}>
271
+ {message.senderName}
272
+ </SenderName>
273
+ </Tooltip>
274
+ )}
275
+ {!isOverlay ? (
276
+ <Text
277
+ as="span"
278
+ variant="xs"
279
+ css={{
280
+ ml: '$4',
281
+ color: '$on_surface_medium',
282
+ flexShrink: 0,
283
+ }}
284
+ >
285
+ {formatTime(message.time)}
286
+ </Text>
287
+ ) : null}
288
+ </Flex>
289
+ <MessageType
290
+ hasCurrentUserSent={message.sender === localPeerId}
291
+ receiver={message.recipientPeer}
292
+ roles={message.recipientRoles}
293
+ />
294
+ {!isOverlay ? <ChatActions onPin={onPin} showPinAction={showPinAction} /> : null}
295
+ </Text>
296
+ <Text
297
+ variant="sm"
298
+ css={{
299
+ w: '100%',
300
+ mt: '$2',
301
+ wordBreak: 'break-word',
302
+ whiteSpace: 'pre-wrap',
303
+ userSelect: 'all',
304
+ color: isOverlay ? '#FFF' : '$on_surface_high',
305
+ }}
306
+ onClick={e => e.stopPropagation()}
307
+ >
308
+ <AnnotisedMessage message={message.message} />
309
+ </Text>
310
+ </Flex>
311
+ </Box>
312
+ );
313
+ },
314
+ );
306
315
  const ChatList = React.forwardRef(
307
- ({ width, height, setRowHeight, getRowHeight, messages, scrollToBottom }, listRef) => {
316
+ ({ width, height, setRowHeight, getRowHeight, messages, unreadCount = 0, scrollToBottom }, listRef) => {
308
317
  const { setPinnedMessage } = useSetPinnedMessage();
309
318
  useLayoutEffect(() => {
310
319
  if (listRef.current && listRef.current.scrollToItem) {
@@ -331,6 +340,9 @@ const ChatList = React.forwardRef(
331
340
  key={messages[index].id}
332
341
  message={messages[index]}
333
342
  setRowHeight={setRowHeight}
343
+ unreadCount={unreadCount}
344
+ isLast={index >= messages.length - 2}
345
+ scrollToBottom={scrollToBottom}
334
346
  onPin={() => setPinnedMessage(messages[index])}
335
347
  />
336
348
  )}
@@ -338,7 +350,7 @@ const ChatList = React.forwardRef(
338
350
  );
339
351
  },
340
352
  );
341
- const VirtualizedChatMessages = React.forwardRef(({ messages, scrollToBottom }, listRef) => {
353
+ const VirtualizedChatMessages = React.forwardRef(({ messages, unreadCount = 0, scrollToBottom }, listRef) => {
342
354
  const rowHeights = useRef({});
343
355
 
344
356
  function getRowHeight(index) {
@@ -377,6 +389,7 @@ const VirtualizedChatMessages = React.forwardRef(({ messages, scrollToBottom },
377
389
  getRowHeight={getRowHeight}
378
390
  scrollToBottom={scrollToBottom}
379
391
  ref={listRef}
392
+ unreadCount={unreadCount}
380
393
  />
381
394
  )}
382
395
  </AutoSizer>
@@ -394,6 +407,7 @@ export const ChatBody = React.forwardRef(({ role, peerId, scrollToBottom }, list
394
407
  messages = useMemo(() => messages?.filter(message => message.type === 'chat') || [], [messages]);
395
408
  const isMobile = useMedia(cssConfig.media.md);
396
409
  const { elements } = useRoomLayoutConferencingScreen();
410
+ const unreadCount = useUnreadCount({ role, peerId });
397
411
 
398
412
  if (messages.length === 0 && !(isMobile && elements?.chat?.is_overlay)) {
399
413
  return (
@@ -425,7 +439,12 @@ export const ChatBody = React.forwardRef(({ role, peerId, scrollToBottom }, list
425
439
 
426
440
  return (
427
441
  <Fragment>
428
- <VirtualizedChatMessages messages={messages} scrollToBottom={scrollToBottom} ref={listRef} />
442
+ <VirtualizedChatMessages
443
+ messages={messages}
444
+ scrollToBottom={scrollToBottom}
445
+ unreadCount={unreadCount}
446
+ ref={listRef}
447
+ />
429
448
  </Fragment>
430
449
  );
431
450
  });
@@ -327,7 +327,7 @@ export const ParticipantSearch = ({ onSearch, placeholder, inSidePane = false })
327
327
  <Input
328
328
  type="text"
329
329
  placeholder={placeholder || 'Search for participants'}
330
- css={{ w: '100%', p: '$6', pl: '$14', mr: '$4', bg: inSidePane ? '$surface_default' : '$surface_dim' }}
330
+ css={{ w: '100%', p: '$6', pl: '$16', mr: '$4', bg: inSidePane ? '$surface_default' : '$surface_dim' }}
331
331
  value={value}
332
332
  onKeyDown={event => {
333
333
  event.stopPropagation();
@@ -29,6 +29,7 @@ export const DesktopLeaveRoom = ({
29
29
  const permissions = useHMSStore(selectPermissions);
30
30
  const { isStreamingOn } = useRecordingStreaming();
31
31
  const showStream = screenType !== 'hls_live_streaming' && isStreamingOn;
32
+ const showLeaveOptions = (permissions?.hlsStreaming && isStreamingOn) || permissions?.endRoom;
32
33
 
33
34
  useDropdownList({ open: open || showEndStreamAlert || showLeaveRoomAlert, name: 'LeaveRoom' });
34
35
 
@@ -38,7 +39,7 @@ export const DesktopLeaveRoom = ({
38
39
 
39
40
  return (
40
41
  <Fragment>
41
- {screenType !== 'hls_live_streaming' && (permissions?.hlsStreaming || permissions?.endRoom) ? (
42
+ {showLeaveOptions ? (
42
43
  <Flex>
43
44
  <LeaveIconButton
44
45
  key="LeaveRoom"
@@ -47,9 +48,7 @@ export const DesktopLeaveRoom = ({
47
48
  borderTopRightRadius: 0,
48
49
  borderBottomRightRadius: 0,
49
50
  }}
50
- onClick={() => {
51
- leaveRoom({ endstream: false });
52
- }}
51
+ onClick={() => setShowLeaveRoomAlert(true)}
53
52
  >
54
53
  <Tooltip title="Leave Room">
55
54
  <Box>
@@ -74,7 +73,7 @@ export const DesktopLeaveRoom = ({
74
73
  <Dropdown.Item
75
74
  css={{
76
75
  bg: '$surface_dim',
77
- color: '$on_surface_low',
76
+ color: '$on_surface_medium',
78
77
  '&:hover': { bg: '$surface_default', color: '$on_surface_high' },
79
78
  }}
80
79
  onClick={() => leaveRoom({ endstream: false })}
@@ -92,42 +91,37 @@ export const DesktopLeaveRoom = ({
92
91
  css={{ p: 0 }}
93
92
  />
94
93
  </Dropdown.Item>
95
- {permissions?.endRoom || permissions?.hlsStreaming ? (
96
- <Dropdown.Item
97
- css={{
98
- bg: '$alert_error_dim',
99
- color: '$alert_error_bright',
100
- '&:hover': { bg: '$alert_error_dim', color: '$alert_error_brighter' },
94
+
95
+ <Dropdown.Item
96
+ css={{
97
+ bg: '$alert_error_dim',
98
+ color: '$alert_error_bright',
99
+ '&:hover': { bg: '$alert_error_dim', color: '$alert_error_brighter' },
100
+ }}
101
+ data-testid="end_room_btn"
102
+ >
103
+ <LeaveCard
104
+ title={showStream ? 'End Stream' : 'End Session'}
105
+ subtitle={`The ${
106
+ showStream ? 'stream' : 'session'
107
+ } will end for everyone. You can't undo this action.`}
108
+ bg=""
109
+ titleColor="$alert_error_brighter"
110
+ icon={<StopIcon height={24} width={24} />}
111
+ onClick={() => {
112
+ setOpen(false);
113
+ setShowEndStreamAlert(true);
101
114
  }}
102
- data-testid="end_room_btn"
103
- >
104
- <LeaveCard
105
- title={showStream ? 'End Stream' : 'End Session'}
106
- subtitle={`The ${
107
- showStream ? 'stream' : 'session'
108
- } will end for everyone. You can't undo this action.`}
109
- bg=""
110
- titleColor="$alert_error_brighter"
111
- icon={<StopIcon height={24} width={24} />}
112
- onClick={() => {
113
- setOpen(false);
114
- setShowEndStreamAlert(true);
115
- }}
116
- css={{ p: 0 }}
117
- />
118
- </Dropdown.Item>
119
- ) : null}
115
+ css={{ p: 0 }}
116
+ />
117
+ </Dropdown.Item>
120
118
  </Dropdown.Content>
121
119
  </Dropdown.Root>
122
120
  </Flex>
123
121
  ) : (
124
122
  <LeaveIconButton
125
123
  onClick={() => {
126
- if (screenType === 'hls_live_streaming') {
127
- setShowLeaveRoomAlert(true);
128
- } else {
129
- leaveRoom({ endstream: false });
130
- }
124
+ setShowLeaveRoomAlert(true);
131
125
  }}
132
126
  key="LeaveRoom"
133
127
  data-testid="leave_room_btn"
@@ -154,16 +148,14 @@ export const DesktopLeaveRoom = ({
154
148
  </Dialog.Portal>
155
149
  </Dialog.Root>
156
150
 
157
- {screenType === 'hls_live_streaming' ? (
158
- <Dialog.Root open={showLeaveRoomAlert} modal={false}>
159
- <Dialog.Portal>
160
- <Dialog.Overlay />
161
- <Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
162
- <LeaveSessionContent setShowLeaveRoomAlert={setShowLeaveRoomAlert} leaveRoom={leaveRoom} isModal />
163
- </Dialog.Content>
164
- </Dialog.Portal>
165
- </Dialog.Root>
166
- ) : null}
151
+ <Dialog.Root open={showLeaveRoomAlert} modal={false}>
152
+ <Dialog.Portal>
153
+ <Dialog.Overlay />
154
+ <Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
155
+ <LeaveSessionContent setShowLeaveRoomAlert={setShowLeaveRoomAlert} leaveRoom={leaveRoom} isModal />
156
+ </Dialog.Content>
157
+ </Dialog.Portal>
158
+ </Dialog.Root>
167
159
  </Fragment>
168
160
  );
169
161
  };
@@ -30,6 +30,7 @@ export const MwebLeaveRoom = ({
30
30
  const permissions = useHMSStore(selectPermissions);
31
31
  const { isStreamingOn } = useRecordingStreaming();
32
32
  const showStream = screenType !== 'hls_live_streaming' && isStreamingOn;
33
+ const showLeaveOptions = (permissions?.hlsStreaming && isStreamingOn) || permissions?.endRoom;
33
34
 
34
35
  useDropdownList({ open, name: 'LeaveRoom' });
35
36
 
@@ -39,7 +40,7 @@ export const MwebLeaveRoom = ({
39
40
 
40
41
  return (
41
42
  <Fragment>
42
- {screenType !== 'hls_live_streaming' ? (
43
+ {showLeaveOptions ? (
43
44
  <Sheet.Root open={open} onOpenChange={setOpen}>
44
45
  <Sheet.Trigger asChild>
45
46
  <LeaveIconButton
@@ -70,36 +71,24 @@ export const MwebLeaveRoom = ({
70
71
  css={{ pt: 0, mt: '$10', color: '$on_surface_low', '&:hover': { color: '$on_surface_high' } }}
71
72
  />
72
73
 
73
- {permissions?.endRoom || permissions?.hlsStreaming ? (
74
- <LeaveCard
75
- title={showStream ? 'End Stream' : 'End Session'}
76
- subtitle={`The will end the ${
77
- showStream ? 'stream' : 'session'
78
- } for everyone. You can't undo this action.`}
79
- bg="$alert_error_dim"
80
- titleColor="$alert_error_brighter"
81
- css={{ color: '$alert_error_bright', '&:hover': { color: '$alert_error_brighter' } }}
82
- icon={<StopIcon height={24} width={24} />}
83
- onClick={() => {
84
- setOpen(false);
85
- setShowEndStreamAlert(true);
86
- }}
87
- />
88
- ) : null}
74
+ <LeaveCard
75
+ title={showStream ? 'End Stream' : 'End Session'}
76
+ subtitle={`The will end the ${
77
+ showStream ? 'stream' : 'session'
78
+ } for everyone. You can't undo this action.`}
79
+ bg="$alert_error_dim"
80
+ titleColor="$alert_error_brighter"
81
+ css={{ color: '$alert_error_bright', '&:hover': { color: '$alert_error_brighter' } }}
82
+ icon={<StopIcon height={24} width={24} />}
83
+ onClick={() => {
84
+ setOpen(false);
85
+ setShowEndStreamAlert(true);
86
+ }}
87
+ />
89
88
  </Sheet.Content>
90
89
  </Sheet.Root>
91
90
  ) : (
92
- <LeaveIconButton
93
- key="LeaveRoom"
94
- data-testid="leave_room_btn"
95
- onClick={() => {
96
- if (screenType === 'hls_live_streaming') {
97
- setShowLeaveRoomAlert(true);
98
- } else {
99
- leaveRoom({ endstream: false });
100
- }
101
- }}
102
- >
91
+ <LeaveIconButton key="LeaveRoom" data-testid="leave_room_btn" onClick={() => setShowLeaveRoomAlert(true)}>
103
92
  <Tooltip title="Leave Room">
104
93
  <Box>
105
94
  <ExitIcon style={{ transform: 'rotate(180deg)' }} />
@@ -116,13 +105,12 @@ export const MwebLeaveRoom = ({
116
105
  />
117
106
  </Sheet.Content>
118
107
  </Sheet.Root>
119
- {screenType === 'hls_live_streaming' ? (
120
- <Sheet.Root open={showLeaveRoomAlert} onOpenChange={setShowLeaveRoomAlert}>
121
- <Sheet.Content css={{ bg: '$surface_dim', p: '$10', pb: '$12' }}>
122
- <LeaveSessionContent setShowLeaveRoomAlert={setShowLeaveRoomAlert} leaveRoom={leaveRoom} />
123
- </Sheet.Content>
124
- </Sheet.Root>
125
- ) : null}
108
+
109
+ <Sheet.Root open={showLeaveRoomAlert} onOpenChange={setShowLeaveRoomAlert}>
110
+ <Sheet.Content css={{ bg: '$surface_dim', p: '$10', pb: '$12' }}>
111
+ <LeaveSessionContent setShowLeaveRoomAlert={setShowLeaveRoomAlert} leaveRoom={leaveRoom} />
112
+ </Sheet.Content>
113
+ </Sheet.Root>
126
114
  </Fragment>
127
115
  );
128
116
  };
@@ -170,7 +170,7 @@ const PreviewJoin = ({
170
170
  <PreviewTile name={name} error={previewError} />
171
171
  </Flex>
172
172
  ) : null}
173
- <Box css={{ w: '100%', maxWidth: `${aspectRatio * 360}px` }}>
173
+ <Box css={{ w: '100%', maxWidth: `${Math.max(aspectRatio, 1) * 360}px` }}>
174
174
  <PreviewControls hideSettings={!toggleVideo && !toggleAudio} />
175
175
  <PreviewForm
176
176
  name={name}
@@ -230,6 +230,7 @@ export const PreviewTile = ({ name, error }: { name: string; error?: boolean })
230
230
  trackId={localPeer.videoTrack}
231
231
  data-testid="preview_tile"
232
232
  />
233
+
233
234
  {!isVideoOn ? (
234
235
  <StyledVideoTile.AvatarContainer>
235
236
  <Avatar name={name} data-testid="preview_avatar_tile" />
@@ -239,8 +240,9 @@ export const PreviewTile = ({ name, error }: { name: string; error?: boolean })
239
240
  ) : !error ? (
240
241
  <FullPageProgress />
241
242
  ) : null}
243
+
242
244
  {showMuteIcon ? (
243
- <StyledVideoTile.AudioIndicator size="medium">
245
+ <StyledVideoTile.AudioIndicator>
244
246
  <MicOffIcon />
245
247
  </StyledVideoTile.AudioIndicator>
246
248
  ) : (
@@ -255,7 +257,7 @@ export const PreviewControls = ({ hideSettings }: { hideSettings: boolean }) =>
255
257
 
256
258
  return (
257
259
  <Flex
258
- justify="between"
260
+ justify={hideSettings && isMobile ? 'center' : 'between'}
259
261
  css={{
260
262
  width: '100%',
261
263
  mt: '$8',
@@ -1,22 +1,15 @@
1
1
  import React from 'react';
2
- import { selectHasPeerHandRaised, selectLocalPeerID, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
3
2
  import { HandIcon } from '@100mslive/react-icons';
4
3
  import { Tooltip } from '../../Tooltip';
5
4
  import IconButton from '../IconButton';
5
+ // @ts-ignore: No implicit Any
6
+ import { useMyMetadata } from './hooks/useMetadata';
6
7
 
7
8
  export const RaiseHand = () => {
8
- const localPeerId = useHMSStore(selectLocalPeerID);
9
- const isHandRaised = useHMSStore(selectHasPeerHandRaised(localPeerId));
10
- const actions = useHMSActions();
11
-
9
+ const { isHandRaised, toggleHandRaise } = useMyMetadata();
12
10
  return (
13
11
  <Tooltip title={isHandRaised ? 'Lower hand' : 'Raise hand'}>
14
- <IconButton
15
- active={!isHandRaised}
16
- onClick={() => {
17
- isHandRaised ? actions.lowerLocalPeerHand() : actions.raiseLocalPeerHand();
18
- }}
19
- >
12
+ <IconButton active={!isHandRaised} onClick={async () => await toggleHandRaise()}>
20
13
  <HandIcon />
21
14
  </IconButton>
22
15
  </Tooltip>