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
@@ -9,7 +9,7 @@
9
9
  information visit https://appbuilder.agora.io.
10
10
  *********************************************
11
11
  */
12
- import React, {useState, useContext} from 'react';
12
+ import React, {useState, useLayoutEffect} from 'react';
13
13
  import {Platform} from 'react-native';
14
14
  import KeyboardManager from 'react-native-keyboard-manager';
15
15
  import AppWrapper from './AppWrapper';
@@ -21,6 +21,7 @@ import {
21
21
  import {SetRoomInfoProvider} from './components/room-info/useSetRoomInfo';
22
22
  import {ShareLinkProvider} from './components/useShareLink';
23
23
  import AppRoutes from './AppRoutes';
24
+ import {isWebInternal} from './utils/common';
24
25
 
25
26
  // hook can't be used in the outside react function calls. so directly checking the platform.
26
27
  if (Platform.OS === 'ios') {
@@ -44,8 +45,64 @@ declare module 'agora-rn-uikit' {
44
45
  // }
45
46
  }
46
47
 
48
+ declare global {
49
+ interface Navigator {
50
+ notifyReady?: () => boolean;
51
+ }
52
+ }
53
+
47
54
  const App: React.FC = () => {
48
55
  //commented for v1 release
56
+ //const CustomRoutes = useCustomization((data) => data?.customRoutes);
57
+ // const RenderCustomRoutes = () => {
58
+ // try {
59
+ // return (
60
+ // CustomRoutes &&
61
+ // Array.isArray(CustomRoutes) &&
62
+ // CustomRoutes.length &&
63
+ // CustomRoutes?.map((item: CustomRoutesInterface, i: number) => {
64
+ // let RouteComponent = item?.isPrivateRoute ? PrivateRoute : Route;
65
+ // return (
66
+ // <RouteComponent
67
+ // path={CUSTOM_ROUTES_PREFIX + item.path}
68
+ // exact={item.exact}
69
+ // key={i}
70
+ // failureRedirectTo={
71
+ // item.failureRedirectTo ? item.failureRedirectTo : '/'
72
+ // }
73
+ // {...item.routeProps}>
74
+ // <item.component {...item.componentProps} />
75
+ // </RouteComponent>
76
+ // );
77
+ // })
78
+ // );
79
+ // } catch (error) {
80
+ // console.error('Error on rendering the custom routes');
81
+ // return null;
82
+ // }
83
+ // };
84
+
85
+ const notifyReady = () => {
86
+ if (typeof window.navigator.notifyReady === 'function') {
87
+ console.log('recording-bot: notifyReady is available');
88
+ window.navigator.notifyReady();
89
+ } else {
90
+ console.log('recording-bot: notifyReady is un-available');
91
+ }
92
+ };
93
+
94
+ useLayoutEffect(() => {
95
+ if (isWebInternal()) {
96
+ // Register only on web
97
+ window.addEventListener('load', notifyReady);
98
+ }
99
+ return () => {
100
+ if (isWebInternal()) {
101
+ window.removeEventListener('load', notifyReady);
102
+ }
103
+ };
104
+ }, []);
105
+
49
106
  const [roomInfo, setRoomInfo] =
50
107
  useState<RoomInfoContextInterface>(RoomInfoDefaultValue);
51
108
 
@@ -20,6 +20,21 @@ import {Text} from 'react-native';
20
20
  import {useCustomization} from 'customization-implementation';
21
21
  import {CUSTOM_ROUTES_PREFIX, CustomRoutesInterface} from 'customization-api';
22
22
  import PrivateRoute from './components/PrivateRoute';
23
+ import RecordingBotRoute from './components/recording-bot/RecordingBotRoute';
24
+ import {useIsRecordingBot} from './subComponents/recording/useIsRecordingBot';
25
+
26
+ function VideoCallWrapper(props) {
27
+ const {isRecordingBotRoute} = useIsRecordingBot();
28
+ return isRecordingBotRoute ? (
29
+ <RecordingBotRoute history={props.history}>
30
+ <VideoCall />
31
+ </RecordingBotRoute>
32
+ ) : (
33
+ <AuthRoute>
34
+ <VideoCall />
35
+ </AuthRoute>
36
+ );
37
+ }
23
38
 
24
39
  function AppRoutes() {
25
40
  const CustomRoutes = useCustomization(data => data?.customRoutes);
@@ -65,9 +80,7 @@ function AppRoutes() {
65
80
  <Create />
66
81
  </AuthRoute>
67
82
  {RenderCustomRoutes()}
68
- <AuthRoute path={'/:phrase'}>
69
- <VideoCall />
70
- </AuthRoute>
83
+ <Route exact path={'/:phrase'} component={VideoCallWrapper} />
71
84
  <Route path="*">
72
85
  <Text>Page not found</Text>
73
86
  </Route>
@@ -87,22 +87,24 @@ const AppWrapper = (props: AppWrapperProps) => {
87
87
  <StatusBar hidden={true} />
88
88
  <StorageProvider>
89
89
  <LanguageProvider>
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
- ]}>
90
+ <GraphQLProvider>
91
+ <Router
92
+ /*@ts-ignore Router will be memory Router in sdk*/
93
+ initialEntries={[
94
+ //@ts-ignore
95
+ isSDK && SdkJoinState.phrase
96
+ ? //@ts-ignore
97
+ `/${SdkJoinState.phrase}`
98
+ : '',
99
+ ]}>
100
+ <ToastProvider>
101
+ <ToastContext.Consumer>
102
+ {({isActionSheetVisible}) => {
103
+ return !isActionSheetVisible ? (
104
+ <ToastComponent />
105
+ ) : null;
106
+ }}
107
+ </ToastContext.Consumer>
106
108
  <AuthProvider>
107
109
  <SessionProvider>
108
110
  <ColorConfigure>
@@ -116,9 +118,9 @@ const AppWrapper = (props: AppWrapperProps) => {
116
118
  </ColorConfigure>
117
119
  </SessionProvider>
118
120
  </AuthProvider>
119
- </Router>
120
- </GraphQLProvider>
121
- </ToastProvider>
121
+ </ToastProvider>
122
+ </Router>
123
+ </GraphQLProvider>
122
124
  </LanguageProvider>
123
125
  </StorageProvider>
124
126
  </SafeAreaView>
@@ -39,6 +39,7 @@ 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';
42
43
 
43
44
  export interface ChatProps {
44
45
  chatBubble?: React.ComponentType<ChatBubbleProps>;
@@ -51,7 +52,7 @@ const Chat = (props?: ChatProps) => {
51
52
  const isSmall = useIsSmall();
52
53
  const {setSidePanel} = useSidePanel();
53
54
  const {showHeader = true} = props;
54
-
55
+ const {isRecordingBot} = useIsRecordingBot();
55
56
  const {chatType, setChatType, setPrivateChatUser} = useChatUIControls();
56
57
 
57
58
  const {
@@ -170,9 +171,13 @@ const Chat = (props?: ChatProps) => {
170
171
  {chatType === ChatType.Group ? (
171
172
  <>
172
173
  <ChatContainer {...props} />
173
- <View style={style.chatInputContainer}>
174
- <ChatInputComponent />
175
- </View>
174
+ {isRecordingBot ? (
175
+ <></>
176
+ ) : (
177
+ <View style={style.chatInputContainer}>
178
+ <ChatInputComponent />
179
+ </View>
180
+ )}
176
181
  </>
177
182
  ) : (
178
183
  <></>
@@ -185,11 +190,15 @@ const Chat = (props?: ChatProps) => {
185
190
  {chatType === ChatType.Private ? (
186
191
  <>
187
192
  <ChatContainer {...props} />
188
- <View>
189
- <View style={style.chatInputContainer}>
190
- <ChatInputComponent />
193
+ {isRecordingBot ? (
194
+ <></>
195
+ ) : (
196
+ <View>
197
+ <View style={style.chatInputContainer}>
198
+ <ChatInputComponent />
199
+ </View>
191
200
  </View>
192
- </View>
201
+ )}
193
202
  </>
194
203
  ) : (
195
204
  <></>
@@ -66,8 +66,6 @@ export enum controlMessageEnum {
66
66
  requestAudio = '7',
67
67
  //newUserJoined = '8',
68
68
  kickScreenshare = '9',
69
- disableButton = '10',
70
- endCallForEveryone = '11',
71
69
  }
72
70
 
73
71
  const ChatContext = createContext(null as unknown as chatContext);
@@ -29,7 +29,7 @@ import Recording from '../subComponents/Recording';
29
29
  import LocalSwitchCamera from '../subComponents/LocalSwitchCamera';
30
30
  import ScreenshareButton from '../subComponents/screenshare/ScreenshareButton';
31
31
  import isMobileOrTablet from '../utils/isMobileOrTablet';
32
- import {ClientRole} from '../../agora-rn-uikit';
32
+ import {ClientRoleType} from '../../agora-rn-uikit';
33
33
  import LiveStreamControls from './livestream/views/LiveStreamControls';
34
34
  import {
35
35
  BREAKPOINTS,
@@ -525,14 +525,14 @@ const MoreButton = () => {
525
525
  if ($config.SCREEN_SHARING) {
526
526
  if (
527
527
  !(
528
- rtcProps.role == ClientRole.Audience &&
528
+ rtcProps.role == ClientRoleType.ClientRoleAudience &&
529
529
  $config.EVENT_MODE &&
530
530
  !$config.RAISE_HAND
531
531
  )
532
532
  ) {
533
533
  actionMenuitems.push({
534
534
  disabled:
535
- rtcProps.role == ClientRole.Audience &&
535
+ rtcProps.role == ClientRoleType.ClientRoleAudience &&
536
536
  $config.EVENT_MODE &&
537
537
  $config.RAISE_HAND &&
538
538
  !isHost,
@@ -775,9 +775,9 @@ export const RaiseHandToolbarItem = () => {
775
775
  data: {isHost},
776
776
  } = useRoomInfo();
777
777
  return $config.EVENT_MODE ? (
778
- rtcProps.role == ClientRole.Audience ? (
778
+ rtcProps.role == ClientRoleType.ClientRoleAudience ? (
779
779
  <LiveStreamControls showControls={true} />
780
- ) : rtcProps?.role == ClientRole.Broadcaster ? (
780
+ ) : rtcProps?.role == ClientRoleType.ClientRoleBroadcaster ? (
781
781
  /**
782
782
  * In event mode when raise hand feature is active
783
783
  * and audience is promoted to host, the audience can also
@@ -11,7 +11,7 @@
11
11
  */
12
12
  import React, {useContext} from 'react';
13
13
  import {View, StyleSheet} from 'react-native';
14
- import {PropsContext, ClientRole} from '../../agora-rn-uikit';
14
+ import {PropsContext, ClientRoleType} from '../../agora-rn-uikit';
15
15
  import LocalAudioMute, {
16
16
  LocalAudioMuteProps,
17
17
  } from '../subComponents/LocalAudioMute';
@@ -40,7 +40,8 @@ const Controls = () => {
40
40
 
41
41
  return (
42
42
  <View style={style.bottomBar}>
43
- {$config.EVENT_MODE && rtcProps.role == ClientRole.Audience ? (
43
+ {$config.EVENT_MODE &&
44
+ rtcProps.role == ClientRoleType.ClientRoleAudience ? (
44
45
  <LiveStreamControls showControls={true} />
45
46
  ) : (
46
47
  <>
@@ -51,7 +52,10 @@ const Controls = () => {
51
52
  */}
52
53
  {$config.EVENT_MODE && (
53
54
  <LiveStreamControls
54
- showControls={rtcProps?.role == ClientRole.Broadcaster && !isHost}
55
+ showControls={
56
+ rtcProps?.role == ClientRoleType.ClientRoleBroadcaster &&
57
+ !isHost
58
+ }
55
59
  />
56
60
  )}
57
61
  <View style={{alignSelf: 'center'}}>
@@ -11,10 +11,10 @@
11
11
  */
12
12
  import React from 'react';
13
13
  import KeepAwake from 'react-native-keep-awake';
14
- import {ClientRole} from '../../agora-rn-uikit';
14
+ import {ClientRoleType} from '../../agora-rn-uikit';
15
15
 
16
16
  interface Props {
17
- userRole: ClientRole;
17
+ userRole: ClientRoleType;
18
18
  }
19
19
  const DeviceConfigure: React.FC<Props> = (props: any) => {
20
20
  return (
@@ -17,7 +17,7 @@ import React, {
17
17
  useRef,
18
18
  useContext,
19
19
  } from 'react';
20
- import {ClientRole, RtcContext} from '../../agora-rn-uikit';
20
+ import {ClientRoleType, RtcContext} from '../../agora-rn-uikit';
21
21
  import DeviceContext from './DeviceContext';
22
22
  import AgoraRTC, {DeviceInfo} from 'agora-rtc-sdk-ng';
23
23
  import {useRtc} from 'customization-api';
@@ -49,7 +49,7 @@ const log = (...args: any[]) => {
49
49
  type WebRtcEngineInstance = InstanceType<typeof RtcEngine>;
50
50
 
51
51
  interface Props {
52
- userRole: ClientRole;
52
+ userRole: ClientRoleType;
53
53
  }
54
54
  export type deviceInfo = MediaDeviceInfo;
55
55
  export type deviceId = deviceInfo['deviceId'];
@@ -52,6 +52,7 @@ import {
52
52
  waitingRoomApprovalRequiredToastSubHeading,
53
53
  } from '../language/default-labels/videoCallScreenLabels';
54
54
  import {useString} from '../utils/useString';
55
+ import useEndCall from '../utils/useEndCall';
55
56
 
56
57
  interface Props {
57
58
  children: React.ReactNode;
@@ -157,6 +158,7 @@ const EventsConfigure: React.FC<Props> = props => {
157
158
  hostRemovedUserToastHeading,
158
159
  )();
159
160
 
161
+ const executeEndCall = useEndCall();
160
162
  const removedUserToastRef = useRef(hostRemovedUserToastHeadingTT);
161
163
 
162
164
  useEffect(() => {
@@ -304,7 +306,7 @@ const EventsConfigure: React.FC<Props> = props => {
304
306
  });
305
307
  }
306
308
  });
307
- events.on(controlMessageEnum.muteAudio, ({sender}) => {
309
+ events.on(controlMessageEnum.muteAudio, async ({sender}) => {
308
310
  Toast.show({
309
311
  leadingIconName: 'mic-off',
310
312
  type: 'info',
@@ -317,7 +319,10 @@ const EventsConfigure: React.FC<Props> = props => {
317
319
  secondaryBtn: null,
318
320
  leadingIcon: null,
319
321
  });
320
- RtcEngineUnsafe.muteLocalAudioStream(true);
322
+ isWebInternal()
323
+ ? await RtcEngineUnsafe.muteLocalAudioStream(true)
324
+ : //@ts-ignore
325
+ await RtcEngineUnsafe.enableLocalAudio(false);
321
326
  dispatch({
322
327
  type: 'LocalMuteAudio',
323
328
  value: [0],
@@ -333,11 +338,6 @@ const EventsConfigure: React.FC<Props> = props => {
333
338
  } catch (error) {
334
339
  console.log('error on stop the screeshare', error);
335
340
  }
336
-
337
- if (!ENABLE_AUTH) {
338
- // await authLogout();
339
- await authLogin();
340
- }
341
341
  Toast.show({
342
342
  leadingIconName: 'info',
343
343
  type: 'info',
@@ -347,22 +347,10 @@ const EventsConfigure: React.FC<Props> = props => {
347
347
  secondaryBtn: null,
348
348
  });
349
349
  setTimeout(() => {
350
- dispatch({
351
- type: 'EndCall',
352
- value: [isHostRef.current, true],
353
- });
350
+ executeEndCall();
354
351
  }, 5000);
355
352
  });
356
353
 
357
- events.on(controlMessageEnum.endCallForEveryone, async () => {
358
- setTimeout(() => {
359
- dispatch({
360
- type: 'EndCall',
361
- value: [isHostRef.current, true],
362
- });
363
- }, 1000);
364
- });
365
-
366
354
  events.on(controlMessageEnum.requestAudio, () => {
367
355
  Toast.show({
368
356
  leadingIconName: 'mic-on',
@@ -379,8 +367,11 @@ const EventsConfigure: React.FC<Props> = props => {
379
367
  containerStyle={style.primaryBtn}
380
368
  textStyle={style.textStyle}
381
369
  text={requestUserAudioPrimaryBtnRef.current}
382
- onPress={() => {
383
- RtcEngineUnsafe.muteLocalAudioStream(false);
370
+ onPress={async () => {
371
+ isWebInternal()
372
+ ? await RtcEngineUnsafe.muteLocalAudioStream(false)
373
+ : //@ts-ignore
374
+ await RtcEngineUnsafe.enableLocalAudio(true);
384
375
  dispatch({
385
376
  type: 'LocalMuteAudio',
386
377
  value: [1],
@@ -15,13 +15,11 @@ import {
15
15
  InMemoryCache,
16
16
  ApolloProvider,
17
17
  NormalizedCacheObject,
18
+ ApolloLink,
18
19
  // from,
19
20
  } from '@apollo/client';
20
- import {setContext} from '@apollo/client/link/context';
21
- // import useMount from './useMount';
22
21
  import React, {createContext, useContext, useEffect, useState} from 'react';
23
22
  import StorageContext from './StorageContext';
24
- import AsyncStorage from '@react-native-async-storage/async-storage';
25
23
 
26
24
  export const GraphQLContext = createContext<{
27
25
  client: ApolloClient<NormalizedCacheObject>;
@@ -35,38 +33,57 @@ const httpLink = createHttpLink({
35
33
  credentials: 'include',
36
34
  });
37
35
 
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
- };
36
+ const cache = new InMemoryCache();
37
+
38
+ const DEFAULT_CLIENT = new ApolloClient({
39
+ link: httpLink,
40
+ cache: cache,
41
+ });
42
+
43
+ const authLink = (token: string) => {
44
+ /**
45
+ * Below we create a new link, whenever a token changes, set
46
+ * context with headers and forward the link so as to
47
+ * execute the next link in the chain
48
+ */
49
+ return new ApolloLink((operation, forward) => {
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);
52
63
  });
64
+ };
53
65
 
54
66
  const GraphQLProvider = (props: {children: React.ReactNode}) => {
55
67
  const {store} = useContext(StorageContext);
56
- const [client, setClient] = useState(
57
- new ApolloClient({
58
- link: authLink(store?.token).concat(httpLink),
59
- cache: new InMemoryCache(),
60
- }),
61
- );
68
+ const [client, setClient] = useState(DEFAULT_CLIENT);
69
+
70
+ // useEffect(() => {
71
+ // setClient(
72
+ // new ApolloClient({
73
+ // link: authLink(store?.token).concat(httpLink),
74
+ // cache: new InMemoryCache(),
75
+ // }),
76
+ // );
77
+ // }, [store?.token]);
62
78
 
63
79
  useEffect(() => {
64
- setClient(
65
- new ApolloClient({
66
- link: authLink(store?.token).concat(httpLink),
67
- cache: new InMemoryCache(),
68
- }),
69
- );
80
+ if (!store?.token) {
81
+ return;
82
+ }
83
+ (async () => {
84
+ const link = authLink(store?.token).concat(httpLink);
85
+ setClient(new ApolloClient({link, cache}));
86
+ })();
70
87
  }, [store?.token]);
71
88
 
72
89
  // const errorLink = onError(
@@ -74,7 +91,7 @@ const GraphQLProvider = (props: {children: React.ReactNode}) => {
74
91
  // // To retry on network errors, we recommend the RetryLink
75
92
  // // instead of the onError link. This just logs the error.
76
93
  // if (networkError) {
77
-
94
+
78
95
  // // switch (err.extensions.code) {
79
96
  // // // Apollo Server sets code to UNAUTHENTICATED
80
97
  // // // when an AuthenticationError is thrown in a resolver
@@ -15,7 +15,11 @@ import {View, StyleSheet, Pressable, Text} from 'react-native';
15
15
  import {isWebInternal, useIsDesktop} from '../utils/common';
16
16
  import {useSetPinnedLayout} from '../pages/video-call/DefaultLayouts';
17
17
  import RenderComponent from '../pages/video-call/RenderComponent';
18
- import {ClientRole, DispatchContext, PropsContext} from '../../agora-rn-uikit';
18
+ import {
19
+ ClientRoleType,
20
+ DispatchContext,
21
+ PropsContext,
22
+ } from '../../agora-rn-uikit';
19
23
  import LiveStreamAttendeeLandingTile from './livestream/views/LiveStreamAttendeeLandingTile';
20
24
 
21
25
  const layout = (len: number, isDesktop: boolean = true) => {
@@ -53,7 +57,7 @@ const GridVideo: LayoutComponent = ({renderData}) => {
53
57
  //livestreaming audience will see this if no host joined the call
54
58
  if (
55
59
  $config.EVENT_MODE &&
56
- rtcProps?.role === ClientRole.Audience &&
60
+ rtcProps?.role === ClientRoleType.ClientRoleAudience &&
57
61
  activeUids.filter(i => !customContent[i]).length === 0
58
62
  ) {
59
63
  return <LiveStreamAttendeeLandingTile />;
@@ -28,6 +28,12 @@ import {useRtc} from 'customization-api';
28
28
  * 7 - Unsupported
29
29
  * 8 - Loading
30
30
  */
31
+
32
+ interface RtcConnection {
33
+ channelId?: string;
34
+ localUid?: number;
35
+ }
36
+
31
37
  export const networkIconsObject: {
32
38
  [key: number]: {
33
39
  icon: keyof IconsInterface;
@@ -106,13 +112,14 @@ export const NetworkQualityProvider: React.FC = (props: {
106
112
 
107
113
  useMount(() => {
108
114
  function handleNetworkQuality(
115
+ connection: RtcConnection,
109
116
  uid: UidType,
110
- downlinkQuality: number,
111
117
  // Currently unused , potential use might be to take weighted average
112
118
  // of this alongside the downlink quality.
113
- uplinkQuality: number,
119
+ uplinkQuality: keyof typeof networkIconsObject,
120
+ downlinkQuality: keyof typeof networkIconsObject,
114
121
  ) {
115
- setNetworkQualityStats((prevNetworkQualityStats) => {
122
+ setNetworkQualityStats(prevNetworkQualityStats => {
116
123
  const updatedNetworkQualityStats = {...prevNetworkQualityStats};
117
124
  if (uid === 0) {
118
125
  const displayedNetworkQuality =
@@ -130,8 +137,7 @@ export const NetworkQualityProvider: React.FC = (props: {
130
137
  return updatedNetworkQualityStats;
131
138
  });
132
139
  }
133
-
134
- RtcEngineUnsafe.addListener('NetworkQuality', handleNetworkQuality);
140
+ RtcEngineUnsafe.addListener('onNetworkQuality', handleNetworkQuality);
135
141
  });
136
142
 
137
143
  return (
@@ -11,7 +11,7 @@
11
11
  */
12
12
  import React, {useContext, useState} from 'react';
13
13
  import {View, Text, StyleSheet, ScrollView} from 'react-native';
14
- import {PropsContext, ClientRole} from '../../agora-rn-uikit';
14
+ import {PropsContext, ClientRoleType} from '../../agora-rn-uikit';
15
15
  import CopyJoinInfo from '../subComponents/CopyJoinInfo';
16
16
  import ParticipantSectionTitle from './participants/ParticipantSectionTitle';
17
17
  import AllHostParticipants from './participants/AllHostParticipants';
@@ -109,7 +109,7 @@ const ParticipantView = props => {
109
109
  {
110
110
  /*Live streaming is true
111
111
  Host and New host view */
112
- rtcProps?.role == ClientRole.Broadcaster &&
112
+ rtcProps?.role == ClientRoleType.ClientRoleBroadcaster &&
113
113
  (isHost ? (
114
114
  /**
115
115
  * Original Host
@@ -177,7 +177,7 @@ const ParticipantView = props => {
177
177
  /**
178
178
  * Audience views all hosts without remote controls
179
179
  */
180
- rtcProps?.role == ClientRole.Audience && (
180
+ rtcProps?.role == ClientRoleType.ClientRoleAudience && (
181
181
  <>
182
182
  <ParticipantSectionTitle
183
183
  title={hostLabel}
@@ -24,7 +24,7 @@ import {useContent} from 'customization-api';
24
24
  import RenderComponent from '../pages/video-call/RenderComponent';
25
25
  import IconButton from '../atoms/IconButton';
26
26
  import hexadecimalTransparency from '../utils/hexadecimalTransparency';
27
- import {BREAKPOINTS, isMobileUA} from '../utils/common';
27
+ import {BREAKPOINTS, isMobileUA, isWebInternal} from '../utils/common';
28
28
  import {DispatchContext} from '../../agora-rn-uikit';
29
29
  import {useVideoCall} from '../components/useVideoCall';
30
30
  import useActiveSpeaker from '../utils/useActiveSpeaker';
@@ -180,7 +180,7 @@ const PinnedVideo = ({renderData}) => {
180
180
  );
181
181
  })}
182
182
  </ScrollView>
183
- {$config.ACTIVE_SPEAKER && !isOnTop && (
183
+ {$config.ACTIVE_SPEAKER && !isOnTop && isWebInternal() && (
184
184
  <View
185
185
  style={
186
186
  isSidePinnedlayout