@100mslive/roomkit-react 0.3.10-alpha.17 → 0.3.10-alpha.18
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/{HLSView-IQXKFUR7.css → HLSView-LNCDKSKQ.css} +3 -3
- package/dist/{HLSView-IQXKFUR7.css.map → HLSView-LNCDKSKQ.css.map} +1 -1
- package/dist/{HLSView-A65NALP3.js → HLSView-SJJ2GAYJ.js} +18 -3
- package/dist/HLSView-SJJ2GAYJ.js.map +7 -0
- package/dist/Prebuilt/common/constants.d.ts +0 -2
- package/dist/Prebuilt/common/hooks.d.ts +8 -1
- package/dist/Prebuilt/components/Polls/Voting/StandardVoting.d.ts +4 -2
- package/dist/Prebuilt/components/Polls/Voting/TimedVoting.d.ts +4 -2
- package/dist/Prebuilt/layouts/WaitingView.d.ts +6 -0
- package/dist/{chunk-F4QZKZVE.js → chunk-FMGGXDNB.js} +901 -788
- package/dist/chunk-FMGGXDNB.js.map +7 -0
- package/dist/index.cjs.css +2 -2
- package/dist/index.cjs.css.map +1 -1
- package/dist/index.cjs.js +1063 -941
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.css +2 -2
- package/dist/index.css.map +1 -1
- package/dist/index.js +1 -1
- package/dist/meta.cjs.json +138 -108
- package/dist/meta.esbuild.json +154 -123
- package/package.json +7 -7
- package/src/Prebuilt/common/constants.ts +0 -2
- package/src/Prebuilt/common/hooks.ts +34 -1
- package/src/Prebuilt/common/utils.js +11 -11
- package/src/Prebuilt/components/AppData/AppData.tsx +0 -2
- package/src/Prebuilt/components/AppData/useUISettings.js +0 -3
- package/src/Prebuilt/components/Chat/Chat.tsx +26 -6
- package/src/Prebuilt/components/Chat/ChatFooter.tsx +18 -2
- package/src/Prebuilt/components/Chat/ChatStates.tsx +1 -1
- package/src/Prebuilt/components/Footer/ChatToggle.tsx +5 -1
- package/src/Prebuilt/components/Footer/ParticipantList.tsx +4 -2
- package/src/Prebuilt/components/Footer/PollsToggle.tsx +1 -1
- package/src/Prebuilt/components/Polls/CreatePollQuiz/PollsQuizMenu.tsx +2 -15
- package/src/Prebuilt/components/Polls/Voting/LeaderboardSummary.tsx +71 -66
- package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +39 -40
- package/src/Prebuilt/components/Polls/Voting/StandardVoting.tsx +12 -6
- package/src/Prebuilt/components/Polls/Voting/TimedVoting.tsx +21 -10
- package/src/Prebuilt/components/Polls/Voting/Voting.tsx +44 -2
- package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +13 -17
- package/src/Prebuilt/layouts/HLSView.jsx +14 -11
- package/src/Prebuilt/layouts/VideoStreamingSection.tsx +44 -9
- package/src/Prebuilt/layouts/WaitingView.tsx +52 -0
- package/dist/HLSView-A65NALP3.js.map +0 -7
- package/dist/chunk-F4QZKZVE.js.map +0 -7
- package/src/Prebuilt/layouts/NonPublisherView.jsx +0 -51
- package/src/Prebuilt/layouts/WaitingView.jsx +0 -51
@@ -1,5 +1,5 @@
|
|
1
1
|
// @ts-check
|
2
|
-
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
2
|
+
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
3
3
|
import { match } from 'ts-pattern';
|
4
4
|
import { selectLocalPeer, selectLocalPeerRoleName, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
|
5
5
|
import { CheckCircleIcon, ChevronDownIcon, CrossCircleIcon } from '@100mslive/react-icons';
|
@@ -21,15 +21,12 @@ export const QuestionCard = ({
|
|
21
21
|
text,
|
22
22
|
options = [],
|
23
23
|
answer,
|
24
|
-
|
25
|
-
|
24
|
+
localPeerResponse,
|
25
|
+
updateSavedResponses,
|
26
26
|
rolesThatCanViewResponses,
|
27
27
|
}) => {
|
28
28
|
const actions = useHMSActions();
|
29
29
|
const localPeer = useHMSStore(selectLocalPeer);
|
30
|
-
const localPeerResponse = responses?.find(
|
31
|
-
response => response.peer?.peerid === localPeer?.id || response.peer?.userid === localPeer?.customerUserId,
|
32
|
-
);
|
33
30
|
|
34
31
|
const isLocalPeerCreator = localPeer?.id === startedBy;
|
35
32
|
const localPeerRoleName = useHMSStore(selectLocalPeerRoleName);
|
@@ -37,20 +34,26 @@ export const QuestionCard = ({
|
|
37
34
|
!rolesThatCanViewResponses ||
|
38
35
|
rolesThatCanViewResponses.length === 0 ||
|
39
36
|
rolesThatCanViewResponses.includes(localPeerRoleName || '');
|
37
|
+
const [localPeerChoice, setLocalPeerChoice] = useState(localPeerResponse);
|
38
|
+
|
39
|
+
useEffect(() => {
|
40
|
+
setLocalPeerChoice(localPeerResponse);
|
41
|
+
}, [localPeerResponse]);
|
42
|
+
|
40
43
|
const showVoteCount =
|
41
|
-
roleCanViewResponse && (
|
44
|
+
roleCanViewResponse && (localPeerChoice || (isLocalPeerCreator && pollState === 'stopped')) && !isQuiz;
|
42
45
|
|
43
46
|
const isLive = pollState === 'started';
|
44
47
|
const pollEnded = pollState === 'stopped';
|
45
|
-
const canRespond = isLive && !
|
48
|
+
const canRespond = isLive && !localPeerChoice;
|
46
49
|
const startTime = useRef(Date.now());
|
47
|
-
const isCorrectAnswer = checkCorrectAnswer(answer,
|
50
|
+
const isCorrectAnswer = checkCorrectAnswer(answer, localPeerChoice, type);
|
48
51
|
|
49
52
|
const [singleOptionAnswer, setSingleOptionAnswer] = useState();
|
50
53
|
const [multipleOptionAnswer, setMultipleOptionAnswer] = useState(new Set());
|
51
54
|
const [showOptions, setShowOptions] = useState(true);
|
52
55
|
|
53
|
-
const respondedToQuiz = isQuiz &&
|
56
|
+
const respondedToQuiz = isQuiz && localPeerChoice && !localPeerChoice.skipped;
|
54
57
|
|
55
58
|
const isValidVote = useMemo(() => {
|
56
59
|
if (type === QUESTION_TYPE.SINGLE_CHOICE) {
|
@@ -64,17 +67,28 @@ export const QuestionCard = ({
|
|
64
67
|
if (!isValidVote) {
|
65
68
|
return;
|
66
69
|
}
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
70
|
+
const submittedResponse = {
|
71
|
+
questionIndex: index,
|
72
|
+
option: singleOptionAnswer,
|
73
|
+
options: Array.from(multipleOptionAnswer),
|
74
|
+
duration: Date.now() - startTime.current,
|
75
|
+
};
|
76
|
+
await actions.interactivityCenter.addResponsesToPoll(pollID, [submittedResponse]);
|
77
|
+
updateSavedResponses(prev => {
|
78
|
+
const prevCopy = { ...prev };
|
79
|
+
prevCopy[index] = { option: singleOptionAnswer, options: Array.from(multipleOptionAnswer) };
|
80
|
+
return prevCopy;
|
81
|
+
});
|
76
82
|
startTime.current = Date.now();
|
77
|
-
}, [
|
83
|
+
}, [
|
84
|
+
isValidVote,
|
85
|
+
index,
|
86
|
+
singleOptionAnswer,
|
87
|
+
multipleOptionAnswer,
|
88
|
+
actions.interactivityCenter,
|
89
|
+
pollID,
|
90
|
+
updateSavedResponses,
|
91
|
+
]);
|
78
92
|
|
79
93
|
return (
|
80
94
|
<Box
|
@@ -147,7 +161,7 @@ export const QuestionCard = ({
|
|
147
161
|
setAnswer={setSingleOptionAnswer}
|
148
162
|
totalResponses={result?.totalResponses}
|
149
163
|
showVoteCount={showVoteCount}
|
150
|
-
localPeerResponse={
|
164
|
+
localPeerResponse={localPeerChoice}
|
151
165
|
isStopped={pollState === 'stopped'}
|
152
166
|
/>
|
153
167
|
) : null}
|
@@ -163,27 +177,19 @@ export const QuestionCard = ({
|
|
163
177
|
setSelectedOptions={setMultipleOptionAnswer}
|
164
178
|
totalResponses={result?.totalResponses}
|
165
179
|
showVoteCount={showVoteCount}
|
166
|
-
localPeerResponse={
|
180
|
+
localPeerResponse={localPeerChoice}
|
167
181
|
isStopped={pollState === 'stopped'}
|
168
182
|
/>
|
169
183
|
) : null}
|
170
184
|
</Box>
|
171
185
|
{isLive && (
|
172
|
-
<QuestionActions
|
173
|
-
isValidVote={isValidVote}
|
174
|
-
onVote={handleVote}
|
175
|
-
response={localPeerResponse}
|
176
|
-
isQuiz={isQuiz}
|
177
|
-
incrementIndex={() => {
|
178
|
-
setCurrentIndex(curr => Math.min(totalQuestions, curr + 1));
|
179
|
-
}}
|
180
|
-
/>
|
186
|
+
<QuestionActions isValidVote={isValidVote} onVote={handleVote} response={localPeerChoice} isQuiz={isQuiz} />
|
181
187
|
)}
|
182
188
|
</Box>
|
183
189
|
);
|
184
190
|
};
|
185
191
|
|
186
|
-
const QuestionActions = ({ isValidVote, response, isQuiz, onVote
|
192
|
+
const QuestionActions = ({ isValidVote, response, isQuiz, onVote }) => {
|
187
193
|
return (
|
188
194
|
<Flex align="center" justify="end" css={{ gap: '$4', w: '100%' }}>
|
189
195
|
{response ? (
|
@@ -193,14 +199,7 @@ const QuestionActions = ({ isValidVote, response, isQuiz, onVote, incrementIndex
|
|
193
199
|
{!isQuiz && !response.skipped ? 'Voted' : null}
|
194
200
|
</Text>
|
195
201
|
) : (
|
196
|
-
<Button
|
197
|
-
css={{ p: '$xs $10', fontWeight: '$semiBold' }}
|
198
|
-
disabled={!isValidVote}
|
199
|
-
onClick={() => {
|
200
|
-
onVote();
|
201
|
-
incrementIndex();
|
202
|
-
}}
|
203
|
-
>
|
202
|
+
<Button css={{ p: '$xs $10', fontWeight: '$semiBold' }} disabled={!isValidVote} onClick={onVote}>
|
204
203
|
{isQuiz ? 'Answer' : 'Vote'}
|
205
204
|
</Button>
|
206
205
|
)}
|
@@ -1,10 +1,18 @@
|
|
1
|
-
import React from 'react';
|
1
|
+
import React, { Dispatch, SetStateAction } from 'react';
|
2
2
|
import { HMSPoll } from '@100mslive/react-sdk';
|
3
3
|
import { PeerParticipationSummary } from './PeerParticipationSummary';
|
4
4
|
// @ts-ignore
|
5
5
|
import { QuestionCard } from './QuestionCard';
|
6
6
|
|
7
|
-
export const StandardView = ({
|
7
|
+
export const StandardView = ({
|
8
|
+
poll,
|
9
|
+
localPeerResponses,
|
10
|
+
updateSavedResponses,
|
11
|
+
}: {
|
12
|
+
poll: HMSPoll;
|
13
|
+
localPeerResponses: Record<number, number | number[] | undefined>;
|
14
|
+
updateSavedResponses: Dispatch<SetStateAction<Record<any, any>>>;
|
15
|
+
}) => {
|
8
16
|
if (!poll?.questions) {
|
9
17
|
return null;
|
10
18
|
}
|
@@ -28,11 +36,9 @@ export const StandardView = ({ poll }: { poll: HMSPoll }) => {
|
|
28
36
|
result={question.result}
|
29
37
|
totalQuestions={poll.questions?.length || 0}
|
30
38
|
options={question.options}
|
31
|
-
|
39
|
+
localPeerResponse={localPeerResponses?.[question.index]}
|
32
40
|
answer={question.answer}
|
33
|
-
|
34
|
-
return;
|
35
|
-
}}
|
41
|
+
updateSavedResponses={updateSavedResponses}
|
36
42
|
rolesThatCanViewResponses={poll.rolesThatCanViewResponses}
|
37
43
|
/>
|
38
44
|
))}
|
@@ -1,16 +1,27 @@
|
|
1
|
-
import React, { useState } from 'react';
|
2
|
-
import { HMSPoll
|
1
|
+
import React, { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
2
|
+
import { HMSPoll } from '@100mslive/react-sdk';
|
3
3
|
// @ts-ignore
|
4
4
|
import { QuestionCard } from './QuestionCard';
|
5
5
|
// @ts-ignore
|
6
|
-
import {
|
6
|
+
import { getIndexToShow } from '../../../common/utils';
|
7
7
|
|
8
|
-
export const TimedView = ({
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
export const TimedView = ({
|
9
|
+
poll,
|
10
|
+
localPeerResponses,
|
11
|
+
updateSavedResponses,
|
12
|
+
}: {
|
13
|
+
poll: HMSPoll;
|
14
|
+
localPeerResponses?: Record<number, number | number[] | undefined>;
|
15
|
+
updateSavedResponses: Dispatch<SetStateAction<Record<any, any>>>;
|
16
|
+
}) => {
|
17
|
+
const [currentIndex, setCurrentIndex] = useState(getIndexToShow(localPeerResponses));
|
12
18
|
const activeQuestion = poll.questions?.find(question => question.index === currentIndex);
|
13
|
-
const attemptedAll = poll.questions?.length
|
19
|
+
const attemptedAll = (poll.questions?.length || 0) < currentIndex;
|
20
|
+
|
21
|
+
// Handles increments so only one question is shown at a time in quiz
|
22
|
+
useEffect(() => {
|
23
|
+
setCurrentIndex(getIndexToShow(localPeerResponses));
|
24
|
+
}, [localPeerResponses]);
|
14
25
|
|
15
26
|
if ((!activeQuestion && !attemptedAll) || !poll.questions?.length) {
|
16
27
|
return null;
|
@@ -32,10 +43,10 @@ export const TimedView = ({ poll }: { poll: HMSPoll }) => {
|
|
32
43
|
result={question?.result}
|
33
44
|
totalQuestions={poll.questions?.length || 0}
|
34
45
|
options={question.options}
|
35
|
-
|
46
|
+
localPeerResponse={localPeerResponses?.[question.index]}
|
36
47
|
answer={question.answer}
|
37
|
-
setCurrentIndex={setCurrentIndex}
|
38
48
|
rolesThatCanViewResponses={poll.rolesThatCanViewResponses}
|
49
|
+
updateSavedResponses={updateSavedResponses}
|
39
50
|
/>
|
40
51
|
) : null;
|
41
52
|
})}
|
@@ -1,5 +1,6 @@
|
|
1
|
-
import React from 'react';
|
1
|
+
import React, { useEffect, useRef, useState } from 'react';
|
2
2
|
import {
|
3
|
+
selectLocalPeerID,
|
3
4
|
selectPeerNameByID,
|
4
5
|
selectPermissions,
|
5
6
|
selectPollByID,
|
@@ -14,6 +15,8 @@ import { StandardView } from './StandardVoting';
|
|
14
15
|
import { TimedView } from './TimedVoting';
|
15
16
|
// @ts-ignore
|
16
17
|
import { usePollViewState } from '../../AppData/useUISettings';
|
18
|
+
// @ts-ignore
|
19
|
+
import { getPeerResponses } from '../../../common/utils';
|
17
20
|
import { StatusIndicator } from '../common/StatusIndicator';
|
18
21
|
import { POLL_VIEWS } from '../../../common/constants';
|
19
22
|
|
@@ -26,6 +29,41 @@ export const Voting = ({ id, toggleVoting }: { id: string; toggleVoting: () => v
|
|
26
29
|
const { setPollView } = usePollViewState();
|
27
30
|
// Sets view - linear or vertical, toggles timer indicator
|
28
31
|
const showSingleView = poll?.type === 'quiz' && poll.state === 'started';
|
32
|
+
const fetchedInitialResponses = useRef(false);
|
33
|
+
const [savedResponses, setSavedResponses] = useState<Record<any, any>>({});
|
34
|
+
const localPeerId = useHMSStore(selectLocalPeerID);
|
35
|
+
|
36
|
+
// To reset whenever a different poll is opened
|
37
|
+
useEffect(() => {
|
38
|
+
fetchedInitialResponses.current = false;
|
39
|
+
setSavedResponses({});
|
40
|
+
}, [id, setSavedResponses]);
|
41
|
+
|
42
|
+
useEffect(() => {
|
43
|
+
const getResponses = async () => {
|
44
|
+
if (poll && actions.interactivityCenter && !fetchedInitialResponses.current) {
|
45
|
+
await actions.interactivityCenter.getPollResponses(poll, true);
|
46
|
+
fetchedInitialResponses.current = true;
|
47
|
+
}
|
48
|
+
};
|
49
|
+
getResponses();
|
50
|
+
}, [poll, actions.interactivityCenter]);
|
51
|
+
|
52
|
+
useEffect(() => {
|
53
|
+
if (poll?.questions) {
|
54
|
+
const localPeerResponses = getPeerResponses(poll.questions, localPeerId);
|
55
|
+
// @ts-ignore
|
56
|
+
localPeerResponses?.forEach(response => {
|
57
|
+
if (response) {
|
58
|
+
setSavedResponses(prev => {
|
59
|
+
const prevCopy = { ...prev };
|
60
|
+
prevCopy[response[0]?.questionIndex] = { option: response[0]?.option, options: response[0]?.options };
|
61
|
+
return prevCopy;
|
62
|
+
});
|
63
|
+
}
|
64
|
+
});
|
65
|
+
}
|
66
|
+
}, [localPeerId, poll?.questions, id]);
|
29
67
|
|
30
68
|
if (!poll) {
|
31
69
|
return null;
|
@@ -74,7 +112,11 @@ export const Voting = ({ id, toggleVoting }: { id: string; toggleVoting: () => v
|
|
74
112
|
</Text>
|
75
113
|
) : null}
|
76
114
|
|
77
|
-
{showSingleView ?
|
115
|
+
{showSingleView ? (
|
116
|
+
<TimedView poll={poll} localPeerResponses={savedResponses} updateSavedResponses={setSavedResponses} />
|
117
|
+
) : (
|
118
|
+
<StandardView poll={poll} localPeerResponses={savedResponses} updateSavedResponses={setSavedResponses} />
|
119
|
+
)}
|
78
120
|
</Flex>
|
79
121
|
<Flex
|
80
122
|
css={{ w: '100%', justifyContent: 'end', alignItems: 'center', p: '$8', borderTop: '1px solid $border_bright' }}
|
@@ -1,8 +1,9 @@
|
|
1
|
-
import React, { useEffect,
|
1
|
+
import React, { useEffect, useState } from 'react';
|
2
2
|
import { useMedia } from 'react-use';
|
3
|
-
import {
|
3
|
+
import { PeopleAddIcon } from '@100mslive/react-icons';
|
4
4
|
import { Flex } from '../../../Layout';
|
5
5
|
import { config as cssConfig } from '../../../Theme';
|
6
|
+
import { WaitingView } from '../../layouts/WaitingView';
|
6
7
|
import { InsetTile } from '../InsetTile';
|
7
8
|
import { Pagination } from '../Pagination';
|
8
9
|
import { Grid } from './Grid';
|
@@ -13,26 +14,14 @@ import { usePagesWithTiles, useTileLayout } from '../hooks/useTileLayout';
|
|
13
14
|
import { UI_SETTINGS } from '../../common/constants';
|
14
15
|
|
15
16
|
export function EqualProminence({ isInsetEnabled = false, peers, onPageChange, onPageSize, edgeToEdge }: LayoutProps) {
|
16
|
-
const localPeer = useHMSStore(selectLocalPeer);
|
17
17
|
const isMobile = useMedia(cssConfig.media.md);
|
18
18
|
let maxTileCount = useUISettings(UI_SETTINGS.maxTileCount);
|
19
19
|
maxTileCount = isMobile ? Math.min(maxTileCount, 6) : maxTileCount;
|
20
|
-
|
20
|
+
const pageList = usePagesWithTiles({
|
21
21
|
peers,
|
22
22
|
maxTileCount,
|
23
23
|
});
|
24
|
-
|
25
|
-
const inputPeers = useMemo(() => {
|
26
|
-
if (pageList.length === 0) {
|
27
|
-
return localPeer ? [localPeer] : [];
|
28
|
-
}
|
29
|
-
return peers;
|
30
|
-
}, [pageList.length, peers, localPeer]);
|
31
|
-
// Pass local peer to main grid if no other peer has tiles
|
32
|
-
pageList = usePagesWithTiles({
|
33
|
-
peers: inputPeers,
|
34
|
-
maxTileCount,
|
35
|
-
});
|
24
|
+
|
36
25
|
const { ref, pagesWithTiles } = useTileLayout({
|
37
26
|
pageList,
|
38
27
|
maxTileCount,
|
@@ -60,7 +49,14 @@ export function EqualProminence({ isInsetEnabled = false, peers, onPageChange, o
|
|
60
49
|
numPages={pagesWithTiles.length}
|
61
50
|
/>
|
62
51
|
)}
|
63
|
-
{
|
52
|
+
{pageList.length === 0 ? (
|
53
|
+
<WaitingView
|
54
|
+
title="Waiting for Host to join"
|
55
|
+
subtitle="Sit back and relax till others join"
|
56
|
+
icon={<PeopleAddIcon width="56px" height="56px" style={{ color: 'white' }} />}
|
57
|
+
/>
|
58
|
+
) : null}
|
59
|
+
{isInsetEnabled && <InsetTile />}
|
64
60
|
</Flex>
|
65
61
|
);
|
66
62
|
}
|
@@ -34,6 +34,7 @@ import { Loading } from '../../Loading';
|
|
34
34
|
import { Text } from '../../Text';
|
35
35
|
import { config, theme, useTheme } from '../../Theme';
|
36
36
|
import { Tooltip } from '../../Tooltip';
|
37
|
+
import { WaitingView } from './WaitingView';
|
37
38
|
import { useSidepaneToggle } from '../components/AppData/useSidepane';
|
38
39
|
import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
39
40
|
import { useIsLandscape, useKeyboardHandler } from '../common/hooks';
|
@@ -457,17 +458,19 @@ const HLSView = () => {
|
|
457
458
|
flex: isLandscape ? '2 1 0' : '1 1 0',
|
458
459
|
}}
|
459
460
|
>
|
460
|
-
|
461
|
-
<
|
462
|
-
{
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
<
|
468
|
-
{
|
469
|
-
|
470
|
-
|
461
|
+
{streamEnded ? (
|
462
|
+
<WaitingView
|
463
|
+
icon={<ColoredHandIcon height={56} width={56} />}
|
464
|
+
title="Stream has ended"
|
465
|
+
subtitle="Have a nice day!"
|
466
|
+
/>
|
467
|
+
) : (
|
468
|
+
<WaitingView
|
469
|
+
icon={<GoLiveIcon height={56} width={56} style={{ color: 'white' }} />}
|
470
|
+
title="Stream yet to start"
|
471
|
+
subtitle="Sit back and relax"
|
472
|
+
/>
|
473
|
+
)}
|
471
474
|
</Flex>
|
472
475
|
</>
|
473
476
|
);
|
@@ -5,7 +5,14 @@ import {
|
|
5
5
|
HLSLiveStreamingScreen_Elements,
|
6
6
|
} from '@100mslive/types-prebuilt';
|
7
7
|
import { match } from 'ts-pattern';
|
8
|
-
import {
|
8
|
+
import {
|
9
|
+
selectIsConnectedToRoom,
|
10
|
+
selectIsLocalScreenShared,
|
11
|
+
selectLocalPeerRoleName,
|
12
|
+
useHMSActions,
|
13
|
+
useHMSStore,
|
14
|
+
} from '@100mslive/react-sdk';
|
15
|
+
import { PeopleAddIcon, ShareScreenIcon } from '@100mslive/react-icons';
|
9
16
|
import FullPageProgress from '../components/FullPageProgress';
|
10
17
|
import { GridLayout } from '../components/VideoLayouts/GridLayout';
|
11
18
|
import { Box, Flex } from '../../Layout';
|
@@ -21,11 +28,10 @@ import { CaptionsViewer } from '../plugins/CaptionsViewer';
|
|
21
28
|
import {
|
22
29
|
usePDFConfig,
|
23
30
|
useUrlToEmbed,
|
24
|
-
useWaitingViewerRole,
|
25
31
|
// @ts-ignore: No implicit Any
|
26
32
|
} from '../components/AppData/useUISettings';
|
27
33
|
import { useCloseScreenshareWhiteboard } from '../components/hooks/useCloseScreenshareWhiteboard';
|
28
|
-
import { useLandscapeHLSStream, useMobileHLSStream } from '../common/hooks';
|
34
|
+
import { useLandscapeHLSStream, useMobileHLSStream, useWaitingRoomInfo } from '../common/hooks';
|
29
35
|
import { SESSION_STORE_KEY } from '../common/constants';
|
30
36
|
// @ts-ignore: No implicit Any
|
31
37
|
const HLSView = React.lazy(() => import('./HLSView'));
|
@@ -39,17 +45,20 @@ export const VideoStreamingSection = ({
|
|
39
45
|
elements: DefaultConferencingScreen_Elements | HLSLiveStreamingScreen_Elements;
|
40
46
|
hideControls: boolean;
|
41
47
|
}) => {
|
42
|
-
const
|
48
|
+
const localPeerRoleName = useHMSStore(selectLocalPeerRoleName);
|
43
49
|
const isConnected = useHMSStore(selectIsConnectedToRoom);
|
50
|
+
const isSharingScreen = useHMSStore(selectIsLocalScreenShared);
|
44
51
|
|
45
52
|
const hmsActions = useHMSActions();
|
46
|
-
const waitingViewerRole = useWaitingViewerRole();
|
47
53
|
const urlToIframe = useUrlToEmbed();
|
48
54
|
const pdfAnnotatorActive = usePDFConfig();
|
49
55
|
const isMobileHLSStream = useMobileHLSStream();
|
50
56
|
const isLandscapeHLSStream = useLandscapeHLSStream();
|
51
57
|
useCloseScreenshareWhiteboard();
|
52
58
|
|
59
|
+
const { isNotAllowedToPublish, isScreenOnlyPublishParams, hasSubscribedRolePublishing } = useWaitingRoomInfo();
|
60
|
+
|
61
|
+
console.log('pring ', isNotAllowedToPublish, isScreenOnlyPublishParams, hasSubscribedRolePublishing);
|
53
62
|
useEffect(() => {
|
54
63
|
if (!isConnected) {
|
55
64
|
return;
|
@@ -64,7 +73,7 @@ export const VideoStreamingSection = ({
|
|
64
73
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
65
74
|
}, [isConnected, hmsActions]);
|
66
75
|
|
67
|
-
if (!
|
76
|
+
if (!localPeerRoleName) {
|
68
77
|
// we don't know the role yet to decide how to render UI
|
69
78
|
return null;
|
70
79
|
}
|
@@ -82,7 +91,15 @@ export const VideoStreamingSection = ({
|
|
82
91
|
.with({ isMobileHLSStream: true }, () => 'column')
|
83
92
|
.otherwise(() => 'row')}
|
84
93
|
>
|
85
|
-
{match({
|
94
|
+
{match({
|
95
|
+
screenType,
|
96
|
+
isNotAllowedToPublish,
|
97
|
+
isScreenOnlyPublishParams,
|
98
|
+
hasSubscribedRolePublishing,
|
99
|
+
isSharingScreen,
|
100
|
+
pdfAnnotatorActive,
|
101
|
+
urlToIframe,
|
102
|
+
})
|
86
103
|
.with(
|
87
104
|
{
|
88
105
|
screenType: 'hls_live_streaming',
|
@@ -90,8 +107,26 @@ export const VideoStreamingSection = ({
|
|
90
107
|
() => <HLSView />,
|
91
108
|
)
|
92
109
|
.when(
|
93
|
-
({
|
94
|
-
|
110
|
+
({ isNotAllowedToPublish, hasSubscribedRolePublishing }) =>
|
111
|
+
isNotAllowedToPublish && !hasSubscribedRolePublishing,
|
112
|
+
() => (
|
113
|
+
<WaitingView
|
114
|
+
title="Waiting for Host to join"
|
115
|
+
subtitle="Sit back and relax"
|
116
|
+
icon={<PeopleAddIcon width="56px" height="56px" style={{ color: 'white' }} />}
|
117
|
+
/>
|
118
|
+
),
|
119
|
+
)
|
120
|
+
.when(
|
121
|
+
({ isScreenOnlyPublishParams, isSharingScreen, hasSubscribedRolePublishing }) =>
|
122
|
+
isScreenOnlyPublishParams && !isSharingScreen && !hasSubscribedRolePublishing,
|
123
|
+
() => (
|
124
|
+
<WaitingView
|
125
|
+
title="Ready to present"
|
126
|
+
subtitle="Select the Screenshare button to start presenting"
|
127
|
+
icon={<ShareScreenIcon width="56px" height="56px" style={{ color: 'white' }} />}
|
128
|
+
/>
|
129
|
+
),
|
95
130
|
)
|
96
131
|
.when(
|
97
132
|
({ pdfAnnotatorActive }) => !!pdfAnnotatorActive,
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { Box, Flex } from '../../Layout';
|
3
|
+
import { Text } from '../../Text';
|
4
|
+
|
5
|
+
export const WaitingView = React.memo(
|
6
|
+
({ icon, title, subtitle }: { icon: React.ReactNode; title: string; subtitle: string }) => {
|
7
|
+
return (
|
8
|
+
<Flex
|
9
|
+
align="center"
|
10
|
+
direction="column"
|
11
|
+
css={{
|
12
|
+
textAlign: 'center',
|
13
|
+
margin: 'auto',
|
14
|
+
h: '100%',
|
15
|
+
justifyContent: 'center',
|
16
|
+
gap: '$8',
|
17
|
+
}}
|
18
|
+
>
|
19
|
+
<Box
|
20
|
+
css={{
|
21
|
+
backgroundColor: '$surface_default',
|
22
|
+
display: 'flex',
|
23
|
+
alignItems: 'center',
|
24
|
+
gap: '$4',
|
25
|
+
size: '$20',
|
26
|
+
r: '$round',
|
27
|
+
justifyContent: 'center',
|
28
|
+
}}
|
29
|
+
>
|
30
|
+
{icon}
|
31
|
+
</Box>
|
32
|
+
<Flex
|
33
|
+
direction="column"
|
34
|
+
css={{
|
35
|
+
p: '$1',
|
36
|
+
gap: '$4',
|
37
|
+
}}
|
38
|
+
>
|
39
|
+
<Text variant="h4" css={{ '@md': { fontSize: '$md', color: '$on_surface_high' } }}>
|
40
|
+
{title}
|
41
|
+
</Text>
|
42
|
+
<Text
|
43
|
+
variant="body1"
|
44
|
+
css={{ fontWeight: '$regular', color: '$on_surface_medium', '@md': { fontSize: '$sm' } }}
|
45
|
+
>
|
46
|
+
{subtitle}
|
47
|
+
</Text>
|
48
|
+
</Flex>
|
49
|
+
</Flex>
|
50
|
+
);
|
51
|
+
},
|
52
|
+
);
|