@100mslive/roomkit-react 0.1.20-alpha.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +27 -2
- package/dist/{HLSView-PJLISGG4.js → HLSView-ULB4DC6B.js} +2 -2
- package/dist/Input/Input.d.ts +3 -3
- package/dist/Prebuilt/components/Chat/ChatActions.d.ts +2 -1
- package/dist/Prebuilt/components/Polls/CreateQuestions/DeleteQuestionModal.d.ts +6 -0
- package/dist/Prebuilt/components/Polls/CreateQuestions/QuestionForm.d.ts +22 -0
- package/dist/Prebuilt/components/Polls/CreateQuestions/SavedQuestion.d.ts +11 -0
- package/dist/Prebuilt/components/Polls/Voting/StandardVoting.d.ts +5 -0
- package/dist/Prebuilt/components/Polls/Voting/TimedVoting.d.ts +5 -0
- package/dist/Prebuilt/components/Polls/Voting/Voting.d.ts +5 -0
- package/dist/Prebuilt/components/Polls/common/Line.d.ts +2 -0
- package/dist/Prebuilt/components/Polls/common/OptionInputWithDelete.d.ts +8 -0
- package/dist/Prebuilt/components/Polls/common/StatusIndicator.d.ts +4 -0
- package/dist/Prebuilt/components/Polls/common/VoteCount.d.ts +4 -0
- package/dist/Prebuilt/components/Polls/common/VoteProgress.d.ts +6 -0
- package/dist/Prebuilt/components/Polls/common/VoterList.d.ts +4 -0
- package/dist/Prebuilt/components/TileMenu/utils.d.ts +5 -0
- package/dist/Prebuilt/components/hooks/usePinnedBy.d.ts +1 -0
- package/dist/Prebuilt/components/hooks/{useSetPinnedMessages.d.ts → usePinnedMessages.d.ts} +6 -1
- package/dist/TextArea/TextArea.d.ts +441 -0
- package/dist/TextArea/index.d.ts +1 -0
- package/dist/Toast/Toast.d.ts +1 -1
- package/dist/{chunk-QENB2CO7.js → chunk-GVA4I77Z.js} +2803 -2743
- package/dist/chunk-GVA4I77Z.js.map +7 -0
- package/dist/index.cjs.js +3038 -2969
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/meta.cjs.json +475 -388
- package/dist/meta.esbuild.json +485 -396
- package/package.json +7 -8
- package/src/Button/Button.tsx +4 -4
- package/src/Input/Input.tsx +1 -1
- package/src/Prebuilt/App.tsx +2 -0
- package/src/Prebuilt/components/Chat/ChatActions.tsx +25 -8
- package/src/Prebuilt/components/Chat/ChatBody.tsx +64 -21
- package/src/Prebuilt/components/Chat/ChatFooter.tsx +1 -0
- package/src/Prebuilt/components/Chat/PinnedMessage.tsx +2 -2
- package/src/Prebuilt/components/Header/AdditionalRoomState.jsx +1 -38
- package/src/Prebuilt/components/Header/StreamActions.tsx +1 -1
- package/src/Prebuilt/components/Polls/CreatePollQuiz/PollsQuizMenu.jsx +11 -1
- package/src/Prebuilt/components/Polls/CreateQuestions/{DeleteQuestionModal.jsx → DeleteQuestionModal.tsx} +9 -1
- package/src/Prebuilt/components/Polls/CreateQuestions/{QuestionForm.jsx → QuestionForm.tsx} +71 -30
- package/src/Prebuilt/components/Polls/CreateQuestions/{SavedQuestion.jsx → SavedQuestion.tsx} +24 -15
- package/src/Prebuilt/components/Polls/Voting/LeaderboardSummary.tsx +1 -1
- package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +61 -80
- package/src/Prebuilt/components/Polls/Voting/{StandardVoting.jsx → StandardVoting.tsx} +3 -7
- package/src/Prebuilt/components/Polls/Voting/{TimedVoting.jsx → TimedVoting.tsx} +4 -7
- package/src/Prebuilt/components/Polls/Voting/{Voting.jsx → Voting.tsx} +4 -3
- package/src/Prebuilt/components/Polls/common/Line.tsx +4 -0
- package/src/Prebuilt/components/Polls/common/{OptionInputWithDelete.jsx → OptionInputWithDelete.tsx} +14 -2
- package/src/Prebuilt/components/Polls/common/SingleChoiceOptions.jsx +1 -1
- package/src/Prebuilt/components/Polls/common/{StatusIndicator.jsx → StatusIndicator.tsx} +1 -2
- package/src/Prebuilt/components/Polls/common/{VoteCount.jsx → VoteCount.tsx} +1 -2
- package/src/Prebuilt/components/Polls/common/{VoteProgress.jsx → VoteProgress.tsx} +3 -2
- package/src/Prebuilt/components/Polls/common/{VoterList.jsx → VoterList.tsx} +1 -1
- package/src/Prebuilt/components/TileMenu/TileMenu.jsx +3 -1
- package/src/Prebuilt/components/TileMenu/TileMenuContent.tsx +15 -3
- package/src/Prebuilt/components/TileMenu/utils.ts +7 -0
- package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +7 -3
- package/src/Prebuilt/components/VideoTile.jsx +2 -4
- package/src/Prebuilt/components/hooks/usePinnedBy.tsx +22 -0
- package/src/Prebuilt/components/hooks/{useSetPinnedMessages.ts → usePinnedMessages.ts} +2 -2
- package/src/Prebuilt/components/hooks/useUnreadPollQuizPresent.tsx +1 -4
- package/src/Prebuilt/layouts/VideoStreamingSection.tsx +0 -1
- package/src/TextArea/TextArea.tsx +30 -0
- package/src/TextArea/index.tsx +1 -0
- package/src/index.ts +1 -0
- package/src/store/StorybookSDK.ts +3 -1
- package/dist/Prebuilt/plugins/whiteboard/ToggleWhiteboard.d.ts +0 -5
- package/dist/chunk-QENB2CO7.js.map +0 -7
- package/src/Prebuilt/components/Polls/common/Votes.jsx +0 -72
- package/src/Prebuilt/layouts/WhiteboardView.jsx +0 -40
- package/src/Prebuilt/plugins/whiteboard/PusherCommunicationProvider.js +0 -110
- package/src/Prebuilt/plugins/whiteboard/README.md +0 -29
- package/src/Prebuilt/plugins/whiteboard/ToggleWhiteboard.tsx +0 -37
- package/src/Prebuilt/plugins/whiteboard/Whiteboard.css +0 -12
- package/src/Prebuilt/plugins/whiteboard/Whiteboard.jsx +0 -11
- package/src/Prebuilt/plugins/whiteboard/WhiteboardEvents.js +0 -8
- package/src/Prebuilt/plugins/whiteboard/index.js +0 -3
- package/src/Prebuilt/plugins/whiteboard/useMultiplayerState.js +0 -212
- package/src/Prebuilt/plugins/whiteboard/useWhiteboardMetadata.js +0 -47
- /package/dist/{HLSView-PJLISGG4.js.map → HLSView-ULB4DC6B.js.map} +0 -0
@@ -1,21 +1,47 @@
|
|
1
1
|
// @ts-check
|
2
2
|
import React, { useCallback, useRef, useState } from 'react';
|
3
|
+
import {
|
4
|
+
HMSPollQuestionCreateParams,
|
5
|
+
HMSPollQuestionOptionCreateParams,
|
6
|
+
HMSPollQuestionType,
|
7
|
+
} from '@100mslive/react-sdk';
|
3
8
|
import { AddCircleIcon, TrashIcon } from '@100mslive/react-icons';
|
4
|
-
import {
|
9
|
+
import { Button, Dropdown, Flex, IconButton, Input, Switch, Text, TextArea, Tooltip } from '../../../..';
|
10
|
+
// @ts-ignore
|
5
11
|
import { DialogDropdownTrigger } from '../../../primitives/DropdownTrigger';
|
12
|
+
// @ts-ignore
|
6
13
|
import { DeleteQuestionModal } from './DeleteQuestionModal';
|
14
|
+
// @ts-ignore
|
7
15
|
import { useDropdownSelection } from '../../hooks/useDropdownSelection';
|
16
|
+
// @ts-ignore
|
8
17
|
import { isValidTextInput } from '../../../common/utils';
|
18
|
+
import { Line } from '../common/Line';
|
19
|
+
// @ts-ignore
|
9
20
|
import { MultipleChoiceOptionInputs } from '../common/MultipleChoiceOptions';
|
21
|
+
// @ts-ignore
|
10
22
|
import { SingleChoiceOptionInputs } from '../common/SingleChoiceOptions';
|
11
23
|
import { QUESTION_TYPE, QUESTION_TYPE_TITLE } from '../../../common/constants';
|
12
24
|
|
13
|
-
export const QuestionForm = ({
|
25
|
+
export const QuestionForm = ({
|
26
|
+
question,
|
27
|
+
index,
|
28
|
+
length,
|
29
|
+
onSave,
|
30
|
+
removeQuestion,
|
31
|
+
isQuiz,
|
32
|
+
}: {
|
33
|
+
question: HMSPollQuestionCreateParams & { draftID: number };
|
34
|
+
index: number;
|
35
|
+
length: number;
|
36
|
+
onSave: (optionParams: HMSPollQuestionCreateParams & { draftID: number; saved: boolean }) => void;
|
37
|
+
removeQuestion: () => void;
|
38
|
+
isQuiz: boolean;
|
39
|
+
}) => {
|
14
40
|
const ref = useRef(null);
|
15
41
|
const selectionBg = useDropdownSelection();
|
16
42
|
const [openDelete, setOpenDelete] = useState(false);
|
17
43
|
const [open, setOpen] = useState(false);
|
18
|
-
const [type, setType] = useState(question.type || QUESTION_TYPE.SINGLE_CHOICE);
|
44
|
+
const [type, setType] = useState<HMSPollQuestionType>(question.type || QUESTION_TYPE.SINGLE_CHOICE);
|
19
45
|
const [text, setText] = useState(question.text);
|
20
46
|
const [weight, setWeight] = useState(isQuiz ? 10 : 1);
|
21
47
|
const [options, setOptions] = useState(
|
@@ -34,14 +60,14 @@ export const QuestionForm = ({ question, index, length, onSave, removeQuestion,
|
|
34
60
|
});
|
35
61
|
|
36
62
|
const handleOptionTextChange = useCallback(
|
37
|
-
(index, text) => {
|
63
|
+
(index: number, text: string) => {
|
38
64
|
setOptions(options => [...options.slice(0, index), { ...options[index], text }, ...options.slice(index + 1)]);
|
39
65
|
},
|
40
66
|
[setOptions],
|
41
67
|
);
|
42
68
|
|
43
69
|
const removeOption = useCallback(
|
44
|
-
index =>
|
70
|
+
(index: number) =>
|
45
71
|
setOptions(options => {
|
46
72
|
const newOptions = [...options];
|
47
73
|
newOptions.splice(index, 1);
|
@@ -51,7 +77,7 @@ export const QuestionForm = ({ question, index, length, onSave, removeQuestion,
|
|
51
77
|
);
|
52
78
|
|
53
79
|
const selectSingleChoiceAnswer = useCallback(
|
54
|
-
answerIndex => {
|
80
|
+
(answerIndex: number) => {
|
55
81
|
if (!isQuiz) {
|
56
82
|
return;
|
57
83
|
}
|
@@ -66,7 +92,7 @@ export const QuestionForm = ({ question, index, length, onSave, removeQuestion,
|
|
66
92
|
);
|
67
93
|
|
68
94
|
const selectMultipleChoiceAnswer = useCallback(
|
69
|
-
(checked, index) => {
|
95
|
+
(checked: boolean, index: number) => {
|
70
96
|
if (!isQuiz) {
|
71
97
|
return;
|
72
98
|
}
|
@@ -90,6 +116,7 @@ export const QuestionForm = ({ question, index, length, onSave, removeQuestion,
|
|
90
116
|
<Dropdown.Root open={open} onOpenChange={setOpen}>
|
91
117
|
<DialogDropdownTrigger
|
92
118
|
ref={ref}
|
119
|
+
// @ts-ignore
|
93
120
|
title={QUESTION_TYPE_TITLE[type]}
|
94
121
|
css={{
|
95
122
|
backgroundColor: '$surface_bright',
|
@@ -98,17 +125,20 @@ export const QuestionForm = ({ question, index, length, onSave, removeQuestion,
|
|
98
125
|
open={open}
|
99
126
|
/>
|
100
127
|
<Dropdown.Portal>
|
128
|
+
{/* @ts-ignore */}
|
101
129
|
<Dropdown.Content align="start" sideOffset={8} css={{ w: ref.current?.clientWidth, zIndex: 1000 }}>
|
102
130
|
{Object.keys(QUESTION_TYPE_TITLE).map(value => {
|
103
131
|
return (
|
104
132
|
<Dropdown.Item
|
105
133
|
key={value}
|
134
|
+
// @ts-ignore
|
106
135
|
onSelect={() => setType(value)}
|
107
136
|
css={{
|
108
137
|
px: '$9',
|
109
138
|
bg: type === value ? selectionBg : undefined,
|
110
139
|
}}
|
111
140
|
>
|
141
|
+
{/* @ts-ignore */}
|
112
142
|
{QUESTION_TYPE_TITLE[value]}
|
113
143
|
</Dropdown.Item>
|
114
144
|
);
|
@@ -116,20 +146,28 @@ export const QuestionForm = ({ question, index, length, onSave, removeQuestion,
|
|
116
146
|
</Dropdown.Content>
|
117
147
|
</Dropdown.Portal>
|
118
148
|
</Dropdown.Root>
|
119
|
-
<
|
149
|
+
<TextArea
|
150
|
+
maxLength={1024}
|
120
151
|
placeholder="Ask a question"
|
121
152
|
css={{
|
122
153
|
mt: '$md',
|
123
154
|
backgroundColor: '$surface_bright',
|
124
155
|
border: '1px solid $border_bright',
|
156
|
+
minHeight: '$14',
|
157
|
+
resize: 'vertical',
|
158
|
+
maxHeight: '$32',
|
125
159
|
}}
|
126
|
-
type="text"
|
127
160
|
value={text}
|
128
161
|
onChange={event => setText(event.target.value)}
|
129
162
|
/>
|
163
|
+
<Text variant="xs" css={{ color: '$on_surface_medium', textAlign: 'end', mt: '$4' }}>
|
164
|
+
{text?.length || 0}/1024
|
165
|
+
</Text>
|
166
|
+
<Line />
|
167
|
+
{/* @ts-ignore */}
|
130
168
|
{type === QUESTION_TYPE.SINGLE_CHOICE || type === QUESTION_TYPE.MULTIPLE_CHOICE ? (
|
131
169
|
<>
|
132
|
-
<Text variant="body2" css={{
|
170
|
+
<Text variant="body2" css={{ mb: '$6', c: '$on_surface_medium' }}>
|
133
171
|
Options
|
134
172
|
</Text>
|
135
173
|
|
@@ -173,7 +211,7 @@ export const QuestionForm = ({ question, index, length, onSave, removeQuestion,
|
|
173
211
|
<AddCircleIcon style={{ position: 'relative', left: '-2px' }} />
|
174
212
|
|
175
213
|
<Text
|
176
|
-
variant="
|
214
|
+
variant="sm"
|
177
215
|
css={{
|
178
216
|
ml: '$4',
|
179
217
|
c: 'inherit',
|
@@ -183,9 +221,10 @@ export const QuestionForm = ({ question, index, length, onSave, removeQuestion,
|
|
183
221
|
</Text>
|
184
222
|
</Flex>
|
185
223
|
)}
|
224
|
+
<Line />
|
186
225
|
{isQuiz ? (
|
187
226
|
<>
|
188
|
-
<Flex justify="between" align="center" css={{
|
227
|
+
<Flex justify="between" align="center" css={{ gap: '$6', w: '100%' }}>
|
189
228
|
<Text variant="sm" css={{ color: '$on_surface_medium' }}>
|
190
229
|
Point Weightage
|
191
230
|
</Text>
|
@@ -194,7 +233,7 @@ export const QuestionForm = ({ question, index, length, onSave, removeQuestion,
|
|
194
233
|
value={weight}
|
195
234
|
min={1}
|
196
235
|
max={999}
|
197
|
-
onChange={e => setWeight(Math.min(e.target.value, 999))}
|
236
|
+
onChange={e => setWeight(Math.min(Number(e.target.value), 999))}
|
198
237
|
css={{
|
199
238
|
backgroundColor: '$surface_bright',
|
200
239
|
border: '1px solid $border_bright',
|
@@ -213,21 +252,15 @@ export const QuestionForm = ({ question, index, length, onSave, removeQuestion,
|
|
213
252
|
</>
|
214
253
|
) : null}
|
215
254
|
|
216
|
-
<Flex justify="
|
217
|
-
<
|
218
|
-
css={{
|
219
|
-
color: '$on_surface_medium',
|
220
|
-
cursor: 'pointer',
|
221
|
-
'&:hover': { color: '$on_surface_high' },
|
222
|
-
}}
|
223
|
-
>
|
255
|
+
<Flex justify="end" align="center" css={{ mt: '$12', gap: '$8' }}>
|
256
|
+
<IconButton css={{ border: '1px solid $border_bright' }}>
|
224
257
|
<TrashIcon onClick={() => setOpenDelete(!open)} />
|
225
|
-
</
|
258
|
+
</IconButton>
|
226
259
|
<Tooltip
|
227
260
|
disabled={isValid}
|
228
261
|
title={
|
229
|
-
options.length
|
230
|
-
? 'At least
|
262
|
+
options.length < 2
|
263
|
+
? 'At least two options must be added'
|
231
264
|
: `Please fill all the fields ${isQuiz ? 'and mark the correct answer(s)' : ''} to continue`
|
232
265
|
}
|
233
266
|
boxCss={{ maxWidth: '$40' }}
|
@@ -257,16 +290,24 @@ export const QuestionForm = ({ question, index, length, onSave, removeQuestion,
|
|
257
290
|
);
|
258
291
|
};
|
259
292
|
|
260
|
-
export const isValidQuestion = ({
|
293
|
+
export const isValidQuestion = ({
|
294
|
+
text,
|
295
|
+
type,
|
296
|
+
options,
|
297
|
+
weight,
|
298
|
+
isQuiz = false,
|
299
|
+
}: {
|
300
|
+
text: string;
|
301
|
+
type: string;
|
302
|
+
options: HMSPollQuestionOptionCreateParams[];
|
303
|
+
weight: number;
|
304
|
+
isQuiz?: boolean;
|
305
|
+
}) => {
|
261
306
|
if (!isValidTextInput(text) || !type) {
|
262
307
|
return false;
|
263
308
|
}
|
264
309
|
|
265
|
-
|
266
|
-
// return true;
|
267
|
-
// }
|
268
|
-
|
269
|
-
const everyOptionHasText = options.length > 0 && options.every(option => option && isValidTextInput(option.text, 1));
|
310
|
+
const everyOptionHasText = options.length > 1 && options.every(option => option && isValidTextInput(option.text, 1));
|
270
311
|
const hasCorrectAnswer = options.some(option => option.isCorrectAnswer);
|
271
312
|
|
272
313
|
if (!isQuiz) {
|
package/src/Prebuilt/components/Polls/CreateQuestions/{SavedQuestion.jsx → SavedQuestion.tsx}
RENAMED
@@ -1,25 +1,41 @@
|
|
1
|
-
// @ts-check
|
2
1
|
import React, { useState } from 'react';
|
2
|
+
import { HMSPollQuestion } from '@100mslive/react-sdk';
|
3
3
|
import { CheckCircleIcon, TrashIcon } from '@100mslive/react-icons';
|
4
|
-
import {
|
4
|
+
import { Button, Flex, Text } from '../../../../';
|
5
|
+
// @ts-ignore
|
6
|
+
import IconButton from '../../../IconButton';
|
5
7
|
import { DeleteQuestionModal } from './DeleteQuestionModal';
|
6
8
|
import { QUESTION_TYPE_TITLE } from '../../../common/constants';
|
7
9
|
|
8
|
-
export const SavedQuestion = ({
|
10
|
+
export const SavedQuestion = ({
|
11
|
+
question,
|
12
|
+
index,
|
13
|
+
length,
|
14
|
+
convertToDraft,
|
15
|
+
removeQuestion,
|
16
|
+
}: {
|
17
|
+
question: HMSPollQuestion & { draftID: number };
|
18
|
+
index: number;
|
19
|
+
length: number;
|
20
|
+
convertToDraft: (draftID: number) => void;
|
21
|
+
removeQuestion: (draftID: number) => void;
|
22
|
+
}) => {
|
9
23
|
const [openDeleteModal, setOpenDeleteModal] = useState(false);
|
10
24
|
return (
|
11
25
|
<>
|
12
26
|
<Text variant="overline" css={{ c: '$on_surface_low', textTransform: 'uppercase' }}>
|
27
|
+
{/* @ts-ignore */}
|
13
28
|
Question {index + 1} of {length}: {QUESTION_TYPE_TITLE[question.type]}
|
14
29
|
</Text>
|
15
30
|
<Text variant="body2" css={{ mt: '$4', mb: '$md' }}>
|
16
31
|
{question.text}
|
17
32
|
</Text>
|
18
|
-
{question.options
|
33
|
+
{question.options?.map((option, index) => (
|
19
34
|
<Flex key={`${option.text}-${index}`} css={{ alignItems: 'center', my: '$xs' }}>
|
20
35
|
<Text variant="body2" css={{ c: '$on_surface_medium' }}>
|
21
36
|
{option.text}
|
22
37
|
</Text>
|
38
|
+
{/* @ts-ignore */}
|
23
39
|
{option.isCorrectAnswer && (
|
24
40
|
<Flex css={{ color: '$alert_success', mx: '$xs' }}>
|
25
41
|
<CheckCircleIcon height={24} width={24} />
|
@@ -32,18 +48,11 @@ export const SavedQuestion = ({ question, index, length, convertToDraft, removeQ
|
|
32
48
|
Not required to answer
|
33
49
|
</Text>
|
34
50
|
) : null}
|
35
|
-
<Flex justify="
|
36
|
-
<
|
37
|
-
onClick={() => setOpenDeleteModal(true)}
|
38
|
-
css={{ color: '$on_surface_low', '&:hover': { color: '$on_surface_medium', cursor: 'pointer' } }}
|
39
|
-
>
|
51
|
+
<Flex justify="end" css={{ w: '100%', alignItems: 'center', gap: '$4' }}>
|
52
|
+
<IconButton onClick={() => setOpenDeleteModal(true)} css={{ background: 'none' }}>
|
40
53
|
<TrashIcon />
|
41
|
-
</
|
42
|
-
<Button
|
43
|
-
variant="standard"
|
44
|
-
css={{ fontWeight: '$semiBold', p: '$4 $8' }}
|
45
|
-
onClick={() => convertToDraft(question.draftID)}
|
46
|
-
>
|
54
|
+
</IconButton>
|
55
|
+
<Button variant="standard" css={{ fontWeight: '$semiBold' }} onClick={() => convertToDraft(question.draftID)}>
|
47
56
|
Edit
|
48
57
|
</Button>
|
49
58
|
</Flex>
|
@@ -39,7 +39,7 @@ export const LeaderboardSummary = ({ pollID }: { pollID: string }) => {
|
|
39
39
|
useEffect(() => {
|
40
40
|
const fetchLeaderboardData = async () => {
|
41
41
|
if (!quizLeaderboard && quiz) {
|
42
|
-
const leaderboardData = await hmsActions.interactivityCenter.fetchLeaderboard(quiz, 0, 50);
|
42
|
+
const leaderboardData = await hmsActions.interactivityCenter.fetchLeaderboard(quiz.id, 0, 50);
|
43
43
|
setQuizLeaderboard(leaderboardData);
|
44
44
|
}
|
45
45
|
};
|
@@ -1,24 +1,19 @@
|
|
1
1
|
// @ts-check
|
2
2
|
import React, { useCallback, useMemo, useState } from 'react';
|
3
3
|
import { selectLocalPeer, selectLocalPeerRoleName, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
|
4
|
-
import {
|
4
|
+
import {
|
5
|
+
CheckCircleIcon,
|
6
|
+
ChevronDownIcon,
|
7
|
+
ChevronLeftIcon,
|
8
|
+
ChevronRightIcon,
|
9
|
+
CrossCircleIcon,
|
10
|
+
} from '@100mslive/react-icons';
|
5
11
|
import { Box, Button, Flex, IconButton, Text } from '../../../../';
|
6
12
|
import { checkCorrectAnswer } from '../../../common/utils';
|
7
13
|
import { MultipleChoiceOptions } from '../common/MultipleChoiceOptions';
|
8
14
|
import { SingleChoiceOptions } from '../common/SingleChoiceOptions';
|
9
15
|
import { QUESTION_TYPE } from '../../../common/constants';
|
10
16
|
|
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
|
-
|
22
17
|
export const QuestionCard = ({
|
23
18
|
pollID,
|
24
19
|
isQuiz,
|
@@ -70,6 +65,7 @@ export const QuestionCard = ({
|
|
70
65
|
// const [textAnswer, setTextAnswer] = useState('');
|
71
66
|
const [singleOptionAnswer, setSingleOptionAnswer] = useState();
|
72
67
|
const [multipleOptionAnswer, setMultipleOptionAnswer] = useState(new Set());
|
68
|
+
const [showOptions, setShowOptions] = useState(true);
|
73
69
|
|
74
70
|
// const stringAnswerExpected = [QUESTION_TYPE.LONG_ANSWER, QUESTION_TYPE.SHORT_ANSWER].includes(type);
|
75
71
|
|
@@ -174,76 +170,61 @@ export const QuestionCard = ({
|
|
174
170
|
) : null}
|
175
171
|
</Flex>
|
176
172
|
|
177
|
-
<
|
173
|
+
<Flex justify="between" css={{ my: '$md' }}>
|
178
174
|
<Text css={{ color: '$on_surface_high' }}>{text}</Text>
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
backgroundColor: '$surface_brighter',
|
189
|
-
mb: '$md',
|
190
|
-
border: '1px solid $border_default',
|
191
|
-
cursor: localPeerResponse ? 'not-allowed' : 'text',
|
192
|
-
}}
|
193
|
-
/>
|
194
|
-
) : null} */}
|
195
|
-
|
196
|
-
{/* {type === QUESTION_TYPE.LONG_ANSWER ? (
|
197
|
-
<TextArea
|
198
|
-
disabled={!canRespond}
|
199
|
-
placeholder="Enter your answer"
|
200
|
-
onChange={e => setTextAnswer(e.target.value)}
|
201
|
-
/>
|
202
|
-
) : null} */}
|
203
|
-
|
204
|
-
{type === QUESTION_TYPE.SINGLE_CHOICE ? (
|
205
|
-
<SingleChoiceOptions
|
206
|
-
questionIndex={index}
|
207
|
-
isQuiz={isQuiz}
|
208
|
-
canRespond={canRespond}
|
209
|
-
response={localPeerResponse}
|
210
|
-
correctOptionIndex={answer?.option}
|
211
|
-
options={options}
|
212
|
-
setAnswer={setSingleOptionAnswer}
|
213
|
-
totalResponses={result?.totalResponses}
|
214
|
-
showVoteCount={showVoteCount}
|
215
|
-
localPeerResponse={localPeerResponse}
|
216
|
-
isStopped={pollState === 'stopped'}
|
217
|
-
/>
|
218
|
-
) : null}
|
219
|
-
|
220
|
-
{type === QUESTION_TYPE.MULTIPLE_CHOICE ? (
|
221
|
-
<MultipleChoiceOptions
|
222
|
-
questionIndex={index}
|
223
|
-
isQuiz={isQuiz}
|
224
|
-
canRespond={canRespond}
|
225
|
-
response={localPeerResponse}
|
226
|
-
correctOptionIndexes={answer?.options}
|
227
|
-
options={options}
|
228
|
-
selectedOptions={multipleOptionAnswer}
|
229
|
-
setSelectedOptions={setMultipleOptionAnswer}
|
230
|
-
totalResponses={result?.totalResponses}
|
231
|
-
showVoteCount={showVoteCount}
|
232
|
-
localPeerResponse={localPeerResponse}
|
233
|
-
isStopped={pollState === 'stopped'}
|
234
|
-
/>
|
235
|
-
) : null}
|
175
|
+
<Box
|
176
|
+
css={{ color: '$on_surface_medium', '&:hover': { color: '$on_surface_high', cursor: 'pointer' } }}
|
177
|
+
onClick={() => setShowOptions(prev => !prev)}
|
178
|
+
>
|
179
|
+
<ChevronDownIcon
|
180
|
+
style={{ transform: showOptions ? 'rotate(180deg)' : 'rotate(0deg)', transition: 'transform 0.3s ease' }}
|
181
|
+
/>
|
182
|
+
</Box>
|
183
|
+
</Flex>
|
236
184
|
|
237
|
-
{
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
185
|
+
<Box css={{ maxHeight: showOptions ? '$80' : '0', transition: 'max-height 0.3s ease', overflowY: 'hidden' }}>
|
186
|
+
{type === QUESTION_TYPE.SINGLE_CHOICE ? (
|
187
|
+
<SingleChoiceOptions
|
188
|
+
questionIndex={index}
|
189
|
+
isQuiz={isQuiz}
|
190
|
+
canRespond={canRespond}
|
191
|
+
response={localPeerResponse}
|
192
|
+
correctOptionIndex={answer?.option}
|
193
|
+
options={options}
|
194
|
+
setAnswer={setSingleOptionAnswer}
|
195
|
+
totalResponses={result?.totalResponses}
|
196
|
+
showVoteCount={showVoteCount}
|
197
|
+
localPeerResponse={localPeerResponse}
|
198
|
+
isStopped={pollState === 'stopped'}
|
199
|
+
/>
|
200
|
+
) : null}
|
201
|
+
{type === QUESTION_TYPE.MULTIPLE_CHOICE ? (
|
202
|
+
<MultipleChoiceOptions
|
203
|
+
questionIndex={index}
|
204
|
+
isQuiz={isQuiz}
|
205
|
+
canRespond={canRespond}
|
206
|
+
response={localPeerResponse}
|
207
|
+
correctOptionIndexes={answer?.options}
|
208
|
+
options={options}
|
209
|
+
selectedOptions={multipleOptionAnswer}
|
210
|
+
setSelectedOptions={setMultipleOptionAnswer}
|
211
|
+
totalResponses={result?.totalResponses}
|
212
|
+
showVoteCount={showVoteCount}
|
213
|
+
localPeerResponse={localPeerResponse}
|
214
|
+
isStopped={pollState === 'stopped'}
|
215
|
+
/>
|
216
|
+
) : null}
|
217
|
+
{isLive && (
|
218
|
+
<QuestionActions
|
219
|
+
isValidVote={isValidVote}
|
220
|
+
skippable={skippable}
|
221
|
+
onSkip={handleSkip}
|
222
|
+
onVote={handleVote}
|
223
|
+
response={localPeerResponse}
|
224
|
+
isQuiz={isQuiz}
|
225
|
+
/>
|
226
|
+
)}
|
227
|
+
</Box>
|
247
228
|
</Box>
|
248
229
|
);
|
249
230
|
};
|
@@ -1,14 +1,10 @@
|
|
1
|
-
// @ts-check
|
2
1
|
import React from 'react';
|
2
|
+
import { HMSPoll } from '@100mslive/react-sdk';
|
3
3
|
import { PeerParticipationSummary } from './PeerParticipationSummary';
|
4
|
+
// @ts-ignore
|
4
5
|
import { QuestionCard } from './QuestionCard';
|
5
6
|
|
6
|
-
|
7
|
-
*
|
8
|
-
* @param {{poll: import("@100mslive/react-sdk").HMSPoll}} param0
|
9
|
-
* @returns
|
10
|
-
*/
|
11
|
-
export const StandardView = ({ poll }) => {
|
7
|
+
export const StandardView = ({ poll }: { poll: HMSPoll }) => {
|
12
8
|
if (!poll?.questions) {
|
13
9
|
return null;
|
14
10
|
}
|
@@ -1,19 +1,16 @@
|
|
1
|
-
// @ts-check
|
2
1
|
import React, { useState } from 'react';
|
2
|
+
import { HMSPoll } from '@100mslive/react-sdk';
|
3
|
+
// @ts-ignore
|
3
4
|
import { QuestionCard } from './QuestionCard';
|
4
5
|
|
5
|
-
|
6
|
-
*
|
7
|
-
* @param {{poll: import("@100mslive/react-sdk").HMSPoll}} param0
|
8
|
-
* @returns
|
9
|
-
*/
|
10
|
-
export const TimedView = ({ poll }) => {
|
6
|
+
export const TimedView = ({ poll }: { poll: HMSPoll }) => {
|
11
7
|
// backend question index starts at 1
|
12
8
|
const [currentIndex, setCurrentIndex] = useState(1);
|
13
9
|
const activeQuestion = poll.questions?.find(question => question.index === currentIndex);
|
14
10
|
if (!activeQuestion) {
|
15
11
|
return null;
|
16
12
|
}
|
13
|
+
|
17
14
|
return (
|
18
15
|
<QuestionCard
|
19
16
|
pollID={poll.id}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
// @ts-check
|
2
1
|
import React from 'react';
|
3
2
|
import {
|
4
3
|
selectLocalPeerID,
|
@@ -8,15 +7,17 @@ import {
|
|
8
7
|
useHMSStore,
|
9
8
|
} from '@100mslive/react-sdk';
|
10
9
|
import { ChevronLeftIcon, CrossIcon } from '@100mslive/react-icons';
|
11
|
-
import { Box, Button, Flex, Text } from '
|
10
|
+
import { Box, Button, Flex, Text } from '../../../..';
|
11
|
+
// @ts-ignore
|
12
12
|
import { Container } from '../../Streaming/Common';
|
13
13
|
import { StandardView } from './StandardVoting';
|
14
14
|
import { TimedView } from './TimedVoting';
|
15
|
+
// @ts-ignore
|
15
16
|
import { usePollViewState } from '../../AppData/useUISettings';
|
16
17
|
import { StatusIndicator } from '../common/StatusIndicator';
|
17
18
|
import { POLL_VIEWS } from '../../../common/constants';
|
18
19
|
|
19
|
-
export const Voting = ({ id, toggleVoting }) => {
|
20
|
+
export const Voting = ({ id, toggleVoting }: { id: string; toggleVoting: () => void }) => {
|
20
21
|
const actions = useHMSActions();
|
21
22
|
const poll = useHMSStore(selectPollByID(id));
|
22
23
|
const pollCreatorName = useHMSStore(selectPeerNameByID(poll?.createdBy));
|
package/src/Prebuilt/components/Polls/common/{OptionInputWithDelete.jsx → OptionInputWithDelete.tsx}
RENAMED
@@ -1,16 +1,28 @@
|
|
1
1
|
import React from 'react';
|
2
|
+
import { HMSPollQuestionOption } from '@100mslive/react-sdk';
|
2
3
|
import { TrashIcon } from '@100mslive/react-icons';
|
3
4
|
import { Input } from '../../../../Input';
|
5
|
+
// @ts-ignore
|
4
6
|
import IconButton from '../../../IconButton';
|
5
7
|
|
6
|
-
export const OptionInputWithDelete = ({
|
8
|
+
export const OptionInputWithDelete = ({
|
9
|
+
index,
|
10
|
+
option,
|
11
|
+
handleOptionTextChange,
|
12
|
+
removeOption,
|
13
|
+
}: {
|
14
|
+
index: number;
|
15
|
+
option: HMSPollQuestionOption;
|
16
|
+
handleOptionTextChange: (index: number, value: string) => void;
|
17
|
+
removeOption: (index: number) => void;
|
18
|
+
}) => {
|
7
19
|
return (
|
8
20
|
<>
|
9
21
|
<Input
|
10
22
|
placeholder={`Option ${index + 1}`}
|
11
23
|
css={{
|
12
24
|
w: '100%',
|
13
|
-
backgroundColor: '$
|
25
|
+
backgroundColor: '$surface_bright',
|
14
26
|
border: '1px solid $border_bright',
|
15
27
|
}}
|
16
28
|
value={option?.text || ''}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
// @ts-check
|
2
2
|
import React from 'react';
|
3
3
|
import { CheckCircleIcon } from '@100mslive/react-icons';
|
4
|
-
import { Flex, Label, RadioGroup, Text } from '
|
4
|
+
import { Flex, Label, RadioGroup, Text } from '../../../..';
|
5
5
|
import { OptionInputWithDelete } from './OptionInputWithDelete';
|
6
6
|
import { VoteCount } from './VoteCount';
|
7
7
|
import { VoteProgress } from './VoteProgress';
|
@@ -1,8 +1,7 @@
|
|
1
|
-
// @ts-check
|
2
1
|
import React from 'react';
|
3
2
|
import { Flex, Text } from '../../../../';
|
4
3
|
|
5
|
-
export const VoteCount = ({ voteCount }) => {
|
4
|
+
export const VoteCount = ({ voteCount }: { voteCount: number }) => {
|
6
5
|
return (
|
7
6
|
<Flex css={{ alignItems: 'center' }}>
|
8
7
|
{voteCount ? (
|
@@ -1,9 +1,10 @@
|
|
1
1
|
import React from 'react';
|
2
|
+
import { HMSPollQuestionOption } from '@100mslive/react-sdk';
|
2
3
|
import { Progress } from '../../../../';
|
3
4
|
|
4
|
-
export const VoteProgress = ({ option, totalResponses }) => {
|
5
|
+
export const VoteProgress = ({ option, totalResponses }: { option: HMSPollQuestionOption; totalResponses: number }) => {
|
5
6
|
const showProgress = typeof option.voteCount === 'number' && typeof totalResponses === 'number' && totalResponses > 0;
|
6
|
-
const progressValue = (100 * option.voteCount) / totalResponses;
|
7
|
+
const progressValue = (100 * (option.voteCount || 0)) / totalResponses;
|
7
8
|
|
8
9
|
return showProgress ? (
|
9
10
|
<Progress.Root value={progressValue} css={{ mt: '$4' }}>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { Avatar, Flex, Text } from '../../../../';
|
3
3
|
|
4
|
-
export const VoterList = ({ voters }) => {
|
4
|
+
export const VoterList = ({ voters }: { voters: string[] }) => {
|
5
5
|
return voters.map((voter, index) => (
|
6
6
|
<Flex align="center" key={`${voter}-${index}`} css={{ gap: '$4', py: '$2' }}>
|
7
7
|
<Avatar
|
@@ -18,6 +18,7 @@ import { StyledMenuTile } from '../../../TileMenu';
|
|
18
18
|
import { ChangeNameModal } from '../MoreSettings/ChangeNameModal';
|
19
19
|
import { TileMenuContent } from './TileMenuContent';
|
20
20
|
import { useDropdownList } from '../hooks/useDropdownList';
|
21
|
+
import { getDragClassName } from './utils';
|
21
22
|
|
22
23
|
/**
|
23
24
|
* Taking peerID as peer won't necesarilly have tracks
|
@@ -48,6 +49,7 @@ const TileMenu = ({
|
|
48
49
|
const peer = useHMSStore(selectPeerByID(peerID));
|
49
50
|
const [showNameChangeModal, setShowNameChangeModal] = useState(false);
|
50
51
|
useDropdownList({ open, name: 'TileMenu' });
|
52
|
+
const dragClassName = getDragClassName();
|
51
53
|
|
52
54
|
if (!(removeOthers || toggleAudio || toggleVideo || setVolume || showPinAction) && hideSimulcastLayers) {
|
53
55
|
return null;
|
@@ -75,7 +77,7 @@ const TileMenu = ({
|
|
75
77
|
data-testid="participant_menu_btn"
|
76
78
|
css={{ bg: `${theme.colors.background_dim.value}A3`, p: '$2', w: 'unset', h: 'unset' }}
|
77
79
|
onClick={e => e.stopPropagation()}
|
78
|
-
className={
|
80
|
+
className={dragClassName}
|
79
81
|
>
|
80
82
|
<VerticalMenuIcon width={20} height={20} />
|
81
83
|
</StyledMenuTile.Trigger>
|