@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.
- 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
package/package.json
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
"prebuilt",
|
11
11
|
"roomkit"
|
12
12
|
],
|
13
|
-
"version": "0.1.14
|
13
|
+
"version": "0.1.14",
|
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
|
80
|
-
"@100mslive/hms-virtual-background": "1.11.23
|
81
|
-
"@100mslive/react-icons": "0.8.23
|
82
|
-
"@100mslive/react-sdk": "0.8.23
|
79
|
+
"@100mslive/hls-player": "0.1.23",
|
80
|
+
"@100mslive/hms-virtual-background": "1.11.23",
|
81
|
+
"@100mslive/react-icons": "0.8.23",
|
82
|
+
"@100mslive/react-sdk": "0.8.23",
|
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": "aed9a8922bbebf1015858ab5b4896acff5647c0a"
|
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 (
|