agora-appbuilder-core 4.0.0-api.7 → 4.0.0-api.9
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 +3 -3
- package/template/_package-lock.json +5911 -4861
- package/template/agora-rn-uikit/.eslintrc.js +5 -0
- package/template/agora-rn-uikit/package.json +14 -14
- package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +41 -22
- package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +2 -2
- package/template/agora-rn-uikit/src/Rtc/Create.tsx +90 -57
- package/template/agora-rn-uikit/src/Rtc/Join.tsx +20 -16
- package/template/agora-rn-uikit/src/RtcConfigure.tsx +10 -10
- package/template/agora-rn-uikit/src/Utils/isBotUser.ts +15 -0
- package/template/agora-rn-uikit/src/Utils/quality.tsx +8 -0
- package/template/agora-rn-uikit/src/Views/MaxVideoView.native.tsx +32 -16
- package/template/agora-rn-uikit/src/Views/MaxVideoView.tsx +25 -14
- package/template/agora-rn-uikit/src/Views/MinVideoView.tsx +15 -9
- package/template/agora-rn-uikit/src/index.ts +1 -1
- package/template/bridge/rtc/webNg/RtcEngine.ts +73 -58
- package/template/bridge/rtc/webNg/{SurfaceView.tsx → RtcSurfaceView.tsx} +20 -26
- package/template/bridge/rtc/webNg/Types.ts +20 -5
- package/template/bridge/rtc/webNg/index.ts +9 -13
- package/template/customization-api/temp.ts +2 -2
- package/template/customization-api/typeDefinition.ts +1 -2
- package/template/customization-api/utils.ts +1 -2
- package/template/index.js +1 -0
- package/template/ios/HelloWorld/HelloWorldDebug.entitlements +10 -0
- package/template/ios/HelloWorld.xcodeproj/project.pbxproj +4 -0
- package/template/ios/Podfile +1 -1
- package/template/ios/Podfile.lock +72 -140
- package/template/package.json +5 -4
- package/template/src/App.tsx +58 -1
- package/template/src/AppRoutes.tsx +16 -3
- package/template/src/AppWrapper.tsx +21 -19
- package/template/src/components/Chat.tsx +17 -8
- package/template/src/components/ChatContext.ts +0 -2
- package/template/src/components/Controls.tsx +5 -5
- package/template/src/components/Controls1.native.tsx +7 -3
- package/template/src/components/DeviceConfigure.native.tsx +2 -2
- package/template/src/components/DeviceConfigure.tsx +2 -2
- package/template/src/components/EventsConfigure.tsx +13 -22
- package/template/src/components/GraphQLProvider.tsx +47 -30
- package/template/src/components/GridVideo.tsx +6 -2
- package/template/src/components/NetworkQualityContext.tsx +11 -5
- package/template/src/components/ParticipantsView.tsx +3 -3
- package/template/src/components/PinnedVideo.tsx +2 -2
- package/template/src/components/Precall.native.tsx +9 -6
- package/template/src/components/Precall.tsx +9 -6
- package/template/src/components/StorageContext.tsx +5 -2
- package/template/src/components/ToastComponent.tsx +7 -1
- package/template/src/components/contexts/LiveStreamDataContext.tsx +3 -3
- package/template/src/components/livestream/LiveStreamContext.tsx +42 -33
- package/template/src/components/livestream/Types.ts +2 -2
- package/template/src/components/participants/Participant.tsx +1 -1
- package/template/src/components/participants/UserActionMenuOptions.tsx +7 -2
- package/template/src/components/recording-bot/RecordingBotRoute.tsx +42 -0
- package/template/src/components/virtual-background/useVB.native.tsx +16 -19
- package/template/src/components/virtual-background/useVB.tsx +1 -1
- package/template/src/components/whiteboard/WhiteboardConfigure.native.tsx +11 -0
- package/template/src/components/whiteboard/WhiteboardConfigure.tsx +5 -0
- package/template/src/components/whiteboard/WhiteboardView.native.tsx +91 -12
- package/template/src/components/whiteboard/WhiteboardWidget.tsx +15 -4
- package/template/src/language/default-labels/precallScreenLabels.ts +5 -3
- package/template/src/language/default-labels/videoCallScreenLabels.ts +93 -41
- package/template/src/pages/VideoCall.tsx +39 -37
- package/template/src/pages/video-call/ActionSheetContent.tsx +4 -3
- package/template/src/pages/video-call/NameWithMicIcon.tsx +2 -1
- package/template/src/pages/video-call/VideoCallMobileView.tsx +26 -2
- package/template/src/pages/video-call/VideoCallScreen.tsx +32 -12
- package/template/src/pages/video-call/VideoCallScreenWrapper.tsx +41 -0
- package/template/src/pages/video-call/VideoComponent.tsx +5 -2
- package/template/src/pages/video-call/VideoRenderer.tsx +55 -34
- package/template/src/rtm-events/constants.ts +0 -2
- package/template/src/subComponents/ChatBubble.tsx +2 -0
- package/template/src/subComponents/LocalAudioMute.tsx +8 -47
- package/template/src/subComponents/LocalEndCall.tsx +5 -52
- package/template/src/subComponents/LocalSwitchCamera.tsx +3 -3
- package/template/src/subComponents/LocalVideoMute.tsx +8 -50
- package/template/src/subComponents/SelectDevice.tsx +5 -2
- package/template/src/subComponents/SelectDeviceSettings.backup.tsx +9 -6
- package/template/src/subComponents/caption/Caption.tsx +12 -10
- package/template/src/subComponents/caption/Transcript.tsx +13 -10
- package/template/src/subComponents/caption/useTranscriptDownload.native.ts +11 -16
- package/template/src/subComponents/caption/utils.ts +1 -0
- package/template/src/subComponents/livestream/ApprovedLiveStreamControlsView.tsx +2 -2
- package/template/src/subComponents/livestream/CurrentLiveStreamRequestsView.tsx +3 -2
- package/template/src/subComponents/livestream/controls/LocalRaiseHand.tsx +1 -1
- package/template/src/subComponents/recording/useIsRecordingBot.tsx +38 -0
- package/template/src/subComponents/recording/useRecording.tsx +176 -135
- package/template/src/subComponents/screenshare/ScreenshareButton.tsx +3 -3
- package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +1 -22
- package/template/src/utils/index.tsx +16 -5
- package/template/src/utils/useEndCall.ts +65 -0
- package/template/src/utils/useIsLocalUserSpeaking.ts +6 -1
- package/template/{bridge/rtc/webNg/LocalView.tsx → src/utils/useLocalAudio.ts} +24 -6
- package/template/src/utils/useMuteToggleLocal.ts +10 -5
- package/template/src/utils/useSearchParams.tsx +18 -0
- package/template/src/wasms/agora-virtual-background.wasm +0 -0
- package/template/src/utils/endCallEveryOne.ts +0 -7
- package/template/src/utils/useDisableButton.tsx +0 -37
|
@@ -22,24 +22,24 @@
|
|
|
22
22
|
"url": "https://github.com/AgoraIO-Community/ReactNative-UIKit/issues"
|
|
23
23
|
},
|
|
24
24
|
"peerDependencies": {
|
|
25
|
-
"react": "
|
|
26
|
-
"react-native": "
|
|
27
|
-
"react-native-agora": "
|
|
25
|
+
"react": "18.2.0",
|
|
26
|
+
"react-native": "0.72.4",
|
|
27
|
+
"react-native-agora": "4.2.6"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@babel/core": "^7.
|
|
31
|
-
"@babel/runtime": "^7.
|
|
30
|
+
"@babel/core": "^7.20.0",
|
|
31
|
+
"@babel/runtime": "^7.20.0",
|
|
32
32
|
"@react-native-community/eslint-config": "^1.0.0",
|
|
33
33
|
"@types/jest": "^24.0.24",
|
|
34
|
-
"@types/react-native": "
|
|
35
|
-
"@types/react-test-renderer": "
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "
|
|
37
|
-
"@typescript-eslint/parser": "
|
|
38
|
-
"babel-jest": "^
|
|
39
|
-
"eslint": "^
|
|
40
|
-
"jest": "^
|
|
41
|
-
"metro-react-native-babel-preset": "
|
|
42
|
-
"react-test-renderer": "
|
|
34
|
+
"@types/react-native": "0.67.6",
|
|
35
|
+
"@types/react-test-renderer": "18.0.0",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "6.4.0",
|
|
37
|
+
"@typescript-eslint/parser": "6.4.0",
|
|
38
|
+
"babel-jest": "^29.2.1",
|
|
39
|
+
"eslint": "^8.19.0",
|
|
40
|
+
"jest": "^29.2.1",
|
|
41
|
+
"metro-react-native-babel-preset": "0.76.8",
|
|
42
|
+
"react-test-renderer": "18.2.0",
|
|
43
43
|
"prettier": "^2.0.4",
|
|
44
44
|
"typescript": "^3.8.3"
|
|
45
45
|
},
|
|
@@ -1,26 +1,44 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import {StyleProp, ViewStyle} from 'react-native';
|
|
3
|
-
import {
|
|
3
|
+
import {IRtcEngineEventHandler} from 'react-native-agora';
|
|
4
4
|
import {EncryptionMode} from 'react-native-agora';
|
|
5
5
|
import {VideoProfile} from '../Utils/quality';
|
|
6
6
|
import {UidType} from './RtcContext';
|
|
7
7
|
|
|
8
8
|
/* User role for live streaming mode */
|
|
9
|
-
export enum
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
export enum ClientRoleType {
|
|
10
|
+
/**
|
|
11
|
+
* 1: Host. A host can both send and receive streams.
|
|
12
|
+
*/
|
|
13
|
+
ClientRoleBroadcaster = 1,
|
|
14
|
+
/**
|
|
15
|
+
* 2: (Default) Audience. An audience member can only receive streams.
|
|
16
|
+
*/
|
|
17
|
+
ClientRoleAudience = 2,
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
/* Mode for RTC (Live or Broadcast) */
|
|
17
|
-
export enum
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
export enum ChannelProfileType {
|
|
22
|
+
/**
|
|
23
|
+
* 0: Communication. Use this profile when there are only two users in the channel.
|
|
24
|
+
*/
|
|
25
|
+
ChannelProfileCommunication = 0,
|
|
26
|
+
/**
|
|
27
|
+
* 1: Live streaming. Live streaming. Use this profile when there are more than two users in the channel.
|
|
28
|
+
*/
|
|
29
|
+
ChannelProfileLiveBroadcasting = 1,
|
|
30
|
+
/**
|
|
31
|
+
* 2: Gaming. This profile is deprecated.
|
|
32
|
+
*/
|
|
33
|
+
ChannelProfileGame = 2,
|
|
34
|
+
/**
|
|
35
|
+
* Cloud gaming. The scenario is optimized for latency. Use this profile if the use case requires frequent interactions between users.
|
|
36
|
+
*/
|
|
37
|
+
ChannelProfileCloudGaming = 3,
|
|
38
|
+
/**
|
|
39
|
+
* @ignore
|
|
40
|
+
*/
|
|
41
|
+
ChannelProfileCommunication1v1 = 4,
|
|
24
42
|
}
|
|
25
43
|
|
|
26
44
|
// disabled is intentionally kept as the 1st item in the enum.
|
|
@@ -118,11 +136,11 @@ export interface RtcPropsInterface {
|
|
|
118
136
|
dual?: boolean | null;
|
|
119
137
|
profile?: VideoProfile;
|
|
120
138
|
initialDualStreamMode?: DualStreamMode;
|
|
121
|
-
role?:
|
|
139
|
+
role?: ClientRoleType /* Set local user's role between audience and host. Use with mode set to livestreaming. (default: host) */;
|
|
122
140
|
callActive?: boolean;
|
|
123
141
|
encryption?: {
|
|
124
142
|
key: string;
|
|
125
|
-
mode: EncryptionMode.
|
|
143
|
+
mode: EncryptionMode.Aes128Gcm2 | EncryptionMode.Aes256Gcm2;
|
|
126
144
|
salt: number[];
|
|
127
145
|
};
|
|
128
146
|
// commented for v1 release
|
|
@@ -138,16 +156,17 @@ export interface RtcPropsInterface {
|
|
|
138
156
|
//core only
|
|
139
157
|
screenShareUid?: number;
|
|
140
158
|
screenShareToken?: string;
|
|
159
|
+
recordingBot?: false;
|
|
141
160
|
//core only
|
|
142
161
|
}
|
|
143
162
|
|
|
144
163
|
export interface CallbacksInterface {
|
|
145
|
-
EndCall(
|
|
164
|
+
EndCall(): void; //?
|
|
146
165
|
FullScreen(): void; //?
|
|
147
166
|
SwitchCamera(): void; //Not in reducer
|
|
148
167
|
UpdateDualStreamMode(mode: DualStreamMode): void;
|
|
149
|
-
UserJoined:
|
|
150
|
-
UserOffline:
|
|
168
|
+
UserJoined: IRtcEngineEventHandler['onUserJoined'];
|
|
169
|
+
UserOffline: IRtcEngineEventHandler['onUserOffline'];
|
|
151
170
|
SwapVideo(uid: UidType): void;
|
|
152
171
|
DequeVideo(uid: UidType): void;
|
|
153
172
|
UserMuteRemoteAudio(uid: UidType, muted: ContentInterface['audio']): void;
|
|
@@ -157,9 +176,9 @@ export interface CallbacksInterface {
|
|
|
157
176
|
LocalPermissionState(
|
|
158
177
|
permissionState: ContentInterface['permissionStatus'],
|
|
159
178
|
): void;
|
|
160
|
-
RemoteAudioStateChanged:
|
|
161
|
-
RemoteVideoStateChanged:
|
|
162
|
-
JoinChannelSuccess:
|
|
179
|
+
RemoteAudioStateChanged: IRtcEngineEventHandler['onRemoteAudioStateChanged'];
|
|
180
|
+
RemoteVideoStateChanged: IRtcEngineEventHandler['onRemoteVideoStateChanged'];
|
|
181
|
+
JoinChannelSuccess: IRtcEngineEventHandler['onJoinChannelSuccess'];
|
|
163
182
|
UpdateRenderList(uid: UidType, user: Partial<ContentInterface>): void;
|
|
164
183
|
AddCustomContent(uid: UidType, data: any): void;
|
|
165
184
|
RemoveCustomContent(uid: UidType): void;
|
|
@@ -174,7 +193,7 @@ export interface PropsInterface {
|
|
|
174
193
|
rtcProps: RtcPropsInterface;
|
|
175
194
|
styleProps?: Partial<StylePropInterface>;
|
|
176
195
|
callbacks?: Partial<CallbacksInterface>;
|
|
177
|
-
mode?:
|
|
196
|
+
mode?: ChannelProfileType;
|
|
178
197
|
}
|
|
179
198
|
|
|
180
199
|
const initialValue: Partial<PropsInterface> = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import {CallbacksInterface} from './PropsContext';
|
|
3
|
-
import
|
|
3
|
+
import {IRtcEngine} from 'react-native-agora';
|
|
4
4
|
import type {DualStreamMode, ContentInterface} from './PropsContext';
|
|
5
5
|
|
|
6
6
|
export type UidType = number;
|
|
@@ -43,7 +43,7 @@ export interface ActionInterface<T extends keyof CallbacksInterface> {
|
|
|
43
43
|
export type ActionType<T extends keyof CallbacksInterface> = ActionInterface<T>;
|
|
44
44
|
|
|
45
45
|
export interface RtcContextInterface {
|
|
46
|
-
RtcEngineUnsafe:
|
|
46
|
+
RtcEngineUnsafe: IRtcEngine;
|
|
47
47
|
setDualStreamMode: React.Dispatch<React.SetStateAction<DualStreamMode>>;
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import React, {useState, useEffect, useContext, useRef
|
|
2
|
-
import
|
|
1
|
+
import React, {useState, useEffect, useContext, useRef} from 'react';
|
|
2
|
+
import {
|
|
3
|
+
createAgoraRtcEngine,
|
|
3
4
|
VideoEncoderConfiguration,
|
|
4
5
|
AreaCode,
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
IRtcEngine,
|
|
7
|
+
AudioProfileType,
|
|
8
|
+
AudioScenarioType,
|
|
7
9
|
} from 'react-native-agora';
|
|
8
10
|
import {Platform} from 'react-native';
|
|
9
11
|
import requestCameraAndAudioPermission from '../Utils/permission';
|
|
10
12
|
import {DispatchType} from '../Contexts/DispatchContext';
|
|
11
13
|
import PropsContext, {
|
|
12
14
|
ToggleState,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
ClientRoleType,
|
|
16
|
+
ChannelProfileType,
|
|
15
17
|
PermissionState,
|
|
16
18
|
} from '../Contexts/PropsContext';
|
|
17
19
|
import quality from '../Utils/quality';
|
|
20
|
+
import {isBotUser} from '../Utils/isBotUser';
|
|
18
21
|
|
|
19
22
|
const Create = ({
|
|
20
23
|
dispatch,
|
|
@@ -22,9 +25,9 @@ const Create = ({
|
|
|
22
25
|
}: {
|
|
23
26
|
dispatch: DispatchType;
|
|
24
27
|
children: (
|
|
25
|
-
engine: React.MutableRefObject<
|
|
28
|
+
engine: React.MutableRefObject<IRtcEngine>,
|
|
26
29
|
tracksReady: boolean,
|
|
27
|
-
) =>
|
|
30
|
+
) => React.ReactElement;
|
|
28
31
|
}) => {
|
|
29
32
|
const mutexLock = useRef(false);
|
|
30
33
|
const [ready, setReady] = useState(false);
|
|
@@ -35,7 +38,7 @@ const Create = ({
|
|
|
35
38
|
audioRoom = false,
|
|
36
39
|
activeSpeaker = false,
|
|
37
40
|
} = rtcProps || {};
|
|
38
|
-
let engine = useRef<
|
|
41
|
+
let engine = useRef<IRtcEngine>({} as IRtcEngine);
|
|
39
42
|
// commented for v1 release
|
|
40
43
|
// const beforeCreate = rtcProps?.lifecycle?.useBeforeCreate
|
|
41
44
|
// ? rtcProps.lifecycle.useBeforeCreate()
|
|
@@ -188,8 +191,8 @@ const Create = ({
|
|
|
188
191
|
};
|
|
189
192
|
const enableVideoAndAudioWithInitialStates = async () => {
|
|
190
193
|
if (
|
|
191
|
-
mode
|
|
192
|
-
rtcProps?.role
|
|
194
|
+
mode === ChannelProfileType.ChannelProfileLiveBroadcasting &&
|
|
195
|
+
rtcProps?.role === ClientRoleType.ClientRoleAudience
|
|
193
196
|
) {
|
|
194
197
|
enableVideoAndAudioWithDisabledState();
|
|
195
198
|
} else {
|
|
@@ -213,36 +216,37 @@ const Create = ({
|
|
|
213
216
|
// console.error('FPE:Error on executing useBeforeCreate', error);
|
|
214
217
|
// }
|
|
215
218
|
try {
|
|
219
|
+
engine.current = createAgoraRtcEngine();
|
|
216
220
|
if (
|
|
217
221
|
geoFencing === true &&
|
|
218
222
|
(Platform.OS === 'android' || Platform.OS === 'ios')
|
|
219
223
|
) {
|
|
220
224
|
if (rtcProps?.appId) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
rtcProps?.appId,
|
|
225
|
+
engine.current.initialize({
|
|
226
|
+
appId: rtcProps.appId,
|
|
224
227
|
// eslint-disable-next-line no-bitwise
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
);
|
|
228
|
+
areaCode: AreaCode.AreaCodeGlob ^ AreaCode.AreaCodeCn,
|
|
229
|
+
});
|
|
228
230
|
}
|
|
229
231
|
} else {
|
|
230
232
|
if (rtcProps?.appId) {
|
|
231
|
-
engine.current
|
|
233
|
+
engine.current.initialize({appId: rtcProps.appId});
|
|
232
234
|
}
|
|
233
235
|
}
|
|
234
236
|
/* Live Streaming */
|
|
235
|
-
if (mode
|
|
237
|
+
if (mode === ChannelProfileType.ChannelProfileLiveBroadcasting) {
|
|
236
238
|
await engine.current.setChannelProfile(
|
|
237
|
-
|
|
239
|
+
ChannelProfileType.ChannelProfileLiveBroadcasting,
|
|
238
240
|
);
|
|
239
241
|
await engine.current.setClientRole(
|
|
240
|
-
rtcProps
|
|
241
|
-
?
|
|
242
|
-
:
|
|
242
|
+
rtcProps?.role === ClientRoleType.ClientRoleAudience
|
|
243
|
+
? ClientRoleType.ClientRoleAudience
|
|
244
|
+
: ClientRoleType.ClientRoleBroadcaster,
|
|
243
245
|
);
|
|
244
246
|
} else {
|
|
245
|
-
await engine.current.setChannelProfile(
|
|
247
|
+
await engine.current.setChannelProfile(
|
|
248
|
+
ChannelProfileType.ChannelProfileCommunication,
|
|
249
|
+
);
|
|
246
250
|
}
|
|
247
251
|
if (activeSpeaker) {
|
|
248
252
|
await engine.current.enableAudioVolumeIndication(100, 3, true);
|
|
@@ -271,14 +275,14 @@ const Create = ({
|
|
|
271
275
|
if (Platform.OS === 'android' || Platform.OS === 'ios') {
|
|
272
276
|
//@ts-ignore
|
|
273
277
|
await engine.current.setAudioProfile(
|
|
274
|
-
|
|
275
|
-
|
|
278
|
+
AudioProfileType.AudioProfileDefault,
|
|
279
|
+
AudioScenarioType.AudioScenarioDefault,
|
|
276
280
|
);
|
|
277
281
|
//also audio route for voice-chat will work through earpiece not phonespeaker
|
|
278
282
|
//for audiolivecast it will work through phone speaker
|
|
279
283
|
//ref - https://docs.agora.io/en/help/integration-issues/profile_difference/#audio-route
|
|
280
284
|
//so setting into phone speaker manually as requested
|
|
281
|
-
if (mode
|
|
285
|
+
if (mode === ChannelProfileType.ChannelProfileCommunication) {
|
|
282
286
|
//@ts-ignore
|
|
283
287
|
await engine.current.setEnableSpeakerphone(true);
|
|
284
288
|
}
|
|
@@ -295,20 +299,27 @@ const Create = ({
|
|
|
295
299
|
*/
|
|
296
300
|
if (
|
|
297
301
|
!(
|
|
298
|
-
mode ===
|
|
299
|
-
rtcProps
|
|
300
|
-
Platform.OS === 'web'
|
|
302
|
+
mode === ChannelProfileType.ChannelProfileLiveBroadcasting &&
|
|
303
|
+
rtcProps?.role === ClientRoleType.ClientRoleAudience &&
|
|
304
|
+
Platform.OS === 'web' &&
|
|
305
|
+
rtcProps?.recordingBot
|
|
301
306
|
)
|
|
302
307
|
) {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
308
|
+
if (rtcProps?.recordingBot) {
|
|
309
|
+
console.log(
|
|
310
|
+
'recording-bot, hence not asking audio/video permission',
|
|
311
|
+
);
|
|
312
|
+
} else {
|
|
313
|
+
enableVideoAndAudioWithInitialStates().then(() => {
|
|
314
|
+
setTracksReady(true);
|
|
315
|
+
isVideoEnabledRef.current = true;
|
|
316
|
+
});
|
|
317
|
+
}
|
|
307
318
|
}
|
|
308
319
|
|
|
309
320
|
engine.current.addListener(
|
|
310
|
-
'
|
|
311
|
-
async (
|
|
321
|
+
'onJoinChannelSuccess',
|
|
322
|
+
async (connection, elapsed) => {
|
|
312
323
|
//Invoke the callback
|
|
313
324
|
console.log('UIkit enabling dual stream', rtcProps?.dual);
|
|
314
325
|
if (rtcProps?.dual) {
|
|
@@ -317,50 +328,55 @@ const Create = ({
|
|
|
317
328
|
// await engine.current.setRemoteSubscribeFallbackOption(1);
|
|
318
329
|
}
|
|
319
330
|
callbacks?.JoinChannelSuccess &&
|
|
320
|
-
callbacks.JoinChannelSuccess(
|
|
331
|
+
callbacks.JoinChannelSuccess(connection, elapsed);
|
|
321
332
|
},
|
|
322
333
|
);
|
|
323
334
|
|
|
324
|
-
engine.current.addListener('
|
|
325
|
-
//
|
|
335
|
+
engine.current.addListener('onUserJoined', async (...args) => {
|
|
336
|
+
// exluding the connection obj being passed by native sdk
|
|
337
|
+
const [, ...remainingArgs] = args;
|
|
326
338
|
//@ts-ignore
|
|
327
|
-
|
|
339
|
+
// preventing bots(ex: STT, recording) in renderlist
|
|
340
|
+
if (isBotUser(remainingArgs)) {
|
|
328
341
|
return;
|
|
329
342
|
}
|
|
330
343
|
//Get current peer IDs
|
|
331
344
|
dispatch({
|
|
332
345
|
type: 'UserJoined',
|
|
333
346
|
//@ts-ignore
|
|
334
|
-
value:
|
|
347
|
+
value: remainingArgs,
|
|
335
348
|
});
|
|
336
349
|
});
|
|
337
350
|
|
|
338
|
-
engine.current.addListener('
|
|
351
|
+
engine.current.addListener('onUserOffline', (...args) => {
|
|
352
|
+
const [, ...remainingArgs] = args;
|
|
339
353
|
//If user leaves
|
|
340
354
|
dispatch({
|
|
341
355
|
type: 'UserOffline',
|
|
342
356
|
//@ts-ignore
|
|
343
|
-
value:
|
|
357
|
+
value: remainingArgs,
|
|
344
358
|
});
|
|
345
359
|
});
|
|
346
360
|
|
|
347
|
-
engine.current.addListener('
|
|
361
|
+
engine.current.addListener('onRemoteAudioStateChanged', (...args) => {
|
|
362
|
+
const [, ...remainingArgs] = args;
|
|
348
363
|
dispatch({
|
|
349
364
|
type: 'RemoteAudioStateChanged',
|
|
350
365
|
//@ts-ignore
|
|
351
|
-
value:
|
|
366
|
+
value: remainingArgs,
|
|
352
367
|
});
|
|
353
368
|
});
|
|
354
369
|
|
|
355
|
-
engine.current.addListener('
|
|
370
|
+
engine.current.addListener('onError', (e) => {
|
|
356
371
|
console.log('Error: ', e);
|
|
357
372
|
});
|
|
358
373
|
|
|
359
|
-
engine.current.addListener('
|
|
374
|
+
engine.current.addListener('onRemoteVideoStateChanged', (...args) => {
|
|
375
|
+
const [, ...remainingArgs] = args;
|
|
360
376
|
dispatch({
|
|
361
377
|
type: 'RemoteVideoStateChanged',
|
|
362
378
|
//@ts-ignore
|
|
363
|
-
value:
|
|
379
|
+
value: remainingArgs,
|
|
364
380
|
});
|
|
365
381
|
});
|
|
366
382
|
|
|
@@ -374,25 +390,39 @@ const Create = ({
|
|
|
374
390
|
init();
|
|
375
391
|
}
|
|
376
392
|
return () => {
|
|
393
|
+
if (Platform.OS !== 'web') {
|
|
394
|
+
// for web, events are cleared in release method
|
|
395
|
+
engine.current.removeAllListeners('onJoinChannelSuccess');
|
|
396
|
+
engine.current.removeAllListeners('onLeaveChannel');
|
|
397
|
+
engine.current.removeAllListeners('onUserJoined');
|
|
398
|
+
engine.current.removeAllListeners('onUserOffline');
|
|
399
|
+
engine.current.removeAllListeners('onRemoteVideoStateChanged');
|
|
400
|
+
engine.current.removeAllListeners('onRemoteAudioStateChanged');
|
|
401
|
+
engine.current.removeAllListeners('onError');
|
|
402
|
+
}
|
|
403
|
+
|
|
377
404
|
/**
|
|
378
405
|
* if condition add for websdk issue
|
|
379
406
|
* For some reason even if engine.current is defined somehow destroy gets undefined and
|
|
380
407
|
* causes a crash so thats why this check is needed before we call the method
|
|
381
408
|
*/
|
|
382
|
-
if (
|
|
383
|
-
engine.current
|
|
409
|
+
if (tracksReady || Platform.OS === 'web') {
|
|
410
|
+
engine.current.release();
|
|
384
411
|
}
|
|
385
412
|
};
|
|
386
|
-
|
|
413
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
414
|
+
}, [rtcProps?.appId, rtcProps?.uid]);
|
|
387
415
|
|
|
388
416
|
useEffect(() => {
|
|
389
417
|
const toggleRole = async () => {
|
|
390
418
|
if (
|
|
391
|
-
mode
|
|
419
|
+
mode === ChannelProfileType.ChannelProfileLiveBroadcasting &&
|
|
392
420
|
engine.current.setClientRole // Check if engine initialized
|
|
393
421
|
) {
|
|
394
|
-
if (rtcProps
|
|
395
|
-
await engine.current?.setClientRole(
|
|
422
|
+
if (rtcProps?.role === ClientRoleType.ClientRoleBroadcaster) {
|
|
423
|
+
await engine.current?.setClientRole(
|
|
424
|
+
ClientRoleType.ClientRoleBroadcaster,
|
|
425
|
+
);
|
|
396
426
|
// isVideoEnabledRef checks if the permission is already taken once
|
|
397
427
|
if (!isVideoEnabledRef.current) {
|
|
398
428
|
await enableVideoAndAudioWithDisabledState();
|
|
@@ -417,7 +447,7 @@ const Create = ({
|
|
|
417
447
|
}
|
|
418
448
|
}
|
|
419
449
|
}
|
|
420
|
-
if (rtcProps
|
|
450
|
+
if (rtcProps?.role === ClientRoleType.ClientRoleAudience) {
|
|
421
451
|
/**
|
|
422
452
|
* To switch the user role back to "audience", call unpublish first
|
|
423
453
|
* Otherwise the setClientRole method call fails and throws an exception.
|
|
@@ -436,7 +466,9 @@ const Create = ({
|
|
|
436
466
|
value: [ToggleState.disabled],
|
|
437
467
|
});
|
|
438
468
|
}
|
|
439
|
-
await engine.current?.setClientRole(
|
|
469
|
+
await engine.current?.setClientRole(
|
|
470
|
+
ClientRoleType.ClientRoleAudience,
|
|
471
|
+
);
|
|
440
472
|
}
|
|
441
473
|
}
|
|
442
474
|
};
|
|
@@ -446,7 +478,8 @@ const Create = ({
|
|
|
446
478
|
return;
|
|
447
479
|
}
|
|
448
480
|
toggleRole();
|
|
449
|
-
|
|
481
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
482
|
+
}, [rtcProps?.role]);
|
|
450
483
|
|
|
451
484
|
return (
|
|
452
485
|
<>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, {useEffect, useContext, useRef} from 'react';
|
|
2
|
-
import
|
|
2
|
+
import {IRtcEngine} from 'react-native-agora';
|
|
3
3
|
import {ContentStateInterface} from '../Contexts/RtcContext';
|
|
4
4
|
import {DispatchType} from '../Contexts/DispatchContext';
|
|
5
5
|
import PropsContext, {ToggleState} from '../Contexts/PropsContext';
|
|
@@ -8,7 +8,7 @@ import {Platform} from 'react-native';
|
|
|
8
8
|
const Join: React.FC<{
|
|
9
9
|
children: React.ReactNode;
|
|
10
10
|
precall: boolean;
|
|
11
|
-
engineRef: React.MutableRefObject<
|
|
11
|
+
engineRef: React.MutableRefObject<IRtcEngine>;
|
|
12
12
|
uidState: ContentStateInterface;
|
|
13
13
|
dispatch: DispatchType;
|
|
14
14
|
tracksReady: boolean;
|
|
@@ -16,7 +16,8 @@ const Join: React.FC<{
|
|
|
16
16
|
}> = ({children, precall, engineRef, uidState, dispatch, tracksReady}) => {
|
|
17
17
|
let joinState = useRef(false);
|
|
18
18
|
const {rtcProps} = useContext(PropsContext);
|
|
19
|
-
|
|
19
|
+
|
|
20
|
+
const audioRoom = rtcProps?.audioRoom || false;
|
|
20
21
|
//commented for v1 release
|
|
21
22
|
// const beforeJoin = rtcProps?.lifecycle?.useBeforeJoin
|
|
22
23
|
// ? rtcProps.lifecycle.useBeforeJoin()
|
|
@@ -27,12 +28,14 @@ const Join: React.FC<{
|
|
|
27
28
|
//@ts-ignore
|
|
28
29
|
engineRef.current.publish();
|
|
29
30
|
}
|
|
31
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
30
32
|
}, [tracksReady]);
|
|
31
33
|
|
|
32
34
|
useEffect(() => {
|
|
33
35
|
if (rtcProps?.preventJoin) {
|
|
34
36
|
return;
|
|
35
37
|
}
|
|
38
|
+
|
|
36
39
|
const engine = engineRef.current;
|
|
37
40
|
async function leave() {
|
|
38
41
|
try {
|
|
@@ -45,20 +48,20 @@ const Join: React.FC<{
|
|
|
45
48
|
}
|
|
46
49
|
const {defaultContent, activeUids} = uidState;
|
|
47
50
|
const [maxUid] = activeUids;
|
|
48
|
-
const videoState = defaultContent[maxUid]
|
|
51
|
+
const videoState = defaultContent[maxUid]?.video;
|
|
49
52
|
async function join() {
|
|
50
53
|
if (
|
|
51
54
|
rtcProps?.encryption &&
|
|
52
|
-
rtcProps
|
|
55
|
+
rtcProps?.encryption.key &&
|
|
53
56
|
rtcProps.encryption.mode &&
|
|
54
57
|
rtcProps.encryption.salt
|
|
55
58
|
) {
|
|
56
|
-
console.log('using channel encryption', rtcProps?.encryption);
|
|
57
59
|
try {
|
|
58
60
|
await engine.enableEncryption(true, {
|
|
59
61
|
encryptionKey: rtcProps?.encryption.key,
|
|
60
62
|
encryptionMode: rtcProps?.encryption.mode,
|
|
61
63
|
encryptionKdfSalt: rtcProps?.encryption.salt,
|
|
64
|
+
datastreamEncryptionEnabled: true,
|
|
62
65
|
});
|
|
63
66
|
} catch (error) {
|
|
64
67
|
console.warn('encryption error', error);
|
|
@@ -89,10 +92,10 @@ const Join: React.FC<{
|
|
|
89
92
|
// }
|
|
90
93
|
try {
|
|
91
94
|
await engine.joinChannel(
|
|
92
|
-
rtcProps
|
|
93
|
-
rtcProps
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
rtcProps?.token || '',
|
|
96
|
+
rtcProps?.channel || '',
|
|
97
|
+
rtcProps?.uid || 0,
|
|
98
|
+
{},
|
|
96
99
|
);
|
|
97
100
|
} catch (error) {
|
|
98
101
|
console.error('RTC joinChannel error', error);
|
|
@@ -122,7 +125,7 @@ const Join: React.FC<{
|
|
|
122
125
|
await leave();
|
|
123
126
|
await join();
|
|
124
127
|
}
|
|
125
|
-
console.log('Attempted join: ', rtcProps
|
|
128
|
+
console.log('Attempted join: ', rtcProps?.channel);
|
|
126
129
|
} else {
|
|
127
130
|
console.log('In precall - waiting to join');
|
|
128
131
|
}
|
|
@@ -133,13 +136,14 @@ const Join: React.FC<{
|
|
|
133
136
|
leave();
|
|
134
137
|
}
|
|
135
138
|
};
|
|
139
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
136
140
|
}, [
|
|
137
|
-
rtcProps
|
|
138
|
-
rtcProps
|
|
139
|
-
rtcProps
|
|
141
|
+
rtcProps?.channel,
|
|
142
|
+
rtcProps?.uid,
|
|
143
|
+
rtcProps?.token,
|
|
140
144
|
precall,
|
|
141
|
-
rtcProps
|
|
142
|
-
rtcProps
|
|
145
|
+
rtcProps?.encryption,
|
|
146
|
+
rtcProps?.preventJoin,
|
|
143
147
|
]);
|
|
144
148
|
|
|
145
149
|
return <>{children}</>;
|