@100mslive/roomkit-react 0.1.14-alpha.1 → 0.1.14

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 (61) hide show
  1. package/dist/{HLSView-JTO7E2KW.js → HLSView-662T7R7H.js} +2 -2
  2. package/dist/Prebuilt/common/constants.d.ts +1 -0
  3. package/dist/Prebuilt/common/hooks.d.ts +24 -0
  4. package/dist/Prebuilt/components/Chat/{Navigation.d.ts → ArrowNavigation.d.ts} +1 -2
  5. package/dist/Prebuilt/components/Chat/ChatFooter.d.ts +2 -4
  6. package/dist/Prebuilt/components/Chat/ChatSelector.d.ts +5 -0
  7. package/dist/Prebuilt/components/Chat/ChatSelectorContainer.d.ts +2 -0
  8. package/dist/Prebuilt/components/Chat/ChatStates.d.ts +3 -0
  9. package/dist/Prebuilt/components/Chat/StickIndicator.d.ts +5 -0
  10. package/dist/Prebuilt/components/Chat/useUnreadCount.d.ts +4 -0
  11. package/dist/Prebuilt/components/ChatSettings.d.ts +2 -0
  12. package/dist/Prebuilt/components/Preview/PreviewForm.d.ts +2 -1
  13. package/dist/Prebuilt/components/SidePaneTabs.d.ts +0 -2
  14. package/dist/Prebuilt/components/TileMenu/TileMenuContent.d.ts +19 -0
  15. package/dist/Prebuilt/components/VirtualBackground/VBOption.d.ts +2 -1
  16. package/dist/Prebuilt/components/hooks/useChatBlacklist.d.ts +2 -1
  17. package/dist/Prebuilt/components/hooks/useSetPinnedMessages.d.ts +1 -1
  18. package/dist/Prebuilt/layouts/SidePane.d.ts +1 -3
  19. package/dist/{chunk-TOKLXTAS.js → chunk-2B7YYNHQ.js} +1651 -1229
  20. package/dist/chunk-2B7YYNHQ.js.map +7 -0
  21. package/dist/index.cjs.js +2074 -1609
  22. package/dist/index.cjs.js.map +4 -4
  23. package/dist/index.js +1 -1
  24. package/dist/meta.cjs.json +451 -115
  25. package/dist/meta.esbuild.json +457 -121
  26. package/package.json +6 -6
  27. package/src/Prebuilt/common/constants.ts +1 -0
  28. package/src/Prebuilt/common/{hooks.js → hooks.ts} +4 -5
  29. package/src/Prebuilt/components/AppData/AppData.tsx +1 -0
  30. package/src/Prebuilt/components/AppData/useUISettings.js +2 -1
  31. package/src/Prebuilt/components/AuthToken.jsx +16 -8
  32. package/src/Prebuilt/components/Chat/{Navigation.tsx → ArrowNavigation.tsx} +3 -19
  33. package/src/Prebuilt/components/Chat/Chat.jsx +15 -44
  34. package/src/Prebuilt/components/Chat/ChatBody.jsx +114 -69
  35. package/src/Prebuilt/components/Chat/ChatFooter.tsx +128 -130
  36. package/src/Prebuilt/components/Chat/ChatSelector.tsx +225 -0
  37. package/src/Prebuilt/components/Chat/ChatSelectorContainer.tsx +158 -0
  38. package/src/Prebuilt/components/Chat/{ChatStates.jsx → ChatStates.tsx} +4 -4
  39. package/src/Prebuilt/components/Chat/PinnedMessage.tsx +59 -41
  40. package/src/Prebuilt/components/Chat/StickIndicator.tsx +24 -0
  41. package/src/Prebuilt/components/Chat/useUnreadCount.ts +19 -0
  42. package/src/Prebuilt/components/ChatSettings.tsx +68 -0
  43. package/src/Prebuilt/components/Footer/ParticipantList.jsx +2 -1
  44. package/src/Prebuilt/components/Header/ParticipantFilter.jsx +2 -1
  45. package/src/Prebuilt/components/Notifications/ChatNotifications.tsx +1 -1
  46. package/src/Prebuilt/components/Preview/PreviewForm.tsx +3 -0
  47. package/src/Prebuilt/components/Preview/PreviewJoin.tsx +2 -1
  48. package/src/Prebuilt/components/SidePaneTabs.tsx +48 -50
  49. package/src/Prebuilt/components/TileMenu/{TileMenuContent.jsx → TileMenuContent.tsx} +72 -41
  50. package/src/Prebuilt/components/VirtualBackground/VBCollection.tsx +2 -1
  51. package/src/Prebuilt/components/VirtualBackground/VBOption.tsx +3 -0
  52. package/src/Prebuilt/components/VirtualBackground/VBToggle.jsx +1 -1
  53. package/src/Prebuilt/components/hooks/useChatBlacklist.ts +8 -6
  54. package/src/Prebuilt/components/hooks/useSetPinnedMessages.ts +2 -7
  55. package/src/Prebuilt/layouts/SidePane.tsx +1 -5
  56. package/src/Prebuilt/provider/roomLayoutProvider/constants/index.ts +1 -0
  57. package/dist/chunk-TOKLXTAS.js.map +0 -7
  58. package/src/Prebuilt/components/Chat/ChatSelector.jsx +0 -161
  59. package/src/Prebuilt/components/Chat/ChatSelectorContainer.jsx +0 -81
  60. package/src/Prebuilt/components/Chat/useUnreadCount.js +0 -17
  61. /package/dist/{HLSView-JTO7E2KW.js.map → HLSView-662T7R7H.js.map} +0 -0
@@ -0,0 +1,158 @@
1
+ import React, { useState } from 'react';
2
+ import { useMedia } from 'react-use';
3
+ import { selectPeerNameByID, useHMSStore } from '@100mslive/react-sdk';
4
+ import { ChevronDownIcon, ChevronUpIcon, CrossIcon, PeopleIcon, PersonIcon } from '@100mslive/react-icons';
5
+ import { Dropdown } from '../../../Dropdown';
6
+ import { Box, Flex } from '../../../Layout';
7
+ import { Sheet } from '../../../Sheet';
8
+ import { Text } from '../../../Text';
9
+ import { config as cssConfig } from '../../../Theme';
10
+ import { ChatSelector } from './ChatSelector';
11
+ import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
12
+ // @ts-ignore
13
+ import { useSubscribeChatSelector } from '../AppData/useUISettings';
14
+ import { useFilteredRoles } from '../../common/hooks';
15
+ import { CHAT_SELECTOR } from '../../common/constants';
16
+
17
+ export const ChatSelectorContainer = () => {
18
+ const [open, setOpen] = useState(false);
19
+ const isMobile = useMedia(cssConfig.media.md);
20
+ const { elements } = useRoomLayoutConferencingScreen();
21
+ const isPrivateChatEnabled = !!elements?.chat?.private_chat_enabled;
22
+ const isPublicChatEnabled = !!elements?.chat?.public_chat_enabled;
23
+ const roles = useFilteredRoles();
24
+ const selectedPeer = useSubscribeChatSelector(CHAT_SELECTOR.PEER_ID);
25
+ const selectedRole = useSubscribeChatSelector(CHAT_SELECTOR.ROLE);
26
+ const selectorPeerName = useHMSStore(selectPeerNameByID(selectedPeer));
27
+ const selection = selectorPeerName || selectedRole || CHAT_SELECTOR.EVERYONE;
28
+
29
+ if (!(isPrivateChatEnabled || isPublicChatEnabled || roles.length > 0) && !isPrivateChatEnabled && !selection) {
30
+ return null;
31
+ }
32
+ return (
33
+ <>
34
+ <Flex align="center" css={{ mb: '$8', flex: '1 1 0', pl: '$2' }}>
35
+ <Text variant="xs" css={{ color: '$on_surface_medium' }}>
36
+ {selection ? 'To' : 'Choose Participant'}
37
+ </Text>
38
+
39
+ {isMobile ? (
40
+ <Flex
41
+ align="center"
42
+ css={{ c: '$on_surface_medium', border: '1px solid $border_bright', r: '$0', p: '$1 $2', ml: '$6' }}
43
+ gap="1"
44
+ onClick={e => {
45
+ setOpen(value => !value);
46
+ e.stopPropagation();
47
+ }}
48
+ >
49
+ <Text
50
+ variant="xs"
51
+ css={{
52
+ c: '$on_surface_high',
53
+ pr: '$2',
54
+ display: 'flex',
55
+ alignItems: 'center',
56
+ gap: '$1',
57
+ textTransform: 'capitalize',
58
+ }}
59
+ >
60
+ {selection === CHAT_SELECTOR.EVERYONE ? (
61
+ <PeopleIcon width={16} height={16} />
62
+ ) : (
63
+ <PersonIcon width={16} height={16} />
64
+ )}
65
+ {selection || 'Search'}
66
+ </Text>
67
+ {selection &&
68
+ (open ? <ChevronUpIcon width={16} height={16} /> : <ChevronDownIcon width={16} height={16} />)}
69
+ </Flex>
70
+ ) : (
71
+ <Dropdown.Root open={open} onOpenChange={value => setOpen(value)}>
72
+ <Dropdown.Trigger
73
+ asChild
74
+ data-testid="participant_list_filter"
75
+ css={{
76
+ border: '1px solid $border_bright',
77
+ r: '$0',
78
+ p: '$1 $2',
79
+ ml: '$6',
80
+ }}
81
+ tabIndex={0}
82
+ >
83
+ <Flex align="center" css={{ c: '$on_surface_medium' }} gap="1">
84
+ <Text
85
+ variant="xs"
86
+ css={{
87
+ c: '$on_surface_high',
88
+ pr: '$2',
89
+ display: 'flex',
90
+ alignItems: 'center',
91
+ gap: '$1',
92
+ textTransform: 'capitalize',
93
+ }}
94
+ >
95
+ {selection === CHAT_SELECTOR.EVERYONE ? (
96
+ <PeopleIcon width={16} height={16} />
97
+ ) : (
98
+ <PersonIcon width={16} height={16} />
99
+ )}
100
+ {selection}
101
+ </Text>
102
+ {selection && (
103
+ <ChevronDownIcon
104
+ style={{ transform: open ? 'rotate(180deg)' : 'rotate(0deg)', transition: 'transform 150ms ease' }}
105
+ width={12}
106
+ height={12}
107
+ />
108
+ )}
109
+ </Flex>
110
+ </Dropdown.Trigger>
111
+
112
+ <Dropdown.Content
113
+ css={{
114
+ w: '$64',
115
+ overflow: 'hidden',
116
+ maxHeight: 'unset',
117
+ bg: '$surface_default',
118
+ }}
119
+ align="start"
120
+ sideOffset={8}
121
+ >
122
+ <ChatSelector role={selectedRole} peerId={selectedPeer} />
123
+ </Dropdown.Content>
124
+ </Dropdown.Root>
125
+ )}
126
+ </Flex>
127
+ {isMobile ? (
128
+ <Sheet.Root open={open} onOpenChange={value => setOpen(value)}>
129
+ <Sheet.Content css={{ pt: '$8' }}>
130
+ <Sheet.Title
131
+ css={{
132
+ display: 'flex',
133
+ w: '100%',
134
+ justifyContent: 'space-between',
135
+ px: '$10',
136
+ pb: '$4',
137
+ mb: '$8',
138
+ borderBottom: '1px solid $border_bright',
139
+ }}
140
+ >
141
+ <Text css={{ color: '$on_surface_medium', fontWeight: '$semiBold' }}>Chat with</Text>
142
+ <Sheet.Close css={{ color: '$on_surface_medium' }}>
143
+ <CrossIcon />
144
+ </Sheet.Close>
145
+ </Sheet.Title>
146
+ <Box
147
+ onClick={() => {
148
+ setOpen(false);
149
+ }}
150
+ >
151
+ <ChatSelector role={selectedRole} peerId={selectedPeer} />
152
+ </Box>
153
+ </Sheet.Content>
154
+ </Sheet.Root>
155
+ ) : null}
156
+ </>
157
+ );
158
+ };
@@ -9,8 +9,8 @@ import { SESSION_STORE_KEY } from '../../common/constants';
9
9
  export const ChatPaused = () => {
10
10
  const hmsActions = useHMSActions();
11
11
  const { elements } = useRoomLayoutConferencingScreen();
12
- const { can_disable_chat } = elements?.chat.real_time_controls || false;
13
- const { enabled: isChatEnabled = true, updatedBy: chatStateUpdatedBy } =
12
+ const can_disable_chat = !!elements?.chat?.real_time_controls?.can_disable_chat;
13
+ const { enabled: isChatEnabled = true, updatedBy: chatStateUpdatedBy = '' } =
14
14
  useHMSStore(selectSessionStore(SESSION_STORE_KEY.CHAT_STATE)) || {};
15
15
 
16
16
  const localPeer = useHMSStore(selectLocalPeer);
@@ -19,7 +19,7 @@ export const ChatPaused = () => {
19
19
  async () =>
20
20
  await hmsActions.sessionStore.set(SESSION_STORE_KEY.CHAT_STATE, {
21
21
  enabled: true,
22
- updatedBy: { userName: localPeer.name, userId: localPeer?.customerUserId, peerId: localPeer.id },
22
+ updatedBy: { userName: localPeer?.name, userId: localPeer?.customerUserId, peerId: localPeer?.id },
23
23
  updatedAt: Date.now(),
24
24
  }),
25
25
  [hmsActions, localPeer],
@@ -39,7 +39,7 @@ export const ChatPaused = () => {
39
39
  variant="xs"
40
40
  css={{ color: '$on_surface_medium', maxWidth: '100%', overflow: 'hidden', textOverflow: 'ellipsis' }}
41
41
  >
42
- Chat has been paused by {chatStateUpdatedBy?.peerId === localPeer.id ? 'you' : chatStateUpdatedBy?.userName}
42
+ Chat has been paused by {chatStateUpdatedBy?.peerId === localPeer?.id ? 'you' : chatStateUpdatedBy?.userName}
43
43
  </Text>
44
44
  </Box>
45
45
  {can_disable_chat ? (
@@ -1,32 +1,32 @@
1
- import React, { useEffect, useRef, useState } from 'react';
1
+ import React, { useEffect, useState } from 'react';
2
2
  import { useSwipeable } from 'react-swipeable';
3
3
  import { useMedia } from 'react-use';
4
4
  import { selectSessionStore, useHMSStore } from '@100mslive/react-sdk';
5
- import { CrossIcon, PinIcon } from '@100mslive/react-icons';
5
+ import { PinIcon, UnpinIcon } from '@100mslive/react-icons';
6
6
  import { Box, Flex } from '../../../Layout';
7
7
  import { Text } from '../../../Text';
8
8
  import { config as cssConfig } from '../../../Theme';
9
+ import { ArrowNavigation } from './ArrowNavigation';
9
10
  // @ts-ignore
10
11
  import { AnnotisedMessage } from './ChatBody';
11
- // @ts-ignore
12
- import { Navigation } from './Navigation';
13
- // @ts-ignore
12
+ import { StickIndicator } from './StickIndicator';
13
+ import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
14
14
  import { SESSION_STORE_KEY } from '../../common/constants';
15
15
 
16
16
  const PINNED_MESSAGE_LENGTH = 75;
17
17
 
18
18
  export const PinnedMessage = ({ clearPinnedMessage }: { clearPinnedMessage: (index: number) => void }) => {
19
- const pinnedMessages = useHMSStore(selectSessionStore(SESSION_STORE_KEY.PINNED_MESSAGES)) || [];
19
+ const pinnedMessages = useHMSStore(selectSessionStore(SESSION_STORE_KEY.PINNED_MESSAGES));
20
20
  const [pinnedMessageIndex, setPinnedMessageIndex] = useState(0);
21
21
  const isMobile = useMedia(cssConfig.media.md);
22
22
 
23
- const [hideOverflow, setHideOverflow] = useState(false);
24
- const canOverflow = pinnedMessages?.[pinnedMessageIndex]?.text?.length > PINNED_MESSAGE_LENGTH || false;
25
- const formattedPinnedMessage = hideOverflow
26
- ? `${pinnedMessages?.[pinnedMessageIndex]?.text.slice(0, PINNED_MESSAGE_LENGTH)}... `
27
- : pinnedMessages?.[pinnedMessageIndex]?.text;
23
+ const { elements } = useRoomLayoutConferencingScreen();
24
+ const canUnpinMessage = !!elements?.chat?.allow_pinning_messages;
25
+
26
+ const [hideOverflow, setHideOverflow] = useState(true);
27
+ const currentPinnedMessage = pinnedMessages?.[pinnedMessageIndex]?.text || '';
28
+ const canOverflow = currentPinnedMessage.length > PINNED_MESSAGE_LENGTH;
28
29
 
29
- const pinnedMessageRef = useRef(null);
30
30
  const showPreviousPinnedMessage = () => {
31
31
  const previousIndex = Math.max(pinnedMessageIndex - 1, 0);
32
32
  setHideOverflow(pinnedMessages[previousIndex].text.length > PINNED_MESSAGE_LENGTH);
@@ -44,19 +44,30 @@ export const PinnedMessage = ({ clearPinnedMessage }: { clearPinnedMessage: (ind
44
44
  onSwipedDown: () => showPreviousPinnedMessage(),
45
45
  });
46
46
 
47
+ // Scenario: User is on a particular index but an earlier message is removed by another peer
47
48
  useEffect(() => {
48
- setHideOverflow(
49
- !!(
50
- pinnedMessages?.[pinnedMessageIndex]?.text?.length &&
51
- pinnedMessages?.[pinnedMessageIndex]?.text.length > PINNED_MESSAGE_LENGTH
52
- ),
53
- );
49
+ const count = pinnedMessages?.length || 1;
50
+ if (pinnedMessageIndex >= count) {
51
+ setPinnedMessageIndex(count - 1);
52
+ }
54
53
  }, [pinnedMessageIndex, pinnedMessages]);
55
54
 
56
- return pinnedMessages?.[pinnedMessageIndex]?.text ? (
57
- <Flex ref={pinnedMessageRef} align="center" css={{ w: '100%', gap: '$4' }}>
55
+ if (!pinnedMessages || pinnedMessages.length === 0) {
56
+ return null;
57
+ }
58
+
59
+ return (
60
+ <Flex align="center" css={{ w: '100%', gap: '$4' }}>
61
+ {!isMobile ? (
62
+ <ArrowNavigation
63
+ index={pinnedMessageIndex}
64
+ total={pinnedMessages.length}
65
+ showPrevious={showPreviousPinnedMessage}
66
+ showNext={showNextPinnedMessage}
67
+ />
68
+ ) : null}
58
69
  <Flex
59
- title={pinnedMessages[pinnedMessageIndex].text}
70
+ title={pinnedMessages[pinnedMessageIndex]?.text}
60
71
  css={{
61
72
  p: '$4',
62
73
  color: '$on_surface_medium',
@@ -70,14 +81,7 @@ export const PinnedMessage = ({ clearPinnedMessage }: { clearPinnedMessage: (ind
70
81
  align="center"
71
82
  justify="between"
72
83
  >
73
- <Navigation
74
- index={pinnedMessageIndex}
75
- total={pinnedMessages.length}
76
- showPrevious={showPreviousPinnedMessage}
77
- showNext={showNextPinnedMessage}
78
- isMobile={isMobile}
79
- />
80
- <PinIcon />
84
+ {isMobile ? <StickIndicator index={pinnedMessageIndex} total={pinnedMessages.length} /> : null}
81
85
 
82
86
  <Box
83
87
  css={{
@@ -92,25 +96,39 @@ export const PinnedMessage = ({ clearPinnedMessage }: { clearPinnedMessage: (ind
92
96
  }}
93
97
  >
94
98
  <Text variant="sm" css={{ color: '$on_surface_medium' }} {...swipeHandlers}>
95
- <AnnotisedMessage message={formattedPinnedMessage} />
99
+ <AnnotisedMessage
100
+ message={`${currentPinnedMessage.slice(
101
+ 0,
102
+ hideOverflow ? PINNED_MESSAGE_LENGTH : currentPinnedMessage.length,
103
+ )}`}
104
+ />
96
105
  {canOverflow ? (
97
106
  <span style={{ cursor: 'pointer' }} onClick={() => setHideOverflow(prev => !prev)}>
98
- &nbsp;{hideOverflow ? 'See more' : 'Collapse'}
107
+ &nbsp;{hideOverflow ? '... See more' : 'Collapse'}
99
108
  </span>
100
109
  ) : null}
101
110
  </Text>
102
111
  </Box>
103
112
 
104
- <Flex
105
- onClick={() => {
106
- clearPinnedMessage(pinnedMessageIndex);
107
- setPinnedMessageIndex(Math.max(0, pinnedMessageIndex - 1));
108
- }}
109
- css={{ cursor: 'pointer', color: '$on_surface_medium', '&:hover': { color: '$on_surface_high' } }}
110
- >
111
- <CrossIcon />
112
- </Flex>
113
+ {canUnpinMessage ? (
114
+ <Flex
115
+ onClick={() => {
116
+ clearPinnedMessage(pinnedMessageIndex);
117
+ setPinnedMessageIndex(Math.max(0, pinnedMessageIndex - 1));
118
+ }}
119
+ css={{
120
+ cursor: 'pointer',
121
+ color: '$on_surface_medium',
122
+ '&:hover': { color: '$on_surface_high' },
123
+ '&:hover .hide-on-hover': { display: 'none !important' },
124
+ '&:hover .show-on-hover': { display: 'block !important' },
125
+ }}
126
+ >
127
+ <UnpinIcon className="show-on-hover" style={{ display: 'none' }} height={20} width={20} />
128
+ <PinIcon className="hide-on-hover" style={{ display: 'block' }} height={20} width={20} />
129
+ </Flex>
130
+ ) : null}
113
131
  </Flex>
114
132
  </Flex>
115
- ) : null;
133
+ );
116
134
  };
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { Box, Flex } from '../../../Layout';
3
+
4
+ export const StickIndicator = ({ total, index }: { total: number; index: number }) => {
5
+ const sticksCount = Math.min(3, total);
6
+
7
+ if (total < 2) {
8
+ return null;
9
+ }
10
+
11
+ return (
12
+ <Flex direction="column" css={{ gap: '$1' }}>
13
+ {[...Array(sticksCount)].map((_, i) => (
14
+ <Box
15
+ css={{
16
+ borderLeft: '2px solid',
17
+ height: '$4',
18
+ borderColor: i === index ? '$on_surface_high' : '$on_surface_low',
19
+ }}
20
+ />
21
+ ))}
22
+ </Flex>
23
+ );
24
+ };
@@ -0,0 +1,19 @@
1
+ import {
2
+ selectMessagesUnreadCountByPeerID,
3
+ selectMessagesUnreadCountByRole,
4
+ selectUnreadHMSMessagesCount,
5
+ useHMSStore,
6
+ } from '@100mslive/react-sdk';
7
+
8
+ export const useUnreadCount = ({ role, peerId }: { role?: string; peerId?: string }) => {
9
+ let unreadCountSelector;
10
+ if (role) {
11
+ unreadCountSelector = selectMessagesUnreadCountByRole(role);
12
+ } else if (peerId) {
13
+ unreadCountSelector = selectMessagesUnreadCountByPeerID(peerId);
14
+ } else {
15
+ unreadCountSelector = selectUnreadHMSMessagesCount;
16
+ }
17
+
18
+ return useHMSStore(unreadCountSelector);
19
+ };
@@ -0,0 +1,68 @@
1
+ import React from 'react';
2
+ import { selectLocalPeer, selectSessionStore, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
3
+ import { PauseCircleIcon, SettingsIcon } from '@100mslive/react-icons';
4
+ import { Flex } from '../../Layout';
5
+ import { Popover } from '../../Popover';
6
+ import { Text } from '../../Text';
7
+ import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
8
+ import { SESSION_STORE_KEY } from '../common/constants';
9
+
10
+ export const ChatSettings = () => {
11
+ const hmsActions = useHMSActions();
12
+ const localPeer = useHMSStore(selectLocalPeer);
13
+ const { elements } = useRoomLayoutConferencingScreen();
14
+ const canPauseChat = !!elements?.chat?.real_time_controls?.can_disable_chat;
15
+ const { enabled: isChatEnabled = true } = useHMSStore(selectSessionStore(SESSION_STORE_KEY.CHAT_STATE)) || {};
16
+ const showPause = canPauseChat && isChatEnabled;
17
+
18
+ if (!showPause) {
19
+ return null;
20
+ }
21
+
22
+ return (
23
+ <Popover.Root>
24
+ <Popover.Trigger asChild css={{ px: '$4' }}>
25
+ <Flex
26
+ align="center"
27
+ css={{ color: '$on_surface_medium', '&:hover': { color: '$on_surface_high' }, cursor: 'pointer' }}
28
+ >
29
+ <SettingsIcon />
30
+ </Flex>
31
+ </Popover.Trigger>
32
+ <Popover.Portal>
33
+ <Popover.Content
34
+ align="end"
35
+ side="bottom"
36
+ sideOffset={2}
37
+ onClick={() => {
38
+ const chatState = {
39
+ enabled: false,
40
+ updatedBy: {
41
+ peerId: localPeer?.id,
42
+ userId: localPeer?.customerUserId,
43
+ userName: localPeer?.name,
44
+ },
45
+ updatedAt: Date.now(),
46
+ };
47
+ hmsActions.sessionStore.set(SESSION_STORE_KEY.CHAT_STATE, chatState);
48
+ }}
49
+ css={{
50
+ backgroundColor: '$surface_default',
51
+ display: 'flex',
52
+ alignItems: 'center',
53
+ gap: '$4',
54
+ borderRadius: '$1',
55
+ color: '$on_surface_high',
56
+ cursor: 'pointer',
57
+ '&:hover': { backgroundColor: '$surface_dim' },
58
+ }}
59
+ >
60
+ <PauseCircleIcon />
61
+ <Text variant="sm" css={{ fontWeight: '$semiBold' }}>
62
+ Pause Chat
63
+ </Text>
64
+ </Popover.Content>
65
+ </Popover.Portal>
66
+ </Popover.Root>
67
+ );
68
+ };
@@ -359,8 +359,9 @@ export const ParticipantSearch = ({ onSearch, placeholder, inSidePane = false })
359
359
  color: '$on_surface_medium',
360
360
  mt: inSidePane ? '$4' : '',
361
361
  }}
362
+ onClick={e => e.stopPropagation()}
362
363
  >
363
- <SearchIcon style={{ position: 'absolute', left: isMobile ? '1.25rem' : '0.5rem' }} />
364
+ <SearchIcon style={{ position: 'absolute', left: '0.5rem' }} />
364
365
  <Input
365
366
  type="text"
366
367
  placeholder={placeholder || 'Search for participants'}
@@ -1,6 +1,7 @@
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 { CHAT_SELECTOR } from '../../common/constants';
4
5
 
5
6
  export const ParticipantFilter = ({ selection, onSelection, isConnected, roles }) => {
6
7
  const [open, setOpen] = useState(false);
@@ -26,7 +27,7 @@ export const ParticipantFilter = ({ selection, onSelection, isConnected, roles }
26
27
  >
27
28
  <Flex align="center">
28
29
  <Text variant="sm" css={{ ...textEllipsis(80) }}>
29
- {selectionValue || 'Everyone'}
30
+ {selectionValue || CHAT_SELECTOR.EVERYONE}
30
31
  </Text>
31
32
  <Box css={{ ml: '$2', color: '$on_surface_low' }}>
32
33
  {open ? <ChevronUpIcon width={14} height={14} /> : <ChevronDownIcon width={14} height={14} />}
@@ -29,6 +29,6 @@ export const ChatNotifications = () => {
29
29
  title: `Chat ${chatState.enabled ? 'resumed' : 'paused'} by ${chatState.updatedBy?.userName}`,
30
30
  };
31
31
  ToastManager.addToast(notification);
32
- }, [chatState]);
32
+ }, [chatState, localPeerId]);
33
33
  return <></>;
34
34
  };
@@ -10,6 +10,7 @@ import { PreviewSettings } from './PreviewJoin';
10
10
 
11
11
  const PreviewForm = ({
12
12
  name,
13
+ disabled,
13
14
  onChange,
14
15
  onJoin,
15
16
  enableJoin,
@@ -17,6 +18,7 @@ const PreviewForm = ({
17
18
  cannotPublishAudio = false,
18
19
  }: {
19
20
  name: string;
21
+ disabled?: boolean;
20
22
  onChange: (name: string) => void;
21
23
  onJoin: () => void;
22
24
  enableJoin: boolean;
@@ -48,6 +50,7 @@ const PreviewForm = ({
48
50
  <Input
49
51
  required
50
52
  id="name"
53
+ disabled={disabled}
51
54
  css={{ w: '100%', boxSizing: 'border-box' }}
52
55
  value={name}
53
56
  onChange={e => onChange(e.target.value.trimStart())}
@@ -178,6 +178,7 @@ const PreviewJoin = ({
178
178
  <PreviewControls hideSettings={!toggleVideo && !toggleAudio} vbEnabled={!!virtual_background} />
179
179
  <PreviewForm
180
180
  name={name}
181
+ disabled={!!initialName}
181
182
  onChange={setName}
182
183
  enableJoin={enableJoin}
183
184
  onJoin={savePreferenceAndJoin}
@@ -187,7 +188,7 @@ const PreviewJoin = ({
187
188
  </Box>
188
189
  </Container>
189
190
  <Box css={{ position: 'absolute', right: '0', top: 0, height: '100%', overflow: 'hidden' }}>
190
- <SidePane screenType="default" />
191
+ <SidePane />
191
192
  </Box>
192
193
  </Flex>
193
194
  ) : (