@100mslive/roomkit-react 0.1.18-alpha.1 → 0.1.19-alpha.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/{HLSView-MR7RYQZB.js → HLSView-GG4WVUQY.js} +2 -2
- package/dist/Prebuilt/common/constants.d.ts +2 -6
- package/dist/Prebuilt/components/Chat/Chat.d.ts +2 -0
- package/dist/Prebuilt/components/Chat/ChatActions.d.ts +12 -0
- package/dist/Prebuilt/components/Chat/ChatBody.d.ts +8 -0
- package/dist/Prebuilt/components/Chat/ChatFooter.d.ts +2 -2
- package/dist/Prebuilt/components/Chat/ChatStates.d.ts +1 -1
- package/dist/Prebuilt/components/Chat/MwebChatOption.d.ts +1 -1
- package/dist/Prebuilt/components/Chat/PinnedMessage.d.ts +1 -3
- package/dist/Prebuilt/components/hooks/useChatBlacklist.d.ts +4 -0
- package/dist/Prebuilt/components/hooks/useSetPinnedMessages.d.ts +3 -10
- package/dist/Prebuilt/components/hooks/useUnreadPollQuizPresent.d.ts +5 -0
- package/dist/{chunk-WFHOR7AP.js → chunk-GXJIUWTP.js} +10083 -4574
- package/dist/chunk-GXJIUWTP.js.map +7 -0
- package/dist/index.cjs.js +12716 -7192
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +1 -1
- package/dist/meta.cjs.json +367 -240
- package/dist/meta.esbuild.json +377 -250
- package/package.json +6 -6
- package/src/Prebuilt/common/constants.ts +4 -4
- package/src/Prebuilt/components/Chat/Chat.tsx +108 -0
- package/src/Prebuilt/components/Chat/ChatActions.tsx +297 -0
- package/src/Prebuilt/components/Chat/ChatBody.tsx +444 -0
- package/src/Prebuilt/components/Chat/ChatFooter.tsx +9 -3
- package/src/Prebuilt/components/Chat/ChatStates.tsx +5 -0
- package/src/Prebuilt/components/Chat/MwebChatOption.tsx +1 -1
- package/src/Prebuilt/components/Chat/PinnedMessage.tsx +4 -2
- package/src/Prebuilt/components/Footer/PollsToggle.tsx +12 -3
- package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +5 -1
- package/src/Prebuilt/components/Polls/CreateQuestions/QuestionForm.jsx +3 -3
- package/src/Prebuilt/components/Polls/Voting/Leaderboard.tsx +9 -1
- package/src/Prebuilt/components/Polls/Voting/LeaderboardEntry.tsx +6 -6
- package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +20 -23
- package/src/Prebuilt/components/Polls/common/MultipleChoiceOptions.jsx +1 -1
- package/src/Prebuilt/components/SidePaneTabs.tsx +33 -11
- package/src/Prebuilt/components/hooks/useChatBlacklist.ts +7 -1
- package/src/Prebuilt/components/hooks/useSetPinnedMessages.ts +19 -11
- package/src/Prebuilt/components/hooks/useUnreadPollQuizPresent.tsx +20 -0
- package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +11 -2
- package/dist/chunk-WFHOR7AP.js.map +0 -7
- package/src/Prebuilt/components/Chat/Chat.jsx +0 -124
- package/src/Prebuilt/components/Chat/ChatBody.jsx +0 -726
- /package/dist/{HLSView-MR7RYQZB.js.map → HLSView-GG4WVUQY.js.map} +0 -0
@@ -2,22 +2,22 @@
|
|
2
2
|
import React, { useCallback, useMemo, useState } from 'react';
|
3
3
|
import { selectLocalPeer, selectLocalPeerRoleName, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
|
4
4
|
import { CheckCircleIcon, ChevronLeftIcon, ChevronRightIcon, CrossCircleIcon } from '@100mslive/react-icons';
|
5
|
-
import { Box, Button, Flex, IconButton,
|
5
|
+
import { Box, Button, Flex, IconButton, Text } from '../../../../';
|
6
6
|
import { checkCorrectAnswer } from '../../../common/utils';
|
7
7
|
import { MultipleChoiceOptions } from '../common/MultipleChoiceOptions';
|
8
8
|
import { SingleChoiceOptions } from '../common/SingleChoiceOptions';
|
9
9
|
import { QUESTION_TYPE } from '../../../common/constants';
|
10
10
|
|
11
|
-
const TextArea = styled('textarea', {
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
});
|
11
|
+
// const TextArea = styled('textarea', {
|
12
|
+
// backgroundColor: '$surface_brighter',
|
13
|
+
// border: '1px solid $border_bright',
|
14
|
+
// borderRadius: '$1',
|
15
|
+
// mb: '$md',
|
16
|
+
// color: '$on_surface_high',
|
17
|
+
// resize: 'none',
|
18
|
+
// p: '$2',
|
19
|
+
// w: '100%',
|
20
|
+
// });
|
21
21
|
|
22
22
|
export const QuestionCard = ({
|
23
23
|
pollID,
|
@@ -67,23 +67,21 @@ export const QuestionCard = ({
|
|
67
67
|
setCurrentIndex(curr => Math.max(1, curr - 1));
|
68
68
|
};
|
69
69
|
|
70
|
-
const [textAnswer, setTextAnswer] = useState('');
|
70
|
+
// const [textAnswer, setTextAnswer] = useState('');
|
71
71
|
const [singleOptionAnswer, setSingleOptionAnswer] = useState();
|
72
72
|
const [multipleOptionAnswer, setMultipleOptionAnswer] = useState(new Set());
|
73
73
|
|
74
|
-
const stringAnswerExpected = [QUESTION_TYPE.LONG_ANSWER, QUESTION_TYPE.SHORT_ANSWER].includes(type);
|
74
|
+
// const stringAnswerExpected = [QUESTION_TYPE.LONG_ANSWER, QUESTION_TYPE.SHORT_ANSWER].includes(type);
|
75
75
|
|
76
76
|
const respondedToQuiz = isQuiz && localPeerResponse && !localPeerResponse.skipped;
|
77
77
|
|
78
78
|
const isValidVote = useMemo(() => {
|
79
|
-
if (
|
80
|
-
return textAnswer.length > 0;
|
81
|
-
} else if (type === QUESTION_TYPE.SINGLE_CHOICE) {
|
79
|
+
if (type === QUESTION_TYPE.SINGLE_CHOICE) {
|
82
80
|
return singleOptionAnswer !== undefined;
|
83
81
|
} else if (type === QUESTION_TYPE.MULTIPLE_CHOICE) {
|
84
82
|
return multipleOptionAnswer.size > 0;
|
85
83
|
}
|
86
|
-
}, [
|
84
|
+
}, [singleOptionAnswer, multipleOptionAnswer, type]);
|
87
85
|
|
88
86
|
const handleVote = useCallback(async () => {
|
89
87
|
if (!isValidVote) {
|
@@ -92,12 +90,11 @@ export const QuestionCard = ({
|
|
92
90
|
await actions.interactivityCenter.addResponsesToPoll(pollID, [
|
93
91
|
{
|
94
92
|
questionIndex: index,
|
95
|
-
text: textAnswer,
|
96
93
|
option: singleOptionAnswer,
|
97
94
|
options: Array.from(multipleOptionAnswer),
|
98
95
|
},
|
99
96
|
]);
|
100
|
-
}, [actions, index, pollID, isValidVote,
|
97
|
+
}, [actions, index, pollID, isValidVote, singleOptionAnswer, multipleOptionAnswer]);
|
101
98
|
|
102
99
|
const handleSkip = useCallback(async () => {
|
103
100
|
await actions.interactivityCenter.addResponsesToPoll(pollID, [
|
@@ -181,7 +178,7 @@ export const QuestionCard = ({
|
|
181
178
|
<Text css={{ color: '$on_surface_high' }}>{text}</Text>
|
182
179
|
</Box>
|
183
180
|
|
184
|
-
{type === QUESTION_TYPE.SHORT_ANSWER ? (
|
181
|
+
{/* {type === QUESTION_TYPE.SHORT_ANSWER ? (
|
185
182
|
<Input
|
186
183
|
disabled={!canRespond}
|
187
184
|
placeholder="Enter your answer"
|
@@ -194,15 +191,15 @@ export const QuestionCard = ({
|
|
194
191
|
cursor: localPeerResponse ? 'not-allowed' : 'text',
|
195
192
|
}}
|
196
193
|
/>
|
197
|
-
) : null}
|
194
|
+
) : null} */}
|
198
195
|
|
199
|
-
{type === QUESTION_TYPE.LONG_ANSWER ? (
|
196
|
+
{/* {type === QUESTION_TYPE.LONG_ANSWER ? (
|
200
197
|
<TextArea
|
201
198
|
disabled={!canRespond}
|
202
199
|
placeholder="Enter your answer"
|
203
200
|
onChange={e => setTextAnswer(e.target.value)}
|
204
201
|
/>
|
205
|
-
) : null}
|
202
|
+
) : null} */}
|
206
203
|
|
207
204
|
{type === QUESTION_TYPE.SINGLE_CHOICE ? (
|
208
205
|
<SingleChoiceOptions
|
@@ -51,7 +51,7 @@ export const MultipleChoiceOptions = ({
|
|
51
51
|
</Checkbox.Root>
|
52
52
|
) : null}
|
53
53
|
|
54
|
-
{isStopped && correctOptionIndexes
|
54
|
+
{isStopped && correctOptionIndexes?.includes(option.index) ? (
|
55
55
|
<Flex css={{ color: '$on_surface_high' }}>
|
56
56
|
<CheckCircleIcon />
|
57
57
|
</Flex>
|
@@ -107,16 +107,37 @@ export const SidePaneTabs = React.memo<{
|
|
107
107
|
<>
|
108
108
|
{hideTabs ? (
|
109
109
|
<>
|
110
|
-
<
|
111
|
-
{
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
110
|
+
<Flex justify="between" css={{ w: '100%' }}>
|
111
|
+
<Text variant="sm" css={{ fontWeight: '$semiBold', p: '$4', c: '$on_surface_high', pr: '$12' }}>
|
112
|
+
{showChat ? (
|
113
|
+
chat_title
|
114
|
+
) : (
|
115
|
+
<span>
|
116
|
+
Participants
|
117
|
+
<ParticipantCount count={peerCount} />
|
118
|
+
</span>
|
119
|
+
)}
|
120
|
+
</Text>
|
121
|
+
<Flex>
|
122
|
+
{showChatSettings ? <ChatSettings /> : null}
|
123
|
+
{isOverlayChat && isChatOpen ? null : (
|
124
|
+
<IconButton
|
125
|
+
css={{ my: '$1', color: '$on_surface_medium', '&:hover': { color: '$on_surface_high' } }}
|
126
|
+
onClick={e => {
|
127
|
+
e.stopPropagation();
|
128
|
+
if (activeTab === SIDE_PANE_OPTIONS.CHAT) {
|
129
|
+
toggleChat();
|
130
|
+
} else {
|
131
|
+
toggleParticipants();
|
132
|
+
}
|
133
|
+
}}
|
134
|
+
data-testid="close_chat"
|
135
|
+
>
|
136
|
+
<CrossIcon />
|
137
|
+
</IconButton>
|
138
|
+
)}
|
139
|
+
</Flex>
|
140
|
+
</Flex>
|
120
141
|
{showChat ? <Chat /> : <ParticipantList offStageRoles={off_stage_roles} onActive={setActiveRole} />}
|
121
142
|
</>
|
122
143
|
) : (
|
@@ -148,7 +169,8 @@ export const SidePaneTabs = React.memo<{
|
|
148
169
|
color: activeTab !== SIDE_PANE_OPTIONS.PARTICIPANTS ? '$on_surface_low' : '$on_surface_high',
|
149
170
|
}}
|
150
171
|
>
|
151
|
-
Participants
|
172
|
+
Participants
|
173
|
+
<ParticipantCount count={peerCount} />
|
152
174
|
</Tabs.Trigger>
|
153
175
|
</Tabs.List>
|
154
176
|
{showChatSettings ? <ChatSettings /> : null}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { useCallback } from 'react';
|
2
|
-
import { selectSessionStore, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
|
2
|
+
import { selectLocalPeer, selectSessionStore, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
|
3
3
|
// @ts-ignore
|
4
4
|
import { ToastManager } from '../Toast/ToastManager';
|
5
5
|
import { SESSION_STORE_KEY } from '../../common/constants';
|
@@ -21,3 +21,9 @@ export const useChatBlacklist = (
|
|
21
21
|
|
22
22
|
return { blacklistItem, blacklistedIDs };
|
23
23
|
};
|
24
|
+
|
25
|
+
export const useIsPeerBlacklisted = ({ local = false, peerCustomerUserId = '' }) => {
|
26
|
+
const localPeer = useHMSStore(selectLocalPeer);
|
27
|
+
const blacklistedPeerIDs = useHMSStore(selectSessionStore(SESSION_STORE_KEY.CHAT_PEER_BLACKLIST)) || [];
|
28
|
+
return blacklistedPeerIDs?.includes(local ? localPeer?.customerUserId : peerCustomerUserId);
|
29
|
+
};
|
@@ -1,5 +1,11 @@
|
|
1
1
|
import { useCallback } from 'react';
|
2
|
-
import {
|
2
|
+
import {
|
3
|
+
HMSMessage,
|
4
|
+
selectPeerNameByID,
|
5
|
+
selectSessionStore,
|
6
|
+
useHMSActions,
|
7
|
+
useHMSVanillaStore,
|
8
|
+
} from '@100mslive/react-sdk';
|
3
9
|
// @ts-ignore
|
4
10
|
import { ToastManager } from '../Toast/ToastManager';
|
5
11
|
// @ts-ignore
|
@@ -8,7 +14,6 @@ import { SESSION_STORE_KEY } from '../../common/constants';
|
|
8
14
|
type PinnedMessage = {
|
9
15
|
text: string;
|
10
16
|
id: string;
|
11
|
-
authorId: string;
|
12
17
|
pinnedBy: string;
|
13
18
|
};
|
14
19
|
|
@@ -20,9 +25,9 @@ export const useSetPinnedMessages = () => {
|
|
20
25
|
const vanillaStore = useHMSVanillaStore();
|
21
26
|
|
22
27
|
const setPinnedMessages = useCallback(
|
23
|
-
async (
|
28
|
+
async (message: HMSMessage, pinnedBy: string) => {
|
24
29
|
const peerName = vanillaStore.getState(selectPeerNameByID(message?.sender)) || message?.senderName;
|
25
|
-
const newPinnedMessage = { text: '', id: message.id, pinnedBy
|
30
|
+
const newPinnedMessage = { text: '', id: message.id, pinnedBy };
|
26
31
|
|
27
32
|
if (message && peerName) {
|
28
33
|
newPinnedMessage['text'] = `${peerName}: ${message.message}`;
|
@@ -30,7 +35,8 @@ export const useSetPinnedMessages = () => {
|
|
30
35
|
newPinnedMessage['text'] = message.message;
|
31
36
|
}
|
32
37
|
|
33
|
-
|
38
|
+
const pinnedMessages = vanillaStore.getState(selectSessionStore(SESSION_STORE_KEY.PINNED_MESSAGES)) || [];
|
39
|
+
if (!pinnedMessages?.find((pinnedMessage: PinnedMessage) => pinnedMessage.id === newPinnedMessage.id)) {
|
34
40
|
await hmsActions.sessionStore
|
35
41
|
.set(SESSION_STORE_KEY.PINNED_MESSAGES, [...pinnedMessages, newPinnedMessage].slice(-3)) // Limiting to maximum of 3 messages - FIFO
|
36
42
|
.catch(err => ToastManager.addToast({ title: err.description }));
|
@@ -40,30 +46,32 @@ export const useSetPinnedMessages = () => {
|
|
40
46
|
);
|
41
47
|
|
42
48
|
const removePinnedMessage = useCallback(
|
43
|
-
async (
|
49
|
+
async (indexToRemove: number) => {
|
50
|
+
const pinnedMessages = vanillaStore.getState(selectSessionStore(SESSION_STORE_KEY.PINNED_MESSAGES)) || [];
|
44
51
|
if (pinnedMessages[indexToRemove]) {
|
45
52
|
await hmsActions.sessionStore
|
46
53
|
.set(
|
47
54
|
SESSION_STORE_KEY.PINNED_MESSAGES,
|
48
|
-
pinnedMessages.filter((_, index: number) => index !== indexToRemove),
|
55
|
+
pinnedMessages.filter((_: PinnedMessage, index: number) => index !== indexToRemove),
|
49
56
|
)
|
50
57
|
.catch(err => ToastManager.addToast({ title: err.description }));
|
51
58
|
}
|
52
59
|
},
|
53
|
-
[hmsActions],
|
60
|
+
[hmsActions, vanillaStore],
|
54
61
|
);
|
55
62
|
|
56
63
|
const unpinBlacklistedMessages = useCallback(
|
57
|
-
async (
|
64
|
+
async (blacklistedMessageIDSet: Set<string>) => {
|
65
|
+
const pinnedMessages = vanillaStore.getState(selectSessionStore(SESSION_STORE_KEY.PINNED_MESSAGES)) || [];
|
58
66
|
const filteredPinnedMessages = pinnedMessages?.filter(
|
59
|
-
pinnedMessage => !blacklistedMessageIDSet?.has(pinnedMessage.id),
|
67
|
+
(pinnedMessage: PinnedMessage) => !blacklistedMessageIDSet?.has(pinnedMessage.id),
|
60
68
|
);
|
61
69
|
|
62
70
|
await hmsActions.sessionStore
|
63
71
|
.set(SESSION_STORE_KEY.PINNED_MESSAGES, filteredPinnedMessages)
|
64
72
|
.catch(err => ToastManager.addToast({ title: err.description }));
|
65
73
|
},
|
66
|
-
[hmsActions],
|
74
|
+
[hmsActions, vanillaStore],
|
67
75
|
);
|
68
76
|
|
69
77
|
return { setPinnedMessages, removePinnedMessage, unpinBlacklistedMessages };
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { useEffect, useState } from 'react';
|
2
|
+
import { selectLocalPeerID } from '@100mslive/hms-video-store';
|
3
|
+
import { HMSNotificationTypes, useHMSNotifications, useHMSStore } from '@100mslive/react-sdk';
|
4
|
+
|
5
|
+
export const useUnreadPollQuizPresent = () => {
|
6
|
+
const localPeerID = useHMSStore(selectLocalPeerID);
|
7
|
+
const notification = useHMSNotifications();
|
8
|
+
const [unreadPollQuiz, setUnreadPollQuiz] = useState(false);
|
9
|
+
|
10
|
+
useEffect(() => {
|
11
|
+
if (!notification) {
|
12
|
+
return;
|
13
|
+
}
|
14
|
+
if (notification.type !== HMSNotificationTypes.POLL_STARTED) {
|
15
|
+
return;
|
16
|
+
}
|
17
|
+
setUnreadPollQuiz(notification.data.startedBy !== localPeerID);
|
18
|
+
}, [localPeerID, notification]);
|
19
|
+
return { unreadPollQuiz, setUnreadPollQuiz };
|
20
|
+
};
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import type { Layout } from '@100mslive/types-prebuilt';
|
3
|
-
import
|
3
|
+
import { isArray, mergeWith } from 'lodash';
|
4
4
|
// @ts-ignore: fix types
|
5
5
|
import { useAuthToken } from '../../components/AppData/useUISettings';
|
6
6
|
import { useFetchRoomLayout, useFetchRoomLayoutResponse } from './hooks/useFetchRoomLayout';
|
@@ -18,6 +18,14 @@ export const RoomLayoutContext = React.createContext<
|
|
18
18
|
| undefined
|
19
19
|
>(undefined);
|
20
20
|
|
21
|
+
function customizer(objValue: any, srcValue: any) {
|
22
|
+
if (isArray(objValue) && isArray(srcValue)) {
|
23
|
+
return srcValue;
|
24
|
+
}
|
25
|
+
// default mergeWith behaviour is followed
|
26
|
+
return undefined;
|
27
|
+
}
|
28
|
+
|
21
29
|
export const RoomLayoutProvider: React.FC<React.PropsWithChildren<RoomLayoutProviderProps>> = ({
|
22
30
|
children,
|
23
31
|
roomLayoutEndpoint,
|
@@ -25,7 +33,8 @@ export const RoomLayoutProvider: React.FC<React.PropsWithChildren<RoomLayoutProv
|
|
25
33
|
}) => {
|
26
34
|
const authToken: string = useAuthToken();
|
27
35
|
const { layout, updateRoomLayoutForRole } = useFetchRoomLayout({ authToken, endpoint: roomLayoutEndpoint });
|
28
|
-
const mergedLayout = authToken && layout ?
|
36
|
+
const mergedLayout = authToken && layout ? mergeWith(layout, overrideLayout, customizer) : layout;
|
37
|
+
|
29
38
|
return (
|
30
39
|
<RoomLayoutContext.Provider value={{ layout: mergedLayout, updateRoomLayoutForRole }}>
|
31
40
|
{children}
|