@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
package/package.json
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
"prebuilt",
|
11
11
|
"roomkit"
|
12
12
|
],
|
13
|
-
"version": "0.3.8-alpha.
|
13
|
+
"version": "0.3.8-alpha.2",
|
14
14
|
"author": "100ms",
|
15
15
|
"license": "MIT",
|
16
16
|
"repository": {
|
@@ -82,11 +82,11 @@
|
|
82
82
|
"react": ">=17.0.2 <19.0.0"
|
83
83
|
},
|
84
84
|
"dependencies": {
|
85
|
-
"@100mslive/hls-player": "0.3.8-alpha.
|
85
|
+
"@100mslive/hls-player": "0.3.8-alpha.2",
|
86
86
|
"@100mslive/hms-noise-cancellation": "0.0.1",
|
87
|
-
"@100mslive/hms-virtual-background": "1.13.8-alpha.
|
88
|
-
"@100mslive/react-icons": "0.10.8-alpha.
|
89
|
-
"@100mslive/react-sdk": "0.10.8-alpha.
|
87
|
+
"@100mslive/hms-virtual-background": "1.13.8-alpha.2",
|
88
|
+
"@100mslive/react-icons": "0.10.8-alpha.2",
|
89
|
+
"@100mslive/react-sdk": "0.10.8-alpha.2",
|
90
90
|
"@100mslive/types-prebuilt": "0.12.8",
|
91
91
|
"@emoji-mart/data": "^1.0.6",
|
92
92
|
"@emoji-mart/react": "^1.0.1",
|
@@ -122,5 +122,5 @@
|
|
122
122
|
"uuid": "^8.3.2",
|
123
123
|
"worker-timers": "^7.0.40"
|
124
124
|
},
|
125
|
-
"gitHead": "
|
125
|
+
"gitHead": "43ee35cc85faabb5a827f7f41a5affebffcfca18"
|
126
126
|
}
|
@@ -3,20 +3,27 @@ import { useMedia } from 'react-use';
|
|
3
3
|
import { HMSHLSPlayer } from '@100mslive/hls-player';
|
4
4
|
import { JoinForm_JoinBtnType } from '@100mslive/types-prebuilt/elements/join_form';
|
5
5
|
import {
|
6
|
+
HMSRecording,
|
6
7
|
parsedUserAgent,
|
7
8
|
selectAvailableRoleNames,
|
8
9
|
selectIsConnectedToRoom,
|
9
10
|
selectPeerCount,
|
10
11
|
selectPeerMetadata,
|
11
12
|
selectPeers,
|
13
|
+
selectRecordingState,
|
12
14
|
selectRemotePeers,
|
15
|
+
useHMSActions,
|
13
16
|
useHMSStore,
|
14
17
|
useHMSVanillaStore,
|
15
18
|
} from '@100mslive/react-sdk';
|
19
|
+
// @ts-ignore: No implicit any
|
20
|
+
import { ToastManager } from '../components/Toast/ToastManager';
|
16
21
|
import { config } from '../../Theme';
|
17
22
|
import { useRoomLayout } from '../provider/roomLayoutProvider';
|
23
|
+
// @ts-ignore
|
24
|
+
import { useSetAppDataByKey } from '../components/AppData/useUISettings';
|
18
25
|
import { useRoomLayoutConferencingScreen } from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
19
|
-
import { CHAT_SELECTOR } from './constants';
|
26
|
+
import { APP_DATA, CHAT_SELECTOR, RTMP_RECORD_DEFAULT_RESOLUTION } from './constants';
|
20
27
|
/**
|
21
28
|
* Hook to execute a callback when alone in room(after a certain 5d of time)
|
22
29
|
* @param {number} thresholdMs The threshold(in ms) after which the callback is executed,
|
@@ -147,3 +154,67 @@ export const useKeyboardHandler = (isPaused: boolean, hlsPlayer: HMSHLSPlayer) =
|
|
147
154
|
|
148
155
|
return handleKeyEvent;
|
149
156
|
};
|
157
|
+
export interface RTMPRecordingResolution {
|
158
|
+
width: number;
|
159
|
+
height: number;
|
160
|
+
}
|
161
|
+
export const useRecordingHandler = () => {
|
162
|
+
const hmsActions = useHMSActions();
|
163
|
+
const recordingState: HMSRecording = useHMSStore(selectRecordingState);
|
164
|
+
const [isRecordingLoading, setIsRecordingLoading] = useState(false);
|
165
|
+
const [recordingStarted, setRecordingState] = useSetAppDataByKey(APP_DATA.recordingStarted);
|
166
|
+
useEffect(() => {
|
167
|
+
if (recordingState.browser.error && recordingStarted) {
|
168
|
+
setRecordingState(false);
|
169
|
+
}
|
170
|
+
}, [recordingStarted, recordingState.browser.error, setRecordingState]);
|
171
|
+
const startRecording = useCallback(
|
172
|
+
async (resolution: RTMPRecordingResolution | null = null) => {
|
173
|
+
try {
|
174
|
+
setRecordingState(true);
|
175
|
+
setIsRecordingLoading(true);
|
176
|
+
await hmsActions.startRTMPOrRecording({
|
177
|
+
resolution: getResolution(resolution),
|
178
|
+
record: true,
|
179
|
+
});
|
180
|
+
} catch (error) {
|
181
|
+
const err = error as Error;
|
182
|
+
if (err.message.includes('stream already running')) {
|
183
|
+
ToastManager.addToast({
|
184
|
+
title: 'Recording already running',
|
185
|
+
variant: 'error',
|
186
|
+
});
|
187
|
+
} else {
|
188
|
+
ToastManager.addToast({
|
189
|
+
title: err.message,
|
190
|
+
variant: 'error',
|
191
|
+
});
|
192
|
+
}
|
193
|
+
setRecordingState(false);
|
194
|
+
}
|
195
|
+
setIsRecordingLoading(false);
|
196
|
+
},
|
197
|
+
[hmsActions, setRecordingState],
|
198
|
+
);
|
199
|
+
return {
|
200
|
+
recordingStarted,
|
201
|
+
startRecording,
|
202
|
+
isRecordingLoading,
|
203
|
+
};
|
204
|
+
};
|
205
|
+
|
206
|
+
export function getResolution(
|
207
|
+
recordingResolution: RTMPRecordingResolution | null,
|
208
|
+
): RTMPRecordingResolution | undefined {
|
209
|
+
if (!recordingResolution) {
|
210
|
+
return undefined;
|
211
|
+
}
|
212
|
+
const resolution: RTMPRecordingResolution = RTMP_RECORD_DEFAULT_RESOLUTION;
|
213
|
+
if (recordingResolution.width) {
|
214
|
+
resolution.width = recordingResolution.width;
|
215
|
+
}
|
216
|
+
if (recordingResolution.height) {
|
217
|
+
resolution.height = recordingResolution.height;
|
218
|
+
}
|
219
|
+
return resolution;
|
220
|
+
}
|
@@ -62,11 +62,13 @@ const initialAppData = {
|
|
62
62
|
[APP_DATA.minimiseInset]: false,
|
63
63
|
[APP_DATA.activeScreensharePeerId]: '',
|
64
64
|
[APP_DATA.disableNotifications]: false,
|
65
|
+
[APP_DATA.loadingEffects]: false,
|
65
66
|
[APP_DATA.background]: 'none',
|
66
67
|
[APP_DATA.pollState]: {
|
67
68
|
[POLL_STATE.pollInView]: '',
|
68
69
|
[POLL_STATE.view]: '',
|
69
70
|
},
|
71
|
+
[APP_DATA.caption]: true,
|
70
72
|
};
|
71
73
|
|
72
74
|
export const AppData = React.memo(() => {
|
@@ -107,6 +107,16 @@ export const useSetSubscribedNotifications = notificationKey => {
|
|
107
107
|
return [value, setValue];
|
108
108
|
};
|
109
109
|
|
110
|
+
export const useIsCaptionEnabled = () => {
|
111
|
+
const isCaptionEnabled = useHMSStore(selectAppDataByPath(APP_DATA.caption));
|
112
|
+
return isCaptionEnabled;
|
113
|
+
};
|
114
|
+
|
115
|
+
export const useSetIsCaptionEnabled = () => {
|
116
|
+
const [value, setValue] = useSetAppDataByKey(APP_DATA.caption);
|
117
|
+
return [value, setValue];
|
118
|
+
};
|
119
|
+
|
110
120
|
export const useSubscribeChatSelector = chatSelectorKey => {
|
111
121
|
const chatSelectorPreference = useHMSStore(selectAppDataByPath(APP_DATA.chatSelector, chatSelectorKey));
|
112
122
|
return chatSelectorPreference;
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { selectIsTranscriptionEnabled, useHMSStore } from '@100mslive/react-sdk';
|
3
|
+
import { ClosedCaptionIcon, OpenCaptionIcon } from '@100mslive/react-icons';
|
4
|
+
import { Tooltip } from '../../Tooltip';
|
5
|
+
// @ts-ignore: No implicit Any
|
6
|
+
import IconButton from '../IconButton';
|
7
|
+
// @ts-ignore: No implicit Any
|
8
|
+
import { useSetIsCaptionEnabled } from './AppData/useUISettings.js';
|
9
|
+
|
10
|
+
export const CaptionIcon = () => {
|
11
|
+
const isCaptionPresent = useHMSStore(selectIsTranscriptionEnabled);
|
12
|
+
const [isCaption, setIsCaption] = useSetIsCaptionEnabled();
|
13
|
+
|
14
|
+
const onClick = () => {
|
15
|
+
setIsCaption(!isCaption);
|
16
|
+
};
|
17
|
+
if (!isCaptionPresent) {
|
18
|
+
return null;
|
19
|
+
}
|
20
|
+
return (
|
21
|
+
<Tooltip title={isCaption ? 'Disable caption' : 'Enable caption'}>
|
22
|
+
<IconButton data-testid="caption_btn" onClick={onClick}>
|
23
|
+
{isCaption ? <ClosedCaptionIcon width="20" height="20px" /> : <OpenCaptionIcon width="20" height="20px" />}
|
24
|
+
</IconButton>
|
25
|
+
</Tooltip>
|
26
|
+
);
|
27
|
+
};
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import React, { useEffect, useRef, useState } from 'react';
|
2
|
+
import { useMedia } from 'react-use';
|
2
3
|
import { DefaultConferencingScreen_Elements } from '@100mslive/types-prebuilt';
|
3
4
|
import { v4 as uuid } from 'uuid';
|
4
5
|
import {
|
@@ -18,27 +19,30 @@ import { ActivatedPIP } from './PIP/PIPComponent';
|
|
18
19
|
import { PictureInPicture } from './PIP/PIPManager';
|
19
20
|
import { RoleChangeRequestModal } from './RoleChangeRequest/RoleChangeRequestModal';
|
20
21
|
import { Box, Flex } from '../../Layout';
|
22
|
+
import { config } from '../../Theme';
|
21
23
|
import { useHMSPrebuiltContext } from '../AppContext';
|
22
24
|
import { VideoStreamingSection } from '../layouts/VideoStreamingSection';
|
23
25
|
// @ts-ignore: No implicit Any
|
24
26
|
import { EmojiReaction } from './EmojiReaction';
|
25
|
-
// @ts-ignore: No implicit Any
|
26
27
|
import FullPageProgress from './FullPageProgress';
|
27
28
|
import { Header } from './Header';
|
28
29
|
import { PreviousRoleInMetadata } from './PreviousRoleInMetadata';
|
29
30
|
import { RaiseHand } from './RaiseHand';
|
31
|
+
import { CaptionsViewer } from '../plugins/CaptionsViewer';
|
30
32
|
import {
|
31
33
|
useRoomLayoutConferencingScreen,
|
32
34
|
useRoomLayoutPreviewScreen,
|
33
35
|
} from '../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
34
36
|
// @ts-ignore: No implicit Any
|
35
|
-
import {
|
36
|
-
import { useLandscapeHLSStream, useMobileHLSStream } from '../common/hooks';
|
37
|
+
import { useIsSidepaneTypeOpen } from './AppData/useSidepane';
|
37
38
|
// @ts-ignore: No implicit Any
|
38
|
-
import {
|
39
|
+
import { useAuthToken, useIsCaptionEnabled, useSetAppDataByKey } from './AppData/useUISettings';
|
40
|
+
import { useLandscapeHLSStream, useMobileHLSStream } from '../common/hooks';
|
41
|
+
import { APP_DATA, isAndroid, isIOS, isIPadOS, SIDE_PANE_OPTIONS } from '../common/constants';
|
39
42
|
|
40
43
|
export const ConferenceScreen = () => {
|
41
44
|
const { userName, endpoints, onJoin: onJoinFunc } = useHMSPrebuiltContext();
|
45
|
+
const isMobile = useMedia(config.media.md);
|
42
46
|
const screenProps = useRoomLayoutConferencingScreen();
|
43
47
|
const { isPreviewScreenEnabled } = useRoomLayoutPreviewScreen();
|
44
48
|
const roomState = useHMSStore(selectRoomState);
|
@@ -59,6 +63,10 @@ export const ConferenceScreen = () => {
|
|
59
63
|
const isMobileHLSStream = useMobileHLSStream();
|
60
64
|
const isLandscapeHLSStream = useLandscapeHLSStream();
|
61
65
|
const isMwebHLSStream = isMobileHLSStream || isLandscapeHLSStream;
|
66
|
+
const isCaptionEnabled = useIsCaptionEnabled();
|
67
|
+
const isChatOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.CHAT);
|
68
|
+
|
69
|
+
const showCaptionAtTop = screenProps.elements?.chat?.is_overlay && isChatOpen;
|
62
70
|
|
63
71
|
const toggleControls = () => {
|
64
72
|
if (dropdownListRef.current?.length === 0 && isMobileDevice && !isMwebHLSStream) {
|
@@ -126,6 +134,28 @@ export const ConferenceScreen = () => {
|
|
126
134
|
<FullPageProgress text="Starting live stream..." css={{ opacity: 0.8, bg: '$background_dim' }} />
|
127
135
|
</Box>
|
128
136
|
) : null}
|
137
|
+
{isCaptionEnabled && screenProps.screenType !== 'hls_live_streaming' && (
|
138
|
+
<Box
|
139
|
+
css={{
|
140
|
+
position: 'fixed',
|
141
|
+
maxWidth: isMobile ? '100%' : '40%',
|
142
|
+
bottom: showCaptionAtTop ? '' : hideControlsForStreaming ? '5%' : '10%',
|
143
|
+
top: showCaptionAtTop ? (hideControlsForStreaming ? '5%' : '10%') : '',
|
144
|
+
left: isMobile ? 0 : '50%',
|
145
|
+
transform: isMobile ? '' : 'translateX(-50%)',
|
146
|
+
background: '#000000A3',
|
147
|
+
overflow: 'clip',
|
148
|
+
zIndex: 10,
|
149
|
+
height: 'fit-content',
|
150
|
+
r: '$1',
|
151
|
+
p: '$6',
|
152
|
+
transition: 'bottom 0.3s ease-in-out',
|
153
|
+
'&:empty': { display: 'none' },
|
154
|
+
}}
|
155
|
+
>
|
156
|
+
<CaptionsViewer />
|
157
|
+
</Box>
|
158
|
+
)}
|
129
159
|
<Flex css={{ size: '100%', overflow: 'hidden' }} direction="column">
|
130
160
|
{!(screenProps.hideSections.includes('header') || isMwebHLSStream) && (
|
131
161
|
<Box
|
@@ -5,6 +5,7 @@ import { Chat_ChatState } from '@100mslive/types-prebuilt/elements/chat';
|
|
5
5
|
import { config as cssConfig, Footer as AppFooter } from '../../..';
|
6
6
|
// @ts-ignore: No implicit Any
|
7
7
|
import { AudioVideoToggle } from '../AudioVideoToggle';
|
8
|
+
import { CaptionIcon } from '../CaptionIcon';
|
8
9
|
// @ts-ignore: No implicit Any
|
9
10
|
import { EmojiReaction } from '../EmojiReaction';
|
10
11
|
// @ts-ignore: No implicit Any
|
@@ -96,6 +97,7 @@ export const Footer = ({
|
|
96
97
|
<>
|
97
98
|
<ScreenshareToggle />
|
98
99
|
<RaiseHand />
|
100
|
+
{screenType !== 'hls_live_streaming' && <CaptionIcon />}
|
99
101
|
{elements?.emoji_reactions && <EmojiReaction />}
|
100
102
|
<LeaveRoom screenType={screenType} />
|
101
103
|
</>
|
@@ -109,7 +109,7 @@ export const RoleAccordion = ({
|
|
109
109
|
},
|
110
110
|
}}
|
111
111
|
>
|
112
|
-
<Flex justify="between" css={{ flexGrow: 1, pr: '$6' }}>
|
112
|
+
<Flex justify="between" align="center" css={{ flexGrow: 1, pr: '$6' }}>
|
113
113
|
<Text
|
114
114
|
variant="sm"
|
115
115
|
css={{ fontWeight: '$semiBold', textTransform: 'capitalize', color: '$on_surface_medium' }}
|
@@ -2,8 +2,17 @@ import React from 'react';
|
|
2
2
|
import { Flex } from '../../Layout';
|
3
3
|
import { Loading } from '../../Loading';
|
4
4
|
import { Text } from '../../Text';
|
5
|
+
import { CSS } from '../../Theme';
|
5
6
|
|
6
|
-
const FullPageProgress = ({
|
7
|
+
const FullPageProgress = ({
|
8
|
+
loaderColor = '$primary_default',
|
9
|
+
text = '',
|
10
|
+
css = {},
|
11
|
+
}: {
|
12
|
+
loaderColor?: string;
|
13
|
+
text?: string;
|
14
|
+
css?: CSS;
|
15
|
+
}) => (
|
7
16
|
<Flex direction="column" justify="center" align="center" css={{ size: '100%', color: loaderColor, ...css }}>
|
8
17
|
<Loading color="currentColor" size={100} />
|
9
18
|
{text ? <Text css={{ mt: '$10', color: '$on_surface_high' }}>{text}</Text> : null}
|
@@ -20,12 +20,9 @@ import { ToastManager } from '../Toast/ToastManager';
|
|
20
20
|
// @ts-ignore
|
21
21
|
import { AdditionalRoomState, getRecordingText } from './AdditionalRoomState';
|
22
22
|
import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
23
|
-
|
24
|
-
import { useSetAppDataByKey } from '../AppData/useUISettings';
|
23
|
+
import { useRecordingHandler } from '../../common/hooks';
|
25
24
|
// @ts-ignore
|
26
25
|
import { formatTime } from '../../common/utils';
|
27
|
-
// @ts-ignore
|
28
|
-
import { APP_DATA } from '../../common/constants';
|
29
26
|
|
30
27
|
export const LiveStatus = () => {
|
31
28
|
const { isHLSRunning, isRTMPRunning } = useRecordingStreaming();
|
@@ -147,7 +144,7 @@ export const RecordingPauseStatus = () => {
|
|
147
144
|
const StartRecording = () => {
|
148
145
|
const permissions = useHMSStore(selectPermissions);
|
149
146
|
const [open, setOpen] = useState(false);
|
150
|
-
const
|
147
|
+
const { startRecording, recordingStarted } = useRecordingHandler();
|
151
148
|
const { isBrowserRecordingOn, isStreamingOn, isHLSRunning } = useRecordingStreaming();
|
152
149
|
const hmsActions = useHMSActions();
|
153
150
|
if (!permissions?.browserRecording || isHLSRunning) {
|
@@ -201,26 +198,7 @@ const StartRecording = () => {
|
|
201
198
|
icon
|
202
199
|
disabled={recordingStarted || isStreamingOn}
|
203
200
|
onClick={async () => {
|
204
|
-
|
205
|
-
setRecordingState(true);
|
206
|
-
await hmsActions.startRTMPOrRecording({
|
207
|
-
record: true,
|
208
|
-
});
|
209
|
-
} catch (error) {
|
210
|
-
const err = error as Error;
|
211
|
-
if (err.message.includes('stream already running')) {
|
212
|
-
ToastManager.addToast({
|
213
|
-
title: 'Recording already running',
|
214
|
-
variant: 'error',
|
215
|
-
});
|
216
|
-
} else {
|
217
|
-
ToastManager.addToast({
|
218
|
-
title: err.message,
|
219
|
-
variant: 'error',
|
220
|
-
});
|
221
|
-
}
|
222
|
-
setRecordingState(false);
|
223
|
-
}
|
201
|
+
await startRecording();
|
224
202
|
}}
|
225
203
|
>
|
226
204
|
{recordingStarted ? <Loading size={24} color="currentColor" /> : <RecordIcon />}
|
@@ -5,6 +5,7 @@ import { match } from 'ts-pattern';
|
|
5
5
|
import {
|
6
6
|
selectIsConnectedToRoom,
|
7
7
|
selectIsLocalVideoEnabled,
|
8
|
+
selectIsTranscriptionEnabled,
|
8
9
|
selectPeerCount,
|
9
10
|
selectPermissions,
|
10
11
|
useHMSActions,
|
@@ -13,12 +14,14 @@ import {
|
|
13
14
|
} from '@100mslive/react-sdk';
|
14
15
|
import {
|
15
16
|
BrbIcon,
|
17
|
+
ClosedCaptionIcon,
|
16
18
|
CrossIcon,
|
17
19
|
EmojiIcon,
|
18
20
|
HamburgerMenuIcon,
|
19
21
|
HandIcon,
|
20
22
|
HandRaiseSlashedIcon,
|
21
23
|
InfoIcon,
|
24
|
+
OpenCaptionIcon,
|
22
25
|
PeopleIcon,
|
23
26
|
QuizActiveIcon,
|
24
27
|
QuizIcon,
|
@@ -49,12 +52,12 @@ import { useSheetToggle } from '../../AppData/useSheet';
|
|
49
52
|
// @ts-ignore: No implicit any
|
50
53
|
import { usePollViewToggle, useSidepaneToggle } from '../../AppData/useSidepane';
|
51
54
|
// @ts-ignore: No implicit Any
|
52
|
-
import { useShowPolls } from '../../AppData/useUISettings';
|
55
|
+
import { useSetIsCaptionEnabled, useShowPolls } from '../../AppData/useUISettings';
|
53
56
|
// @ts-ignore: No implicit any
|
54
57
|
import { useDropdownList } from '../../hooks/useDropdownList';
|
55
58
|
import { useMyMetadata } from '../../hooks/useMetadata';
|
56
59
|
import { useUnreadPollQuizPresent } from '../../hooks/useUnreadPollQuizPresent';
|
57
|
-
import { useLandscapeHLSStream, useMobileHLSStream } from '../../../common/hooks';
|
60
|
+
import { useLandscapeHLSStream, useMobileHLSStream, useRecordingHandler } from '../../../common/hooks';
|
58
61
|
// @ts-ignore: No implicit any
|
59
62
|
import { getFormattedCount } from '../../../common/utils';
|
60
63
|
// @ts-ignore: No implicit any
|
@@ -88,7 +91,6 @@ export const MwebOptions = ({
|
|
88
91
|
const [openSettingsSheet, setOpenSettingsSheet] = useState(false);
|
89
92
|
const [showEmojiCard, setShowEmojiCard] = useState(false);
|
90
93
|
const [showRecordingOn, setShowRecordingOn] = useState(false);
|
91
|
-
const [isRecordingLoading, setIsRecordingLoading] = useState(false);
|
92
94
|
const toggleParticipants = useSidepaneToggle(SIDE_PANE_OPTIONS.PARTICIPANTS);
|
93
95
|
const { showPolls } = useShowPolls();
|
94
96
|
const togglePollView = usePollViewToggle();
|
@@ -102,7 +104,11 @@ export const MwebOptions = ({
|
|
102
104
|
const isLandscapeHLSStream = useLandscapeHLSStream();
|
103
105
|
const toggleVB = useSidepaneToggle(SIDE_PANE_OPTIONS.VB);
|
104
106
|
const isLocalVideoEnabled = useHMSStore(selectIsLocalVideoEnabled);
|
107
|
+
const { startRecording, isRecordingLoading } = useRecordingHandler();
|
105
108
|
|
109
|
+
const isCaptionPresent = useHMSStore(selectIsTranscriptionEnabled);
|
110
|
+
|
111
|
+
const [isCaptionEnabled, setIsCaptionEnabled] = useSetIsCaptionEnabled();
|
106
112
|
useDropdownList({ open: openModals.size > 0 || openOptionsSheet || openSettingsSheet, name: 'MoreSettings' });
|
107
113
|
|
108
114
|
const updateState = (modalName: string, value: boolean) => {
|
@@ -187,6 +193,20 @@ export const MwebOptions = ({
|
|
187
193
|
<ActionTile.Title>{isHandRaised ? 'Lower' : 'Raise'} Hand</ActionTile.Title>
|
188
194
|
</ActionTile.Root>
|
189
195
|
) : null}
|
196
|
+
{isCaptionPresent && screenType !== 'hls_live_streaming' ? (
|
197
|
+
<ActionTile.Root
|
198
|
+
onClick={() => {
|
199
|
+
setIsCaptionEnabled(!isCaptionEnabled);
|
200
|
+
}}
|
201
|
+
>
|
202
|
+
{isCaptionEnabled ? (
|
203
|
+
<ClosedCaptionIcon width="20" height="20px" />
|
204
|
+
) : (
|
205
|
+
<OpenCaptionIcon width="20" height="20px" />
|
206
|
+
)}
|
207
|
+
<ActionTile.Title>{isCaptionEnabled ? 'Hide Captions' : 'Captions Disabled'}</ActionTile.Title>
|
208
|
+
</ActionTile.Root>
|
209
|
+
) : null}
|
190
210
|
|
191
211
|
{isLocalVideoEnabled && !!elements?.virtual_background ? (
|
192
212
|
<ActionTile.Root
|
@@ -260,29 +280,8 @@ export const MwebOptions = ({
|
|
260
280
|
setShowRecordingOn(true);
|
261
281
|
} else {
|
262
282
|
// start recording
|
263
|
-
|
264
|
-
|
265
|
-
await hmsActions.startRTMPOrRecording({
|
266
|
-
record: true,
|
267
|
-
});
|
268
|
-
setOpenOptionsSheet(false);
|
269
|
-
setIsRecordingLoading(false);
|
270
|
-
} catch (error) {
|
271
|
-
// @ts-ignore
|
272
|
-
if (error.message.includes('stream already running')) {
|
273
|
-
ToastManager.addToast({
|
274
|
-
title: 'Recording already running',
|
275
|
-
variant: 'error',
|
276
|
-
});
|
277
|
-
} else {
|
278
|
-
ToastManager.addToast({
|
279
|
-
// @ts-ignore
|
280
|
-
title: error.message,
|
281
|
-
variant: 'error',
|
282
|
-
});
|
283
|
-
}
|
284
|
-
setIsRecordingLoading(false);
|
285
|
-
}
|
283
|
+
await startRecording();
|
284
|
+
setOpenOptionsSheet(false);
|
286
285
|
}
|
287
286
|
if (isHLSRunning) {
|
288
287
|
setOpenOptionsSheet(false);
|
@@ -7,11 +7,7 @@ import { useSetSubscribedChatSelector, useSubscribedNotifications } from '../App
|
|
7
7
|
// @ts-ignore: No implicit Any
|
8
8
|
import { CHAT_SELECTOR, SUBSCRIBED_NOTIFICATIONS } from '../../common/constants';
|
9
9
|
|
10
|
-
const notificationTypes = [
|
11
|
-
HMSNotificationTypes.PEER_LIST,
|
12
|
-
HMSNotificationTypes.PEER_JOINED,
|
13
|
-
HMSNotificationTypes.PEER_LEFT,
|
14
|
-
];
|
10
|
+
const notificationTypes = [HMSNotificationTypes.PEER_JOINED, HMSNotificationTypes.PEER_LEFT];
|
15
11
|
|
16
12
|
export const PeerNotifications = () => {
|
17
13
|
const notification = useHMSNotifications(notificationTypes);
|
@@ -26,11 +22,6 @@ export const PeerNotifications = () => {
|
|
26
22
|
|
27
23
|
console.debug(`[${notification.type}]`, notification);
|
28
24
|
switch (notification.type) {
|
29
|
-
case HMSNotificationTypes.PEER_LIST:
|
30
|
-
if (!isPeerJoinSubscribed || notification.data.length === 0) {
|
31
|
-
return;
|
32
|
-
}
|
33
|
-
break;
|
34
25
|
case HMSNotificationTypes.PEER_JOINED:
|
35
26
|
if (!isPeerJoinSubscribed) {
|
36
27
|
return;
|
@@ -47,7 +38,6 @@ export const PeerNotifications = () => {
|
|
47
38
|
default:
|
48
39
|
return;
|
49
40
|
}
|
50
|
-
|
51
41
|
ToastBatcher.showToast({ notification });
|
52
42
|
}, [notification, isPeerJoinSubscribed, isPeerLeftSubscribed, selectedPeer.id, setPeerSelector]);
|
53
43
|
|
@@ -2,6 +2,7 @@ import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'reac
|
|
2
2
|
import { useMeasure, useMedia } from 'react-use';
|
3
3
|
import {
|
4
4
|
HMSRoomState,
|
5
|
+
selectAppData,
|
5
6
|
selectIsLocalVideoEnabled,
|
6
7
|
selectLocalPeer,
|
7
8
|
selectRoomState,
|
@@ -16,24 +17,17 @@ import { MicOffIcon, SettingsIcon } from '@100mslive/react-icons';
|
|
16
17
|
import { Avatar, Box, config as cssConfig, Flex, flexCenter, styled, StyledVideoTile, Text, Video } from '../../..';
|
17
18
|
import { AudioLevel } from '../../../AudioLevel';
|
18
19
|
import { useHMSPrebuiltContext } from '../../AppContext';
|
19
|
-
// @ts-ignore: No implicit Any
|
20
20
|
import IconButton from '../../IconButton';
|
21
21
|
import SidePane from '../../layouts/SidePane';
|
22
|
-
// @ts-ignore: No implicit Any
|
23
22
|
import { AudioVideoToggle } from '../AudioVideoToggle';
|
24
|
-
// @ts-ignore: No implicit Any
|
25
23
|
import Chip from '../Chip';
|
26
|
-
// @ts-ignore: No implicit Any
|
27
24
|
import TileConnection from '../Connection/TileConnection';
|
28
|
-
// @ts-ignore: No implicit Any
|
29
25
|
import FullPageProgress from '../FullPageProgress';
|
30
26
|
// @ts-ignore: No implicit Any
|
31
27
|
import { Logo } from '../Header/HeaderComponents';
|
32
28
|
// @ts-ignore: No implicit Any
|
33
29
|
import SettingsModal from '../Settings/SettingsModal';
|
34
|
-
// @ts-ignore: No implicit Any
|
35
30
|
import { VBToggle } from '../VirtualBackground/VBToggle';
|
36
|
-
// @ts-ignore: No implicit Any
|
37
31
|
import PreviewForm from './PreviewForm';
|
38
32
|
import { useRoomLayoutPreviewScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
39
33
|
// @ts-ignore: No implicit Any
|
@@ -42,7 +36,7 @@ import { useAuthToken, useUISettings } from '../AppData/useUISettings';
|
|
42
36
|
import { defaultPreviewPreference, UserPreferencesKeys, useUserPreferences } from '../hooks/useUserPreferences';
|
43
37
|
// @ts-ignore: No implicit Any
|
44
38
|
import { calculateAvatarAndAttribBoxSize, getFormattedCount } from '../../common/utils';
|
45
|
-
import { UI_SETTINGS } from '../../common/constants';
|
39
|
+
import { APP_DATA, UI_SETTINGS } from '../../common/constants';
|
46
40
|
|
47
41
|
const getParticipantChipContent = (peerCount = 0) => {
|
48
42
|
if (peerCount === 0) {
|
@@ -85,6 +79,7 @@ const PreviewJoin = ({
|
|
85
79
|
const [previewError, setPreviewError] = useState(false);
|
86
80
|
const { endpoints } = useHMSPrebuiltContext();
|
87
81
|
const { peerCount } = useParticipants();
|
82
|
+
const loadingEffects = useHMSStore(selectAppData(APP_DATA.loadingEffects));
|
88
83
|
const { enableJoin, preview, join } = usePreviewJoin({
|
89
84
|
name,
|
90
85
|
token: authToken,
|
@@ -166,7 +161,7 @@ const PreviewJoin = ({
|
|
166
161
|
name={name}
|
167
162
|
disabled={!!initialName}
|
168
163
|
onChange={setName}
|
169
|
-
enableJoin={enableJoin}
|
164
|
+
enableJoin={enableJoin && !loadingEffects}
|
170
165
|
onJoin={savePreferenceAndJoin}
|
171
166
|
cannotPublishVideo={!toggleVideo}
|
172
167
|
cannotPublishAudio={!toggleAudio}
|
@@ -3,14 +3,11 @@ import { useSearchParam } from 'react-use';
|
|
3
3
|
import { Flex } from '../../..';
|
4
4
|
import { useHMSPrebuiltContext } from '../../AppContext';
|
5
5
|
import { useRoomLayout } from '../../provider/roomLayoutProvider';
|
6
|
-
// @ts-ignore: No implicit Any
|
7
6
|
import FullPageProgress from '../FullPageProgress';
|
8
|
-
// @ts-ignore: No implicit Any
|
9
7
|
import PreviewJoin from './PreviewJoin';
|
10
8
|
import { useRoomLayoutPreviewScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
|
11
9
|
// @ts-ignore: No implicit Any
|
12
10
|
import { useAuthToken } from '../AppData/useUISettings';
|
13
|
-
// @ts-ignore: No implicit Any
|
14
11
|
import { QUERY_PARAM_PREVIEW_AS_ROLE } from '../../common/constants';
|
15
12
|
|
16
13
|
export const PreviewScreen = () => {
|
@@ -4,27 +4,13 @@ import { AlertTriangleIcon } from '@100mslive/react-icons';
|
|
4
4
|
import { Button, Dialog, Flex, Text } from '../../../';
|
5
5
|
import { ResolutionInput } from '../Streaming/ResolutionInput';
|
6
6
|
import { ToastManager } from '../Toast/ToastManager';
|
7
|
-
import {
|
8
|
-
import {
|
9
|
-
|
10
|
-
export function getResolution(recordingResolution) {
|
11
|
-
const resolution = {};
|
12
|
-
if (recordingResolution.width) {
|
13
|
-
resolution.width = recordingResolution.width;
|
14
|
-
}
|
15
|
-
if (recordingResolution.height) {
|
16
|
-
resolution.height = recordingResolution.height;
|
17
|
-
}
|
18
|
-
if (Object.keys(resolution).length > 0) {
|
19
|
-
return resolution;
|
20
|
-
}
|
21
|
-
}
|
7
|
+
import { useRecordingHandler } from '../../common/hooks';
|
8
|
+
import { RTMP_RECORD_DEFAULT_RESOLUTION } from '../../common/constants';
|
22
9
|
|
23
10
|
const StartRecording = ({ open, onOpenChange }) => {
|
24
11
|
const permissions = useHMSStore(selectPermissions);
|
25
12
|
const [resolution, setResolution] = useState(RTMP_RECORD_DEFAULT_RESOLUTION);
|
26
|
-
|
27
|
-
const [recordingStarted, setRecordingState] = useSetAppDataByKey(APP_DATA.recordingStarted);
|
13
|
+
const { startRecording, recordingStarted } = useRecordingHandler();
|
28
14
|
const { isBrowserRecordingOn, isStreamingOn, isHLSRunning } = useRecordingStreaming();
|
29
15
|
const hmsActions = useHMSActions();
|
30
16
|
if (!permissions?.browserRecording || isHLSRunning) {
|
@@ -101,26 +87,7 @@ const StartRecording = ({ open, onOpenChange }) => {
|
|
101
87
|
type="submit"
|
102
88
|
disabled={recordingStarted || isStreamingOn}
|
103
89
|
onClick={async () => {
|
104
|
-
|
105
|
-
setRecordingState(true);
|
106
|
-
await hmsActions.startRTMPOrRecording({
|
107
|
-
resolution: getResolution(resolution),
|
108
|
-
record: true,
|
109
|
-
});
|
110
|
-
} catch (error) {
|
111
|
-
if (error.message.includes('stream already running')) {
|
112
|
-
ToastManager.addToast({
|
113
|
-
title: 'Recording already running',
|
114
|
-
variant: 'error',
|
115
|
-
});
|
116
|
-
} else {
|
117
|
-
ToastManager.addToast({
|
118
|
-
title: error.message,
|
119
|
-
variant: 'error',
|
120
|
-
});
|
121
|
-
}
|
122
|
-
setRecordingState(false);
|
123
|
-
}
|
90
|
+
await startRecording(resolution);
|
124
91
|
onOpenChange(false);
|
125
92
|
}}
|
126
93
|
>
|