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.
Files changed (97) hide show
  1. package/package.json +3 -3
  2. package/template/_package-lock.json +5911 -4861
  3. package/template/agora-rn-uikit/.eslintrc.js +5 -0
  4. package/template/agora-rn-uikit/package.json +14 -14
  5. package/template/agora-rn-uikit/src/Contexts/PropsContext.tsx +41 -22
  6. package/template/agora-rn-uikit/src/Contexts/RtcContext.tsx +2 -2
  7. package/template/agora-rn-uikit/src/Rtc/Create.tsx +90 -57
  8. package/template/agora-rn-uikit/src/Rtc/Join.tsx +20 -16
  9. package/template/agora-rn-uikit/src/RtcConfigure.tsx +10 -10
  10. package/template/agora-rn-uikit/src/Utils/isBotUser.ts +15 -0
  11. package/template/agora-rn-uikit/src/Utils/quality.tsx +8 -0
  12. package/template/agora-rn-uikit/src/Views/MaxVideoView.native.tsx +32 -16
  13. package/template/agora-rn-uikit/src/Views/MaxVideoView.tsx +25 -14
  14. package/template/agora-rn-uikit/src/Views/MinVideoView.tsx +15 -9
  15. package/template/agora-rn-uikit/src/index.ts +1 -1
  16. package/template/bridge/rtc/webNg/RtcEngine.ts +73 -58
  17. package/template/bridge/rtc/webNg/{SurfaceView.tsx → RtcSurfaceView.tsx} +20 -26
  18. package/template/bridge/rtc/webNg/Types.ts +20 -5
  19. package/template/bridge/rtc/webNg/index.ts +9 -13
  20. package/template/customization-api/temp.ts +2 -2
  21. package/template/customization-api/typeDefinition.ts +1 -2
  22. package/template/customization-api/utils.ts +1 -2
  23. package/template/index.js +1 -0
  24. package/template/ios/HelloWorld/HelloWorldDebug.entitlements +10 -0
  25. package/template/ios/HelloWorld.xcodeproj/project.pbxproj +4 -0
  26. package/template/ios/Podfile +1 -1
  27. package/template/ios/Podfile.lock +72 -140
  28. package/template/package.json +5 -4
  29. package/template/src/App.tsx +58 -1
  30. package/template/src/AppRoutes.tsx +16 -3
  31. package/template/src/AppWrapper.tsx +21 -19
  32. package/template/src/components/Chat.tsx +17 -8
  33. package/template/src/components/ChatContext.ts +0 -2
  34. package/template/src/components/Controls.tsx +5 -5
  35. package/template/src/components/Controls1.native.tsx +7 -3
  36. package/template/src/components/DeviceConfigure.native.tsx +2 -2
  37. package/template/src/components/DeviceConfigure.tsx +2 -2
  38. package/template/src/components/EventsConfigure.tsx +13 -22
  39. package/template/src/components/GraphQLProvider.tsx +47 -30
  40. package/template/src/components/GridVideo.tsx +6 -2
  41. package/template/src/components/NetworkQualityContext.tsx +11 -5
  42. package/template/src/components/ParticipantsView.tsx +3 -3
  43. package/template/src/components/PinnedVideo.tsx +2 -2
  44. package/template/src/components/Precall.native.tsx +9 -6
  45. package/template/src/components/Precall.tsx +9 -6
  46. package/template/src/components/StorageContext.tsx +5 -2
  47. package/template/src/components/ToastComponent.tsx +7 -1
  48. package/template/src/components/contexts/LiveStreamDataContext.tsx +3 -3
  49. package/template/src/components/livestream/LiveStreamContext.tsx +42 -33
  50. package/template/src/components/livestream/Types.ts +2 -2
  51. package/template/src/components/participants/Participant.tsx +1 -1
  52. package/template/src/components/participants/UserActionMenuOptions.tsx +7 -2
  53. package/template/src/components/recording-bot/RecordingBotRoute.tsx +42 -0
  54. package/template/src/components/virtual-background/useVB.native.tsx +16 -19
  55. package/template/src/components/virtual-background/useVB.tsx +1 -1
  56. package/template/src/components/whiteboard/WhiteboardConfigure.native.tsx +11 -0
  57. package/template/src/components/whiteboard/WhiteboardConfigure.tsx +5 -0
  58. package/template/src/components/whiteboard/WhiteboardView.native.tsx +91 -12
  59. package/template/src/components/whiteboard/WhiteboardWidget.tsx +15 -4
  60. package/template/src/language/default-labels/precallScreenLabels.ts +5 -3
  61. package/template/src/language/default-labels/videoCallScreenLabels.ts +93 -41
  62. package/template/src/pages/VideoCall.tsx +39 -37
  63. package/template/src/pages/video-call/ActionSheetContent.tsx +4 -3
  64. package/template/src/pages/video-call/NameWithMicIcon.tsx +2 -1
  65. package/template/src/pages/video-call/VideoCallMobileView.tsx +26 -2
  66. package/template/src/pages/video-call/VideoCallScreen.tsx +32 -12
  67. package/template/src/pages/video-call/VideoCallScreenWrapper.tsx +41 -0
  68. package/template/src/pages/video-call/VideoComponent.tsx +5 -2
  69. package/template/src/pages/video-call/VideoRenderer.tsx +55 -34
  70. package/template/src/rtm-events/constants.ts +0 -2
  71. package/template/src/subComponents/ChatBubble.tsx +2 -0
  72. package/template/src/subComponents/LocalAudioMute.tsx +8 -47
  73. package/template/src/subComponents/LocalEndCall.tsx +5 -52
  74. package/template/src/subComponents/LocalSwitchCamera.tsx +3 -3
  75. package/template/src/subComponents/LocalVideoMute.tsx +8 -50
  76. package/template/src/subComponents/SelectDevice.tsx +5 -2
  77. package/template/src/subComponents/SelectDeviceSettings.backup.tsx +9 -6
  78. package/template/src/subComponents/caption/Caption.tsx +12 -10
  79. package/template/src/subComponents/caption/Transcript.tsx +13 -10
  80. package/template/src/subComponents/caption/useTranscriptDownload.native.ts +11 -16
  81. package/template/src/subComponents/caption/utils.ts +1 -0
  82. package/template/src/subComponents/livestream/ApprovedLiveStreamControlsView.tsx +2 -2
  83. package/template/src/subComponents/livestream/CurrentLiveStreamRequestsView.tsx +3 -2
  84. package/template/src/subComponents/livestream/controls/LocalRaiseHand.tsx +1 -1
  85. package/template/src/subComponents/recording/useIsRecordingBot.tsx +38 -0
  86. package/template/src/subComponents/recording/useRecording.tsx +176 -135
  87. package/template/src/subComponents/screenshare/ScreenshareButton.tsx +3 -3
  88. package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +1 -22
  89. package/template/src/utils/index.tsx +16 -5
  90. package/template/src/utils/useEndCall.ts +65 -0
  91. package/template/src/utils/useIsLocalUserSpeaking.ts +6 -1
  92. package/template/{bridge/rtc/webNg/LocalView.tsx → src/utils/useLocalAudio.ts} +24 -6
  93. package/template/src/utils/useMuteToggleLocal.ts +10 -5
  94. package/template/src/utils/useSearchParams.tsx +18 -0
  95. package/template/src/wasms/agora-virtual-background.wasm +0 -0
  96. package/template/src/utils/endCallEveryOne.ts +0 -7
  97. package/template/src/utils/useDisableButton.tsx +0 -37
@@ -3,4 +3,9 @@ module.exports = {
3
3
  extends: '@react-native-community',
4
4
  parser: '@typescript-eslint/parser',
5
5
  plugins: ['@typescript-eslint'],
6
+ "rules": {
7
+ "no-shadow": "off",
8
+ "@typescript-eslint/no-shadow": ["error"]
9
+ },
10
+
6
11
  };
@@ -22,24 +22,24 @@
22
22
  "url": "https://github.com/AgoraIO-Community/ReactNative-UIKit/issues"
23
23
  },
24
24
  "peerDependencies": {
25
- "react": "^16.9.0",
26
- "react-native": "^0.61.5",
27
- "react-native-agora": "^3.0.1-rc.4"
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.6.2",
31
- "@babel/runtime": "^7.6.2",
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": "^0.62.0",
35
- "@types/react-test-renderer": "16.9.2",
36
- "@typescript-eslint/eslint-plugin": "^2.27.0",
37
- "@typescript-eslint/parser": "^2.27.0",
38
- "babel-jest": "^24.9.0",
39
- "eslint": "^6.5.1",
40
- "jest": "^24.9.0",
41
- "metro-react-native-babel-preset": "^0.58.0",
42
- "react-test-renderer": "16.11.0",
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 {RtcEngineEvents} from 'react-native-agora/lib/typescript/common/RtcEvents';
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 ClientRole {
10
- /* 1: A host can both send and receive streams. */
11
- Broadcaster = 1,
12
- /* 2: The default role. An audience can only receive streams. */
13
- Audience = 2,
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 ChannelProfile {
18
- /** 0: (Default) The Communication profile.
19
- * Use this profile in one-on-one calls or group calls, where all users can talk freely. */
20
- Communication = 0,
21
- /** 1: The Live-Broadcast profile.
22
- * Users in a live-broadcast channel have a role as either host or audience. A host can both send and receive streams; an audience can only receive streams. */
23
- LiveBroadcasting = 1,
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?: ClientRole /* Set local user's role between audience and host. Use with mode set to livestreaming. (default: host) */;
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.AES128GCM2 | EncryptionMode.AES128GCM2;
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(isHost: boolean, isTriggeredByHost: boolean): void; //?
164
+ EndCall(): void; //?
146
165
  FullScreen(): void; //?
147
166
  SwitchCamera(): void; //Not in reducer
148
167
  UpdateDualStreamMode(mode: DualStreamMode): void;
149
- UserJoined: RtcEngineEvents['UserJoined'];
150
- UserOffline: RtcEngineEvents['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: RtcEngineEvents['RemoteAudioStateChanged'];
161
- RemoteVideoStateChanged: RtcEngineEvents['RemoteVideoStateChanged'];
162
- JoinChannelSuccess: RtcEngineEvents['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?: ChannelProfile;
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 RtcEngine from 'react-native-agora';
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: RtcEngine;
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, FC} from 'react';
2
- import RtcEngine, {
1
+ import React, {useState, useEffect, useContext, useRef} from 'react';
2
+ import {
3
+ createAgoraRtcEngine,
3
4
  VideoEncoderConfiguration,
4
5
  AreaCode,
5
- AudioProfile,
6
- AudioScenario,
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
- ClientRole,
14
- ChannelProfile,
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<RtcEngine>,
28
+ engine: React.MutableRefObject<IRtcEngine>,
26
29
  tracksReady: boolean,
27
- ) => JSX.Element;
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<RtcEngine>({} as RtcEngine);
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 == ChannelProfile.LiveBroadcasting &&
192
- rtcProps?.role == ClientRole.Audience
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
- //@ts-ignore
222
- engine.current = await RtcEngine.createWithAreaCode(
223
- rtcProps?.appId,
225
+ engine.current.initialize({
226
+ appId: rtcProps.appId,
224
227
  // eslint-disable-next-line no-bitwise
225
- //@ts-ignore
226
- AreaCode.GLOB ^ AreaCode.CN,
227
- );
228
+ areaCode: AreaCode.AreaCodeGlob ^ AreaCode.AreaCodeCn,
229
+ });
228
230
  }
229
231
  } else {
230
232
  if (rtcProps?.appId) {
231
- engine.current = await RtcEngine.create(rtcProps.appId);
233
+ engine.current.initialize({appId: rtcProps.appId});
232
234
  }
233
235
  }
234
236
  /* Live Streaming */
235
- if (mode == ChannelProfile.LiveBroadcasting) {
237
+ if (mode === ChannelProfileType.ChannelProfileLiveBroadcasting) {
236
238
  await engine.current.setChannelProfile(
237
- ChannelProfile.LiveBroadcasting,
239
+ ChannelProfileType.ChannelProfileLiveBroadcasting,
238
240
  );
239
241
  await engine.current.setClientRole(
240
- rtcProps.role === ClientRole.Audience
241
- ? ClientRole.Audience
242
- : ClientRole.Broadcaster,
242
+ rtcProps?.role === ClientRoleType.ClientRoleAudience
243
+ ? ClientRoleType.ClientRoleAudience
244
+ : ClientRoleType.ClientRoleBroadcaster,
243
245
  );
244
246
  } else {
245
- await engine.current.setChannelProfile(ChannelProfile.Communication);
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
- AudioProfile.Default,
275
- AudioScenario.Default,
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 == ChannelProfile.Communication) {
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 === ChannelProfile.LiveBroadcasting &&
299
- rtcProps.role == ClientRole.Audience &&
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
- enableVideoAndAudioWithInitialStates().then(() => {
304
- setTracksReady(true);
305
- isVideoEnabledRef.current = true;
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
- 'JoinChannelSuccess',
311
- async (channel, uid, elapsed) => {
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(channel, uid, elapsed);
331
+ callbacks.JoinChannelSuccess(connection, elapsed);
321
332
  },
322
333
  );
323
334
 
324
- engine.current.addListener('UserJoined', async (...args) => {
325
- // preventing STT pusher bot in renderlist
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
- if (args[0] === 111111) {
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: args,
347
+ value: remainingArgs,
335
348
  });
336
349
  });
337
350
 
338
- engine.current.addListener('UserOffline', (...args) => {
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: args,
357
+ value: remainingArgs,
344
358
  });
345
359
  });
346
360
 
347
- engine.current.addListener('RemoteAudioStateChanged', (...args) => {
361
+ engine.current.addListener('onRemoteAudioStateChanged', (...args) => {
362
+ const [, ...remainingArgs] = args;
348
363
  dispatch({
349
364
  type: 'RemoteAudioStateChanged',
350
365
  //@ts-ignore
351
- value: args,
366
+ value: remainingArgs,
352
367
  });
353
368
  });
354
369
 
355
- engine.current.addListener('Error', (e) => {
370
+ engine.current.addListener('onError', (e) => {
356
371
  console.log('Error: ', e);
357
372
  });
358
373
 
359
- engine.current.addListener('RemoteVideoStateChanged', (...args) => {
374
+ engine.current.addListener('onRemoteVideoStateChanged', (...args) => {
375
+ const [, ...remainingArgs] = args;
360
376
  dispatch({
361
377
  type: 'RemoteVideoStateChanged',
362
378
  //@ts-ignore
363
- value: args,
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 (engine.current.destroy) {
383
- engine.current!.destroy();
409
+ if (tracksReady || Platform.OS === 'web') {
410
+ engine.current.release();
384
411
  }
385
412
  };
386
- }, [rtcProps.appId, rtcProps.uid]);
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 == ChannelProfile.LiveBroadcasting &&
419
+ mode === ChannelProfileType.ChannelProfileLiveBroadcasting &&
392
420
  engine.current.setClientRole // Check if engine initialized
393
421
  ) {
394
- if (rtcProps.role == ClientRole.Broadcaster) {
395
- await engine.current?.setClientRole(ClientRole.Broadcaster);
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.role == ClientRole.Audience) {
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(ClientRole.Audience);
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
- }, [rtcProps.role]);
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 RtcEngine from 'react-native-agora';
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<RtcEngine>;
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
- const {audioRoom = false} = rtcProps;
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].video;
51
+ const videoState = defaultContent[maxUid]?.video;
49
52
  async function join() {
50
53
  if (
51
54
  rtcProps?.encryption &&
52
- rtcProps.encryption.key &&
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.token || null,
93
- rtcProps.channel,
94
- null,
95
- rtcProps.uid || 0,
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.channel);
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.channel,
138
- rtcProps.uid,
139
- rtcProps.token,
141
+ rtcProps?.channel,
142
+ rtcProps?.uid,
143
+ rtcProps?.token,
140
144
  precall,
141
- rtcProps.encryption,
142
- rtcProps.preventJoin,
145
+ rtcProps?.encryption,
146
+ rtcProps?.preventJoin,
143
147
  ]);
144
148
 
145
149
  return <>{children}</>;