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

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.
Files changed (26) hide show
  1. package/LICENSE +21 -0
  2. package/dist/{HLSView-GKCGIZ5F.js → HLSView-DJGDJPXM.js} +2 -2
  3. package/dist/Prebuilt/components/Polls/Voting/PeerParticipationSummary.d.ts +2 -2
  4. package/dist/Prebuilt/components/Polls/Voting/StatisticBox.d.ts +1 -1
  5. package/dist/Prebuilt/components/Polls/Voting/useQuizSummary.d.ts +7 -0
  6. package/dist/{chunk-FTOP3RHP.js → chunk-ERKB3GGI.js} +454 -447
  7. package/dist/chunk-ERKB3GGI.js.map +7 -0
  8. package/dist/index.cjs.js +1497 -1484
  9. package/dist/index.cjs.js.map +4 -4
  10. package/dist/index.js +1 -1
  11. package/dist/meta.cjs.json +120 -66
  12. package/dist/meta.esbuild.json +133 -79
  13. package/package.json +12 -6
  14. package/src/Introduction/Integrating.stories.mdx +1 -1
  15. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +3 -3
  16. package/src/Prebuilt/components/Polls/CreateQuestions/QuestionForm.tsx +6 -5
  17. package/src/Prebuilt/components/Polls/Voting/LeaderboardSummary.tsx +7 -59
  18. package/src/Prebuilt/components/Polls/Voting/PeerParticipationSummary.tsx +40 -14
  19. package/src/Prebuilt/components/Polls/Voting/StandardVoting.tsx +1 -1
  20. package/src/Prebuilt/components/Polls/Voting/StatisticBox.tsx +16 -11
  21. package/src/Prebuilt/components/Polls/Voting/Voting.tsx +5 -7
  22. package/src/Prebuilt/components/Polls/Voting/useQuizSummary.tsx +50 -0
  23. package/src/Prebuilt/layouts/WhiteboardView.tsx +4 -1
  24. package/src/Toast/Toast.tsx +1 -0
  25. package/dist/chunk-FTOP3RHP.js.map +0 -7
  26. /package/dist/{HLSView-GKCGIZ5F.js.map → HLSView-DJGDJPXM.js.map} +0 -0
@@ -1,51 +1,27 @@
1
- import React, { useEffect, useState } from 'react';
2
- import {
3
- HMSQuizLeaderboardResponse,
4
- HMSQuizLeaderboardSummary,
5
- selectPollByID,
6
- useHMSActions,
7
- useHMSStore,
8
- } from '@100mslive/react-sdk';
1
+ import React, { useState } from 'react';
2
+ import { selectPollByID, useHMSStore } from '@100mslive/react-sdk';
9
3
  import { ChevronLeftIcon, ChevronRightIcon, CrossIcon } from '@100mslive/react-icons';
10
4
  import { Box, Flex } from '../../../../Layout';
11
5
  import { Loading } from '../../../../Loading';
12
6
  import { Text } from '../../../../Text';
13
7
  import { LeaderboardEntry } from './LeaderboardEntry';
14
- import { StatisticBox } from './StatisticBox';
8
+ import { PeerParticipationSummary } from './PeerParticipationSummary';
15
9
  // @ts-ignore
16
10
  import { useSidepaneToggle } from '../../AppData/useSidepane';
17
11
  // @ts-ignore
18
12
  import { usePollViewState } from '../../AppData/useUISettings';
13
+ import { useQuizSummary } from './useQuizSummary';
19
14
  // @ts-ignore
20
15
  import { StatusIndicator } from '../common/StatusIndicator';
21
16
  import { POLL_VIEWS } from '../../../common/constants';
22
17
 
23
18
  export const LeaderboardSummary = ({ pollID }: { pollID: string }) => {
24
- const hmsActions = useHMSActions();
25
19
  const quiz = useHMSStore(selectPollByID(pollID));
26
- const [quizLeaderboard, setQuizLeaderboard] = useState<HMSQuizLeaderboardResponse | undefined>();
20
+ const { quizLeaderboard, maxPossibleScore } = useQuizSummary(pollID);
27
21
  const [viewAllEntries, setViewAllEntries] = useState(false);
28
- const summary: HMSQuizLeaderboardSummary = quizLeaderboard?.summary || {
29
- totalUsers: 0,
30
- votedUsers: 0,
31
- avgScore: 0,
32
- avgTime: 0,
33
- correctAnswers: 0,
34
- };
35
-
36
22
  const { setPollView } = usePollViewState();
37
23
  const toggleSidepane = useSidepaneToggle();
38
24
 
39
- useEffect(() => {
40
- const fetchLeaderboardData = async () => {
41
- if (!quizLeaderboard && quiz) {
42
- const leaderboardData = await hmsActions.interactivityCenter.fetchLeaderboard(quiz.id, 0, 50);
43
- setQuizLeaderboard(leaderboardData);
44
- }
45
- };
46
- fetchLeaderboardData();
47
- }, [quiz, hmsActions.interactivityCenter, quizLeaderboard]);
48
-
49
25
  if (!quiz || !quizLeaderboard)
50
26
  return (
51
27
  <Flex align="center" justify="center" css={{ size: '100%' }}>
@@ -53,14 +29,6 @@ export const LeaderboardSummary = ({ pollID }: { pollID: string }) => {
53
29
  </Flex>
54
30
  );
55
31
 
56
- const defaultCalculations = { maxPossibleScore: 0, totalResponses: 0 };
57
- const { maxPossibleScore, totalResponses } =
58
- quiz.questions?.reduce((accumulator, question) => {
59
- accumulator.maxPossibleScore += question.weight || 0;
60
- accumulator.totalResponses += question?.responses?.length || 0;
61
- return accumulator;
62
- }, defaultCalculations) || defaultCalculations;
63
-
64
32
  const questionCount = quiz.questions?.length || 0;
65
33
 
66
34
  return (
@@ -86,29 +54,9 @@ export const LeaderboardSummary = ({ pollID }: { pollID: string }) => {
86
54
  </Flex>
87
55
  </Flex>
88
56
 
89
- {!viewAllEntries ? (
90
- <Box css={{ py: '$4' }}>
91
- <Text variant="sm" css={{ fontWeight: '$semiBold' }}>
92
- Participation Summary
93
- </Text>
94
-
95
- <Box css={{ my: '$4' }}>
96
- <Flex css={{ w: '100%', gap: '$4' }}>
97
- <StatisticBox
98
- title="Voted"
99
- value={`${summary?.totalUsers ? (100 * summary?.votedUsers) / summary?.totalUsers : 0}%`}
100
- />
101
- <StatisticBox title="Correct Answers" value={`${summary?.correctAnswers}/${totalResponses}`} />
102
- </Flex>
103
- <Flex css={{ w: '100%', gap: '$4', mt: '$4' }}>
104
- {summary?.avgTime > 0 ? <StatisticBox title="Avg. Time" value={summary?.avgTime} /> : null}
105
- <StatisticBox title="Avg. Score" value={summary?.avgScore} />
106
- </Flex>
107
- </Box>
108
- </Box>
109
- ) : null}
57
+ {!viewAllEntries ? <PeerParticipationSummary quiz={quiz} /> : null}
110
58
 
111
- <Text variant="sm" css={{ fontWeight: '$semiBold' }}>
59
+ <Text variant="sm" css={{ fontWeight: '$semiBold', mt: '$4' }}>
112
60
  Leaderboard
113
61
  </Text>
114
62
  <Text variant="xs" css={{ color: '$on_surface_medium' }}>
@@ -1,23 +1,49 @@
1
1
  import React from 'react';
2
- import { HMSPoll, selectLocalPeer, useHMSStore } from '@100mslive/react-sdk';
2
+ import { HMSPoll, selectLocalPeerID, useHMSStore } from '@100mslive/react-sdk';
3
3
  import { Box } from '../../../../Layout';
4
4
  import { Text } from '../../../../Text';
5
5
  import { StatisticBox } from './StatisticBox';
6
- // @ts-ignore
7
- import { getPeerParticipationSummary } from '../../../common/utils';
6
+ import { useQuizSummary } from './useQuizSummary';
8
7
 
9
- export const PeerParticipationSummary = ({ poll }: { poll: HMSPoll }) => {
10
- const localPeer = useHMSStore(selectLocalPeer);
11
- const { totalResponses, correctResponses, score } = getPeerParticipationSummary(
12
- poll,
13
- localPeer?.id,
14
- localPeer?.customerUserId,
15
- );
8
+ export const PeerParticipationSummary = ({ quiz }: { quiz: HMSPoll }) => {
9
+ const localPeerId = useHMSStore(selectLocalPeerID);
10
+ const { quizLeaderboard, summary } = useQuizSummary(quiz.id);
11
+ if (quiz.state !== 'stopped') {
12
+ return <></>;
13
+ }
14
+ const isLocalPeerQuizCreator = localPeerId === quiz.startedBy;
15
+ const peerEntry = quizLeaderboard?.entries.find(entry => entry.peer?.peerid === localPeerId);
16
+
17
+ const boxes = isLocalPeerQuizCreator
18
+ ? [
19
+ {
20
+ title: 'Voted',
21
+ value: `${summary.totalUsers ? ((100 * summary.votedUsers) / summary.totalUsers).toFixed(0) : 0}% (${
22
+ summary.votedUsers
23
+ }/${summary.totalUsers})`,
24
+ },
25
+ {
26
+ title: 'Correct Answers',
27
+ value: `${summary.totalUsers ? ((100 * summary.correctUsers) / summary.totalUsers).toFixed(0) : 0}% (${
28
+ summary.correctUsers
29
+ }/${summary.totalUsers})`,
30
+ },
31
+ { title: 'Avg. Time Taken', value: summary.avgTime },
32
+ {
33
+ title: 'Avg. Score',
34
+ value: Number.isInteger(summary.avgScore) ? summary.avgScore : summary.avgScore.toFixed(2),
35
+ },
36
+ ]
37
+ : [
38
+ { title: 'Your rank', value: peerEntry?.position ? `${peerEntry.position}/${summary.totalUsers}` : '-' },
39
+ { title: 'Points', value: peerEntry?.score },
40
+ { title: 'Time Taken', value: peerEntry?.duration },
41
+ {
42
+ title: 'Correct Answers',
43
+ value: peerEntry?.totalResponses ? `${peerEntry?.correctResponses}/${peerEntry.totalResponses}` : '-',
44
+ },
45
+ ];
16
46
 
17
- const boxes = [
18
- { title: 'Points', value: score },
19
- { title: 'Correct Answers', value: `${correctResponses}/${totalResponses}` },
20
- ];
21
47
  return (
22
48
  <Box>
23
49
  <Text css={{ fontWeight: '$semiBold', my: '$8' }}>Participation Summary</Text>
@@ -14,7 +14,7 @@ export const StandardView = ({ poll }: { poll: HMSPoll }) => {
14
14
 
15
15
  return (
16
16
  <>
17
- {isQuiz && isStopped ? <PeerParticipationSummary poll={poll} /> : null}
17
+ {isQuiz && isStopped ? <PeerParticipationSummary quiz={poll} /> : null}
18
18
  {poll.questions?.map((question, index) => (
19
19
  <QuestionCard
20
20
  pollID={poll.id}
@@ -2,14 +2,19 @@ import React from 'react';
2
2
  import { Box } from '../../../../Layout';
3
3
  import { Text } from '../../../../Text';
4
4
 
5
- export const StatisticBox = ({ title, value = 0 }: { title: string; value: string | number }) => (
6
- <Box css={{ p: '$8', background: '$surface_default', borderRadius: '$1', w: '100%' }}>
7
- <Text
8
- variant="tiny"
9
- css={{ textTransform: 'uppercase', color: '$on_surface_medium', fontWeight: '$semiBold', my: '$4' }}
10
- >
11
- {title}
12
- </Text>
13
- <Text css={{ fontWeight: '$semiBold' }}>{value}</Text>
14
- </Box>
15
- );
5
+ export const StatisticBox = ({ title, value = 0 }: { title: string; value: string | number | undefined }) => {
6
+ if (!value) {
7
+ return <></>;
8
+ }
9
+ return (
10
+ <Box css={{ p: '$8', background: '$surface_default', borderRadius: '$1', w: '100%' }}>
11
+ <Text
12
+ variant="tiny"
13
+ css={{ textTransform: 'uppercase', color: '$on_surface_medium', fontWeight: '$semiBold', my: '$4' }}
14
+ >
15
+ {title}
16
+ </Text>
17
+ <Text css={{ fontWeight: '$semiBold' }}>{value}</Text>
18
+ </Box>
19
+ );
20
+ };
@@ -68,13 +68,11 @@ export const Voting = ({ id, toggleVoting }: { id: string; toggleVoting: () => v
68
68
  </Flex>
69
69
 
70
70
  <Flex direction="column" css={{ p: '$8 $10', overflowY: 'auto' }}>
71
- <Flex align="center">
72
- <Box css={{ flex: 'auto' }}>
73
- <Text css={{ color: '$on_surface_medium', fontWeight: '$semiBold' }}>
74
- {pollCreatorName || 'Participant'} started a {poll.type}
75
- </Text>
76
- </Box>
77
- </Flex>
71
+ {poll.state === 'started' ? (
72
+ <Text css={{ color: '$on_surface_medium', fontWeight: '$semiBold' }}>
73
+ {pollCreatorName || 'Participant'} started a {poll.type}
74
+ </Text>
75
+ ) : null}
78
76
 
79
77
  {isTimed ? <TimedView poll={poll} /> : <StandardView poll={poll} />}
80
78
 
@@ -0,0 +1,50 @@
1
+ import { useEffect, useState } from 'react';
2
+ import {
3
+ HMSQuizLeaderboardResponse,
4
+ HMSQuizLeaderboardSummary,
5
+ selectPollByID,
6
+ useHMSActions,
7
+ useHMSStore,
8
+ } from '@100mslive/react-sdk';
9
+
10
+ export const useQuizSummary = (quizID: string) => {
11
+ const hmsActions = useHMSActions();
12
+ const quiz = useHMSStore(selectPollByID(quizID));
13
+ const [quizLeaderboard, setQuizLeaderboard] = useState<HMSQuizLeaderboardResponse | undefined>();
14
+
15
+ const summary: HMSQuizLeaderboardSummary = quizLeaderboard?.summary || {
16
+ totalUsers: 0,
17
+ votedUsers: 0,
18
+ avgScore: 0,
19
+ avgTime: 0,
20
+ correctUsers: 0,
21
+ };
22
+ const [calculations, setCalculations] = useState({ maxPossibleScore: 0, totalResponses: 0 });
23
+
24
+ useEffect(() => {
25
+ const fetchLeaderboardData = async () => {
26
+ if (!quizLeaderboard && quiz && !quiz?.anonymous && quiz.state === 'stopped') {
27
+ const leaderboardData = await hmsActions.interactivityCenter.fetchLeaderboard(quiz.id, 0, 50);
28
+
29
+ const { maxPossibleScore, totalResponses } =
30
+ quiz?.questions?.reduce((accumulator, question) => {
31
+ accumulator.maxPossibleScore += question.weight || 0;
32
+ accumulator.totalResponses += question?.responses?.length || 0;
33
+ return accumulator;
34
+ }, calculations) || calculations;
35
+
36
+ setQuizLeaderboard(leaderboardData);
37
+ setCalculations({ maxPossibleScore, totalResponses });
38
+ }
39
+ };
40
+
41
+ fetchLeaderboardData();
42
+ }, [quiz, hmsActions.interactivityCenter, quizLeaderboard, calculations]);
43
+
44
+ return {
45
+ quizLeaderboard,
46
+ summary,
47
+ maxPossibleScore: calculations.maxPossibleScore,
48
+ totalResponses: calculations.totalResponses,
49
+ };
50
+ };
@@ -1,14 +1,17 @@
1
1
  import React, { useEffect, useMemo } from 'react';
2
+ import { useMedia } from 'react-use';
2
3
  import { selectPeers, selectWhiteboard, useHMSStore, useWhiteboard } from '@100mslive/react-sdk';
3
4
  import { SecondaryTiles } from '../components/SecondaryTiles';
4
5
  import { ProminenceLayout } from '../components/VideoLayouts/ProminenceLayout';
6
+ import { config as cssConfig } from '../../';
5
7
  import { Box } from '../../Layout';
6
8
  // @ts-ignore: No implicit Any
7
9
  import { useSetAppDataByKey } from '../components/AppData/useUISettings';
8
10
  import { APP_DATA } from '../common/constants';
9
11
 
10
12
  const EmbedComponent = () => {
11
- const { iframeRef } = useWhiteboard();
13
+ const isMobile = useMedia(cssConfig.media.md);
14
+ const { iframeRef } = useWhiteboard(isMobile);
12
15
 
13
16
  return (
14
17
  <Box
@@ -78,6 +78,7 @@ const ToastClose = styled(ToastPrimitives.Close, {});
78
78
  const ToastAction = styled(ToastPrimitives.Action, {
79
79
  cursor: 'pointer',
80
80
  background: 'none',
81
+ border: 'none',
81
82
  });
82
83
  const ToastViewport = styled(ToastPrimitives.Viewport, {
83
84
  position: 'fixed',