@100mslive/roomkit-react 0.3.1 → 0.3.2-alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/{HLSView-7WNDXOED.js → HLSView-7E6TK45Q.js} +13 -3
- package/dist/HLSView-7E6TK45Q.js.map +7 -0
- package/dist/Prebuilt/common/hooks.d.ts +2 -0
- package/dist/Prebuilt/components/Footer/ParticipantList.d.ts +2 -1
- package/dist/Prebuilt/components/Footer/RoleAccordion.d.ts +1 -0
- package/dist/Prebuilt/components/hooks/useGroupOnStageActions.d.ts +10 -0
- package/dist/Prebuilt/components/hooks/usePeerOnStageActions.d.ts +14 -0
- package/dist/{chunk-3OCZREZ3.js → chunk-FKNIYFKS.js} +697 -552
- package/dist/chunk-FKNIYFKS.js.map +7 -0
- package/dist/index.cjs.js +1910 -1745
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +1 -1
- package/dist/meta.cjs.json +152 -29
- package/dist/meta.esbuild.json +160 -36
- package/package.json +6 -6
- package/src/Prebuilt/common/hooks.ts +27 -1
- package/src/Prebuilt/components/Chat/PinnedMessage.tsx +4 -3
- package/src/Prebuilt/components/Footer/ParticipantList.tsx +90 -66
- package/src/Prebuilt/components/Footer/RoleAccordion.tsx +20 -1
- package/src/Prebuilt/components/MwebLandscapePrompt.tsx +1 -1
- package/src/Prebuilt/components/Polls/CreatePollQuiz/PollsQuizMenu.tsx +1 -1
- package/src/Prebuilt/components/Polls/CreateQuestions/QuestionForm.tsx +1 -1
- package/src/Prebuilt/components/Polls/common/OptionInputWithDelete.tsx +1 -1
- package/src/Prebuilt/components/VideoLayouts/ScreenshareLayout.tsx +2 -0
- package/src/Prebuilt/components/hooks/useGroupOnStageActions.tsx +54 -0
- package/src/Prebuilt/components/hooks/usePeerOnStageActions.tsx +49 -0
- package/src/Prebuilt/layouts/HLSView.jsx +10 -1
- package/dist/HLSView-7WNDXOED.js.map +0 -7
- package/dist/chunk-3OCZREZ3.js.map +0 -7
@@ -9,24 +9,30 @@ import {
|
|
9
9
|
selectIsPeerAudioEnabled,
|
10
10
|
selectLocalPeerID,
|
11
11
|
selectPeerCount,
|
12
|
-
selectPeerMetadata,
|
13
12
|
selectPermissions,
|
14
|
-
useHMSActions,
|
15
13
|
useHMSStore,
|
16
14
|
} from '@100mslive/react-sdk';
|
17
|
-
import {
|
15
|
+
import {
|
16
|
+
AddIcon,
|
17
|
+
ChangeRoleIcon,
|
18
|
+
CrossIcon,
|
19
|
+
HandIcon,
|
20
|
+
MicOffIcon,
|
21
|
+
PeopleIcon,
|
22
|
+
SearchIcon,
|
23
|
+
VerticalMenuIcon,
|
24
|
+
} from '@100mslive/react-icons';
|
18
25
|
import { Accordion, Box, config as cssConfig, Dropdown, Flex, Input, Text, textEllipsis } from '../../..';
|
26
|
+
import { IconButton as BaseIconButton } from '../../../IconButton';
|
19
27
|
// @ts-ignore: No implicit Any
|
20
28
|
import IconButton from '../../IconButton';
|
21
29
|
import { ConnectionIndicator } from '../Connection/ConnectionIndicator';
|
22
30
|
import { RemoveParticipant } from '../RemoveParticipant';
|
23
31
|
import { RoleAccordion } from './RoleAccordion';
|
24
|
-
import {
|
25
|
-
ConferencingScreenElements,
|
26
|
-
useRoomLayoutConferencingScreen,
|
27
|
-
} from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
32
|
+
import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
28
33
|
// @ts-ignore: No implicit Any
|
29
34
|
import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane';
|
35
|
+
import { usePeerOnStageActions } from '../hooks/usePeerOnStageActions';
|
30
36
|
import { useParticipants } from '../../common/hooks';
|
31
37
|
// @ts-ignore: No implicit Any
|
32
38
|
import { getFormattedCount } from '../../common/utils';
|
@@ -146,10 +152,12 @@ export const ParticipantCount = () => {
|
|
146
152
|
export const Participant = ({
|
147
153
|
peer,
|
148
154
|
isConnected,
|
155
|
+
isHandRaisedAccordion,
|
149
156
|
style,
|
150
157
|
}: {
|
151
158
|
peer: HMSPeer;
|
152
159
|
isConnected: boolean;
|
160
|
+
isHandRaisedAccordion?: boolean;
|
153
161
|
style: React.CSSProperties;
|
154
162
|
}) => {
|
155
163
|
const localPeerId = useHMSStore(selectLocalPeerID);
|
@@ -175,7 +183,12 @@ export const Participant = ({
|
|
175
183
|
{peer.name} {localPeerId === peer.id ? '(You)' : ''}
|
176
184
|
</Text>
|
177
185
|
{isConnected && peer.roleName ? (
|
178
|
-
<ParticipantActions
|
186
|
+
<ParticipantActions
|
187
|
+
peerId={peer.id}
|
188
|
+
isLocal={peer.id === localPeerId}
|
189
|
+
role={peer.roleName}
|
190
|
+
isHandRaisedAccordion={isHandRaisedAccordion}
|
191
|
+
/>
|
179
192
|
) : null}
|
180
193
|
</Flex>
|
181
194
|
);
|
@@ -247,7 +260,17 @@ const VirtualizedParticipants = ({
|
|
247
260
|
* shows settings to change for a participant like changing their role
|
248
261
|
*/
|
249
262
|
const ParticipantActions = React.memo(
|
250
|
-
({
|
263
|
+
({
|
264
|
+
peerId,
|
265
|
+
role,
|
266
|
+
isLocal,
|
267
|
+
isHandRaisedAccordion,
|
268
|
+
}: {
|
269
|
+
peerId: string;
|
270
|
+
role: string;
|
271
|
+
isLocal: boolean;
|
272
|
+
isHandRaisedAccordion?: boolean;
|
273
|
+
}) => {
|
251
274
|
const isHandRaised = useHMSStore(selectHasPeerHandRaised(peerId));
|
252
275
|
const canChangeRole = useHMSStore(selectPermissions)?.changeRole;
|
253
276
|
const canRemoveOthers = useHMSStore(selectPermissions)?.removeOthers;
|
@@ -264,72 +287,73 @@ const ParticipantActions = React.memo(
|
|
264
287
|
gap: '$8',
|
265
288
|
}}
|
266
289
|
>
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
290
|
+
{isHandRaisedAccordion ? (
|
291
|
+
<HandRaisedAccordionParticipantActions peerId={peerId} role={role} />
|
292
|
+
) : (
|
293
|
+
<>
|
294
|
+
<ConnectionIndicator peerId={peerId} />
|
295
|
+
{isHandRaised && (
|
296
|
+
<Flex
|
297
|
+
align="center"
|
298
|
+
justify="center"
|
299
|
+
css={{ p: '$1', c: '$on_surface_high', bg: '$surface_bright', borderRadius: '$round' }}
|
300
|
+
>
|
301
|
+
<HandIcon height={19} width={19} />
|
302
|
+
</Flex>
|
303
|
+
)}
|
304
|
+
{isAudioMuted ? (
|
305
|
+
<Flex
|
306
|
+
align="center"
|
307
|
+
justify="center"
|
308
|
+
css={{ p: '$2', c: '$on_surface_high', bg: '$surface_bright', borderRadius: '$round' }}
|
309
|
+
>
|
310
|
+
<MicOffIcon height={19} width={19} />
|
311
|
+
</Flex>
|
312
|
+
) : null}
|
286
313
|
|
287
|
-
|
288
|
-
|
289
|
-
)
|
314
|
+
{shouldShowMoreActions && !isLocal ? <ParticipantMoreActions peerId={peerId} role={role} /> : null}
|
315
|
+
</>
|
316
|
+
)}
|
290
317
|
</Flex>
|
291
318
|
);
|
292
319
|
},
|
293
320
|
);
|
294
321
|
|
295
|
-
const
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
322
|
+
const HandRaisedAccordionParticipantActions = ({ peerId, role }: { peerId: string; role: string }) => {
|
323
|
+
const { handleStageAction, lowerPeerHand, shouldShowStageRoleChange, isInStage } = usePeerOnStageActions({
|
324
|
+
peerId,
|
325
|
+
role,
|
326
|
+
});
|
327
|
+
return (
|
328
|
+
<>
|
329
|
+
<BaseIconButton
|
330
|
+
css={{ p: '$1', c: '$on_surface_high', bg: '$surface_bright', borderRadius: '$round' }}
|
331
|
+
onClick={() => lowerPeerHand()}
|
332
|
+
>
|
333
|
+
<CrossIcon height={19} width={19} />
|
334
|
+
</BaseIconButton>
|
335
|
+
{shouldShowStageRoleChange && !isInStage && (
|
336
|
+
<BaseIconButton
|
337
|
+
css={{ p: '$1', c: '$on_surface_high', bg: '$primary_default', borderRadius: '$round' }}
|
338
|
+
onClick={() => handleStageAction()}
|
339
|
+
>
|
340
|
+
<AddIcon height={19} width={19} />
|
341
|
+
</BaseIconButton>
|
342
|
+
)}
|
343
|
+
</>
|
344
|
+
);
|
345
|
+
};
|
346
|
+
|
347
|
+
const ParticipantMoreActions = ({ peerId, role }: { peerId: string; role: string }) => {
|
307
348
|
const {
|
349
|
+
open,
|
350
|
+
setOpen,
|
308
351
|
bring_to_stage_label,
|
309
352
|
remove_from_stage_label,
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
} =
|
314
|
-
const isInStage = role === on_stage_role;
|
315
|
-
const shouldShowStageRoleChange =
|
316
|
-
canChangeRole &&
|
317
|
-
((isInStage && remove_from_stage_label) || (off_stage_roles?.includes(role) && bring_to_stage_label));
|
318
|
-
const prevRole = useHMSStore(selectPeerMetadata(peerId))?.prevRole;
|
319
|
-
const [open, setOpen] = useState(false);
|
320
|
-
|
321
|
-
const handleStageAction = async () => {
|
322
|
-
if (isInStage) {
|
323
|
-
prevRole && hmsActions.changeRoleOfPeer(peerId, prevRole, true);
|
324
|
-
} else if (on_stage_role) {
|
325
|
-
await hmsActions.changeRoleOfPeer(peerId, on_stage_role, skip_preview_for_role_change);
|
326
|
-
if (skip_preview_for_role_change) {
|
327
|
-
await hmsActions.lowerRemotePeerHand(peerId);
|
328
|
-
}
|
329
|
-
}
|
330
|
-
setOpen(false);
|
331
|
-
};
|
332
|
-
|
353
|
+
handleStageAction,
|
354
|
+
isInStage,
|
355
|
+
shouldShowStageRoleChange,
|
356
|
+
} = usePeerOnStageActions({ peerId, role });
|
333
357
|
return (
|
334
358
|
<Dropdown.Root open={open} onOpenChange={value => setOpen(value)} modal={false}>
|
335
359
|
<Dropdown.Trigger
|
@@ -4,10 +4,13 @@ import { FixedSizeList } from 'react-window';
|
|
4
4
|
import { HMSPeer, selectIsLargeRoom, useHMSStore, usePaginatedParticipants } from '@100mslive/react-sdk';
|
5
5
|
import { ChevronRightIcon } from '@100mslive/react-icons';
|
6
6
|
import { Accordion } from '../../../Accordion';
|
7
|
+
import { Button } from '../../../Button';
|
8
|
+
import { HorizontalDivider } from '../../../Divider';
|
7
9
|
import { Flex } from '../../../Layout';
|
8
10
|
import { Text } from '../../../Text';
|
9
11
|
import { Participant } from './ParticipantList';
|
10
12
|
import { RoleOptions } from './RoleOptions';
|
13
|
+
import { useGroupOnStageActions } from '../hooks/useGroupOnStageActions';
|
11
14
|
// @ts-ignore: No implicit Any
|
12
15
|
import { getFormattedCount } from '../../common/utils';
|
13
16
|
|
@@ -16,6 +19,7 @@ const ITER_TIMER = 5000;
|
|
16
19
|
|
17
20
|
export interface ItemData {
|
18
21
|
peerList: HMSPeer[];
|
22
|
+
isHandRaisedAccordion?: boolean;
|
19
23
|
isConnected: boolean;
|
20
24
|
}
|
21
25
|
|
@@ -29,6 +33,7 @@ export const VirtualizedParticipantItem = React.memo(
|
|
29
33
|
<Participant
|
30
34
|
key={data.peerList[index].id}
|
31
35
|
peer={data.peerList[index]}
|
36
|
+
isHandRaisedAccordion={data.isHandRaisedAccordion}
|
32
37
|
isConnected={data.isConnected}
|
33
38
|
style={style}
|
34
39
|
/>
|
@@ -63,6 +68,9 @@ export const RoleAccordion = ({
|
|
63
68
|
peersInAccordion = peersInAccordion.filter(peer => peer.name.toLowerCase().includes(filter.search || ''));
|
64
69
|
}
|
65
70
|
}
|
71
|
+
const { bringAllToStage, bring_to_stage_label, canBringToStage, lowerAllHands } = useGroupOnStageActions({
|
72
|
+
peers: peersInAccordion,
|
73
|
+
});
|
66
74
|
|
67
75
|
useEffect(() => {
|
68
76
|
if (!isOffStageRole || !isLargeRoom) {
|
@@ -113,7 +121,7 @@ export const RoleAccordion = ({
|
|
113
121
|
<Accordion.Content contentStyles={{ border: '1px solid $border_default', borderTop: 'none' }}>
|
114
122
|
<FixedSizeList
|
115
123
|
itemSize={ROW_HEIGHT}
|
116
|
-
itemData={{ peerList: peersInAccordion, isConnected }}
|
124
|
+
itemData={{ peerList: peersInAccordion, isConnected, isHandRaisedAccordion }}
|
117
125
|
itemKey={itemKey}
|
118
126
|
itemCount={peersInAccordion.length}
|
119
127
|
width={width}
|
@@ -140,6 +148,17 @@ export const RoleAccordion = ({
|
|
140
148
|
<ChevronRightIcon />
|
141
149
|
</Flex>
|
142
150
|
) : null}
|
151
|
+
{isHandRaisedAccordion && (
|
152
|
+
<>
|
153
|
+
<HorizontalDivider />
|
154
|
+
<Flex css={{ w: '100%', p: '$6', gap: '$4' }} justify="center">
|
155
|
+
<Button variant="standard" onClick={() => lowerAllHands()}>
|
156
|
+
Lower All Hands
|
157
|
+
</Button>
|
158
|
+
{canBringToStage && <Button onClick={() => bringAllToStage()}>{bring_to_stage_label}</Button>}
|
159
|
+
</Flex>
|
160
|
+
</>
|
161
|
+
)}
|
143
162
|
</Accordion.Content>
|
144
163
|
</Accordion.Item>
|
145
164
|
);
|
@@ -32,7 +32,7 @@ export const MwebLandscapePrompt = () => {
|
|
32
32
|
// Angle check needed to diff bw mobile and desktop
|
33
33
|
setShowMwebLandscapePrompt(
|
34
34
|
match({ angle, isLandscapeHLSStream, isLandscape, type })
|
35
|
-
.with({ isLandscapeHLSStream }, () => false)
|
35
|
+
.with({ isLandscapeHLSStream: true }, () => false)
|
36
36
|
.with({ angle: P.when(angle => angle && angle >= 90) }, ({ type }) => type.includes('landscape'))
|
37
37
|
.otherwise(() => isLandscape),
|
38
38
|
);
|
@@ -140,7 +140,7 @@ const AddMenu = () => {
|
|
140
140
|
type="text"
|
141
141
|
placeholder="Enter a name to continue"
|
142
142
|
value={title}
|
143
|
-
onChange={event => setTitle(event.target.value)}
|
143
|
+
onChange={event => setTitle(event.target.value.trimStart())}
|
144
144
|
css={{
|
145
145
|
backgroundColor: '$surface_bright',
|
146
146
|
border: '1px solid $border_default',
|
@@ -159,7 +159,7 @@ export const QuestionForm = ({
|
|
159
159
|
maxHeight: '$32',
|
160
160
|
}}
|
161
161
|
value={text}
|
162
|
-
onChange={event => setText(event.target.value)}
|
162
|
+
onChange={event => setText(event.target.value.trimStart())}
|
163
163
|
/>
|
164
164
|
<Text variant="xs" css={{ color: '$on_surface_medium', textAlign: 'end', mt: '$4' }}>
|
165
165
|
{text?.length || 0}/1024
|
@@ -27,7 +27,7 @@ export const OptionInputWithDelete = ({
|
|
27
27
|
}}
|
28
28
|
value={option?.text || ''}
|
29
29
|
key={index}
|
30
|
-
onChange={event => handleOptionTextChange(index, event.target.value)}
|
30
|
+
onChange={event => handleOptionTextChange(index, event.target.value.trimStart())}
|
31
31
|
/>
|
32
32
|
<IconButton onClick={() => removeOption(index)} css={{ bg: 'transparent', border: 'none' }}>
|
33
33
|
<TrashIcon />
|
@@ -55,6 +55,8 @@ export const ScreenshareLayout = ({ peers, onPageChange, onPageSize, edgeToEdge
|
|
55
55
|
};
|
56
56
|
}, [activeSharePeer?.id, isMobile, setActiveScreenSharePeer]);
|
57
57
|
|
58
|
+
console.log({ activeSharePeer, secondaryPeers });
|
59
|
+
|
58
60
|
return (
|
59
61
|
<ProminenceLayout.Root edgeToEdge={edgeToEdge} hasSidebar={hasSidebar}>
|
60
62
|
<ProminenceLayout.ProminentSection>
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { match, P } from 'ts-pattern';
|
2
|
+
import { HMSPeer, selectPermissions, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
|
3
|
+
import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
4
|
+
|
5
|
+
export const useGroupOnStageActions = ({ peers }: { peers: HMSPeer[] }) => {
|
6
|
+
const hmsActions = useHMSActions();
|
7
|
+
const { elements } = useRoomLayoutConferencingScreen();
|
8
|
+
const {
|
9
|
+
bring_to_stage_label,
|
10
|
+
remove_from_stage_label,
|
11
|
+
on_stage_role,
|
12
|
+
off_stage_roles = [],
|
13
|
+
skip_preview_for_role_change = false,
|
14
|
+
} = elements.on_stage_exp || {};
|
15
|
+
const canChangeRole = useHMSStore(selectPermissions)?.changeRole;
|
16
|
+
|
17
|
+
const offStageRolePeers = peers.filter(peer =>
|
18
|
+
match({ on_stage_role, bring_to_stage_label, roleName: peer.roleName })
|
19
|
+
.with(
|
20
|
+
{
|
21
|
+
on_stage_role: P.when(role => !!role),
|
22
|
+
bring_to_stage_label: P.when(label => !!label),
|
23
|
+
roleName: P.when(role => !!role && off_stage_roles.includes(role)),
|
24
|
+
},
|
25
|
+
() => true,
|
26
|
+
)
|
27
|
+
.otherwise(() => false),
|
28
|
+
);
|
29
|
+
|
30
|
+
const lowerAllHands = async () => {
|
31
|
+
return Promise.all(peers.map(peer => hmsActions.lowerRemotePeerHand(peer.id)));
|
32
|
+
};
|
33
|
+
|
34
|
+
const bringAllToStage = () => {
|
35
|
+
if (!canChangeRole || !on_stage_role) {
|
36
|
+
return;
|
37
|
+
}
|
38
|
+
return Promise.all(
|
39
|
+
offStageRolePeers.map(peer => {
|
40
|
+
return hmsActions.changeRoleOfPeer(peer.id, on_stage_role, skip_preview_for_role_change).then(() => {
|
41
|
+
return skip_preview_for_role_change ? hmsActions.lowerRemotePeerHand(peer.id) : null;
|
42
|
+
});
|
43
|
+
}),
|
44
|
+
);
|
45
|
+
};
|
46
|
+
|
47
|
+
return {
|
48
|
+
lowerAllHands,
|
49
|
+
bringAllToStage,
|
50
|
+
canBringToStage: canChangeRole && offStageRolePeers.length > 0,
|
51
|
+
bring_to_stage_label,
|
52
|
+
remove_from_stage_label,
|
53
|
+
};
|
54
|
+
};
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import { useState } from 'react';
|
2
|
+
import { selectPeerMetadata, selectPermissions, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
|
3
|
+
import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
4
|
+
|
5
|
+
export const usePeerOnStageActions = ({ peerId, role }: { peerId: string; role: string }) => {
|
6
|
+
const hmsActions = useHMSActions();
|
7
|
+
const { elements } = useRoomLayoutConferencingScreen();
|
8
|
+
const {
|
9
|
+
bring_to_stage_label,
|
10
|
+
remove_from_stage_label,
|
11
|
+
on_stage_role,
|
12
|
+
off_stage_roles = [],
|
13
|
+
skip_preview_for_role_change = false,
|
14
|
+
} = elements.on_stage_exp || {};
|
15
|
+
const isInStage = role === on_stage_role;
|
16
|
+
const canChangeRole = useHMSStore(selectPermissions)?.changeRole;
|
17
|
+
const shouldShowStageRoleChange =
|
18
|
+
canChangeRole &&
|
19
|
+
((isInStage && remove_from_stage_label) || (off_stage_roles?.includes(role) && bring_to_stage_label));
|
20
|
+
const prevRole = useHMSStore(selectPeerMetadata(peerId))?.prevRole;
|
21
|
+
const [open, setOpen] = useState(false);
|
22
|
+
|
23
|
+
const lowerPeerHand = async () => {
|
24
|
+
await hmsActions.lowerRemotePeerHand(peerId);
|
25
|
+
};
|
26
|
+
|
27
|
+
const handleStageAction = async () => {
|
28
|
+
if (isInStage) {
|
29
|
+
prevRole && hmsActions.changeRoleOfPeer(peerId, prevRole, true);
|
30
|
+
} else if (on_stage_role) {
|
31
|
+
await hmsActions.changeRoleOfPeer(peerId, on_stage_role, skip_preview_for_role_change);
|
32
|
+
if (skip_preview_for_role_change) {
|
33
|
+
await lowerPeerHand();
|
34
|
+
}
|
35
|
+
}
|
36
|
+
setOpen(false);
|
37
|
+
};
|
38
|
+
|
39
|
+
return {
|
40
|
+
open,
|
41
|
+
setOpen,
|
42
|
+
lowerPeerHand,
|
43
|
+
handleStageAction,
|
44
|
+
shouldShowStageRoleChange,
|
45
|
+
isInStage,
|
46
|
+
bring_to_stage_label,
|
47
|
+
remove_from_stage_label,
|
48
|
+
};
|
49
|
+
};
|
@@ -36,7 +36,7 @@ import { config, theme, useTheme } from '../../Theme';
|
|
36
36
|
import { Tooltip } from '../../Tooltip';
|
37
37
|
import { useSidepaneToggle } from '../components/AppData/useSidepane';
|
38
38
|
import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
39
|
-
import { useIsLandscape } from '../common/hooks';
|
39
|
+
import { useIsLandscape, useKeyboardHandler } from '../common/hooks';
|
40
40
|
import { APP_DATA, EMOJI_REACTION_TYPE, POLL_STATE, POLL_VIEWS, SIDE_PANE_OPTIONS } from '../common/constants';
|
41
41
|
|
42
42
|
let hlsPlayer;
|
@@ -367,6 +367,8 @@ const HLSView = () => {
|
|
367
367
|
[controlsVisible, isLandscape, isMobile, qualityDropDownOpen, seekProgress],
|
368
368
|
);
|
369
369
|
|
370
|
+
const keyHandler = useKeyboardHandler(isPaused, hlsPlayer);
|
371
|
+
|
370
372
|
if (!hlsUrl || streamEnded) {
|
371
373
|
return (
|
372
374
|
<>
|
@@ -437,7 +439,14 @@ const HLSView = () => {
|
|
437
439
|
'@md': {
|
438
440
|
height: 'auto',
|
439
441
|
},
|
442
|
+
outline: 'none',
|
443
|
+
}}
|
444
|
+
onKeyDown={async event => {
|
445
|
+
if (hlsState?.variants[0]?.playlist_type === HLSPlaylistType.DVR) {
|
446
|
+
await keyHandler(event);
|
447
|
+
}
|
440
448
|
}}
|
449
|
+
tabIndex="0"
|
441
450
|
>
|
442
451
|
{!(isMobile || isLandscape) && (
|
443
452
|
<HLSAutoplayBlockedPrompt open={isHlsAutoplayBlocked} unblockAutoPlay={unblockAutoPlay} />
|