@luciq/react-native 19.6.0-51917-SNAPSHOT → 19.7.0

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.
@@ -2,6 +2,7 @@ package ai.luciq.reactlibrary;
2
2
 
3
3
  import static ai.luciq.apm.configuration.cp.APMFeature.APM_NETWORK_PLUGIN_INSTALLED;
4
4
  import static ai.luciq.apm.configuration.cp.APMFeature.CP_NATIVE_INTERCEPTION_ENABLED;
5
+ import static ai.luciq.reactlibrary.Constants.NET_TAG;
5
6
  import static ai.luciq.reactlibrary.utils.LuciqUtil.getMethod;
6
7
 
7
8
  import android.app.Application;
@@ -13,8 +14,6 @@ import android.os.Build;
13
14
  import android.util.Log;
14
15
  import android.view.View;
15
16
 
16
- import com.facebook.react.bridge.ReactApplicationContext;
17
-
18
17
  import androidx.annotation.NonNull;
19
18
  import androidx.annotation.UiThread;
20
19
 
@@ -32,22 +31,37 @@ import com.facebook.react.bridge.WritableNativeArray;
32
31
  import com.facebook.react.bridge.WritableNativeMap;
33
32
  import com.facebook.react.uimanager.UIManagerHelper;
34
33
  import com.facebook.react.uimanager.UIManagerModule;
34
+
35
+ import org.json.JSONException;
36
+ import org.json.JSONObject;
37
+ import org.json.JSONTokener;
38
+
39
+ import java.io.File;
40
+ import java.lang.reflect.Method;
41
+ import java.util.ArrayList;
42
+ import java.util.Arrays;
43
+ import java.util.HashMap;
44
+ import java.util.Iterator;
45
+ import java.util.List;
46
+ import java.util.Locale;
47
+ import java.util.Map;
48
+
49
+ import javax.annotation.Nullable;
50
+
35
51
  import ai.luciq.apm.InternalAPM;
36
- import ai.luciq.apm.configuration.cp.APMFeature;
37
52
  import ai.luciq.library.Feature;
53
+ import ai.luciq.library.IssueType;
54
+ import ai.luciq.library.LogLevel;
38
55
  import ai.luciq.library.Luciq;
39
56
  import ai.luciq.library.LuciqColorTheme;
40
57
  import ai.luciq.library.LuciqCustomTextPlaceHolder;
41
- import ai.luciq.library.IssueType;
42
- import ai.luciq.library.LogLevel;
43
58
  import ai.luciq.library.ReproConfigurations;
44
59
  import ai.luciq.library.core.InstabugCore;
60
+ import ai.luciq.library.featuresflags.model.LuciqFeatureFlag;
45
61
  import ai.luciq.library.internal.crossplatform.CoreFeature;
46
62
  import ai.luciq.library.internal.crossplatform.CoreFeaturesState;
47
63
  import ai.luciq.library.internal.crossplatform.FeaturesStateListener;
48
64
  import ai.luciq.library.internal.crossplatform.InternalCore;
49
- import ai.luciq.library.featuresflags.model.LuciqFeatureFlag;
50
- import ai.luciq.library.internal.crossplatform.InternalCore;
51
65
  import ai.luciq.library.internal.crossplatform.OnFeaturesUpdatedListener;
52
66
  import ai.luciq.library.internal.module.LuciqLocale;
53
67
  import ai.luciq.library.invocation.LuciqInvocationEvent;
@@ -56,29 +70,12 @@ import ai.luciq.library.model.LuciqTheme;
56
70
  import ai.luciq.library.model.NetworkLog;
57
71
  import ai.luciq.library.model.Report;
58
72
  import ai.luciq.library.ui.onboarding.WelcomeMessage;
59
- import ai.luciq.library.util.LuciqSDKLogger;
60
73
  import ai.luciq.reactlibrary.utils.ArrayUtil;
61
74
  import ai.luciq.reactlibrary.utils.EventEmitterModule;
75
+ import ai.luciq.reactlibrary.utils.LuciqRNLogger;
62
76
  import ai.luciq.reactlibrary.utils.MainThreadHandler;
63
-
64
77
  import ai.luciq.reactlibrary.utils.RNTouchedViewExtractor;
65
78
 
66
- import org.json.JSONException;
67
- import org.json.JSONObject;
68
- import org.json.JSONTokener;
69
-
70
- import java.io.File;
71
- import java.lang.reflect.Method;
72
- import java.util.ArrayList;
73
- import java.util.Arrays;
74
- import java.util.HashMap;
75
- import java.util.Iterator;
76
- import java.util.List;
77
- import java.util.Locale;
78
- import java.util.Map;
79
-
80
- import javax.annotation.Nullable;
81
-
82
79
 
83
80
  /**
84
81
  * The type Rn luciq reactnative module.
@@ -86,7 +83,7 @@ import javax.annotation.Nullable;
86
83
  public class RNLuciqReactnativeModule extends EventEmitterModule {
87
84
 
88
85
  private static final String TAG = "Luciq-RN-Core";
89
- private static final String NET_TAG = "LCQ-RN-NET";
86
+ ;
90
87
 
91
88
  private LuciqCustomTextPlaceHolder placeHolders;
92
89
  private static Report currentReport;
@@ -124,6 +121,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
124
121
 
125
122
  /**
126
123
  * Enables or disables Luciq functionality.
124
+ *
127
125
  * @param isEnabled A boolean to enable/disable Luciq.
128
126
  */
129
127
  @ReactMethod
@@ -164,7 +162,9 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
164
162
 
165
163
 
166
164
  ) {
167
- Log.d(NET_TAG, "[init] Called — logLevel=" + logLevel + ", useNativeNetworkInterception=" + useNativeNetworkInterception + ", codePushVersion=" + codePushVersion + ", appVariant=" + appVariant);
165
+ final int parsedLogLevel = ArgsRegistry.sdkLogLevels.getOrDefault(logLevel, LogLevel.ERROR);
166
+ LuciqRNLogger.setLevel(parsedLogLevel);
167
+ LuciqRNLogger.d(NET_TAG, "[init] Called — logLevel=" + logLevel + ", useNativeNetworkInterception=" + useNativeNetworkInterception + ", codePushVersion=" + codePushVersion + ", appVariant=" + appVariant);
168
168
  MainThreadHandler.runOnMainThread(new Runnable() {
169
169
  @Override
170
170
  public void run() {
@@ -173,7 +173,6 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
173
173
  final ArrayList<String> keys = ArrayUtil.parseReadableArrayOfStrings(invocationEventValues);
174
174
  final ArrayList<LuciqInvocationEvent> parsedInvocationEvents = ArgsRegistry.invocationEvents.getAll(keys);
175
175
  final LuciqInvocationEvent[] invocationEvents = parsedInvocationEvents.toArray(new LuciqInvocationEvent[0]);
176
- final int parsedLogLevel = ArgsRegistry.sdkLogLevels.getOrDefault(logLevel, LogLevel.ERROR);
177
176
 
178
177
  final Application application = (Application) reactContext.getApplicationContext();
179
178
 
@@ -181,7 +180,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
181
180
  .setInvocationEvents(invocationEvents)
182
181
  .setLogLevel(parsedLogLevel);
183
182
 
184
- if (map!=null&&map.hasKey("ignoreAndroidSecureFlag")) {
183
+ if (map != null && map.hasKey("ignoreAndroidSecureFlag")) {
185
184
  builder.ignoreFlagSecure(map.getBoolean("ignoreAndroidSecureFlag"));
186
185
  }
187
186
 
@@ -192,12 +191,12 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
192
191
  builder.setCodePushVersion(codePushVersion);
193
192
  }
194
193
  }
195
- if (appVariant != null) {
196
- builder.setAppVariant(appVariant);
197
- }
194
+ if (appVariant != null) {
195
+ builder.setAppVariant(appVariant);
196
+ }
198
197
 
199
- if(overAirVersion != null ) {
200
- if(Luciq.isBuilt()) {
198
+ if (overAirVersion != null) {
199
+ if (Luciq.isBuilt()) {
201
200
  Luciq.setOverAirVersion(overAirVersion.getString("version"),
202
201
  ArgsRegistry.overAirUpdateService.get(overAirVersion.getString("service")));
203
202
  } else {
@@ -206,7 +205,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
206
205
  }
207
206
 
208
207
  builder.build();
209
- Log.d(NET_TAG, "[init] SDK build complete");
208
+ LuciqRNLogger.d(NET_TAG, "[init] SDK build complete");
210
209
  }
211
210
  });
212
211
  }
@@ -550,7 +549,6 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
550
549
  }
551
550
 
552
551
 
553
-
554
552
  /**
555
553
  * Removes user attribute if exists.
556
554
  *
@@ -972,7 +970,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
972
970
  final String requestHeaders,
973
971
  final String responseHeaders,
974
972
  final double duration) {
975
- Log.d(NET_TAG, "[networkLogAndroid-Core] Received from JS: " + method + " " + url + ", status=" + (int) responseCode + ", duration=" + (long) duration + "ms, reqBodyLen=" + (requestBody != null ? requestBody.length() : 0) + ", resBodyLen=" + (responseBody != null ? responseBody.length() : 0));
973
+ LuciqRNLogger.d(NET_TAG, "[networkLogAndroid-Core] Received from JS: " + method + " " + url + ", status=" + (int) responseCode + ", duration=" + (long) duration + "ms, reqBodyLen=" + (requestBody != null ? requestBody.length() : 0) + ", resBodyLen=" + (responseBody != null ? responseBody.length() : 0));
976
974
  try {
977
975
  final String date = String.valueOf(System.currentTimeMillis());
978
976
 
@@ -989,14 +987,14 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
989
987
  networkLog.setRequestHeaders(requestHeaders);
990
988
  networkLog.setResponseHeaders(responseHeaders);
991
989
  } catch (OutOfMemoryError | Exception exception) {
992
- Log.e(NET_TAG, "[networkLogAndroid-Core] OOM/Error setting log contents: " + exception.getMessage() + " for " + method + " " + url);
990
+ LuciqRNLogger.e(NET_TAG, "[networkLogAndroid-Core] OOM/Error setting log contents: " + exception.getMessage() + " for " + method + " " + url);
993
991
  Log.d(TAG, "Error: " + exception.getMessage() + "while trying to set network log contents (request body, response body, request headers, and response headers).");
994
992
  }
995
993
 
996
994
  networkLog.insert();
997
- Log.d(NET_TAG, "[networkLogAndroid-Core] Successfully inserted NetworkLog: " + method + " " + url);
995
+ LuciqRNLogger.d(NET_TAG, "[networkLogAndroid-Core] Successfully inserted NetworkLog: " + method + " " + url);
998
996
  } catch (OutOfMemoryError | Exception exception) {
999
- Log.e(NET_TAG, "[networkLogAndroid-Core] OOM/Error inserting network log: " + exception.getMessage() + " for " + method + " " + url);
997
+ LuciqRNLogger.e(NET_TAG, "[networkLogAndroid-Core] OOM/Error inserting network log: " + exception.getMessage() + " for " + method + " " + url);
1000
998
  Log.d(TAG, "Error: " + exception.getMessage() + "while trying to insert a network log");
1001
999
  }
1002
1000
  }
@@ -1005,18 +1003,18 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1005
1003
  @Nullable
1006
1004
  private View resolveReactView(final int reactTag) {
1007
1005
  try {
1008
- final ReactApplicationContext reactContext = getReactApplicationContext();
1009
- final UIManagerModule uiManagerModule = reactContext.getNativeModule(UIManagerModule.class);
1006
+ final ReactApplicationContext reactContext = getReactApplicationContext();
1007
+ final UIManagerModule uiManagerModule = reactContext.getNativeModule(UIManagerModule.class);
1010
1008
 
1011
- if (uiManagerModule == null) {
1009
+ if (uiManagerModule == null) {
1012
1010
  UIManager uiNewManagerModule = UIManagerHelper.getUIManagerForReactTag(reactContext, reactTag);
1013
1011
  if (uiNewManagerModule != null) {
1014
1012
  return uiNewManagerModule.resolveView(reactTag);
1015
1013
  }
1016
- return null;
1017
- }
1014
+ return null;
1015
+ }
1018
1016
 
1019
- return uiManagerModule.resolveView(reactTag);
1017
+ return uiManagerModule.resolveView(reactTag);
1020
1018
  } catch (Exception e) {
1021
1019
  return null;
1022
1020
  }
@@ -1031,8 +1029,8 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1031
1029
  try {
1032
1030
  final View view = resolveReactView(reactTag);
1033
1031
 
1034
- if(view !=null){
1035
- Luciq.addPrivateViews(view);
1032
+ if (view != null) {
1033
+ Luciq.addPrivateViews(view);
1036
1034
  }
1037
1035
  } catch (Exception e) {
1038
1036
  e.printStackTrace();
@@ -1048,9 +1046,9 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1048
1046
  public void run() {
1049
1047
  try {
1050
1048
  final View view = resolveReactView(reactTag);
1051
- if(view !=null){
1049
+ if (view != null) {
1052
1050
 
1053
- Luciq.removePrivateViews(view);
1051
+ Luciq.removePrivateViews(view);
1054
1052
  }
1055
1053
  } catch (Exception e) {
1056
1054
  e.printStackTrace();
@@ -1085,7 +1083,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1085
1083
  * Reports that the screen has been changed (Repro Steps) the screen sent to this method will be the 'current view' on the dashboard
1086
1084
  *
1087
1085
  * @param screenName string containing the screen name
1088
- * @param spanId the span ID for screen loading tracking (nullable)
1086
+ * @param spanId the span ID for screen loading tracking (nullable)
1089
1087
  */
1090
1088
  @ReactMethod
1091
1089
  public void reportScreenChange(final String screenName, @Nullable final String spanId) {
@@ -1094,9 +1092,9 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1094
1092
  public void run() {
1095
1093
  try {
1096
1094
  Long uiTraceId = spanId != null ? Long.parseLong(spanId) : null;
1097
- Method method = getMethod(Class.forName("ai.luciq.library.Luciq"), "reportScreenChange", Bitmap.class, String.class , Long.class);
1095
+ Method method = getMethod(Class.forName("ai.luciq.library.Luciq"), "reportScreenChange", Bitmap.class, String.class, Long.class);
1098
1096
  if (method != null) {
1099
- method.invoke(null, null, screenName , uiTraceId);
1097
+ method.invoke(null, null, screenName, uiTraceId);
1100
1098
  }
1101
1099
  } catch (Exception e) {
1102
1100
  e.printStackTrace();
@@ -1106,7 +1104,6 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1106
1104
  }
1107
1105
 
1108
1106
 
1109
-
1110
1107
  @ReactMethod
1111
1108
  public void addFeatureFlags(final ReadableMap featureFlagsMap) {
1112
1109
  MainThreadHandler.runOnMainThread(new Runnable() {
@@ -1179,7 +1176,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1179
1176
  */
1180
1177
  @ReactMethod
1181
1178
  public void registerFeatureFlagsChangeListener() {
1182
- Log.d(NET_TAG, "[registerFeatureFlagsChangeListener] Registering native feature flags listener");
1179
+ LuciqRNLogger.d(NET_TAG, "[registerFeatureFlagsChangeListener] Registering native feature flags listener");
1183
1180
  MainThreadHandler.runOnMainThread(new Runnable() {
1184
1181
  @Override
1185
1182
  public void run() {
@@ -1187,19 +1184,19 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1187
1184
  InternalCore.INSTANCE._setFeaturesStateListener(new FeaturesStateListener() {
1188
1185
  @Override
1189
1186
  public void invoke(@NonNull CoreFeaturesState featuresState) {
1190
- Log.d(NET_TAG, "[FeatureFlagsListener] Received update — W3CTraceID=" + featuresState.isW3CExternalTraceIdEnabled() + ", generatedHeader=" + featuresState.isAttachingGeneratedHeaderEnabled() + ", caughtHeader=" + featuresState.isAttachingCapturedHeaderEnabled() + ", networkBodyLimit=" + featuresState.getNetworkLogCharLimit());
1187
+ LuciqRNLogger.d(NET_TAG, "[FeatureFlagsListener] Received update — W3CTraceID=" + featuresState.isW3CExternalTraceIdEnabled() + ", generatedHeader=" + featuresState.isAttachingGeneratedHeaderEnabled() + ", caughtHeader=" + featuresState.isAttachingCapturedHeaderEnabled() + ", networkBodyLimit=" + featuresState.getNetworkLogCharLimit());
1191
1188
  WritableMap params = Arguments.createMap();
1192
1189
  params.putBoolean("isW3ExternalTraceIDEnabled", featuresState.isW3CExternalTraceIdEnabled());
1193
1190
  params.putBoolean("isW3ExternalGeneratedHeaderEnabled", featuresState.isAttachingGeneratedHeaderEnabled());
1194
1191
  params.putBoolean("isW3CaughtHeaderEnabled", featuresState.isAttachingCapturedHeaderEnabled());
1195
- params.putInt("networkBodyLimit",featuresState.getNetworkLogCharLimit());
1192
+ params.putInt("networkBodyLimit", featuresState.getNetworkLogCharLimit());
1196
1193
 
1197
1194
  sendEvent(Constants.LCQ_ON_FEATURE_FLAGS_UPDATE_RECEIVED_CALLBACK, params);
1198
- Log.d(NET_TAG, "[FeatureFlagsListener] Sent event to JS: " + Constants.LCQ_ON_FEATURE_FLAGS_UPDATE_RECEIVED_CALLBACK);
1195
+ LuciqRNLogger.d(NET_TAG, "[FeatureFlagsListener] Sent event to JS: " + Constants.LCQ_ON_FEATURE_FLAGS_UPDATE_RECEIVED_CALLBACK);
1199
1196
  }
1200
1197
  });
1201
1198
  } catch (Exception e) {
1202
- Log.e(NET_TAG, "[registerFeatureFlagsChangeListener] Failed to register listener", e);
1199
+ LuciqRNLogger.e(NET_TAG, "[registerFeatureFlagsChangeListener] Failed to register listener", e);
1203
1200
  e.printStackTrace();
1204
1201
  }
1205
1202
 
@@ -1214,16 +1211,16 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1214
1211
  */
1215
1212
  @ReactMethod
1216
1213
  public void isW3ExternalTraceIDEnabled(Promise promise) {
1217
- Log.d(NET_TAG, "[isW3ExternalTraceIDEnabled] Querying native flag");
1214
+ LuciqRNLogger.d(NET_TAG, "[isW3ExternalTraceIDEnabled] Querying native flag");
1218
1215
  MainThreadHandler.runOnMainThread(new Runnable() {
1219
1216
  @Override
1220
1217
  public void run() {
1221
1218
  try {
1222
1219
  boolean enabled = InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_EXTERNAL_TRACE_ID);
1223
- Log.d(NET_TAG, "[isW3ExternalTraceIDEnabled] Result=" + enabled);
1220
+ LuciqRNLogger.d(NET_TAG, "[isW3ExternalTraceIDEnabled] Result=" + enabled);
1224
1221
  promise.resolve(enabled);
1225
1222
  } catch (Exception e) {
1226
- Log.e(NET_TAG, "[isW3ExternalTraceIDEnabled] Error querying flag", e);
1223
+ LuciqRNLogger.e(NET_TAG, "[isW3ExternalTraceIDEnabled] Error querying flag", e);
1227
1224
  e.printStackTrace();
1228
1225
  promise.resolve(false);
1229
1226
  }
@@ -1239,16 +1236,16 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1239
1236
  */
1240
1237
  @ReactMethod
1241
1238
  public void isW3ExternalGeneratedHeaderEnabled(Promise promise) {
1242
- Log.d(NET_TAG, "[isW3ExternalGeneratedHeaderEnabled] Querying native flag");
1239
+ LuciqRNLogger.d(NET_TAG, "[isW3ExternalGeneratedHeaderEnabled] Querying native flag");
1243
1240
  MainThreadHandler.runOnMainThread(new Runnable() {
1244
1241
  @Override
1245
1242
  public void run() {
1246
1243
  try {
1247
1244
  boolean enabled = InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_ATTACHING_GENERATED_HEADER);
1248
- Log.d(NET_TAG, "[isW3ExternalGeneratedHeaderEnabled] Result=" + enabled);
1245
+ LuciqRNLogger.d(NET_TAG, "[isW3ExternalGeneratedHeaderEnabled] Result=" + enabled);
1249
1246
  promise.resolve(enabled);
1250
1247
  } catch (Exception e) {
1251
- Log.e(NET_TAG, "[isW3ExternalGeneratedHeaderEnabled] Error querying flag", e);
1248
+ LuciqRNLogger.e(NET_TAG, "[isW3ExternalGeneratedHeaderEnabled] Error querying flag", e);
1252
1249
  e.printStackTrace();
1253
1250
  promise.resolve(false);
1254
1251
  }
@@ -1263,16 +1260,16 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1263
1260
  */
1264
1261
  @ReactMethod
1265
1262
  public void isW3CaughtHeaderEnabled(Promise promise) {
1266
- Log.d(NET_TAG, "[isW3CaughtHeaderEnabled] Querying native flag");
1263
+ LuciqRNLogger.d(NET_TAG, "[isW3CaughtHeaderEnabled] Querying native flag");
1267
1264
  MainThreadHandler.runOnMainThread(new Runnable() {
1268
1265
  @Override
1269
1266
  public void run() {
1270
1267
  try {
1271
1268
  boolean enabled = InternalCore.INSTANCE._isFeatureEnabled(CoreFeature.W3C_ATTACHING_CAPTURED_HEADER);
1272
- Log.d(NET_TAG, "[isW3CaughtHeaderEnabled] Result=" + enabled);
1269
+ LuciqRNLogger.d(NET_TAG, "[isW3CaughtHeaderEnabled] Result=" + enabled);
1273
1270
  promise.resolve(enabled);
1274
1271
  } catch (Exception e) {
1275
- Log.e(NET_TAG, "[isW3CaughtHeaderEnabled] Error querying flag", e);
1272
+ LuciqRNLogger.e(NET_TAG, "[isW3CaughtHeaderEnabled] Error querying flag", e);
1276
1273
  e.printStackTrace();
1277
1274
  promise.resolve(false);
1278
1275
  }
@@ -1287,7 +1284,7 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1287
1284
  * Map between the exported JS constant and the arg key in {@link ArgsRegistry}.
1288
1285
  * The constant name and the arg key should match to be able to resolve the
1289
1286
  * constant with its actual value from the {@link ArgsRegistry} maps.
1290
- *
1287
+ * <p>
1291
1288
  * This is a workaround, because RN cannot resolve enums in the constants map.
1292
1289
  */
1293
1290
  @Override
@@ -1318,23 +1315,25 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1318
1315
  }
1319
1316
  });
1320
1317
  }
1318
+
1321
1319
  /**
1322
- * Enables or disables capturing network body.
1323
- * @param isEnabled A boolean to enable/disable capturing network body.
1324
- */
1325
- @ReactMethod
1326
- public void setNetworkLogBodyEnabled(final boolean isEnabled) {
1327
- MainThreadHandler.runOnMainThread(new Runnable() {
1328
- @Override
1329
- public void run() {
1330
- try {
1331
- Luciq.setNetworkLogBodyEnabled(isEnabled);
1332
- } catch (Exception e) {
1333
- e.printStackTrace();
1334
- }
1335
- }
1336
- });
1337
- }
1320
+ * Enables or disables capturing network body.
1321
+ *
1322
+ * @param isEnabled A boolean to enable/disable capturing network body.
1323
+ */
1324
+ @ReactMethod
1325
+ public void setNetworkLogBodyEnabled(final boolean isEnabled) {
1326
+ MainThreadHandler.runOnMainThread(new Runnable() {
1327
+ @Override
1328
+ public void run() {
1329
+ try {
1330
+ Luciq.setNetworkLogBodyEnabled(isEnabled);
1331
+ } catch (Exception e) {
1332
+ e.printStackTrace();
1333
+ }
1334
+ }
1335
+ });
1336
+ }
1338
1337
 
1339
1338
  /**
1340
1339
  * Sets the auto mask screenshots types.
@@ -1366,16 +1365,16 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1366
1365
  */
1367
1366
  @ReactMethod
1368
1367
  public void getNetworkBodyMaxSize(Promise promise) {
1369
- Log.d(NET_TAG, "[getNetworkBodyMaxSize] Querying network body size limit");
1368
+ LuciqRNLogger.d(NET_TAG, "[getNetworkBodyMaxSize] Querying network body size limit");
1370
1369
  MainThreadHandler.runOnMainThread(new Runnable() {
1371
1370
  @Override
1372
1371
  public void run() {
1373
1372
  try {
1374
1373
  Object limit = InternalCore.INSTANCE.get_networkLogCharLimit();
1375
- Log.d(NET_TAG, "[getNetworkBodyMaxSize] Result=" + limit);
1374
+ LuciqRNLogger.d(NET_TAG, "[getNetworkBodyMaxSize] Result=" + limit);
1376
1375
  promise.resolve(limit);
1377
1376
  } catch (Exception e) {
1378
- Log.e(NET_TAG, "[getNetworkBodyMaxSize] Error querying limit", e);
1377
+ LuciqRNLogger.e(NET_TAG, "[getNetworkBodyMaxSize] Error querying limit", e);
1379
1378
  e.printStackTrace();
1380
1379
  promise.resolve(false);
1381
1380
  }
@@ -1383,20 +1382,20 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1383
1382
  });
1384
1383
  }
1385
1384
 
1386
- /**
1387
- * Sets current App variant
1388
- *
1389
- * @param appVariant The app variant name .
1390
- */
1391
- @ReactMethod
1392
- public void setAppVariant(@NonNull String appVariant) {
1393
- try {
1394
- Luciq.setAppVariant(appVariant);
1385
+ /**
1386
+ * Sets current App variant
1387
+ *
1388
+ * @param appVariant The app variant name .
1389
+ */
1390
+ @ReactMethod
1391
+ public void setAppVariant(@NonNull String appVariant) {
1392
+ try {
1393
+ Luciq.setAppVariant(appVariant);
1395
1394
 
1396
- } catch (Exception e) {
1397
- e.printStackTrace();
1398
- }
1395
+ } catch (Exception e) {
1396
+ e.printStackTrace();
1399
1397
  }
1398
+ }
1400
1399
 
1401
1400
  /**
1402
1401
  * Enables or disables WebView monitoring.
@@ -1527,17 +1526,16 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1527
1526
  }
1528
1527
 
1529
1528
 
1530
-
1531
1529
  /**
1532
1530
  * Applies a color to the theme builder if present in the configuration.
1533
1531
  *
1534
1532
  * @param themeConfig The theme configuration map
1535
- * @param builder The theme builder
1536
- * @param key The configuration key
1537
- * @param setter The color setter function
1533
+ * @param builder The theme builder
1534
+ * @param key The configuration key
1535
+ * @param setter The color setter function
1538
1536
  */
1539
1537
  private void applyColorIfPresent(ReadableMap themeConfig, ai.luciq.library.model.LuciqTheme.Builder builder,
1540
- String key, java.util.function.BiConsumer<ai.luciq.library.model.LuciqTheme.Builder, Integer> setter) {
1538
+ String key, java.util.function.BiConsumer<ai.luciq.library.model.LuciqTheme.Builder, Integer> setter) {
1541
1539
  if (themeConfig.hasKey(key)) {
1542
1540
  int color = getColor(themeConfig, key);
1543
1541
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
@@ -1550,12 +1548,12 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1550
1548
  * Applies a text style to the theme builder if present in the configuration.
1551
1549
  *
1552
1550
  * @param themeConfig The theme configuration map
1553
- * @param builder The theme builder
1554
- * @param key The configuration key
1555
- * @param setter The text style setter function
1551
+ * @param builder The theme builder
1552
+ * @param key The configuration key
1553
+ * @param setter The text style setter function
1556
1554
  */
1557
1555
  private void applyTextStyleIfPresent(ReadableMap themeConfig, ai.luciq.library.model.LuciqTheme.Builder builder,
1558
- String key, java.util.function.BiConsumer<ai.luciq.library.model.LuciqTheme.Builder, Integer> setter) {
1556
+ String key, java.util.function.BiConsumer<ai.luciq.library.model.LuciqTheme.Builder, Integer> setter) {
1559
1557
  if (themeConfig.hasKey(key)) {
1560
1558
  int style = getTextStyle(themeConfig, key);
1561
1559
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
@@ -1568,13 +1566,13 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1568
1566
  * Sets a font on the theme builder if the font configuration is present in the theme config.
1569
1567
  *
1570
1568
  * @param themeConfig The theme configuration map
1571
- * @param builder The theme builder
1572
- * @param fileKey The key for font file path
1573
- * @param assetKey The key for font asset path
1574
- * @param fontType The type of font (for logging purposes)
1569
+ * @param builder The theme builder
1570
+ * @param fileKey The key for font file path
1571
+ * @param assetKey The key for font asset path
1572
+ * @param fontType The type of font (for logging purposes)
1575
1573
  */
1576
1574
  private void setFontIfPresent(ReadableMap themeConfig, ai.luciq.library.model.LuciqTheme.Builder builder,
1577
- String fileKey, String assetKey, String fontType) {
1575
+ String fileKey, String assetKey, String fontType) {
1578
1576
  if (themeConfig.hasKey(fileKey) || themeConfig.hasKey(assetKey)) {
1579
1577
  Typeface typeface = getTypeface(themeConfig, fileKey, assetKey);
1580
1578
  if (typeface != null) {
@@ -1659,27 +1657,28 @@ public class RNLuciqReactnativeModule extends EventEmitterModule {
1659
1657
  return Typeface.DEFAULT;
1660
1658
  }
1661
1659
 
1662
- /**
1663
- * Extracts the filename from a path, removing any directory prefixes.
1664
- *
1665
- * @param path The full path to the file
1666
- * @return Just the filename with extension
1667
- */
1668
- private String getFileName(String path) {
1669
- if (path == null || path.isEmpty()) {
1670
- return path;
1671
- }
1660
+ /**
1661
+ * Extracts the filename from a path, removing any directory prefixes.
1662
+ *
1663
+ * @param path The full path to the file
1664
+ * @return Just the filename with extension
1665
+ */
1666
+ private String getFileName(String path) {
1667
+ if (path == null || path.isEmpty()) {
1668
+ return path;
1669
+ }
1672
1670
 
1673
- int lastSeparator = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
1674
- if (lastSeparator >= 0 && lastSeparator < path.length() - 1) {
1675
- return path.substring(lastSeparator + 1);
1676
- }
1671
+ int lastSeparator = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
1672
+ if (lastSeparator >= 0 && lastSeparator < path.length() - 1) {
1673
+ return path.substring(lastSeparator + 1);
1674
+ }
1677
1675
 
1678
- return path;
1679
- }
1676
+ return path;
1677
+ }
1680
1678
 
1681
- /**
1679
+ /**
1682
1680
  * Enables or disables displaying in full-screen mode, hiding the status and navigation bars.
1681
+ *
1683
1682
  * @param isEnabled A boolean to enable/disable setFullscreen.
1684
1683
  */
1685
1684
  @ReactMethod
@@ -1688,7 +1687,7 @@ private String getFileName(String path) {
1688
1687
  @Override
1689
1688
  public void run() {
1690
1689
  try {
1691
- Luciq.setFullscreen(isEnabled);
1690
+ Luciq.setFullscreen(isEnabled);
1692
1691
  } catch (Exception e) {
1693
1692
  e.printStackTrace();
1694
1693
  }
@@ -1,7 +1,5 @@
1
1
  package ai.luciq.reactlibrary.utils;
2
2
 
3
- import android.util.Log;
4
-
5
3
  import androidx.annotation.Nullable;
6
4
  import androidx.annotation.VisibleForTesting;
7
5
 
@@ -26,17 +24,17 @@ public abstract class EventEmitterModule extends ReactContextBaseJavaModule {
26
24
  .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
27
25
  .emit(event, params);
28
26
  } else {
29
- Log.w(NET_TAG, "[EventEmitter] Event DROPPED (no JS listeners): event=" + event + ", module=" + getName() + ", listenerCount=0");
27
+ LuciqRNLogger.w(NET_TAG, "[EventEmitter] Event DROPPED (no JS listeners): event=" + event + ", module=" + getName() + ", listenerCount=0");
30
28
  }
31
29
  }
32
30
 
33
31
  protected void addListener(String ignoredEvent) {
34
32
  listenerCount++;
35
- Log.d(NET_TAG, "[EventEmitter] addListener — module=" + getName() + ", event=" + ignoredEvent + ", listenerCount=" + listenerCount);
33
+ LuciqRNLogger.d(NET_TAG, "[EventEmitter] addListener — module=" + getName() + ", event=" + ignoredEvent + ", listenerCount=" + listenerCount);
36
34
  }
37
35
 
38
36
  protected void removeListeners(Integer count) {
39
37
  listenerCount -= count;
40
- Log.d(NET_TAG, "[EventEmitter] removeListeners — module=" + getName() + ", removed=" + count + ", listenerCount=" + listenerCount);
38
+ LuciqRNLogger.d(NET_TAG, "[EventEmitter] removeListeners — module=" + getName() + ", removed=" + count + ", listenerCount=" + listenerCount);
41
39
  }
42
40
  }
@@ -0,0 +1,53 @@
1
+ package ai.luciq.reactlibrary.utils;
2
+
3
+ import android.util.Log;
4
+
5
+ import ai.luciq.library.LogLevel;
6
+
7
+ /**
8
+ * Bridge-side logger that gates android.util.Log calls on the same
9
+ * debugLogsLevel the host app passes to Luciq.init(), so the native
10
+ * RN bridge diagnostic logs do not leak in production builds when the
11
+ * JS-side Logger is silent.
12
+ *
13
+ * Mirrors the level hierarchy in src/utils/logger.ts:
14
+ * VERBOSE > DEBUG > ERROR > NONE
15
+ */
16
+ public final class LuciqRNLogger {
17
+
18
+ private static volatile int currentLevel = LogLevel.ERROR;
19
+
20
+ private LuciqRNLogger() {}
21
+
22
+ public static void setLevel(int level) {
23
+ currentLevel = level;
24
+ }
25
+
26
+ public static int getLevel() {
27
+ return currentLevel;
28
+ }
29
+
30
+ public static void d(String tag, String message) {
31
+ if (currentLevel >= LogLevel.DEBUG) {
32
+ Log.d(tag, message);
33
+ }
34
+ }
35
+
36
+ public static void w(String tag, String message) {
37
+ if (currentLevel >= LogLevel.DEBUG) {
38
+ Log.w(tag, message);
39
+ }
40
+ }
41
+
42
+ public static void e(String tag, String message) {
43
+ if (currentLevel >= LogLevel.ERROR) {
44
+ Log.e(tag, message);
45
+ }
46
+ }
47
+
48
+ public static void e(String tag, String message, Throwable throwable) {
49
+ if (currentLevel >= LogLevel.ERROR) {
50
+ Log.e(tag, message, throwable);
51
+ }
52
+ }
53
+ }