agora-appbuilder-core 4.0.0-test.10 → 4.0.0-test.12
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/package.json +2 -2
- package/template/_package-lock.json +17 -17
- package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +0 -1
- package/template/agora-rn-uikit/src/Rtc/Create.tsx +9 -16
- package/template/agora-rn-uikit/src/Rtc/Join.tsx +1 -1
- package/template/agora-rn-uikit/src/RtcConfigure.tsx +17 -36
- package/template/package.json +1 -1
- package/template/src/AppRoutes.tsx +3 -16
- package/template/src/AppWrapper.tsx +19 -21
- package/template/src/components/Chat.tsx +8 -17
- package/template/src/components/GraphQLProvider.tsx +30 -47
- package/template/src/components/StorageContext.tsx +2 -2
- package/template/src/components/ToastComponent.tsx +1 -7
- package/template/src/language/default-labels/videoCallScreenLabels.ts +0 -14
- package/template/src/pages/VideoCall.tsx +12 -24
- package/template/src/pages/video-call/VideoCallScreen.tsx +12 -32
- package/template/src/subComponents/recording/useRecording.tsx +66 -92
- package/template/src/utils/useIsLocalUserSpeaking.ts +1 -6
- package/template/agora-rn-uikit/src/Utils/isBotUser.ts +0 -16
- package/template/src/components/recording-bot/RecordingBotRoute.tsx +0 -42
- package/template/src/pages/video-call/VideoCallScreenWrapper.tsx +0 -41
- package/template/src/subComponents/recording/useIsRecordingBot.tsx +0 -38
- package/template/src/utils/useSearchParams.tsx +0 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agora-appbuilder-core",
|
|
3
|
-
"version": "4.0.0-test.
|
|
3
|
+
"version": "4.0.0-test.12",
|
|
4
4
|
"description": "React Native template for RTE app builder",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
],
|
|
10
10
|
"scripts": {
|
|
11
11
|
"vercel-build": "npm run dev-setup && cd template && npm run web:build && cd .. && npm run copy-vercel",
|
|
12
|
-
"uikit": "rm -rf template/agora-rn-uikit && git clone https://github.com/AgoraIO-Community/ReactNative-UIKit.git template/agora-rn-uikit && cd template/agora-rn-uikit && git checkout
|
|
12
|
+
"uikit": "rm -rf template/agora-rn-uikit && git clone https://github.com/AgoraIO-Community/ReactNative-UIKit.git template/agora-rn-uikit && cd template/agora-rn-uikit && git checkout v3-release-fixes-encryption",
|
|
13
13
|
"deps": "cd template && npm i",
|
|
14
14
|
"dev-setup": "npm run uikit && npm run deps && node devSetup.js",
|
|
15
15
|
"web-build": "cd template && npm run web:build && cd .. && npm run copy-vercel",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"agora-extension-ai-denoiser": "1.1.0",
|
|
21
21
|
"agora-extension-virtual-background": "^1.1.3",
|
|
22
22
|
"agora-react-native-rtm": "1.5.1",
|
|
23
|
-
"agora-rtc-sdk-ng": "4.
|
|
23
|
+
"agora-rtc-sdk-ng": "4.19.0",
|
|
24
24
|
"agora-rtm-sdk": "1.5.1",
|
|
25
25
|
"buffer": "^6.0.3",
|
|
26
26
|
"electron-log": "4.3.5",
|
|
@@ -7668,14 +7668,14 @@
|
|
|
7668
7668
|
}
|
|
7669
7669
|
},
|
|
7670
7670
|
"node_modules/agora-rtc-sdk-ng": {
|
|
7671
|
-
"version": "4.
|
|
7672
|
-
"resolved": "https://registry.npmjs.org/agora-rtc-sdk-ng/-/agora-rtc-sdk-ng-4.
|
|
7673
|
-
"integrity": "sha512-
|
|
7674
|
-
"dependencies": {
|
|
7675
|
-
"@agora-js/media": "4.
|
|
7676
|
-
"@agora-js/report": "4.
|
|
7677
|
-
"@agora-js/shared": "4.
|
|
7678
|
-
"agora-rte-extension": "^1.2.
|
|
7671
|
+
"version": "4.19.0",
|
|
7672
|
+
"resolved": "https://registry.npmjs.org/agora-rtc-sdk-ng/-/agora-rtc-sdk-ng-4.19.0.tgz",
|
|
7673
|
+
"integrity": "sha512-uVljhNooPWnJQGOvGWLPtjHuTET15pLz1lEPA1NFNoe94/yl6Ib5Ayl253+Y0gSzQwrQswRuRIITNNec/eXpSw==",
|
|
7674
|
+
"dependencies": {
|
|
7675
|
+
"@agora-js/media": "^4.19.0",
|
|
7676
|
+
"@agora-js/report": "^4.19.0",
|
|
7677
|
+
"@agora-js/shared": "^4.19.0",
|
|
7678
|
+
"agora-rte-extension": "^1.2.3",
|
|
7679
7679
|
"axios": "^0.27.2",
|
|
7680
7680
|
"formdata-polyfill": "^4.0.7",
|
|
7681
7681
|
"ua-parser-js": "^0.7.34",
|
|
@@ -37782,14 +37782,14 @@
|
|
|
37782
37782
|
"requires": {}
|
|
37783
37783
|
},
|
|
37784
37784
|
"agora-rtc-sdk-ng": {
|
|
37785
|
-
"version": "4.
|
|
37786
|
-
"resolved": "https://registry.npmjs.org/agora-rtc-sdk-ng/-/agora-rtc-sdk-ng-4.
|
|
37787
|
-
"integrity": "sha512-
|
|
37788
|
-
"requires": {
|
|
37789
|
-
"@agora-js/media": "4.
|
|
37790
|
-
"@agora-js/report": "4.
|
|
37791
|
-
"@agora-js/shared": "4.
|
|
37792
|
-
"agora-rte-extension": "^1.2.
|
|
37785
|
+
"version": "4.19.0",
|
|
37786
|
+
"resolved": "https://registry.npmjs.org/agora-rtc-sdk-ng/-/agora-rtc-sdk-ng-4.19.0.tgz",
|
|
37787
|
+
"integrity": "sha512-uVljhNooPWnJQGOvGWLPtjHuTET15pLz1lEPA1NFNoe94/yl6Ib5Ayl253+Y0gSzQwrQswRuRIITNNec/eXpSw==",
|
|
37788
|
+
"requires": {
|
|
37789
|
+
"@agora-js/media": "^4.19.0",
|
|
37790
|
+
"@agora-js/report": "^4.19.0",
|
|
37791
|
+
"@agora-js/shared": "^4.19.0",
|
|
37792
|
+
"agora-rte-extension": "^1.2.3",
|
|
37793
37793
|
"axios": "^0.27.2",
|
|
37794
37794
|
"formdata-polyfill": "^4.0.7",
|
|
37795
37795
|
"ua-parser-js": "^0.7.34",
|
|
@@ -15,7 +15,6 @@ import PropsContext, {
|
|
|
15
15
|
PermissionState,
|
|
16
16
|
} from '../Contexts/PropsContext';
|
|
17
17
|
import quality from '../Utils/quality';
|
|
18
|
-
import {isBotUser} from '../Utils/isBotUser';
|
|
19
18
|
|
|
20
19
|
const Create = ({
|
|
21
20
|
dispatch,
|
|
@@ -297,21 +296,14 @@ const Create = ({
|
|
|
297
296
|
if (
|
|
298
297
|
!(
|
|
299
298
|
mode === ChannelProfile.LiveBroadcasting &&
|
|
300
|
-
rtcProps
|
|
301
|
-
Platform.OS === 'web'
|
|
302
|
-
rtcProps?.recordingBot
|
|
299
|
+
rtcProps.role == ClientRole.Audience &&
|
|
300
|
+
Platform.OS === 'web'
|
|
303
301
|
)
|
|
304
302
|
) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
} else {
|
|
310
|
-
enableVideoAndAudioWithInitialStates().then(() => {
|
|
311
|
-
setTracksReady(true);
|
|
312
|
-
isVideoEnabledRef.current = true;
|
|
313
|
-
});
|
|
314
|
-
}
|
|
303
|
+
enableVideoAndAudioWithInitialStates().then(() => {
|
|
304
|
+
setTracksReady(true);
|
|
305
|
+
isVideoEnabledRef.current = true;
|
|
306
|
+
});
|
|
315
307
|
}
|
|
316
308
|
|
|
317
309
|
engine.current.addListener(
|
|
@@ -330,8 +322,9 @@ const Create = ({
|
|
|
330
322
|
);
|
|
331
323
|
|
|
332
324
|
engine.current.addListener('UserJoined', async (...args) => {
|
|
333
|
-
// preventing
|
|
334
|
-
|
|
325
|
+
// preventing STT pusher bot in renderlist
|
|
326
|
+
//@ts-ignore
|
|
327
|
+
if (args[0] === 111111) {
|
|
335
328
|
return;
|
|
336
329
|
}
|
|
337
330
|
//Get current peer IDs
|
|
@@ -45,7 +45,7 @@ const Join: React.FC<{
|
|
|
45
45
|
}
|
|
46
46
|
const {defaultContent, activeUids} = uidState;
|
|
47
47
|
const [maxUid] = activeUids;
|
|
48
|
-
const videoState = defaultContent[maxUid]
|
|
48
|
+
const videoState = defaultContent[maxUid].video;
|
|
49
49
|
async function join() {
|
|
50
50
|
if (
|
|
51
51
|
rtcProps?.encryption &&
|
|
@@ -47,42 +47,23 @@ const RtcConfigure = (props: {children: React.ReactNode}) => {
|
|
|
47
47
|
);
|
|
48
48
|
const localUid = useLocalUid();
|
|
49
49
|
|
|
50
|
-
const initialLocalState: Partial<ContentStateInterface> =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
lastJoinedUid: 0,
|
|
68
|
-
}
|
|
69
|
-
: {
|
|
70
|
-
customContent: {},
|
|
71
|
-
defaultContent: {
|
|
72
|
-
[localUid]: {
|
|
73
|
-
uid: localUid,
|
|
74
|
-
audio: ToggleState.disabled,
|
|
75
|
-
video: ToggleState.disabled,
|
|
76
|
-
streamType: 'high',
|
|
77
|
-
type: 'rtc',
|
|
78
|
-
permissionStatus: PermissionState.NOT_REQUESTED,
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
activeUids: [localUid],
|
|
82
|
-
pinnedUid: undefined,
|
|
83
|
-
secondaryPinnedUid: undefined,
|
|
84
|
-
lastJoinedUid: 0,
|
|
85
|
-
};
|
|
50
|
+
const initialLocalState: Partial<ContentStateInterface> = {
|
|
51
|
+
customContent: {},
|
|
52
|
+
defaultContent: {
|
|
53
|
+
[localUid]: {
|
|
54
|
+
uid: localUid,
|
|
55
|
+
audio: ToggleState.disabled,
|
|
56
|
+
video: ToggleState.disabled,
|
|
57
|
+
streamType: 'high',
|
|
58
|
+
type: 'rtc',
|
|
59
|
+
permissionStatus: PermissionState.NOT_REQUESTED,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
activeUids: [localUid],
|
|
63
|
+
pinnedUid: undefined,
|
|
64
|
+
secondaryPinnedUid: undefined,
|
|
65
|
+
lastJoinedUid: 0,
|
|
66
|
+
};
|
|
86
67
|
|
|
87
68
|
const [initialState, setInitialState] = React.useState(
|
|
88
69
|
JSON.parse(JSON.stringify(initialLocalState)),
|
package/template/package.json
CHANGED
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"agora-extension-ai-denoiser": "1.1.0",
|
|
61
61
|
"agora-extension-virtual-background": "^1.1.3",
|
|
62
62
|
"agora-react-native-rtm": "1.5.1",
|
|
63
|
-
"agora-rtc-sdk-ng": "4.
|
|
63
|
+
"agora-rtc-sdk-ng": "4.19.0",
|
|
64
64
|
"agora-rtm-sdk": "1.5.1",
|
|
65
65
|
"buffer": "^6.0.3",
|
|
66
66
|
"electron-log": "4.3.5",
|
|
@@ -17,21 +17,6 @@ import {Route, Switch, Redirect} from './components/Router';
|
|
|
17
17
|
import AuthRoute from './auth/AuthRoute';
|
|
18
18
|
import {IDPAuth} from './auth/IDPAuth';
|
|
19
19
|
import {Text} from 'react-native';
|
|
20
|
-
import RecordingBotRoute from './components/recording-bot/RecordingBotRoute';
|
|
21
|
-
import {useIsRecordingBot} from './subComponents/recording/useIsRecordingBot';
|
|
22
|
-
|
|
23
|
-
function VideoCallWrapper(props) {
|
|
24
|
-
const {isRecordingBotRoute} = useIsRecordingBot();
|
|
25
|
-
return isRecordingBotRoute ? (
|
|
26
|
-
<RecordingBotRoute history={props.history}>
|
|
27
|
-
<VideoCall />
|
|
28
|
-
</RecordingBotRoute>
|
|
29
|
-
) : (
|
|
30
|
-
<AuthRoute>
|
|
31
|
-
<VideoCall />
|
|
32
|
-
</AuthRoute>
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
20
|
|
|
36
21
|
function AppRoutes() {
|
|
37
22
|
return (
|
|
@@ -48,7 +33,9 @@ function AppRoutes() {
|
|
|
48
33
|
<AuthRoute exact path={'/create'}>
|
|
49
34
|
<Create />
|
|
50
35
|
</AuthRoute>
|
|
51
|
-
<
|
|
36
|
+
<AuthRoute path={'/:phrase'}>
|
|
37
|
+
<VideoCall />
|
|
38
|
+
</AuthRoute>
|
|
52
39
|
<Route path="*">
|
|
53
40
|
<Text>Page not found</Text>
|
|
54
41
|
</Route>
|
|
@@ -87,24 +87,22 @@ const AppWrapper = (props: AppWrapperProps) => {
|
|
|
87
87
|
<StatusBar hidden={true} />
|
|
88
88
|
<StorageProvider>
|
|
89
89
|
<LanguageProvider>
|
|
90
|
-
<
|
|
91
|
-
<
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}}
|
|
107
|
-
</ToastContext.Consumer>
|
|
90
|
+
<ToastProvider>
|
|
91
|
+
<ToastContext.Consumer>
|
|
92
|
+
{({isActionSheetVisible}) => {
|
|
93
|
+
return !isActionSheetVisible ? <ToastComponent /> : null;
|
|
94
|
+
}}
|
|
95
|
+
</ToastContext.Consumer>
|
|
96
|
+
<GraphQLProvider>
|
|
97
|
+
<Router
|
|
98
|
+
/*@ts-ignore Router will be memory Router in sdk*/
|
|
99
|
+
initialEntries={[
|
|
100
|
+
//@ts-ignore
|
|
101
|
+
isSDK && SdkJoinState.phrase
|
|
102
|
+
? //@ts-ignore
|
|
103
|
+
`/${SdkJoinState.phrase}`
|
|
104
|
+
: '',
|
|
105
|
+
]}>
|
|
108
106
|
<AuthProvider>
|
|
109
107
|
<SessionProvider>
|
|
110
108
|
<ColorConfigure>
|
|
@@ -118,9 +116,9 @@ const AppWrapper = (props: AppWrapperProps) => {
|
|
|
118
116
|
</ColorConfigure>
|
|
119
117
|
</SessionProvider>
|
|
120
118
|
</AuthProvider>
|
|
121
|
-
</
|
|
122
|
-
</
|
|
123
|
-
</
|
|
119
|
+
</Router>
|
|
120
|
+
</GraphQLProvider>
|
|
121
|
+
</ToastProvider>
|
|
124
122
|
</LanguageProvider>
|
|
125
123
|
</StorageProvider>
|
|
126
124
|
</SafeAreaView>
|
|
@@ -39,7 +39,6 @@ import {useLayout} from '../utils/useLayout';
|
|
|
39
39
|
import {getGridLayoutName} from '../pages/video-call/DefaultLayouts';
|
|
40
40
|
import {ChatHeader} from '../pages/video-call/SidePanelHeader';
|
|
41
41
|
import useCaptionWidth from '../../src/subComponents/caption/useCaptionWidth';
|
|
42
|
-
import {useIsRecordingBot} from '../subComponents/recording/useIsRecordingBot';
|
|
43
42
|
|
|
44
43
|
export interface ChatProps {
|
|
45
44
|
chatBubble?: React.ComponentType<ChatBubbleProps>;
|
|
@@ -52,7 +51,7 @@ const Chat = (props?: ChatProps) => {
|
|
|
52
51
|
const isSmall = useIsSmall();
|
|
53
52
|
const {setSidePanel} = useSidePanel();
|
|
54
53
|
const {showHeader = true} = props;
|
|
55
|
-
|
|
54
|
+
|
|
56
55
|
const {chatType, setChatType, setPrivateChatUser} = useChatUIControls();
|
|
57
56
|
|
|
58
57
|
const {
|
|
@@ -171,13 +170,9 @@ const Chat = (props?: ChatProps) => {
|
|
|
171
170
|
{chatType === ChatType.Group ? (
|
|
172
171
|
<>
|
|
173
172
|
<ChatContainer {...props} />
|
|
174
|
-
{
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
<View style={style.chatInputContainer}>
|
|
178
|
-
<ChatInputComponent />
|
|
179
|
-
</View>
|
|
180
|
-
)}
|
|
173
|
+
<View style={style.chatInputContainer}>
|
|
174
|
+
<ChatInputComponent />
|
|
175
|
+
</View>
|
|
181
176
|
</>
|
|
182
177
|
) : (
|
|
183
178
|
<></>
|
|
@@ -190,15 +185,11 @@ const Chat = (props?: ChatProps) => {
|
|
|
190
185
|
{chatType === ChatType.Private ? (
|
|
191
186
|
<>
|
|
192
187
|
<ChatContainer {...props} />
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
<View>
|
|
197
|
-
<View style={style.chatInputContainer}>
|
|
198
|
-
<ChatInputComponent />
|
|
199
|
-
</View>
|
|
188
|
+
<View>
|
|
189
|
+
<View style={style.chatInputContainer}>
|
|
190
|
+
<ChatInputComponent />
|
|
200
191
|
</View>
|
|
201
|
-
|
|
192
|
+
</View>
|
|
202
193
|
</>
|
|
203
194
|
) : (
|
|
204
195
|
<></>
|
|
@@ -15,11 +15,13 @@ import {
|
|
|
15
15
|
InMemoryCache,
|
|
16
16
|
ApolloProvider,
|
|
17
17
|
NormalizedCacheObject,
|
|
18
|
-
ApolloLink,
|
|
19
18
|
// from,
|
|
20
19
|
} from '@apollo/client';
|
|
20
|
+
import {setContext} from '@apollo/client/link/context';
|
|
21
|
+
// import useMount from './useMount';
|
|
21
22
|
import React, {createContext, useContext, useEffect, useState} from 'react';
|
|
22
23
|
import StorageContext from './StorageContext';
|
|
24
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
23
25
|
|
|
24
26
|
export const GraphQLContext = createContext<{
|
|
25
27
|
client: ApolloClient<NormalizedCacheObject>;
|
|
@@ -33,57 +35,38 @@ const httpLink = createHttpLink({
|
|
|
33
35
|
credentials: 'include',
|
|
34
36
|
});
|
|
35
37
|
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (token) {
|
|
51
|
-
operation.setContext(({headers = {}}) => ({
|
|
52
|
-
headers: {
|
|
53
|
-
...headers,
|
|
54
|
-
'X-Project-ID': $config.PROJECT_ID,
|
|
55
|
-
'X-Platform-ID': 'turnkey_web',
|
|
56
|
-
...(token && {
|
|
57
|
-
authorization: token ? `Bearer ${token}` : '',
|
|
58
|
-
}),
|
|
59
|
-
},
|
|
60
|
-
}));
|
|
61
|
-
}
|
|
62
|
-
return forward(operation);
|
|
38
|
+
const authLink = (token: string) =>
|
|
39
|
+
setContext(async (_, {headers}) => {
|
|
40
|
+
// get the authentication token from local storage if it exists
|
|
41
|
+
// return the headers to the context so httpLink can read them
|
|
42
|
+
return {
|
|
43
|
+
headers: {
|
|
44
|
+
...headers,
|
|
45
|
+
'X-Project-ID': $config.PROJECT_ID,
|
|
46
|
+
'X-Platform-ID': 'turnkey_web',
|
|
47
|
+
...(token && {
|
|
48
|
+
authorization: token ? `Bearer ${token}` : '',
|
|
49
|
+
}),
|
|
50
|
+
},
|
|
51
|
+
};
|
|
63
52
|
});
|
|
64
|
-
};
|
|
65
53
|
|
|
66
54
|
const GraphQLProvider = (props: {children: React.ReactNode}) => {
|
|
67
55
|
const {store} = useContext(StorageContext);
|
|
68
|
-
const [client, setClient] = useState(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
// cache: new InMemoryCache(),
|
|
75
|
-
// }),
|
|
76
|
-
// );
|
|
77
|
-
// }, [store?.token]);
|
|
56
|
+
const [client, setClient] = useState(
|
|
57
|
+
new ApolloClient({
|
|
58
|
+
link: authLink(store?.token).concat(httpLink),
|
|
59
|
+
cache: new InMemoryCache(),
|
|
60
|
+
}),
|
|
61
|
+
);
|
|
78
62
|
|
|
79
63
|
useEffect(() => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
})();
|
|
64
|
+
setClient(
|
|
65
|
+
new ApolloClient({
|
|
66
|
+
link: authLink(store?.token).concat(httpLink),
|
|
67
|
+
cache: new InMemoryCache(),
|
|
68
|
+
}),
|
|
69
|
+
);
|
|
87
70
|
}, [store?.token]);
|
|
88
71
|
|
|
89
72
|
// const errorLink = onError(
|
|
@@ -91,7 +74,7 @@ const GraphQLProvider = (props: {children: React.ReactNode}) => {
|
|
|
91
74
|
// // To retry on network errors, we recommend the RetryLink
|
|
92
75
|
// // instead of the onError link. This just logs the error.
|
|
93
76
|
// if (networkError) {
|
|
94
|
-
|
|
77
|
+
|
|
95
78
|
// // switch (err.extensions.code) {
|
|
96
79
|
// // // Apollo Server sets code to UNAUTHENTICATED
|
|
97
80
|
// // // when an AuthenticationError is thrown in a resolver
|
|
@@ -78,12 +78,12 @@ export const StorageProvider = (props: {children: React.ReactNode}) => {
|
|
|
78
78
|
setReady(true);
|
|
79
79
|
} else {
|
|
80
80
|
const storeFromStorage = JSON.parse(storeString);
|
|
81
|
-
Object.keys(initStoreValue).forEach(key => {
|
|
81
|
+
Object.keys(initStoreValue).forEach((key) => {
|
|
82
82
|
if (!storeFromStorage[key]) {
|
|
83
83
|
storeFromStorage[key] = initStoreValue[key];
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
|
-
//
|
|
86
|
+
//unauth flow delete token from the localstoage if any
|
|
87
87
|
if (!ENABLE_AUTH) {
|
|
88
88
|
storeFromStorage['token'] = null;
|
|
89
89
|
}
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import Toast from '../../react-native-toast-message';
|
|
3
3
|
import ToastConfig from '../subComponents/ToastConfig';
|
|
4
|
-
import {useIsRecordingBot} from '../subComponents/recording/useIsRecordingBot';
|
|
5
4
|
|
|
6
5
|
const ToastComponent = () => {
|
|
7
|
-
const {isRecordingBot} = useIsRecordingBot();
|
|
8
|
-
|
|
9
6
|
// if ($config.TOAST_NOTIFICATIONS) {
|
|
10
7
|
// return <Toast ref={(ref) => Toast.setRef(ref)} config={ToastConfig} />;
|
|
11
8
|
// } else return <></>;
|
|
12
|
-
|
|
13
|
-
return <></>;
|
|
14
|
-
}
|
|
15
|
-
return <Toast ref={ref => Toast.setRef(ref)} config={ToastConfig} />;
|
|
9
|
+
return <Toast ref={(ref) => Toast.setRef(ref)} config={ToastConfig} />;
|
|
16
10
|
};
|
|
17
11
|
export default ToastComponent;
|
|
@@ -438,12 +438,6 @@ export const videoRoomScreenShareErrorToastSubHeading = `video${room}ScreenShare
|
|
|
438
438
|
|
|
439
439
|
export const videoRoomRecordingToastHeading = `video${room}RecordingToastHeading`;
|
|
440
440
|
export const videoRoomRecordingToastSubHeading = `video${room}RecordingToastSubHeading`;
|
|
441
|
-
export const videoRoomRecordingStartErrorToastHeading =
|
|
442
|
-
'videoRoomRecordingStartErrorToastHeading';
|
|
443
|
-
export const videoRoomRecordingStopErrorToastHeading =
|
|
444
|
-
'videoRoomRecordingStopErrorToastHeading';
|
|
445
|
-
export const videoRoomRecordingErrorToastSubHeading =
|
|
446
|
-
'videoRoomRecordingErrorToastSubHeading';
|
|
447
441
|
|
|
448
442
|
export const peoplePanelUserNotFoundLabel = 'peoplePanelUserNotFoundLabel';
|
|
449
443
|
export const peoplePanelStreamingRequestSectionHeader =
|
|
@@ -731,10 +725,6 @@ export interface I18nVideoCallScreenLabelsInterface {
|
|
|
731
725
|
[videoRoomScreenShareErrorToastSubHeading]?: I18nBaseType;
|
|
732
726
|
[videoRoomRecordingToastHeading]?: I18nConditionalType;
|
|
733
727
|
[videoRoomRecordingToastSubHeading]?: I18nDynamicType;
|
|
734
|
-
[videoRoomRecordingStartErrorToastHeading]?: I18nBaseType;
|
|
735
|
-
[videoRoomRecordingStopErrorToastHeading]?: I18nBaseType;
|
|
736
|
-
[videoRoomRecordingErrorToastSubHeading]?: I18nBaseType;
|
|
737
|
-
|
|
738
728
|
[peoplePanelUserNotFoundLabel]?: I18nBaseType;
|
|
739
729
|
[peoplePanelStreamingRequestSectionHeader]?: I18nBaseType;
|
|
740
730
|
[peoplePanelLivestreamingApprovalBtnText]?: I18nBaseType;
|
|
@@ -1165,10 +1155,6 @@ export const VideoCallScreenLabels: I18nVideoCallScreenLabelsInterface = {
|
|
|
1165
1155
|
active ? 'Recording Started' : 'Recording Stopped',
|
|
1166
1156
|
[videoRoomRecordingToastSubHeading]: name =>
|
|
1167
1157
|
`This room is being recorded by ${name}`,
|
|
1168
|
-
[videoRoomRecordingStartErrorToastHeading]: 'Recording failed to start',
|
|
1169
|
-
[videoRoomRecordingStopErrorToastHeading]: 'Recording failed to stop',
|
|
1170
|
-
[videoRoomRecordingErrorToastSubHeading]: 'There was an internal error.',
|
|
1171
|
-
|
|
1172
1158
|
[peoplePanelUserNotFoundLabel]: 'User not found',
|
|
1173
1159
|
[peoplePanelStreamingRequestSectionHeader]: 'STREAMING REQUEST',
|
|
1174
1160
|
[peoplePanelLivestreamingApprovalBtnText]: 'Accept',
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
*/
|
|
12
12
|
// @ts-nocheck
|
|
13
13
|
import React, {useState, useContext, useEffect, useRef} from 'react';
|
|
14
|
-
import {useApolloClient} from '@apollo/client';
|
|
15
14
|
import {View, StyleSheet, Text} from 'react-native';
|
|
16
15
|
import {
|
|
17
16
|
RtcConfigure,
|
|
@@ -50,6 +49,7 @@ import {
|
|
|
50
49
|
WaitingRoomStatus,
|
|
51
50
|
} from '../components/room-info/useRoomInfo';
|
|
52
51
|
import {SidePanelProvider} from '../utils/useSidePanel';
|
|
52
|
+
import VideoCallScreen from './video-call/VideoCallScreen';
|
|
53
53
|
import {NetworkQualityProvider} from '../components/NetworkQualityContext';
|
|
54
54
|
import {ChatNotificationProvider} from '../components/chat-notification/useChatNotification';
|
|
55
55
|
import {ChatUIControlsProvider} from '../components/chat-ui/useChatUIControls';
|
|
@@ -70,13 +70,13 @@ import {CaptionProvider} from '../subComponents/caption/useCaption';
|
|
|
70
70
|
import SdkMuteToggleListener from '../components/SdkMuteToggleListener';
|
|
71
71
|
import StorageContext from '../components/StorageContext';
|
|
72
72
|
import {useSetRoomInfo} from '../components/room-info/useSetRoomInfo';
|
|
73
|
+
import WhiteboardConfigure from '../components/whiteboard/WhiteboardConfigure';
|
|
73
74
|
import {NoiseSupressionProvider} from '../app-state/useNoiseSupression';
|
|
74
75
|
import {VideoQualityContextProvider} from '../app-state/useVideoQuality';
|
|
75
76
|
import {VBProvider} from '../components/virtual-background/useVB';
|
|
76
77
|
import {DisableChatProvider} from '../components/disable-chat/useDisableChat';
|
|
77
78
|
import {WaitingRoomProvider} from '../components/contexts/WaitingRoomContext';
|
|
78
|
-
import
|
|
79
|
-
import {useIsRecordingBot} from '../subComponents/recording/useIsRecordingBot';
|
|
79
|
+
import {isWeb} from '../utils/common';
|
|
80
80
|
import {videoRoomStartingCallText} from '../language/default-labels/videoCallScreenLabels';
|
|
81
81
|
import {useString} from '../utils/useString';
|
|
82
82
|
|
|
@@ -129,26 +129,9 @@ const VideoCall: React.FC = () => {
|
|
|
129
129
|
const hasBrandLogo = useHasBrandLogo();
|
|
130
130
|
const joiningLoaderLabel = useString(videoRoomStartingCallText)();
|
|
131
131
|
|
|
132
|
-
const client = useApolloClient();
|
|
133
|
-
|
|
134
132
|
const {setGlobalErrorMessage} = useContext(ErrorContext);
|
|
135
133
|
const {awake, release} = useWakeLock();
|
|
136
|
-
const
|
|
137
|
-
/**
|
|
138
|
-
* Should we set the callscreen to active ??
|
|
139
|
-
* a) If Recording bot( i.e prop: recordingBot) is TRUE then it means,
|
|
140
|
-
* the recording bot is accessing the screen - so YES we should set
|
|
141
|
-
* the callActive as true and we need not check for whether
|
|
142
|
-
* $config.PRECALL is enabled or not.
|
|
143
|
-
* b) If Recording bot( i.e prop: recordingBot) is FALSE then we should set
|
|
144
|
-
* the callActive depending upon the value of magic variable - $config.PRECALL
|
|
145
|
-
*/
|
|
146
|
-
const shouldCallBeSetToActive = isRecordingBot
|
|
147
|
-
? true
|
|
148
|
-
: $config.PRECALL
|
|
149
|
-
? false
|
|
150
|
-
: true;
|
|
151
|
-
const [callActive, setCallActive] = useState(shouldCallBeSetToActive);
|
|
134
|
+
const [callActive, setCallActive] = useState($config.PRECALL ? false : true);
|
|
152
135
|
|
|
153
136
|
//layouts
|
|
154
137
|
const layouts = useLayoutsData();
|
|
@@ -197,7 +180,6 @@ const VideoCall: React.FC = () => {
|
|
|
197
180
|
sdkCameraDevice.deviceId || store?.activeDeviceId?.videoinput || null,
|
|
198
181
|
preferredMicrophoneId:
|
|
199
182
|
sdkMicrophoneDevice.deviceId || store?.activeDeviceId?.audioinput || null,
|
|
200
|
-
recordingBot: isRecordingBot ? true : false,
|
|
201
183
|
});
|
|
202
184
|
|
|
203
185
|
const history = useHistory();
|
|
@@ -342,7 +324,6 @@ const VideoCall: React.FC = () => {
|
|
|
342
324
|
// TODO: These callbacks are being called twice
|
|
343
325
|
SDKEvents.emit('leave');
|
|
344
326
|
history.push('/');
|
|
345
|
-
client.resetStore();
|
|
346
327
|
}, 0);
|
|
347
328
|
},
|
|
348
329
|
UserJoined: (uid: UidType) => {
|
|
@@ -447,7 +428,14 @@ const VideoCall: React.FC = () => {
|
|
|
447
428
|
<VideoMeetingDataProvider>
|
|
448
429
|
<VideoCallProvider>
|
|
449
430
|
<DisableChatProvider>
|
|
450
|
-
|
|
431
|
+
{$config.ENABLE_WHITEBOARD &&
|
|
432
|
+
isWebInternal() ? (
|
|
433
|
+
<WhiteboardConfigure>
|
|
434
|
+
<VideoCallScreen />
|
|
435
|
+
</WhiteboardConfigure>
|
|
436
|
+
) : (
|
|
437
|
+
<VideoCallScreen />
|
|
438
|
+
)}
|
|
451
439
|
</DisableChatProvider>
|
|
452
440
|
</VideoCallProvider>
|
|
453
441
|
</VideoMeetingDataProvider>
|
|
@@ -35,12 +35,12 @@ import events, {PersistanceLevel} from '../../rtm-events-api';
|
|
|
35
35
|
import VideoCallMobileView from './VideoCallMobileView';
|
|
36
36
|
import CaptionContainer from '../../subComponents/caption/CaptionContainer';
|
|
37
37
|
import Transcript from '../../subComponents/caption/Transcript';
|
|
38
|
+
|
|
38
39
|
import Spacer from '../../atoms/Spacer';
|
|
39
40
|
import Leftbar, {LeftbarProps} from '../../components/Leftbar';
|
|
40
41
|
import Rightbar, {RightbarProps} from '../../components/Rightbar';
|
|
41
42
|
import useFindActiveSpeaker from '../../utils/useFindActiveSpeaker';
|
|
42
43
|
import VBPanel from '../../components/virtual-background/VBPanel';
|
|
43
|
-
import {useIsRecordingBot} from '../../subComponents/recording/useIsRecordingBot';
|
|
44
44
|
|
|
45
45
|
const VideoCallScreen = () => {
|
|
46
46
|
useFindActiveSpeaker();
|
|
@@ -231,8 +231,6 @@ const VideoCallScreen = () => {
|
|
|
231
231
|
const isDesktop = useIsDesktop();
|
|
232
232
|
const isSmall = useIsSmall();
|
|
233
233
|
|
|
234
|
-
const {isRecordingBot, recordingBotUIConfig} = useIsRecordingBot();
|
|
235
|
-
|
|
236
234
|
return VideocallComponent ? (
|
|
237
235
|
<VideocallComponent />
|
|
238
236
|
) : // ) : !isDesktop ? (
|
|
@@ -257,23 +255,16 @@ const VideoCallScreen = () => {
|
|
|
257
255
|
)}
|
|
258
256
|
</ToolbarProvider>
|
|
259
257
|
<View style={style.full}>
|
|
260
|
-
<
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
includeDefaultItems={false}
|
|
271
|
-
/>
|
|
272
|
-
) : (
|
|
273
|
-
<TopbarComponent />
|
|
274
|
-
)}
|
|
275
|
-
</ToolbarProvider>
|
|
276
|
-
</View>
|
|
258
|
+
<ToolbarProvider value={{position: ToolbarPosition.top}}>
|
|
259
|
+
{TopbarProps?.length ? (
|
|
260
|
+
<TopbarComponent
|
|
261
|
+
customItems={TopbarProps}
|
|
262
|
+
includeDefaultItems={false}
|
|
263
|
+
/>
|
|
264
|
+
) : (
|
|
265
|
+
<TopbarComponent />
|
|
266
|
+
)}
|
|
267
|
+
</ToolbarProvider>
|
|
277
268
|
<View
|
|
278
269
|
style={[
|
|
279
270
|
style.videoView,
|
|
@@ -325,14 +316,7 @@ const VideoCallScreen = () => {
|
|
|
325
316
|
<>
|
|
326
317
|
<CaptionContainer />
|
|
327
318
|
<Spacer size={10} />
|
|
328
|
-
<
|
|
329
|
-
style={
|
|
330
|
-
isRecordingBot &&
|
|
331
|
-
!recordingBotUIConfig.bottomBar &&
|
|
332
|
-
style.zeroHeight
|
|
333
|
-
}>
|
|
334
|
-
<BottombarComponent />
|
|
335
|
-
</View>
|
|
319
|
+
<BottombarComponent />
|
|
336
320
|
</>
|
|
337
321
|
)}
|
|
338
322
|
</ToolbarProvider>
|
|
@@ -378,8 +362,4 @@ const style = StyleSheet.create({
|
|
|
378
362
|
flex: 12,
|
|
379
363
|
flexDirection: 'row',
|
|
380
364
|
},
|
|
381
|
-
zeroHeight: {
|
|
382
|
-
height: 0,
|
|
383
|
-
visibility: 'hidden',
|
|
384
|
-
},
|
|
385
365
|
});
|
|
@@ -17,31 +17,24 @@ import React, {
|
|
|
17
17
|
useRef,
|
|
18
18
|
useState,
|
|
19
19
|
} from 'react';
|
|
20
|
+
import {gql, useMutation} from '@apollo/client';
|
|
21
|
+
import {useParams} from '../../components/Router';
|
|
22
|
+
import {PropsContext} from '../../../agora-rn-uikit';
|
|
20
23
|
import Toast from '../../../react-native-toast-message';
|
|
21
24
|
import {createHook} from 'customization-implementation';
|
|
22
25
|
import {useString} from '../../utils/useString';
|
|
23
26
|
import ChatContext from '../../components/ChatContext';
|
|
24
27
|
import events, {PersistanceLevel} from '../../rtm-events-api';
|
|
25
28
|
import {EventActions, EventNames} from '../../rtm-events';
|
|
29
|
+
import useRecordingLayoutQuery from './useRecordingLayoutQuery';
|
|
30
|
+
import {useScreenContext} from '../../components/contexts/ScreenShareContext';
|
|
26
31
|
import {useContent} from 'customization-api';
|
|
27
32
|
import {trimText} from '../../utils/common';
|
|
28
33
|
import {useRoomInfo} from 'customization-api';
|
|
29
|
-
import StorageContext from '../../components/StorageContext';
|
|
30
|
-
import {useSidePanel} from '../../utils/useSidePanel';
|
|
31
|
-
import {useCaption} from '../caption/useCaption';
|
|
32
|
-
import {SidePanelType} from '../SidePanelEnum';
|
|
33
|
-
import {
|
|
34
|
-
ChatType,
|
|
35
|
-
useChatUIControls,
|
|
36
|
-
} from '../../components/chat-ui/useChatUIControls';
|
|
37
|
-
import {useIsRecordingBot} from './useIsRecordingBot';
|
|
38
34
|
import {
|
|
39
35
|
videoRoomRecordingToastHeading,
|
|
40
36
|
videoRoomRecordingToastSubHeading,
|
|
41
37
|
videoRoomUserFallbackText,
|
|
42
|
-
videoRoomRecordingStartErrorToastHeading,
|
|
43
|
-
videoRoomRecordingStopErrorToastHeading,
|
|
44
|
-
videoRoomRecordingErrorToastSubHeading,
|
|
45
38
|
} from '../../language/default-labels/videoCallScreenLabels';
|
|
46
39
|
|
|
47
40
|
export interface RecordingContextInterface {
|
|
@@ -58,6 +51,26 @@ const RecordingContext = createContext<RecordingContextInterface>({
|
|
|
58
51
|
inProgress: false,
|
|
59
52
|
});
|
|
60
53
|
|
|
54
|
+
const START_RECORDING = gql`
|
|
55
|
+
mutation startRecordingSession(
|
|
56
|
+
$passphrase: String!
|
|
57
|
+
$secret: String
|
|
58
|
+
$config: recordingConfig!
|
|
59
|
+
) {
|
|
60
|
+
startRecordingSession(
|
|
61
|
+
passphrase: $passphrase
|
|
62
|
+
secret: $secret
|
|
63
|
+
config: $config
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
const STOP_RECORDING = gql`
|
|
69
|
+
mutation stopRecordingSession($passphrase: String!) {
|
|
70
|
+
stopRecordingSession(passphrase: $passphrase)
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
|
|
61
74
|
/**
|
|
62
75
|
* Component to start / stop Agora cloud recording.
|
|
63
76
|
* Sends a control message to all users in the channel over RTM to indicate that
|
|
@@ -87,13 +100,17 @@ interface RecordingProviderProps {
|
|
|
87
100
|
*/
|
|
88
101
|
|
|
89
102
|
const RecordingProvider = (props: RecordingProviderProps) => {
|
|
103
|
+
const {rtcProps} = useContext(PropsContext);
|
|
90
104
|
const {setRecordingActive, isRecordingActive, callActive} = props?.value;
|
|
91
105
|
const {
|
|
92
|
-
data: {isHost
|
|
106
|
+
data: {isHost},
|
|
93
107
|
} = useRoomInfo();
|
|
94
108
|
const [inProgress, setInProgress] = useState(false);
|
|
95
109
|
const [uidWhoStarted, setUidWhoStarted] = useState(0);
|
|
96
110
|
const {defaultContent, activeUids} = useContent();
|
|
111
|
+
const {phrase} = useParams<{phrase: string}>();
|
|
112
|
+
const [startRecordingQuery] = useMutation(START_RECORDING);
|
|
113
|
+
const [stopRecordingQuery] = useMutation(STOP_RECORDING);
|
|
97
114
|
const prevRecordingState = usePrevious<{isRecordingActive: boolean}>({
|
|
98
115
|
isRecordingActive,
|
|
99
116
|
});
|
|
@@ -101,41 +118,11 @@ const RecordingProvider = (props: RecordingProviderProps) => {
|
|
|
101
118
|
videoRoomRecordingToastHeading,
|
|
102
119
|
);
|
|
103
120
|
const subheading = useString(videoRoomRecordingToastSubHeading);
|
|
104
|
-
|
|
105
|
-
const headingStartError = useString(
|
|
106
|
-
videoRoomRecordingStartErrorToastHeading,
|
|
107
|
-
)();
|
|
108
|
-
const headingStopError = useString(videoRoomRecordingStopErrorToastHeading)();
|
|
109
|
-
const subheadingError = useString(videoRoomRecordingErrorToastSubHeading)();
|
|
110
|
-
|
|
111
121
|
const userlabel = useString(videoRoomUserFallbackText)();
|
|
112
122
|
|
|
123
|
+
const {executePresenterQuery, executeNormalQuery} = useRecordingLayoutQuery();
|
|
113
124
|
const {localUid} = useContext(ChatContext);
|
|
114
|
-
const {
|
|
115
|
-
|
|
116
|
-
const {setChatType} = useChatUIControls();
|
|
117
|
-
const {setSidePanel} = useSidePanel();
|
|
118
|
-
const {setIsCaptionON} = useCaption();
|
|
119
|
-
const {isRecordingBot, recordingBotUIConfig} = useIsRecordingBot();
|
|
120
|
-
|
|
121
|
-
const setRecordingBotUI = () => {
|
|
122
|
-
if (isRecordingBot) {
|
|
123
|
-
if (recordingBotUIConfig?.chat && $config.CHAT) {
|
|
124
|
-
setSidePanel(SidePanelType.Chat);
|
|
125
|
-
setChatType(ChatType.Group);
|
|
126
|
-
}
|
|
127
|
-
if (recordingBotUIConfig.stt && $config.ENABLE_STT) {
|
|
128
|
-
setIsCaptionON(true);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
useEffect(() => {
|
|
134
|
-
if (callActive) {
|
|
135
|
-
setRecordingBotUI();
|
|
136
|
-
}
|
|
137
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
138
|
-
}, [callActive]);
|
|
125
|
+
const {screenShareData} = useScreenContext();
|
|
139
126
|
|
|
140
127
|
React.useEffect(() => {
|
|
141
128
|
events.on(EventNames.RECORDING_ATTRIBUTE, data => {
|
|
@@ -193,36 +180,25 @@ const RecordingProvider = (props: RecordingProviderProps) => {
|
|
|
193
180
|
}
|
|
194
181
|
}, [isRecordingActive, callActive, isHost]);
|
|
195
182
|
|
|
196
|
-
const showErrorToast = (text1: string, text2?: string) => {
|
|
197
|
-
Toast.show({
|
|
198
|
-
leadingIconName: 'alert',
|
|
199
|
-
type: 'error',
|
|
200
|
-
text1: text1,
|
|
201
|
-
text2: text2 ? text2 : '',
|
|
202
|
-
visibilityTime: 3000,
|
|
203
|
-
primaryBtn: null,
|
|
204
|
-
secondaryBtn: null,
|
|
205
|
-
leadingIcon: null,
|
|
206
|
-
});
|
|
207
|
-
};
|
|
208
|
-
|
|
209
183
|
const startRecording = () => {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
184
|
+
setInProgress(true);
|
|
185
|
+
// If recording is not going on, start the recording by executing the graphql query
|
|
186
|
+
startRecordingQuery({
|
|
187
|
+
variables: {
|
|
188
|
+
passphrase: phrase,
|
|
189
|
+
secret:
|
|
190
|
+
rtcProps.encryption && rtcProps.encryption.key
|
|
191
|
+
? rtcProps.encryption.key
|
|
192
|
+
: '',
|
|
193
|
+
config: {
|
|
194
|
+
resolution: 'SD360p',
|
|
195
|
+
trigger: 'AUTO',
|
|
196
|
+
},
|
|
217
197
|
},
|
|
218
|
-
body: JSON.stringify({
|
|
219
|
-
passphrase: roomId.host,
|
|
220
|
-
url: `${$config.FRONTEND_ENDPOINT}/${passphrase}`,
|
|
221
|
-
}),
|
|
222
198
|
})
|
|
223
|
-
.then(
|
|
199
|
+
.then(res => {
|
|
224
200
|
setInProgress(false);
|
|
225
|
-
if (res.
|
|
201
|
+
if (res.data.startRecordingSession === 'success') {
|
|
226
202
|
/**
|
|
227
203
|
* 1. Once the backend sucessfuly starts recording, send message
|
|
228
204
|
* in the channel indicating that cloud recording is now active.
|
|
@@ -238,10 +214,22 @@ const RecordingProvider = (props: RecordingProviderProps) => {
|
|
|
238
214
|
// 2. set the local recording state to true to update the UI
|
|
239
215
|
setUidWhoStarted(localUid);
|
|
240
216
|
setRecordingActive(true);
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
217
|
+
// 3. set the presenter mode if screen share is active
|
|
218
|
+
// 3.a Get the most recent screenshare uid
|
|
219
|
+
const sorted = Object.entries(screenShareData)
|
|
220
|
+
.filter(el => el[1]?.ts && el[1].ts > 0 && el[1]?.isActive)
|
|
221
|
+
.sort((a, b) => b[1].ts - a[1].ts);
|
|
222
|
+
|
|
223
|
+
const activeScreenshareUid = sorted.length > 0 ? sorted[0][0] : 0;
|
|
224
|
+
if (activeScreenshareUid) {
|
|
225
|
+
console.log(
|
|
226
|
+
'screenshare: Executing presenter query for screenuid',
|
|
227
|
+
activeScreenshareUid,
|
|
228
|
+
);
|
|
229
|
+
executePresenterQuery(parseInt(activeScreenshareUid));
|
|
230
|
+
} else {
|
|
231
|
+
executeNormalQuery();
|
|
232
|
+
}
|
|
245
233
|
}
|
|
246
234
|
})
|
|
247
235
|
.catch(err => {
|
|
@@ -268,21 +256,11 @@ const RecordingProvider = (props: RecordingProviderProps) => {
|
|
|
268
256
|
activeUids.indexOf(uidWhoStarted) === -1
|
|
269
257
|
) {
|
|
270
258
|
setInProgress(true);
|
|
271
|
-
// If recording is already going on, stop the recording by executing the
|
|
272
|
-
|
|
273
|
-
fetch(`${$config.BACKEND_ENDPOINT}/v1/recording/stop`, {
|
|
274
|
-
method: 'POST',
|
|
275
|
-
headers: {
|
|
276
|
-
'Content-Type': 'application/json',
|
|
277
|
-
authorization: store.token ? `Bearer ${store.token}` : '',
|
|
278
|
-
},
|
|
279
|
-
body: JSON.stringify({
|
|
280
|
-
passphrase: roomId.host,
|
|
281
|
-
}),
|
|
282
|
-
})
|
|
259
|
+
// If recording is already going on, stop the recording by executing the graphql query.
|
|
260
|
+
stopRecordingQuery({variables: {passphrase: phrase}})
|
|
283
261
|
.then(res => {
|
|
284
262
|
setInProgress(false);
|
|
285
|
-
if (res.
|
|
263
|
+
if (res.data.stopRecordingSession === 'success') {
|
|
286
264
|
/**
|
|
287
265
|
* 1. Once the backend sucessfuly starts recording, send message
|
|
288
266
|
* in the channel indicating that cloud recording is now inactive.
|
|
@@ -297,10 +275,6 @@ const RecordingProvider = (props: RecordingProviderProps) => {
|
|
|
297
275
|
);
|
|
298
276
|
// 2. set the local recording state to false to update the UI
|
|
299
277
|
setRecordingActive(false);
|
|
300
|
-
} else if (res.status === 500) {
|
|
301
|
-
showErrorToast(headingStopError, subheadingError);
|
|
302
|
-
} else {
|
|
303
|
-
showErrorToast(headingStopError);
|
|
304
278
|
}
|
|
305
279
|
})
|
|
306
280
|
.catch(err => {
|
|
@@ -5,7 +5,6 @@ import {useAsyncEffect} from './useAsyncEffect';
|
|
|
5
5
|
import LocalEventEmitter, {
|
|
6
6
|
LocalEventsEnum,
|
|
7
7
|
} from '../rtm-events-api/LocalEvents';
|
|
8
|
-
import {useIsRecordingBot} from '../subComponents/recording/useIsRecordingBot';
|
|
9
8
|
|
|
10
9
|
const useIsLocalUserSpeaking = () => {
|
|
11
10
|
const log: (arg1: string, ...args: any[]) => void = (arg1, ...args) => {
|
|
@@ -16,7 +15,6 @@ const useIsLocalUserSpeaking = () => {
|
|
|
16
15
|
const speechRef = useRef(null);
|
|
17
16
|
const audioRef = useRef(audio);
|
|
18
17
|
const audioTrackRef = useRef(null);
|
|
19
|
-
const {isRecordingBot} = useIsRecordingBot();
|
|
20
18
|
|
|
21
19
|
useEffect(() => {
|
|
22
20
|
audioRef.current = audio;
|
|
@@ -42,9 +40,6 @@ const useIsLocalUserSpeaking = () => {
|
|
|
42
40
|
|
|
43
41
|
useEffect(() => {
|
|
44
42
|
LocalEventEmitter.on(LocalEventsEnum.MIC_CHANGED, () => {
|
|
45
|
-
if (isRecordingBot) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
43
|
listenForSpeaker();
|
|
49
44
|
});
|
|
50
45
|
}, []);
|
|
@@ -80,7 +75,7 @@ const useIsLocalUserSpeaking = () => {
|
|
|
80
75
|
};
|
|
81
76
|
|
|
82
77
|
useAsyncEffect(async () => {
|
|
83
|
-
if ($config.ACTIVE_SPEAKER
|
|
78
|
+
if ($config.ACTIVE_SPEAKER) {
|
|
84
79
|
await listenForSpeaker();
|
|
85
80
|
return () => {
|
|
86
81
|
try {
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export function isBotUser(args: [uid: number, elapsed: number]): boolean {
|
|
2
|
-
console.log('supriya inside UserJoined verifying if bot user', args[0]);
|
|
3
|
-
// STT bot
|
|
4
|
-
if (args[0] === 111111) {
|
|
5
|
-
return true;
|
|
6
|
-
}
|
|
7
|
-
// Web Recording bot (userUid)
|
|
8
|
-
if (args[0] === 100000) {
|
|
9
|
-
return true;
|
|
10
|
-
}
|
|
11
|
-
// Web Recording bot (screenUid)
|
|
12
|
-
if (args[0] === 100001) {
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
********************************************
|
|
3
|
-
Copyright © 2024 Agora Lab, Inc., all rights reserved.
|
|
4
|
-
AppBuilder and all associated components, source code, APIs, services, and documentation
|
|
5
|
-
(the “Materials”) are owned by Agora Lab, Inc. and its licensors. The Materials may not be
|
|
6
|
-
accessed, used, modified, or distributed for any purpose without a license from Agora Lab, Inc.
|
|
7
|
-
Use without a license or in violation of any license terms and conditions (including use for
|
|
8
|
-
any purpose competitive to Agora Lab, Inc.’s business) is strictly prohibited. For more
|
|
9
|
-
information visit https://appbuilder.agora.io.
|
|
10
|
-
*********************************************
|
|
11
|
-
*/
|
|
12
|
-
import React, {useContext, useEffect, useState} from 'react';
|
|
13
|
-
import type {RouteProps} from 'react-router';
|
|
14
|
-
import StorageContext from '../StorageContext';
|
|
15
|
-
import Loading from '../../subComponents/Loading';
|
|
16
|
-
import {useIsRecordingBot} from '../../subComponents/recording/useIsRecordingBot';
|
|
17
|
-
|
|
18
|
-
interface RecordingBotRouteProps extends RouteProps {
|
|
19
|
-
children: React.ReactNode;
|
|
20
|
-
history: any;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const RecordingBotRoute: React.FC<RecordingBotRouteProps> = props => {
|
|
24
|
-
const {setStore, store} = useContext(StorageContext);
|
|
25
|
-
const [ready, setReady] = useState(false);
|
|
26
|
-
const {recordingBotToken} = useIsRecordingBot();
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
setStore &&
|
|
29
|
-
setStore(prevState => ({
|
|
30
|
-
...prevState,
|
|
31
|
-
token: recordingBotToken,
|
|
32
|
-
}));
|
|
33
|
-
}, []);
|
|
34
|
-
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
store?.token === recordingBotToken && setReady(true);
|
|
37
|
-
}, [store?.token, recordingBotToken]);
|
|
38
|
-
|
|
39
|
-
return ready ? <>{props.children}</> : <Loading text={'Loading...'} />;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export default RecordingBotRoute;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import React, {useContext, useEffect} from 'react';
|
|
2
|
-
import {PropsContext} from '../../../agora-rn-uikit';
|
|
3
|
-
import VideoCallScreen from '../video-call/VideoCallScreen';
|
|
4
|
-
import {isWebInternal} from '../../utils/common';
|
|
5
|
-
import {useLocation} from '../../components/Router';
|
|
6
|
-
import {getParamFromURL} from '../../utils/common';
|
|
7
|
-
import {useUserPreference} from '../../components/useUserPreference';
|
|
8
|
-
import WhiteboardConfigure from '../../components/whiteboard/WhiteboardConfigure';
|
|
9
|
-
|
|
10
|
-
const VideoCallScreenWithRecordingBot: React.FC = () => {
|
|
11
|
-
const location = useLocation();
|
|
12
|
-
const {setDisplayName} = useUserPreference();
|
|
13
|
-
|
|
14
|
-
const recordingBotName = getParamFromURL(location?.search, 'user_name');
|
|
15
|
-
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
setDisplayName(recordingBotName);
|
|
18
|
-
}, []);
|
|
19
|
-
return <VideoCallScreen />;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const VideoCallScreenWrapper: React.FC = () => {
|
|
23
|
-
const {rtcProps} = useContext(PropsContext);
|
|
24
|
-
|
|
25
|
-
if ($config.ENABLE_WHITEBOARD && isWebInternal()) {
|
|
26
|
-
return (
|
|
27
|
-
<WhiteboardConfigure>
|
|
28
|
-
{rtcProps?.recordingBot ? (
|
|
29
|
-
<VideoCallScreenWithRecordingBot />
|
|
30
|
-
) : (
|
|
31
|
-
<VideoCallScreen />
|
|
32
|
-
)}
|
|
33
|
-
</WhiteboardConfigure>
|
|
34
|
-
);
|
|
35
|
-
} else if (rtcProps?.recordingBot) {
|
|
36
|
-
return <VideoCallScreenWithRecordingBot />;
|
|
37
|
-
}
|
|
38
|
-
return <VideoCallScreen />;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export default VideoCallScreenWrapper;
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import {useSearchParams} from '../../utils/useSearchParams';
|
|
2
|
-
|
|
3
|
-
interface RecordingBotUIConfig {
|
|
4
|
-
chat: boolean;
|
|
5
|
-
topBar: boolean;
|
|
6
|
-
bottomBar: boolean;
|
|
7
|
-
stt: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const regexPattern = new RegExp('true');
|
|
11
|
-
|
|
12
|
-
export function useIsRecordingBot() {
|
|
13
|
-
// Reading and setting URL params
|
|
14
|
-
const isRecordingBot = useSearchParams().get('bot');
|
|
15
|
-
const recordingBotToken = useSearchParams().get('token');
|
|
16
|
-
const recordingBotName = useSearchParams().get('user_name');
|
|
17
|
-
const isRecordingBotRoute = isRecordingBot && recordingBotToken;
|
|
18
|
-
|
|
19
|
-
const chatParam = useSearchParams().get('chat');
|
|
20
|
-
const topBarParam = useSearchParams().get('topBar');
|
|
21
|
-
const bottomBarParam = useSearchParams().get('bottomBar');
|
|
22
|
-
const sttParam = useSearchParams().get('stt');
|
|
23
|
-
|
|
24
|
-
const recordingBotUIConfig: RecordingBotUIConfig = {
|
|
25
|
-
chat: chatParam ? regexPattern.test(chatParam) : true,
|
|
26
|
-
topBar: topBarParam ? regexPattern.test(topBarParam) : false,
|
|
27
|
-
bottomBar: bottomBarParam ? regexPattern.test(bottomBarParam) : false,
|
|
28
|
-
stt: sttParam ? regexPattern.test(sttParam) : false,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
isRecordingBotRoute,
|
|
33
|
-
isRecordingBot,
|
|
34
|
-
recordingBotToken,
|
|
35
|
-
recordingBotName,
|
|
36
|
-
recordingBotUIConfig,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import {useLocation} from '../components/Router';
|
|
2
|
-
import {useMemo} from 'react';
|
|
3
|
-
|
|
4
|
-
interface ReadOnlyURLSearchParams extends URLSearchParams {
|
|
5
|
-
append: never;
|
|
6
|
-
set: never;
|
|
7
|
-
delete: never;
|
|
8
|
-
sort: never;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function useSearchParams() {
|
|
12
|
-
const {search} = useLocation();
|
|
13
|
-
|
|
14
|
-
return useMemo(
|
|
15
|
-
() => new URLSearchParams(search) as ReadOnlyURLSearchParams,
|
|
16
|
-
[search],
|
|
17
|
-
);
|
|
18
|
-
}
|