@100mslive/roomkit-react 0.1.14-alpha.0 → 0.1.14-alpha.2
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/{HLSView-HCZVI2RM.js → HLSView-3RARRZJO.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-DKWT744J.js → chunk-W76VLHN6.js} +1690 -1268
- package/dist/chunk-W76VLHN6.js.map +7 -0
- package/dist/index.cjs.js +2104 -1639
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +1 -1
- package/dist/meta.cjs.json +452 -116
- package/dist/meta.esbuild.json +458 -122
- 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-DKWT744J.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-HCZVI2RM.js.map → HLSView-3RARRZJO.js.map} +0 -0
package/package.json
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
"prebuilt",
|
11
11
|
"roomkit"
|
12
12
|
],
|
13
|
-
"version": "0.1.14-alpha.
|
13
|
+
"version": "0.1.14-alpha.2",
|
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.23-alpha.
|
80
|
-
"@100mslive/hms-virtual-background": "1.11.23-alpha.
|
81
|
-
"@100mslive/react-icons": "0.8.23-alpha.
|
82
|
-
"@100mslive/react-sdk": "0.8.23-alpha.
|
79
|
+
"@100mslive/hls-player": "0.1.23-alpha.2",
|
80
|
+
"@100mslive/hms-virtual-background": "1.11.23-alpha.2",
|
81
|
+
"@100mslive/react-icons": "0.8.23-alpha.2",
|
82
|
+
"@100mslive/react-sdk": "0.8.23-alpha.2",
|
83
83
|
"@100mslive/types-prebuilt": "0.12.4",
|
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": "
|
118
|
+
"gitHead": "1b964f1d356fe098de341574a63a6c3b5332e418"
|
119
119
|
}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
// @ts-check
|
2
1
|
import { useEffect, useRef, useState } from 'react';
|
3
2
|
import { JoinForm_JoinBtnType } from '@100mslive/types-prebuilt/elements/join_form';
|
4
3
|
import {
|
@@ -12,7 +11,7 @@ import {
|
|
12
11
|
useHMSVanillaStore,
|
13
12
|
} from '@100mslive/react-sdk';
|
14
13
|
import { useRoomLayout } from '../provider/roomLayoutProvider';
|
15
|
-
|
14
|
+
import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
16
15
|
/**
|
17
16
|
* Hook to execute a callback when alone in room(after a certain 5d of time)
|
18
17
|
* @param {number} thresholdMs The threshold(in ms) after which the callback is executed,
|
@@ -52,8 +51,8 @@ export const useWhenAloneInRoom = (thresholdMs = 5 * 60 * 1000) => {
|
|
52
51
|
};
|
53
52
|
|
54
53
|
export const useFilteredRoles = () => {
|
55
|
-
const
|
56
|
-
return
|
54
|
+
const { elements } = useRoomLayoutConferencingScreen();
|
55
|
+
return elements?.chat?.roles_whitelist || [];
|
57
56
|
};
|
58
57
|
|
59
58
|
export const useShowStreamingUI = () => {
|
@@ -63,7 +62,7 @@ export const useShowStreamingUI = () => {
|
|
63
62
|
};
|
64
63
|
|
65
64
|
// The search results should not have role name matches
|
66
|
-
export const useParticipants = params => {
|
65
|
+
export const useParticipants = (params?: { metadata?: { isHandRaised?: boolean }; role?: string; search?: string }) => {
|
67
66
|
const isConnected = useHMSStore(selectIsConnectedToRoom);
|
68
67
|
const peerCount = useHMSStore(selectPeerCount);
|
69
68
|
const availableRoles = useHMSStore(selectAvailableRoleNames);
|
@@ -96,6 +96,7 @@ export const AppData = React.memo(() => {
|
|
96
96
|
const uiSettings = preferences || {};
|
97
97
|
const updatedSettings = {
|
98
98
|
...uiSettings,
|
99
|
+
[UI_SETTINGS.isAudioOnly]: undefined,
|
99
100
|
[UI_SETTINGS.uiViewMode]: uiSettings.uiViewMode || UI_MODE_GRID,
|
100
101
|
};
|
101
102
|
hmsActions.setAppData(APP_DATA.uiSettings, updatedSettings, true);
|
@@ -13,7 +13,7 @@ import {
|
|
13
13
|
useHMSVanillaStore,
|
14
14
|
} from '@100mslive/react-sdk';
|
15
15
|
import { UserPreferencesKeys, useUserPreferences } from '../hooks/useUserPreferences';
|
16
|
-
import { APP_DATA, POLL_STATE, SESSION_STORE_KEY } from '../../common/constants';
|
16
|
+
import { APP_DATA, POLL_STATE, SESSION_STORE_KEY, UI_SETTINGS } from '../../common/constants';
|
17
17
|
|
18
18
|
/**
|
19
19
|
* fields saved related to UI settings in store's app data can be
|
@@ -154,6 +154,7 @@ const useSetAppData = ({ key1, key2 }) => {
|
|
154
154
|
const appData = store.getState(selectAppData());
|
155
155
|
setPreferences({
|
156
156
|
...appData.uiSettings,
|
157
|
+
[UI_SETTINGS.isAudioOnly]: undefined,
|
157
158
|
subscribedNotifications: appData.subscribedNotifications,
|
158
159
|
});
|
159
160
|
},
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
2
2
|
import { useSessionStorage } from 'react-use';
|
3
|
-
import { v4 } from 'uuid';
|
3
|
+
import { v4 as uuid } from 'uuid';
|
4
4
|
import { useHMSActions } from '@100mslive/react-sdk';
|
5
5
|
import { styled } from '../../Theme';
|
6
6
|
import { useHMSPrebuiltContext } from '../AppContext';
|
@@ -26,12 +26,6 @@ const AuthToken = React.memo(({ authTokenByRoomCodeEndpoint, defaultAuthToken })
|
|
26
26
|
const [, setAuthTokenInAppData] = useSetAppDataByKey(APP_DATA.authToken);
|
27
27
|
const [savedUserId, setSavedUserId] = useSessionStorage(UserPreferencesKeys.USER_ID);
|
28
28
|
|
29
|
-
useEffect(() => {
|
30
|
-
if (!savedUserId && !userId) {
|
31
|
-
setSavedUserId(v4());
|
32
|
-
}
|
33
|
-
}, [savedUserId, setSavedUserId, userId]);
|
34
|
-
|
35
29
|
useEffect(() => {
|
36
30
|
if (authToken) {
|
37
31
|
setAuthTokenInAppData(authToken);
|
@@ -42,11 +36,25 @@ const AuthToken = React.memo(({ authTokenByRoomCodeEndpoint, defaultAuthToken })
|
|
42
36
|
return;
|
43
37
|
}
|
44
38
|
|
39
|
+
if (!savedUserId && !userId) {
|
40
|
+
setSavedUserId(uuid());
|
41
|
+
return;
|
42
|
+
}
|
43
|
+
|
45
44
|
hmsActions
|
46
45
|
.getAuthTokenByRoomCode({ roomCode, userId: userId || savedUserId }, { endpoint: authTokenByRoomCodeEndpoint })
|
47
46
|
.then(token => setAuthTokenInAppData(token))
|
48
47
|
.catch(error => setError(convertError(error)));
|
49
|
-
}, [
|
48
|
+
}, [
|
49
|
+
hmsActions,
|
50
|
+
authToken,
|
51
|
+
authTokenByRoomCodeEndpoint,
|
52
|
+
setAuthTokenInAppData,
|
53
|
+
roomCode,
|
54
|
+
userId,
|
55
|
+
savedUserId,
|
56
|
+
setSavedUserId,
|
57
|
+
]);
|
50
58
|
|
51
59
|
if (error.title) {
|
52
60
|
return <ErrorDialog title={error.title}>{error.body}</ErrorDialog>;
|
@@ -1,40 +1,24 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { ChevronDownIcon, ChevronUpIcon } from '@100mslive/react-icons';
|
3
|
-
import {
|
3
|
+
import { Flex } from '../../../Layout';
|
4
4
|
|
5
|
-
export const
|
5
|
+
export const ArrowNavigation = ({
|
6
6
|
total,
|
7
7
|
index,
|
8
8
|
showPrevious,
|
9
9
|
showNext,
|
10
|
-
isMobile,
|
11
10
|
}: {
|
12
11
|
total: number;
|
13
12
|
index: number;
|
14
13
|
showPrevious: () => void;
|
15
14
|
showNext: () => void;
|
16
|
-
isMobile: boolean;
|
17
15
|
}) => {
|
18
|
-
const sticksCount = Math.min(3, total);
|
19
|
-
|
20
16
|
if (total < 2) {
|
21
17
|
return null;
|
22
18
|
}
|
23
19
|
|
24
|
-
return
|
20
|
+
return (
|
25
21
|
<Flex direction="column" css={{ gap: '$1' }}>
|
26
|
-
{[...Array(sticksCount)].map((_, i) => (
|
27
|
-
<Box
|
28
|
-
css={{
|
29
|
-
borderLeft: '2px solid',
|
30
|
-
height: '$4',
|
31
|
-
borderColor: i === index ? '$on_surface_high' : '$on_surface_low',
|
32
|
-
}}
|
33
|
-
/>
|
34
|
-
))}
|
35
|
-
</Flex>
|
36
|
-
) : (
|
37
|
-
<Flex direction="column" css={{ gap: '$4' }}>
|
38
22
|
<Flex
|
39
23
|
onClick={showPrevious}
|
40
24
|
css={
|
@@ -1,10 +1,9 @@
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
2
2
|
import { useMedia } from 'react-use';
|
3
|
-
import { selectLocalPeer, selectSessionStore } from '@100mslive/hms-video-store';
|
3
|
+
import { selectLocalPeer, selectPeerByID, selectSessionStore } from '@100mslive/hms-video-store';
|
4
4
|
import {
|
5
5
|
HMSNotificationTypes,
|
6
6
|
selectHMSMessagesCount,
|
7
|
-
selectPeerNameByID,
|
8
7
|
useHMSActions,
|
9
8
|
useHMSNotifications,
|
10
9
|
useHMSStore,
|
@@ -23,38 +22,32 @@ import { useSetPinnedMessages } from '../hooks/useSetPinnedMessages';
|
|
23
22
|
import { useUnreadCount } from './useUnreadCount';
|
24
23
|
import { CHAT_SELECTOR, SESSION_STORE_KEY } from '../../common/constants';
|
25
24
|
|
26
|
-
export const Chat = (
|
25
|
+
export const Chat = () => {
|
26
|
+
const { elements, screenType } = useRoomLayoutConferencingScreen();
|
27
27
|
const notification = useHMSNotifications(HMSNotificationTypes.PEER_LEFT);
|
28
|
-
const [
|
29
|
-
const [
|
30
|
-
const peerName = useHMSStore(selectPeerNameByID(peerSelector));
|
28
|
+
const [selectedPeer, setPeerSelector] = useSetSubscribedChatSelector(CHAT_SELECTOR.PEER_ID);
|
29
|
+
const [selectedRole, setRoleSelector] = useSetSubscribedChatSelector(CHAT_SELECTOR.ROLE);
|
31
30
|
const localPeer = useHMSStore(selectLocalPeer);
|
32
|
-
const [chatOptions, setChatOptions] = useState({
|
33
|
-
role: roleSelector || '',
|
34
|
-
peerId: peerSelector && peerName ? peerSelector : '',
|
35
|
-
selection: roleSelector ? roleSelector : peerSelector && peerName ? peerName : 'Everyone',
|
36
|
-
});
|
37
31
|
const [isSelectorOpen] = useState(false);
|
38
32
|
const listRef = useRef(null);
|
39
33
|
const hmsActions = useHMSActions();
|
40
34
|
const { removePinnedMessage } = useSetPinnedMessages();
|
41
35
|
const pinnedMessages = useHMSStore(selectSessionStore(SESSION_STORE_KEY.PINNED_MESSAGES)) || [];
|
36
|
+
const isPeerPresent = !!useHMSStore(selectPeerByID(selectedPeer));
|
42
37
|
|
43
38
|
useEffect(() => {
|
44
|
-
if (notification && notification.data &&
|
39
|
+
if (notification && notification.data && selectedPeer === notification.data.id) {
|
45
40
|
setPeerSelector('');
|
46
|
-
|
47
|
-
role: '',
|
48
|
-
peerId: '',
|
49
|
-
selection: 'Everyone',
|
50
|
-
});
|
41
|
+
setRoleSelector('');
|
51
42
|
}
|
52
|
-
|
43
|
+
if (selectedPeer && !isPeerPresent) {
|
44
|
+
setPeerSelector('');
|
45
|
+
}
|
46
|
+
}, [notification, selectedPeer, setPeerSelector, setRoleSelector, isPeerPresent]);
|
53
47
|
const blacklistedPeerIDs = useHMSStore(selectSessionStore(SESSION_STORE_KEY.CHAT_PEER_BLACKLIST)) || [];
|
54
48
|
const blacklistedPeerIDSet = new Set(blacklistedPeerIDs);
|
55
49
|
const isLocalPeerBlacklisted = blacklistedPeerIDSet.has(localPeer?.customerUserId);
|
56
50
|
const storeMessageSelector = selectHMSMessagesCount;
|
57
|
-
const { elements } = useRoomLayoutConferencingScreen();
|
58
51
|
const { enabled: isChatEnabled = true } = useHMSStore(selectSessionStore(SESSION_STORE_KEY.CHAT_STATE)) || {};
|
59
52
|
const isMobile = useMedia(cssConfig.media.md);
|
60
53
|
|
@@ -92,14 +85,7 @@ export const Chat = ({ screenType }) => {
|
|
92
85
|
</>
|
93
86
|
)}
|
94
87
|
|
95
|
-
<ChatBody
|
96
|
-
role={chatOptions.role}
|
97
|
-
peerId={chatOptions.peerId}
|
98
|
-
ref={listRef}
|
99
|
-
scrollToBottom={scrollToBottom}
|
100
|
-
screenType={screenType}
|
101
|
-
blacklistedPeerIDs={blacklistedPeerIDs}
|
102
|
-
/>
|
88
|
+
<ChatBody ref={listRef} scrollToBottom={scrollToBottom} screenType={screenType} />
|
103
89
|
|
104
90
|
<ChatPaused />
|
105
91
|
|
@@ -110,24 +96,9 @@ export const Chat = ({ screenType }) => {
|
|
110
96
|
) : null}
|
111
97
|
|
112
98
|
{isChatEnabled && !isLocalPeerBlacklisted ? (
|
113
|
-
<ChatFooter
|
114
|
-
role={chatOptions.role}
|
115
|
-
onSend={() => scrollToBottom(1)}
|
116
|
-
selection={chatOptions.selection}
|
117
|
-
screenType={screenType}
|
118
|
-
onSelect={({ role, peerId, selection }) => {
|
119
|
-
setChatOptions({
|
120
|
-
role,
|
121
|
-
peerId,
|
122
|
-
selection,
|
123
|
-
});
|
124
|
-
setPeerSelector(peerId);
|
125
|
-
setRoleSelector(role);
|
126
|
-
}}
|
127
|
-
peerId={chatOptions.peerId}
|
128
|
-
>
|
99
|
+
<ChatFooter onSend={() => scrollToBottom(1)} screenType={screenType}>
|
129
100
|
{!isSelectorOpen && !isScrolledToBottom && (
|
130
|
-
<NewMessageIndicator role={
|
101
|
+
<NewMessageIndicator role={selectedRole} peerId={selectedPeer} scrollToBottom={scrollToBottom} />
|
131
102
|
)}
|
132
103
|
</ChatFooter>
|
133
104
|
) : null}
|
@@ -7,16 +7,22 @@ import {
|
|
7
7
|
selectHMSMessages,
|
8
8
|
selectLocalPeerID,
|
9
9
|
selectLocalPeerName,
|
10
|
-
selectLocalPeerRoleName,
|
11
10
|
selectMessagesByPeerID,
|
12
11
|
selectMessagesByRole,
|
13
|
-
selectPeerNameByID,
|
14
12
|
selectPermissions,
|
15
13
|
selectSessionStore,
|
16
14
|
useHMSActions,
|
17
15
|
useHMSStore,
|
18
16
|
} from '@100mslive/react-sdk';
|
19
|
-
import {
|
17
|
+
import {
|
18
|
+
CopyIcon,
|
19
|
+
CrossCircleIcon,
|
20
|
+
CrossIcon,
|
21
|
+
EyeCloseIcon,
|
22
|
+
PinIcon,
|
23
|
+
ReplyIcon,
|
24
|
+
VerticalMenuIcon,
|
25
|
+
} from '@100mslive/react-icons';
|
20
26
|
import { Dropdown } from '../../../Dropdown';
|
21
27
|
import { IconButton } from '../../../IconButton';
|
22
28
|
import { Box, Flex } from '../../../Layout';
|
@@ -28,10 +34,11 @@ import emptyChat from '../../images/empty-chat.svg';
|
|
28
34
|
import { ToastManager } from '../Toast/ToastManager';
|
29
35
|
import { MwebChatOption } from './MwebChatOption';
|
30
36
|
import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
37
|
+
import { useSetSubscribedChatSelector, useSubscribeChatSelector } from '../AppData/useUISettings';
|
31
38
|
import { useChatBlacklist } from '../hooks/useChatBlacklist';
|
32
39
|
import { useSetPinnedMessages } from '../hooks/useSetPinnedMessages';
|
33
40
|
import { useUnreadCount } from './useUnreadCount';
|
34
|
-
import { SESSION_STORE_KEY } from '../../common/constants';
|
41
|
+
import { CHAT_SELECTOR, SESSION_STORE_KEY } from '../../common/constants';
|
35
42
|
|
36
43
|
const iconStyle = { height: '1.125rem', width: '1.125rem' };
|
37
44
|
const tooltipBoxCSS = {
|
@@ -63,21 +70,28 @@ const MessageTypeContainer = ({ left, right }) => {
|
|
63
70
|
<Flex
|
64
71
|
align="center"
|
65
72
|
css={{
|
66
|
-
|
73
|
+
position: 'absolute',
|
74
|
+
right: 0,
|
75
|
+
zIndex: 1,
|
67
76
|
mr: '$4',
|
68
|
-
p: '$2
|
77
|
+
p: '$2',
|
69
78
|
border: '1px solid $border_bright',
|
70
79
|
r: '$0',
|
80
|
+
gap: '$3',
|
71
81
|
}}
|
82
|
+
className="message_type_container"
|
72
83
|
>
|
73
84
|
{left && (
|
74
|
-
<SenderName variant="
|
85
|
+
<SenderName variant="caption" as="span" css={{ color: '$on_surface_medium' }}>
|
75
86
|
{left}
|
76
87
|
</SenderName>
|
77
88
|
)}
|
78
|
-
{left && right && <Box css={{ borderLeft: '1px solid $border_bright', mx: '$4', h: '$8' }} />}
|
79
89
|
{right && (
|
80
|
-
<SenderName
|
90
|
+
<SenderName
|
91
|
+
as="span"
|
92
|
+
variant="caption"
|
93
|
+
css={{ color: '$on_surface_high', textTransform: 'capitalize', fontWeight: '$semiBold' }}
|
94
|
+
>
|
81
95
|
{right}
|
82
96
|
</SenderName>
|
83
97
|
)}
|
@@ -85,20 +99,13 @@ const MessageTypeContainer = ({ left, right }) => {
|
|
85
99
|
);
|
86
100
|
};
|
87
101
|
|
88
|
-
const MessageType = ({ roles,
|
89
|
-
const peerName = useHMSStore(selectPeerNameByID(receiver));
|
90
|
-
const localPeerRoleName = useHMSStore(selectLocalPeerRoleName);
|
102
|
+
const MessageType = ({ roles, receiver }) => {
|
91
103
|
if (receiver) {
|
92
|
-
return
|
93
|
-
<MessageTypeContainer
|
94
|
-
left={hasCurrentUserSent ? `${peerName ? `TO ${peerName}` : ''}` : 'TO YOU'}
|
95
|
-
right="PRIVATE"
|
96
|
-
/>
|
97
|
-
);
|
104
|
+
return <MessageTypeContainer left="Direct Message" />;
|
98
105
|
}
|
99
106
|
|
100
|
-
if (roles && roles.length) {
|
101
|
-
return <MessageTypeContainer left="
|
107
|
+
if (roles && roles.length > 0) {
|
108
|
+
return <MessageTypeContainer left="To Group" right={roles[0]} />;
|
102
109
|
}
|
103
110
|
return null;
|
104
111
|
};
|
@@ -143,30 +150,37 @@ const getMessageType = ({ roles, receiver }) => {
|
|
143
150
|
}
|
144
151
|
return receiver ? 'private' : '';
|
145
152
|
};
|
146
|
-
const ChatActions = ({
|
153
|
+
const ChatActions = ({
|
154
|
+
onPin,
|
155
|
+
showPinAction,
|
156
|
+
onReplyPrivately,
|
157
|
+
showReplyPrivateAction,
|
158
|
+
message,
|
159
|
+
sentByLocalPeer,
|
160
|
+
isMobile,
|
161
|
+
openSheet,
|
162
|
+
setOpenSheet,
|
163
|
+
}) => {
|
147
164
|
const { elements } = useRoomLayoutConferencingScreen();
|
148
165
|
const { can_hide_message, can_block_user } = elements?.chat?.real_time_controls || {
|
149
166
|
can_hide_message: false,
|
150
167
|
can_block_user: false,
|
151
168
|
};
|
152
169
|
const [open, setOpen] = useState(false);
|
153
|
-
const blacklistedPeerIDs = useHMSStore(selectSessionStore(SESSION_STORE_KEY.CHAT_PEER_BLACKLIST)) || [];
|
154
170
|
const { blacklistItem: blacklistPeer } = useChatBlacklist(SESSION_STORE_KEY.CHAT_PEER_BLACKLIST);
|
155
171
|
|
156
|
-
const blacklistedMessageIDs =
|
157
|
-
|
158
|
-
|
172
|
+
const { blacklistItem: blacklistMessage, blacklistedIDs: blacklistedMessageIDs = [] } = useChatBlacklist(
|
173
|
+
SESSION_STORE_KEY.CHAT_MESSAGE_BLACKLIST,
|
174
|
+
);
|
159
175
|
const { unpinBlacklistedMessages } = useSetPinnedMessages();
|
160
176
|
|
161
|
-
const pinnedMessages = useHMSStore(selectSessionStore(SESSION_STORE_KEY.PINNED_MESSAGES))
|
162
|
-
|
177
|
+
const pinnedMessages = useHMSStore(selectSessionStore(SESSION_STORE_KEY.PINNED_MESSAGES));
|
163
178
|
const updatePinnedMessages = useCallback(
|
164
|
-
(
|
179
|
+
(messageID = '') => {
|
165
180
|
const blacklistedMessageIDSet = new Set([...blacklistedMessageIDs, messageID]);
|
166
|
-
|
167
|
-
unpinBlacklistedMessages(pinnedMessages, blacklistedPeerIDSet, blacklistedMessageIDSet);
|
181
|
+
unpinBlacklistedMessages(pinnedMessages, blacklistedMessageIDSet);
|
168
182
|
},
|
169
|
-
[
|
183
|
+
[blacklistedMessageIDs, unpinBlacklistedMessages, pinnedMessages],
|
170
184
|
);
|
171
185
|
|
172
186
|
const copyMessageContent = useCallback(() => {
|
@@ -184,6 +198,13 @@ const ChatActions = ({ onPin, showPinAction, message, sentByLocalPeer, isMobile,
|
|
184
198
|
}, [message]);
|
185
199
|
|
186
200
|
const options = {
|
201
|
+
reply: {
|
202
|
+
text: 'Reply Privately',
|
203
|
+
tooltipText: 'Reply privately',
|
204
|
+
icon: <ReplyIcon style={iconStyle} />,
|
205
|
+
onClick: onReplyPrivately,
|
206
|
+
show: showReplyPrivateAction,
|
207
|
+
},
|
187
208
|
pin: {
|
188
209
|
text: 'Pin message',
|
189
210
|
tooltipText: 'Pin',
|
@@ -202,18 +223,15 @@ const ChatActions = ({ onPin, showPinAction, message, sentByLocalPeer, isMobile,
|
|
202
223
|
text: 'Hide for everyone',
|
203
224
|
icon: <EyeCloseIcon style={iconStyle} />,
|
204
225
|
onClick: async () => {
|
205
|
-
blacklistMessage(
|
206
|
-
updatePinnedMessages(
|
226
|
+
blacklistMessage(message.id);
|
227
|
+
updatePinnedMessages(message.id);
|
207
228
|
},
|
208
229
|
show: can_hide_message,
|
209
230
|
},
|
210
231
|
block: {
|
211
232
|
text: 'Block from chat',
|
212
233
|
icon: <CrossCircleIcon style={iconStyle} />,
|
213
|
-
onClick: async () =>
|
214
|
-
blacklistPeer(blacklistedPeerIDs, message?.senderUserId);
|
215
|
-
updatePinnedMessages({ peerID: message?.senderUserId });
|
216
|
-
},
|
234
|
+
onClick: async () => blacklistPeer(message?.senderUserId),
|
217
235
|
color: '$alert_error_default',
|
218
236
|
show: can_block_user && !sentByLocalPeer,
|
219
237
|
},
|
@@ -269,9 +287,19 @@ const ChatActions = ({ onPin, showPinAction, message, sentByLocalPeer, isMobile,
|
|
269
287
|
borderRadius: '$1',
|
270
288
|
p: '$2',
|
271
289
|
opacity: open ? 1 : 0,
|
290
|
+
position: 'absolute',
|
291
|
+
right: 0,
|
292
|
+
zIndex: 1,
|
272
293
|
'@md': { opacity: 1 },
|
273
294
|
}}
|
274
295
|
>
|
296
|
+
{options.reply.show ? (
|
297
|
+
<Tooltip boxCss={tooltipBoxCSS} title={options.reply.tooltipText}>
|
298
|
+
<IconButton data-testid="reply_message_btn" onClick={options.reply.onClick}>
|
299
|
+
{options.reply.icon}
|
300
|
+
</IconButton>
|
301
|
+
</Tooltip>
|
302
|
+
) : null}
|
275
303
|
{options.pin.show ? (
|
276
304
|
<Tooltip boxCss={tooltipBoxCSS} title={options.pin.tooltipText}>
|
277
305
|
<IconButton data-testid="pin_message_btn" onClick={options.pin.onClick}>
|
@@ -335,7 +363,7 @@ const SenderName = styled(Text, {
|
|
335
363
|
overflow: 'hidden',
|
336
364
|
textOverflow: 'ellipsis',
|
337
365
|
whiteSpace: 'nowrap',
|
338
|
-
maxWidth: '
|
366
|
+
maxWidth: '16ch',
|
339
367
|
minWidth: 0,
|
340
368
|
color: '$on_surface_high',
|
341
369
|
fontWeight: '$semiBold',
|
@@ -344,6 +372,7 @@ const SenderName = styled(Text, {
|
|
344
372
|
const ChatMessage = React.memo(
|
345
373
|
({ index, style = {}, message, setRowHeight, isLast = false, unreadCount = 0, scrollToBottom, onPin }) => {
|
346
374
|
const { ref, inView } = useInView({ threshold: 0.5, triggerOnce: true });
|
375
|
+
const { elements } = useRoomLayoutConferencingScreen();
|
347
376
|
const rowRef = useRef(null);
|
348
377
|
useEffect(() => {
|
349
378
|
if (rowRef.current) {
|
@@ -351,11 +380,14 @@ const ChatMessage = React.memo(
|
|
351
380
|
}
|
352
381
|
}, [index, setRowHeight]);
|
353
382
|
const isMobile = useMedia(cssConfig.media.md);
|
354
|
-
const
|
383
|
+
const isPrivateChatEnabled = !!elements?.chat?.private_chat_enabled;
|
355
384
|
const isOverlay = elements?.chat?.is_overlay && isMobile;
|
356
385
|
const hmsActions = useHMSActions();
|
357
386
|
const localPeerId = useHMSStore(selectLocalPeerID);
|
358
387
|
const permissions = useHMSStore(selectPermissions);
|
388
|
+
const selectedPeer = useSubscribeChatSelector(CHAT_SELECTOR.PEER_ID);
|
389
|
+
const selectedRole = useSubscribeChatSelector(CHAT_SELECTOR.ROLE);
|
390
|
+
const [, setPeerSelector] = useSetSubscribedChatSelector(CHAT_SELECTOR.PEER_ID);
|
359
391
|
const messageType = getMessageType({
|
360
392
|
roles: message.recipientRoles,
|
361
393
|
receiver: message.recipientPeer,
|
@@ -383,7 +415,8 @@ const ChatMessage = React.memo(
|
|
383
415
|
mb: '$5',
|
384
416
|
pr: '$10',
|
385
417
|
mt: '$4',
|
386
|
-
'&:hover .chat_actions': {
|
418
|
+
'&:not(:hover} .chat_actions': { display: 'none' },
|
419
|
+
'&:hover .chat_actions': { display: 'flex', opacity: 1 },
|
387
420
|
}}
|
388
421
|
style={style}
|
389
422
|
>
|
@@ -392,10 +425,16 @@ const ChatMessage = React.memo(
|
|
392
425
|
align="center"
|
393
426
|
css={{
|
394
427
|
flexWrap: 'wrap',
|
428
|
+
position: 'relative',
|
395
429
|
// Theme independent color, token should not be used for transparent chat
|
396
|
-
bg:
|
430
|
+
bg:
|
431
|
+
messageType && !(selectedPeer || selectedRole)
|
432
|
+
? isOverlay
|
433
|
+
? 'rgba(0, 0, 0, 0.64)'
|
434
|
+
: '$surface_default'
|
435
|
+
: undefined,
|
397
436
|
r: '$1',
|
398
|
-
p: '$
|
437
|
+
p: '$4',
|
399
438
|
userSelect: 'none',
|
400
439
|
'@md': {
|
401
440
|
cursor: 'pointer',
|
@@ -416,21 +455,29 @@ const ChatMessage = React.memo(
|
|
416
455
|
css={{
|
417
456
|
color: isOverlay ? '#FFF' : '$on_surface_high',
|
418
457
|
fontWeight: '$semiBold',
|
419
|
-
display: '
|
458
|
+
display: 'flex',
|
420
459
|
alignItems: 'center',
|
421
|
-
|
460
|
+
alignSelf: 'stretch',
|
422
461
|
width: '100%',
|
423
462
|
}}
|
424
463
|
as="div"
|
425
464
|
>
|
426
465
|
<Flex align="baseline">
|
427
466
|
{message.senderName === 'You' || !message.senderName ? (
|
428
|
-
<SenderName
|
467
|
+
<SenderName
|
468
|
+
as="span"
|
469
|
+
variant="sub2"
|
470
|
+
css={{ color: isOverlay ? '#FFF' : '$on_surface_high', fontWeight: '$semiBold' }}
|
471
|
+
>
|
429
472
|
{message.senderName || 'Anonymous'}
|
430
473
|
</SenderName>
|
431
474
|
) : (
|
432
475
|
<Tooltip title={message.senderName} side="top" align="start">
|
433
|
-
<SenderName
|
476
|
+
<SenderName
|
477
|
+
as="span"
|
478
|
+
variant="sub2"
|
479
|
+
css={{ color: isOverlay ? '#FFF' : '$on_surface_high', fontWeight: '$semiBold' }}
|
480
|
+
>
|
434
481
|
{message.senderName}
|
435
482
|
</SenderName>
|
436
483
|
</Tooltip>
|
@@ -438,9 +485,9 @@ const ChatMessage = React.memo(
|
|
438
485
|
{!isOverlay ? (
|
439
486
|
<Text
|
440
487
|
as="span"
|
441
|
-
variant="
|
488
|
+
variant="caption"
|
442
489
|
css={{
|
443
|
-
ml: '$
|
490
|
+
ml: '$2',
|
444
491
|
color: '$on_surface_medium',
|
445
492
|
flexShrink: 0,
|
446
493
|
}}
|
@@ -449,17 +496,17 @@ const ChatMessage = React.memo(
|
|
449
496
|
</Text>
|
450
497
|
) : null}
|
451
498
|
</Flex>
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
roles={message.recipientRoles}
|
456
|
-
/>
|
499
|
+
{!(selectedPeer || selectedRole) && (
|
500
|
+
<MessageType receiver={message.recipientPeer} roles={message.recipientRoles} />
|
501
|
+
)}
|
457
502
|
|
458
503
|
<ChatActions
|
459
504
|
onPin={onPin}
|
460
505
|
showPinAction={showPinAction}
|
461
506
|
message={message}
|
462
507
|
sentByLocalPeer={message.sender === localPeerId}
|
508
|
+
onReplyPrivately={() => setPeerSelector(message.sender)}
|
509
|
+
showReplyPrivateAction={!selectedPeer && message.sender !== localPeerId && isPrivateChatEnabled}
|
463
510
|
isMobile={isMobile}
|
464
511
|
openSheet={openSheet}
|
465
512
|
setOpenSheet={setOpenSheet}
|
@@ -574,30 +621,28 @@ const VirtualizedChatMessages = React.forwardRef(({ messages, unreadCount = 0, s
|
|
574
621
|
);
|
575
622
|
});
|
576
623
|
|
577
|
-
export const ChatBody = React.forwardRef(({
|
578
|
-
const
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
624
|
+
export const ChatBody = React.forwardRef(({ scrollToBottom }, listRef) => {
|
625
|
+
const selectedPeer = useSubscribeChatSelector(CHAT_SELECTOR.PEER_ID);
|
626
|
+
const selectedRole = useSubscribeChatSelector(CHAT_SELECTOR.ROLE);
|
627
|
+
let storeMessageSelector;
|
628
|
+
if (selectedRole) {
|
629
|
+
storeMessageSelector = selectMessagesByRole(selectedRole);
|
630
|
+
} else if (selectedPeer) {
|
631
|
+
storeMessageSelector = selectMessagesByPeerID(selectedPeer);
|
632
|
+
} else {
|
633
|
+
storeMessageSelector = selectHMSMessages;
|
634
|
+
}
|
583
635
|
let messages = useHMSStore(storeMessageSelector) || [];
|
584
636
|
const blacklistedMessageIDs = useHMSStore(selectSessionStore(SESSION_STORE_KEY.CHAT_MESSAGE_BLACKLIST)) || [];
|
585
637
|
const getFilteredMessages = () => {
|
586
638
|
const blacklistedMessageIDSet = new Set(blacklistedMessageIDs);
|
587
|
-
|
588
|
-
return (
|
589
|
-
messages?.filter(
|
590
|
-
message =>
|
591
|
-
message.type === 'chat' &&
|
592
|
-
!blacklistedMessageIDSet.has(message.id) &&
|
593
|
-
!blacklistedPeerIDSet.has(message?.senderUserId),
|
594
|
-
) || []
|
595
|
-
);
|
639
|
+
|
640
|
+
return messages?.filter(message => message.type === 'chat' && !blacklistedMessageIDSet.has(message.id)) || [];
|
596
641
|
};
|
597
642
|
|
598
643
|
const isMobile = useMedia(cssConfig.media.md);
|
599
644
|
const { elements } = useRoomLayoutConferencingScreen();
|
600
|
-
const unreadCount = useUnreadCount({ role, peerId });
|
645
|
+
const unreadCount = useUnreadCount({ role: selectedRole, peerId: selectedPeer });
|
601
646
|
|
602
647
|
if (messages.length === 0 && !(isMobile && elements?.chat?.is_overlay)) {
|
603
648
|
return (
|