@100mslive/roomkit-react 0.1.20-alpha.1 → 0.2.0
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/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>
|