@100mslive/roomkit-react 0.1.20-alpha.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. package/README.md +27 -2
  2. package/dist/{HLSView-BWR4T6PI.js → HLSView-ULB4DC6B.js} +2 -2
  3. package/dist/Input/Input.d.ts +3 -3
  4. package/dist/Prebuilt/components/Chat/ChatActions.d.ts +2 -1
  5. package/dist/Prebuilt/components/Polls/CreateQuestions/DeleteQuestionModal.d.ts +6 -0
  6. package/dist/Prebuilt/components/Polls/CreateQuestions/QuestionForm.d.ts +22 -0
  7. package/dist/Prebuilt/components/Polls/CreateQuestions/SavedQuestion.d.ts +11 -0
  8. package/dist/Prebuilt/components/Polls/Voting/StandardVoting.d.ts +5 -0
  9. package/dist/Prebuilt/components/Polls/Voting/TimedVoting.d.ts +5 -0
  10. package/dist/Prebuilt/components/Polls/Voting/Voting.d.ts +5 -0
  11. package/dist/Prebuilt/components/Polls/common/Line.d.ts +2 -0
  12. package/dist/Prebuilt/components/Polls/common/OptionInputWithDelete.d.ts +8 -0
  13. package/dist/Prebuilt/components/Polls/common/StatusIndicator.d.ts +4 -0
  14. package/dist/Prebuilt/components/Polls/common/VoteCount.d.ts +4 -0
  15. package/dist/Prebuilt/components/Polls/common/VoteProgress.d.ts +6 -0
  16. package/dist/Prebuilt/components/Polls/common/VoterList.d.ts +4 -0
  17. package/dist/Prebuilt/components/TileMenu/utils.d.ts +5 -0
  18. package/dist/Prebuilt/components/hooks/usePinnedBy.d.ts +1 -0
  19. package/dist/Prebuilt/components/hooks/{useSetPinnedMessages.d.ts → usePinnedMessages.d.ts} +6 -1
  20. package/dist/TextArea/TextArea.d.ts +441 -0
  21. package/dist/TextArea/index.d.ts +1 -0
  22. package/dist/Toast/Toast.d.ts +1 -1
  23. package/dist/{chunk-SYBH2G3R.js → chunk-GVA4I77Z.js} +2802 -2740
  24. package/dist/chunk-GVA4I77Z.js.map +7 -0
  25. package/dist/index.cjs.js +3035 -2967
  26. package/dist/index.cjs.js.map +4 -4
  27. package/dist/index.d.ts +1 -0
  28. package/dist/index.js +3 -1
  29. package/dist/meta.cjs.json +476 -394
  30. package/dist/meta.esbuild.json +486 -402
  31. package/package.json +7 -8
  32. package/src/Button/Button.tsx +4 -4
  33. package/src/Input/Input.tsx +1 -1
  34. package/src/Prebuilt/components/Chat/ChatActions.tsx +25 -8
  35. package/src/Prebuilt/components/Chat/ChatBody.tsx +64 -21
  36. package/src/Prebuilt/components/Chat/ChatFooter.tsx +1 -0
  37. package/src/Prebuilt/components/Chat/PinnedMessage.tsx +2 -2
  38. package/src/Prebuilt/components/Header/AdditionalRoomState.jsx +1 -38
  39. package/src/Prebuilt/components/Header/StreamActions.tsx +1 -1
  40. package/src/Prebuilt/components/Polls/CreatePollQuiz/PollsQuizMenu.jsx +11 -1
  41. package/src/Prebuilt/components/Polls/CreateQuestions/{DeleteQuestionModal.jsx → DeleteQuestionModal.tsx} +9 -1
  42. package/src/Prebuilt/components/Polls/CreateQuestions/{QuestionForm.jsx → QuestionForm.tsx} +71 -30
  43. package/src/Prebuilt/components/Polls/CreateQuestions/{SavedQuestion.jsx → SavedQuestion.tsx} +24 -15
  44. package/src/Prebuilt/components/Polls/Voting/LeaderboardSummary.tsx +1 -1
  45. package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +61 -80
  46. package/src/Prebuilt/components/Polls/Voting/{StandardVoting.jsx → StandardVoting.tsx} +3 -7
  47. package/src/Prebuilt/components/Polls/Voting/{TimedVoting.jsx → TimedVoting.tsx} +4 -7
  48. package/src/Prebuilt/components/Polls/Voting/{Voting.jsx → Voting.tsx} +4 -3
  49. package/src/Prebuilt/components/Polls/common/Line.tsx +4 -0
  50. package/src/Prebuilt/components/Polls/common/{OptionInputWithDelete.jsx → OptionInputWithDelete.tsx} +14 -2
  51. package/src/Prebuilt/components/Polls/common/SingleChoiceOptions.jsx +1 -1
  52. package/src/Prebuilt/components/Polls/common/{StatusIndicator.jsx → StatusIndicator.tsx} +1 -2
  53. package/src/Prebuilt/components/Polls/common/{VoteCount.jsx → VoteCount.tsx} +1 -2
  54. package/src/Prebuilt/components/Polls/common/{VoteProgress.jsx → VoteProgress.tsx} +3 -2
  55. package/src/Prebuilt/components/Polls/common/{VoterList.jsx → VoterList.tsx} +1 -1
  56. package/src/Prebuilt/components/TileMenu/TileMenu.jsx +3 -1
  57. package/src/Prebuilt/components/TileMenu/TileMenuContent.tsx +15 -3
  58. package/src/Prebuilt/components/TileMenu/utils.ts +7 -0
  59. package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +7 -3
  60. package/src/Prebuilt/components/VideoTile.jsx +2 -4
  61. package/src/Prebuilt/components/hooks/usePinnedBy.tsx +22 -0
  62. package/src/Prebuilt/components/hooks/{useSetPinnedMessages.ts → usePinnedMessages.ts} +2 -2
  63. package/src/Prebuilt/components/hooks/useUnreadPollQuizPresent.tsx +1 -4
  64. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +0 -1
  65. package/src/TextArea/TextArea.tsx +30 -0
  66. package/src/TextArea/index.tsx +1 -0
  67. package/src/index.ts +1 -0
  68. package/src/store/StorybookSDK.ts +3 -1
  69. package/dist/Prebuilt/plugins/whiteboard/ToggleWhiteboard.d.ts +0 -5
  70. package/dist/chunk-SYBH2G3R.js.map +0 -7
  71. package/src/Prebuilt/components/Polls/common/Votes.jsx +0 -72
  72. package/src/Prebuilt/layouts/WhiteboardView.jsx +0 -40
  73. package/src/Prebuilt/plugins/whiteboard/PusherCommunicationProvider.js +0 -110
  74. package/src/Prebuilt/plugins/whiteboard/README.md +0 -29
  75. package/src/Prebuilt/plugins/whiteboard/ToggleWhiteboard.tsx +0 -37
  76. package/src/Prebuilt/plugins/whiteboard/Whiteboard.css +0 -12
  77. package/src/Prebuilt/plugins/whiteboard/Whiteboard.jsx +0 -11
  78. package/src/Prebuilt/plugins/whiteboard/WhiteboardEvents.js +0 -8
  79. package/src/Prebuilt/plugins/whiteboard/index.js +0 -3
  80. package/src/Prebuilt/plugins/whiteboard/useMultiplayerState.js +0 -212
  81. package/src/Prebuilt/plugins/whiteboard/useWhiteboardMetadata.js +0 -47
  82. /package/dist/{HLSView-BWR4T6PI.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 { Box, Button, Dropdown, Flex, Input, Switch, Text, Tooltip } from '../../../../';
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 = ({ question, index, length, onSave, removeQuestion, isQuiz }) => {
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
- <Input
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={{ my: '$6', c: '$on_surface_medium' }}>
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="body1"
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={{ mt: '$md', gap: '$6', w: '100%' }}>
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="between" align="center" css={{ mt: '$12' }}>
217
- <Box
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
- </Box>
258
+ </IconButton>
226
259
  <Tooltip
227
260
  disabled={isValid}
228
261
  title={
229
- options.length === 0
230
- ? 'At least one option is required for a question'
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 = ({ text, type, options, weight, isQuiz = false }) => {
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
- // if (![QUESTION_TYPE.SINGLE_CHOICE, QUESTION_TYPE.MULTIPLE_CHOICE].includes(type)) {
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) {
@@ -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 { Box, Button, Flex, Text } from '../../../../';
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 = ({ question, index, length, convertToDraft, removeQuestion }) => {
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.map((option, index) => (
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="between" css={{ w: '100%', alignItems: 'center' }}>
36
- <Box
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
- </Box>
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 { CheckCircleIcon, ChevronLeftIcon, ChevronRightIcon, CrossCircleIcon } from '@100mslive/react-icons';
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
- <Box css={{ my: '$md' }}>
173
+ <Flex justify="between" css={{ my: '$md' }}>
178
174
  <Text css={{ color: '$on_surface_high' }}>{text}</Text>
179
- </Box>
180
-
181
- {/* {type === QUESTION_TYPE.SHORT_ANSWER ? (
182
- <Input
183
- disabled={!canRespond}
184
- placeholder="Enter your answer"
185
- onChange={e => setTextAnswer(e.target.value)}
186
- css={{
187
- w: '100%',
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
- {isLive && (
238
- <QuestionActions
239
- isValidVote={isValidVote}
240
- skippable={skippable}
241
- onSkip={handleSkip}
242
- onVote={handleVote}
243
- response={localPeerResponse}
244
- isQuiz={isQuiz}
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));
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { Flex } from '../../../../Layout';
3
+
4
+ export const Line = () => <Flex css={{ w: '100%', borderBottom: '1px solid $border_bright', h: '1px', my: '$8' }} />;
@@ -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 = ({ index, option, handleOptionTextChange, removeOption }) => {
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: '$surface_default',
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 StatusIndicator = ({ isLive }) => {
4
+ export const StatusIndicator = ({ isLive }: { isLive: boolean }) => {
6
5
  return (
7
6
  <Flex align="center">
8
7
  <Flex
@@ -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={isMobile ? '__cancel-drag-event' : ''}
80
+ className={dragClassName}
79
81
  >
80
82
  <VerticalMenuIcon width={20} height={20} />
81
83
  </StyledMenuTile.Trigger>