@100mslive/roomkit-react 0.1.7 → 0.1.8
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/AudioLevel/AudioLevel.d.ts +5 -8
- package/dist/AudioLevel/index.d.ts +2 -1
- package/dist/AudioLevel/useBorderAudioLevel.d.ts +8 -0
- package/dist/{HLSView-3S74KF3A.js → HLSView-DDGPZHA2.js} +5 -4
- package/dist/{HLSView-3S74KF3A.js.map → HLSView-DDGPZHA2.js.map} +2 -2
- package/dist/Prebuilt/App.d.ts +1 -0
- package/dist/Prebuilt/AppContext.d.ts +1 -0
- package/dist/Prebuilt/components/Chip.d.ts +12 -0
- package/dist/Prebuilt/components/Footer/PaginatedParticipants.d.ts +5 -0
- package/dist/Prebuilt/components/Footer/RoleAccordion.d.ts +10 -3
- package/dist/Prebuilt/components/Notifications/HeadlessEndRoomListener.d.ts +2 -0
- package/dist/Prebuilt/components/PrebuiltDialogPortal.d.ts +4 -0
- package/dist/Prebuilt/components/PrebuiltTileElements.d.ts +2198 -0
- package/dist/{VirtualBackground-3TI5NA4V.js → VirtualBackground-UVZJVOA2.js} +3 -3
- package/dist/{chunk-5DQ3WTED.js → chunk-6SQTFOK6.js} +2 -2
- package/dist/{chunk-5DQ3WTED.js.map → chunk-6SQTFOK6.js.map} +1 -1
- package/dist/{chunk-36X4ZCLC.js → chunk-HUMNPIYI.js} +2 -2
- package/dist/{chunk-Z7P5WITU.js → chunk-PRM33R4R.js} +591 -1186
- package/dist/chunk-PRM33R4R.js.map +7 -0
- package/dist/{conference-JNABIZBG.js → conference-N7S47TDK.js} +1505 -717
- package/dist/conference-N7S47TDK.js.map +7 -0
- package/dist/index.cjs.js +3083 -2825
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +4 -2
- package/dist/meta.cjs.json +1107 -740
- package/dist/meta.esbuild.json +1160 -791
- package/package.json +6 -6
- package/src/AudioLevel/AudioLevel.tsx +79 -30
- package/src/AudioLevel/audio-level.png +0 -0
- package/src/AudioLevel/index.ts +2 -1
- package/src/AudioLevel/useBorderAudioLevel.tsx +34 -0
- package/src/Prebuilt/App.tsx +6 -0
- package/src/Prebuilt/AppContext.tsx +2 -0
- package/src/Prebuilt/common/constants.js +1 -1
- package/src/Prebuilt/common/utils.js +0 -7
- package/src/Prebuilt/components/AppData/AppData.jsx +1 -1
- package/src/Prebuilt/components/AppData/useUISettings.js +1 -1
- package/src/Prebuilt/components/{Chip.jsx → Chip.tsx} +18 -3
- package/src/Prebuilt/components/Footer/PaginatedParticipants.tsx +94 -0
- package/src/Prebuilt/components/Footer/ParticipantList.jsx +67 -26
- package/src/Prebuilt/components/Footer/RoleAccordion.tsx +91 -49
- package/src/Prebuilt/components/Footer/RoleOptions.tsx +1 -1
- package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +7 -4
- package/src/Prebuilt/components/MoreSettings/ChangeNameModal.jsx +3 -2
- package/src/Prebuilt/components/MoreSettings/EmbedUrl.jsx +3 -2
- package/src/Prebuilt/components/MwebLandscapePrompt.jsx +58 -0
- package/src/Prebuilt/components/Notifications/HLSFailureModal.jsx +3 -2
- package/src/Prebuilt/components/Notifications/HeadlessEndRoomListener.tsx +23 -0
- package/src/Prebuilt/components/Notifications/Notifications.jsx +1 -1
- package/src/Prebuilt/components/Notifications/PermissionErrorModal.jsx +3 -2
- package/src/Prebuilt/components/PrebuiltDialogPortal.tsx +6 -0
- package/src/Prebuilt/components/PrebuiltTileElements.tsx +5 -0
- package/src/Prebuilt/components/Preview/PreviewJoin.tsx +11 -7
- package/src/Prebuilt/components/RoleChangeModal.jsx +3 -2
- package/src/Prebuilt/components/RoleChangeRequest/RequestPrompt.tsx +3 -2
- package/src/Prebuilt/components/Settings/SettingsModal.jsx +3 -2
- package/src/Prebuilt/components/Settings/StartRecording.jsx +3 -2
- package/src/Prebuilt/components/SidePaneTabs.tsx +31 -5
- package/src/Prebuilt/components/StatsForNerds.jsx +3 -2
- package/src/Prebuilt/components/VideoTile.jsx +21 -83
- package/src/Prebuilt/components/conference.jsx +4 -3
- package/src/Prebuilt/components/hooks/useDropdownSelection.jsx +1 -1
- package/src/Prebuilt/components/pdfAnnotator/pdfFileOptions.jsx +3 -2
- package/src/Prebuilt/components/pdfAnnotator/shareScreenOptions.jsx +4 -29
- package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +3 -2
- package/src/Prebuilt/layouts/HLSView.jsx +1 -0
- package/src/Prebuilt/layouts/SidePane.tsx +1 -0
- package/src/Prebuilt/primitives/DialogContent.jsx +5 -4
- package/dist/chunk-Z7P5WITU.js.map +0 -7
- package/dist/conference-JNABIZBG.js.map +0 -7
- /package/dist/{VirtualBackground-3TI5NA4V.js.map → VirtualBackground-UVZJVOA2.js.map} +0 -0
- /package/dist/{chunk-36X4ZCLC.js.map → chunk-HUMNPIYI.js.map} +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
2
|
import { useMeasure } from 'react-use';
|
|
3
3
|
import { FixedSizeList } from 'react-window';
|
|
4
|
-
import { HMSPeer } from '@100mslive/react-sdk';
|
|
4
|
+
import { HMSPeer, selectIsLargeRoom, useHMSStore, usePaginatedParticipants } from '@100mslive/react-sdk';
|
|
5
|
+
import { ChevronRightIcon } from '@100mslive/react-icons';
|
|
5
6
|
import { Accordion } from '../../../Accordion';
|
|
6
|
-
import {
|
|
7
|
+
import { Flex } from '../../../Layout';
|
|
7
8
|
import { Text } from '../../../Text';
|
|
8
9
|
// @ts-ignore: No implicit Any
|
|
9
10
|
import { Participant } from './ParticipantList';
|
|
@@ -11,18 +12,19 @@ import { RoleOptions } from './RoleOptions';
|
|
|
11
12
|
// @ts-ignore: No implicit Any
|
|
12
13
|
import { getFormattedCount } from '../../common/utils';
|
|
13
14
|
|
|
14
|
-
const ROW_HEIGHT = 50;
|
|
15
|
+
export const ROW_HEIGHT = 50;
|
|
16
|
+
const ITER_TIMER = 5000;
|
|
15
17
|
|
|
16
|
-
interface ItemData {
|
|
18
|
+
export interface ItemData {
|
|
17
19
|
peerList: HMSPeer[];
|
|
18
20
|
isConnected: boolean;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
function itemKey(index: number, data: ItemData) {
|
|
23
|
+
export function itemKey(index: number, data: ItemData) {
|
|
22
24
|
return data.peerList[index].id;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
const VirtualizedParticipantItem = React.memo(({ index, data }: { index: number; data: ItemData }) => {
|
|
27
|
+
export const VirtualizedParticipantItem = React.memo(({ index, data }: { index: number; data: ItemData }) => {
|
|
26
28
|
return <Participant key={data.peerList[index].id} peer={data.peerList[index]} isConnected={data.isConnected} />;
|
|
27
29
|
});
|
|
28
30
|
|
|
@@ -32,63 +34,103 @@ export const RoleAccordion = ({
|
|
|
32
34
|
isConnected,
|
|
33
35
|
filter,
|
|
34
36
|
isHandRaisedAccordion = false,
|
|
37
|
+
offStageRoles,
|
|
38
|
+
onActive,
|
|
35
39
|
}: ItemData & {
|
|
36
40
|
roleName: string;
|
|
37
41
|
isHandRaisedAccordion?: boolean;
|
|
38
42
|
filter?: { search: string };
|
|
43
|
+
offStageRoles: string[];
|
|
44
|
+
onActive?: (role: string) => void;
|
|
39
45
|
}) => {
|
|
40
46
|
const [ref, { width }] = useMeasure<HTMLDivElement>();
|
|
41
47
|
const showAcordion = filter?.search ? peerList.some(peer => peer.name.toLowerCase().includes(filter.search)) : true;
|
|
48
|
+
const isLargeRoom = useHMSStore(selectIsLargeRoom);
|
|
49
|
+
const { peers, total, loadPeers } = usePaginatedParticipants({ role: roleName, limit: 10 });
|
|
50
|
+
const isOffStageRole = roleName && offStageRoles.includes(roleName);
|
|
42
51
|
|
|
43
|
-
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (!isOffStageRole || !isLargeRoom) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
loadPeers();
|
|
57
|
+
const interval = setInterval(() => {
|
|
58
|
+
loadPeers();
|
|
59
|
+
}, ITER_TIMER);
|
|
60
|
+
return () => clearInterval(interval);
|
|
61
|
+
}, [isOffStageRole, isLargeRoom]); //eslint-disable-line
|
|
62
|
+
|
|
63
|
+
if (!showAcordion || (isHandRaisedAccordion && filter?.search) || (peerList.length === 0 && filter?.search)) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const height = ROW_HEIGHT * (peers.length || peerList.length);
|
|
68
|
+
const peersInAccordion = isOffStageRole && isLargeRoom ? peers : peerList;
|
|
69
|
+
const hasNext = total > peersInAccordion.length;
|
|
70
|
+
|
|
71
|
+
if (peersInAccordion.length === 0) {
|
|
44
72
|
return null;
|
|
45
73
|
}
|
|
46
|
-
const height = ROW_HEIGHT * peerList.length;
|
|
47
74
|
|
|
48
75
|
return (
|
|
49
|
-
<
|
|
50
|
-
<Accordion.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
76
|
+
<Accordion.Item value={roleName} css={{ '&:hover .role_actions': { visibility: 'visible' }, mb: '$8' }} ref={ref}>
|
|
77
|
+
<Accordion.Header
|
|
78
|
+
iconStyles={{ c: '$on_surface_high' }}
|
|
79
|
+
css={{
|
|
80
|
+
textTransform: 'capitalize',
|
|
81
|
+
p: '$6 $8',
|
|
82
|
+
fontSize: '$sm',
|
|
83
|
+
fontWeight: '$semiBold',
|
|
84
|
+
c: '$on_surface_medium',
|
|
85
|
+
borderRadius: '$1',
|
|
86
|
+
border: '1px solid $border_default',
|
|
87
|
+
'&[data-state="open"]': {
|
|
88
|
+
borderBottomLeftRadius: 0,
|
|
89
|
+
borderBottomRightRadius: 0,
|
|
90
|
+
},
|
|
91
|
+
}}
|
|
55
92
|
>
|
|
56
|
-
<
|
|
57
|
-
<
|
|
58
|
-
|
|
93
|
+
<Flex justify="between" css={{ flexGrow: 1, pr: '$6' }}>
|
|
94
|
+
<Text
|
|
95
|
+
variant="sm"
|
|
96
|
+
css={{ fontWeight: '$semiBold', textTransform: 'capitalize', color: '$on_surface_medium' }}
|
|
97
|
+
>
|
|
98
|
+
{roleName} {`(${getFormattedCount(isLargeRoom && isOffStageRole ? total : peerList.length)})`}
|
|
99
|
+
</Text>
|
|
100
|
+
<RoleOptions roleName={roleName} peerList={peersInAccordion} />
|
|
101
|
+
</Flex>
|
|
102
|
+
</Accordion.Header>
|
|
103
|
+
<Accordion.Content contentStyles={{ border: '1px solid $border_default', borderTop: 'none' }}>
|
|
104
|
+
<FixedSizeList
|
|
105
|
+
itemSize={ROW_HEIGHT}
|
|
106
|
+
itemData={{ peerList: peersInAccordion, isConnected }}
|
|
107
|
+
itemKey={itemKey}
|
|
108
|
+
itemCount={peersInAccordion.length}
|
|
109
|
+
width={width}
|
|
110
|
+
height={height}
|
|
111
|
+
>
|
|
112
|
+
{VirtualizedParticipantItem}
|
|
113
|
+
</FixedSizeList>
|
|
114
|
+
{offStageRoles?.includes(roleName) && hasNext ? (
|
|
115
|
+
<Flex
|
|
116
|
+
align="center"
|
|
117
|
+
justify="end"
|
|
59
118
|
css={{
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
119
|
+
gap: '$1',
|
|
120
|
+
cursor: 'pointer',
|
|
121
|
+
color: '$on_surface_high',
|
|
122
|
+
p: '$6',
|
|
123
|
+
borderTop: '1px solid $border_default',
|
|
65
124
|
}}
|
|
125
|
+
onClick={() => onActive?.(roleName)}
|
|
66
126
|
>
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
</Flex>
|
|
76
|
-
</Accordion.Header>
|
|
77
|
-
<Accordion.Content>
|
|
78
|
-
<Box css={{ borderTop: '1px solid $border_default' }} />
|
|
79
|
-
<FixedSizeList
|
|
80
|
-
itemSize={ROW_HEIGHT}
|
|
81
|
-
itemData={{ peerList, isConnected }}
|
|
82
|
-
itemKey={itemKey}
|
|
83
|
-
itemCount={peerList.length}
|
|
84
|
-
width={width}
|
|
85
|
-
height={height}
|
|
86
|
-
>
|
|
87
|
-
{VirtualizedParticipantItem}
|
|
88
|
-
</FixedSizeList>
|
|
89
|
-
</Accordion.Content>
|
|
90
|
-
</Accordion.Item>
|
|
91
|
-
</Accordion.Root>
|
|
92
|
-
</Flex>
|
|
127
|
+
<Text variant="sm" css={{ color: 'inherit' }}>
|
|
128
|
+
View All
|
|
129
|
+
</Text>
|
|
130
|
+
<ChevronRightIcon />
|
|
131
|
+
</Flex>
|
|
132
|
+
) : null}
|
|
133
|
+
</Accordion.Content>
|
|
134
|
+
</Accordion.Item>
|
|
93
135
|
);
|
|
94
136
|
};
|
|
@@ -46,7 +46,7 @@ export const RoleOptions = ({ roleName, peerList }: { roleName: string; peerList
|
|
|
46
46
|
const canRemoveRoleFromRoom =
|
|
47
47
|
permissions?.removeOthers && (on_stage_role === roleName || off_stage_roles?.includes(roleName));
|
|
48
48
|
|
|
49
|
-
if (!(canMuteRole || canRemoveRoleFromStage || canRemoveRoleFromRoom)) {
|
|
49
|
+
if (!(canMuteRole || canRemoveRoleFromStage || canRemoveRoleFromRoom) || peerList.length === 0) {
|
|
50
50
|
return null;
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import React, { Fragment, useState } from 'react';
|
|
2
2
|
import { ConferencingScreen } from '@100mslive/types-prebuilt';
|
|
3
|
+
// @ts-ignore: No implicit Any
|
|
3
4
|
import { selectIsConnectedToRoom, selectPermissions, useHMSStore, useRecordingStreaming } from '@100mslive/react-sdk';
|
|
5
|
+
// @ts-ignore: No implicit Any
|
|
4
6
|
import { ExitIcon, StopIcon, VerticalMenuIcon } from '@100mslive/react-icons';
|
|
5
7
|
import { Dropdown } from '../../../Dropdown';
|
|
6
8
|
import { Box, Flex } from '../../../Layout';
|
|
7
9
|
import { Dialog } from '../../../Modal';
|
|
8
10
|
import { Tooltip } from '../../../Tooltip';
|
|
11
|
+
import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
|
|
9
12
|
import { EndSessionContent } from './EndSessionContent';
|
|
10
13
|
import { LeaveIconButton, MenuTriggerButton } from './LeaveAtoms';
|
|
11
14
|
import { LeaveCard } from './LeaveCard';
|
|
@@ -135,7 +138,7 @@ export const DesktopLeaveRoom = ({
|
|
|
135
138
|
)}
|
|
136
139
|
|
|
137
140
|
<Dialog.Root open={showEndStreamAlert} modal={false}>
|
|
138
|
-
<
|
|
141
|
+
<PrebuiltDialogPortal>
|
|
139
142
|
<Dialog.Overlay />
|
|
140
143
|
<Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
|
|
141
144
|
<EndSessionContent
|
|
@@ -145,16 +148,16 @@ export const DesktopLeaveRoom = ({
|
|
|
145
148
|
isModal
|
|
146
149
|
/>
|
|
147
150
|
</Dialog.Content>
|
|
148
|
-
</
|
|
151
|
+
</PrebuiltDialogPortal>
|
|
149
152
|
</Dialog.Root>
|
|
150
153
|
|
|
151
154
|
<Dialog.Root open={showLeaveRoomAlert} modal={false}>
|
|
152
|
-
<
|
|
155
|
+
<PrebuiltDialogPortal>
|
|
153
156
|
<Dialog.Overlay />
|
|
154
157
|
<Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
|
|
155
158
|
<LeaveSessionContent setShowLeaveRoomAlert={setShowLeaveRoomAlert} leaveRoom={leaveRoom} isModal />
|
|
156
159
|
</Dialog.Content>
|
|
157
|
-
</
|
|
160
|
+
</PrebuiltDialogPortal>
|
|
158
161
|
</Dialog.Root>
|
|
159
162
|
</Fragment>
|
|
160
163
|
);
|
|
@@ -3,6 +3,7 @@ import { useMedia } from 'react-use';
|
|
|
3
3
|
import { selectLocalPeerName, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
|
|
4
4
|
import { config as cssConfig, Dialog } from '../../../';
|
|
5
5
|
import { Sheet } from '../../../Sheet';
|
|
6
|
+
import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
|
|
6
7
|
import { ToastManager } from '../Toast/ToastManager';
|
|
7
8
|
import { ChangeNameContent } from './ChangeNameContent';
|
|
8
9
|
import { UserPreferencesKeys, useUserPreferences } from '../hooks/useUserPreferences';
|
|
@@ -58,12 +59,12 @@ export const ChangeNameModal = ({ onOpenChange, openParentSheet = null }) => {
|
|
|
58
59
|
|
|
59
60
|
return (
|
|
60
61
|
<Dialog.Root defaultOpen onOpenChange={onOpenChange}>
|
|
61
|
-
<
|
|
62
|
+
<PrebuiltDialogPortal>
|
|
62
63
|
<Dialog.Overlay />
|
|
63
64
|
<Dialog.Content css={{ bg: '$surface_dim', width: 'min(400px,80%)', p: '$10' }}>
|
|
64
65
|
<ChangeNameContent {...props} />
|
|
65
66
|
</Dialog.Content>
|
|
66
|
-
</
|
|
67
|
+
</PrebuiltDialogPortal>
|
|
67
68
|
</Dialog.Root>
|
|
68
69
|
);
|
|
69
70
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
2
|
import { LinkIcon } from '@100mslive/react-icons';
|
|
3
3
|
import { Button, Dialog, Dropdown, Flex, Input, Text } from '../../../';
|
|
4
|
+
import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
|
|
4
5
|
import { useSetAppDataByKey } from '../AppData/useUISettings';
|
|
5
6
|
import { APP_DATA } from '../../common/constants';
|
|
6
7
|
|
|
@@ -30,7 +31,7 @@ export function EmbedUrlModal({ onOpenChange }) {
|
|
|
30
31
|
|
|
31
32
|
return (
|
|
32
33
|
<Dialog.Root defaultOpen onOpenChange={onOpenChange}>
|
|
33
|
-
<
|
|
34
|
+
<PrebuiltDialogPortal>
|
|
34
35
|
<Dialog.Overlay />
|
|
35
36
|
<Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
|
|
36
37
|
<Dialog.Title
|
|
@@ -75,7 +76,7 @@ export function EmbedUrlModal({ onOpenChange }) {
|
|
|
75
76
|
</Button>
|
|
76
77
|
</Flex>
|
|
77
78
|
</Dialog.Content>
|
|
78
|
-
</
|
|
79
|
+
</PrebuiltDialogPortal>
|
|
79
80
|
</Dialog.Root>
|
|
80
81
|
);
|
|
81
82
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { RefreshIcon } from '@100mslive/react-icons';
|
|
3
|
+
import { Button } from '../../Button';
|
|
4
|
+
import { Box, Flex } from '../../Layout';
|
|
5
|
+
import { Dialog } from '../../Modal';
|
|
6
|
+
import { Text } from '../../Text';
|
|
7
|
+
import { PrebuiltDialogPortal } from './PrebuiltDialogPortal';
|
|
8
|
+
import { isAndroid, isIOS } from '../common/constants';
|
|
9
|
+
|
|
10
|
+
export const MwebLandscapePrompt = () => {
|
|
11
|
+
const isMobile = isAndroid || isIOS;
|
|
12
|
+
const [showMwebLandscapePrompt, setShowMwebLandscapePrompt] = useState(false);
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const handleResize = () => {
|
|
16
|
+
setShowMwebLandscapePrompt(isMobile && window.innerHeight < window.innerWidth);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
handleResize();
|
|
20
|
+
window.addEventListener('resize', handleResize);
|
|
21
|
+
|
|
22
|
+
return () => {
|
|
23
|
+
window.removeEventListener('resize', handleResize);
|
|
24
|
+
};
|
|
25
|
+
}, []);
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<Dialog.Root open={showMwebLandscapePrompt} onOpenChange={setShowMwebLandscapePrompt}>
|
|
29
|
+
<PrebuiltDialogPortal>
|
|
30
|
+
<Dialog.Overlay />
|
|
31
|
+
<Dialog.Content css={{ w: 'min(420px, 90%)', p: '$8', bg: '$surface_dim' }}>
|
|
32
|
+
<Box>
|
|
33
|
+
<Flex
|
|
34
|
+
css={{
|
|
35
|
+
color: '$primary_default',
|
|
36
|
+
display: 'flex',
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
<RefreshIcon style={{ marginRight: '0.5rem' }} />
|
|
41
|
+
<Text variant="lg" css={{ color: '$on_surface_high', fontWeight: '$semiBold' }}>
|
|
42
|
+
Please rotate your device
|
|
43
|
+
</Text>
|
|
44
|
+
</Flex>
|
|
45
|
+
<Text variant="sm" css={{ color: '$on_surface_medium', mb: '$8', mt: '$4' }}>
|
|
46
|
+
We do not support landscape mode as of now, please use the app in portrait mode for the best experience.
|
|
47
|
+
</Text>
|
|
48
|
+
<Flex align="center" justify="between" css={{ w: '100%', gap: '$8' }}>
|
|
49
|
+
<Button outlined variant="standard" css={{ w: '100%' }} onClick={() => setShowMwebLandscapePrompt(false)}>
|
|
50
|
+
Continue anyway
|
|
51
|
+
</Button>
|
|
52
|
+
</Flex>
|
|
53
|
+
</Box>
|
|
54
|
+
</Dialog.Content>
|
|
55
|
+
</PrebuiltDialogPortal>
|
|
56
|
+
</Dialog.Root>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
@@ -4,6 +4,7 @@ import { Button } from '../../../Button';
|
|
|
4
4
|
import { Flex } from '../../../Layout';
|
|
5
5
|
import { Dialog } from '../../../Modal';
|
|
6
6
|
import { Text } from '../../../Text';
|
|
7
|
+
import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
|
|
7
8
|
import { useSetAppDataByKey } from '../AppData/useUISettings';
|
|
8
9
|
import { APP_DATA } from '../../common/constants';
|
|
9
10
|
|
|
@@ -37,7 +38,7 @@ export function HLSFailureModal() {
|
|
|
37
38
|
}
|
|
38
39
|
}}
|
|
39
40
|
>
|
|
40
|
-
<
|
|
41
|
+
<PrebuiltDialogPortal>
|
|
41
42
|
<Dialog.Overlay />
|
|
42
43
|
<Dialog.Content css={{ w: 'min(360px, 90%)' }}>
|
|
43
44
|
<Dialog.Title
|
|
@@ -65,7 +66,7 @@ export function HLSFailureModal() {
|
|
|
65
66
|
</Button>
|
|
66
67
|
</Flex>
|
|
67
68
|
</Dialog.Content>
|
|
68
|
-
</
|
|
69
|
+
</PrebuiltDialogPortal>
|
|
69
70
|
</Dialog.Root>
|
|
70
71
|
) : null;
|
|
71
72
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React, { useEffect } from 'react';
|
|
2
|
+
import { HMSNotificationTypes, useHMSNotifications } from '@100mslive/react-sdk';
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import { useIsNotificationDisabled } from '../AppData/useUISettings';
|
|
5
|
+
import { useRedirectToLeave } from '../hooks/useRedirectToLeave';
|
|
6
|
+
|
|
7
|
+
export function HeadlessEndRoomListener() {
|
|
8
|
+
const notification = useHMSNotifications();
|
|
9
|
+
const isNotificationDisabled = useIsNotificationDisabled();
|
|
10
|
+
const { redirectToLeave } = useRedirectToLeave();
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (!notification || !isNotificationDisabled) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if ([HMSNotificationTypes.ROOM_ENDED, HMSNotificationTypes.REMOVED_FROM_ROOM].includes(notification.type)) {
|
|
17
|
+
redirectToLeave(1000);
|
|
18
|
+
}
|
|
19
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
20
|
+
}, [notification]);
|
|
21
|
+
|
|
22
|
+
return <></>;
|
|
23
|
+
}
|
|
@@ -104,7 +104,7 @@ export function Notifications() {
|
|
|
104
104
|
close: false,
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
|
-
// goto leave for terminal if any action is not performed within
|
|
107
|
+
// goto leave for terminal if any action is not performed within 1s
|
|
108
108
|
// if network is still unavailable going to preview will throw an error
|
|
109
109
|
redirectToLeave(1000);
|
|
110
110
|
return;
|
|
@@ -4,6 +4,7 @@ import { HMSNotificationTypes, useHMSNotifications } from '@100mslive/react-sdk'
|
|
|
4
4
|
import { Button, config as cssConfig, Dialog, Flex, Text } from '../../../';
|
|
5
5
|
import androidPermissionAlert from '../../images/android-perm-1.png';
|
|
6
6
|
import iosPermissions from '../../images/ios-perm-0.png';
|
|
7
|
+
import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
|
|
7
8
|
import { isAndroid, isIOS } from '../../common/constants';
|
|
8
9
|
|
|
9
10
|
export function PermissionErrorModal() {
|
|
@@ -39,7 +40,7 @@ export function PermissionErrorModal() {
|
|
|
39
40
|
|
|
40
41
|
return deviceType ? (
|
|
41
42
|
<Dialog.Root open={!!deviceType}>
|
|
42
|
-
<
|
|
43
|
+
<PrebuiltDialogPortal>
|
|
43
44
|
<Dialog.Overlay />
|
|
44
45
|
<Dialog.Content css={{ w: 'min(380px, 90%)', p: '$8' }}>
|
|
45
46
|
<Dialog.Title
|
|
@@ -118,7 +119,7 @@ export function PermissionErrorModal() {
|
|
|
118
119
|
</Flex>
|
|
119
120
|
) : null}
|
|
120
121
|
</Dialog.Content>
|
|
121
|
-
</
|
|
122
|
+
</PrebuiltDialogPortal>
|
|
122
123
|
</Dialog.Root>
|
|
123
124
|
) : null;
|
|
124
125
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { Dialog } from '../../Modal';
|
|
3
|
+
|
|
4
|
+
export const PrebuiltDialogPortal = ({ children }: { children: ReactNode }) => (
|
|
5
|
+
<Dialog.Portal container={document.getElementById('prebuilt-container')}>{children}</Dialog.Portal>
|
|
6
|
+
);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { styled } from '../../Theme';
|
|
2
|
+
import { StyledVideoTile } from '../../VideoTile';
|
|
3
|
+
|
|
4
|
+
export const PrebuiltAudioIndicator = styled(StyledVideoTile.AudioIndicator, { height: '$12', width: '$12' });
|
|
5
|
+
export const PrebuiltAttributeBox = styled(StyledVideoTile.AttributeBox, { height: '$12', width: '$12' });
|
|
@@ -11,9 +11,12 @@ import {
|
|
|
11
11
|
useParticipants,
|
|
12
12
|
usePreviewJoin,
|
|
13
13
|
useRecordingStreaming,
|
|
14
|
+
// @ts-ignore: No implicit Any
|
|
14
15
|
} from '@100mslive/react-sdk';
|
|
16
|
+
// @ts-ignore: No implicit Any
|
|
15
17
|
import { MicOffIcon, SettingsIcon } from '@100mslive/react-icons';
|
|
16
18
|
import { Avatar, Box, config as cssConfig, Flex, flexCenter, styled, StyledVideoTile, Text, Video } from '../../..';
|
|
19
|
+
import { AudioLevel } from '../../../AudioLevel';
|
|
17
20
|
import { useHMSPrebuiltContext } from '../../AppContext';
|
|
18
21
|
// @ts-ignore: No implicit Any
|
|
19
22
|
import IconButton from '../../IconButton';
|
|
@@ -28,11 +31,10 @@ import TileConnection from '../Connection/TileConnection';
|
|
|
28
31
|
import FullPageProgress from '../FullPageProgress';
|
|
29
32
|
// @ts-ignore: No implicit Any
|
|
30
33
|
import { Logo } from '../Header/HeaderComponents';
|
|
34
|
+
import { PrebuiltAudioIndicator } from '../PrebuiltTileElements';
|
|
31
35
|
// @ts-ignore: No implicit Any
|
|
32
36
|
import SettingsModal from '../Settings/SettingsModal';
|
|
33
37
|
// @ts-ignore: No implicit Any
|
|
34
|
-
import { AudioLevel } from '../VideoTile';
|
|
35
|
-
// @ts-ignore: No implicit Any
|
|
36
38
|
import PreviewForm from './PreviewForm';
|
|
37
39
|
// @ts-ignore: No implicit Any
|
|
38
40
|
import { useAuthToken, useUISettings } from '../AppData/useUISettings';
|
|
@@ -233,7 +235,7 @@ export const PreviewTile = ({ name, error }: { name: string; error?: boolean })
|
|
|
233
235
|
|
|
234
236
|
{!isVideoOn ? (
|
|
235
237
|
<StyledVideoTile.AvatarContainer>
|
|
236
|
-
<Avatar name={name} data-testid="preview_avatar_tile" />
|
|
238
|
+
<Avatar name={name} data-testid="preview_avatar_tile" size="medium" />
|
|
237
239
|
</StyledVideoTile.AvatarContainer>
|
|
238
240
|
) : null}
|
|
239
241
|
</>
|
|
@@ -242,11 +244,13 @@ export const PreviewTile = ({ name, error }: { name: string; error?: boolean })
|
|
|
242
244
|
) : null}
|
|
243
245
|
|
|
244
246
|
{showMuteIcon ? (
|
|
245
|
-
<
|
|
246
|
-
<MicOffIcon />
|
|
247
|
-
</
|
|
247
|
+
<PrebuiltAudioIndicator>
|
|
248
|
+
<MicOffIcon height={16} width={16} />
|
|
249
|
+
</PrebuiltAudioIndicator>
|
|
248
250
|
) : (
|
|
249
|
-
<
|
|
251
|
+
<PrebuiltAudioIndicator>
|
|
252
|
+
<AudioLevel trackId={localPeer?.audioTrack} />
|
|
253
|
+
</PrebuiltAudioIndicator>
|
|
250
254
|
)}
|
|
251
255
|
</StyledVideoTile.Container>
|
|
252
256
|
);
|
|
@@ -9,6 +9,7 @@ import { Box, Flex } from '../../Layout';
|
|
|
9
9
|
import { Dialog } from '../../Modal';
|
|
10
10
|
import { Text } from '../../Text';
|
|
11
11
|
import { Tooltip } from '../../Tooltip';
|
|
12
|
+
import { PrebuiltDialogPortal } from './PrebuiltDialogPortal';
|
|
12
13
|
import { useDropdownSelection } from './hooks/useDropdownSelection';
|
|
13
14
|
import { useFilteredRoles } from '../common/hooks';
|
|
14
15
|
import { textEllipsis } from '../../utils';
|
|
@@ -47,7 +48,7 @@ export const RoleChangeModal = ({ peerId, onOpenChange }) => {
|
|
|
47
48
|
const peerNameMaxWidth = 200;
|
|
48
49
|
return (
|
|
49
50
|
<Dialog.Root defaultOpen onOpenChange={onOpenChange}>
|
|
50
|
-
<
|
|
51
|
+
<PrebuiltDialogPortal>
|
|
51
52
|
<Dialog.Overlay />
|
|
52
53
|
<Dialog.Content css={{ width: 'min(400px,80%)', p: '$10' }}>
|
|
53
54
|
<Dialog.Title css={{ p: 0 }} asChild>
|
|
@@ -179,7 +180,7 @@ export const RoleChangeModal = ({ peerId, onOpenChange }) => {
|
|
|
179
180
|
</Box>
|
|
180
181
|
</Flex>
|
|
181
182
|
</Dialog.Content>
|
|
182
|
-
</
|
|
183
|
+
</PrebuiltDialogPortal>
|
|
183
184
|
</Dialog.Root>
|
|
184
185
|
);
|
|
185
186
|
};
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { useMedia } from 'react-use';
|
|
3
3
|
import { Box, Button, config as cssConfig, Dialog, Flex, Text } from '../../..';
|
|
4
4
|
import { Sheet } from '../../../Sheet';
|
|
5
|
+
import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
|
|
5
6
|
|
|
6
7
|
export const RequestPrompt = ({
|
|
7
8
|
open = true,
|
|
@@ -34,7 +35,7 @@ export const RequestPrompt = ({
|
|
|
34
35
|
|
|
35
36
|
return (
|
|
36
37
|
<Dialog.Root open={open} onOpenChange={onOpenChange}>
|
|
37
|
-
<
|
|
38
|
+
<PrebuiltDialogPortal>
|
|
38
39
|
<Dialog.Overlay />
|
|
39
40
|
<Dialog.Content css={{ p: '$10' }}>
|
|
40
41
|
<Dialog.Title css={{ p: 0, display: 'flex', flexDirection: 'row', gap: '$md', justifyContent: 'center' }}>
|
|
@@ -43,7 +44,7 @@ export const RequestPrompt = ({
|
|
|
43
44
|
<Box css={{ mt: '$4', mb: '$10' }}>{body}</Box>
|
|
44
45
|
<RequestActions actionText={actionText} onAction={onAction} />
|
|
45
46
|
</Dialog.Content>
|
|
46
|
-
</
|
|
47
|
+
</PrebuiltDialogPortal>
|
|
47
48
|
</Dialog.Root>
|
|
48
49
|
);
|
|
49
50
|
};
|
|
@@ -9,6 +9,7 @@ import { Sheet } from '../../../Sheet';
|
|
|
9
9
|
import { Tabs } from '../../../Tabs';
|
|
10
10
|
import { Text } from '../../../Text';
|
|
11
11
|
import { config as cssConfig } from '../../../Theme';
|
|
12
|
+
import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
|
|
12
13
|
import { settingContent, settingsList } from './common.js';
|
|
13
14
|
|
|
14
15
|
const SettingsModal = ({ open, onOpenChange, screenType, children = <></> }) => {
|
|
@@ -186,7 +187,7 @@ const DesktopSettingModal = ({
|
|
|
186
187
|
return (
|
|
187
188
|
<Dialog.Root open={open} onOpenChange={onOpenChange}>
|
|
188
189
|
<Dialog.Trigger asChild>{children}</Dialog.Trigger>
|
|
189
|
-
<
|
|
190
|
+
<PrebuiltDialogPortal>
|
|
190
191
|
<Dialog.Overlay />
|
|
191
192
|
<Dialog.Content
|
|
192
193
|
css={{
|
|
@@ -256,7 +257,7 @@ const DesktopSettingModal = ({
|
|
|
256
257
|
</IconButton>
|
|
257
258
|
</Dialog.Close>
|
|
258
259
|
</Dialog.Content>
|
|
259
|
-
</
|
|
260
|
+
</PrebuiltDialogPortal>
|
|
260
261
|
</Dialog.Root>
|
|
261
262
|
);
|
|
262
263
|
};
|
|
@@ -2,6 +2,7 @@ import React, { useState } from 'react';
|
|
|
2
2
|
import { selectPermissions, useHMSActions, useHMSStore, useRecordingStreaming } from '@100mslive/react-sdk';
|
|
3
3
|
import { AlertTriangleIcon } from '@100mslive/react-icons';
|
|
4
4
|
import { Button, Dialog, Flex, Text } from '../../../';
|
|
5
|
+
import { PrebuiltDialogPortal } from '../PrebuiltDialogPortal';
|
|
5
6
|
import { ResolutionInput } from '../Streaming/ResolutionInput';
|
|
6
7
|
import { getResolution } from '../Streaming/RTMPStreaming';
|
|
7
8
|
import { ToastManager } from '../Toast/ToastManager';
|
|
@@ -21,7 +22,7 @@ const StartRecording = ({ open, onOpenChange }) => {
|
|
|
21
22
|
if (isBrowserRecordingOn) {
|
|
22
23
|
return (
|
|
23
24
|
<Dialog.Root open={open} onOpenChange={onOpenChange}>
|
|
24
|
-
<
|
|
25
|
+
<PrebuiltDialogPortal>
|
|
25
26
|
<Dialog.Content
|
|
26
27
|
css={{
|
|
27
28
|
width: 'min(400px,80%)',
|
|
@@ -66,7 +67,7 @@ const StartRecording = ({ open, onOpenChange }) => {
|
|
|
66
67
|
</Button>
|
|
67
68
|
</Flex>
|
|
68
69
|
</Dialog.Content>
|
|
69
|
-
</
|
|
70
|
+
</PrebuiltDialogPortal>
|
|
70
71
|
</Dialog.Root>
|
|
71
72
|
);
|
|
72
73
|
}
|