agora-appbuilder-core 4.0.7 → 4.0.8-beta-01

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 (89) hide show
  1. package/package.json +1 -1
  2. package/template/_package-lock.json +82 -0
  3. package/template/android/app/build.gradle +8 -0
  4. package/template/android/build.gradle +3 -0
  5. package/template/bridge/rtc/webNg/RtcEngine.ts +581 -31
  6. package/template/bridge/rtc/webNg/RtcSurfaceView.tsx +2 -1
  7. package/template/bridge/rtm/web/index.ts +2 -1
  8. package/template/customization-api/customize.ts +29 -10
  9. package/template/customization-api/sub-components.ts +2 -3
  10. package/template/customization-api/types.ts +1 -2
  11. package/template/index.js +17 -1
  12. package/template/index.web.js +2 -2
  13. package/template/package.json +3 -0
  14. package/template/src/SDKAppWrapper.tsx +44 -2
  15. package/template/src/app-state/useNoiseSupression.native.tsx +6 -0
  16. package/template/src/app-state/useNoiseSupression.tsx +17 -0
  17. package/template/src/auth/AuthProvider.tsx +145 -8
  18. package/template/src/auth/IDPAuth.electron.tsx +2 -1
  19. package/template/src/auth/IDPAuth.tsx +8 -2
  20. package/template/src/auth/openIDPURL.native.tsx +14 -3
  21. package/template/src/auth/useTokenAuth.tsx +7 -1
  22. package/template/src/components/Controls.tsx +6 -3
  23. package/template/src/components/DeviceConfigure.tsx +67 -17
  24. package/template/src/components/EventsConfigure.tsx +2 -2
  25. package/template/src/components/Precall.tsx +21 -0
  26. package/template/src/components/RTMConfigure.tsx +188 -24
  27. package/template/src/components/SettingsView.tsx +2 -0
  28. package/template/src/components/Share.tsx +11 -0
  29. package/template/src/components/StorageContext.tsx +32 -2
  30. package/template/src/components/chat-messages/useChatMessages.tsx +65 -5
  31. package/template/src/components/contexts/WaitingRoomContext.tsx +5 -1
  32. package/template/src/components/livestream/LiveStreamContext.tsx +2 -2
  33. package/template/src/components/participants/UserActionMenuOptions.tsx +2 -2
  34. package/template/src/components/popups/StartScreenSharePopup.native.tsx +2 -2
  35. package/template/src/components/popups/StopScreenSharePopup.native.tsx +2 -2
  36. package/template/src/components/precall/joinCallBtn.tsx +6 -0
  37. package/template/src/components/precall/usePreCall.tsx +18 -2
  38. package/template/src/components/room-info/useRoomInfo.tsx +28 -25
  39. package/template/src/components/useUserPreference.tsx +13 -2
  40. package/template/src/components/useWakeLock.tsx +18 -4
  41. package/template/src/components/virtual-background/VBCard.tsx +40 -1
  42. package/template/src/components/virtual-background/VButils.native.ts +24 -5
  43. package/template/src/components/virtual-background/VButils.ts +29 -5
  44. package/template/src/components/virtual-background/VideoPreview.tsx +11 -1
  45. package/template/src/components/virtual-background/useVB.native.tsx +19 -3
  46. package/template/src/components/whiteboard/WhiteboardConfigure.tsx +32 -5
  47. package/template/src/components/whiteboard/WhiteboardToolBox.tsx +38 -8
  48. package/template/src/components/whiteboard/WhiteboardView.native.tsx +37 -13
  49. package/template/src/language/useLanguage.tsx +10 -4
  50. package/template/src/logger/AppBuilderLogger.tsx +215 -0
  51. package/template/src/logger/constants.ts +18 -0
  52. package/template/src/logger/transports/agora-transport.native.ts +58 -0
  53. package/template/src/logger/transports/agora-transport.ts +28 -0
  54. package/template/src/logger/transports/customer-transport.ts +115 -0
  55. package/template/src/pages/Create.tsx +27 -2
  56. package/template/src/pages/Endcall.tsx +6 -1
  57. package/template/src/pages/Join.tsx +31 -4
  58. package/template/src/pages/VideoCall.tsx +20 -56
  59. package/template/src/pages/video-call/DefaultLayouts.ts +11 -3
  60. package/template/src/pages/video-call/SidePanelHeader.tsx +12 -2
  61. package/template/src/pages/video-call/VideoCallScreen.tsx +8 -0
  62. package/template/src/pages/video-call/VideoRenderer.tsx +7 -1
  63. package/template/src/rtm/RTMEngine.ts +5 -0
  64. package/template/src/rtm-events-api/Events.ts +70 -16
  65. package/template/src/subComponents/LayoutIconDropdown.tsx +6 -0
  66. package/template/src/subComponents/LocalAudioMute.tsx +13 -3
  67. package/template/src/subComponents/LocalEndCall.tsx +10 -5
  68. package/template/src/subComponents/LocalVideoMute.tsx +15 -1
  69. package/template/src/subComponents/ScreenShareNotice.tsx +2 -2
  70. package/template/src/subComponents/SelectDevice.tsx +111 -3
  71. package/template/src/subComponents/caption/CaptionContainer.tsx +17 -2
  72. package/template/src/subComponents/caption/useSTTAPI.tsx +62 -20
  73. package/template/src/subComponents/caption/useTranscriptDownload.native.ts +35 -5
  74. package/template/src/subComponents/caption/useTranscriptDownload.ts +12 -2
  75. package/template/src/subComponents/chat/ChatParticipants.tsx +6 -0
  76. package/template/src/subComponents/recording/useRecording.tsx +102 -15
  77. package/template/src/subComponents/screenshare/ScreenshareButton.tsx +3 -3
  78. package/template/src/subComponents/screenshare/ScreenshareConfigure.native.tsx +37 -6
  79. package/template/src/subComponents/screenshare/ScreenshareConfigure.tsx +22 -6
  80. package/template/src/subComponents/screenshare/useScreenshare.tsx +4 -4
  81. package/template/src/subComponents/waiting-rooms/useWaitingRoomAPI.ts +26 -0
  82. package/template/src/utils/axiomLogger.ts +2 -1
  83. package/template/src/utils/useCreateRoom.ts +30 -0
  84. package/template/src/utils/useFindActiveSpeaker.ts +43 -0
  85. package/template/src/utils/useFocus.tsx +8 -3
  86. package/template/src/utils/useIsLocalUserSpeaking.ts +19 -3
  87. package/template/src/utils/useJoinRoom.ts +27 -0
  88. package/template/src/utils/useLayout.tsx +9 -3
  89. package/template/src/utils/useSidePanel.tsx +14 -3
@@ -41,6 +41,7 @@ import {
41
41
  whiteboardToolboxUploadText,
42
42
  whiteboardToolboxWidthLabel,
43
43
  } from '../../language/default-labels/videoCallScreenLabels';
44
+ import {LogSource, logger} from '../../logger/AppBuilderLogger';
44
45
 
45
46
  const supportedDocTypes = [
46
47
  'application/msword',
@@ -336,13 +337,23 @@ const WhiteboardToolBox = ({whiteboardRoom}) => {
336
337
  body: body,
337
338
  })
338
339
  .then(res2 => {
339
- console.log('debugging file convert success', res2);
340
+ logger.debug(
341
+ LogSource.NetworkRest,
342
+ 'whiteboard_fileconvert',
343
+ 'file convert success',
344
+ res2,
345
+ );
340
346
  //updating upload flag as true
341
347
  //once we got RTM message we will proceed to insert image into whiteboard
342
348
  setUploadRef();
343
349
  })
344
350
  .catch(err2 => {
345
- console.log('debugging file convert failed', err2);
351
+ logger.error(
352
+ LogSource.NetworkRest,
353
+ 'whiteboard_fileconvert',
354
+ 'file convert failed',
355
+ err2,
356
+ );
346
357
  Toast.show({
347
358
  type: 'error',
348
359
  text1: whiteboardFileUploadErrorToastHeadingTT('File'),
@@ -358,7 +369,7 @@ const WhiteboardToolBox = ({whiteboardRoom}) => {
358
369
  });
359
370
  });
360
371
  } else {
361
- console.log('debugging upload url is empty');
372
+ logger.debug(LogSource.Internals, 'WHITEBOARD', 'upload url is empty');
362
373
  Toast.show({
363
374
  type: 'error',
364
375
  text1: whiteboardFileUploadErrorToastHeadingTT('File'),
@@ -401,10 +412,20 @@ const WhiteboardToolBox = ({whiteboardRoom}) => {
401
412
  const imageUrl = jsonData?.url?.replaceAll('\u0026', '&');
402
413
  insertImageIntoWhiteboard(imageUrl);
403
414
  }
404
- console.log('debugging image upload success', res2);
415
+ logger.debug(
416
+ LogSource.NetworkRest,
417
+ 'whiteboard_image',
418
+ 'image upload success',
419
+ res2,
420
+ );
405
421
  })
406
422
  .catch(err2 => {
407
- console.log('debugging error get image url', err2);
423
+ logger.error(
424
+ LogSource.NetworkRest,
425
+ 'whiteboard_image',
426
+ 'Failed to get image URL',
427
+ err2,
428
+ );
408
429
  Toast.show({
409
430
  type: 'error',
410
431
  text1: whiteboardFileUploadErrorToastHeadingTT('Image'),
@@ -420,7 +441,11 @@ const WhiteboardToolBox = ({whiteboardRoom}) => {
420
441
  });
421
442
  });
422
443
  } else {
423
- console.log('debugging image upload url is empty');
444
+ logger.debug(
445
+ LogSource.Internals,
446
+ 'WHITEBOARD',
447
+ 'image upload url is empty',
448
+ );
424
449
  Toast.show({
425
450
  type: 'error',
426
451
  text1: whiteboardFileUploadErrorToastHeadingTT('Image'),
@@ -469,7 +494,12 @@ const WhiteboardToolBox = ({whiteboardRoom}) => {
469
494
  }
470
495
  })
471
496
  .catch(err => {
472
- console.log('debugging upload api failed', err);
497
+ logger.error(
498
+ LogSource.NetworkRest,
499
+ 'whiteboard_upload',
500
+ 'upload api failed',
501
+ err,
502
+ );
473
503
  Toast.show({
474
504
  type: 'error',
475
505
  text1: whiteboardFileUploadErrorToastHeadingTT('File'),
@@ -477,7 +507,7 @@ const WhiteboardToolBox = ({whiteboardRoom}) => {
477
507
  });
478
508
  });
479
509
  } else {
480
- console.log('debugging unsupported file');
510
+ logger.error(LogSource.Internals, 'WHITEBOARD', 'unsupported file');
481
511
  Toast.show({
482
512
  type: 'error',
483
513
  text1: whiteboardFileUploadTypeErrorToastHeadingTT,
@@ -1,12 +1,12 @@
1
1
  /*
2
2
  ********************************************
3
3
  Copyright © 2021 Agora Lab, Inc., all rights reserved.
4
- AppBuilder and all associated components, source code, APIs, services, and documentation
5
- (the “Materials”) are owned by Agora Lab, Inc. and its licensors. The Materials may not be
6
- accessed, used, modified, or distributed for any purpose without a license from Agora Lab, Inc.
7
- Use without a license or in violation of any license terms and conditions (including use for
8
- any purpose competitive to Agora Lab, Inc.’s business) is strictly prohibited. For more
9
- information visit https://appbuilder.agora.io.
4
+ AppBuilder and all associated components, source code, APIs, services, and documentation
5
+ (the “Materials”) are owned by Agora Lab, Inc. and its licensors. The Materials may not be
6
+ accessed, used, modified, or distributed for any purpose without a license from Agora Lab, Inc.
7
+ Use without a license or in violation of any license terms and conditions (including use for
8
+ any purpose competitive to Agora Lab, Inc.’s business) is strictly prohibited. For more
9
+ information visit https://appbuilder.agora.io.
10
10
  *********************************************
11
11
  */
12
12
 
@@ -19,6 +19,7 @@ import {
19
19
  RoomCallbackHandler,
20
20
  } from '@netless/react-native-whiteboard';
21
21
  import WhiteboardWidget from './WhiteboardWidget';
22
+ import {LogSource, logger} from '../../logger/AppBuilderLogger';
22
23
  import {
23
24
  whiteboardInitializingText,
24
25
  whiteboardNativeInfoToastHeading,
@@ -68,14 +69,24 @@ const WhiteboardView: React.FC<WhiteboardViewInterface> = () => {
68
69
 
69
70
  const roomCallbacks: Partial<RoomCallbackHandler> = {
70
71
  onPhaseChanged: e => {
71
- console.log('debugging onPhaseChanged changed: ', e);
72
- setIsLoading(false);
72
+ logger.debug(
73
+ LogSource.Internals,
74
+ 'WHITEBOARD',
75
+ 'onPhaseChanged changed:',
76
+ e,
77
+ ),
78
+ setIsLoading(false);
73
79
  },
74
80
  // onRoomStateChanged: e =>
75
81
  // console.log('debugging onRoomStateChanged changed: ', e),
76
82
  onDisconnectWithError: e => {
77
- console.log('debugging onDisconnectWithError: ', e);
78
- setIsLoading(false);
83
+ logger.debug(
84
+ LogSource.Internals,
85
+ 'WHITEBOARD',
86
+ 'onDisconnectWithError:',
87
+ e,
88
+ ),
89
+ setIsLoading(false);
79
90
  },
80
91
  };
81
92
 
@@ -90,15 +101,28 @@ const WhiteboardView: React.FC<WhiteboardViewInterface> = () => {
90
101
  roomRef.current = aRoom;
91
102
  sdkRef.current = aSdk;
92
103
 
93
- console.log('debugging aRoom', aRoom);
104
+ logger.debug(LogSource.Internals, 'WHITEBOARD', 'debugging aRoom:', {
105
+ data: aRoom,
106
+ });
107
+
94
108
  setIsLoading(false);
95
109
  if (error) {
96
- console.log(error);
110
+ logger.error(
111
+ LogSource.Internals,
112
+ 'WHITEBOARD',
113
+ 'joinRoomCallback error:',
114
+ error,
115
+ );
97
116
  } else {
98
117
  try {
99
118
  //aRoom.setMemberState({currentApplianceName: 'hand'});
100
119
  } catch (error2) {
101
- console.log('debugging error on whiteboard setMemberState');
120
+ logger.error(
121
+ LogSource.Internals,
122
+ 'WHITEBOARD',
123
+ 'error on whiteboard setMemberState',
124
+ error,
125
+ );
102
126
  }
103
127
  }
104
128
  };
@@ -13,6 +13,7 @@ import React, {createContext, useContext, useEffect, useState} from 'react';
13
13
  import {createHook, useCustomization} from 'customization-implementation';
14
14
  import {DEFAULT_I18_DATA} from './index';
15
15
  import StorageContext from '../components/StorageContext';
16
+ import {LogSource, logger} from '../logger/AppBuilderLogger';
16
17
 
17
18
  export interface LanguageContextInterface {
18
19
  languageCode: string;
@@ -30,13 +31,13 @@ const LanguageContext = createContext<LanguageContextInterface>({
30
31
 
31
32
  const LanguageProvider = (props: LanguagePropsInterface) => {
32
33
  const {store, setStore} = useContext(StorageContext);
33
- const i18nData = useCustomization((data) => data?.i18n);
34
+ const i18nData = useCustomization(data => data?.i18n);
34
35
 
35
36
  //If language code is stored in the localstorage no longer available in fpe data
36
37
  //then we will update the localstorage value to default value
37
38
  let storedCode =
38
39
  i18nData && Array.isArray(i18nData) && i18nData.length
39
- ? i18nData?.find((item) => item.locale === store.selectedLanguageCode)
40
+ ? i18nData?.find(item => item.locale === store.selectedLanguageCode)
40
41
  ? store.selectedLanguageCode
41
42
  : undefined
42
43
  : undefined;
@@ -51,7 +52,7 @@ const LanguageProvider = (props: LanguagePropsInterface) => {
51
52
 
52
53
  useEffect(() => {
53
54
  if (setStore) {
54
- setStore((prevState) => {
55
+ setStore(prevState => {
55
56
  return {
56
57
  ...prevState,
57
58
  selectedLanguageCode: languageCode,
@@ -63,7 +64,7 @@ const LanguageProvider = (props: LanguagePropsInterface) => {
63
64
  useEffect(() => {
64
65
  let storedCode =
65
66
  i18nData && Array.isArray(i18nData) && i18nData.length
66
- ? i18nData?.find((item) => item.locale === store.selectedLanguageCode)
67
+ ? i18nData?.find(item => item.locale === store.selectedLanguageCode)
67
68
  ? store.selectedLanguageCode
68
69
  : undefined
69
70
  : undefined;
@@ -77,6 +78,11 @@ const LanguageProvider = (props: LanguagePropsInterface) => {
77
78
  }, [i18nData]);
78
79
 
79
80
  const setLanguageCode = (langCode: string) => {
81
+ logger.log(
82
+ LogSource.Internals,
83
+ 'LANGUAGE',
84
+ `Language selected ${langCode}`,
85
+ );
80
86
  setLanguageCodeLocal(langCode);
81
87
  };
82
88
 
@@ -0,0 +1,215 @@
1
+ import 'react-native-get-random-values';
2
+ import {nanoid} from 'nanoid';
3
+ import pkg from '../../package.json';
4
+ import {isWeb} from '../utils/common';
5
+ import {
6
+ ENABLE_AGORA_LOGGER_TRANSPORT,
7
+ ENABLE_BROWSER_CONSOLE_LOGS,
8
+ ENABLE_CUSTOMER_LOGGER_TRANSPORT,
9
+ } from './constants';
10
+ import {
11
+ getTransportLogger,
12
+ initTransportLayerForAgora,
13
+ } from './transports/agora-transport';
14
+ import configJSON from '../../config.json';
15
+ import {getPlatformId} from '../auth/config';
16
+ import {initTransportLayerForCustomers} from './transports/customer-transport';
17
+
18
+ const cli_version = 'test';
19
+
20
+ export declare const StatusTypes: {
21
+ readonly debug: 'debug';
22
+ readonly error: 'error';
23
+ readonly info: 'info';
24
+ readonly warn: 'warn';
25
+ };
26
+
27
+ export type StatusType = (typeof StatusTypes)[keyof typeof StatusTypes];
28
+
29
+ export enum LogSource {
30
+ AgoraSDK = 'Agora-SDK',
31
+ /** Logs related to all features */
32
+ Internals = 'Internals',
33
+ /** Logs related to REST API calls */
34
+ NetworkRest = 'Network-REST',
35
+ /** Logs related to Events */
36
+ Events = 'Events',
37
+ /** Logs related to Customization API */
38
+ CustomizationAPI = 'Customization',
39
+ /** Logs related to SDK */
40
+ SDK = 'SDK',
41
+ }
42
+
43
+ type LogType = {
44
+ [LogSource.AgoraSDK]: 'Log' | 'API' | 'Event' | 'Service';
45
+ [LogSource.Internals]:
46
+ | 'AUTH'
47
+ | 'CREATE_MEETING'
48
+ | 'ENTER_MEETING_ROOM'
49
+ | 'JOIN_MEETING'
50
+ | 'PRECALL_SCREEN'
51
+ | 'DEVICE_CONFIGURE'
52
+ | 'LOCAL_MUTE'
53
+ | 'VIRTUAL_BACKGROUND'
54
+ | 'VIDEO_CALL_ROOM'
55
+ | 'LANGUAGE'
56
+ | 'CONTROLS'
57
+ | 'CHAT'
58
+ | 'NAME'
59
+ | 'STT'
60
+ | 'SCREENSHARE'
61
+ | 'WHITEBOARD'
62
+ | 'LAYOUT'
63
+ | 'TRANSCRIPT'
64
+ | 'NOISE_CANCELLATION'
65
+ | 'ACTIVE_SPEAKER'
66
+ | 'WAITING_ROOM'
67
+ | 'RECORDING'
68
+ | 'STORE';
69
+ [LogSource.NetworkRest]:
70
+ | 'idp_login'
71
+ | 'token_login'
72
+ | 'unauth_login'
73
+ | 'idp_logout'
74
+ | 'token_logout'
75
+ | 'user_details'
76
+ | 'createChannel'
77
+ | 'joinChannel'
78
+ | 'channel_join_request'
79
+ | 'channel_join_approval'
80
+ | 'stt'
81
+ | 'whiteboard_image'
82
+ | 'whiteboard_upload'
83
+ | 'whiteboard_fileconvert'
84
+ | 'recording_start'
85
+ | 'recording_stop'
86
+ | 'recordings_get';
87
+ [LogSource.Events]: 'CUSTOM_EVENTS' | 'RTM_EVENTS';
88
+ [LogSource.CustomizationAPI]: 'Log';
89
+ [LogSource.SDK]: 'Log' | 'Event';
90
+ };
91
+
92
+ /** Log levels */
93
+ export type LogLevel = 'log' | 'warn' | 'error' | 'info';
94
+
95
+ /** Signature of a logging function */
96
+ type LogFn = <T extends LogSource>(
97
+ source: T,
98
+ type: LogType[T],
99
+ logMessage: string,
100
+ ...data: any[]
101
+ ) => void;
102
+
103
+ // const NO_OP: LogFn = (message?: any, ...optionalParams: any[]) => {};
104
+
105
+ /** Basic logger interface */
106
+ export interface Logger {
107
+ log: LogFn;
108
+ warn: LogFn;
109
+ error: LogFn;
110
+ info: LogFn;
111
+ debug: LogFn;
112
+ }
113
+ /** Logger which outputs to the browser console */
114
+ export default class AppBuilderLogger implements Logger {
115
+ log: LogFn;
116
+ info: LogFn;
117
+ warn: LogFn;
118
+ debug: LogFn;
119
+ error: LogFn;
120
+
121
+ constructor(_transportLogger?: any) {
122
+ const session = nanoid();
123
+ const platform = getPlatformId();
124
+ const rtmPkg = isWeb()
125
+ ? pkg.dependencies['agora-rtm-sdk']
126
+ : pkg.dependencies['agora-react-native-rtm'];
127
+ const rtcPkg = isWeb()
128
+ ? pkg.dependencies['agora-rtc-sdk-ng']
129
+ : pkg.dependencies['react-native-agora'];
130
+ const logger =
131
+ (status: StatusType) =>
132
+ <T extends LogSource>(
133
+ source: T,
134
+ type: LogType[T],
135
+ logMessage: string,
136
+ ...data: any[]
137
+ ) => {
138
+ if (!$config.LOG_ENABLED) {
139
+ return;
140
+ }
141
+
142
+ const context = {
143
+ timestamp: Date.now(),
144
+ source,
145
+ version: cli_version,
146
+ type,
147
+ data,
148
+ platform,
149
+ contextInfo: {
150
+ session_id: session,
151
+ app_id: $config.APP_ID,
152
+ project_id: $config.PROJECT_ID,
153
+ agora_sdk_version: {
154
+ rtm: rtmPkg,
155
+ rtc: rtcPkg,
156
+ },
157
+ },
158
+ };
159
+
160
+ if (
161
+ (ENABLE_AGORA_LOGGER_TRANSPORT || ENABLE_CUSTOMER_LOGGER_TRANSPORT) &&
162
+ _transportLogger
163
+ ) {
164
+ try {
165
+ _transportLogger(logMessage, context, status);
166
+ } catch (error) {
167
+ console.log(
168
+ `error occured whhile trasnporting log for project : ${$config.PROJECT_ID}`,
169
+ error,
170
+ );
171
+ }
172
+ }
173
+ if (ENABLE_BROWSER_CONSOLE_LOGS || status === 'debug') {
174
+ const consoleHeader = `%cApp-Builder: ${source}:[${type}] `;
175
+ const consoleCSS = 'color: violet; font-weight: bold';
176
+
177
+ console[status](
178
+ consoleHeader,
179
+ consoleCSS,
180
+ logMessage,
181
+ context,
182
+ status,
183
+ );
184
+ }
185
+ };
186
+
187
+ this.log = logger('info');
188
+ this.info = logger('info');
189
+ this.debug = logger('debug');
190
+ this.warn = logger('warn');
191
+ this.error = logger('error');
192
+
193
+ this.debug(
194
+ LogSource.Internals,
195
+ 'AUTH',
196
+ 'App intitialized with config.json',
197
+ {
198
+ config: configJSON,
199
+ },
200
+ );
201
+ }
202
+ }
203
+
204
+ let _transportLogger = null;
205
+
206
+ if (ENABLE_AGORA_LOGGER_TRANSPORT) {
207
+ initTransportLayerForAgora();
208
+ _transportLogger = getTransportLogger();
209
+ }
210
+
211
+ if (ENABLE_CUSTOMER_LOGGER_TRANSPORT) {
212
+ _transportLogger = initTransportLayerForCustomers();
213
+ }
214
+
215
+ export const logger = new AppBuilderLogger(_transportLogger);
@@ -0,0 +1,18 @@
1
+ const CONFERENCING_APP_ID = 'b8c2ef0f986541a8992451c07d30fb4b';
2
+ const CONFERENCING_PROJECT_ID = '8d2b1a60e4e0e95ac455';
3
+ const isInternalApp =
4
+ $config.APP_ID === CONFERENCING_APP_ID &&
5
+ $config.PROJECT_ID === CONFERENCING_PROJECT_ID;
6
+ // Send logs to configured transport-> Datadog (used for internal app - www.confercning.agora.io)
7
+ // Use the app id strict check to keep this true
8
+ export const ENABLE_AGORA_LOGGER_TRANSPORT =
9
+ $config.LOG_ENABLED && isInternalApp;
10
+ // $config.LOG_ENABLED && $config.APP_ID === CONFERENCING_APP_ID && true;
11
+
12
+ // Send logs to configured transport-> axiom (used for customer deployed apps)
13
+ export const ENABLE_CUSTOMER_LOGGER_TRANSPORT = false;
14
+ // $config.LOG_ENABLED && !isInternalApp;
15
+
16
+ // Print logs to browser console window - true in dev mode
17
+ export const ENABLE_BROWSER_CONSOLE_LOGS = $config.LOG_ENABLED;
18
+ // && process.env.NODE_ENV === 'development';
@@ -0,0 +1,58 @@
1
+ import {StatusType} from '@datadog/browser-logs';
2
+ import {
3
+ BatchSize,
4
+ DatadogProvider,
5
+ DatadogProviderConfiguration,
6
+ SdkVerbosity,
7
+ DdLogs,
8
+ UploadFrequency,
9
+ } from '@datadog/mobile-react-native';
10
+
11
+ export const initTransportLayerForAgora = () => {
12
+ console.log(
13
+ 'Initialized the logger in index entry file for native platforms ',
14
+ );
15
+ };
16
+
17
+ const getConfig = () => {
18
+ const loggerConfig = new DatadogProviderConfiguration(
19
+ 'pubdb41371dc4efb3e57a918a4f2096578c',
20
+ 'none',
21
+ 'fc33ae27-6fd6-4c7b-94c6-c2c11b9f565e',
22
+ true, // track User interactions (e.g.: Tap on buttons. You can use 'accessibilityLabel' element property to give tap action the name, otherwise element type will be reported)
23
+ true, // track XHR Resources
24
+ true, // track Errors
25
+ );
26
+ // Optional: Select your Datadog website (one of "US1", "EU1", "US3", "US5", "AP1" or "GOV")
27
+ loggerConfig.site = 'US1';
28
+ // Optional: Enable JavaScript long task collection
29
+ loggerConfig.longTaskThresholdMs = 100;
30
+ // Optional: enable or disable native crash reports
31
+ loggerConfig.nativeCrashReportEnabled = true;
32
+ // Optional: sample RUM sessions (here, 100% of session will be sent to Datadog. Default = 100%)
33
+ loggerConfig.sampleRate = 100;
34
+ // Optional: The service name for your application
35
+ loggerConfig.serviceName = 'app-builder-core-frontend-native';
36
+
37
+ if (__DEV__) {
38
+ // Optional: Send data more frequently
39
+ loggerConfig.uploadFrequency = UploadFrequency.FREQUENT;
40
+ // Optional: Send smaller batches of data
41
+ loggerConfig.batchSize = BatchSize.SMALL;
42
+ // Optional: Enable debug logging
43
+ loggerConfig.verbosity = SdkVerbosity.DEBUG;
44
+ }
45
+ return loggerConfig;
46
+ };
47
+
48
+ const getTransportLogger = () => {
49
+ return (text: string, data: any, status: StatusType) => {
50
+ if (status === 'error') {
51
+ DdLogs.error(text, data);
52
+ } else {
53
+ DdLogs.debug(text, data);
54
+ }
55
+ };
56
+ };
57
+
58
+ export {DatadogProvider, getTransportLogger, getConfig};
@@ -0,0 +1,28 @@
1
+ import {StatusType, datadogLogs} from '@datadog/browser-logs';
2
+ import {version as cli_version} from '../../../../package.json';
3
+
4
+ const DATADOG_CLIENT_TOKEN = 'pubeccdaed5357d217e2c75e85aaef432fe';
5
+ const DATADOG_SITE = 'datadoghq.com';
6
+
7
+ export const initTransportLayerForAgora = () => {
8
+ datadogLogs.init({
9
+ clientToken: DATADOG_CLIENT_TOKEN,
10
+ site: DATADOG_SITE,
11
+ forwardErrorsToLogs: false,
12
+ sessionSampleRate: 100,
13
+ service: 'app-builder-core-frontend',
14
+ version: cli_version,
15
+ env: 'none',
16
+ });
17
+ };
18
+
19
+ export const getTransportLogger = () => {
20
+ return (text: string, data: any, status: StatusType) => {
21
+ datadogLogs.logger.log(
22
+ text,
23
+ data,
24
+ status,
25
+ status === 'error' ? data[0] : undefined,
26
+ );
27
+ };
28
+ };
@@ -0,0 +1,115 @@
1
+ import createRetryFetch from 'fetch-retry';
2
+ import {isWeb} from '../../utils/common';
3
+
4
+ /* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value#examples */
5
+ export function getCircularReplacer() {
6
+ const ancestors = [];
7
+ return function (key, value) {
8
+ if (typeof value !== 'object' || value === null) {
9
+ return value;
10
+ }
11
+ // `this` is the object that value is contained in,
12
+ // i.e., its direct parent.
13
+ while (ancestors.length > 0 && ancestors[ancestors.length - 1] !== this) {
14
+ ancestors.pop();
15
+ }
16
+ if (ancestors.includes(value)) {
17
+ return '[Circular]';
18
+ }
19
+ ancestors.push(value);
20
+ return value;
21
+ };
22
+ }
23
+ const getSafeBody = (p: any[]) => {
24
+ try {
25
+ return JSON.stringify(p, getCircularReplacer());
26
+ } catch (error) {
27
+ console.error('there was an error converting this object');
28
+ return '';
29
+ }
30
+ };
31
+
32
+ const fetchRetry = createRetryFetch(fetch, {
33
+ retries: 23,
34
+ retryDelay: function (attempt) {
35
+ return Math.pow(2, attempt) * 1000; // 1000, 2000, 4000
36
+ },
37
+ retryOn: function (attempt, error, response) {
38
+ // retry on any network error, or 4xx or 5xx status codes
39
+ if (error !== null || response.status > 400) {
40
+ return true;
41
+ }
42
+ },
43
+ });
44
+
45
+ const sendLogs = (p: any[]) => {
46
+ fetchRetry(
47
+ 'https://axiom-queue.appbuilder.workers.dev?dataset=app-builder-core-frontend-customer',
48
+ // "&strategy=queue", // to send logs to a specific dataset [default: queue]
49
+ {
50
+ method: 'POST',
51
+ headers: new Headers({
52
+ 'Content-Type': 'application/json',
53
+ }),
54
+ body: getSafeBody(p),
55
+ },
56
+ ).catch(err => {
57
+ console.log('error ocuured while replacing circular reference', p, err);
58
+ });
59
+ };
60
+
61
+ export const createAxiomLogger = () => {
62
+ const queue: any[] = [];
63
+ let batchId = 0;
64
+ let timeout: number | null = null;
65
+
66
+ const sendInterval = 45000; // 45s
67
+
68
+ const flush = () => {
69
+ if (timeout !== null) {
70
+ clearTimeout(timeout);
71
+ timeout = null;
72
+ }
73
+ if (queue.length === 0) return;
74
+ sendLogs(queue);
75
+ queue.length = 0;
76
+ batchId = batchId + 1;
77
+ };
78
+
79
+ const log = (logContent: {[key: string]: any}) => {
80
+ logContent.batchId = batchId;
81
+ queue.push(logContent);
82
+ if (queue.length >= 1000) {
83
+ flush();
84
+ } else {
85
+ if (timeout === null) {
86
+ // @ts-ignore
87
+ timeout = setTimeout(() => {
88
+ flush();
89
+ }, sendInterval);
90
+ }
91
+ }
92
+ };
93
+
94
+ return [log, flush] as const;
95
+ };
96
+
97
+ export const initTransportLayerForCustomers = () => {
98
+ const [log, flush] = createAxiomLogger();
99
+
100
+ const printLogs = (...args: any[]) => {
101
+ log({
102
+ data: args,
103
+ _time: Date.now(),
104
+ projectId: $config.PROJECT_ID,
105
+ appId: $config.APP_ID,
106
+ service: 'app-builder-core-frontend-customer',
107
+ });
108
+
109
+ isWeb() &&
110
+ window.addEventListener('beforeunload', () => {
111
+ flush();
112
+ });
113
+ };
114
+ return printLogs;
115
+ };