agora-appbuilder-core 4.0.29-beta-23 → 4.0.29-beta-25

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 (36) hide show
  1. package/package.json +1 -1
  2. package/template/agora-rn-uikit/src/Rtc/Create.tsx +2 -2
  3. package/template/agora-rn-uikit/src/Rtc/Join.tsx +7 -7
  4. package/template/customization-api/sub-components.ts +1 -0
  5. package/template/customization-api/utils.ts +0 -1
  6. package/template/defaultConfig.js +2 -2
  7. package/template/src/atoms/ActionMenu.tsx +9 -1
  8. package/template/src/atoms/Checkbox.tsx +17 -3
  9. package/template/src/atoms/TertiaryButton.tsx +20 -4
  10. package/template/src/atoms/Toggle.tsx +9 -3
  11. package/template/src/auth/AuthProvider.tsx +7 -0
  12. package/template/src/auth/useIDPAuth.electron.tsx +1 -0
  13. package/template/src/auth/useIDPAuth.native.tsx +1 -0
  14. package/template/src/auth/useIDPAuth.tsx +1 -0
  15. package/template/src/auth/useTokenAuth.tsx +2 -0
  16. package/template/src/components/ChatContext.ts +1 -1
  17. package/template/src/components/CustomSidePanel.tsx +1 -2
  18. package/template/src/components/EventsConfigure.tsx +46 -11
  19. package/template/src/components/RTMConfigure.tsx +3 -0
  20. package/template/src/components/common/Error.tsx +17 -3
  21. package/template/src/components/popups/InvitePopup.tsx +16 -0
  22. package/template/src/components/useUserPreference.tsx +15 -0
  23. package/template/src/components/whiteboard/WhiteboardToolBox.tsx +3 -0
  24. package/template/src/components/whiteboard/WhiteboardWidget.tsx +1 -0
  25. package/template/src/pages/Create.tsx +9 -0
  26. package/template/src/pages/Join.tsx +15 -0
  27. package/template/src/pages/VideoCall.tsx +38 -0
  28. package/template/src/subComponents/caption/useSTTAPI.tsx +1 -0
  29. package/template/src/subComponents/recording/useRecording.tsx +70 -30
  30. package/template/src/subComponents/recording/useRecordingLayoutQuery.tsx +93 -9
  31. package/template/src/subComponents/waiting-rooms/useWaitingRoomAPI.ts +1 -0
  32. package/template/src/utils/common.tsx +0 -6
  33. package/template/src/utils/useCreateRoom.ts +14 -1
  34. package/template/src/utils/useGetMeetingPhrase.ts +8 -0
  35. package/template/src/utils/useJoinRoom.ts +9 -0
  36. package/template/src/utils/useMutePSTN.ts +14 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agora-appbuilder-core",
3
- "version": "4.0.29-beta-23",
3
+ "version": "4.0.29-beta-25",
4
4
  "description": "React Native template for RTE app builder",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -194,9 +194,9 @@ const Create = ({
194
194
  mode === ChannelProfileType.ChannelProfileLiveBroadcasting &&
195
195
  rtcProps?.role === ClientRoleType.ClientRoleAudience
196
196
  ) {
197
- enableVideoAndAudioWithDisabledState();
197
+ await enableVideoAndAudioWithDisabledState();
198
198
  } else {
199
- enableVideoAndAudioWithEnabledState();
199
+ await enableVideoAndAudioWithEnabledState();
200
200
  }
201
201
  };
202
202
 
@@ -1,4 +1,4 @@
1
- import React, {useEffect, useContext, useRef} from 'react';
1
+ import React, {useEffect, useContext, useRef, useState} from 'react';
2
2
  import {IRtcEngine} from 'react-native-agora';
3
3
  import {ContentStateInterface} from '../Contexts/RtcContext';
4
4
  import {DispatchType} from '../Contexts/DispatchContext';
@@ -14,7 +14,7 @@ const Join: React.FC<{
14
14
  tracksReady: boolean;
15
15
  preventJoin?: boolean;
16
16
  }> = ({children, precall, engineRef, uidState, dispatch, tracksReady}) => {
17
- let joinState = useRef(false);
17
+ const [joinState, setJoinState] = useState(false);
18
18
  const {rtcProps} = useContext(PropsContext);
19
19
 
20
20
  const audioRoom = rtcProps?.audioRoom || false;
@@ -24,12 +24,12 @@ const Join: React.FC<{
24
24
  // : null;
25
25
 
26
26
  useEffect(() => {
27
- if (joinState.current && tracksReady && Platform.OS === 'web') {
27
+ if (joinState && tracksReady && Platform.OS === 'web') {
28
28
  //@ts-ignore
29
29
  engineRef.current.publish();
30
30
  }
31
31
  // eslint-disable-next-line react-hooks/exhaustive-deps
32
- }, [tracksReady]);
32
+ }, [tracksReady, joinState]);
33
33
 
34
34
  useEffect(() => {
35
35
  if (rtcProps?.preventJoin) {
@@ -41,7 +41,7 @@ const Join: React.FC<{
41
41
  try {
42
42
  console.log('Leaving channel');
43
43
  engine.leaveChannel();
44
- joinState.current = false;
44
+ setJoinState(false);
45
45
  } catch (err) {
46
46
  console.error('Cannot leave the channel:', err);
47
47
  }
@@ -118,9 +118,9 @@ const Join: React.FC<{
118
118
  }
119
119
  async function init() {
120
120
  if (!precall) {
121
- if (!joinState.current) {
121
+ if (!joinState) {
122
122
  await join();
123
- joinState.current = true;
123
+ setJoinState(true);
124
124
  } else {
125
125
  await leave();
126
126
  await join();
@@ -85,3 +85,4 @@ export {default as TranscriptPanel} from '../src/subComponents/caption/Transcrip
85
85
  export type {TranscriptProps} from '../src/subComponents/caption/Transcript';
86
86
  export {default as CaptionPanel} from '../src/subComponents/caption/CaptionContainer';
87
87
  export {default as VBPreview} from '../src/components/virtual-background/VideoPreview';
88
+ export {default as Toast} from '../react-native-toast-message';
@@ -43,7 +43,6 @@ export {useString} from '../src/utils/useString';
43
43
  export type {LanguageType} from '../src/subComponents/caption/utils';
44
44
  export {default as useSpeechToText} from '../src/utils/useSpeechToText';
45
45
  export {isMobileUA} from '../src/utils/common';
46
- export {getSessionId} from '../src/utils/common';
47
46
  export {default as ThemeConfig} from '../src/theme';
48
47
  export {default as hexadecimalTransparency} from '../src/utils/hexadecimalTransparency';
49
48
  export {useFullScreen} from '../src/utils/useFullScreen';
@@ -76,8 +76,8 @@ const DefaultConfig = {
76
76
  CHAT_ORG_NAME: '',
77
77
  CHAT_APP_NAME: '',
78
78
  CHAT_URL: '',
79
- CLI_VERSION: '3.0.28',
80
- CORE_VERSION: '4.0.28',
79
+ CLI_VERSION: '3.0.29-beta-24',
80
+ CORE_VERSION: '4.0.29-beta-24',
81
81
  DISABLE_LANDSCAPE_MODE: false,
82
82
  STT_AUTO_START: false,
83
83
  CLOUD_RECORDING_AUTO_START: false,
@@ -9,6 +9,8 @@ import {
9
9
  TouchableOpacity,
10
10
  ViewStyle,
11
11
  useWindowDimensions,
12
+ StyleProp,
13
+ TextStyle,
12
14
  } from 'react-native';
13
15
  import React, {SetStateAction, useState} from 'react';
14
16
 
@@ -32,6 +34,7 @@ export interface ActionMenuItem {
32
34
  iconColor: string;
33
35
  textColor: string;
34
36
  title: string;
37
+ titleStyle?: StyleProp<TextStyle>;
35
38
  label?: string;
36
39
  toggleStatus?: boolean;
37
40
  onPress: () => void;
@@ -97,6 +100,7 @@ const ActionMenu = (props: ActionMenuProps) => {
97
100
  onHoverCallback = undefined,
98
101
  onHoverContent = undefined,
99
102
  iconSize = 20,
103
+ titleStyle = {},
100
104
  } = item;
101
105
  return (
102
106
  <PlatformWrapper key={props.from + '_' + title + index}>
@@ -175,7 +179,11 @@ const ActionMenu = (props: ActionMenuProps) => {
175
179
  )}
176
180
  </View>
177
181
  <Text
178
- style={[styles.text, textColor ? {color: textColor} : {}]}>
182
+ style={[
183
+ styles.text,
184
+ titleStyle,
185
+ textColor ? {color: textColor} : {},
186
+ ]}>
179
187
  {label || title}
180
188
  </Text>
181
189
  {toggleStatus !== undefined && toggleStatus !== null ? (
@@ -6,6 +6,7 @@ import {
6
6
  Platform,
7
7
  StyleSheet,
8
8
  TextStyle,
9
+ ViewStyle,
9
10
  } from 'react-native';
10
11
 
11
12
  import ThemeConfig from '../theme';
@@ -17,6 +18,9 @@ interface CheckboxProps {
17
18
  onChange: (checked: boolean) => void;
18
19
  labelStye?: TextStyle;
19
20
  disabled?: boolean;
21
+ containerStyle?: ViewStyle;
22
+ checkBoxStyle?: ViewStyle;
23
+ tickColor?: string;
20
24
  }
21
25
 
22
26
  const Checkbox: React.FC<CheckboxProps> = ({
@@ -25,6 +29,9 @@ const Checkbox: React.FC<CheckboxProps> = ({
25
29
  onChange,
26
30
  disabled = false,
27
31
  labelStye = {},
32
+ containerStyle = {},
33
+ checkBoxStyle = {},
34
+ tickColor = $config.FONT_COLOR,
28
35
  }) => {
29
36
  const [isChecked, setIsChecked] = useState(checked);
30
37
 
@@ -40,15 +47,21 @@ const Checkbox: React.FC<CheckboxProps> = ({
40
47
  };
41
48
 
42
49
  return (
43
- <TouchableOpacity onPress={handleCheckboxToggle} style={styles.container}>
50
+ <TouchableOpacity
51
+ onPress={handleCheckboxToggle}
52
+ style={(styles.container, containerStyle)}>
44
53
  <View
45
- style={[styles.checkboxContainer, isChecked && styles.fillSelected]}>
54
+ style={[
55
+ styles.checkboxContainer,
56
+ checkBoxStyle,
57
+ isChecked && styles.fillSelected,
58
+ ]}>
46
59
  {isChecked && (
47
60
  <ImageIcon
48
61
  iconType="plain"
49
62
  name={'tick'}
50
63
  iconSize={8}
51
- tintColor={$config.FONT_COLOR}
64
+ tintColor={tickColor}
52
65
  />
53
66
  )}
54
67
  </View>
@@ -76,6 +89,7 @@ const styles = StyleSheet.create({
76
89
  borderColor: $config.SEMANTIC_NEUTRAL,
77
90
  justifyContent: 'center',
78
91
  alignItems: 'center',
92
+ borderRadius: 1,
79
93
  },
80
94
  checkIcon: {
81
95
  position: 'absolute',
@@ -31,6 +31,7 @@ const TertiaryButton = (props: ButtonProps) => {
31
31
  iconName,
32
32
  iconSize = 26,
33
33
  iconColor = $config.PRIMARY_ACTION_TEXT_COLOR,
34
+ disabled = false,
34
35
  ...rest
35
36
  } = props;
36
37
  const [isHovered, setIsHovered] = useState(false);
@@ -38,16 +39,17 @@ const TertiaryButton = (props: ButtonProps) => {
38
39
  return (
39
40
  <PlatformWrapper setIsHovered={setIsHovered}>
40
41
  <TouchableOpacity
41
- ref={(ref) => props?.setRef && props.setRef(ref)}
42
+ ref={ref => props?.setRef && props.setRef(ref)}
42
43
  style={[
43
44
  styles.container,
44
- isHovered
45
+ isHovered && !disabled
45
46
  ? {
46
47
  backgroundColor:
47
48
  $config.CARD_LAYER_5_COLOR + hexadecimalTransparency['15%'],
48
49
  }
49
50
  : {},
50
51
  props?.containerStyle,
52
+ disabled ? styles.disabledContainer : {},
51
53
  ]}
52
54
  {...rest}>
53
55
  <View style={styles.flexRow}>
@@ -57,11 +59,18 @@ const TertiaryButton = (props: ButtonProps) => {
57
59
  iconSize={iconSize}
58
60
  iconType="plain"
59
61
  name={iconName}
60
- tintColor={iconColor}
62
+ tintColor={disabled ? $config.SEMANTIC_NEUTRAL : iconColor}
61
63
  />
62
64
  </View>
63
65
  )}
64
- <Text style={[styles.text, props?.textStyle]}>{text}</Text>
66
+ <Text
67
+ style={[
68
+ styles.text,
69
+ props?.textStyle,
70
+ disabled ? styles.disabledText : {},
71
+ ]}>
72
+ {text}
73
+ </Text>
65
74
  </View>
66
75
  </TouchableOpacity>
67
76
  </PlatformWrapper>
@@ -105,4 +114,11 @@ const styles = StyleSheet.create({
105
114
  fontSize: ThemeConfig.FontSize.small,
106
115
  fontWeight: '600',
107
116
  },
117
+ disabledContainer: {
118
+ borderColor: $config.SEMANTIC_NEUTRAL,
119
+ cursor: 'default',
120
+ },
121
+ disabledText: {
122
+ color: $config.SEMANTIC_NEUTRAL,
123
+ },
108
124
  });
@@ -6,10 +6,16 @@ interface SwitchProps {
6
6
  isEnabled: boolean;
7
7
  disabled?: boolean;
8
8
  toggleSwitch: (isEnabled: boolean) => void;
9
+ circleColor?: string;
9
10
  }
10
11
 
11
12
  const Toggle = (props: SwitchProps) => {
12
- const {isEnabled, toggleSwitch, disabled = false} = props;
13
+ const {
14
+ isEnabled,
15
+ toggleSwitch,
16
+ disabled = false,
17
+ circleColor = $config.CARD_LAYER_1_COLOR,
18
+ } = props;
13
19
  return (
14
20
  <View>
15
21
  <CustomSwitch
@@ -21,8 +27,8 @@ const Toggle = (props: SwitchProps) => {
21
27
  disabled={false}
22
28
  backgroundActive={$config.PRIMARY_ACTION_BRAND_COLOR}
23
29
  backgroundInactive={$config.SEMANTIC_NEUTRAL}
24
- circleActiveColor={$config.CARD_LAYER_1_COLOR}
25
- circleInActiveColor={$config.CARD_LAYER_1_COLOR}
30
+ circleActiveColor={circleColor}
31
+ circleInActiveColor={circleColor}
26
32
  // renderInsideCircle={() => <CustomComponent />} // custom component to render inside the Switch circle (Text, Image, etc.)
27
33
  changeValueImmediately={true} // if rendering inside circle, change state immediately or wait for animation to complete
28
34
  innerCircleStyle={{
@@ -309,6 +309,7 @@ const AuthProvider = (props: AuthProviderProps) => {
309
309
  context: {
310
310
  headers: {
311
311
  'X-Request-Id': requestId,
312
+ 'X-Session-Id': logger.getSessionId(),
312
313
  },
313
314
  },
314
315
  });
@@ -332,6 +333,11 @@ const AuthProvider = (props: AuthProviderProps) => {
332
333
  'user_details',
333
334
  'API user details query failed. User is un-authenticated. Will Login in the user',
334
335
  {
336
+ networkError: {
337
+ name: error?.networkError?.name,
338
+ code: error?.networkError?.result?.error?.code,
339
+ message: error?.networkError?.result?.error?.message,
340
+ },
335
341
  error,
336
342
  startReqTs,
337
343
  endRequestTs,
@@ -522,6 +528,7 @@ const AuthProvider = (props: AuthProviderProps) => {
522
528
  credentials: 'include',
523
529
  headers: {
524
530
  'X-Request-Id': requestId,
531
+ 'X-Session-Id': logger.getSessionId(),
525
532
  },
526
533
  })
527
534
  .then(response => response.json())
@@ -36,6 +36,7 @@ export const useIDPAuth = () => {
36
36
  headers: {
37
37
  authorization: store?.token ? `Bearer ${store?.token}` : '',
38
38
  'X-Request-Id': requestId,
39
+ 'X-Session-Id': logger.getSessionId(),
39
40
  },
40
41
  })
41
42
  .then(response => response.json())
@@ -33,6 +33,7 @@ export const useIDPAuth = () => {
33
33
  headers: {
34
34
  authorization: store?.token ? `Bearer ${store?.token}` : '',
35
35
  'X-Request-Id': requestId,
36
+ 'X-Session-Id': logger.getSessionId(),
36
37
  },
37
38
  })
38
39
  .then(response => response.json())
@@ -31,6 +31,7 @@ export const useIDPAuth = () => {
31
31
  headers: {
32
32
  authorization: store?.token ? `Bearer ${store?.token}` : '',
33
33
  'X-Request-Id': requestId,
34
+ 'X-Session-Id': logger.getSessionId(),
34
35
  },
35
36
  })
36
37
  .then(response => response.json())
@@ -57,6 +57,7 @@ const useTokenAuth = () => {
57
57
  authorization: store?.token ? `Bearer ${store.token}` : '',
58
58
  'X-Platform-ID': getPlatformId(),
59
59
  'X-Request-Id': requestId,
60
+ 'X-Session-Id': logger.getSessionId(),
60
61
  },
61
62
  })
62
63
  .then(response => response.json())
@@ -213,6 +214,7 @@ const useTokenAuth = () => {
213
214
  ? `Bearer ${tokenRef.current}`
214
215
  : '',
215
216
  'X-Request-Id': requestId,
217
+ 'X-Session-Id': logger.getSessionId(),
216
218
  },
217
219
  },
218
220
  )
@@ -16,7 +16,6 @@ import {createContext, SetStateAction} from 'react';
16
16
  import {ChatMessageType, Reaction} from './chat-messages/useChatMessages';
17
17
  import {createHook} from 'customization-implementation';
18
18
 
19
-
20
19
  export interface ChatBubbleProps {
21
20
  isLocal: boolean;
22
21
  message: string;
@@ -67,6 +66,7 @@ export enum messageActionType {
67
66
  }
68
67
 
69
68
  export interface RtmContextInterface {
69
+ isInitialQueueCompleted: boolean;
70
70
  hasUserJoinedRTM: boolean;
71
71
  rtmInitTimstamp: number;
72
72
  engine: RtmEngine;
@@ -65,7 +65,7 @@ const CustomSidePanelView = (props: CustomSidePanelViewInterface) => {
65
65
  {showHeader && (
66
66
  <CustomSidePanelHeader name={name} title={title} onClose={onClose} />
67
67
  )}
68
- <ScrollView style={[style.bodyContainer]}>
68
+ <ScrollView contentContainerStyle={[style.bodyContainer]}>
69
69
  {CustomSidePanelContent ? <CustomSidePanelContent /> : <></>}
70
70
  </ScrollView>
71
71
  </View>
@@ -75,7 +75,6 @@ const CustomSidePanelView = (props: CustomSidePanelViewInterface) => {
75
75
  const style = StyleSheet.create({
76
76
  bodyContainer: {
77
77
  flex: 1,
78
- padding: 20,
79
78
  },
80
79
  });
81
80
 
@@ -54,13 +54,23 @@ import {
54
54
  import {useString} from '../utils/useString';
55
55
  import useEndCall from '../utils/useEndCall';
56
56
  import {logger, LogSource} from '../logger/AppBuilderLogger';
57
+ import {useIsRecordingBot} from '../subComponents/recording/useIsRecordingBot';
57
58
 
58
59
  interface Props {
59
60
  children: React.ReactNode;
60
61
  callActive: boolean;
62
+ sttAutoStarted: boolean;
63
+ setSttAutoStarted: React.Dispatch<React.SetStateAction<boolean>>;
61
64
  }
62
65
 
63
- const EventsConfigure: React.FC<Props> = ({callActive, children}) => {
66
+ const EventsConfigure: React.FC<Props> = ({
67
+ callActive,
68
+ children,
69
+ setSttAutoStarted,
70
+ sttAutoStarted,
71
+ }) => {
72
+ const {isRecordingBot} = useIsRecordingBot();
73
+ const isSTTAlreadyActiveRef = useRef(undefined);
64
74
  // mute user audio
65
75
  const hostMutedUserAudioToastHeadingTT = useString<I18nMuteType>(
66
76
  hostMutedUserToastHeading,
@@ -257,40 +267,60 @@ const EventsConfigure: React.FC<Props> = ({callActive, children}) => {
257
267
  permissionStatusRef.current = permissionStatus;
258
268
  }, [permissionStatus]);
259
269
 
260
- const {hasUserJoinedRTM} = useContext(ChatContext);
270
+ const {hasUserJoinedRTM, isInitialQueueCompleted} = useContext(ChatContext);
261
271
  const {startSpeechToText} = useSpeechToText();
262
- const [autoStartCompleted, setAutoStartCompleted] = useState(false);
263
-
264
272
  //auto start stt
265
273
  useEffect(() => {
266
274
  if (
275
+ !isRecordingBot &&
267
276
  $config.ENABLE_CAPTION &&
268
277
  $config.STT_AUTO_START &&
269
278
  callActive &&
270
279
  hasUserJoinedRTM &&
271
- !autoStartCompleted
280
+ isInitialQueueCompleted &&
281
+ !sttAutoStarted
272
282
  ) {
273
283
  //host will start the caption
274
- if (isHost && roomId?.host) {
275
- logger.log(LogSource.Internals, 'STT', 'STT_AUTO_START triggered');
284
+ if (isHost && roomId?.host && !isSTTAlreadyActiveRef.current) {
285
+ logger.log(LogSource.Internals, 'STT', 'STT_AUTO_START triggered', {
286
+ uidWhoTriggered: localUid,
287
+ });
276
288
  //start with default language
277
289
  startSpeechToText(['en-US'])
278
290
  .then(() => {
279
291
  logger.log(LogSource.Internals, 'STT', 'STT_AUTO_START success');
280
- setAutoStartCompleted(true);
292
+ setSttAutoStarted(true);
281
293
  })
282
294
  .catch(err => {
283
295
  logger.log(
284
296
  LogSource.Internals,
285
- 'RECORDING',
297
+ 'STT',
286
298
  'STT_AUTO_START failed',
287
299
  err,
288
300
  );
289
- setAutoStartCompleted(false);
301
+ setSttAutoStarted(false);
290
302
  });
291
303
  }
304
+
305
+ if (isHost && roomId?.host && isSTTAlreadyActiveRef.current) {
306
+ logger.log(
307
+ LogSource.Internals,
308
+ 'STT',
309
+ 'STT_AUTO_START already triggered by some other host',
310
+ );
311
+ setSttAutoStarted(true);
312
+ }
292
313
  }
293
- }, [callActive, isHost, hasUserJoinedRTM, roomId, autoStartCompleted]);
314
+ }, [
315
+ isRecordingBot,
316
+ callActive,
317
+ isHost,
318
+ hasUserJoinedRTM,
319
+ roomId,
320
+ sttAutoStarted,
321
+ isInitialQueueCompleted,
322
+ isSTTAlreadyActiveRef.current,
323
+ ]);
294
324
 
295
325
  useEffect(() => {
296
326
  //user joined event listener
@@ -520,6 +550,11 @@ const EventsConfigure: React.FC<Props> = ({callActive, children}) => {
520
550
 
521
551
  events.on(EventNames.STT_ACTIVE, data => {
522
552
  const payload = JSON.parse(data?.payload);
553
+ if (payload.active) {
554
+ isSTTAlreadyActiveRef.current = true;
555
+ } else {
556
+ isSTTAlreadyActiveRef.current = false;
557
+ }
523
558
  setRoomInfo(prev => {
524
559
  return {
525
560
  ...prev,
@@ -93,6 +93,7 @@ const RtmConfigure = (props: any) => {
93
93
  }, [defaultContent]);
94
94
 
95
95
  const [hasUserJoinedRTM, setHasUserJoinedRTM] = useState<boolean>(false);
96
+ const [isInitialQueueCompleted, setIsInitialQueueCompleted] = useState(false);
96
97
  const [onlineUsersCount, setTotalOnlineUsers] = useState<number>(0);
97
98
 
98
99
  let engine = useRef<RtmEngine>(null!);
@@ -181,6 +182,7 @@ const RtmConfigure = (props: any) => {
181
182
  });
182
183
  setHasUserJoinedRTM(true);
183
184
  await runQueuedEvents();
185
+ setIsInitialQueueCompleted(true);
184
186
  logger.log(
185
187
  LogSource.AgoraSDK,
186
188
  'Log',
@@ -811,6 +813,7 @@ const RtmConfigure = (props: any) => {
811
813
  return (
812
814
  <ChatContext.Provider
813
815
  value={{
816
+ isInitialQueueCompleted,
814
817
  rtmInitTimstamp,
815
818
  hasUserJoinedRTM,
816
819
  engine: engine.current,
@@ -16,6 +16,15 @@ import Error from '../../subComponents/Error';
16
16
  type ErrorType = {
17
17
  name: string;
18
18
  message: string;
19
+ networkError?: {
20
+ name?: string;
21
+ result?: {
22
+ error?: {
23
+ code?: number;
24
+ message?: string;
25
+ };
26
+ };
27
+ };
19
28
  };
20
29
  type ErrorContextType = {
21
30
  error: ErrorType | undefined;
@@ -46,12 +55,17 @@ const ErrorProvider = (props: {children: React.ReactNode}) => {
46
55
  const CommonError: React.FC = () => {
47
56
  const {error} = useContext(ErrorContext);
48
57
  useEffect(() => {
49
- if (error?.name || error?.message) {
58
+ if (
59
+ error?.networkError?.name ||
60
+ error?.networkError?.result?.error?.message ||
61
+ error?.name ||
62
+ error?.message
63
+ ) {
50
64
  Toast.show({
51
65
  leadingIconName: 'alert',
52
66
  type: 'error',
53
- text1: error.name,
54
- text2: error.message,
67
+ text1: error?.networkError?.name || error.name,
68
+ text2: error?.networkError?.result?.error?.message || error.message,
55
69
  visibilityTime: 1000 * 10,
56
70
  primaryBtn: null,
57
71
  secondaryBtn: null,
@@ -37,6 +37,7 @@ import {
37
37
  invitePopupHeading,
38
38
  } from '../../language/default-labels/videoCallScreenLabels';
39
39
  import {cancelText} from '../../language/default-labels/commonLabels';
40
+ import {logger, LogSource} from '../../logger/AppBuilderLogger';
40
41
 
41
42
  const InvitePopup = () => {
42
43
  const {setShowInvitePopup, showInvitePopup} = useVideoCall();
@@ -47,6 +48,21 @@ const InvitePopup = () => {
47
48
  const getMeeting = useGetMeetingPhrase();
48
49
  useEffect(() => {
49
50
  getMeeting(phrase).catch(error => {
51
+ logger.error(
52
+ LogSource.Internals,
53
+ 'GET_MEETING_PHRASE',
54
+ 'unable to fetch meeting details',
55
+ error,
56
+ {
57
+ networkError: {
58
+ name: error?.networkError?.name,
59
+ //@ts-ignore
60
+ code: error?.networkError?.result?.error?.code,
61
+ //@ts-ignore
62
+ message: error?.networkError?.result?.error?.message,
63
+ },
64
+ },
65
+ );
50
66
  setGlobalErrorMessage(error);
51
67
  });
52
68
  }, [phrase]);
@@ -116,6 +116,7 @@ const UserPreferenceProvider = (props: {children: React.ReactNode}) => {
116
116
  context: {
117
117
  headers: {
118
118
  'X-Request-Id': requestId,
119
+ 'X-Session-Id': logger.getSessionId(),
119
120
  },
120
121
  },
121
122
  variables: {
@@ -145,6 +146,13 @@ const UserPreferenceProvider = (props: {children: React.ReactNode}) => {
145
146
  'ERROR, could not save the name',
146
147
  error,
147
148
  {
149
+ networkError: {
150
+ name: error?.networkError?.name,
151
+ //@ts-ignore
152
+ code: error?.networkError?.result?.error?.code,
153
+ //@ts-ignore
154
+ message: error?.networkError?.result?.error?.message,
155
+ },
148
156
  startReqTs,
149
157
  endReqTs,
150
158
  latency: endReqTs - startReqTs,
@@ -160,6 +168,13 @@ const UserPreferenceProvider = (props: {children: React.ReactNode}) => {
160
168
  'ERROR, could not save the name',
161
169
  error,
162
170
  {
171
+ networkError: {
172
+ name: error?.networkError?.name,
173
+ //@ts-ignore
174
+ code: error?.networkError?.result?.error?.code,
175
+ //@ts-ignore
176
+ message: error?.networkError?.result?.error?.message,
177
+ },
163
178
  startReqTs,
164
179
  endReqTs,
165
180
  latency: endReqTs - startReqTs,
@@ -359,6 +359,7 @@ const WhiteboardToolBox = ({whiteboardRoom}) => {
359
359
  myHeaders2.append('Content-Type', 'application/json');
360
360
  myHeaders2.append('Authorization', `Bearer ${store?.token}`);
361
361
  myHeaders2.append('X-Request-Id', requestId);
362
+ myHeaders2.append('X-Session-Id', logger.getSessionId());
362
363
 
363
364
  const body = JSON.stringify({
364
365
  resource_url: url,
@@ -498,6 +499,7 @@ const WhiteboardToolBox = ({whiteboardRoom}) => {
498
499
  myHeaders2.append('Content-Type', 'application/json');
499
500
  myHeaders2.append('Authorization', `Bearer ${store?.token}`);
500
501
  myHeaders2.append('X-Request-Id', requestId);
502
+ myHeaders2.append('X-Session-Id', logger.getSessionId());
501
503
  const body = JSON.stringify({
502
504
  resource_url: url,
503
505
  });
@@ -624,6 +626,7 @@ const WhiteboardToolBox = ({whiteboardRoom}) => {
624
626
  headers: {
625
627
  authorization: store?.token ? `Bearer ${store?.token}` : '',
626
628
  'X-Request-Id': requestId,
629
+ 'X-Session-Id': logger.getSessionId(),
627
630
  },
628
631
  })
629
632
  .then(async res => {
@@ -148,6 +148,7 @@ const WhiteboardWidget = ({whiteboardRoom}) => {
148
148
  myHeaders2.append('Content-Type', 'application/json');
149
149
  myHeaders2.append('Authorization', `Bearer ${store?.token}`);
150
150
  myHeaders2.append('X-Request-Id', requestId);
151
+ myHeaders2.append('X-Session-Id', logger.getSessionId());
151
152
  const body = JSON.stringify({
152
153
  room_uuid: room_uuid,
153
154
  path: '/init',
@@ -212,6 +212,15 @@ const Create = () => {
212
212
  'CREATE_MEETING',
213
213
  'There was error while creating meeting',
214
214
  error,
215
+ {
216
+ networkError: {
217
+ name: error?.networkError?.name,
218
+ //@ts-ignore
219
+ code: error?.networkError?.result?.error?.code,
220
+ //@ts-ignore
221
+ message: error?.networkError?.result?.error?.message,
222
+ },
223
+ },
215
224
  );
216
225
  if (
217
226
  createRoomErrorToastHeadingText ||
@@ -130,6 +130,21 @@ const Join = () => {
130
130
  history.push(phrase);
131
131
  })
132
132
  .catch(error => {
133
+ logger.error(
134
+ LogSource.Internals,
135
+ 'JOIN_MEETING',
136
+ 'Error on join room page',
137
+ error,
138
+ {
139
+ networkError: {
140
+ name: error?.networkError?.name,
141
+ //@ts-ignore
142
+ code: error?.networkError?.result?.error?.code,
143
+ //@ts-ignore
144
+ message: error?.networkError?.result?.error?.message,
145
+ },
146
+ },
147
+ );
133
148
  const isInvalidUrl =
134
149
  error?.message.toLowerCase().trim() === 'invalid passphrase' || false;
135
150
  Toast.show({
@@ -150,6 +150,8 @@ const VideoCall: React.FC = () => {
150
150
  const [queryComplete, setQueryComplete] = useState(false);
151
151
  const [waitingRoomAttendeeJoined, setWaitingRoomAttendeeJoined] =
152
152
  useState(false);
153
+ const [sttAutoStarted, setSttAutoStarted] = useState(false);
154
+ const [recordingAutoStarted, setRecordingAutoStarted] = useState(false);
153
155
 
154
156
  const {phrase} = useParams<{phrase: string}>();
155
157
 
@@ -249,6 +251,21 @@ const VideoCall: React.FC = () => {
249
251
  useJoin(phrase, RoomInfoDefaultValue.roomPreference)
250
252
  .then(() => {})
251
253
  .catch(error => {
254
+ logger.error(
255
+ LogSource.Internals,
256
+ 'JOIN_MEETING',
257
+ 'Join channel error',
258
+ error,
259
+ {
260
+ networkError: {
261
+ name: error?.networkError?.name,
262
+ //@ts-ignore
263
+ code: error?.networkError?.result?.error?.code,
264
+ //@ts-ignore
265
+ message: error?.networkError?.result?.error?.message,
266
+ },
267
+ },
268
+ );
252
269
  setGlobalErrorMessage(error);
253
270
  history.push('/');
254
271
  });
@@ -287,6 +304,21 @@ const VideoCall: React.FC = () => {
287
304
  setQueryComplete(false);
288
305
  currentMeetingPhrase.current = sdkMeetingPath;
289
306
  useJoin(sdkMeetingPhrase, preference).catch(error => {
307
+ logger.error(
308
+ LogSource.Internals,
309
+ 'JOIN_MEETING',
310
+ 'Join channel error',
311
+ error,
312
+ {
313
+ networkError: {
314
+ name: error?.networkError?.name,
315
+ //@ts-ignore
316
+ code: error?.networkError?.result?.error?.code,
317
+ //@ts-ignore
318
+ message: error?.networkError?.result?.error?.message,
319
+ },
320
+ },
321
+ );
290
322
  setGlobalErrorMessage(error);
291
323
  history.push('/');
292
324
  currentMeetingPhrase.current = '';
@@ -435,6 +467,10 @@ const VideoCall: React.FC = () => {
435
467
  <CaptionProvider>
436
468
  <WaitingRoomProvider>
437
469
  <EventsConfigure
470
+ setSttAutoStarted={
471
+ setSttAutoStarted
472
+ }
473
+ sttAutoStarted={sttAutoStarted}
438
474
  callActive={callActive}>
439
475
  <ScreenshareConfigure
440
476
  isRecordingActive={
@@ -454,6 +490,8 @@ const VideoCall: React.FC = () => {
454
490
  setRecordingActive,
455
491
  isRecordingActive,
456
492
  callActive,
493
+ recordingAutoStarted,
494
+ setRecordingAutoStarted,
457
495
  }}>
458
496
  <NetworkQualityProvider>
459
497
  {!isMobileUA() && (
@@ -65,6 +65,7 @@ const useSTTAPI = (): IuseSTTAPI => {
65
65
  'Content-Type': 'application/json',
66
66
  authorization: store.token ? `Bearer ${store.token}` : '',
67
67
  'X-Request-Id': requestId,
68
+ 'X-Session-Id': logger.getSessionId(),
68
69
  },
69
70
  body: JSON.stringify({
70
71
  passphrase: roomId?.host || '',
@@ -104,6 +104,8 @@ interface RecordingProviderProps {
104
104
  setRecordingActive: React.Dispatch<SetStateAction<boolean>>;
105
105
  isRecordingActive: boolean;
106
106
  callActive: boolean;
107
+ recordingAutoStarted: boolean;
108
+ setRecordingAutoStarted: React.Dispatch<React.SetStateAction<boolean>>;
107
109
  };
108
110
  }
109
111
 
@@ -141,8 +143,13 @@ const showErrorToast = (text1: string, text2?: string) => {
141
143
  };
142
144
 
143
145
  const RecordingProvider = (props: RecordingProviderProps) => {
144
- const {setRecordingActive, isRecordingActive, callActive} = props?.value;
145
- const [autoStartCompleted, setAutoStartCompleted] = useState(false);
146
+ const {
147
+ setRecordingActive,
148
+ isRecordingActive,
149
+ callActive,
150
+ recordingAutoStarted,
151
+ setRecordingAutoStarted,
152
+ } = props?.value;
146
153
  const {
147
154
  data: {isHost, roomId},
148
155
  } = useRoomInfo();
@@ -167,7 +174,8 @@ const RecordingProvider = (props: RecordingProviderProps) => {
167
174
 
168
175
  const userlabel = useString(videoRoomUserFallbackText)();
169
176
 
170
- const {localUid, hasUserJoinedRTM} = useContext(ChatContext);
177
+ const {localUid, hasUserJoinedRTM, isInitialQueueCompleted} =
178
+ useContext(ChatContext);
171
179
  const {store} = React.useContext(StorageContext);
172
180
 
173
181
  const {setChatType} = useChatUIControls();
@@ -274,6 +282,7 @@ const RecordingProvider = (props: RecordingProviderProps) => {
274
282
  'Content-Type': 'application/json',
275
283
  authorization: store.token ? `Bearer ${store.token}` : '',
276
284
  'X-Request-Id': requestId,
285
+ 'X-Session-Id': logger.getSessionId(),
277
286
  },
278
287
  body: JSON.stringify({
279
288
  passphrase: roomId.host,
@@ -356,7 +365,19 @@ const RecordingProvider = (props: RecordingProviderProps) => {
356
365
  'recording_start',
357
366
  'Error while start recording',
358
367
  err,
359
- {startReqTs, endRequestTs, latency, requestId},
368
+ {
369
+ networkError: {
370
+ name: err?.networkError?.name,
371
+ //@ts-ignore
372
+ code: err?.networkError?.result?.error?.code,
373
+ //@ts-ignore
374
+ message: err?.networkError?.result?.error?.message,
375
+ },
376
+ startReqTs,
377
+ endRequestTs,
378
+ latency,
379
+ requestId,
380
+ },
360
381
  );
361
382
  setRecordingActive(false);
362
383
  setInProgress(false);
@@ -405,6 +426,7 @@ const RecordingProvider = (props: RecordingProviderProps) => {
405
426
  'Content-Type': 'application/json',
406
427
  authorization: store.token ? `Bearer ${store.token}` : '',
407
428
  'X-Request-Id': requestId,
429
+ 'X-Session-Id': logger.getSessionId(),
408
430
  },
409
431
  body: JSON.stringify({
410
432
  passphrase: roomId.host,
@@ -548,6 +570,7 @@ const RecordingProvider = (props: RecordingProviderProps) => {
548
570
  'Content-Type': 'application/json',
549
571
  authorization: store.token ? `Bearer ${store.token}` : '',
550
572
  'X-Request-Id': requestId,
573
+ 'X-Session-Id': logger.getSessionId(),
551
574
  },
552
575
  body: JSON.stringify({
553
576
  passphrase: roomId?.host,
@@ -826,33 +849,50 @@ const RecordingProvider = (props: RecordingProviderProps) => {
826
849
  _stopRecording,
827
850
  ]);
828
851
 
829
- //commented auto start for cloud recording
830
852
  // auto start recording
831
- // useEffect(() => {
832
- // if (
833
- // $config.CLOUD_RECORDING &&
834
- // $config.CLOUD_RECORDING_AUTO_START &&
835
- // callActive &&
836
- // !isRecordingActive &&
837
- // isHost &&
838
- // hasUserJoinedRTM &&
839
- // !autoStartCompleted
840
- // ) {
841
- // logger.log(
842
- // LogSource.Internals,
843
- // 'RECORDING',
844
- // 'CLOUD_RECORDING_AUTO_START triggered',
845
- // );
846
- // startRecording();
847
- // setAutoStartCompleted(true);
848
- // }
849
- // }, [
850
- // isRecordingActive,
851
- // isHost,
852
- // callActive,
853
- // hasUserJoinedRTM,
854
- // autoStartCompleted,
855
- // ]);
853
+ useEffect(() => {
854
+ if (
855
+ $config.CLOUD_RECORDING &&
856
+ $config.CLOUD_RECORDING_AUTO_START &&
857
+ callActive &&
858
+ hasUserJoinedRTM &&
859
+ isInitialQueueCompleted &&
860
+ isHost &&
861
+ roomId?.host &&
862
+ !isRecordingBot &&
863
+ !recordingAutoStarted
864
+ ) {
865
+ if (!isRecordingActive) {
866
+ logger.log(
867
+ LogSource.Internals,
868
+ 'RECORDING',
869
+ 'CLOUD_RECORDING_AUTO_START triggered',
870
+ {
871
+ uidWhoTriggered: localUid,
872
+ },
873
+ );
874
+ startRecording();
875
+ setRecordingAutoStarted(true);
876
+ } else {
877
+ logger.log(
878
+ LogSource.Internals,
879
+ 'RECORDING',
880
+ 'CLOUD_RECORDING_AUTO_START already triggered by some other host',
881
+ );
882
+ setRecordingAutoStarted(true);
883
+ }
884
+ }
885
+ }, [
886
+ callActive,
887
+ hasUserJoinedRTM,
888
+ isInitialQueueCompleted,
889
+ isHost,
890
+ isRecordingBot,
891
+ isRecordingActive,
892
+ recordingAutoStarted,
893
+ localUid,
894
+ roomId,
895
+ ]);
856
896
 
857
897
  // useEffect(() => { //
858
898
  // if (hasUserJoinedRTM && isRecordingBot) {
@@ -3,6 +3,8 @@ import {useParams} from '../../components/Router';
3
3
 
4
4
  import {gql, useMutation} from '@apollo/client';
5
5
  import {UidType} from '../../../agora-rn-uikit';
6
+ import {logger, LogSource} from '../../logger/AppBuilderLogger';
7
+ import getUniqueID from '../../utils/getUniqueID';
6
8
 
7
9
  const SET_PRESENTER = gql`
8
10
  mutation setPresenter($uid: Int!, $passphrase: String!) {
@@ -29,25 +31,88 @@ function useRecordingLayoutQuery() {
29
31
  * https://docs.agora.io/en/cloud-recording/cloud_recording_layout?platform=RESTful
30
32
  */
31
33
  const executePresenterQuery = (screenShareUid: UidType) => {
34
+ const requestId = getUniqueID();
35
+ const startReqTs = Date.now();
32
36
  setPresenterQuery({
33
37
  variables: {
34
38
  uid: screenShareUid,
35
39
  passphrase: phrase,
36
40
  },
41
+ context: {
42
+ headers: {
43
+ 'X-Request-Id': requestId,
44
+ 'X-Session-Id': logger.getSessionId(),
45
+ },
46
+ },
37
47
  })
38
- .then((res) => {
39
- if (res.data.setPresenter === 'success') {
48
+ .then(res => {
49
+ if (res?.data?.setPresenter === 'success') {
50
+ const endReqTs = Date.now();
51
+ logger.log(
52
+ LogSource.Internals,
53
+ 'RECORDING',
54
+ 'setPresenterQuery success',
55
+ {
56
+ responseData: res,
57
+ startReqTs,
58
+ endReqTs,
59
+ latency: endReqTs - startReqTs,
60
+ requestId,
61
+ },
62
+ );
40
63
  }
41
64
  })
42
- .catch((err) => {
43
- console.log(err);
65
+ .catch(error => {
66
+ const endReqTs = Date.now();
67
+ logger.error(
68
+ LogSource.Internals,
69
+ 'RECORDING',
70
+ 'setPresenterQuery failure',
71
+ error,
72
+ {
73
+ networkError: {
74
+ name: error?.networkError?.name,
75
+ //@ts-ignore
76
+ code: error?.networkError?.result?.error?.code,
77
+ //@ts-ignore
78
+ message: error?.networkError?.result?.error?.message,
79
+ },
80
+ startReqTs,
81
+ endReqTs,
82
+ latency: endReqTs - startReqTs,
83
+ requestId,
84
+ },
85
+ );
44
86
  });
45
87
  };
46
88
 
47
89
  const executeNormalQuery = () => {
48
- setNormalQuery({variables: {passphrase: phrase}})
49
- .then((res) => {
50
- if (res.data.stopRecordingSession === 'success') {
90
+ const requestId = getUniqueID();
91
+ const startReqTs = Date.now();
92
+ setNormalQuery({
93
+ variables: {passphrase: phrase},
94
+ context: {
95
+ headers: {
96
+ 'X-Request-Id': requestId,
97
+ 'X-Session-Id': logger.getSessionId(),
98
+ },
99
+ },
100
+ })
101
+ .then(res => {
102
+ if (res?.data?.stopRecordingSession === 'success') {
103
+ const endReqTs = Date.now();
104
+ logger.log(
105
+ LogSource.Internals,
106
+ 'RECORDING',
107
+ 'executeNormalQuery success',
108
+ {
109
+ responseData: res,
110
+ startReqTs,
111
+ endReqTs,
112
+ latency: endReqTs - startReqTs,
113
+ requestId,
114
+ },
115
+ );
51
116
  // Once the backend sucessfuly stops recording,
52
117
  // send a control message to everbody in the channel indicating that cloud recording is now inactive.
53
118
  // sendControlMessage(controlMessageEnum.cloudRecordingUnactive);
@@ -55,8 +120,27 @@ function useRecordingLayoutQuery() {
55
120
  // setScreenshareActive(false);
56
121
  }
57
122
  })
58
- .catch((err) => {
59
- console.log(err);
123
+ .catch(error => {
124
+ const endReqTs = Date.now();
125
+ logger.error(
126
+ LogSource.Internals,
127
+ 'RECORDING',
128
+ 'executeNormalQuery failure',
129
+ error,
130
+ {
131
+ networkError: {
132
+ name: error?.networkError?.name,
133
+ //@ts-ignore
134
+ code: error?.networkError?.result?.error?.code,
135
+ //@ts-ignore
136
+ message: error?.networkError?.result?.error?.message,
137
+ },
138
+ startReqTs,
139
+ endReqTs,
140
+ latency: endReqTs - startReqTs,
141
+ requestId,
142
+ },
143
+ );
60
144
  });
61
145
  };
62
146
 
@@ -43,6 +43,7 @@ const useWaitingRoomAPI = (): IuseWaitingRoomAPI => {
43
43
  'Content-Type': 'application/json',
44
44
  authorization: store.token ? `Bearer ${store.token}` : '',
45
45
  'X-Request-Id': requestId,
46
+ 'X-Session-Id': logger.getSessionId(),
46
47
  },
47
48
  body: payload,
48
49
  });
@@ -17,11 +17,6 @@ import {
17
17
  import Platform from '../subComponents/Platform';
18
18
  import * as ReactIs from 'react-is';
19
19
 
20
- const getSessionId = () => {
21
- const {logger} = require('../logger/AppBuilderLogger');
22
- return logger.getSessionId();
23
- };
24
-
25
20
  const trimText = (text: string, length: number = 25) => {
26
21
  if (!text) {
27
22
  return '';
@@ -386,7 +381,6 @@ function MergeMoreButtonFields(sourceArray, updateObject) {
386
381
  }
387
382
 
388
383
  export {
389
- getSessionId,
390
384
  updateToolbarDefaultConfig,
391
385
  useIsDesktop,
392
386
  useIsSmall,
@@ -56,6 +56,7 @@ export default function useCreateRoom(): createRoomFun {
56
56
  context: {
57
57
  headers: {
58
58
  'X-Request-Id': requestId,
59
+ 'X-Session-Id': logger.getSessionId(),
59
60
  },
60
61
  },
61
62
  variables: {
@@ -75,7 +76,19 @@ export default function useCreateRoom(): createRoomFun {
75
76
  'createChannel',
76
77
  'API createChannel failed. There was an error',
77
78
  error,
78
- {startReqTs, endReqTs, latency: latency, requestId},
79
+ {
80
+ networkError: {
81
+ name: error?.networkError?.name,
82
+ //@ts-ignore
83
+ code: error?.networkError?.result?.error?.code,
84
+ //@ts-ignore
85
+ message: error?.networkError?.result?.error?.message,
86
+ },
87
+ startReqTs,
88
+ endReqTs,
89
+ latency: latency,
90
+ requestId,
91
+ },
79
92
  );
80
93
  throw error;
81
94
  }
@@ -42,6 +42,7 @@ export default function useGetMeetingPhrase() {
42
42
  context: {
43
43
  headers: {
44
44
  'X-Request-Id': requestId,
45
+ 'X-Session-Id': logger.getSessionId(),
45
46
  },
46
47
  },
47
48
  query: SHARE,
@@ -57,6 +58,13 @@ export default function useGetMeetingPhrase() {
57
58
  'Query GET_MEETING_PHRASE failed',
58
59
  response.error,
59
60
  {
61
+ networkError: {
62
+ name: response?.error?.networkError?.name,
63
+ //@ts-ignore
64
+ code: response?.error?.networkError?.result?.error?.code,
65
+ //@ts-ignore
66
+ message: response?.error?.networkError?.result?.error?.message,
67
+ },
60
68
  requestId,
61
69
  startReqTs,
62
70
  endReqTs,
@@ -128,6 +128,7 @@ export default function useJoinRoom() {
128
128
  context: {
129
129
  headers: {
130
130
  'X-Request-Id': requestId,
131
+ 'X-Session-Id': logger.getSessionId(),
131
132
  },
132
133
  },
133
134
  query:
@@ -149,8 +150,16 @@ export default function useJoinRoom() {
149
150
  `API ${
150
151
  isWaitingRoomEnabled ? 'channel_join_request' : 'joinChannel'
151
152
  } failed.`,
153
+ 'Join Channel Failed',
152
154
  response?.error,
153
155
  {
156
+ networkError: {
157
+ name: response?.error?.networkError?.name,
158
+ //@ts-ignore
159
+ code: response?.error?.networkError?.result?.error?.code,
160
+ //@ts-ignore
161
+ message: response?.error?.networkError?.result?.error?.message,
162
+ },
154
163
  startReqTs,
155
164
  endReqTs,
156
165
  latency,
@@ -34,6 +34,7 @@ const useMutePSTN = () => {
34
34
  context: {
35
35
  headers: {
36
36
  'X-Request-Id': requestId,
37
+ 'X-Session-Id': logger.getSessionId(),
37
38
  },
38
39
  },
39
40
  variables: {
@@ -53,7 +54,19 @@ const useMutePSTN = () => {
53
54
  'MUTE_PSTN',
54
55
  'Mutation MUTE_PSTN success',
55
56
  error,
56
- {startReqTs, endReqTs, latency: endReqTs - startReqTs, requestId},
57
+ {
58
+ networkError: {
59
+ name: error?.networkError?.name,
60
+ //@ts-ignore
61
+ code: error?.networkError?.result?.error?.code,
62
+ //@ts-ignore
63
+ message: error?.networkError?.result?.error?.message,
64
+ },
65
+ startReqTs,
66
+ endReqTs,
67
+ latency: endReqTs - startReqTs,
68
+ requestId,
69
+ },
57
70
  );
58
71
  throw error;
59
72
  } else {