@luciq/react-native 19.3.0-40271-SNAPSHOT → 19.4.0-44237-SNAPSHOT

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 (119) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +118 -0
  3. package/RNLuciq.podspec +6 -2
  4. package/android/build.gradle +25 -0
  5. package/android/native.gradle +1 -1
  6. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqAPMModule.java +3 -12
  7. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqBugReportingModule.java +28 -24
  8. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqCrashReportingModule.java +18 -7
  9. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsModule.java +1 -2
  10. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerModule.java +29 -56
  11. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativeModule.java +121 -47
  12. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqReactnativePackage.java +2 -0
  13. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqRepliesModule.java +4 -16
  14. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqSessionReplayModule.java +5 -16
  15. package/android/src/main/java/ai/luciq/reactlibrary/RNLuciqSurveysModule.java +7 -15
  16. package/android/src/main/java/ai/luciq/reactlibrary/utils/EventEmitterModule.java +0 -7
  17. package/android/src/main/java/ai/luciq/reactlibrary/utils/ReportUtil.java +0 -7
  18. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqAPMBaseSpec.java +9 -0
  19. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqBaseSpec.java +33 -0
  20. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqBugReportingBaseSpec.java +33 -0
  21. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqCrashReportingBaseSpec.java +9 -0
  22. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsBaseSpec.java +9 -0
  23. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerBaseSpec.java +33 -0
  24. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqRepliesBaseSpec.java +33 -0
  25. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqSessionReplayBaseSpec.java +33 -0
  26. package/android/src/newarch/java/ai/luciq/reactlibrary/RNLuciqSurveysBaseSpec.java +33 -0
  27. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqAPMBaseSpec.java +11 -0
  28. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqBaseSpec.java +22 -0
  29. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqBugReportingBaseSpec.java +22 -0
  30. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqCrashReportingBaseSpec.java +10 -0
  31. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqFeatureRequestsBaseSpec.java +10 -0
  32. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqNetworkLoggerBaseSpec.java +22 -0
  33. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqRepliesBaseSpec.java +22 -0
  34. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqSessionReplayBaseSpec.java +22 -0
  35. package/android/src/oldarch/java/ai/luciq/reactlibrary/RNLuciqSurveysBaseSpec.java +22 -0
  36. package/dist/modules/BugReporting.js +3 -3
  37. package/dist/modules/Luciq.d.ts +15 -0
  38. package/dist/modules/Luciq.js +23 -3
  39. package/dist/modules/NetworkLogger.d.ts +5 -0
  40. package/dist/modules/NetworkLogger.js +1 -9
  41. package/dist/modules/Replies.js +1 -1
  42. package/dist/modules/Surveys.js +2 -2
  43. package/dist/native/NativeBugReporting.d.ts +4 -4
  44. package/dist/native/NativeCrashReporting.d.ts +2 -2
  45. package/dist/native/NativeLuciq.d.ts +5 -3
  46. package/dist/native/NativePackage.js +25 -2
  47. package/dist/native/NativeReplies.d.ts +1 -1
  48. package/dist/native/NativeSurveys.d.ts +2 -2
  49. package/dist/native/specs/NativeAPM.d.ts +21 -0
  50. package/dist/native/specs/NativeAPM.js +2 -0
  51. package/dist/native/specs/NativeBugReporting.d.ts +29 -0
  52. package/dist/native/specs/NativeBugReporting.js +2 -0
  53. package/dist/native/specs/NativeCrashReporting.d.ts +12 -0
  54. package/dist/native/specs/NativeCrashReporting.js +2 -0
  55. package/dist/native/specs/NativeFeatureRequests.d.ts +8 -0
  56. package/dist/native/specs/NativeFeatureRequests.js +2 -0
  57. package/dist/native/specs/NativeLuciq.d.ts +80 -0
  58. package/dist/native/specs/NativeLuciq.js +2 -0
  59. package/dist/native/specs/NativeNetworkLogger.d.ts +16 -0
  60. package/dist/native/specs/NativeNetworkLogger.js +2 -0
  61. package/dist/native/specs/NativeReplies.d.ts +21 -0
  62. package/dist/native/specs/NativeReplies.js +2 -0
  63. package/dist/native/specs/NativeSessionReplay.d.ts +17 -0
  64. package/dist/native/specs/NativeSessionReplay.js +2 -0
  65. package/dist/native/specs/NativeSurveys.d.ts +18 -0
  66. package/dist/native/specs/NativeSurveys.js +2 -0
  67. package/dist/utils/Enums.js +3 -1
  68. package/dist/utils/FeatureFlags.d.ts +0 -6
  69. package/dist/utils/FeatureFlags.js +0 -35
  70. package/dist/utils/LuciqUtils.d.ts +1 -1
  71. package/dist/utils/LuciqUtils.js +0 -9
  72. package/dist/utils/XhrNetworkInterceptor.js +53 -85
  73. package/ios/RNLuciq/LuciqAPMBridge.h +5 -5
  74. package/ios/RNLuciq/{LuciqAPMBridge.m → LuciqAPMBridge.mm} +48 -39
  75. package/ios/RNLuciq/LuciqBugReportingBridge.h +6 -6
  76. package/ios/RNLuciq/LuciqBugReportingBridge.mm +234 -0
  77. package/ios/RNLuciq/LuciqCrashReportingBridge.h +16 -5
  78. package/ios/RNLuciq/LuciqCrashReportingBridge.mm +91 -0
  79. package/ios/RNLuciq/LuciqFeatureRequestsBridge.h +1 -1
  80. package/ios/RNLuciq/{LuciqFeatureRequestsBridge.m → LuciqFeatureRequestsBridge.mm} +21 -16
  81. package/ios/RNLuciq/LuciqNetworkLoggerBridge.h +1 -30
  82. package/ios/RNLuciq/{LuciqNetworkLoggerBridge.m → LuciqNetworkLoggerBridge.mm} +46 -77
  83. package/ios/RNLuciq/LuciqReactBridge.h +13 -13
  84. package/ios/RNLuciq/{LuciqReactBridge.m → LuciqReactBridge.mm} +95 -34
  85. package/ios/RNLuciq/LuciqRepliesBridge.h +3 -3
  86. package/ios/RNLuciq/LuciqRepliesBridge.mm +86 -0
  87. package/ios/RNLuciq/LuciqSessionReplayBridge.h +5 -5
  88. package/ios/RNLuciq/{LuciqSessionReplayBridge.m → LuciqSessionReplayBridge.mm} +35 -25
  89. package/ios/RNLuciq/LuciqSurveysBridge.h +5 -5
  90. package/ios/RNLuciq/{LuciqSurveysBridge.m → LuciqSurveysBridge.mm} +34 -35
  91. package/ios/native.rb +1 -1
  92. package/package.json +9 -1
  93. package/src/modules/BugReporting.ts +3 -3
  94. package/src/modules/Luciq.ts +26 -4
  95. package/src/modules/NetworkLogger.ts +1 -26
  96. package/src/modules/Replies.ts +1 -1
  97. package/src/modules/Surveys.ts +2 -2
  98. package/src/native/NativeBugReporting.ts +3 -6
  99. package/src/native/NativeCrashReporting.ts +2 -2
  100. package/src/native/NativeLuciq.ts +7 -3
  101. package/src/native/NativePackage.ts +52 -2
  102. package/src/native/NativeReplies.ts +1 -1
  103. package/src/native/NativeSurveys.ts +2 -2
  104. package/src/native/specs/NativeAPM.ts +47 -0
  105. package/src/native/specs/NativeBugReporting.ts +53 -0
  106. package/src/native/specs/NativeCrashReporting.ts +23 -0
  107. package/src/native/specs/NativeFeatureRequests.ts +10 -0
  108. package/src/native/specs/NativeLuciq.ts +137 -0
  109. package/src/native/specs/NativeNetworkLogger.ts +31 -0
  110. package/src/native/specs/NativeReplies.ts +27 -0
  111. package/src/native/specs/NativeSessionReplay.ts +20 -0
  112. package/src/native/specs/NativeSurveys.ts +23 -0
  113. package/src/utils/Enums.ts +4 -1
  114. package/src/utils/FeatureFlags.ts +0 -44
  115. package/src/utils/LuciqUtils.ts +1 -21
  116. package/src/utils/XhrNetworkInterceptor.ts +55 -128
  117. package/ios/RNLuciq/LuciqBugReportingBridge.m +0 -249
  118. package/ios/RNLuciq/LuciqCrashReportingBridge.m +0 -68
  119. package/ios/RNLuciq/LuciqRepliesBridge.m +0 -80
@@ -1,10 +1,7 @@
1
1
  import LuciqConstants from './LuciqConstants';
2
2
  import { stringifyIfNotString, generateW3CHeader } from './LuciqUtils';
3
3
 
4
- import { getCachedW3cFlags } from './FeatureFlags';
5
- import { Logger } from './logger';
6
-
7
- const TAG = 'LCQ-RN-NET:';
4
+ import { FeatureFlags } from '../utils/FeatureFlags';
8
5
 
9
6
  export type ProgressCallback = (totalBytesSent: number, totalBytesExpectedToSend: number) => void;
10
7
  export type NetworkDataCallback = (data: NetworkData) => void;
@@ -43,41 +40,45 @@ let originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
43
40
  let onProgressCallback: ProgressCallback | null;
44
41
  let onDoneCallback: NetworkDataCallback | null;
45
42
  let isInterceptorEnabled = false;
46
-
47
- const networkMap = new WeakMap<XMLHttpRequest, NetworkData>();
48
-
49
- const createNetworkData = (): NetworkData => ({
50
- id: '',
51
- url: '',
52
- method: '',
53
- requestBody: '',
54
- requestBodySize: 0,
55
- responseBody: '',
56
- responseBodySize: 0,
57
- responseCode: 0,
58
- requestHeaders: {},
59
- responseHeaders: {},
60
- contentType: '',
61
- errorDomain: '',
62
- errorCode: 0,
63
- startTime: 0,
64
- duration: 0,
65
- gqlQueryName: '',
66
- serverErrorMessage: '',
67
- requestContentType: '',
68
- isW3cHeaderFound: null,
69
- partialId: null,
70
- networkStartTimeInSeconds: null,
71
- w3cGeneratedHeader: null,
72
- w3cCaughtHeader: null,
73
- });
74
-
75
- const getTraceparentHeader = (networkData: NetworkData) => {
76
- const {
43
+ let network: NetworkData;
44
+
45
+ const _reset = () => {
46
+ network = {
47
+ id: '',
48
+ url: '',
49
+ method: '',
50
+ requestBody: '',
51
+ requestBodySize: 0,
52
+ responseBody: '',
53
+ responseBodySize: 0,
54
+ responseCode: 0,
55
+ requestHeaders: {},
56
+ responseHeaders: {},
57
+ contentType: '',
58
+ errorDomain: '',
59
+ errorCode: 0,
60
+ startTime: 0,
61
+ duration: 0,
62
+ gqlQueryName: '',
63
+ serverErrorMessage: '',
64
+ requestContentType: '',
65
+ isW3cHeaderFound: null,
66
+ partialId: null,
67
+ networkStartTimeInSeconds: null,
68
+ w3cGeneratedHeader: null,
69
+ w3cCaughtHeader: null,
70
+ };
71
+ };
72
+ const getTraceparentHeader = async (networkData: NetworkData) => {
73
+ const [
77
74
  isW3cExternalTraceIDEnabled,
78
75
  isW3cExternalGeneratedHeaderEnabled,
79
76
  isW3cCaughtHeaderEnabled,
80
- } = getCachedW3cFlags();
77
+ ] = await Promise.all([
78
+ FeatureFlags.isW3ExternalTraceID(),
79
+ FeatureFlags.isW3ExternalGeneratedHeader(),
80
+ FeatureFlags.isW3CaughtHeader(),
81
+ ]);
81
82
 
82
83
  return injectHeaders(networkData, {
83
84
  isW3cExternalTraceIDEnabled,
@@ -146,77 +147,44 @@ export default {
146
147
  onProgressCallback = callback;
147
148
  },
148
149
  enableInterception() {
150
+ // Prevents infinite calls to XMLHttpRequest.open when enabling interception multiple times
149
151
  if (isInterceptorEnabled) {
150
- Logger.debug(TAG, 'enableInterception called but already enabled, skipping');
151
152
  return;
152
153
  }
153
154
 
154
- Logger.debug(TAG, 'Enabling XHR network interception');
155
-
156
155
  originalXHROpen = XMLHttpRequest.prototype.open;
157
156
  originalXHRSend = XMLHttpRequest.prototype.send;
158
157
  originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
159
158
  // An error code that signifies an issue with the RN client.
160
159
  const clientErrorCode = 9876;
161
160
  XMLHttpRequest.prototype.open = function (method, url, ...args) {
162
- const networkData = createNetworkData();
163
- networkData.url = url;
164
- networkData.method = method;
165
- networkMap.set(this, networkData);
166
- Logger.debug(TAG, `[open] ${method} ${url}`);
161
+ _reset();
162
+ network.url = url;
163
+ network.method = method;
167
164
  originalXHROpen.apply(this, [method, url, ...args]);
168
165
  };
169
166
 
170
167
  XMLHttpRequest.prototype.setRequestHeader = function (header, value) {
168
+ // According to the HTTP RFC, headers are case-insensitive, so we convert
169
+ // them to lower-case to make accessing headers predictable.
170
+ // This avoid issues like failing to get the Content-Type header for a request
171
+ // because the header is set as 'Content-Type' instead of 'content-type'.
171
172
  const key = header.toLowerCase();
172
- const networkData = networkMap.get(this);
173
- if (networkData) {
174
- networkData.requestHeaders[key] = stringifyIfNotString(value);
175
- } else {
176
- Logger.debug(
177
- TAG,
178
- `[setRequestHeader] No networkData found in WeakMap for header "${key}" — request may have been GC'd or open() was not called`,
179
- );
180
- }
173
+ network.requestHeaders[key] = stringifyIfNotString(value);
181
174
  originalXHRSetRequestHeader.apply(this, [header, value]);
182
175
  };
183
176
 
184
- XMLHttpRequest.prototype.send = function (data) {
185
- const networkData = networkMap.get(this);
186
- if (!networkData) {
187
- Logger.debug(
188
- TAG,
189
- '[send] No networkData found in WeakMap — falling back to original send (open() was not intercepted)',
190
- );
191
- originalXHRSend.apply(this, [data]);
192
- return;
193
- }
194
-
195
- Logger.debug(TAG, `[send] ${networkData.method} ${networkData.url}`);
196
-
197
- const cloneNetwork = JSON.parse(JSON.stringify(networkData));
177
+ XMLHttpRequest.prototype.send = async function (data) {
178
+ const cloneNetwork = JSON.parse(JSON.stringify(network));
198
179
  cloneNetwork.requestBody = data ? data : '';
199
180
 
200
181
  if (typeof cloneNetwork.requestBody !== 'string') {
201
182
  cloneNetwork.requestBody = JSON.stringify(cloneNetwork.requestBody);
202
183
  }
203
184
 
204
- let isReported = false;
205
-
206
185
  if (this.addEventListener) {
207
186
  this.addEventListener('readystatechange', async () => {
208
187
  if (!isInterceptorEnabled) {
209
- Logger.debug(
210
- TAG,
211
- `[readystatechange] Interceptor disabled, ignoring state=${this.readyState} for ${cloneNetwork.url}`,
212
- );
213
- return;
214
- }
215
- if (isReported) {
216
- Logger.debug(
217
- TAG,
218
- `[readystatechange] Already reported, ignoring state=${this.readyState} for ${cloneNetwork.url}`,
219
- );
220
188
  return;
221
189
  }
222
190
  if (this.readyState === this.HEADERS_RECEIVED) {
@@ -249,11 +217,6 @@ export default {
249
217
  cloneNetwork.requestContentType =
250
218
  cloneNetwork.requestHeaders['content-type'].split(';')[0];
251
219
  }
252
-
253
- Logger.debug(
254
- TAG,
255
- `[readystatechange] HEADERS_RECEIVED for ${cloneNetwork.url}, contentType=${cloneNetwork.contentType}`,
256
- );
257
220
  }
258
221
 
259
222
  if (this.readyState === this.DONE) {
@@ -276,15 +239,12 @@ export default {
276
239
  typeof _response === 'string' ? _response : JSON.stringify(_response);
277
240
  cloneNetwork.responseBody = '';
278
241
 
242
+ // Detect a more descriptive error message.
279
243
  if (typeof _response === 'string' && _response.length > 0) {
280
244
  cloneNetwork.errorDomain = _response;
281
245
  }
282
246
 
283
247
  cloneNetwork.responseBody = `ERROR: ${cloneNetwork.errorDomain}`;
284
- Logger.debug(
285
- TAG,
286
- `[readystatechange] DONE with client error for ${cloneNetwork.url}, errorDomain=${cloneNetwork.errorDomain}`,
287
- );
288
248
 
289
249
  // @ts-ignore
290
250
  } else if (this._timedOut) {
@@ -293,7 +253,6 @@ export default {
293
253
  cloneNetwork.responseCode = 0;
294
254
  cloneNetwork.contentType = 'text/plain';
295
255
  cloneNetwork.responseBody = `ERROR: ${cloneNetwork.errorDomain}`;
296
- Logger.debug(TAG, `[readystatechange] DONE with timeout for ${cloneNetwork.url}`);
297
256
  }
298
257
 
299
258
  // Only set response body if not already set by error handlers
@@ -341,18 +300,8 @@ export default {
341
300
  delete cloneNetwork.gqlQueryName;
342
301
  }
343
302
 
344
- isReported = true;
345
- Logger.debug(
346
- TAG,
347
- `[readystatechange] DONE for ${cloneNetwork.method} ${cloneNetwork.url} — status=${cloneNetwork.responseCode}, duration=${cloneNetwork.duration}ms, hasCallback=${!!onDoneCallback}`,
348
- );
349
303
  if (onDoneCallback) {
350
304
  onDoneCallback(cloneNetwork);
351
- } else {
352
- Logger.debug(
353
- TAG,
354
- `[readystatechange] WARNING: onDoneCallback is null, network log for ${cloneNetwork.url} will be LOST`,
355
- );
356
305
  }
357
306
  }
358
307
  });
@@ -361,6 +310,7 @@ export default {
361
310
  if (!isInterceptorEnabled) {
362
311
  return;
363
312
  }
313
+ // check if will be able to compute progress
364
314
  if (event.lengthComputable && onProgressCallback) {
365
315
  const totalBytesSent = event.loaded;
366
316
  const totalBytesExpectedToSend = event.total - event.loaded;
@@ -370,57 +320,34 @@ export default {
370
320
  this.addEventListener('progress', downloadUploadProgressCallback);
371
321
  this.upload.addEventListener('progress', downloadUploadProgressCallback);
372
322
 
323
+ // Handler for abort events (works with fetch, Axios, and any XHR-based requests)
373
324
  this.addEventListener('abort', () => {
374
325
  if (!isInterceptorEnabled) {
375
- Logger.debug(
376
- TAG,
377
- `[abort] Interceptor disabled, ignoring abort for ${cloneNetwork.url}`,
378
- );
379
326
  return;
380
327
  }
381
- if (isReported) {
382
- Logger.debug(
383
- TAG,
384
- `[abort] Already reported via readystatechange DONE, ignoring duplicate abort for ${cloneNetwork.url}`,
385
- );
386
- return;
387
- }
388
- isReported = true;
389
328
  cloneNetwork.duration = Date.now() - cloneNetwork.startTime;
390
329
  cloneNetwork.responseCode = 0;
391
330
  cloneNetwork.errorCode = clientErrorCode;
392
331
  cloneNetwork.errorDomain = 'cancelled';
393
332
  cloneNetwork.responseBody = `ERROR: ${cloneNetwork.errorDomain}`;
394
- Logger.debug(
395
- TAG,
396
- `[abort] Request cancelled: ${cloneNetwork.method} ${cloneNetwork.url}, duration=${cloneNetwork.duration}ms, hasCallback=${!!onDoneCallback}`,
397
- );
398
- if (onDoneCallback) {
399
- onDoneCallback(cloneNetwork);
400
- } else {
401
- Logger.debug(
402
- TAG,
403
- `[abort] WARNING: onDoneCallback is null, cancelled log for ${cloneNetwork.url} will be LOST`,
404
- );
405
- }
406
333
  });
407
334
  }
408
335
 
409
336
  cloneNetwork.startTime = Date.now();
410
- const traceparent = getTraceparentHeader(cloneNetwork);
337
+ const traceparent = await getTraceparentHeader(cloneNetwork);
411
338
  if (traceparent) {
412
339
  this.setRequestHeader('Traceparent', traceparent);
413
- Logger.debug(TAG, `[send] Injected traceparent header for ${cloneNetwork.url}`);
340
+ }
341
+ if (this.readyState === this.UNSENT) {
342
+ return; // Prevent sending the request if not opened
414
343
  }
415
344
 
416
345
  originalXHRSend.apply(this, [data]);
417
346
  };
418
347
  isInterceptorEnabled = true;
419
- Logger.debug(TAG, 'XHR network interception enabled');
420
348
  },
421
349
 
422
350
  disableInterception() {
423
- Logger.debug(TAG, 'Disabling XHR network interception');
424
351
  isInterceptorEnabled = false;
425
352
  XMLHttpRequest.prototype.send = originalXHRSend;
426
353
  XMLHttpRequest.prototype.open = originalXHROpen;
@@ -1,249 +0,0 @@
1
- //
2
- // LuciqBugReportingBridge.m
3
- // RNLuciq
4
- //
5
- // Created by Salma Ali on 7/30/19.
6
- // Copyright © 2019 luciq. All rights reserved.
7
- //
8
-
9
- #import "LuciqBugReportingBridge.h"
10
- #import <LuciqSDK/LCQBugReporting.h>
11
- #import <asl.h>
12
- #import <React/RCTLog.h>
13
- #import <os/log.h>
14
- #import <React/RCTUIManager.h>
15
-
16
- @implementation LuciqBugReportingBridge
17
-
18
- - (dispatch_queue_t)methodQueue {
19
- return dispatch_get_main_queue();
20
- }
21
-
22
- + (BOOL)requiresMainQueueSetup
23
- {
24
- return NO;
25
- }
26
-
27
- - (NSArray<NSString *> *)supportedEvents {
28
- return @[
29
- @"LCQpreInvocationHandler",
30
- @"LCQpostInvocationHandler",
31
- @"LCQDidSelectPromptOptionHandler",
32
- ];
33
- }
34
-
35
- RCT_EXPORT_MODULE(LCQBugReporting)
36
-
37
- RCT_EXPORT_METHOD(setEnabled:(BOOL) isEnabled) {
38
- LCQBugReporting.enabled = isEnabled;
39
- }
40
-
41
- RCT_EXPORT_METHOD(setAutoScreenRecordingEnabled:(BOOL)enabled) {
42
- LCQBugReporting.autoScreenRecordingEnabled = enabled;
43
- }
44
-
45
- RCT_EXPORT_METHOD(setAutoScreenRecordingDuration:(CGFloat)duration) {
46
- LCQBugReporting.autoScreenRecordingDuration = duration;
47
- }
48
-
49
- RCT_EXPORT_METHOD(setOnInvokeHandler:(RCTResponseSenderBlock)callBack) {
50
- if (callBack != nil) {
51
- LCQBugReporting.willInvokeHandler = ^{
52
- [self sendEventWithName:@"LCQpreInvocationHandler" body:nil];
53
- };
54
- } else {
55
- LCQBugReporting.willInvokeHandler = nil;
56
- }
57
- }
58
-
59
- RCT_EXPORT_METHOD(setOnSDKDismissedHandler:(RCTResponseSenderBlock)callBack) {
60
- if (callBack != nil) {
61
- LCQBugReporting.didDismissHandler = ^(LCQDismissType dismissType, LCQReportCategory reportType) {
62
-
63
- //parse dismiss type enum
64
- NSString* dismissTypeString;
65
- if (dismissType == LCQDismissTypeCancel) {
66
- dismissTypeString = @"CANCEL";
67
- } else if (dismissType == LCQDismissTypeSubmit) {
68
- dismissTypeString = @"SUBMIT";
69
- } else if (dismissType == LCQDismissTypeAddAttachment) {
70
- dismissTypeString = @"ADD_ATTACHMENT";
71
- }
72
-
73
- //parse report type enum
74
- NSString* reportTypeString;
75
- if (reportType == LCQReportCategoryBug) {
76
- reportTypeString = @"bug";
77
- } else if (reportType == LCQReportCategoryFeedback) {
78
- reportTypeString = @"feedback";
79
- } else {
80
- reportTypeString = @"other";
81
- }
82
- NSDictionary *result = @{ @"dismissType": dismissTypeString,
83
- @"reportType": reportTypeString};
84
- [self sendEventWithName:@"LCQpostInvocationHandler" body: result];
85
- };
86
- } else {
87
- LCQBugReporting.didDismissHandler = nil;
88
- }
89
- }
90
-
91
- RCT_EXPORT_METHOD(setDidSelectPromptOptionHandler:(RCTResponseSenderBlock)callBack) {
92
- if (callBack != nil) {
93
-
94
- LCQBugReporting.didSelectPromptOptionHandler = ^(LCQPromptOption promptOption) {
95
-
96
- NSString *promptOptionString;
97
- if (promptOption == LCQPromptOptionBug) {
98
- promptOptionString = @"bug";
99
- } else if (promptOption == LCQBugReportingTypeFeedback) {
100
- promptOptionString = @"feedback";
101
- } else if (promptOption == LCQPromptOptionChat) {
102
- promptOptionString = @"chat";
103
- } else {
104
- promptOptionString = @"none";
105
- }
106
-
107
- [self sendEventWithName:@"LCQDidSelectPromptOptionHandler" body:@{
108
- @"promptOption": promptOptionString
109
- }];
110
- };
111
- } else {
112
- LCQBugReporting.didSelectPromptOptionHandler = nil;
113
- }
114
- }
115
-
116
- RCT_EXPORT_METHOD(setInvocationEvents:(NSArray*)invocationEventsArray) {
117
- LCQInvocationEvent invocationEvents = 0;
118
- for (NSNumber *boxedValue in invocationEventsArray) {
119
- invocationEvents |= [boxedValue intValue];
120
- }
121
- LCQBugReporting.invocationEvents = invocationEvents;
122
- }
123
-
124
- RCT_EXPORT_METHOD(setOptions:(NSArray*)invocationOptionsArray) {
125
- LCQBugReportingOption invocationOptions = 0;
126
-
127
- for (NSNumber *boxedValue in invocationOptionsArray) {
128
- invocationOptions |= [boxedValue intValue];
129
- }
130
-
131
- LCQBugReporting.bugReportingOptions = invocationOptions;
132
- }
133
-
134
- RCT_EXPORT_METHOD(setFloatingButtonEdge:(CGRectEdge)floatingButtonEdge withTopOffset:(double)floatingButtonOffsetFromTop) {
135
- LCQBugReporting.floatingButtonEdge = floatingButtonEdge;
136
- LCQBugReporting.floatingButtonTopOffset = floatingButtonOffsetFromTop;
137
- }
138
-
139
- RCT_EXPORT_METHOD(setExtendedBugReportMode:(LCQExtendedBugReportMode)extendedBugReportMode) {
140
- LCQBugReporting.extendedBugReportMode = extendedBugReportMode;
141
- }
142
-
143
- RCT_EXPORT_METHOD(setEnabledAttachmentTypes:(BOOL)screenShot
144
- extraScreenShot:(BOOL)extraScreenShot
145
- galleryImage:(BOOL)galleryImage
146
- screenRecording:(BOOL)screenRecording) {
147
- LCQAttachmentType attachmentTypes = 0;
148
- if(screenShot) {
149
- attachmentTypes = LCQAttachmentTypeScreenShot;
150
- }
151
- if(extraScreenShot) {
152
- attachmentTypes |= LCQAttachmentTypeExtraScreenShot;
153
- }
154
- if(galleryImage) {
155
- attachmentTypes |= LCQAttachmentTypeGalleryImage;
156
- }
157
- if(screenRecording) {
158
- attachmentTypes |= LCQAttachmentTypeScreenRecording;
159
- }
160
-
161
- LCQBugReporting.enabledAttachmentTypes = attachmentTypes;
162
- }
163
-
164
- RCT_EXPORT_METHOD(setViewHierarchyEnabled:(BOOL)viewHirearchyEnabled) {
165
- LCQBugReporting.shouldCaptureViewHierarchy = viewHirearchyEnabled;
166
- }
167
-
168
- RCT_EXPORT_METHOD(setVideoRecordingFloatingButtonPosition:(LCQPosition)position) {
169
- LCQBugReporting.videoRecordingFloatingButtonPosition = position;
170
- }
171
-
172
- RCT_EXPORT_METHOD(setReportTypes:(NSArray*) types ) {
173
- LCQBugReportingReportType reportTypes = 0;
174
- for (NSNumber *boxedValue in types) {
175
- reportTypes |= [boxedValue intValue];
176
- }
177
- [LCQBugReporting setPromptOptionsEnabledReportTypes: reportTypes];
178
- }
179
-
180
- RCT_EXPORT_METHOD(show:(LCQBugReportingReportType)type options:(NSArray*) options) {
181
- LCQBugReportingOption parsedOptions = 0;
182
- for (NSNumber *boxedValue in options) {
183
- parsedOptions |= [boxedValue intValue];
184
- }
185
- NSArray* args = @[@(type), @(parsedOptions)];
186
- [[NSRunLoop mainRunLoop] performSelector:@selector(showBugReportingWithReportTypeAndOptionsHelper:) target:self argument:args order:0 modes:@[NSDefaultRunLoopMode]];
187
- }
188
-
189
- - (void) showBugReportingWithReportTypeAndOptionsHelper:(NSArray*)args {
190
- LCQBugReportingReportType parsedreportType = [args[0] intValue];
191
- LCQBugReportingOption parsedOptions = [args[1] intValue];
192
- [LCQBugReporting showWithReportType:parsedreportType options:parsedOptions];
193
- }
194
-
195
- RCT_EXPORT_METHOD(setShakingThresholdForiPhone:(double)iPhoneShakingThreshold) {
196
- LCQBugReporting.shakingThresholdForiPhone = iPhoneShakingThreshold;
197
- }
198
-
199
- RCT_EXPORT_METHOD(setShakingThresholdForiPad:(double)iPadShakingThreshold) {
200
- LCQBugReporting.shakingThresholdForiPad = iPadShakingThreshold;
201
- }
202
-
203
- RCT_EXPORT_METHOD(setDisclaimerText:(NSString*)text) {
204
- [LCQBugReporting setDisclaimerText:text];
205
- }
206
-
207
- RCT_EXPORT_METHOD(setCommentMinimumCharacterCount:(nonnull NSNumber *)limit reportTypes:(NSArray *)reportTypes) {
208
- LCQBugReportingType parsedReportTypes = 0;
209
- if (![reportTypes count]) {
210
- parsedReportTypes = @(LCQBugReportingTypeBug).integerValue | @(LCQBugReportingTypeFeedback).integerValue | @(LCQBugReportingTypeQuestion).integerValue;
211
- }
212
- else {
213
- for (NSNumber *reportType in reportTypes) {
214
- parsedReportTypes |= [reportType intValue];
215
- }
216
- }
217
- [LCQBugReporting setCommentMinimumCharacterCount:[limit integerValue] forBugReportType:parsedReportTypes];
218
- }
219
-
220
- RCT_EXPORT_METHOD(addUserConsent:(NSString *)key
221
- description:(NSString *)description
222
- mandatory:(BOOL)mandatory
223
- checked:(BOOL)checked
224
- actionType:(id)actionType) {
225
- LCQConsentAction mappedActionType = (LCQConsentAction)[actionType integerValue];
226
-
227
- [LCQBugReporting addUserConsentWithKey:key
228
- description:description
229
- mandatory:mandatory
230
- checked:checked
231
- actionType:mappedActionType];
232
- }
233
-
234
- RCT_EXPORT_METHOD(setProactiveReportingConfigurations:(BOOL)enabled gap:(nonnull NSNumber* )gap model:(nonnull NSNumber* )modal) {
235
- LCQProactiveReportingConfigurations *configurations = [[LCQProactiveReportingConfigurations alloc] init];
236
- configurations.enabled = enabled; //Enable/disable
237
- configurations.gapBetweenModals = gap; // Time in seconds
238
- configurations.modalDelayAfterDetection = modal; // Time in seconds
239
- [LCQBugReporting setProactiveReportingConfigurations:configurations];
240
- }
241
-
242
-
243
- @synthesize description;
244
-
245
- @synthesize hash;
246
-
247
- @synthesize superclass;
248
-
249
- @end
@@ -1,68 +0,0 @@
1
- #import "LuciqCrashReportingBridge.h"
2
- #import "Util/LCQCrashReporting+CP.h"
3
-
4
-
5
- @implementation LuciqCrashReportingBridge
6
-
7
- - (dispatch_queue_t)methodQueue {
8
- return dispatch_get_main_queue();
9
- }
10
-
11
- + (BOOL)requiresMainQueueSetup
12
- {
13
- return NO;
14
- }
15
-
16
- - (NSArray<NSString *> *)supportedEvents {
17
- return @[
18
- @"LCQSendHandledJSCrash",
19
- @"LCQSendUnhandledJSCrash",
20
- ];
21
- }
22
-
23
- RCT_EXPORT_MODULE(LCQCrashReporting)
24
-
25
- RCT_EXPORT_METHOD(setEnabled: (BOOL) isEnabled) {
26
- LCQCrashReporting.enabled = isEnabled;
27
- }
28
-
29
- RCT_EXPORT_METHOD(sendJSCrash:(NSDictionary *)stackTrace
30
- resolver:(RCTPromiseResolveBlock)resolve
31
- rejecter:(RCTPromiseRejectBlock)reject) {
32
-
33
- dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
34
- dispatch_async(queue, ^{
35
- [LCQCrashReporting cp_reportFatalCrashWithStackTrace:stackTrace];
36
- resolve([NSNull null]);
37
- });
38
- }
39
-
40
- RCT_EXPORT_METHOD(sendHandledJSCrash: (NSDictionary *)stackTrace
41
- userAttributes:(nullable NSDictionary *)userAttributes fingerprint:(nullable NSString *)fingerprint nonFatalExceptionLevel:(LCQNonFatalLevel)nonFatalExceptionLevel
42
- resolver:(RCTPromiseResolveBlock)resolve
43
- rejecter:(RCTPromiseRejectBlock)reject) {
44
-
45
- if([fingerprint isKindOfClass:NSNull.class]){
46
- fingerprint = nil;
47
- }
48
-
49
- if([userAttributes isKindOfClass:NSNull.class]){
50
- userAttributes = nil;
51
- }
52
- dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
53
- dispatch_async(queue, ^{
54
- [LCQCrashReporting cp_reportNonFatalCrashWithStackTrace:stackTrace level:nonFatalExceptionLevel groupingString:fingerprint userAttributes:userAttributes];
55
-
56
- resolve([NSNull null]);
57
- });
58
-
59
- }
60
- @synthesize description;
61
-
62
- @synthesize hash;
63
-
64
- @synthesize superclass;
65
-
66
- @end
67
-
68
-
@@ -1,80 +0,0 @@
1
- //
2
- // LuciqRepliesBridge.m
3
- // RNLuciq
4
- //
5
- // Created by Salma Ali on 7/30/19.
6
- // Copyright © 2019 luciq. All rights reserved.
7
- //
8
- //
9
-
10
- #import "LuciqRepliesBridge.h"
11
- #import <LuciqSDK/LCQReplies.h>
12
- #import <asl.h>
13
- #import <React/RCTLog.h>
14
- #import <os/log.h>
15
- #import <LuciqSDK/LCQTypes.h>
16
- #import <React/RCTUIManager.h>
17
-
18
- @implementation LuciqRepliesBridge
19
-
20
- - (dispatch_queue_t)methodQueue {
21
- return dispatch_get_main_queue();
22
- }
23
-
24
- + (BOOL)requiresMainQueueSetup
25
- {
26
- return NO;
27
- }
28
-
29
- - (NSArray<NSString *> *)supportedEvents {
30
- return @[@"LCQOnNewReplyReceivedCallback"];
31
- }
32
-
33
- RCT_EXPORT_MODULE(LCQReplies)
34
-
35
- RCT_EXPORT_METHOD(setEnabled:(BOOL) isEnabled) {
36
- LCQReplies.enabled = isEnabled;
37
- }
38
-
39
- RCT_EXPORT_METHOD(hasChats:(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject) {
40
- BOOL hasChats = LCQReplies.hasChats;
41
- resolve(@(hasChats));
42
-
43
- }
44
-
45
- RCT_EXPORT_METHOD(show) {
46
- [[NSRunLoop mainRunLoop] performSelector:@selector(show) target:[LCQReplies class] argument:nil order:0 modes:@[NSDefaultRunLoopMode]];
47
- }
48
-
49
- RCT_EXPORT_METHOD(setOnNewReplyReceivedHandler:(RCTResponseSenderBlock) callback) {
50
- if (callback != nil) {
51
- LCQReplies.didReceiveReplyHandler = ^{
52
- [self sendEventWithName:@"LCQOnNewReplyReceivedCallback" body:nil];
53
- };
54
- } else {
55
- LCQReplies.didReceiveReplyHandler = nil;
56
- }
57
-
58
- }
59
-
60
- RCT_EXPORT_METHOD(getUnreadRepliesCount:(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject) {
61
- resolve(@(LCQReplies.unreadRepliesCount));
62
- }
63
-
64
- RCT_EXPORT_METHOD(setInAppNotificationEnabled:(BOOL)isChatNotificationEnabled) {
65
- LCQReplies.inAppNotificationsEnabled = isChatNotificationEnabled;
66
- }
67
-
68
- RCT_EXPORT_METHOD(setPushNotificationsEnabled:(BOOL)isPushNotificationEnabled) {
69
- [LCQReplies setPushNotificationsEnabled:isPushNotificationEnabled];
70
- }
71
-
72
- @synthesize description;
73
-
74
- @synthesize hash;
75
-
76
- @synthesize superclass;
77
-
78
- @end
79
-
80
-