@100mslive/roomkit-react 0.3.1 → 0.3.2-alpha.1
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.
- 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} />
|