@100mslive/roomkit-react 0.1.14-alpha.1 → 0.1.14
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/{HLSView-JTO7E2KW.js → HLSView-662T7R7H.js} +2 -2
- package/dist/Prebuilt/common/constants.d.ts +1 -0
- package/dist/Prebuilt/common/hooks.d.ts +24 -0
- package/dist/Prebuilt/components/Chat/{Navigation.d.ts → ArrowNavigation.d.ts} +1 -2
- package/dist/Prebuilt/components/Chat/ChatFooter.d.ts +2 -4
- package/dist/Prebuilt/components/Chat/ChatSelector.d.ts +5 -0
- package/dist/Prebuilt/components/Chat/ChatSelectorContainer.d.ts +2 -0
- package/dist/Prebuilt/components/Chat/ChatStates.d.ts +3 -0
- package/dist/Prebuilt/components/Chat/StickIndicator.d.ts +5 -0
- package/dist/Prebuilt/components/Chat/useUnreadCount.d.ts +4 -0
- package/dist/Prebuilt/components/ChatSettings.d.ts +2 -0
- package/dist/Prebuilt/components/Preview/PreviewForm.d.ts +2 -1
- package/dist/Prebuilt/components/SidePaneTabs.d.ts +0 -2
- package/dist/Prebuilt/components/TileMenu/TileMenuContent.d.ts +19 -0
- package/dist/Prebuilt/components/VirtualBackground/VBOption.d.ts +2 -1
- package/dist/Prebuilt/components/hooks/useChatBlacklist.d.ts +2 -1
- package/dist/Prebuilt/components/hooks/useSetPinnedMessages.d.ts +1 -1
- package/dist/Prebuilt/layouts/SidePane.d.ts +1 -3
- package/dist/{chunk-TOKLXTAS.js → chunk-2B7YYNHQ.js} +1651 -1229
- package/dist/chunk-2B7YYNHQ.js.map +7 -0
- package/dist/index.cjs.js +2074 -1609
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +1 -1
- package/dist/meta.cjs.json +451 -115
- package/dist/meta.esbuild.json +457 -121
- package/package.json +6 -6
- package/src/Prebuilt/common/constants.ts +1 -0
- package/src/Prebuilt/common/{hooks.js → hooks.ts} +4 -5
- package/src/Prebuilt/components/AppData/AppData.tsx +1 -0
- package/src/Prebuilt/components/AppData/useUISettings.js +2 -1
- package/src/Prebuilt/components/AuthToken.jsx +16 -8
- package/src/Prebuilt/components/Chat/{Navigation.tsx → ArrowNavigation.tsx} +3 -19
- package/src/Prebuilt/components/Chat/Chat.jsx +15 -44
- package/src/Prebuilt/components/Chat/ChatBody.jsx +114 -69
- package/src/Prebuilt/components/Chat/ChatFooter.tsx +128 -130
- package/src/Prebuilt/components/Chat/ChatSelector.tsx +225 -0
- package/src/Prebuilt/components/Chat/ChatSelectorContainer.tsx +158 -0
- package/src/Prebuilt/components/Chat/{ChatStates.jsx → ChatStates.tsx} +4 -4
- package/src/Prebuilt/components/Chat/PinnedMessage.tsx +59 -41
- package/src/Prebuilt/components/Chat/StickIndicator.tsx +24 -0
- package/src/Prebuilt/components/Chat/useUnreadCount.ts +19 -0
- package/src/Prebuilt/components/ChatSettings.tsx +68 -0
- package/src/Prebuilt/components/Footer/ParticipantList.jsx +2 -1
- package/src/Prebuilt/components/Header/ParticipantFilter.jsx +2 -1
- package/src/Prebuilt/components/Notifications/ChatNotifications.tsx +1 -1
- package/src/Prebuilt/components/Preview/PreviewForm.tsx +3 -0
- package/src/Prebuilt/components/Preview/PreviewJoin.tsx +2 -1
- package/src/Prebuilt/components/SidePaneTabs.tsx +48 -50
- package/src/Prebuilt/components/TileMenu/{TileMenuContent.jsx → TileMenuContent.tsx} +72 -41
- package/src/Prebuilt/components/VirtualBackground/VBCollection.tsx +2 -1
- package/src/Prebuilt/components/VirtualBackground/VBOption.tsx +3 -0
- package/src/Prebuilt/components/VirtualBackground/VBToggle.jsx +1 -1
- package/src/Prebuilt/components/hooks/useChatBlacklist.ts +8 -6
- package/src/Prebuilt/components/hooks/useSetPinnedMessages.ts +2 -7
- package/src/Prebuilt/layouts/SidePane.tsx +1 -5
- package/src/Prebuilt/provider/roomLayoutProvider/constants/index.ts +1 -0
- package/dist/chunk-TOKLXTAS.js.map +0 -7
- package/src/Prebuilt/components/Chat/ChatSelector.jsx +0 -161
- package/src/Prebuilt/components/Chat/ChatSelectorContainer.jsx +0 -81
- package/src/Prebuilt/components/Chat/useUnreadCount.js +0 -17
- /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
|
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
|
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
|
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,
|
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 {
|
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
|
-
|
12
|
-
import {
|
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
|
24
|
-
const
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
),
|
53
|
-
);
|
49
|
+
const count = pinnedMessages?.length || 1;
|
50
|
+
if (pinnedMessageIndex >= count) {
|
51
|
+
setPinnedMessageIndex(count - 1);
|
52
|
+
}
|
54
53
|
}, [pinnedMessageIndex, pinnedMessages]);
|
55
54
|
|
56
|
-
|
57
|
-
|
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]
|
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
|
-
<
|
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
|
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
|
-
{hideOverflow ? 'See more' : 'Collapse'}
|
107
|
+
{hideOverflow ? '... See more' : 'Collapse'}
|
99
108
|
</span>
|
100
109
|
) : null}
|
101
110
|
</Text>
|
102
111
|
</Box>
|
103
112
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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
|
-
)
|
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:
|
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 ||
|
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} />}
|
@@ -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
|
191
|
+
<SidePane />
|
191
192
|
</Box>
|
192
193
|
</Flex>
|
193
194
|
) : (
|