react-native-debug-toolkit 3.2.3 → 3.2.5

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 (74) hide show
  1. package/android/src/main/java/com/reactnativedebugtoolkit/DebugToolkitDevConnectModule.java +80 -10
  2. package/ios/DebugToolkitDevConnect.mm +84 -19
  3. package/lib/commonjs/core/initialize.js +15 -3
  4. package/lib/commonjs/core/initialize.js.map +1 -1
  5. package/lib/commonjs/features/devConnect/DevConnectTab.js +121 -58
  6. package/lib/commonjs/features/devConnect/DevConnectTab.js.map +1 -1
  7. package/lib/commonjs/features/devConnect/devConnectPreferences.js +6 -2
  8. package/lib/commonjs/features/devConnect/devConnectPreferences.js.map +1 -1
  9. package/lib/commonjs/features/devConnect/devConnectUtils.js +8 -0
  10. package/lib/commonjs/features/devConnect/devConnectUtils.js.map +1 -1
  11. package/lib/commonjs/features/devConnect/index.js +33 -5
  12. package/lib/commonjs/features/devConnect/index.js.map +1 -1
  13. package/lib/commonjs/features/devConnect/nativeDevConnect.js +26 -0
  14. package/lib/commonjs/features/devConnect/nativeDevConnect.js.map +1 -1
  15. package/lib/commonjs/ui/DebugView.js +10 -2
  16. package/lib/commonjs/ui/DebugView.js.map +1 -1
  17. package/lib/commonjs/utils/DaemonClient.js +5 -0
  18. package/lib/commonjs/utils/DaemonClient.js.map +1 -1
  19. package/lib/module/core/initialize.js +16 -4
  20. package/lib/module/core/initialize.js.map +1 -1
  21. package/lib/module/features/devConnect/DevConnectTab.js +122 -59
  22. package/lib/module/features/devConnect/DevConnectTab.js.map +1 -1
  23. package/lib/module/features/devConnect/devConnectPreferences.js +6 -2
  24. package/lib/module/features/devConnect/devConnectPreferences.js.map +1 -1
  25. package/lib/module/features/devConnect/devConnectUtils.js +7 -0
  26. package/lib/module/features/devConnect/devConnectUtils.js.map +1 -1
  27. package/lib/module/features/devConnect/index.js +30 -7
  28. package/lib/module/features/devConnect/index.js.map +1 -1
  29. package/lib/module/features/devConnect/nativeDevConnect.js +24 -0
  30. package/lib/module/features/devConnect/nativeDevConnect.js.map +1 -1
  31. package/lib/module/ui/DebugView.js +11 -3
  32. package/lib/module/ui/DebugView.js.map +1 -1
  33. package/lib/module/utils/DaemonClient.js +5 -0
  34. package/lib/module/utils/DaemonClient.js.map +1 -1
  35. package/lib/typescript/src/core/initialize.d.ts +4 -2
  36. package/lib/typescript/src/core/initialize.d.ts.map +1 -1
  37. package/lib/typescript/src/features/devConnect/DevConnectTab.d.ts +1 -1
  38. package/lib/typescript/src/features/devConnect/DevConnectTab.d.ts.map +1 -1
  39. package/lib/typescript/src/features/devConnect/devConnectPreferences.d.ts.map +1 -1
  40. package/lib/typescript/src/features/devConnect/devConnectUtils.d.ts +1 -0
  41. package/lib/typescript/src/features/devConnect/devConnectUtils.d.ts.map +1 -1
  42. package/lib/typescript/src/features/devConnect/index.d.ts +1 -0
  43. package/lib/typescript/src/features/devConnect/index.d.ts.map +1 -1
  44. package/lib/typescript/src/features/devConnect/nativeDevConnect.d.ts +2 -0
  45. package/lib/typescript/src/features/devConnect/nativeDevConnect.d.ts.map +1 -1
  46. package/lib/typescript/src/features/devConnect/types.d.ts +5 -1
  47. package/lib/typescript/src/features/devConnect/types.d.ts.map +1 -1
  48. package/lib/typescript/src/ui/DebugView.d.ts.map +1 -1
  49. package/lib/typescript/src/utils/DaemonClient.d.ts +2 -0
  50. package/lib/typescript/src/utils/DaemonClient.d.ts.map +1 -1
  51. package/package.json +2 -10
  52. package/src/core/initialize.ts +17 -5
  53. package/src/features/devConnect/DevConnectTab.tsx +120 -45
  54. package/src/features/devConnect/devConnectPreferences.ts +7 -2
  55. package/src/features/devConnect/devConnectUtils.ts +8 -0
  56. package/src/features/devConnect/index.ts +31 -7
  57. package/src/features/devConnect/nativeDevConnect.ts +28 -0
  58. package/src/features/devConnect/types.ts +9 -1
  59. package/src/ui/DebugView.tsx +12 -3
  60. package/src/utils/DaemonClient.ts +7 -0
  61. package/lib/commonjs/features/devConnect/DevConnectQrScanner.js +0 -248
  62. package/lib/commonjs/features/devConnect/DevConnectQrScanner.js.map +0 -1
  63. package/lib/commonjs/features/devConnect/cameraKit.js +0 -54
  64. package/lib/commonjs/features/devConnect/cameraKit.js.map +0 -1
  65. package/lib/module/features/devConnect/DevConnectQrScanner.js +0 -243
  66. package/lib/module/features/devConnect/DevConnectQrScanner.js.map +0 -1
  67. package/lib/module/features/devConnect/cameraKit.js +0 -49
  68. package/lib/module/features/devConnect/cameraKit.js.map +0 -1
  69. package/lib/typescript/src/features/devConnect/DevConnectQrScanner.d.ts +0 -10
  70. package/lib/typescript/src/features/devConnect/DevConnectQrScanner.d.ts.map +0 -1
  71. package/lib/typescript/src/features/devConnect/cameraKit.d.ts +0 -47
  72. package/lib/typescript/src/features/devConnect/cameraKit.d.ts.map +0 -1
  73. package/src/features/devConnect/DevConnectQrScanner.tsx +0 -214
  74. package/src/features/devConnect/cameraKit.ts +0 -93
@@ -7,6 +7,7 @@ import android.preference.PreferenceManager;
7
7
  import androidx.annotation.NonNull;
8
8
  import androidx.annotation.Nullable;
9
9
 
10
+ import com.reactnativedebugtoolkit.BuildConfig;
10
11
  import com.facebook.react.bridge.Arguments;
11
12
  import com.facebook.react.bridge.Promise;
12
13
  import com.facebook.react.bridge.ReactApplicationContext;
@@ -16,6 +17,10 @@ import com.facebook.react.bridge.UiThreadUtil;
16
17
  import com.facebook.react.bridge.WritableMap;
17
18
 
18
19
  import java.lang.reflect.Method;
20
+ import java.net.Inet4Address;
21
+ import java.net.InetAddress;
22
+ import java.net.NetworkInterface;
23
+ import java.util.Enumeration;
19
24
 
20
25
  public class DebugToolkitDevConnectModule extends ReactContextBaseJavaModule {
21
26
  private static final String MODULE_NAME = "DebugToolkitDevConnect";
@@ -47,7 +52,27 @@ public class DebugToolkitDevConnectModule extends ReactContextBaseJavaModule {
47
52
  }
48
53
  }
49
54
 
50
- private boolean triggerDevSupportReload(@Nullable Object devSupportManager) throws Exception {
55
+ private void setDebugServerHost(@Nullable Object devSupportManager, String hostPort) throws Exception {
56
+ if (devSupportManager == null) {
57
+ return;
58
+ }
59
+
60
+ Object devSettings = callGetter(devSupportManager, "getDevSettings");
61
+ Object packagerConnectionSettings = devSettings == null
62
+ ? null
63
+ : callGetter(devSettings, "getPackagerConnectionSettings");
64
+ if (packagerConnectionSettings == null) {
65
+ return;
66
+ }
67
+
68
+ Method setter = packagerConnectionSettings.getClass().getMethod("setDebugServerHost", String.class);
69
+ setter.invoke(packagerConnectionSettings, hostPort);
70
+ }
71
+
72
+ private boolean triggerDevSupportReload(
73
+ @Nullable Object devSupportManager,
74
+ String hostPort
75
+ ) throws Exception {
51
76
  if (devSupportManager == null) {
52
77
  return false;
53
78
  }
@@ -57,18 +82,23 @@ public class DebugToolkitDevConnectModule extends ReactContextBaseJavaModule {
57
82
  return false;
58
83
  }
59
84
 
85
+ setDebugServerHost(devSupportManager, hostPort);
60
86
  Method reloadMethod = devSupportManager.getClass().getMethod("handleReloadJS");
61
87
  reloadMethod.invoke(devSupportManager);
62
88
  return true;
63
89
  }
64
90
 
65
- private boolean reloadFromReactHost(Context applicationContext, String reason) throws Exception {
91
+ private boolean reloadFromReactHost(
92
+ Context applicationContext,
93
+ String reason,
94
+ String hostPort
95
+ ) throws Exception {
66
96
  Object reactHost = callGetter(applicationContext, "getReactHost");
67
97
  if (reactHost == null) {
68
98
  return false;
69
99
  }
70
100
 
71
- if (triggerDevSupportReload(callGetter(reactHost, "getDevSupportManager"))) {
101
+ if (triggerDevSupportReload(callGetter(reactHost, "getDevSupportManager"), hostPort)) {
72
102
  return true;
73
103
  }
74
104
 
@@ -77,7 +107,7 @@ public class DebugToolkitDevConnectModule extends ReactContextBaseJavaModule {
77
107
  return true;
78
108
  }
79
109
 
80
- private boolean reloadFromReactNativeHost(Context applicationContext) throws Exception {
110
+ private boolean reloadFromReactNativeHost(Context applicationContext, String hostPort) throws Exception {
81
111
  Object reactNativeHost = callGetter(applicationContext, "getReactNativeHost");
82
112
  Object instanceManager = reactNativeHost == null
83
113
  ? null
@@ -85,15 +115,20 @@ public class DebugToolkitDevConnectModule extends ReactContextBaseJavaModule {
85
115
  Object devSupportManager = instanceManager == null
86
116
  ? null
87
117
  : callGetter(instanceManager, "getDevSupportManager");
88
- return triggerDevSupportReload(devSupportManager);
118
+ return triggerDevSupportReload(devSupportManager, hostPort);
89
119
  }
90
120
 
91
- private void resolveAfterReload(String reason, @Nullable WritableMap result, Promise promise) {
121
+ private void resolveAfterReload(
122
+ String reason,
123
+ @Nullable WritableMap result,
124
+ String hostPort,
125
+ Promise promise
126
+ ) {
92
127
  UiThreadUtil.runOnUiThread(() -> {
93
128
  try {
94
129
  Context applicationContext = getReactApplicationContext().getApplicationContext();
95
- boolean reloaded = reloadFromReactHost(applicationContext, reason)
96
- || reloadFromReactNativeHost(applicationContext);
130
+ boolean reloaded = reloadFromReactHost(applicationContext, reason, hostPort)
131
+ || reloadFromReactNativeHost(applicationContext, hostPort);
97
132
  if (!reloaded) {
98
133
  promise.reject("reload_unavailable", "Unable to trigger React Native reload after updating Metro host.");
99
134
  return;
@@ -126,7 +161,7 @@ public class DebugToolkitDevConnectModule extends ReactContextBaseJavaModule {
126
161
 
127
162
  WritableMap result = Arguments.createMap();
128
163
  result.putString("hostPort", hostPort);
129
- resolveAfterReload(APPLY_RELOAD_REASON, result, promise);
164
+ resolveAfterReload(APPLY_RELOAD_REASON, result, hostPort, promise);
130
165
  }
131
166
 
132
167
  @ReactMethod
@@ -137,7 +172,7 @@ public class DebugToolkitDevConnectModule extends ReactContextBaseJavaModule {
137
172
  return;
138
173
  }
139
174
 
140
- resolveAfterReload(RESET_RELOAD_REASON, null, promise);
175
+ resolveAfterReload(RESET_RELOAD_REASON, null, "", promise);
141
176
  }
142
177
 
143
178
  @ReactMethod
@@ -151,4 +186,39 @@ public class DebugToolkitDevConnectModule extends ReactContextBaseJavaModule {
151
186
  getPreferences().edit().putString(key, value).apply();
152
187
  promise.resolve(null);
153
188
  }
189
+
190
+ @ReactMethod
191
+ public void isDebugBuild(Promise promise) {
192
+ promise.resolve("debug".equals(BuildConfig.BUILD_TYPE));
193
+ }
194
+
195
+ @ReactMethod
196
+ public void getLocalIp(Promise promise) {
197
+ try {
198
+ Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
199
+ String fallback = null;
200
+ while (interfaces != null && interfaces.hasMoreElements()) {
201
+ NetworkInterface iface = interfaces.nextElement();
202
+ if (iface.isLoopback() || !iface.isUp()) continue;
203
+ String name = iface.getName();
204
+ Enumeration<InetAddress> addresses = iface.getInetAddresses();
205
+ while (addresses.hasMoreElements()) {
206
+ InetAddress addr = addresses.nextElement();
207
+ if (addr instanceof Inet4Address && !addr.isLoopbackAddress()) {
208
+ String ip = addr.getHostAddress();
209
+ if (name != null && (name.startsWith("wlan") || name.startsWith("eth"))) {
210
+ promise.resolve(ip);
211
+ return;
212
+ }
213
+ if (fallback == null) {
214
+ fallback = ip;
215
+ }
216
+ }
217
+ }
218
+ }
219
+ promise.resolve(fallback);
220
+ } catch (Exception e) {
221
+ promise.resolve(null);
222
+ }
223
+ }
154
224
  }
@@ -1,23 +1,14 @@
1
1
  #import <Foundation/Foundation.h>
2
+ #import <React/RCTBundleManager.h>
2
3
  #import <React/RCTBridgeModule.h>
3
4
  #import <React/RCTBundleURLProvider.h>
4
5
  #import <React/RCTReloadCommand.h>
6
+ #include <ifaddrs.h>
7
+ #include <arpa/inet.h>
8
+ #include <net/if.h>
5
9
 
6
- static NSString *const DebugToolkitRCTJsLocationKey = @"RCT_jsLocation";
7
10
  static NSString *const DebugToolkitBundleRoot = @"index";
8
11
 
9
- static void DebugToolkitResolveAfterReload(NSString *reason, id result, RCTPromiseResolveBlock resolve)
10
- {
11
- dispatch_async(dispatch_get_main_queue(), ^{
12
- NSURL *bundleURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:DebugToolkitBundleRoot];
13
- if (bundleURL) {
14
- RCTReloadCommandSetBundleURL(bundleURL);
15
- }
16
- RCTTriggerReloadCommandListeners(reason);
17
- resolve(result ?: [NSNull null]);
18
- });
19
- }
20
-
21
12
  @interface DebugToolkitDevConnect : NSObject <RCTBridgeModule>
22
13
  @end
23
14
 
@@ -25,11 +16,30 @@ static void DebugToolkitResolveAfterReload(NSString *reason, id result, RCTPromi
25
16
 
26
17
  RCT_EXPORT_MODULE(DebugToolkitDevConnect)
27
18
 
19
+ @synthesize bundleManager = _bundleManager;
20
+
28
21
  + (BOOL)requiresMainQueueSetup
29
22
  {
30
23
  return NO;
31
24
  }
32
25
 
26
+ - (void)applyBundleURL:(NSURL *)bundleURL
27
+ reason:(NSString *)reason
28
+ result:(id)result
29
+ resolve:(RCTPromiseResolveBlock)resolve
30
+ {
31
+ dispatch_async(dispatch_get_main_queue(), ^{
32
+ if (bundleURL) {
33
+ if (self->_bundleManager) {
34
+ self->_bundleManager.bundleURL = bundleURL;
35
+ }
36
+ RCTReloadCommandSetBundleURL(bundleURL);
37
+ }
38
+ resolve(result ?: [NSNull null]);
39
+ RCTTriggerReloadCommandListeners(reason);
40
+ });
41
+ }
42
+
33
43
  RCT_EXPORT_METHOD(getMetroHost:(RCTPromiseResolveBlock)resolve
34
44
  rejecter:(__unused RCTPromiseRejectBlock)reject)
35
45
  {
@@ -47,17 +57,22 @@ RCT_EXPORT_METHOD(applyMetroHost:(NSString *)hostPort
47
57
  }
48
58
 
49
59
  [RCTBundleURLProvider sharedSettings].jsLocation = hostPort;
50
- DebugToolkitResolveAfterReload(@"DebugToolkit DevConnect Metro host changed", @{ @"hostPort" : hostPort }, resolve);
60
+ NSURL *bundleURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:DebugToolkitBundleRoot];
61
+ [self applyBundleURL:bundleURL
62
+ reason:@"DebugToolkit DevConnect Metro host changed"
63
+ result:@{ @"hostPort" : hostPort }
64
+ resolve:resolve];
51
65
  }
52
66
 
53
67
  RCT_EXPORT_METHOD(resetMetroHost:(RCTPromiseResolveBlock)resolve
54
68
  rejecter:(__unused RCTPromiseRejectBlock)reject)
55
69
  {
56
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
57
- [defaults removeObjectForKey:DebugToolkitRCTJsLocationKey];
58
- [defaults synchronize];
59
- [[NSNotificationCenter defaultCenter] postNotificationName:RCTBundleURLProviderUpdatedNotification object:nil];
60
- DebugToolkitResolveAfterReload(@"DebugToolkit DevConnect Metro host reset", [NSNull null], resolve);
70
+ [[RCTBundleURLProvider sharedSettings] resetToDefaults];
71
+ NSURL *bundleURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForFallbackExtension:nil];
72
+ [self applyBundleURL:bundleURL
73
+ reason:@"DebugToolkit DevConnect Metro host reset"
74
+ result:[NSNull null]
75
+ resolve:resolve];
61
76
  }
62
77
 
63
78
  RCT_EXPORT_METHOD(getPreference:(NSString *)key
@@ -78,4 +93,54 @@ RCT_EXPORT_METHOD(setPreference:(NSString *)key
78
93
  resolve([NSNull null]);
79
94
  }
80
95
 
96
+ RCT_EXPORT_METHOD(isDebugBuild:(RCTPromiseResolveBlock)resolve
97
+ rejecter:(__unused RCTPromiseRejectBlock)reject)
98
+ {
99
+ #if DEBUG
100
+ resolve(@YES);
101
+ #else
102
+ resolve(@NO);
103
+ #endif
104
+ }
105
+
106
+ RCT_EXPORT_METHOD(getLocalIp:(RCTPromiseResolveBlock)resolve
107
+ rejecter:(__unused RCTPromiseRejectBlock)reject)
108
+ {
109
+ struct ifaddrs *interfaces = NULL;
110
+ if (getifaddrs(&interfaces) == 0) {
111
+ // First pass: prefer Wi-Fi interface (en0)
112
+ struct ifaddrs *iface = interfaces;
113
+ while (iface != NULL) {
114
+ if (iface->ifa_addr->sa_family == AF_INET && !(iface->ifa_flags & IFF_LOOPBACK)) {
115
+ if (strcmp(iface->ifa_name, "en0") == 0) {
116
+ char addrStr[INET_ADDRSTRLEN];
117
+ struct sockaddr_in *sin = (struct sockaddr_in *)iface->ifa_addr;
118
+ inet_ntop(AF_INET, &sin->sin_addr, addrStr, sizeof(addrStr));
119
+ NSString *ip = [NSString stringWithUTF8String:addrStr];
120
+ freeifaddrs(interfaces);
121
+ resolve(ip);
122
+ return;
123
+ }
124
+ }
125
+ iface = iface->ifa_next;
126
+ }
127
+ // Second pass: any non-loopback IPv4
128
+ iface = interfaces;
129
+ while (iface != NULL) {
130
+ if (iface->ifa_addr->sa_family == AF_INET && !(iface->ifa_flags & IFF_LOOPBACK)) {
131
+ char addrStr[INET_ADDRSTRLEN];
132
+ struct sockaddr_in *sin = (struct sockaddr_in *)iface->ifa_addr;
133
+ inet_ntop(AF_INET, &sin->sin_addr, addrStr, sizeof(addrStr));
134
+ NSString *ip = [NSString stringWithUTF8String:addrStr];
135
+ freeifaddrs(interfaces);
136
+ resolve(ip);
137
+ return;
138
+ }
139
+ iface = iface->ifa_next;
140
+ }
141
+ }
142
+ freeifaddrs(interfaces);
143
+ resolve([NSNull null]);
144
+ }
145
+
81
146
  @end
@@ -57,14 +57,26 @@ function resolveDefaultFeatures() {
57
57
  /**
58
58
  * Initialize the debug toolkit.
59
59
  *
60
+ * Detects debug/release mode via native bridge first, falls back to `__DEV__`.
61
+ *
60
62
  * @example
61
- * initializeDebugToolkit({
63
+ * await initializeDebugToolkit({
62
64
  * features: { network: true, console: true },
63
65
  * enabled: true,
64
66
  * });
65
67
  */
66
- function initializeDebugToolkit(options) {
67
- const enabled = options?.enabled ?? isDebugMode;
68
+ async function initializeDebugToolkit(options) {
69
+ let enabled;
70
+ if (options?.enabled !== undefined) {
71
+ enabled = options.enabled;
72
+ } else {
73
+ try {
74
+ const nativeResult = await (0, _devConnect.nativeIsDebugBuild)();
75
+ enabled = nativeResult !== null ? nativeResult : isDebugMode;
76
+ } catch {
77
+ enabled = isDebugMode;
78
+ }
79
+ }
68
80
  const resolvedFeatures = options?.features ? resolveFeatureConfigs(options.features) : resolveDefaultFeatures();
69
81
  try {
70
82
  _DebugToolkit.DebugToolkit.setEnabled(enabled);
@@ -1 +1 @@
1
- {"version":3,"names":["_DebugToolkit","require","_network","_console","_zustand","_navigation","_track","_environment","_clipboard","_devConnect","_DaemonClient","isDebugMode","__DEV__","featureRegistry","network","createNetworkFeature","console","createConsoleLogFeature","zustand","createZustandLogFeature","navigation","createNavigationLogFeature","track","createTrackFeature","environment","createEnvironmentFeature","clipboard","createClipboardFeature","devConnect","createDevConnectFeature","DEFAULT_FEATURES","resolveFeatureConfigs","configs","features","entries","Object","name","config","creator","warn","undefined","push","resolveDefaultFeatures","map","initializeDebugToolkit","options","enabled","resolvedFeatures","DebugToolkit","setEnabled","reset","replaceFeatures","daemonClient","setEndpointDetector","url","addToBlacklist","hasFeatures","showLauncher","hideLauncher","restoreDevConnectSettingsToDaemon","then","restore","catch","error"],"sourceRoot":"../../../src","sources":["core/initialize.ts"],"mappings":";;;;;;AAAA,IAAAA,aAAA,GAAAC,OAAA;AACA,IAAAC,QAAA,GAAAD,OAAA;AAEA,IAAAE,QAAA,GAAAF,OAAA;AAEA,IAAAG,QAAA,GAAAH,OAAA;AAEA,IAAAI,WAAA,GAAAJ,OAAA;AAEA,IAAAK,MAAA,GAAAL,OAAA;AAEA,IAAAM,YAAA,GAAAN,OAAA;AACA,IAAAO,UAAA,GAAAP,OAAA;AACA,IAAAQ,WAAA,GAAAR,OAAA;AACA,IAAAS,aAAA,GAAAT,OAAA;AAGA,MAAMU,WAAW,GAAGC,OAAO;;AAE3B;;AAiBA;AACA;AACA;AACA,MAAMC,eAA8E,GAAG;EACrFC,OAAO,EAAEC,6BAAoB;EAC7BC,OAAO,EAAEC,gCAAuB;EAChCC,OAAO,EAAEC,gCAAuB;EAChCC,UAAU,EAAEC,sCAA0B;EACtCC,KAAK,EAAEC,yBAAkB;EACzBC,WAAW,EAAEC,qCAAwB;EACrCC,SAAS,EAAEC,iCAAsB;EACjCC,UAAU,EAAEC;AACd,CAAC;AAED,MAAMC,gBAAsC,GAAG,CAC7C,SAAS,EACT,SAAS,EACT,YAAY,EACZ,SAAS,EACT,OAAO,EACP,WAAW,EACX,YAAY,CACb;AAED,SAASC,qBAAqBA,CAACC,OAAuB,EAAqB;EACzE,MAAMC,QAA2B,GAAG,EAAE;EACtC,MAAMC,OAAO,GAAGC,MAAM,CAACD,OAAO,CAACF,OAAO,CAAoC;EAE1E,KAAK,MAAM,CAACI,IAAI,EAAEC,MAAM,CAAC,IAAIH,OAAO,EAAE;IACpC,IAAIG,MAAM,KAAK,KAAK,EAAE;IAEtB,MAAMC,OAAO,GAAGzB,eAAe,CAACuB,IAAI,CAAC;IACrC,IAAI,CAACE,OAAO,EAAE;MACZtB,OAAO,CAACuB,IAAI,CAAC,oCAAoCH,IAAI,GAAG,CAAC;MACzD;IACF;IAEA,IAAIC,MAAM,KAAK,IAAI,IAAIA,MAAM,KAAKG,SAAS,EAAE;MAC3CP,QAAQ,CAACQ,IAAI,CAACH,OAAO,CAAC,CAAC,CAAC;IAC1B,CAAC,MAAM,IAAI,OAAOD,MAAM,KAAK,QAAQ,EAAE;MACrCJ,QAAQ,CAACQ,IAAI,CAACH,OAAO,CAACD,MAAiC,CAAC,CAAC;IAC3D;EACF;EAEA,OAAOJ,QAAQ;AACjB;AAEA,SAASS,sBAAsBA,CAAA,EAAsB;EACnD,OAAOZ,gBAAgB,CAACa,GAAG,CAAEP,IAAI,IAAKvB,eAAe,CAACuB,IAAI,CAAC,CAAE,CAAC,CAAC;AACjE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASQ,sBAAsBA,CACpCC,OAA2B,EACN;EACrB,MAAMC,OAAO,GAAGD,OAAO,EAAEC,OAAO,IAAInC,WAAW;EAE/C,MAAMoC,gBAAgB,GAAGF,OAAO,EAAEZ,QAAQ,GACtCF,qBAAqB,CAACc,OAAO,CAACZ,QAAQ,CAAC,GACvCS,sBAAsB,CAAC,CAAC;EAE5B,IAAI;IACFM,0BAAY,CAACC,UAAU,CAACH,OAAO,CAAC;IAEhC,IAAI,CAACA,OAAO,EAAE;MACZE,0BAAY,CAACE,KAAK,CAAC,CAAC;MACpB,OAAOF,0BAAY;IACrB;IAEAA,0BAAY,CAACG,eAAe,CAACJ,gBAAgB,CAAC;IAE9CK,0BAAY,CAACC,mBAAmB,CAAEC,GAAG,IAAK;MACxC,IAAAC,uBAAc,EAACD,GAAG,CAAC;IACrB,CAAC,CAAC;IAEF,IAAIN,0BAAY,CAACQ,WAAW,CAAC,CAAC,EAAE;MAC9BR,0BAAY,CAACS,YAAY,CAAC,CAAC;IAC7B,CAAC,MAAM;MACLT,0BAAY,CAACU,YAAY,CAAC,CAAC;IAC7B;IAEA,IAAAC,6CAAiC,EAAC,CAAC,CAChCC,IAAI,CAAC,MAAMR,0BAAY,CAACS,OAAO,CAAC,CAAC,EAAE,MAAMT,0BAAY,CAACS,OAAO,CAAC,CAAC,CAAC,CAChEC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAElB,OAAOd,0BAAY;EACrB,CAAC,CAAC,OAAOe,KAAK,EAAE;IACd/C,OAAO,CAAC+C,KAAK,CAAC,uCAAuC,EAAEA,KAAK,CAAC;IAC7D,OAAOf,0BAAY;EACrB;AACF","ignoreList":[]}
1
+ {"version":3,"names":["_DebugToolkit","require","_network","_console","_zustand","_navigation","_track","_environment","_clipboard","_devConnect","_DaemonClient","isDebugMode","__DEV__","featureRegistry","network","createNetworkFeature","console","createConsoleLogFeature","zustand","createZustandLogFeature","navigation","createNavigationLogFeature","track","createTrackFeature","environment","createEnvironmentFeature","clipboard","createClipboardFeature","devConnect","createDevConnectFeature","DEFAULT_FEATURES","resolveFeatureConfigs","configs","features","entries","Object","name","config","creator","warn","undefined","push","resolveDefaultFeatures","map","initializeDebugToolkit","options","enabled","nativeResult","nativeIsDebugBuild","resolvedFeatures","DebugToolkit","setEnabled","reset","replaceFeatures","daemonClient","setEndpointDetector","url","addToBlacklist","hasFeatures","showLauncher","hideLauncher","restoreDevConnectSettingsToDaemon","then","restore","catch","error"],"sourceRoot":"../../../src","sources":["core/initialize.ts"],"mappings":";;;;;;AAAA,IAAAA,aAAA,GAAAC,OAAA;AACA,IAAAC,QAAA,GAAAD,OAAA;AAEA,IAAAE,QAAA,GAAAF,OAAA;AAEA,IAAAG,QAAA,GAAAH,OAAA;AAEA,IAAAI,WAAA,GAAAJ,OAAA;AAEA,IAAAK,MAAA,GAAAL,OAAA;AAEA,IAAAM,YAAA,GAAAN,OAAA;AACA,IAAAO,UAAA,GAAAP,OAAA;AACA,IAAAQ,WAAA,GAAAR,OAAA;AACA,IAAAS,aAAA,GAAAT,OAAA;AAGA,MAAMU,WAAW,GAAGC,OAAO;;AAE3B;;AAiBA;AACA;AACA;AACA,MAAMC,eAA8E,GAAG;EACrFC,OAAO,EAAEC,6BAAoB;EAC7BC,OAAO,EAAEC,gCAAuB;EAChCC,OAAO,EAAEC,gCAAuB;EAChCC,UAAU,EAAEC,sCAA0B;EACtCC,KAAK,EAAEC,yBAAkB;EACzBC,WAAW,EAAEC,qCAAwB;EACrCC,SAAS,EAAEC,iCAAsB;EACjCC,UAAU,EAAEC;AACd,CAAC;AAED,MAAMC,gBAAsC,GAAG,CAC7C,SAAS,EACT,SAAS,EACT,YAAY,EACZ,SAAS,EACT,OAAO,EACP,WAAW,EACX,YAAY,CACb;AAED,SAASC,qBAAqBA,CAACC,OAAuB,EAAqB;EACzE,MAAMC,QAA2B,GAAG,EAAE;EACtC,MAAMC,OAAO,GAAGC,MAAM,CAACD,OAAO,CAACF,OAAO,CAAoC;EAE1E,KAAK,MAAM,CAACI,IAAI,EAAEC,MAAM,CAAC,IAAIH,OAAO,EAAE;IACpC,IAAIG,MAAM,KAAK,KAAK,EAAE;IAEtB,MAAMC,OAAO,GAAGzB,eAAe,CAACuB,IAAI,CAAC;IACrC,IAAI,CAACE,OAAO,EAAE;MACZtB,OAAO,CAACuB,IAAI,CAAC,oCAAoCH,IAAI,GAAG,CAAC;MACzD;IACF;IAEA,IAAIC,MAAM,KAAK,IAAI,IAAIA,MAAM,KAAKG,SAAS,EAAE;MAC3CP,QAAQ,CAACQ,IAAI,CAACH,OAAO,CAAC,CAAC,CAAC;IAC1B,CAAC,MAAM,IAAI,OAAOD,MAAM,KAAK,QAAQ,EAAE;MACrCJ,QAAQ,CAACQ,IAAI,CAACH,OAAO,CAACD,MAAiC,CAAC,CAAC;IAC3D;EACF;EAEA,OAAOJ,QAAQ;AACjB;AAEA,SAASS,sBAAsBA,CAAA,EAAsB;EACnD,OAAOZ,gBAAgB,CAACa,GAAG,CAAEP,IAAI,IAAKvB,eAAe,CAACuB,IAAI,CAAC,CAAE,CAAC,CAAC;AACjE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAeQ,sBAAsBA,CAC1CC,OAA2B,EACG;EAC9B,IAAIC,OAAgB;EACpB,IAAID,OAAO,EAAEC,OAAO,KAAKN,SAAS,EAAE;IAClCM,OAAO,GAAGD,OAAO,CAACC,OAAO;EAC3B,CAAC,MAAM;IACL,IAAI;MACF,MAAMC,YAAY,GAAG,MAAM,IAAAC,8BAAkB,EAAC,CAAC;MAC/CF,OAAO,GAAGC,YAAY,KAAK,IAAI,GAAGA,YAAY,GAAGpC,WAAW;IAC9D,CAAC,CAAC,MAAM;MACNmC,OAAO,GAAGnC,WAAW;IACvB;EACF;EAEA,MAAMsC,gBAAgB,GAAGJ,OAAO,EAAEZ,QAAQ,GACtCF,qBAAqB,CAACc,OAAO,CAACZ,QAAQ,CAAC,GACvCS,sBAAsB,CAAC,CAAC;EAE5B,IAAI;IACFQ,0BAAY,CAACC,UAAU,CAACL,OAAO,CAAC;IAEhC,IAAI,CAACA,OAAO,EAAE;MACZI,0BAAY,CAACE,KAAK,CAAC,CAAC;MACpB,OAAOF,0BAAY;IACrB;IAEAA,0BAAY,CAACG,eAAe,CAACJ,gBAAgB,CAAC;IAE9CK,0BAAY,CAACC,mBAAmB,CAAEC,GAAG,IAAK;MACxC,IAAAC,uBAAc,EAACD,GAAG,CAAC;IACrB,CAAC,CAAC;IAEF,IAAIN,0BAAY,CAACQ,WAAW,CAAC,CAAC,EAAE;MAC9BR,0BAAY,CAACS,YAAY,CAAC,CAAC;IAC7B,CAAC,MAAM;MACLT,0BAAY,CAACU,YAAY,CAAC,CAAC;IAC7B;IAEA,IAAAC,6CAAiC,EAAC,CAAC,CAChCC,IAAI,CAAC,MAAMR,0BAAY,CAACS,OAAO,CAAC,CAAC,EAAE,MAAMT,0BAAY,CAACS,OAAO,CAAC,CAAC,CAAC,CAChEC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAElB,OAAOd,0BAAY;EACrB,CAAC,CAAC,OAAOe,KAAK,EAAE;IACdjD,OAAO,CAACiD,KAAK,CAAC,uCAAuC,EAAEA,KAAK,CAAC;IAC7D,OAAOf,0BAAY;EACrB;AACF","ignoreList":[]}
@@ -11,7 +11,6 @@ var _DaemonClient = require("../../utils/DaemonClient");
11
11
  var _devConnectUtils = require("./devConnectUtils");
12
12
  var _devConnectPreferences = require("./devConnectPreferences");
13
13
  var _nativeDevConnect = require("./nativeDevConnect");
14
- var _DevConnectQrScanner = require("./DevConnectQrScanner");
15
14
  var _jsxRuntime = require("react/jsx-runtime");
16
15
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
17
16
  const CONNECTION_TIMEOUT_MS = 2000;
@@ -34,7 +33,8 @@ function describeMetroFailure(result) {
34
33
  return result.error ? `Metro switch failed: ${result.error}` : 'Metro switch failed.';
35
34
  }
36
35
  function DevConnectTab({
37
- snapshot
36
+ snapshot,
37
+ feature
38
38
  }) {
39
39
  const inputRef = (0, _react.useRef)(null);
40
40
  const [computerHost, setComputerHost] = (0, _react.useState)(snapshot.computerHost);
@@ -45,15 +45,23 @@ function DevConnectTab({
45
45
  const [message, setMessage] = (0, _react.useState)(null);
46
46
  const [sending, setSending] = (0, _react.useState)(false);
47
47
  const [metroBusy, setMetroBusy] = (0, _react.useState)(false);
48
- const [qrVisible, setQrVisible] = (0, _react.useState)(false);
49
48
  const isSim = snapshot.isSimulator;
49
+ const updateFeatureSettings = (0, _react.useCallback)(patch => {
50
+ feature.updateSettings?.(patch);
51
+ }, [feature]);
50
52
  (0, _react.useEffect)(() => {
51
53
  setComputerHost(snapshot.computerHost);
54
+ }, [snapshot.computerHost]);
55
+ (0, _react.useEffect)(() => {
52
56
  setMetroPort(snapshot.metroPort);
57
+ }, [snapshot.metroPort]);
58
+ (0, _react.useEffect)(() => {
53
59
  setDaemonPort(snapshot.daemonPort);
60
+ }, [snapshot.daemonPort]);
61
+ (0, _react.useEffect)(() => {
54
62
  setStreaming(snapshot.streaming);
55
63
  setSyncState(snapshot.streaming ? 'running' : 'idle');
56
- }, [snapshot.computerHost, snapshot.daemonPort, snapshot.metroPort, snapshot.streaming]);
64
+ }, [snapshot.streaming]);
57
65
  const metroHost = isSim ? getSimulatorMetroHost() : computerHost;
58
66
  const metroTarget = (0, _react.useMemo)(() => (0, _devConnectUtils.buildMetroTarget)(metroHost, metroPort), [metroHost, metroPort]);
59
67
  const metroUrls = (0, _react.useMemo)(() => (0, _devConnectUtils.buildMetroUrls)(metroHost, metroPort), [metroHost, metroPort]);
@@ -62,33 +70,88 @@ function DevConnectTab({
62
70
  const target = (0, _devConnectUtils.parseComputerTarget)(value);
63
71
  if (target) {
64
72
  setMetroPort(target.metroPort);
65
- (0, _devConnectPreferences.saveComputerTarget)(value).catch(() => {});
73
+ (0, _devConnectPreferences.saveComputerTarget)(value).then(savedTarget => {
74
+ if (savedTarget) {
75
+ updateFeatureSettings({
76
+ computerHost: savedTarget.computerHost,
77
+ metroPort: savedTarget.metroPort
78
+ });
79
+ }
80
+ }).catch(() => {});
66
81
  }
67
82
  setSyncState(prev => prev === 'failed' ? 'idle' : prev);
68
83
  setMessage(null);
69
- }, []);
84
+ }, [updateFeatureSettings]);
70
85
  const handleMetroPortChange = (0, _react.useCallback)(value => {
71
86
  setMetroPort(value);
72
87
  const normalized = (0, _devConnectUtils.normalizePort)(value);
73
88
  if (normalized) {
74
- (0, _devConnectPreferences.saveMetroPort)(normalized).catch(() => {});
89
+ (0, _devConnectPreferences.saveMetroPort)(normalized).then(() => updateFeatureSettings({
90
+ metroPort: normalized
91
+ })).catch(() => {});
75
92
  }
76
93
  setMessage(null);
77
- }, []);
94
+ }, [updateFeatureSettings]);
78
95
  const handleDaemonPortChange = (0, _react.useCallback)(value => {
79
96
  setDaemonPort(value);
80
97
  const normalized = (0, _devConnectUtils.normalizePort)(value);
81
98
  if (normalized) {
82
- (0, _devConnectPreferences.saveDaemonPort)(normalized).catch(() => {});
99
+ (0, _devConnectPreferences.saveDaemonPort)(normalized).then(() => updateFeatureSettings({
100
+ daemonPort: normalized
101
+ })).catch(() => {});
83
102
  }
84
103
  setMessage(null);
85
- }, []);
86
- const handleQrTarget = (0, _react.useCallback)(target => {
87
- setComputerHost(target.computerHost);
88
- setMetroPort(target.metroPort);
89
- (0, _devConnectPreferences.saveComputerTarget)(`${target.computerHost}:${target.metroPort}`).catch(() => {});
90
- setMessage('Computer IP updated from QR code.');
91
- }, []);
104
+ }, [updateFeatureSettings]);
105
+ const persistConnectionSettings = (0, _react.useCallback)(async () => {
106
+ const normalizedDaemonPort = (0, _devConnectUtils.normalizePort)(daemonPort);
107
+ if (!normalizedDaemonPort) {
108
+ setMessage('Enter a valid desktop logs port.');
109
+ return false;
110
+ }
111
+ const patch = {
112
+ daemonPort: normalizedDaemonPort
113
+ };
114
+ const writes = [(0, _devConnectPreferences.saveDaemonPort)(normalizedDaemonPort)];
115
+ setDaemonPort(normalizedDaemonPort);
116
+ if (!isSim) {
117
+ const normalizedHost = (0, _devConnectUtils.normalizeComputerHost)(computerHost);
118
+ if (!normalizedHost) {
119
+ setMessage('Enter your computer IP first.');
120
+ return false;
121
+ }
122
+ patch.computerHost = normalizedHost;
123
+ writes.push((0, _devConnectPreferences.saveComputerHost)(normalizedHost));
124
+ setComputerHost(normalizedHost);
125
+ }
126
+ const normalizedMetroPort = (0, _devConnectUtils.normalizePort)(metroPort);
127
+ if (normalizedMetroPort) {
128
+ patch.metroPort = normalizedMetroPort;
129
+ writes.push((0, _devConnectPreferences.saveMetroPort)(normalizedMetroPort));
130
+ setMetroPort(normalizedMetroPort);
131
+ }
132
+ await Promise.all(writes);
133
+ updateFeatureSettings(patch);
134
+ return true;
135
+ }, [computerHost, daemonPort, isSim, metroPort, updateFeatureSettings]);
136
+ const persistMetroSettings = (0, _react.useCallback)(async () => {
137
+ if (!metroTarget) {
138
+ setMessage('Enter a valid computer IP and Metro port.');
139
+ return false;
140
+ }
141
+ const patch = {
142
+ metroPort: metroTarget.port
143
+ };
144
+ const writes = [(0, _devConnectPreferences.saveMetroPort)(metroTarget.port)];
145
+ setMetroPort(metroTarget.port);
146
+ if (!isSim) {
147
+ patch.computerHost = metroTarget.host;
148
+ writes.push((0, _devConnectPreferences.saveComputerTarget)(metroTarget.hostPort));
149
+ setComputerHost(metroTarget.host);
150
+ }
151
+ await Promise.all(writes);
152
+ updateFeatureSettings(patch);
153
+ return true;
154
+ }, [isSim, metroTarget, updateFeatureSettings]);
92
155
  const validateSettings = (0, _react.useCallback)(() => {
93
156
  if (!isSim && !(0, _devConnectUtils.normalizeComputerHost)(computerHost)) {
94
157
  setMessage('Enter your computer IP first.');
@@ -130,6 +193,9 @@ function DevConnectTab({
130
193
  if (!validateSettings()) {
131
194
  return;
132
195
  }
196
+ if (!(await persistConnectionSettings())) {
197
+ return;
198
+ }
133
199
  const daemonOptions = configureDaemon();
134
200
  setMessage('Checking desktop connection...');
135
201
  setSyncState('checking');
@@ -165,11 +231,14 @@ function DevConnectTab({
165
231
  }
166
232
  });
167
233
  setStreaming(true);
168
- }, [configureDaemon, streaming, validateSettings]);
234
+ }, [configureDaemon, persistConnectionSettings, streaming, validateSettings]);
169
235
  const sendOnce = (0, _react.useCallback)(async () => {
170
236
  if (!validateSettings()) {
171
237
  return;
172
238
  }
239
+ if (!(await persistConnectionSettings())) {
240
+ return;
241
+ }
173
242
  const daemonOptions = configureDaemon();
174
243
  setSending(true);
175
244
  setMessage('Checking desktop connection...');
@@ -196,7 +265,7 @@ function DevConnectTab({
196
265
  } finally {
197
266
  setSending(false);
198
267
  }
199
- }, [configureDaemon, validateSettings]);
268
+ }, [configureDaemon, persistConnectionSettings, validateSettings]);
200
269
  const applyRemoteBundle = (0, _react.useCallback)(async () => {
201
270
  if (!metroTarget) {
202
271
  setMessage('Enter a valid computer IP and Metro port.');
@@ -211,6 +280,9 @@ function DevConnectTab({
211
280
  setMetroBusy(true);
212
281
  setMessage('Checking Metro...');
213
282
  try {
283
+ if (!(await persistMetroSettings())) {
284
+ return;
285
+ }
214
286
  const result = await (0, _nativeDevConnect.applyMetroBundle)(metroTarget.host, metroTarget.port);
215
287
  if (result.ok) {
216
288
  setMessage(`Using Metro at ${result.hostPort}. Reloading...`);
@@ -220,7 +292,7 @@ function DevConnectTab({
220
292
  } finally {
221
293
  setMetroBusy(false);
222
294
  }
223
- }, [metroTarget, snapshot.nativeMetroAvailable]);
295
+ }, [metroTarget, persistMetroSettings, snapshot.nativeMetroAvailable]);
224
296
  const resetRemoteBundle = (0, _react.useCallback)(async () => {
225
297
  if (!snapshot.nativeMetroAvailable) {
226
298
  setMessage(describeMetroFailure({
@@ -243,10 +315,12 @@ function DevConnectTab({
243
315
  const canConnect = isSim || Boolean((0, _devConnectUtils.normalizeComputerHost)(computerHost)) && Boolean((0, _devConnectUtils.normalizePort)(daemonPort));
244
316
  const canUseMetro = Boolean(metroTarget) && snapshot.nativeMetroAvailable && !metroBusy;
245
317
  const busy = sending || syncState === 'checking';
246
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.KeyboardAvoidingView, {
318
+ const subnetPrefix = snapshot.subnetPrefix;
319
+ const ipPlaceholder = subnetPrefix ? `${subnetPrefix}...` : '192.168.1.10';
320
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.KeyboardAvoidingView, {
247
321
  style: styles.container,
248
322
  behavior: _reactNative.Platform.OS === 'ios' ? 'padding' : undefined,
249
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
323
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
250
324
  keyboardShouldPersistTaps: "handled",
251
325
  showsVerticalScrollIndicator: false,
252
326
  contentContainerStyle: styles.scrollContent,
@@ -261,14 +335,14 @@ function DevConnectTab({
261
335
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
262
336
  style: styles.label,
263
337
  children: "Computer IP"
264
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
338
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
265
339
  style: styles.inputRow,
266
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
340
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
267
341
  ref: inputRef,
268
342
  style: styles.input,
269
343
  value: computerHost,
270
344
  onChangeText: handleHostChange,
271
- placeholder: "192.168.1.10",
345
+ placeholder: ipPlaceholder,
272
346
  placeholderTextColor: _colors.Colors.textLight,
273
347
  autoCapitalize: "none",
274
348
  autoCorrect: false,
@@ -276,17 +350,19 @@ function DevConnectTab({
276
350
  returnKeyType: "done",
277
351
  onSubmitEditing: () => inputRef.current?.blur(),
278
352
  editable: !streaming
279
- }), snapshot.qrAvailable ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
280
- style: styles.scanButton,
281
- onPress: () => setQrVisible(true),
282
- disabled: streaming,
283
- activeOpacity: 0.7,
284
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
285
- style: styles.scanButtonText,
286
- children: "Scan"
287
- })
288
- }) : null]
289
- })]
353
+ })
354
+ }), subnetPrefix && !computerHost ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
355
+ style: styles.subnetHint,
356
+ onPress: () => {
357
+ setComputerHost(subnetPrefix);
358
+ inputRef.current?.focus();
359
+ },
360
+ activeOpacity: 0.6,
361
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
362
+ style: styles.subnetHintText,
363
+ children: ["Tap to fill: ", subnetPrefix]
364
+ })
365
+ }) : null]
290
366
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
291
367
  style: styles.section,
292
368
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
@@ -415,11 +491,7 @@ function DevConnectTab({
415
491
  children: "Native DevConnect requires pod install / Gradle sync and app rebuild."
416
492
  }) : null]
417
493
  })]
418
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_DevConnectQrScanner.DevConnectQrScanner, {
419
- visible: qrVisible,
420
- onClose: () => setQrVisible(false),
421
- onScanTarget: handleQrTarget
422
- })]
494
+ })
423
495
  });
424
496
  }
425
497
  const styles = _reactNative.StyleSheet.create({
@@ -468,8 +540,15 @@ const styles = _reactNative.StyleSheet.create({
468
540
  },
469
541
  inputRow: {
470
542
  flexDirection: 'row',
471
- alignItems: 'center',
472
- gap: 8
543
+ alignItems: 'center'
544
+ },
545
+ subnetHint: {
546
+ marginTop: 6
547
+ },
548
+ subnetHintText: {
549
+ fontSize: 12,
550
+ color: _colors.Colors.primary,
551
+ fontWeight: '500'
473
552
  },
474
553
  input: {
475
554
  flex: 1,
@@ -483,22 +562,6 @@ const styles = _reactNative.StyleSheet.create({
483
562
  color: _colors.Colors.text,
484
563
  fontFamily: 'Courier'
485
564
  },
486
- scanButton: {
487
- minWidth: 62,
488
- alignItems: 'center',
489
- justifyContent: 'center',
490
- paddingHorizontal: 12,
491
- paddingVertical: 10,
492
- borderRadius: 8,
493
- backgroundColor: _colors.Colors.surface,
494
- borderWidth: 1,
495
- borderColor: _colors.Colors.primary
496
- },
497
- scanButtonText: {
498
- color: _colors.Colors.primary,
499
- fontSize: 13,
500
- fontWeight: '600'
501
- },
502
565
  portRow: {
503
566
  flexDirection: 'row',
504
567
  gap: 10