@100mslive/roomkit-react 0.2.0 → 0.2.1-alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +21 -0
- package/dist/{HLSView-ULB4DC6B.js → HLSView-QPKBRL74.js} +2 -2
- package/dist/Prebuilt/components/Polls/Voting/PeerParticipationSummary.d.ts +2 -2
- package/dist/Prebuilt/components/Polls/Voting/StatisticBox.d.ts +1 -1
- package/dist/Prebuilt/components/Polls/Voting/useQuizSummary.d.ts +7 -0
- package/dist/{chunk-GVA4I77Z.js → chunk-LRZEFY46.js} +595 -587
- package/dist/chunk-LRZEFY46.js.map +7 -0
- package/dist/index.cjs.js +1628 -1616
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +1 -1
- package/dist/meta.cjs.json +119 -65
- package/dist/meta.esbuild.json +132 -78
- package/package.json +7 -6
- package/src/Introduction/Integrating.stories.mdx +1 -1
- package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.jsx +3 -3
- package/src/Prebuilt/components/Polls/Voting/LeaderboardSummary.tsx +7 -59
- package/src/Prebuilt/components/Polls/Voting/PeerParticipationSummary.tsx +37 -14
- package/src/Prebuilt/components/Polls/Voting/StandardVoting.tsx +1 -1
- package/src/Prebuilt/components/Polls/Voting/StatisticBox.tsx +16 -11
- package/src/Prebuilt/components/Polls/Voting/Voting.tsx +5 -7
- package/src/Prebuilt/components/Polls/Voting/useQuizSummary.tsx +50 -0
- package/src/Prebuilt/layouts/WhiteboardView.tsx +4 -1
- package/src/TileMenu/StyledMenuTile.tsx +1 -0
- package/dist/chunk-GVA4I77Z.js.map +0 -7
- /package/dist/{HLSView-ULB4DC6B.js.map → HLSView-QPKBRL74.js.map} +0 -0
@@ -1,23 +1,46 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import { HMSPoll,
|
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
|
-
|
7
|
-
import { getPeerParticipationSummary } from '../../../common/utils';
|
6
|
+
import { useQuizSummary } from './useQuizSummary';
|
8
7
|
|
9
|
-
export const PeerParticipationSummary = ({
|
10
|
-
const
|
11
|
-
const {
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
+
{ title: 'Avg. Score', value: summary.avgScore },
|
33
|
+
]
|
34
|
+
: [
|
35
|
+
{ title: 'Your rank', value: peerEntry?.position ? `${peerEntry.position}/${summary.totalUsers}` : '-' },
|
36
|
+
{ title: 'Points', value: peerEntry?.score },
|
37
|
+
{ title: 'Time Taken', value: peerEntry?.duration },
|
38
|
+
{
|
39
|
+
title: 'Correct Answers',
|
40
|
+
value: peerEntry?.totalResponses ? `${peerEntry?.correctResponses}/${peerEntry.totalResponses}` : '-',
|
41
|
+
},
|
42
|
+
];
|
16
43
|
|
17
|
-
const boxes = [
|
18
|
-
{ title: 'Points', value: score },
|
19
|
-
{ title: 'Correct Answers', value: `${correctResponses}/${totalResponses}` },
|
20
|
-
];
|
21
44
|
return (
|
22
45
|
<Box>
|
23
46
|
<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
|
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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
>
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
72
|
-
<
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
13
|
+
const isMobile = useMedia(cssConfig.media.md);
|
14
|
+
const { iframeRef } = useWhiteboard(isMobile);
|
12
15
|
|
13
16
|
return (
|
14
17
|
<Box
|