@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.
Files changed (44) hide show
  1. package/dist/{HLSView-MR7RYQZB.js → HLSView-GG4WVUQY.js} +2 -2
  2. package/dist/Prebuilt/common/constants.d.ts +2 -6
  3. package/dist/Prebuilt/components/Chat/Chat.d.ts +2 -0
  4. package/dist/Prebuilt/components/Chat/ChatActions.d.ts +12 -0
  5. package/dist/Prebuilt/components/Chat/ChatBody.d.ts +8 -0
  6. package/dist/Prebuilt/components/Chat/ChatFooter.d.ts +2 -2
  7. package/dist/Prebuilt/components/Chat/ChatStates.d.ts +1 -1
  8. package/dist/Prebuilt/components/Chat/MwebChatOption.d.ts +1 -1
  9. package/dist/Prebuilt/components/Chat/PinnedMessage.d.ts +1 -3
  10. package/dist/Prebuilt/components/hooks/useChatBlacklist.d.ts +4 -0
  11. package/dist/Prebuilt/components/hooks/useSetPinnedMessages.d.ts +3 -10
  12. package/dist/Prebuilt/components/hooks/useUnreadPollQuizPresent.d.ts +5 -0
  13. package/dist/{chunk-WFHOR7AP.js → chunk-GXJIUWTP.js} +10083 -4574
  14. package/dist/chunk-GXJIUWTP.js.map +7 -0
  15. package/dist/index.cjs.js +12716 -7192
  16. package/dist/index.cjs.js.map +4 -4
  17. package/dist/index.js +1 -1
  18. package/dist/meta.cjs.json +367 -240
  19. package/dist/meta.esbuild.json +377 -250
  20. package/package.json +6 -6
  21. package/src/Prebuilt/common/constants.ts +4 -4
  22. package/src/Prebuilt/components/Chat/Chat.tsx +108 -0
  23. package/src/Prebuilt/components/Chat/ChatActions.tsx +297 -0
  24. package/src/Prebuilt/components/Chat/ChatBody.tsx +444 -0
  25. package/src/Prebuilt/components/Chat/ChatFooter.tsx +9 -3
  26. package/src/Prebuilt/components/Chat/ChatStates.tsx +5 -0
  27. package/src/Prebuilt/components/Chat/MwebChatOption.tsx +1 -1
  28. package/src/Prebuilt/components/Chat/PinnedMessage.tsx +4 -2
  29. package/src/Prebuilt/components/Footer/PollsToggle.tsx +12 -3
  30. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +5 -1
  31. package/src/Prebuilt/components/Polls/CreateQuestions/QuestionForm.jsx +3 -3
  32. package/src/Prebuilt/components/Polls/Voting/Leaderboard.tsx +9 -1
  33. package/src/Prebuilt/components/Polls/Voting/LeaderboardEntry.tsx +6 -6
  34. package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +20 -23
  35. package/src/Prebuilt/components/Polls/common/MultipleChoiceOptions.jsx +1 -1
  36. package/src/Prebuilt/components/SidePaneTabs.tsx +33 -11
  37. package/src/Prebuilt/components/hooks/useChatBlacklist.ts +7 -1
  38. package/src/Prebuilt/components/hooks/useSetPinnedMessages.ts +19 -11
  39. package/src/Prebuilt/components/hooks/useUnreadPollQuizPresent.tsx +20 -0
  40. package/src/Prebuilt/provider/roomLayoutProvider/index.tsx +11 -2
  41. package/dist/chunk-WFHOR7AP.js.map +0 -7
  42. package/src/Prebuilt/components/Chat/Chat.jsx +0 -124
  43. package/src/Prebuilt/components/Chat/ChatBody.jsx +0 -726
  44. /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, Input, styled, Text } from '../../../../';
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
- 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
- });
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 (stringAnswerExpected) {
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
- }, [textAnswer, singleOptionAnswer, multipleOptionAnswer, type, stringAnswerExpected]);
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, textAnswer, singleOptionAnswer, multipleOptionAnswer]);
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.includes(option.index) ? (
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
- <Text variant="sm" css={{ fontWeight: '$semiBold', p: '$4', c: '$on_surface_high', pr: '$12' }}>
111
- {showChat ? (
112
- chat_title
113
- ) : (
114
- <span>
115
- Participants <ParticipantCount count={peerCount} />
116
- </span>
117
- )}
118
- </Text>
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&nbsp;
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 &nbsp; <ParticipantCount count={peerCount} />
172
+ Participants&nbsp;
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 { HMSMessage, selectPeerNameByID, useHMSActions, useHMSVanillaStore } from '@100mslive/react-sdk';
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 (pinnedMessages: PinnedMessage[] = [], message: HMSMessage, pinnedBy: string) => {
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, authorId: message?.senderUserId || '' };
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
- if (newPinnedMessage && !pinnedMessages.find(pinnedMessage => pinnedMessage.id === newPinnedMessage.id)) {
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 (pinnedMessages: PinnedMessage[] = [], indexToRemove: number) => {
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 (pinnedMessages: PinnedMessage[] = [], blacklistedMessageIDSet: Set<string>) => {
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 merge from 'lodash.merge';
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 ? merge(layout, overrideLayout) : 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}