@100mslive/roomkit-react 0.2.1-alpha.2 → 0.2.2-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. package/dist/{HLSView-S5JHEMWJ.js → HLSView-4TLGLPKO.js} +19 -4
  2. package/dist/HLSView-4TLGLPKO.js.map +7 -0
  3. package/dist/Prebuilt/components/Polls/Voting/LeaderboardEntry.d.ts +2 -1
  4. package/dist/Prebuilt/components/RoleChangeRequest/RequestPrompt.d.ts +2 -1
  5. package/dist/Prebuilt/components/VirtualBackground/VBHandler.d.ts +1 -0
  6. package/dist/{chunk-AWWYBQSE.js → chunk-ARSLHHAZ.js} +176 -159
  7. package/dist/{chunk-AWWYBQSE.js.map → chunk-ARSLHHAZ.js.map} +3 -3
  8. package/dist/index.cjs.js +159 -124
  9. package/dist/index.cjs.js.map +3 -3
  10. package/dist/index.js +1 -1
  11. package/dist/meta.cjs.json +40 -40
  12. package/dist/meta.esbuild.json +49 -49
  13. package/package.json +6 -6
  14. package/src/Button/Button.tsx +2 -2
  15. package/src/Prebuilt/components/Notifications/PermissionErrorModal.tsx +8 -1
  16. package/src/Prebuilt/components/Polls/Voting/LeaderboardEntry.tsx +17 -5
  17. package/src/Prebuilt/components/Polls/Voting/LeaderboardSummary.tsx +1 -0
  18. package/src/Prebuilt/components/Polls/Voting/PeerParticipationSummary.tsx +4 -2
  19. package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +38 -81
  20. package/src/Prebuilt/components/Polls/Voting/StandardVoting.tsx +0 -1
  21. package/src/Prebuilt/components/Polls/Voting/TimedVoting.tsx +2 -3
  22. package/src/Prebuilt/components/Polls/Voting/Voting.tsx +3 -3
  23. package/src/Prebuilt/components/Polls/common/MultipleChoiceOptions.jsx +1 -2
  24. package/src/Prebuilt/components/Polls/common/SingleChoiceOptions.jsx +6 -4
  25. package/src/Prebuilt/components/Polls/common/StatusIndicator.tsx +1 -1
  26. package/src/Prebuilt/components/Preview/PreviewJoin.tsx +4 -14
  27. package/src/Prebuilt/components/RoleChangeRequest/RequestPrompt.tsx +15 -5
  28. package/src/Prebuilt/components/RoleChangeRequest/RoleChangeRequestModal.tsx +3 -0
  29. package/src/Prebuilt/components/VirtualBackground/VBHandler.tsx +11 -1
  30. package/src/Prebuilt/components/VirtualBackground/VBPicker.tsx +16 -2
  31. package/src/Prebuilt/layouts/HLSView.jsx +16 -1
  32. package/src/Sheet/Sheet.tsx +1 -1
  33. package/dist/HLSView-S5JHEMWJ.js.map +0 -7
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "prebuilt",
11
11
  "roomkit"
12
12
  ],
13
- "version": "0.2.1-alpha.2",
13
+ "version": "0.2.2-alpha.0",
14
14
  "author": "100ms",
15
15
  "license": "MIT",
16
16
  "repository": {
@@ -82,10 +82,10 @@
82
82
  "react": ">=17.0.2 <19.0.0"
83
83
  },
84
84
  "dependencies": {
85
- "@100mslive/hls-player": "0.2.1-alpha.2",
86
- "@100mslive/hms-virtual-background": "1.12.1-alpha.2",
87
- "@100mslive/react-icons": "0.9.1-alpha.2",
88
- "@100mslive/react-sdk": "0.9.1-alpha.2",
85
+ "@100mslive/hls-player": "0.2.2-alpha.0",
86
+ "@100mslive/hms-virtual-background": "1.12.2-alpha.0",
87
+ "@100mslive/react-icons": "0.9.2-alpha.0",
88
+ "@100mslive/react-sdk": "0.9.2-alpha.0",
89
89
  "@100mslive/types-prebuilt": "0.12.5",
90
90
  "@emoji-mart/data": "^1.0.6",
91
91
  "@emoji-mart/react": "^1.0.1",
@@ -120,5 +120,5 @@
120
120
  "uuid": "^8.3.2",
121
121
  "worker-timers": "^7.0.40"
122
122
  },
123
- "gitHead": "28ace828c5944beff16c169195c807e4750e817e"
123
+ "gitHead": "8d716a49dfb9bfed4ee6863e9e55490b39b49ed5"
124
124
  }
@@ -143,8 +143,8 @@ const StyledButton = styled('button', {
143
143
  '$secondary_bright',
144
144
  '$secondary_dim',
145
145
  '$secondary_disabled',
146
- '$on_surface_high',
147
- '$on_surface_low',
146
+ '$on_secondary_high',
147
+ '$on_secondary_low',
148
148
  ),
149
149
  danger: getButtonVariants(
150
150
  '$alert_error_default',
@@ -44,7 +44,14 @@ export function PermissionErrorModal() {
44
44
  <Dialog.Root open={!!deviceType}>
45
45
  <Dialog.Portal>
46
46
  <Dialog.Overlay />
47
- <Dialog.Content css={{ w: 'min(380px, 90%)', p: '$8' }}>
47
+ <Dialog.Content
48
+ css={{
49
+ w: 'min(380px, 90%)',
50
+ p: '$8',
51
+ // overlay over Sheet.tsx
52
+ zIndex: 23,
53
+ }}
54
+ >
48
55
  <Dialog.Title
49
56
  css={{
50
57
  borderBottom: '1px solid $border_default',
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { CheckCircleIcon, TrophyFilledIcon } from '@100mslive/react-icons';
2
+ import { CheckCircleIcon, ClockIcon, TrophyFilledIcon } from '@100mslive/react-icons';
3
3
  import { Box, Flex } from '../../../../Layout';
4
4
  import { Text } from '../../../../Text';
5
5
 
@@ -12,6 +12,7 @@ export const LeaderboardEntry = ({
12
12
  correctResponses,
13
13
  userName,
14
14
  maxPossibleScore,
15
+ duration,
15
16
  }: {
16
17
  position: number;
17
18
  score: number;
@@ -19,6 +20,7 @@ export const LeaderboardEntry = ({
19
20
  correctResponses: number;
20
21
  userName: string;
21
22
  maxPossibleScore: number;
23
+ duration: number;
22
24
  }) => {
23
25
  return (
24
26
  <Flex align="center" justify="between" css={{ my: '$4' }}>
@@ -49,13 +51,23 @@ export const LeaderboardEntry = ({
49
51
  </Text>
50
52
  </Box>
51
53
  </Flex>
54
+
52
55
  <Flex align="center" css={{ gap: '$4', color: '$on_surface_medium' }}>
53
56
  {position === 1 ? <TrophyFilledIcon height={16} width={16} /> : null}
54
- <CheckCircleIcon height={16} width={16} />
55
57
  {questionCount ? (
56
- <Text variant="xs">
57
- {correctResponses} / {questionCount}
58
- </Text>
58
+ <>
59
+ <CheckCircleIcon height={16} width={16} />
60
+ <Text variant="xs">
61
+ {correctResponses}/{questionCount}
62
+ </Text>
63
+ </>
64
+ ) : null}
65
+
66
+ {duration ? (
67
+ <Flex align="center" css={{ gap: '$2', color: '$on_surface_medium' }}>
68
+ <ClockIcon height={16} width={16} />
69
+ <Text variant="xs">{(duration / 1000).toFixed(3)}s</Text>
70
+ </Flex>
59
71
  ) : null}
60
72
  </Flex>
61
73
  </Flex>
@@ -86,6 +86,7 @@ export const LeaderboardSummary = ({ pollID }: { pollID: string }) => {
86
86
  correctResponses={question.correctResponses}
87
87
  userName={question.peer.username || ''}
88
88
  maxPossibleScore={maxPossibleScore}
89
+ duration={question.duration}
89
90
  />
90
91
  ))}
91
92
  {quizLeaderboard?.entries?.length > 5 && !viewAllEntries ? (
@@ -28,7 +28,8 @@ export const PeerParticipationSummary = ({ quiz }: { quiz: HMSPoll }) => {
28
28
  summary.correctUsers
29
29
  }/${summary.totalUsers})`,
30
30
  },
31
- { title: 'Avg. Time Taken', value: summary.avgTime },
31
+ // Time in ms
32
+ { title: 'Avg. Time Taken', value: `${(summary.avgTime / 1000).toFixed(3)}s` },
32
33
  {
33
34
  title: 'Avg. Score',
34
35
  value: Number.isInteger(summary.avgScore) ? summary.avgScore : summary.avgScore.toFixed(2),
@@ -37,7 +38,8 @@ export const PeerParticipationSummary = ({ quiz }: { quiz: HMSPoll }) => {
37
38
  : [
38
39
  { title: 'Your rank', value: peerEntry?.position ? `${peerEntry.position}/${summary.totalUsers}` : '-' },
39
40
  { title: 'Points', value: peerEntry?.score },
40
- { title: 'Time Taken', value: peerEntry?.duration },
41
+ // Time in ms
42
+ { title: 'Time Taken', value: `${((peerEntry?.duration || 0) / 1000).toFixed(3)}s` },
41
43
  {
42
44
  title: 'Correct Answers',
43
45
  value: peerEntry?.totalResponses ? `${peerEntry?.correctResponses}/${peerEntry.totalResponses}` : '-',
@@ -1,14 +1,8 @@
1
1
  // @ts-check
2
- import React, { useCallback, useMemo, useState } from 'react';
2
+ import React, { useCallback, useMemo, useRef, useState } from 'react';
3
3
  import { selectLocalPeer, selectLocalPeerRoleName, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
4
- import {
5
- CheckCircleIcon,
6
- ChevronDownIcon,
7
- ChevronLeftIcon,
8
- ChevronRightIcon,
9
- CrossCircleIcon,
10
- } from '@100mslive/react-icons';
11
- import { Box, Button, Flex, IconButton, Text } from '../../../../';
4
+ import { CheckCircleIcon, ChevronDownIcon, CrossCircleIcon } from '@100mslive/react-icons';
5
+ import { Box, Button, Flex, Text } from '../../../../';
12
6
  import { checkCorrectAnswer } from '../../../common/utils';
13
7
  import { MultipleChoiceOptions } from '../common/MultipleChoiceOptions';
14
8
  import { SingleChoiceOptions } from '../common/SingleChoiceOptions';
@@ -27,9 +21,7 @@ export const QuestionCard = ({
27
21
  options = [],
28
22
  answer,
29
23
  setCurrentIndex,
30
- skippable = false,
31
24
  responses = [],
32
- isTimed = false,
33
25
  rolesThatCanViewResponses,
34
26
  }) => {
35
27
  const actions = useHMSActions();
@@ -37,6 +29,7 @@ export const QuestionCard = ({
37
29
  const localPeerResponse = responses?.find(
38
30
  response => response.peer?.peerid === localPeer?.id || response.peer?.userid === localPeer?.customerUserId,
39
31
  );
32
+
40
33
  const isLocalPeerCreator = localPeer?.id === startedBy;
41
34
  const localPeerRoleName = useHMSStore(selectLocalPeerRoleName);
42
35
  const roleCanViewResponse =
@@ -48,27 +41,13 @@ export const QuestionCard = ({
48
41
 
49
42
  const isLive = pollState === 'started';
50
43
  const canRespond = isLive && !localPeerResponse;
51
-
44
+ const startTime = useRef(Date.now());
52
45
  const isCorrectAnswer = checkCorrectAnswer(answer, localPeerResponse, type);
53
46
 
54
- const prev = index !== 1;
55
- const next = index !== totalQuestions && (skippable || localPeerResponse);
56
-
57
- const moveNext = useCallback(() => {
58
- setCurrentIndex(curr => Math.min(totalQuestions, curr + 1));
59
- }, [setCurrentIndex, totalQuestions]);
60
-
61
- const movePrev = () => {
62
- setCurrentIndex(curr => Math.max(1, curr - 1));
63
- };
64
-
65
- // const [textAnswer, setTextAnswer] = useState('');
66
47
  const [singleOptionAnswer, setSingleOptionAnswer] = useState();
67
48
  const [multipleOptionAnswer, setMultipleOptionAnswer] = useState(new Set());
68
49
  const [showOptions, setShowOptions] = useState(true);
69
50
 
70
- // const stringAnswerExpected = [QUESTION_TYPE.LONG_ANSWER, QUESTION_TYPE.SHORT_ANSWER].includes(type);
71
-
72
51
  const respondedToQuiz = isQuiz && localPeerResponse && !localPeerResponse.skipped;
73
52
 
74
53
  const isValidVote = useMemo(() => {
@@ -83,24 +62,31 @@ export const QuestionCard = ({
83
62
  if (!isValidVote) {
84
63
  return;
85
64
  }
65
+
86
66
  await actions.interactivityCenter.addResponsesToPoll(pollID, [
87
67
  {
88
68
  questionIndex: index,
89
69
  option: singleOptionAnswer,
90
70
  options: Array.from(multipleOptionAnswer),
71
+ duration: Date.now() - startTime.current,
91
72
  },
92
73
  ]);
93
- }, [actions, index, pollID, isValidVote, singleOptionAnswer, multipleOptionAnswer]);
74
+ startTime.current = Date.now();
94
75
 
95
- const handleSkip = useCallback(async () => {
96
- await actions.interactivityCenter.addResponsesToPoll(pollID, [
97
- {
98
- questionIndex: index,
99
- skipped: true,
100
- },
101
- ]);
102
- moveNext();
103
- }, [actions, index, pollID, moveNext]);
76
+ if (isQuiz && index !== totalQuestions) {
77
+ setSingleOptionAnswer(undefined);
78
+ setMultipleOptionAnswer(new Set());
79
+ }
80
+ }, [
81
+ isValidVote,
82
+ actions.interactivityCenter,
83
+ pollID,
84
+ index,
85
+ singleOptionAnswer,
86
+ multipleOptionAnswer,
87
+ totalQuestions,
88
+ isQuiz,
89
+ ]);
104
90
 
105
91
  return (
106
92
  <Box
@@ -135,39 +121,6 @@ export const QuestionCard = ({
135
121
  {respondedToQuiz && !isCorrectAnswer ? <CrossCircleIcon height={20} width={20} /> : null}
136
122
  QUESTION {index} OF {totalQuestions}: {type.toUpperCase()}
137
123
  </Text>
138
-
139
- {isTimed ? (
140
- <Flex align="center" css={{ gap: '$4' }}>
141
- <IconButton
142
- disabled={!prev}
143
- onClick={movePrev}
144
- css={
145
- prev
146
- ? { color: '$on_surface_high', cursor: 'pointer' }
147
- : {
148
- color: '$on_surface_low',
149
- cursor: 'not-allowed',
150
- }
151
- }
152
- >
153
- <ChevronLeftIcon height={16} width={16} />
154
- </IconButton>
155
- <IconButton
156
- disabled={!next}
157
- onClick={moveNext}
158
- css={
159
- next
160
- ? { color: '$on_surface_high', cursor: 'pointer' }
161
- : {
162
- color: '$on_surface_low',
163
- cursor: 'not-allowed',
164
- }
165
- }
166
- >
167
- <ChevronRightIcon height={16} width={16} />
168
- </IconButton>
169
- </Flex>
170
- ) : null}
171
124
  </Flex>
172
125
 
173
126
  <Flex justify="between" css={{ my: '$md' }}>
@@ -185,10 +138,10 @@ export const QuestionCard = ({
185
138
  <Box css={{ maxHeight: showOptions ? '$80' : '0', transition: 'max-height 0.3s ease', overflowY: 'hidden' }}>
186
139
  {type === QUESTION_TYPE.SINGLE_CHOICE ? (
187
140
  <SingleChoiceOptions
141
+ key={index}
188
142
  questionIndex={index}
189
143
  isQuiz={isQuiz}
190
144
  canRespond={canRespond}
191
- response={localPeerResponse}
192
145
  correctOptionIndex={answer?.option}
193
146
  options={options}
194
147
  setAnswer={setSingleOptionAnswer}
@@ -196,14 +149,15 @@ export const QuestionCard = ({
196
149
  showVoteCount={showVoteCount}
197
150
  localPeerResponse={localPeerResponse}
198
151
  isStopped={pollState === 'stopped'}
152
+ answer={singleOptionAnswer}
199
153
  />
200
154
  ) : null}
155
+
201
156
  {type === QUESTION_TYPE.MULTIPLE_CHOICE ? (
202
157
  <MultipleChoiceOptions
203
158
  questionIndex={index}
204
159
  isQuiz={isQuiz}
205
160
  canRespond={canRespond}
206
- response={localPeerResponse}
207
161
  correctOptionIndexes={answer?.options}
208
162
  options={options}
209
163
  selectedOptions={multipleOptionAnswer}
@@ -214,14 +168,16 @@ export const QuestionCard = ({
214
168
  isStopped={pollState === 'stopped'}
215
169
  />
216
170
  ) : null}
171
+
217
172
  {isLive && (
218
173
  <QuestionActions
219
174
  isValidVote={isValidVote}
220
- skippable={skippable}
221
- onSkip={handleSkip}
222
175
  onVote={handleVote}
223
176
  response={localPeerResponse}
224
177
  isQuiz={isQuiz}
178
+ incrementIndex={() => {
179
+ setCurrentIndex(curr => Math.min(totalQuestions, curr + 1));
180
+ }}
225
181
  />
226
182
  )}
227
183
  </Box>
@@ -229,15 +185,9 @@ export const QuestionCard = ({
229
185
  );
230
186
  };
231
187
 
232
- const QuestionActions = ({ isValidVote, skippable, response, isQuiz, onVote, onSkip }) => {
188
+ const QuestionActions = ({ isValidVote, response, isQuiz, onVote, incrementIndex }) => {
233
189
  return (
234
190
  <Flex align="center" justify="end" css={{ gap: '$4', w: '100%' }}>
235
- {skippable && !response ? (
236
- <Button variant="standard" onClick={onSkip} css={{ p: '$xs $10', fontWeight: '$semiBold' }}>
237
- Skip
238
- </Button>
239
- ) : null}
240
-
241
191
  {response ? (
242
192
  <Text css={{ fontWeight: '$semiBold', color: '$on_surface_medium' }}>
243
193
  {response.skipped ? 'Skipped' : null}
@@ -245,7 +195,14 @@ const QuestionActions = ({ isValidVote, skippable, response, isQuiz, onVote, onS
245
195
  {!isQuiz && !response.skipped ? 'Voted' : null}
246
196
  </Text>
247
197
  ) : (
248
- <Button css={{ p: '$xs $10', fontWeight: '$semiBold' }} disabled={!isValidVote} onClick={onVote}>
198
+ <Button
199
+ css={{ p: '$xs $10', fontWeight: '$semiBold' }}
200
+ disabled={!isValidVote}
201
+ onClick={() => {
202
+ onVote();
203
+ incrementIndex();
204
+ }}
205
+ >
249
206
  {isQuiz ? 'Answer' : 'Vote'}
250
207
  </Button>
251
208
  )}
@@ -28,7 +28,6 @@ export const StandardView = ({ poll }: { poll: HMSPoll }) => {
28
28
  result={question.result}
29
29
  totalQuestions={poll.questions?.length || 0}
30
30
  options={question.options}
31
- skippable={question.skippable}
32
31
  responses={question.responses}
33
32
  answer={question.answer}
34
33
  setCurrentIndex={() => {
@@ -4,9 +4,10 @@ import { HMSPoll } from '@100mslive/react-sdk';
4
4
  import { QuestionCard } from './QuestionCard';
5
5
 
6
6
  export const TimedView = ({ poll }: { poll: HMSPoll }) => {
7
- // backend question index starts at 1
7
+ // Backend question index starts at 1
8
8
  const [currentIndex, setCurrentIndex] = useState(1);
9
9
  const activeQuestion = poll.questions?.find(question => question.index === currentIndex);
10
+
10
11
  if (!activeQuestion) {
11
12
  return null;
12
13
  }
@@ -23,12 +24,10 @@ export const TimedView = ({ poll }: { poll: HMSPoll }) => {
23
24
  result={activeQuestion?.result}
24
25
  totalQuestions={poll.questions?.length || 0}
25
26
  options={activeQuestion.options}
26
- skippable={activeQuestion.skippable || false}
27
27
  responses={activeQuestion.responses}
28
28
  answer={activeQuestion.answer}
29
29
  setCurrentIndex={setCurrentIndex}
30
30
  rolesThatCanViewResponses={poll.rolesThatCanViewResponses}
31
- isTimed
32
31
  />
33
32
  );
34
33
  };
@@ -23,6 +23,8 @@ export const Voting = ({ id, toggleVoting }: { id: string; toggleVoting: () => v
23
23
  const pollCreatorName = useHMSStore(selectPeerNameByID(poll?.createdBy));
24
24
  const isLocalPeerCreator = useHMSStore(selectLocalPeerID) === poll?.createdBy;
25
25
  const { setPollView } = usePollViewState();
26
+ // Sets view - linear or vertical, toggles timer indicator
27
+ const showSingleView = poll?.type === 'quiz' && poll.state === 'started';
26
28
 
27
29
  if (!poll) {
28
30
  return null;
@@ -30,8 +32,6 @@ export const Voting = ({ id, toggleVoting }: { id: string; toggleVoting: () => v
30
32
 
31
33
  const canViewLeaderboard = poll.type === 'quiz' && poll.state === 'stopped' && !poll.anonymous;
32
34
 
33
- // Sets view - linear or vertical, toggles timer indicator
34
- const isTimed = (poll.duration || 0) > 0;
35
35
  const isLive = poll.state === 'started';
36
36
 
37
37
  return (
@@ -74,7 +74,7 @@ export const Voting = ({ id, toggleVoting }: { id: string; toggleVoting: () => v
74
74
  </Text>
75
75
  ) : null}
76
76
 
77
- {isTimed ? <TimedView poll={poll} /> : <StandardView poll={poll} />}
77
+ {showSingleView ? <TimedView poll={poll} /> : <StandardView poll={poll} />}
78
78
 
79
79
  {poll.state === 'started' && isLocalPeerCreator && (
80
80
  <Button
@@ -10,7 +10,6 @@ export const MultipleChoiceOptions = ({
10
10
  questionIndex,
11
11
  options,
12
12
  canRespond,
13
- response,
14
13
  totalResponses,
15
14
  selectedOptions,
16
15
  setSelectedOptions,
@@ -39,7 +38,7 @@ export const MultipleChoiceOptions = ({
39
38
  <Checkbox.Root
40
39
  id={`${questionIndex}-${option.index}`}
41
40
  disabled={!canRespond}
42
- checked={response?.options?.includes(option.index)}
41
+ checked={localPeerResponse?.options?.includes(option.index)}
43
42
  onCheckedChange={checked => handleCheckedChange(checked, option.index)}
44
43
  css={{
45
44
  cursor: canRespond ? 'pointer' : 'not-allowed',
@@ -9,7 +9,6 @@ import { VoteProgress } from './VoteProgress';
9
9
  export const SingleChoiceOptions = ({
10
10
  questionIndex,
11
11
  options,
12
- response,
13
12
  canRespond,
14
13
  setAnswer,
15
14
  totalResponses,
@@ -18,9 +17,10 @@ export const SingleChoiceOptions = ({
18
17
  isStopped,
19
18
  isQuiz,
20
19
  localPeerResponse,
20
+ answer,
21
21
  }) => {
22
22
  return (
23
- <RadioGroup.Root value={response?.option} onValueChange={value => setAnswer(value)}>
23
+ <RadioGroup.Root value={answer || null} onValueChange={value => setAnswer(value)}>
24
24
  <Flex direction="column" css={{ gap: '$md', w: '100%', mb: '$md' }}>
25
25
  {options.map(option => {
26
26
  return (
@@ -65,8 +65,10 @@ export const SingleChoiceOptions = ({
65
65
 
66
66
  <Flex direction="column" css={{ flexGrow: '1' }}>
67
67
  <Flex css={{ w: '100%' }}>
68
- <Text css={{ display: 'flex', flexGrow: '1' }}>
69
- <Label htmlFor={`${questionIndex}-${option.index}`}>{option.text}</Label>
68
+ <Text css={{ display: 'flex', flexGrow: '1', color: '$on_surface_high' }}>
69
+ <Label style={{ color: 'inherit' }} htmlFor={`${questionIndex}-${option.index}`}>
70
+ {option.text}
71
+ </Label>
70
72
  </Text>
71
73
  {showVoteCount && <VoteCount voteCount={option.voteCount} />}
72
74
  </Flex>
@@ -15,7 +15,7 @@ export const StatusIndicator = ({ isLive }: { isLive: boolean }) => {
15
15
  variant="caption"
16
16
  css={{
17
17
  fontWeight: '$semiBold',
18
- color: '$on_surface_high',
18
+ color: '$on_primary_high',
19
19
  }}
20
20
  >
21
21
  {isLive ? 'LIVE' : 'ENDED'}
@@ -160,20 +160,7 @@ const PreviewJoin = ({
160
160
  <Chip content={getParticipantChipContent(peerCount)} hideIfNoContent />
161
161
  </Flex>
162
162
  </Flex>
163
- {toggleVideo ? (
164
- <Flex
165
- align="center"
166
- justify="center"
167
- css={{
168
- mt: '$14',
169
- '@md': { mt: 0 },
170
- '@sm': { width: '100%' },
171
- flexDirection: 'column',
172
- }}
173
- >
174
- <PreviewTile name={name} error={previewError} />
175
- </Flex>
176
- ) : null}
163
+ {toggleVideo ? <PreviewTile name={name} error={previewError} /> : null}
177
164
  <Box css={{ w: '100%', maxWidth: `${Math.max(aspectRatio, 1) * 360}px` }}>
178
165
  <PreviewControls hideSettings={!toggleVideo && !toggleAudio} vbEnabled={!!virtual_background} />
179
166
  <PreviewForm
@@ -225,9 +212,12 @@ export const PreviewTile = ({ name, error }: { name: string; error?: boolean })
225
212
  bg: '$surface_default',
226
213
  aspectRatio,
227
214
  height: 'min(360px, 70vh)',
215
+ width: 'auto',
228
216
  maxWidth: '640px',
229
217
  overflow: 'clip',
218
+ mt: '$14',
230
219
  '@md': {
220
+ mt: 0,
231
221
  width: 'min(220px, 70vw)',
232
222
  maxWidth: '100%',
233
223
  my: '$4',
@@ -10,6 +10,7 @@ export const RequestPrompt = ({
10
10
  body,
11
11
  actionText = 'Accept',
12
12
  onAction,
13
+ disableActions = false,
13
14
  }: {
14
15
  open?: boolean;
15
16
  onOpenChange: (value: boolean) => void;
@@ -17,6 +18,7 @@ export const RequestPrompt = ({
17
18
  body: React.ReactNode;
18
19
  actionText?: string;
19
20
  onAction: () => void;
21
+ disableActions?: boolean;
20
22
  }) => {
21
23
  const isMobile = useMedia(cssConfig.media.md);
22
24
 
@@ -26,7 +28,7 @@ export const RequestPrompt = ({
26
28
  <Sheet.Content css={{ py: '$8' }}>
27
29
  <Text css={{ fontWeight: '$semiBold', c: '$on_surface_high', '@md': { px: '$8' } }}>{title}</Text>
28
30
  {body}
29
- <RequestActions actionText={actionText} onAction={onAction} />
31
+ <RequestActions actionText={actionText} onAction={onAction} disabled={disableActions} />
30
32
  </Sheet.Content>
31
33
  </Sheet.Root>
32
34
  );
@@ -40,24 +42,32 @@ export const RequestPrompt = ({
40
42
  <Text variant="h6">{title}</Text>
41
43
  </Dialog.Title>
42
44
  <Box css={{ mt: '$4', mb: '$10' }}>{body}</Box>
43
- <RequestActions actionText={actionText} onAction={onAction} />
45
+ <RequestActions actionText={actionText} onAction={onAction} disabled={disableActions} />
44
46
  </Dialog.Content>
45
47
  </Dialog.Portal>
46
48
  </Dialog.Root>
47
49
  );
48
50
  };
49
51
 
50
- const RequestActions = ({ onAction, actionText }: { actionText?: string; onAction: () => void }) => (
52
+ const RequestActions = ({
53
+ onAction,
54
+ actionText,
55
+ disabled = false,
56
+ }: {
57
+ actionText?: string;
58
+ onAction: () => void;
59
+ disabled?: boolean;
60
+ }) => (
51
61
  <Flex justify="center" align="center" css={{ width: '100%', gap: '$md', '@md': { mt: '$8', px: '$8' } }}>
52
62
  <Box css={{ width: '50%' }}>
53
63
  <Dialog.Close css={{ width: '100%' }}>
54
- <Button variant="standard" outlined css={{ width: '100%' }}>
64
+ <Button variant="standard" outlined css={{ width: '100%' }} disabled={disabled}>
55
65
  Decline
56
66
  </Button>
57
67
  </Dialog.Close>
58
68
  </Box>
59
69
  <Box css={{ width: '50%' }}>
60
- <Button variant="primary" css={{ width: '100%' }} onClick={onAction}>
70
+ <Button variant="primary" css={{ width: '100%' }} onClick={onAction} disabled={disabled}>
61
71
  {actionText}
62
72
  </Button>
63
73
  </Box>
@@ -1,5 +1,6 @@
1
1
  import React, { useEffect } from 'react';
2
2
  import {
3
+ selectIsInPreview,
3
4
  selectLocalPeerName,
4
5
  selectLocalPeerRoleName,
5
6
  selectRoleChangeRequest,
@@ -20,6 +21,7 @@ import { ROLE_CHANGE_DECLINED } from '../../common/constants';
20
21
  export const RoleChangeRequestModal = () => {
21
22
  const hmsActions = useHMSActions();
22
23
  const { updateMetaData } = useMyMetadata();
24
+ const isPreview = useHMSStore(selectIsInPreview);
23
25
  const currentRole = useHMSStore(selectLocalPeerRoleName);
24
26
  const roleChangeRequest = useHMSStore(selectRoleChangeRequest);
25
27
  const name = useHMSStore(selectLocalPeerName);
@@ -87,6 +89,7 @@ export const RoleChangeRequestModal = () => {
87
89
  await hmsActions.lowerLocalPeerHand();
88
90
  }}
89
91
  actionText="Accept"
92
+ disableActions={!isPreview}
90
93
  />
91
94
  );
92
95
  };
@@ -19,8 +19,18 @@ export class VBPlugin {
19
19
  if (this.effectsPlugin) {
20
20
  return this.effectsPlugin?.getBackground();
21
21
  } else {
22
+ const background = this.hmsPlugin?.getBackground();
22
23
  // @ts-ignore
23
- return this.hmsPlugin?.background?.src || this.hmsPlugin?.background;
24
+ return background?.src || background;
25
+ }
26
+ };
27
+
28
+ getBlurAmount = () => {
29
+ if (this.effectsPlugin) {
30
+ return this.effectsPlugin.getBlurAmount();
31
+ } else {
32
+ // Treating HMS VB intensity as a fixed value
33
+ return this.hmsPlugin?.getBackground() === HMSVirtualBackgroundTypes.BLUR ? 1 : 0;
24
34
  }
25
35
  };
26
36