@100mslive/roomkit-react 0.3.8-alpha.0 → 0.3.8-alpha.2
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-CTZXD762.js → HLSView-XZDT3RRC.js} +2 -2
- package/dist/Prebuilt/common/constants.d.ts +2 -0
- package/dist/Prebuilt/common/hooks.d.ts +10 -0
- package/dist/Prebuilt/components/CaptionIcon.d.ts +2 -0
- package/dist/Prebuilt/components/FullPageProgress.d.ts +8 -0
- package/dist/Prebuilt/components/VirtualBackground/VBHandler.d.ts +3 -3
- package/dist/Prebuilt/plugins/CaptionsViewer.d.ts +2 -0
- package/dist/Text/Text.d.ts +1 -1
- package/dist/{chunk-NDLMRKFR.js → chunk-SQPIZNW2.js} +2367 -2128
- package/dist/chunk-SQPIZNW2.js.map +7 -0
- package/dist/index.cjs.js +3254 -2998
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +1 -1
- package/dist/meta.cjs.json +244 -86
- package/dist/meta.esbuild.json +250 -92
- package/package.json +6 -6
- package/src/Prebuilt/common/constants.ts +2 -0
- package/src/Prebuilt/common/hooks.ts +72 -1
- package/src/Prebuilt/components/AppData/AppData.tsx +2 -0
- package/src/Prebuilt/components/AppData/useUISettings.js +10 -0
- package/src/Prebuilt/components/CaptionIcon.tsx +27 -0
- package/src/Prebuilt/components/ConferenceScreen.tsx +34 -4
- package/src/Prebuilt/components/Footer/Footer.tsx +2 -0
- package/src/Prebuilt/components/Footer/RoleAccordion.tsx +1 -1
- package/src/Prebuilt/components/{FullPageProgress.jsx → FullPageProgress.tsx} +10 -1
- package/src/Prebuilt/components/Header/StreamActions.tsx +3 -25
- package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +25 -26
- package/src/Prebuilt/components/Notifications/PeerNotifications.tsx +1 -11
- package/src/Prebuilt/components/Preview/PreviewJoin.tsx +4 -9
- package/src/Prebuilt/components/Preview/PreviewScreen.tsx +0 -3
- package/src/Prebuilt/components/Settings/StartRecording.jsx +4 -37
- package/src/Prebuilt/components/Toast/ToastConfig.jsx +0 -22
- package/src/Prebuilt/components/VirtualBackground/VBHandler.tsx +3 -3
- package/src/Prebuilt/components/VirtualBackground/VBOption.tsx +3 -1
- package/src/Prebuilt/components/VirtualBackground/VBPicker.tsx +23 -7
- package/src/Prebuilt/components/VirtualBackground/VBToggle.tsx +5 -3
- package/src/Prebuilt/layouts/VideoStreamingSection.tsx +0 -3
- package/src/Prebuilt/plugins/CaptionsViewer.tsx +191 -0
- package/dist/chunk-NDLMRKFR.js.map +0 -7
- /package/dist/{HLSView-CTZXD762.js.map → HLSView-XZDT3RRC.js.map} +0 -0
@@ -72,28 +72,6 @@ const HandRaiseAction = React.forwardRef(({ id = '', isSingleHandRaise = true },
|
|
72
72
|
});
|
73
73
|
|
74
74
|
export const ToastConfig = {
|
75
|
-
PEER_LIST: {
|
76
|
-
single: function (notification) {
|
77
|
-
if (notification.data.length === 1) {
|
78
|
-
return {
|
79
|
-
title: `${notification.data[0]?.name} joined`,
|
80
|
-
icon: <PeopleAddIcon />,
|
81
|
-
};
|
82
|
-
}
|
83
|
-
return {
|
84
|
-
title: `${notification.data[notification.data.length - 1]?.name} and ${
|
85
|
-
notification.data.length - 1
|
86
|
-
} others joined`,
|
87
|
-
icon: <PeopleAddIcon />,
|
88
|
-
};
|
89
|
-
},
|
90
|
-
multiple: notifications => {
|
91
|
-
return {
|
92
|
-
title: `${notifications[0].data.name} and ${notifications.length - 1} others joined`,
|
93
|
-
icon: <PeopleAddIcon />,
|
94
|
-
};
|
95
|
-
},
|
96
|
-
},
|
97
75
|
PEER_JOINED: {
|
98
76
|
single: function (notification) {
|
99
77
|
return {
|
@@ -4,12 +4,12 @@ export class VBPlugin {
|
|
4
4
|
private hmsPlugin?: HMSVBPlugin;
|
5
5
|
private effectsPlugin?: HMSEffectsPlugin | undefined;
|
6
6
|
|
7
|
-
initialisePlugin = (effectsSDKKey?: string) => {
|
7
|
+
initialisePlugin = (effectsSDKKey?: string, onInit?: () => void) => {
|
8
8
|
if (this.getVBObject()) {
|
9
9
|
return;
|
10
10
|
}
|
11
11
|
if (effectsSDKKey) {
|
12
|
-
this.effectsPlugin = new HMSEffectsPlugin(effectsSDKKey);
|
12
|
+
this.effectsPlugin = new HMSEffectsPlugin(effectsSDKKey, onInit);
|
13
13
|
} else {
|
14
14
|
this.hmsPlugin = new HMSVBPlugin(HMSVirtualBackgroundTypes.NONE, HMSVirtualBackgroundTypes.NONE);
|
15
15
|
}
|
@@ -70,7 +70,7 @@ export class VBPlugin {
|
|
70
70
|
}
|
71
71
|
};
|
72
72
|
|
73
|
-
setPreset = async (preset:
|
73
|
+
setPreset = async (preset: 'quality' | 'balanced') => {
|
74
74
|
if (this.effectsPlugin) {
|
75
75
|
await this.effectsPlugin.setPreset(preset);
|
76
76
|
}
|
@@ -28,7 +28,9 @@ const Root = ({
|
|
28
28
|
'&:hover': { border: '4px solid $primary_dim' },
|
29
29
|
...(mediaURL ? { height: '$20', backgroundImage: `url(${mediaURL})`, backgroundSize: 'cover' } : {}),
|
30
30
|
}}
|
31
|
-
onClick={async () =>
|
31
|
+
onClick={async () => {
|
32
|
+
await onClick?.();
|
33
|
+
}}
|
32
34
|
>
|
33
35
|
{children}
|
34
36
|
</Flex>
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
2
|
+
import { useMedia } from 'react-use';
|
2
3
|
import {
|
3
4
|
selectAppData,
|
4
5
|
selectEffectsKey,
|
@@ -19,14 +20,14 @@ import {
|
|
19
20
|
useHMSStore,
|
20
21
|
} from '@100mslive/react-sdk';
|
21
22
|
import { BlurPersonHighIcon, CrossCircleIcon, CrossIcon } from '@100mslive/react-icons';
|
22
|
-
import { Box, Flex, Slider, Video } from '../../../index';
|
23
|
+
import { Box, config as cssConfig, Flex, Loading, Slider, Video } from '../../../index';
|
23
24
|
import { Text } from '../../../Text';
|
24
25
|
import { VBCollection } from './VBCollection';
|
25
26
|
import { VBHandler } from './VBHandler';
|
26
27
|
// @ts-ignore
|
27
28
|
import { useSidepaneToggle } from '../AppData/useSidepane';
|
28
29
|
// @ts-ignore
|
29
|
-
import { useUISettings } from '../AppData/useUISettings';
|
30
|
+
import { useSetAppDataByKey, useUISettings } from '../AppData/useUISettings';
|
30
31
|
import { APP_DATA, SIDE_PANE_OPTIONS, UI_SETTINGS } from '../../common/constants';
|
31
32
|
import { defaultMedia } from './constants';
|
32
33
|
|
@@ -46,6 +47,8 @@ export const VBPicker = ({ backgroundMedia = [] }: { backgroundMedia: VirtualBac
|
|
46
47
|
const isLargeRoom = useHMSStore(selectIsLargeRoom);
|
47
48
|
const isEffectsEnabled = useHMSStore(selectIsEffectsEnabled);
|
48
49
|
const effectsKey = useHMSStore(selectEffectsKey);
|
50
|
+
const isMobile = useMedia(cssConfig.media.md);
|
51
|
+
const [loadingEffects, setLoadingEffects] = useSetAppDataByKey(APP_DATA.loadingEffects);
|
49
52
|
const isPluginAdded = useHMSStore(selectIsLocalVideoPluginPresent(VBHandler?.getName() || ''));
|
50
53
|
const background = useHMSStore(selectAppData(APP_DATA.background));
|
51
54
|
const mediaList = backgroundMedia.length
|
@@ -61,13 +64,15 @@ export const VBPicker = ({ backgroundMedia = [] }: { backgroundMedia: VirtualBac
|
|
61
64
|
return;
|
62
65
|
}
|
63
66
|
if (!isPluginAdded) {
|
67
|
+
setLoadingEffects(true);
|
64
68
|
let vbObject = VBHandler.getVBObject();
|
65
69
|
if (!vbObject) {
|
66
|
-
VBHandler.initialisePlugin(isEffectsEnabled && effectsKey ? effectsKey : '');
|
70
|
+
VBHandler.initialisePlugin(isEffectsEnabled && effectsKey ? effectsKey : '', () => setLoadingEffects(false));
|
67
71
|
vbObject = VBHandler.getVBObject();
|
68
72
|
if (isEffectsEnabled && effectsKey) {
|
69
73
|
hmsActions.addPluginsToVideoStream([vbObject as HMSEffectsPlugin]);
|
70
74
|
} else {
|
75
|
+
setLoadingEffects(false);
|
71
76
|
if (!role) {
|
72
77
|
return;
|
73
78
|
}
|
@@ -89,19 +94,30 @@ export const VBPicker = ({ backgroundMedia = [] }: { backgroundMedia: VirtualBac
|
|
89
94
|
};
|
90
95
|
handleDefaultBackground();
|
91
96
|
}
|
92
|
-
}, [
|
97
|
+
}, [
|
98
|
+
hmsActions,
|
99
|
+
role,
|
100
|
+
isPluginAdded,
|
101
|
+
isEffectsEnabled,
|
102
|
+
effectsKey,
|
103
|
+
track?.id,
|
104
|
+
background,
|
105
|
+
blurAmount,
|
106
|
+
setLoadingEffects,
|
107
|
+
]);
|
93
108
|
|
94
109
|
useEffect(() => {
|
95
110
|
if (!isVideoOn) {
|
96
111
|
toggleVB();
|
97
112
|
}
|
98
|
-
|
113
|
+
return () => setLoadingEffects(false);
|
114
|
+
}, [isVideoOn, setLoadingEffects, toggleVB]);
|
99
115
|
|
100
116
|
return (
|
101
117
|
<Flex css={{ pr: '$6', size: '100%' }} direction="column">
|
102
118
|
<Flex align="center" justify="between" css={{ w: '100%', background: '$surface_dim', pb: '$4' }}>
|
103
|
-
<Text variant="h6" css={{ color: '$on_surface_high' }}>
|
104
|
-
Virtual Background
|
119
|
+
<Text variant="h6" css={{ color: '$on_surface_high', display: 'flex', alignItems: 'center' }}>
|
120
|
+
Virtual Background {isMobile && loadingEffects ? <Loading size={18} style={{ marginLeft: '0.5rem' }} /> : ''}
|
105
121
|
</Text>
|
106
122
|
<Box
|
107
123
|
css={{ color: '$on_surface_high', '&:hover': { color: '$on_surface_medium' }, cursor: 'pointer' }}
|
@@ -1,17 +1,19 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import { selectIsEffectsEnabled, selectIsLocalVideoEnabled, useHMSStore } from '@100mslive/react-sdk';
|
2
|
+
import { selectAppData, selectIsEffectsEnabled, selectIsLocalVideoEnabled, useHMSStore } from '@100mslive/react-sdk';
|
3
3
|
import { VirtualBackgroundIcon } from '@100mslive/react-icons';
|
4
|
+
import { Loading } from '../../../Loading';
|
4
5
|
import { Tooltip } from '../../../Tooltip';
|
5
6
|
import IconButton from '../../IconButton';
|
6
7
|
// @ts-ignore
|
7
8
|
import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane';
|
8
|
-
import { isSafari, SIDE_PANE_OPTIONS } from '../../common/constants';
|
9
|
+
import { APP_DATA, isSafari, SIDE_PANE_OPTIONS } from '../../common/constants';
|
9
10
|
|
10
11
|
export const VBToggle = () => {
|
11
12
|
const toggleVB = useSidepaneToggle(SIDE_PANE_OPTIONS.VB);
|
12
13
|
const isVBOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.VB);
|
13
14
|
const isVideoOn = useHMSStore(selectIsLocalVideoEnabled);
|
14
15
|
const isEffectsEnabled = useHMSStore(selectIsEffectsEnabled);
|
16
|
+
const loadingEffects = useHMSStore(selectAppData(APP_DATA.loadingEffects));
|
15
17
|
|
16
18
|
if (!isVideoOn || (!isEffectsEnabled && isSafari)) {
|
17
19
|
return null;
|
@@ -20,7 +22,7 @@ export const VBToggle = () => {
|
|
20
22
|
return (
|
21
23
|
<Tooltip side="top" disabled={isVBOpen} title="Configure Virtual Background">
|
22
24
|
<IconButton active={!isVBOpen} onClick={toggleVB} data-testid="virtual_bg_btn">
|
23
|
-
<VirtualBackgroundIcon />
|
25
|
+
{loadingEffects ? <Loading size={18} /> : <VirtualBackgroundIcon />}
|
24
26
|
</IconButton>
|
25
27
|
</Tooltip>
|
26
28
|
);
|
@@ -6,7 +6,6 @@ import {
|
|
6
6
|
} from '@100mslive/types-prebuilt';
|
7
7
|
import { match } from 'ts-pattern';
|
8
8
|
import { selectIsConnectedToRoom, selectLocalPeerRoleName, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
|
9
|
-
// @ts-ignore: No implicit Any
|
10
9
|
import FullPageProgress from '../components/FullPageProgress';
|
11
10
|
import { GridLayout } from '../components/VideoLayouts/GridLayout';
|
12
11
|
import { Box, Flex } from '../../Layout';
|
@@ -25,7 +24,6 @@ import {
|
|
25
24
|
} from '../components/AppData/useUISettings';
|
26
25
|
import { useCloseScreenshareWhiteboard } from '../components/hooks/useCloseScreenshareWhiteboard';
|
27
26
|
import { useLandscapeHLSStream, useMobileHLSStream } from '../common/hooks';
|
28
|
-
// @ts-ignore: No implicit Any
|
29
27
|
import { SESSION_STORE_KEY } from '../common/constants';
|
30
28
|
|
31
29
|
// @ts-ignore: No implicit Any
|
@@ -107,7 +105,6 @@ export const VideoStreamingSection = ({
|
|
107
105
|
// @ts-ignore
|
108
106
|
return <GridLayout {...(elements as DefaultConferencingScreen_Elements)?.video_tile_layout?.grid} />;
|
109
107
|
})}
|
110
|
-
|
111
108
|
<Box
|
112
109
|
css={{
|
113
110
|
flex: match({ isLandscapeHLSStream, isMobileHLSStream })
|
@@ -0,0 +1,191 @@
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
2
|
+
import { HMSTranscript, selectPeerNameByID, useHMSStore, useTranscript } from '@100mslive/react-sdk';
|
3
|
+
import { Flex } from '../../Layout';
|
4
|
+
import { Text } from '../../Text';
|
5
|
+
|
6
|
+
interface CaptionQueueData extends HMSTranscript {
|
7
|
+
transcriptQueue: SimpleQueue;
|
8
|
+
}
|
9
|
+
|
10
|
+
interface TranscriptData extends HMSTranscript {
|
11
|
+
timeout?: NodeJS.Timeout | undefined;
|
12
|
+
}
|
13
|
+
class SimpleQueue {
|
14
|
+
private storage: TranscriptData[] = [];
|
15
|
+
constructor(private capacity: number = 3, private MAX_STORAGE_TIME: number = 5000) {}
|
16
|
+
enqueue(data: TranscriptData): void {
|
17
|
+
if (this.size() === this.capacity && this.storage[this.size() - 1].final) {
|
18
|
+
this.dequeue(this.storage[this.size() - 1]);
|
19
|
+
}
|
20
|
+
if (this.size() === 0) {
|
21
|
+
this.storage.push(data);
|
22
|
+
this.addTimeout(this.storage[this.size() - 1], data.final);
|
23
|
+
return;
|
24
|
+
}
|
25
|
+
if (this.size() > 0 && this.storage[this.size() - 1]?.final === true) {
|
26
|
+
this.storage.push(data);
|
27
|
+
this.addTimeout(this.storage[this.size() - 1], data.final);
|
28
|
+
return;
|
29
|
+
}
|
30
|
+
this.storage[this.size() - 1].transcript = data.transcript;
|
31
|
+
this.storage[this.size() - 1].final = data.final;
|
32
|
+
this.storage[this.size() - 1].end = data.end;
|
33
|
+
this.addTimeout(this.storage[this.size() - 1], data.final);
|
34
|
+
}
|
35
|
+
addTimeout(item: TranscriptData, isFinal: boolean) {
|
36
|
+
if (!isFinal) {
|
37
|
+
return;
|
38
|
+
}
|
39
|
+
item.timeout = setTimeout(() => {
|
40
|
+
this.dequeue(item);
|
41
|
+
}, this.MAX_STORAGE_TIME);
|
42
|
+
}
|
43
|
+
dequeue(item: TranscriptData): TranscriptData | undefined {
|
44
|
+
const index = this.storage.indexOf(item);
|
45
|
+
if (index === -1) {
|
46
|
+
return undefined;
|
47
|
+
}
|
48
|
+
const removedItem = this.storage.splice(index, 1);
|
49
|
+
if (removedItem.length <= 0) {
|
50
|
+
return undefined;
|
51
|
+
}
|
52
|
+
this.clearTimeout(removedItem[0]);
|
53
|
+
return item;
|
54
|
+
}
|
55
|
+
clearTimeout(item: TranscriptData) {
|
56
|
+
if (!item.timeout) {
|
57
|
+
return;
|
58
|
+
}
|
59
|
+
clearTimeout(item.timeout);
|
60
|
+
}
|
61
|
+
peek(): TranscriptData | undefined {
|
62
|
+
if (this.size() <= 0) {
|
63
|
+
return undefined;
|
64
|
+
}
|
65
|
+
return this.storage[0];
|
66
|
+
}
|
67
|
+
getTranscription(): string {
|
68
|
+
let script = '';
|
69
|
+
this.storage.forEach((value: TranscriptData) => (script += value.transcript + ' '));
|
70
|
+
return script;
|
71
|
+
}
|
72
|
+
reset() {
|
73
|
+
this.storage.length = 0;
|
74
|
+
}
|
75
|
+
size(): number {
|
76
|
+
return this.storage.length;
|
77
|
+
}
|
78
|
+
}
|
79
|
+
class Queue {
|
80
|
+
private storage: Record<string, CaptionQueueData> = {};
|
81
|
+
constructor(private capacity: number = 3) {}
|
82
|
+
|
83
|
+
enqueue(data: HMSTranscript): void {
|
84
|
+
if (this.size() === this.capacity) {
|
85
|
+
this.dequeue();
|
86
|
+
}
|
87
|
+
if (!this.storage[data.peer_id]) {
|
88
|
+
this.storage[data.peer_id] = {
|
89
|
+
peer_id: data.peer_id,
|
90
|
+
transcript: data.transcript,
|
91
|
+
final: data.final,
|
92
|
+
transcriptQueue: new SimpleQueue(),
|
93
|
+
start: data.start,
|
94
|
+
end: data.end,
|
95
|
+
};
|
96
|
+
this.storage[data.peer_id].transcriptQueue.enqueue(data as TranscriptData);
|
97
|
+
return;
|
98
|
+
}
|
99
|
+
this.storage[data.peer_id].transcriptQueue.enqueue(data as TranscriptData);
|
100
|
+
}
|
101
|
+
dequeue(): CaptionQueueData {
|
102
|
+
const key: string = Object.keys(this.storage).shift() || '';
|
103
|
+
const captionData = this.storage[key];
|
104
|
+
captionData.transcriptQueue.reset();
|
105
|
+
delete this.storage[key];
|
106
|
+
return captionData;
|
107
|
+
}
|
108
|
+
|
109
|
+
peek(): CaptionQueueData | undefined {
|
110
|
+
if (this.size() <= 0) return undefined;
|
111
|
+
const key: string = Object.keys(this.storage).shift() || '';
|
112
|
+
return this.storage[key];
|
113
|
+
}
|
114
|
+
|
115
|
+
findPeerData(): { [key: string]: string }[] {
|
116
|
+
const keys = Object.keys(this.storage);
|
117
|
+
const data = keys.map((key: string) => {
|
118
|
+
const data = this.storage[key];
|
119
|
+
const word = data.transcriptQueue.getTranscription();
|
120
|
+
return { [key]: word };
|
121
|
+
});
|
122
|
+
return data;
|
123
|
+
}
|
124
|
+
size(): number {
|
125
|
+
return Object.keys(this.storage).length;
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
class CaptionMaintainerQueue {
|
130
|
+
captionData: Queue = new Queue();
|
131
|
+
push(data: HMSTranscript[] = []) {
|
132
|
+
data.forEach((value: HMSTranscript) => {
|
133
|
+
this.captionData.enqueue(value);
|
134
|
+
});
|
135
|
+
}
|
136
|
+
}
|
137
|
+
const TranscriptView = ({ peer_id, data }: { peer_id: string; data: string }) => {
|
138
|
+
const peerName = useHMSStore(selectPeerNameByID(peer_id));
|
139
|
+
data = data.trim();
|
140
|
+
if (!data) return null;
|
141
|
+
return (
|
142
|
+
<Text
|
143
|
+
variant="body2"
|
144
|
+
css={{
|
145
|
+
fontWeight: '$normal',
|
146
|
+
}}
|
147
|
+
>
|
148
|
+
{`${peerName}: ${data}`}
|
149
|
+
</Text>
|
150
|
+
);
|
151
|
+
};
|
152
|
+
|
153
|
+
export const CaptionsViewer = () => {
|
154
|
+
const [captionQueue] = useState<CaptionMaintainerQueue>(new CaptionMaintainerQueue());
|
155
|
+
const [currentData, setCurrentData] = useState<{ [key: string]: string }[]>([]);
|
156
|
+
|
157
|
+
useEffect(() => {
|
158
|
+
const timeInterval = setInterval(() => {
|
159
|
+
if (!captionQueue) {
|
160
|
+
return;
|
161
|
+
}
|
162
|
+
const data = captionQueue.captionData?.findPeerData();
|
163
|
+
setCurrentData(data);
|
164
|
+
}, 1000);
|
165
|
+
return () => clearInterval(timeInterval);
|
166
|
+
}, [captionQueue]);
|
167
|
+
|
168
|
+
useTranscript({
|
169
|
+
onTranscript: (data: HMSTranscript[]) => {
|
170
|
+
captionQueue && captionQueue.push(data as HMSTranscript[]);
|
171
|
+
},
|
172
|
+
});
|
173
|
+
const dataToShow = currentData.filter((data: { [key: string]: string }) => {
|
174
|
+
const key = Object.keys(data)[0];
|
175
|
+
if (data[key]) {
|
176
|
+
return true;
|
177
|
+
}
|
178
|
+
return false;
|
179
|
+
});
|
180
|
+
if (dataToShow.length <= 0) {
|
181
|
+
return null;
|
182
|
+
}
|
183
|
+
return (
|
184
|
+
<Flex direction="column" gap={1}>
|
185
|
+
{dataToShow.map((data: { [key: string]: string }, index: number) => {
|
186
|
+
const key = Object.keys(data)[0];
|
187
|
+
return <TranscriptView key={index} peer_id={key} data={data[key]} />;
|
188
|
+
})}
|
189
|
+
</Flex>
|
190
|
+
);
|
191
|
+
};
|