@100mslive/roomkit-react 0.1.6 → 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 (51) hide show
  1. package/dist/{HLSView-4NSE37G7.js → HLSView-3S74KF3A.js} +23 -4
  2. package/dist/HLSView-3S74KF3A.js.map +7 -0
  3. package/dist/Prebuilt/components/RoleChangeRequest/RequestPrompt.d.ts +9 -0
  4. package/dist/VideoTile/StyledVideoTile.d.ts +445 -3
  5. package/dist/{VirtualBackground-A5UM363O.js → VirtualBackground-3TI5NA4V.js} +3 -3
  6. package/dist/{chunk-BUWIMYLW.js → chunk-36X4ZCLC.js} +2 -2
  7. package/dist/{chunk-NMOZ33TX.js → chunk-5DQ3WTED.js} +3 -2
  8. package/dist/{chunk-NMOZ33TX.js.map → chunk-5DQ3WTED.js.map} +2 -2
  9. package/dist/{chunk-Q6U22HIE.js → chunk-Z7P5WITU.js} +223 -200
  10. package/dist/chunk-Z7P5WITU.js.map +7 -0
  11. package/dist/{conference-S7R3O4OC.js → conference-JNABIZBG.js} +534 -504
  12. package/dist/conference-JNABIZBG.js.map +7 -0
  13. package/dist/index.cjs.js +1011 -924
  14. package/dist/index.cjs.js.map +4 -4
  15. package/dist/index.js +2 -2
  16. package/dist/meta.cjs.json +241 -167
  17. package/dist/meta.esbuild.json +276 -203
  18. package/package.json +6 -6
  19. package/src/Input/Input.tsx +1 -1
  20. package/src/Prebuilt/common/hooks.js +1 -2
  21. package/src/Prebuilt/common/utils.js +7 -2
  22. package/src/Prebuilt/components/Chat/ChatBody.jsx +125 -106
  23. package/src/Prebuilt/components/Chat/ChatFooter.tsx +1 -0
  24. package/src/Prebuilt/components/Footer/Footer.tsx +4 -1
  25. package/src/Prebuilt/components/Footer/ParticipantList.jsx +8 -9
  26. package/src/Prebuilt/components/Header/ParticipantFilter.jsx +9 -12
  27. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +36 -44
  28. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +23 -35
  29. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +4 -2
  30. package/src/Prebuilt/components/Notifications/Notifications.jsx +14 -1
  31. package/src/Prebuilt/components/Notifications/PeerNotifications.jsx +4 -15
  32. package/src/Prebuilt/components/Preview/PreviewJoin.tsx +12 -5
  33. package/src/Prebuilt/components/RaiseHand.jsx +3 -6
  34. package/src/Prebuilt/components/RoleChangeRequest/RequestPrompt.tsx +66 -0
  35. package/src/Prebuilt/components/RoleChangeRequest/RoleChangeRequestModal.tsx +89 -0
  36. package/src/Prebuilt/components/SidePaneTabs.tsx +21 -2
  37. package/src/Prebuilt/components/VideoTile.jsx +24 -15
  38. package/src/Prebuilt/components/conference.jsx +1 -1
  39. package/src/Prebuilt/components/hooks/useMetadata.jsx +15 -4
  40. package/src/Prebuilt/layouts/HLSView.jsx +20 -1
  41. package/src/Prebuilt/layouts/SidePane.tsx +0 -1
  42. package/src/Tooltip/Tooltip.tsx +1 -1
  43. package/src/VideoTile/StyledVideoTile.tsx +10 -14
  44. package/src/fixtures/peers.ts +5 -3
  45. package/dist/HLSView-4NSE37G7.js.map +0 -7
  46. package/dist/chunk-Q6U22HIE.js.map +0 -7
  47. package/dist/conference-S7R3O4OC.js.map +0 -7
  48. package/src/Prebuilt/components/RoleChangeRequestModal.tsx +0 -120
  49. /package/dist/Prebuilt/components/{RoleChangeRequestModal.d.ts → RoleChangeRequest/RoleChangeRequestModal.d.ts} +0 -0
  50. /package/dist/{VirtualBackground-A5UM363O.js.map → VirtualBackground-3TI5NA4V.js.map} +0 -0
  51. /package/dist/{chunk-BUWIMYLW.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.6",
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.15",
80
- "@100mslive/hms-virtual-background": "1.11.15",
81
- "@100mslive/react-icons": "0.8.15",
82
- "@100mslive/react-sdk": "0.8.15",
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": "0578f113babef7488a788837c63f7f8a7aa246e3"
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: {
@@ -12,7 +12,6 @@ import {
12
12
  useHMSVanillaStore,
13
13
  } from '@100mslive/react-sdk';
14
14
  import { useRoomLayout } from '../provider/roomLayoutProvider';
15
- import { isInternalRole } from './utils';
16
15
 
17
16
  /**
18
17
  * Hook to execute a callback when alone in room(after a certain 5d of time)
@@ -53,7 +52,7 @@ export const useWhenAloneInRoom = (thresholdMs = 5 * 60 * 1000) => {
53
52
  };
54
53
 
55
54
  export const useFilteredRoles = () => {
56
- const roles = useHMSStore(selectAvailableRoleNames).filter(role => !isInternalRole(role));
55
+ const roles = useHMSStore(selectAvailableRoleNames);
57
56
  return roles;
58
57
  };
59
58
 
@@ -56,8 +56,6 @@ export const isScreenshareSupported = () => {
56
56
  return typeof navigator.mediaDevices.getDisplayMedia !== 'undefined';
57
57
  };
58
58
 
59
- export const isInternalRole = role => role && role.startsWith('__internal');
60
-
61
59
  export const metadataPayloadParser = payload => {
62
60
  try {
63
61
  const data = window.atob(payload);
@@ -90,3 +88,10 @@ export const formatTime = timeInSeconds => {
90
88
  const hour = hours !== 0 ? `${hours < 10 ? '0' : ''}${hours}:` : '';
91
89
  return `${hour}${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
92
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
  });
@@ -151,6 +151,7 @@ export const ChatFooter = ({
151
151
  c: '$on_surface_high',
152
152
  '&:valid ~ .send-msg': { color: '$on_surface_high' },
153
153
  '& ~ .send-msg': { color: '$on_surface_low' },
154
+ '&::placeholder': { color: '$on_surface_medium' },
154
155
  }}
155
156
  placeholder="Send a message...."
156
157
  ref={inputRef}
@@ -6,6 +6,7 @@ import {
6
6
  HLSLiveStreamingScreen_Elements,
7
7
  } from '@100mslive/types-prebuilt';
8
8
  import { Chat_ChatState } from '@100mslive/types-prebuilt/elements/chat';
9
+ import { useAVToggle } from '@100mslive/react-sdk';
9
10
  import { config as cssConfig, Footer as AppFooter } from '../../..';
10
11
  // @ts-ignore: No implicit Any
11
12
  import { AudioVideoToggle } from '../AudioVideoToggle';
@@ -41,6 +42,8 @@ export const Footer = ({
41
42
  const isOverlayChat = !!elements?.chat?.is_overlay;
42
43
  const openByDefault = elements?.chat?.initial_state === Chat_ChatState.CHAT_STATE_OPEN;
43
44
 
45
+ const { toggleAudio, toggleVideo } = useAVToggle();
46
+ const noAVPermissions = !(toggleAudio || toggleVideo);
44
47
  const isChatOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.CHAT);
45
48
  const toggleChat = useSidepaneToggle(SIDE_PANE_OPTIONS.CHAT);
46
49
 
@@ -91,7 +94,7 @@ export const Footer = ({
91
94
  >
92
95
  {isMobile ? (
93
96
  <>
94
- {screenType === 'hls_live_streaming' ? <RaiseHand /> : null}
97
+ {noAVPermissions ? <RaiseHand /> : null}
95
98
  {elements?.chat && <ChatToggle />}
96
99
  <MoreSettings elements={elements} screenType={screenType} />
97
100
  </>
@@ -1,11 +1,12 @@
1
1
  import React, { Fragment, useCallback, useEffect, useState } from 'react';
2
2
  import { useDebounce, useMedia } from 'react-use';
3
3
  import {
4
+ selectHandRaisedPeers,
5
+ selectHasPeerHandRaised,
4
6
  selectIsPeerAudioEnabled,
5
7
  selectLocalPeerID,
6
8
  selectPeerCount,
7
9
  selectPeerMetadata,
8
- selectPeersByCondition,
9
10
  selectPermissions,
10
11
  useHMSActions,
11
12
  useHMSStore,
@@ -27,7 +28,7 @@ import { RoleAccordion } from './RoleAccordion';
27
28
  import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
28
29
  import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane';
29
30
  import { useParticipants } from '../../common/hooks';
30
- import { isInternalRole } from '../../common/utils';
31
+ import { getFormattedCount } from '../../common/utils';
31
32
  import { SIDE_PANE_OPTIONS } from '../../common/constants';
32
33
 
33
34
  export const ParticipantList = () => {
@@ -35,7 +36,7 @@ export const ParticipantList = () => {
35
36
  const { participants, isConnected, peerCount } = useParticipants(filter);
36
37
  const peersOrderedByRoles = {};
37
38
 
38
- const handRaisedPeers = useHMSStore(selectPeersByCondition(peer => JSON.parse(peer.metadata || '{}')?.isHandRaised));
39
+ const handRaisedPeers = useHMSStore(selectHandRaisedPeers);
39
40
 
40
41
  participants.forEach(participant => {
41
42
  if (peersOrderedByRoles[participant.roleName] === undefined) {
@@ -107,7 +108,7 @@ export const ParticipantCount = () => {
107
108
  >
108
109
  <PeopleIcon />
109
110
  <Text variant="sm" css={{ mx: '$4', c: 'inherit' }}>
110
- {peerCount}
111
+ {getFormattedCount(peerCount)}
111
112
  </Text>
112
113
  </IconButton>
113
114
  );
@@ -176,7 +177,7 @@ export const Participant = ({ peer, isConnected }) => {
176
177
  * shows settings to change for a participant like changing their role
177
178
  */
178
179
  const ParticipantActions = React.memo(({ peerId, role, isLocal }) => {
179
- const isHandRaised = useHMSStore(selectPeerMetadata(peerId))?.isHandRaised;
180
+ const isHandRaised = useHMSStore(selectHasPeerHandRaised(peerId));
180
181
  const canChangeRole = useHMSStore(selectPermissions)?.changeRole;
181
182
  const shouldShowMoreActions = canChangeRole;
182
183
  const isAudioMuted = !useHMSStore(selectIsPeerAudioEnabled(peerId));
@@ -209,9 +210,7 @@ const ParticipantActions = React.memo(({ peerId, role, isLocal }) => {
209
210
  </Flex>
210
211
  ) : null}
211
212
 
212
- {shouldShowMoreActions && !isInternalRole(role) && !isLocal ? (
213
- <ParticipantMoreActions peerId={peerId} role={role} />
214
- ) : null}
213
+ {shouldShowMoreActions && !isLocal ? <ParticipantMoreActions peerId={peerId} role={role} /> : null}
215
214
  </Flex>
216
215
  );
217
216
  });
@@ -328,7 +327,7 @@ export const ParticipantSearch = ({ onSearch, placeholder, inSidePane = false })
328
327
  <Input
329
328
  type="text"
330
329
  placeholder={placeholder || 'Search for participants'}
331
- 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' }}
332
331
  value={value}
333
332
  onKeyDown={event => {
334
333
  event.stopPropagation();
@@ -1,7 +1,6 @@
1
1
  import React, { useCallback, useState } from 'react';
2
2
  import { CheckIcon, ChevronDownIcon, ChevronUpIcon, HandRaiseIcon, PeopleIcon } from '@100mslive/react-icons';
3
3
  import { Box, Dropdown, Flex, Text, textEllipsis } from '../../../';
4
- import { isInternalRole } from '../../common/utils';
5
4
 
6
5
  export const ParticipantFilter = ({ selection, onSelection, isConnected, roles }) => {
7
6
  const [open, setOpen] = useState(false);
@@ -53,17 +52,15 @@ export const ParticipantFilter = ({ selection, onSelection, isConnected, roles }
53
52
  value={{ metadata: { isHandRaised: true }, role: '' }}
54
53
  />
55
54
  <Dropdown.ItemSeparator />
56
- {roles
57
- .filter(role => !isInternalRole(role))
58
- .map(role => (
59
- <Item
60
- key={role}
61
- selected={selectionValue === role}
62
- title={role}
63
- value={{ metadata: { isHandRaised: false }, role }}
64
- onSelection={onItemClick}
65
- />
66
- ))}
55
+ {roles.map(role => (
56
+ <Item
57
+ key={role}
58
+ selected={selectionValue === role}
59
+ title={role}
60
+ value={{ metadata: { isHandRaised: false }, role }}
61
+ onSelection={onItemClick}
62
+ />
63
+ ))}
67
64
  </Dropdown.Content>
68
65
  </Dropdown.Root>
69
66
  );
@@ -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
  };