agora-appbuilder-core 4.1.7 → 4.1.8-beta.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/package.json +2 -2
- package/template/_package-lock.json +30671 -5376
- package/template/bridge/rtc/webNg/RtcEngine.ts +4 -4
- package/template/defaultConfig.js +2 -2
- package/template/esbuild.rsdk.go +1 -2
- package/template/package.json +0 -1
- package/template/src/AppWrapper.tsx +30 -35
- package/template/src/auth/AuthProvider.tsx +28 -35
- package/template/src/auth/IDPAuth.tsx +1 -14
- package/template/src/components/Controls.tsx +45 -15
- package/template/src/components/common/GenericModal.tsx +143 -0
- package/template/src/components/common/GenericPopup.tsx +152 -0
- package/template/src/components/common/data-table.tsx +385 -0
- package/template/src/components/controls/useControlPermissionMatrix.tsx +6 -7
- package/template/src/components/precall/usePreCall.tsx +1 -2
- package/template/src/components/room-info/useRoomInfo.tsx +1 -0
- package/template/src/components/stt-transcript/STTTranscriptTable.tsx +295 -0
- package/template/src/components/stt-transcript/ViewSTTTranscriptModal.tsx +44 -0
- package/template/src/components/stt-transcript/useFetchSTTTranscript.tsx +193 -0
- package/template/src/components/useUserPreference.tsx +0 -11
- package/template/src/language/default-labels/videoCallScreenLabels.ts +7 -0
- package/template/src/logger/AppBuilderLogger.tsx +1 -0
- package/template/src/pages/Create.tsx +2 -2
- package/template/src/pages/VideoCall.tsx +1 -6
- package/template/src/subComponents/LogoutButton.tsx +1 -11
- package/template/src/subComponents/recording/useRecordingLayoutQuery.tsx +83 -78
- package/template/src/utils/common.tsx +79 -1
- package/template/src/utils/useCreateRoom.ts +94 -112
- package/template/src/utils/useEndCall.ts +16 -3
- package/template/src/utils/useGetMeetingPhrase.ts +67 -76
- package/template/src/utils/useJoinRoom.ts +5 -3
- package/template/src/utils/useMutePSTN.ts +47 -45
- package/template/webpack.rsdk.config.js +1 -2
- package/template/src/components/GraphQLProvider.tsx +0 -122
|
@@ -13,14 +13,8 @@ import React, {useContext} from 'react';
|
|
|
13
13
|
import {TouchableOpacity, Text, StyleSheet} from 'react-native';
|
|
14
14
|
import StorageContext, {initStoreValue} from '../components/StorageContext';
|
|
15
15
|
import {useHistory} from '../components/Router';
|
|
16
|
-
import {gql, useMutation} from '@apollo/client';
|
|
17
16
|
import {useString} from '../utils/useString';
|
|
18
17
|
|
|
19
|
-
const LOGOUT = gql`
|
|
20
|
-
mutation logoutSession($token: String!) {
|
|
21
|
-
logoutSession(token: $token)
|
|
22
|
-
}
|
|
23
|
-
`;
|
|
24
18
|
/**
|
|
25
19
|
* Sends a logout request to the backend and logs out the user from the frontend.
|
|
26
20
|
*/
|
|
@@ -28,7 +22,6 @@ const LogoutButton = () => {
|
|
|
28
22
|
const {store, setStore} = useContext(StorageContext);
|
|
29
23
|
const {token} = store;
|
|
30
24
|
const history = useHistory();
|
|
31
|
-
const [logoutQuery] = useMutation(LOGOUT);
|
|
32
25
|
//commented for v1 release
|
|
33
26
|
// const oauthLoginLabel = useString('oauthLoginLabel')();
|
|
34
27
|
// const logoutButton = useString('logoutButton')();
|
|
@@ -41,16 +34,13 @@ const LogoutButton = () => {
|
|
|
41
34
|
* User stored some data in localstorage we don't want to remove their on logout.
|
|
42
35
|
* so setting prevstate with store default value
|
|
43
36
|
*/
|
|
44
|
-
setStore(
|
|
37
|
+
setStore(prevState => {
|
|
45
38
|
return {
|
|
46
39
|
...prevState,
|
|
47
40
|
...initStoreValue,
|
|
48
41
|
};
|
|
49
42
|
});
|
|
50
43
|
}
|
|
51
|
-
logoutQuery({variables: {token}}).catch((e) => {
|
|
52
|
-
console.log(e);
|
|
53
|
-
});
|
|
54
44
|
};
|
|
55
45
|
|
|
56
46
|
const login = () => {
|
|
@@ -1,26 +1,15 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, {useContext} from 'react';
|
|
2
2
|
import {useParams} from '../../components/Router';
|
|
3
3
|
|
|
4
|
-
import {gql, useMutation} from '@apollo/client';
|
|
5
4
|
import {UidType} from '../../../agora-rn-uikit';
|
|
6
5
|
import {logger, LogSource} from '../../logger/AppBuilderLogger';
|
|
7
6
|
import getUniqueID from '../../utils/getUniqueID';
|
|
7
|
+
import StorageContext from '../../components/StorageContext';
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
mutation setPresenter($uid: Int!, $passphrase: String!) {
|
|
11
|
-
setPresenter(uid: $uid, passphrase: $passphrase)
|
|
12
|
-
}
|
|
13
|
-
`;
|
|
14
|
-
|
|
15
|
-
const SET_NORMAL = gql`
|
|
16
|
-
mutation setNormal($passphrase: String!) {
|
|
17
|
-
setNormal(passphrase: $passphrase)
|
|
18
|
-
}
|
|
19
|
-
`;
|
|
9
|
+
const RECORDING_LAYOUT_URL = `${$config.BACKEND_ENDPOINT}/v1/recording/layout/update`;
|
|
20
10
|
|
|
21
11
|
function useRecordingLayoutQuery() {
|
|
22
|
-
const
|
|
23
|
-
const [setNormalQuery] = useMutation(SET_NORMAL);
|
|
12
|
+
const {store} = useContext(StorageContext);
|
|
24
13
|
const {phrase} = useParams<any>();
|
|
25
14
|
/**
|
|
26
15
|
* @param screenShareUid
|
|
@@ -30,104 +19,120 @@ function useRecordingLayoutQuery() {
|
|
|
30
19
|
* and we want that as the main view
|
|
31
20
|
* https://docs.agora.io/en/cloud-recording/cloud_recording_layout?platform=RESTful
|
|
32
21
|
*/
|
|
33
|
-
const executePresenterQuery = (screenShareUid: UidType) => {
|
|
22
|
+
const executePresenterQuery = async (screenShareUid: UidType) => {
|
|
34
23
|
const requestId = getUniqueID();
|
|
35
24
|
const startReqTs = Date.now();
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const payload = JSON.stringify({
|
|
28
|
+
uid: screenShareUid?.toString(),
|
|
39
29
|
passphrase: phrase,
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
preset: 'presenter',
|
|
31
|
+
});
|
|
32
|
+
const res = await fetch(`${RECORDING_LAYOUT_URL}`, {
|
|
33
|
+
method: 'POST',
|
|
42
34
|
headers: {
|
|
35
|
+
'Content-Type': 'application/json',
|
|
36
|
+
authorization: store.token ? `Bearer ${store.token}` : '',
|
|
43
37
|
'X-Request-Id': requestId,
|
|
44
38
|
'X-Session-Id': logger.getSessionId(),
|
|
45
39
|
},
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
'RECORDING',
|
|
54
|
-
'setPresenterQuery success',
|
|
55
|
-
{
|
|
56
|
-
responseData: res,
|
|
57
|
-
startReqTs,
|
|
58
|
-
endReqTs,
|
|
59
|
-
latency: endReqTs - startReqTs,
|
|
60
|
-
requestId,
|
|
61
|
-
},
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
.catch(error => {
|
|
40
|
+
body: payload,
|
|
41
|
+
});
|
|
42
|
+
const response = await res.json();
|
|
43
|
+
|
|
44
|
+
if (response?.error) {
|
|
45
|
+
throw response?.error;
|
|
46
|
+
} else {
|
|
66
47
|
const endReqTs = Date.now();
|
|
67
|
-
logger.
|
|
48
|
+
logger.log(
|
|
68
49
|
LogSource.Internals,
|
|
69
50
|
'RECORDING',
|
|
70
|
-
'setPresenterQuery
|
|
71
|
-
JSON.stringify(error || {}),
|
|
51
|
+
'setPresenterQuery success',
|
|
72
52
|
{
|
|
53
|
+
responseData: res,
|
|
73
54
|
startReqTs,
|
|
74
55
|
endReqTs,
|
|
75
56
|
latency: endReqTs - startReqTs,
|
|
76
57
|
requestId,
|
|
77
58
|
},
|
|
78
59
|
);
|
|
79
|
-
}
|
|
60
|
+
}
|
|
61
|
+
} catch (error) {
|
|
62
|
+
const endReqTs = Date.now();
|
|
63
|
+
logger.error(
|
|
64
|
+
LogSource.Internals,
|
|
65
|
+
'RECORDING',
|
|
66
|
+
'setPresenterQuery failure',
|
|
67
|
+
JSON.stringify(error || {}),
|
|
68
|
+
{
|
|
69
|
+
startReqTs,
|
|
70
|
+
endReqTs,
|
|
71
|
+
latency: endReqTs - startReqTs,
|
|
72
|
+
requestId,
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
}
|
|
80
76
|
};
|
|
81
77
|
|
|
82
|
-
const executeNormalQuery = () => {
|
|
78
|
+
const executeNormalQuery = async () => {
|
|
83
79
|
const requestId = getUniqueID();
|
|
84
80
|
const startReqTs = Date.now();
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
81
|
+
|
|
82
|
+
const payload = JSON.stringify({
|
|
83
|
+
passphrase: phrase,
|
|
84
|
+
preset: 'normal',
|
|
85
|
+
});
|
|
86
|
+
try {
|
|
87
|
+
const res = await fetch(`${RECORDING_LAYOUT_URL}`, {
|
|
88
|
+
method: 'POST',
|
|
88
89
|
headers: {
|
|
90
|
+
'Content-Type': 'application/json',
|
|
91
|
+
authorization: store.token ? `Bearer ${store.token}` : '',
|
|
89
92
|
'X-Request-Id': requestId,
|
|
90
93
|
'X-Session-Id': logger.getSessionId(),
|
|
91
94
|
},
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
'RECORDING',
|
|
100
|
-
'executeNormalQuery success',
|
|
101
|
-
{
|
|
102
|
-
responseData: res,
|
|
103
|
-
startReqTs,
|
|
104
|
-
endReqTs,
|
|
105
|
-
latency: endReqTs - startReqTs,
|
|
106
|
-
requestId,
|
|
107
|
-
},
|
|
108
|
-
);
|
|
109
|
-
// Once the backend sucessfuly stops recording,
|
|
110
|
-
// send a control message to everbody in the channel indicating that cloud recording is now inactive.
|
|
111
|
-
// sendControlMessage(controlMessageEnum.cloudRecordingUnactive);
|
|
112
|
-
// set the local recording state to false to update the UI
|
|
113
|
-
// setScreenshareActive(false);
|
|
114
|
-
}
|
|
115
|
-
})
|
|
116
|
-
.catch(error => {
|
|
95
|
+
body: payload,
|
|
96
|
+
});
|
|
97
|
+
const response = await res.json();
|
|
98
|
+
|
|
99
|
+
if (response?.error) {
|
|
100
|
+
throw response?.error;
|
|
101
|
+
} else {
|
|
117
102
|
const endReqTs = Date.now();
|
|
118
|
-
logger.
|
|
103
|
+
logger.log(
|
|
119
104
|
LogSource.Internals,
|
|
120
105
|
'RECORDING',
|
|
121
|
-
'executeNormalQuery
|
|
122
|
-
JSON.stringify(error || {}),
|
|
106
|
+
'executeNormalQuery success',
|
|
123
107
|
{
|
|
108
|
+
responseData: res,
|
|
124
109
|
startReqTs,
|
|
125
110
|
endReqTs,
|
|
126
111
|
latency: endReqTs - startReqTs,
|
|
127
112
|
requestId,
|
|
128
113
|
},
|
|
129
114
|
);
|
|
130
|
-
|
|
115
|
+
// Once the backend sucessfuly stops recording,
|
|
116
|
+
// send a control message to everbody in the channel indicating that cloud recording is now inactive.
|
|
117
|
+
// sendControlMessage(controlMessageEnum.cloudRecordingUnactive);
|
|
118
|
+
// set the local recording state to false to update the UI
|
|
119
|
+
// setScreenshareActive(false);
|
|
120
|
+
}
|
|
121
|
+
} catch (error) {
|
|
122
|
+
const endReqTs = Date.now();
|
|
123
|
+
logger.error(
|
|
124
|
+
LogSource.Internals,
|
|
125
|
+
'RECORDING',
|
|
126
|
+
'executeNormalQuery failure',
|
|
127
|
+
JSON.stringify(error || {}),
|
|
128
|
+
{
|
|
129
|
+
startReqTs,
|
|
130
|
+
endReqTs,
|
|
131
|
+
latency: endReqTs - startReqTs,
|
|
132
|
+
requestId,
|
|
133
|
+
},
|
|
134
|
+
);
|
|
135
|
+
}
|
|
131
136
|
};
|
|
132
137
|
|
|
133
138
|
return {
|
|
@@ -254,7 +254,7 @@ const debounceFn = (fn: Function, ms = 300) => {
|
|
|
254
254
|
};
|
|
255
255
|
|
|
256
256
|
const capitalizeFirstLetter = (word: string): string => {
|
|
257
|
-
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
257
|
+
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
258
258
|
};
|
|
259
259
|
|
|
260
260
|
const CustomToolbarSort = (a, b) =>
|
|
@@ -382,6 +382,82 @@ function MergeMoreButtonFields(sourceArray, updateObject) {
|
|
|
382
382
|
return result;
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
+
function getFormattedDateTime(ipDate: string) {
|
|
386
|
+
try {
|
|
387
|
+
let rdate = new Date(ipDate);
|
|
388
|
+
let ryear = rdate.getFullYear();
|
|
389
|
+
if (ryear === 1) {
|
|
390
|
+
throw Error(`Invalid end date, ${ipDate}`);
|
|
391
|
+
}
|
|
392
|
+
let rmonth = rdate.getMonth() + 1;
|
|
393
|
+
let rdt = rdate.getDate();
|
|
394
|
+
let hour = rdate.getHours();
|
|
395
|
+
let minute = rdate.getMinutes();
|
|
396
|
+
let ampm = hour >= 12 ? 'pm' : 'am';
|
|
397
|
+
hour = hour % 12;
|
|
398
|
+
hour = hour ? hour : 12; // the hour '0' should be '12'
|
|
399
|
+
minute = minute < 10 ? minute : minute;
|
|
400
|
+
|
|
401
|
+
const formattedHHMM = `${String(hour)}:${String(minute).padStart(
|
|
402
|
+
2,
|
|
403
|
+
'0',
|
|
404
|
+
)} ${ampm}`;
|
|
405
|
+
|
|
406
|
+
let today = new Date();
|
|
407
|
+
today.setHours(0);
|
|
408
|
+
today.setMinutes(0);
|
|
409
|
+
today.setSeconds(0);
|
|
410
|
+
today.setMilliseconds(0);
|
|
411
|
+
|
|
412
|
+
let compDate = new Date(ryear, rmonth - 1, rdt); // month - 1 because January == 0
|
|
413
|
+
let diff = today.getTime() - compDate.getTime(); // get the difference between today(at 00:00:00) and the date
|
|
414
|
+
|
|
415
|
+
if (compDate.getTime() == today.getTime()) {
|
|
416
|
+
return ['Today', `${formattedHHMM}`];
|
|
417
|
+
} else if (diff <= 24 * 60 * 60 * 1000) {
|
|
418
|
+
return ['Yesterday', `${formattedHHMM}`];
|
|
419
|
+
} else {
|
|
420
|
+
let fulldate = rdate.toDateString();
|
|
421
|
+
fulldate = fulldate.substring(fulldate.indexOf(' ') + 1);
|
|
422
|
+
return [fulldate, `${formattedHHMM}`];
|
|
423
|
+
}
|
|
424
|
+
} catch (error) {
|
|
425
|
+
console.error('error while converting recorded time: ', error);
|
|
426
|
+
return ipDate;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const getFileName = (url: string) => {
|
|
431
|
+
return url.split('#')[0].split('?')[0].split('/').pop();
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
const downloadS3Link = (url: string): Promise<void> => {
|
|
435
|
+
return new Promise((resolve, reject) => {
|
|
436
|
+
if (typeof url !== 'string' || !url.trim()) {
|
|
437
|
+
return reject(new Error('Invalid URL provided for download'));
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
try {
|
|
441
|
+
const fileName = getFileName(url);
|
|
442
|
+
const a = document.createElement('a');
|
|
443
|
+
|
|
444
|
+
a.href = url;
|
|
445
|
+
a.download = fileName;
|
|
446
|
+
a.target = '_blank';
|
|
447
|
+
a.rel = 'noopener noreferrer';
|
|
448
|
+
|
|
449
|
+
// Append to body to make `click()` work in all browsers
|
|
450
|
+
document.body.appendChild(a);
|
|
451
|
+
a.click();
|
|
452
|
+
// Clean up
|
|
453
|
+
document.body.removeChild(a);
|
|
454
|
+
resolve();
|
|
455
|
+
} catch (err) {
|
|
456
|
+
reject(err instanceof Error ? err : new Error('Download failed'));
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
};
|
|
460
|
+
|
|
385
461
|
export {
|
|
386
462
|
updateToolbarDefaultConfig,
|
|
387
463
|
useIsDesktop,
|
|
@@ -415,4 +491,6 @@ export {
|
|
|
415
491
|
CustomToolbarMerge,
|
|
416
492
|
MergeMoreButtonFields,
|
|
417
493
|
AuthErrorCodes,
|
|
494
|
+
downloadS3Link,
|
|
495
|
+
getFormattedDateTime,
|
|
418
496
|
};
|
|
@@ -1,31 +1,13 @@
|
|
|
1
|
-
import {gql, useMutation} from '@apollo/client';
|
|
2
1
|
import {RoomInfoContextInterface} from '../components/room-info/useRoomInfo';
|
|
3
2
|
import {useSetRoomInfo} from '../components/room-info/useSetRoomInfo';
|
|
4
3
|
import SDKEvents from '../utils/SdkEvents';
|
|
5
|
-
import isSDK from './isSDK';
|
|
6
4
|
import {LogSource, logger} from '../logger/AppBuilderLogger';
|
|
7
5
|
import getUniqueID from './getUniqueID';
|
|
6
|
+
import {useContext} from 'react';
|
|
7
|
+
import StorageContext from '../components/StorageContext';
|
|
8
|
+
|
|
9
|
+
const CREATE_ROOM_URL = `${$config.BACKEND_ENDPOINT}/v1/channel`;
|
|
8
10
|
|
|
9
|
-
const CREATE_CHANNEL = gql`
|
|
10
|
-
mutation CreateChannel($title: String!, $enablePSTN: Boolean) {
|
|
11
|
-
createChannel(title: $title, enablePSTN: $enablePSTN) {
|
|
12
|
-
passphrase {
|
|
13
|
-
host
|
|
14
|
-
view
|
|
15
|
-
}
|
|
16
|
-
channel
|
|
17
|
-
title
|
|
18
|
-
pstn {
|
|
19
|
-
number
|
|
20
|
-
dtmf
|
|
21
|
-
error {
|
|
22
|
-
code
|
|
23
|
-
message
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
`;
|
|
29
11
|
/**
|
|
30
12
|
* Returns an asynchronous function to create a meeting with the given options.
|
|
31
13
|
*/
|
|
@@ -34,8 +16,8 @@ export type createRoomFun = (
|
|
|
34
16
|
enablePSTN?: boolean,
|
|
35
17
|
) => Promise<void>;
|
|
36
18
|
export default function useCreateRoom(): createRoomFun {
|
|
37
|
-
const [createChannel, {error}] = useMutation(CREATE_CHANNEL);
|
|
38
19
|
const {setRoomInfo} = useSetRoomInfo();
|
|
20
|
+
const {store} = useContext(StorageContext);
|
|
39
21
|
return async (
|
|
40
22
|
roomTitle: string,
|
|
41
23
|
enablePSTN?: boolean,
|
|
@@ -56,25 +38,99 @@ export default function useCreateRoom(): createRoomFun {
|
|
|
56
38
|
requestId,
|
|
57
39
|
},
|
|
58
40
|
);
|
|
59
|
-
|
|
60
|
-
|
|
41
|
+
try {
|
|
42
|
+
const payload = JSON.stringify({
|
|
43
|
+
title: roomTitle,
|
|
44
|
+
enablePSTN: enablePSTN,
|
|
45
|
+
});
|
|
46
|
+
const response = await fetch(`${CREATE_ROOM_URL}`, {
|
|
47
|
+
method: 'POST',
|
|
61
48
|
headers: {
|
|
49
|
+
'Content-Type': 'application/json',
|
|
50
|
+
authorization: store.token ? `Bearer ${store.token}` : '',
|
|
62
51
|
'X-Request-Id': requestId,
|
|
63
52
|
'X-Session-Id': logger.getSessionId(),
|
|
64
53
|
},
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
54
|
+
body: payload,
|
|
55
|
+
});
|
|
56
|
+
const res = await response.json();
|
|
57
|
+
if (res?.error) {
|
|
58
|
+
throw res.error;
|
|
59
|
+
} else if (res?.channel) {
|
|
60
|
+
const endReqTs = Date.now();
|
|
61
|
+
const latency = endReqTs - startReqTs;
|
|
62
|
+
logger.log(
|
|
63
|
+
LogSource.NetworkRest,
|
|
64
|
+
'createChannel',
|
|
65
|
+
'API createChannel. Channel created successfully',
|
|
66
|
+
{
|
|
67
|
+
responseData: res,
|
|
68
|
+
startReqTs,
|
|
69
|
+
endReqTs,
|
|
70
|
+
latency: latency,
|
|
71
|
+
requestId,
|
|
72
|
+
},
|
|
73
|
+
);
|
|
74
|
+
let roomInfo: Partial<RoomInfoContextInterface['data']> = {
|
|
75
|
+
roomId: {
|
|
76
|
+
attendee: '',
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
if (res?.viewer_pass_phrase) {
|
|
80
|
+
roomInfo.roomId.attendee = res.viewer_pass_phrase;
|
|
81
|
+
}
|
|
82
|
+
if (res?.host_pass_phrase) {
|
|
83
|
+
roomInfo.roomId.host = res.host_pass_phrase;
|
|
84
|
+
}
|
|
85
|
+
if (enablePSTN === true && res?.pstn) {
|
|
86
|
+
if (res.pstn?.error?.code || res.pstn?.error?.message) {
|
|
87
|
+
roomInfo.pstn = {
|
|
88
|
+
number: '',
|
|
89
|
+
pin: '',
|
|
90
|
+
error: {
|
|
91
|
+
code: res.pstn?.error?.code,
|
|
92
|
+
message: res.pstn?.error?.message,
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
} else {
|
|
96
|
+
roomInfo.pstn = {
|
|
97
|
+
number: res.pstn?.number,
|
|
98
|
+
pin: res.pstn?.dtmf,
|
|
99
|
+
error: null,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
logger.log(LogSource.Internals, 'CREATE_MEETING', 'Room created', {
|
|
104
|
+
isHost: true,
|
|
105
|
+
isSeparateHostLink: isSeparateHostLink ? true : false,
|
|
106
|
+
meetingTitle: roomTitle,
|
|
107
|
+
roomId: roomInfo?.roomId,
|
|
108
|
+
pstn: roomInfo?.pstn,
|
|
109
|
+
});
|
|
110
|
+
setRoomInfo(prev => {
|
|
111
|
+
return {
|
|
112
|
+
...prev,
|
|
113
|
+
data: {
|
|
114
|
+
isHost: true,
|
|
115
|
+
isSeparateHostLink: isSeparateHostLink ? true : false,
|
|
116
|
+
meetingTitle: roomTitle,
|
|
117
|
+
roomId: roomInfo?.roomId,
|
|
118
|
+
pstn: roomInfo?.pstn,
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
SDKEvents.emit(
|
|
123
|
+
'create',
|
|
124
|
+
roomInfo.roomId.host,
|
|
125
|
+
roomInfo.roomId.attendee,
|
|
126
|
+
roomInfo?.pstn,
|
|
127
|
+
);
|
|
128
|
+
} else {
|
|
129
|
+
throw new Error(`An error occurred in parsing the channel data.`);
|
|
130
|
+
}
|
|
131
|
+
} catch (error) {
|
|
132
|
+
const endReqTs = Date.now();
|
|
133
|
+
const latency = endReqTs - startReqTs;
|
|
78
134
|
logger.error(
|
|
79
135
|
LogSource.NetworkRest,
|
|
80
136
|
'createChannel',
|
|
@@ -89,79 +145,5 @@ export default function useCreateRoom(): createRoomFun {
|
|
|
89
145
|
);
|
|
90
146
|
throw error;
|
|
91
147
|
}
|
|
92
|
-
|
|
93
|
-
if (res && res?.data && res?.data?.createChannel) {
|
|
94
|
-
logger.log(
|
|
95
|
-
LogSource.NetworkRest,
|
|
96
|
-
'createChannel',
|
|
97
|
-
'API createChannel. Channel created successfully',
|
|
98
|
-
{
|
|
99
|
-
responseData: res.data.createChannel,
|
|
100
|
-
startReqTs,
|
|
101
|
-
endReqTs,
|
|
102
|
-
latency: latency,
|
|
103
|
-
requestId,
|
|
104
|
-
},
|
|
105
|
-
);
|
|
106
|
-
let roomInfo: Partial<RoomInfoContextInterface['data']> = {
|
|
107
|
-
roomId: {
|
|
108
|
-
attendee: '',
|
|
109
|
-
},
|
|
110
|
-
};
|
|
111
|
-
if (res?.data?.createChannel?.passphrase?.view) {
|
|
112
|
-
roomInfo.roomId.attendee = res.data.createChannel.passphrase.view;
|
|
113
|
-
}
|
|
114
|
-
if (res?.data?.createChannel?.passphrase?.host) {
|
|
115
|
-
roomInfo.roomId.host = res.data.createChannel.passphrase.host;
|
|
116
|
-
}
|
|
117
|
-
if (enablePSTN === true && res?.data?.createChannel?.pstn) {
|
|
118
|
-
if (
|
|
119
|
-
res.data.createChannel.pstn?.error?.code ||
|
|
120
|
-
res.data.createChannel.pstn?.error?.message
|
|
121
|
-
) {
|
|
122
|
-
roomInfo.pstn = {
|
|
123
|
-
number: '',
|
|
124
|
-
pin: '',
|
|
125
|
-
error: {
|
|
126
|
-
code: res.data.createChannel.pstn?.error?.code,
|
|
127
|
-
message: res.data.createChannel.pstn?.error?.message,
|
|
128
|
-
},
|
|
129
|
-
};
|
|
130
|
-
} else {
|
|
131
|
-
roomInfo.pstn = {
|
|
132
|
-
number: res.data.createChannel.pstn?.number,
|
|
133
|
-
pin: res.data.createChannel.pstn?.dtmf,
|
|
134
|
-
error: null,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
logger.log(LogSource.Internals, 'CREATE_MEETING', 'Room created', {
|
|
139
|
-
isHost: true,
|
|
140
|
-
isSeparateHostLink: isSeparateHostLink ? true : false,
|
|
141
|
-
meetingTitle: roomTitle,
|
|
142
|
-
roomId: roomInfo?.roomId,
|
|
143
|
-
pstn: roomInfo?.pstn,
|
|
144
|
-
});
|
|
145
|
-
setRoomInfo(prev => {
|
|
146
|
-
return {
|
|
147
|
-
...prev,
|
|
148
|
-
data: {
|
|
149
|
-
isHost: true,
|
|
150
|
-
isSeparateHostLink: isSeparateHostLink ? true : false,
|
|
151
|
-
meetingTitle: roomTitle,
|
|
152
|
-
roomId: roomInfo?.roomId,
|
|
153
|
-
pstn: roomInfo?.pstn,
|
|
154
|
-
},
|
|
155
|
-
};
|
|
156
|
-
});
|
|
157
|
-
SDKEvents.emit(
|
|
158
|
-
'create',
|
|
159
|
-
roomInfo.roomId.host,
|
|
160
|
-
roomInfo.roomId.attendee,
|
|
161
|
-
roomInfo?.pstn,
|
|
162
|
-
);
|
|
163
|
-
} else {
|
|
164
|
-
throw new Error(`An error occurred in parsing the channel data.`);
|
|
165
|
-
}
|
|
166
148
|
};
|
|
167
149
|
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import {useContext} from 'react';
|
|
2
2
|
import {useCustomization} from 'customization-implementation';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
useCaption,
|
|
5
|
+
useContent,
|
|
6
|
+
useRoomInfo,
|
|
7
|
+
useSTTAPI,
|
|
8
|
+
} from 'customization-api';
|
|
4
9
|
import {PropsContext, DispatchContext} from '../../agora-rn-uikit';
|
|
5
10
|
import {useHistory} from '../components/Router';
|
|
6
11
|
import {stopForegroundService} from '../subComponents/LocalEndCall';
|
|
@@ -18,6 +23,7 @@ const useEndCall = () => {
|
|
|
18
23
|
} = useRoomInfo();
|
|
19
24
|
const {authLogin} = useAuth();
|
|
20
25
|
const {deleteChatUser} = useChatConfigure();
|
|
26
|
+
const {stop: stopSTTAPI} = useSTTAPI();
|
|
21
27
|
|
|
22
28
|
const {rtcProps} = useContext(PropsContext);
|
|
23
29
|
const {dispatch} = useContext(DispatchContext);
|
|
@@ -49,9 +55,16 @@ const useEndCall = () => {
|
|
|
49
55
|
stopForegroundService();
|
|
50
56
|
// stopping STT on call end,if only last user is remaining in call
|
|
51
57
|
const usersInCall = Object.entries(defaultContent).filter(
|
|
52
|
-
item =>
|
|
58
|
+
item =>
|
|
59
|
+
item[1].type === 'rtc' && item[1].isHost === 'true' && !item[1].offline,
|
|
53
60
|
);
|
|
54
|
-
usersInCall.length === 1 && isSTTActive
|
|
61
|
+
if (usersInCall.length === 1 && isSTTActive) {
|
|
62
|
+
console.log('Stopping stt api as only one host is in the call');
|
|
63
|
+
stopSTTAPI().catch(error => {
|
|
64
|
+
console.log('Error stopping stt', error);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
55
68
|
// removing user from chat server
|
|
56
69
|
if ($config.CHAT) {
|
|
57
70
|
deleteChatUser();
|