@100mslive/roomkit-react 0.1.7 → 0.1.8-alpha.0
Sign up to get free protection for your applications and to get access to all the features.
- 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-IQRPLYNH.js} +5 -4
- package/dist/{HLSView-3S74KF3A.js.map → HLSView-IQRPLYNH.js.map} +2 -2
- package/dist/Prebuilt/components/Chip.d.ts +12 -0
- package/dist/Prebuilt/components/PrebuiltDialogPortal.d.ts +4 -0
- package/dist/{VirtualBackground-3TI5NA4V.js → VirtualBackground-GP4ATXD3.js} +3 -3
- package/dist/{chunk-36X4ZCLC.js → chunk-2H5NIZB7.js} +2 -2
- package/dist/{chunk-Z7P5WITU.js → chunk-GLYGPYNS.js} +560 -1190
- package/dist/chunk-GLYGPYNS.js.map +7 -0
- package/dist/{chunk-5DQ3WTED.js → chunk-Z3O2WGWV.js} +2 -2
- package/dist/{chunk-5DQ3WTED.js.map → chunk-Z3O2WGWV.js.map} +1 -1
- package/dist/{conference-JNABIZBG.js → conference-JD35TNH4.js} +1351 -662
- package/dist/conference-JD35TNH4.js.map +7 -0
- package/dist/index.cjs.js +3387 -3297
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +4 -2
- package/dist/meta.cjs.json +1001 -826
- package/dist/meta.esbuild.json +1053 -877
- 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 +1 -0
- package/src/Prebuilt/common/utils.js +0 -7
- package/src/Prebuilt/components/{Chip.jsx → Chip.tsx} +13 -2
- package/src/Prebuilt/components/Footer/ParticipantList.jsx +23 -12
- package/src/Prebuilt/components/Footer/RoleAccordion.tsx +43 -3
- 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/PermissionErrorModal.jsx +3 -2
- package/src/Prebuilt/components/PrebuiltDialogPortal.tsx +6 -0
- package/src/Prebuilt/components/Preview/PreviewJoin.tsx +4 -3
- 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/StatsForNerds.jsx +3 -2
- package/src/Prebuilt/components/VideoTile.jsx +22 -69
- 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/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-GP4ATXD3.js.map} +0 -0
- /package/dist/{chunk-36X4ZCLC.js.map → chunk-2H5NIZB7.js.map} +0 -0
package/package.json
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
"prebuilt",
|
11
11
|
"roomkit"
|
12
12
|
],
|
13
|
-
"version": "0.1.
|
13
|
+
"version": "0.1.8-alpha.0",
|
14
14
|
"author": "100ms",
|
15
15
|
"license": "MIT",
|
16
16
|
"files": [
|
@@ -76,10 +76,10 @@
|
|
76
76
|
"react": ">=17.0.2 <19.0.0"
|
77
77
|
},
|
78
78
|
"dependencies": {
|
79
|
-
"@100mslive/hls-player": "0.1.
|
80
|
-
"@100mslive/hms-virtual-background": "1.11.
|
81
|
-
"@100mslive/react-icons": "0.8.
|
82
|
-
"@100mslive/react-sdk": "0.8.
|
79
|
+
"@100mslive/hls-player": "0.1.17-alpha.0",
|
80
|
+
"@100mslive/hms-virtual-background": "1.11.17-alpha.0",
|
81
|
+
"@100mslive/react-icons": "0.8.17-alpha.0",
|
82
|
+
"@100mslive/react-sdk": "0.8.17-alpha.0",
|
83
83
|
"@100mslive/types-prebuilt": "0.12.0",
|
84
84
|
"@emoji-mart/data": "^1.0.6",
|
85
85
|
"@emoji-mart/react": "^1.0.1",
|
@@ -115,5 +115,5 @@
|
|
115
115
|
"uuid": "^8.3.2",
|
116
116
|
"worker-timers": "^7.0.40"
|
117
117
|
},
|
118
|
-
"gitHead": "
|
118
|
+
"gitHead": "d6e072de081b508a297ebc1684a33a8e9db048ef"
|
119
119
|
}
|
@@ -1,34 +1,83 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
2
|
+
import { selectTrackAudioByID, useHMSVanillaStore } from '@100mslive/react-sdk';
|
3
|
+
import { Box, Flex } from '../Layout';
|
4
|
+
import { keyframes } from '../Theme';
|
5
|
+
//@ts-ignore
|
6
|
+
import bg from './audio-level.png';
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
*
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
8
|
+
// keep the calculated values before hand to avoid recalcuation everytime
|
9
|
+
const positionValues = new Array(101).fill(0).reduce((acc, _, index) => {
|
10
|
+
acc[index] = Math.round((index / 100) * 4) / 4; // convert to 0.25 multiples
|
11
|
+
return acc;
|
12
|
+
}, {});
|
13
|
+
|
14
|
+
const barAnimation = keyframes({
|
15
|
+
from: {
|
16
|
+
maskSize: '4em .8em',
|
17
|
+
'-webkit-mask-position-y': '.1em',
|
18
|
+
maskPosition: 'initial .1em',
|
19
|
+
},
|
20
|
+
|
21
|
+
'50%': {
|
22
|
+
maskSize: '4em 1em',
|
23
|
+
'-webkit-mask-position-y': 0,
|
24
|
+
maskPosition: 'initial 0',
|
25
|
+
},
|
26
|
+
|
27
|
+
to: {
|
28
|
+
maskSize: '4em .8em',
|
29
|
+
'-webkit-mask-position-y': '.1em',
|
30
|
+
maskPosition: 'initial 0',
|
31
|
+
},
|
32
|
+
});
|
33
|
+
|
34
|
+
const AudioBar = () => {
|
35
|
+
return (
|
36
|
+
<Box
|
37
|
+
css={{
|
38
|
+
width: '.25em',
|
39
|
+
height: '1em',
|
40
|
+
maskImage: `url(${bg})`,
|
41
|
+
'-webkit-mask-repeat': 'no-repeat',
|
42
|
+
backgroundColor: '$on_primary_high',
|
43
|
+
maskSize: '4em 1em',
|
44
|
+
}}
|
45
|
+
/>
|
22
46
|
);
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
});
|
29
|
-
return ref;
|
30
|
-
}
|
47
|
+
};
|
48
|
+
|
49
|
+
export const AudioLevel = ({ trackId, size }: { trackId?: string; size?: 'small' | 'medium' }) => {
|
50
|
+
const ref = useRef<HTMLDivElement | null>(null);
|
51
|
+
const vanillaStore = useHMSVanillaStore();
|
31
52
|
|
32
|
-
|
33
|
-
|
53
|
+
useEffect(() => {
|
54
|
+
const unsubscribe = vanillaStore.subscribe(audioLevel => {
|
55
|
+
if (ref.current) {
|
56
|
+
let index = 0;
|
57
|
+
//@ts-ignore
|
58
|
+
for (const child of ref.current.children) {
|
59
|
+
const positionX = `-${positionValues[audioLevel] * (index === 1 ? 2.5 : 1.25)}em`;
|
60
|
+
child.style['-webkit-mask-position-x'] = positionX;
|
61
|
+
child.style['mask-position'] = `${positionX} 0`;
|
62
|
+
child.style['animation'] =
|
63
|
+
positionValues[audioLevel] > 0 ? `${barAnimation} 0.6s steps(3,jump-none) 0s infinite` : 'none';
|
64
|
+
index++;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}, selectTrackAudioByID(trackId));
|
68
|
+
return unsubscribe;
|
69
|
+
}, [vanillaStore, trackId]);
|
70
|
+
return (
|
71
|
+
<Flex
|
72
|
+
ref={ref}
|
73
|
+
css={{
|
74
|
+
fontSize: size === 'small' ? '0.75rem' : '1rem',
|
75
|
+
gap: size === 'small' ? '$1' : '$2',
|
76
|
+
}}
|
77
|
+
>
|
78
|
+
<AudioBar />
|
79
|
+
<AudioBar />
|
80
|
+
<AudioBar />
|
81
|
+
</Flex>
|
82
|
+
);
|
34
83
|
};
|
Binary file
|
package/src/AudioLevel/index.ts
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
export { useBorderAudioLevel } from './
|
1
|
+
export { useBorderAudioLevel } from './useBorderAudioLevel';
|
2
|
+
export { AudioLevel } from './AudioLevel';
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import { useCallback, useRef } from 'react';
|
2
|
+
import { HMSTrackID } from '@100mslive/hms-video-store';
|
3
|
+
import { useAudioLevelStyles } from '@100mslive/react-sdk';
|
4
|
+
import { useTheme } from '../Theme';
|
5
|
+
|
6
|
+
/**
|
7
|
+
* pass in a track id and get a ref. That ref can be attached to an element which will have border
|
8
|
+
* as per audio level post that.
|
9
|
+
*/
|
10
|
+
export function useBorderAudioLevel(audioTrackId?: HMSTrackID) {
|
11
|
+
const { theme } = useTheme();
|
12
|
+
const color = theme.colors.primary_default.value;
|
13
|
+
const getStyle = useCallback(
|
14
|
+
(level: number) => {
|
15
|
+
const style: Record<string, string> = {
|
16
|
+
transition: 'outline 0.4s ease-in-out',
|
17
|
+
};
|
18
|
+
style['outline'] = level ? `${sigmoid(level) * 4}px solid ${color}` : '0px solid transparent';
|
19
|
+
return style;
|
20
|
+
},
|
21
|
+
[color],
|
22
|
+
);
|
23
|
+
const ref = useRef(null);
|
24
|
+
useAudioLevelStyles({
|
25
|
+
trackId: audioTrackId,
|
26
|
+
getStyle,
|
27
|
+
ref,
|
28
|
+
});
|
29
|
+
return ref;
|
30
|
+
}
|
31
|
+
|
32
|
+
export const sigmoid = (z: number) => {
|
33
|
+
return 1 / (1 + Math.exp(-z));
|
34
|
+
};
|
package/src/Prebuilt/App.tsx
CHANGED
@@ -218,6 +218,7 @@ export const HMSPrebuilt = React.forwardRef<HMSPrebuiltRefType, HMSPrebuiltProps
|
|
218
218
|
<AppData appDetails={metadata} tokenEndpoint={tokenByRoomIdRoleEndpoint} />
|
219
219
|
<Init />
|
220
220
|
<Box
|
221
|
+
id="prebuilt-container"
|
221
222
|
css={{
|
222
223
|
bg: '$background_dim',
|
223
224
|
size: '100%',
|
@@ -88,10 +88,3 @@ export const formatTime = timeInSeconds => {
|
|
88
88
|
const hour = hours !== 0 ? `${hours < 10 ? '0' : ''}${hours}:` : '';
|
89
89
|
return `${hour}${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
|
90
90
|
};
|
91
|
-
|
92
|
-
export const getAttributeBoxSize = (width, height) => {
|
93
|
-
if (!width || !height) {
|
94
|
-
return '';
|
95
|
-
}
|
96
|
-
return width < 180 || height < 180 ? 'small' : 'medium';
|
97
|
-
};
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { Flex } from '../../Layout';
|
3
3
|
import { Text } from '../../Text';
|
4
|
+
import { CSS } from '../../Theme';
|
4
5
|
|
5
6
|
const Chip = ({
|
6
7
|
icon = <></>,
|
@@ -8,12 +9,22 @@ const Chip = ({
|
|
8
9
|
backgroundColor = '$surface_default',
|
9
10
|
textColor = '$on_surface_high',
|
10
11
|
hideIfNoContent = false,
|
12
|
+
onClick,
|
13
|
+
css = {},
|
14
|
+
}: {
|
15
|
+
icon?: React.JSX.Element;
|
16
|
+
content: string;
|
17
|
+
backgroundColor?: string;
|
18
|
+
textColor?: string;
|
19
|
+
hideIfNoContent?: boolean;
|
20
|
+
onClick?: () => void | Promise<void>;
|
21
|
+
css?: CSS;
|
11
22
|
}) => {
|
12
23
|
if (hideIfNoContent && !content) {
|
13
|
-
return;
|
24
|
+
return null;
|
14
25
|
}
|
15
26
|
return (
|
16
|
-
<Flex align="center" css={{ backgroundColor, p: '$4 $6', borderRadius: '$4' }}>
|
27
|
+
<Flex align="center" css={{ backgroundColor, p: '$4 $6', borderRadius: '$4', ...css }} onClick={() => onClick?.()}>
|
17
28
|
{icon}
|
18
29
|
<Text variant="sm" css={{ fontWeight: '$semiBold', color: textColor, ml: '$2' }}>
|
19
30
|
{content}
|
@@ -127,13 +127,15 @@ const VirtualizedParticipants = ({ peersOrderedByRoles = {}, isConnected, filter
|
|
127
127
|
flex: '1 1 0',
|
128
128
|
}}
|
129
129
|
>
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
130
|
+
{handRaisedList.length > 0 ? (
|
131
|
+
<RoleAccordion
|
132
|
+
peerList={handRaisedList}
|
133
|
+
roleName="Hand Raised"
|
134
|
+
filter={filter}
|
135
|
+
isConnected={isConnected}
|
136
|
+
isHandRaisedAccordion
|
137
|
+
/>
|
138
|
+
) : null}
|
137
139
|
{Object.keys(peersOrderedByRoles).map(role => (
|
138
140
|
<RoleAccordion
|
139
141
|
key={role}
|
@@ -179,7 +181,10 @@ export const Participant = ({ peer, isConnected }) => {
|
|
179
181
|
const ParticipantActions = React.memo(({ peerId, role, isLocal }) => {
|
180
182
|
const isHandRaised = useHMSStore(selectHasPeerHandRaised(peerId));
|
181
183
|
const canChangeRole = useHMSStore(selectPermissions)?.changeRole;
|
182
|
-
const
|
184
|
+
const canRemoveOthers = useHMSStore(selectPermissions)?.removeOthers;
|
185
|
+
const { elements } = useRoomLayoutConferencingScreen();
|
186
|
+
const { on_stage_exp } = elements || {};
|
187
|
+
const shouldShowMoreActions = (on_stage_exp && canChangeRole) || canRemoveOthers;
|
183
188
|
const isAudioMuted = !useHMSStore(selectIsPeerAudioEnabled(peerId));
|
184
189
|
|
185
190
|
return (
|
@@ -210,15 +215,21 @@ const ParticipantActions = React.memo(({ peerId, role, isLocal }) => {
|
|
210
215
|
</Flex>
|
211
216
|
) : null}
|
212
217
|
|
213
|
-
{shouldShowMoreActions && !isLocal ?
|
218
|
+
{shouldShowMoreActions && !isLocal ? (
|
219
|
+
<ParticipantMoreActions
|
220
|
+
peerId={peerId}
|
221
|
+
role={role}
|
222
|
+
elements={elements}
|
223
|
+
canChangeRole={canChangeRole}
|
224
|
+
canRemoveOthers={canRemoveOthers}
|
225
|
+
/>
|
226
|
+
) : null}
|
214
227
|
</Flex>
|
215
228
|
);
|
216
229
|
});
|
217
230
|
|
218
|
-
const ParticipantMoreActions = ({ peerId, role }) => {
|
231
|
+
const ParticipantMoreActions = ({ peerId, role, elements, canChangeRole, canRemoveOthers }) => {
|
219
232
|
const hmsActions = useHMSActions();
|
220
|
-
const { changeRole: canChangeRole, removeOthers: canRemoveOthers } = useHMSStore(selectPermissions);
|
221
|
-
const { elements } = useRoomLayoutConferencingScreen();
|
222
233
|
const {
|
223
234
|
bring_to_stage_label,
|
224
235
|
remove_from_stage_label,
|
@@ -1,10 +1,12 @@
|
|
1
|
-
import React from 'react';
|
1
|
+
import React, { useCallback, useEffect, useRef, useState } 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, HMSPeerListIterator, useHMSActions } from '@100mslive/react-sdk';
|
5
|
+
import { AddCircleIcon } from '@100mslive/react-icons';
|
5
6
|
import { Accordion } from '../../../Accordion';
|
6
7
|
import { Box, Flex } from '../../../Layout';
|
7
8
|
import { Text } from '../../../Text';
|
9
|
+
import Chip from '../Chip';
|
8
10
|
// @ts-ignore: No implicit Any
|
9
11
|
import { Participant } from './ParticipantList';
|
10
12
|
import { RoleOptions } from './RoleOptions';
|
@@ -38,11 +40,34 @@ export const RoleAccordion = ({
|
|
38
40
|
filter?: { search: string };
|
39
41
|
}) => {
|
40
42
|
const [ref, { width }] = useMeasure<HTMLDivElement>();
|
43
|
+
const actions = useHMSActions();
|
41
44
|
const showAcordion = filter?.search ? peerList.some(peer => peer.name.toLowerCase().includes(filter.search)) : true;
|
45
|
+
const [hasNext, setHasNext] = useState(false);
|
46
|
+
const iteratorRef = useRef<HMSPeerListIterator | null>(null);
|
42
47
|
|
43
|
-
|
48
|
+
const loadNext = useCallback(() => {
|
49
|
+
if (!roleName || roleName === 'Hand Raised') {
|
50
|
+
return;
|
51
|
+
}
|
52
|
+
if (!iteratorRef.current) {
|
53
|
+
iteratorRef.current = actions.getPeerListIterator({ role: roleName });
|
54
|
+
}
|
55
|
+
iteratorRef.current
|
56
|
+
.next()
|
57
|
+
.catch(console.error)
|
58
|
+
.finally(() => {
|
59
|
+
setHasNext(iteratorRef.current ? iteratorRef.current.hasNext() : false);
|
60
|
+
});
|
61
|
+
}, [actions, roleName]);
|
62
|
+
|
63
|
+
useEffect(() => {
|
64
|
+
loadNext();
|
65
|
+
}, [loadNext]);
|
66
|
+
|
67
|
+
if (!showAcordion || (isHandRaisedAccordion && filter?.search) || (peerList.length === 0 && filter?.search)) {
|
44
68
|
return null;
|
45
69
|
}
|
70
|
+
|
46
71
|
const height = ROW_HEIGHT * peerList.length;
|
47
72
|
|
48
73
|
return (
|
@@ -86,6 +111,21 @@ export const RoleAccordion = ({
|
|
86
111
|
>
|
87
112
|
{VirtualizedParticipantItem}
|
88
113
|
</FixedSizeList>
|
114
|
+
{hasNext ? (
|
115
|
+
<Chip
|
116
|
+
icon={<AddCircleIcon />}
|
117
|
+
content="Load More"
|
118
|
+
onClick={loadNext}
|
119
|
+
backgroundColor="$secondary_default"
|
120
|
+
css={{
|
121
|
+
w: 'max-content',
|
122
|
+
borderRadius: '$size$9',
|
123
|
+
m: '$2 auto',
|
124
|
+
p: '$4',
|
125
|
+
cursor: 'pointer',
|
126
|
+
}}
|
127
|
+
/>
|
128
|
+
) : null}
|
89
129
|
</Accordion.Content>
|
90
130
|
</Accordion.Item>
|
91
131
|
</Accordion.Root>
|
@@ -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
|
}
|
@@ -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
|
+
);
|
@@ -14,6 +14,7 @@ import {
|
|
14
14
|
} from '@100mslive/react-sdk';
|
15
15
|
import { MicOffIcon, SettingsIcon } from '@100mslive/react-icons';
|
16
16
|
import { Avatar, Box, config as cssConfig, Flex, flexCenter, styled, StyledVideoTile, Text, Video } from '../../..';
|
17
|
+
import { AudioLevel } from '../../../AudioLevel';
|
17
18
|
import { useHMSPrebuiltContext } from '../../AppContext';
|
18
19
|
// @ts-ignore: No implicit Any
|
19
20
|
import IconButton from '../../IconButton';
|
@@ -31,8 +32,6 @@ import { Logo } from '../Header/HeaderComponents';
|
|
31
32
|
// @ts-ignore: No implicit Any
|
32
33
|
import SettingsModal from '../Settings/SettingsModal';
|
33
34
|
// @ts-ignore: No implicit Any
|
34
|
-
import { AudioLevel } from '../VideoTile';
|
35
|
-
// @ts-ignore: No implicit Any
|
36
35
|
import PreviewForm from './PreviewForm';
|
37
36
|
// @ts-ignore: No implicit Any
|
38
37
|
import { useAuthToken, useUISettings } from '../AppData/useUISettings';
|
@@ -246,7 +245,9 @@ export const PreviewTile = ({ name, error }: { name: string; error?: boolean })
|
|
246
245
|
<MicOffIcon />
|
247
246
|
</StyledVideoTile.AudioIndicator>
|
248
247
|
) : (
|
249
|
-
<
|
248
|
+
<StyledVideoTile.AudioIndicator size="medium">
|
249
|
+
<AudioLevel trackId={localPeer?.audioTrack} />
|
250
|
+
</StyledVideoTile.AudioIndicator>
|
250
251
|
)}
|
251
252
|
</StyledVideoTile.Container>
|
252
253
|
);
|
@@ -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
|
};
|