react-native-inapp-inspector 2.3.12 → 2.3.14

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 (232) hide show
  1. package/android/build/.transforms/6683d6eeaa3e1dfa689c3385111a0386/results.bin +1 -0
  2. package/android/build/.transforms/6683d6eeaa3e1dfa689c3385111a0386/transformed/classes/classes_dex/classes.dex +0 -0
  3. package/android/build/.transforms/9d2a3e5e0f0ea07cafb0c0bf290630ee/results.bin +1 -0
  4. package/android/build/.transforms/9d2a3e5e0f0ea07cafb0c0bf290630ee/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/BuildConfig.dex +0 -0
  5. package/android/build/.transforms/9d2a3e5e0f0ea07cafb0c0bf290630ee/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/InAppInspectorFloatingView$iconView$1.dex +0 -0
  6. package/android/build/.transforms/9d2a3e5e0f0ea07cafb0c0bf290630ee/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/InAppInspectorFloatingView.dex +0 -0
  7. package/android/build/.transforms/9d2a3e5e0f0ea07cafb0c0bf290630ee/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NativeNetworkInspectorSpec.dex +0 -0
  8. package/android/build/.transforms/9d2a3e5e0f0ea07cafb0c0bf290630ee/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorModule$Companion.dex +0 -0
  9. package/android/build/.transforms/9d2a3e5e0f0ea07cafb0c0bf290630ee/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorModule$frameCallback$1.dex +0 -0
  10. package/android/build/.transforms/9d2a3e5e0f0ea07cafb0c0bf290630ee/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorModule$shakeListener$1.dex +0 -0
  11. package/android/build/.transforms/9d2a3e5e0f0ea07cafb0c0bf290630ee/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorModule.dex +0 -0
  12. package/android/build/.transforms/9d2a3e5e0f0ea07cafb0c0bf290630ee/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/inappinspector/NetworkInspectorPackage.dex +0 -0
  13. package/android/build/.transforms/9d2a3e5e0f0ea07cafb0c0bf290630ee/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
  14. package/android/build/generated/source/buildConfig/debug/com/inappinspector/BuildConfig.java +10 -0
  15. package/android/build/generated/source/codegen/java/com/inappinspector/NativeNetworkInspectorSpec.java +104 -0
  16. package/android/build/generated/source/codegen/jni/CMakeLists.txt +28 -0
  17. package/android/build/generated/source/codegen/jni/RNInAppInspectorSpec-generated.cpp +128 -0
  18. package/android/build/generated/source/codegen/jni/RNInAppInspectorSpec.h +31 -0
  19. package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/ComponentDescriptors.cpp +22 -0
  20. package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/ComponentDescriptors.h +24 -0
  21. package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/EventEmitters.cpp +16 -0
  22. package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/EventEmitters.h +17 -0
  23. package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/Props.cpp +19 -0
  24. package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/Props.h +18 -0
  25. package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/RNInAppInspectorSpecJSI.h +177 -0
  26. package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/ShadowNodes.cpp +17 -0
  27. package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/ShadowNodes.h +23 -0
  28. package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/States.cpp +16 -0
  29. package/android/build/generated/source/codegen/jni/react/renderer/components/RNInAppInspectorSpec/States.h +20 -0
  30. package/android/build/generated/source/codegen/schema.json +1 -0
  31. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +7 -0
  32. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +18 -0
  33. package/android/build/intermediates/aar_main_jar/debug/syncDebugLibJars/classes.jar +0 -0
  34. package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +6 -0
  35. package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +1 -0
  36. package/android/build/intermediates/annotations_typedef_file/debug/extractDebugAnnotations/typedefs.txt +0 -0
  37. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  38. package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  39. package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
  40. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -0
  41. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
  42. package/android/build/intermediates/incremental/debug-mergeJavaRes/merge-state +0 -0
  43. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
  44. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
  45. package/android/build/intermediates/incremental/packageDebugAssets/merger.xml +2 -0
  46. package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/react-native-inapp-inspector_debug.kotlin_module +0 -0
  47. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/inappinspector/BuildConfig.class +0 -0
  48. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/inappinspector/NativeNetworkInspectorSpec.class +0 -0
  49. package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +2 -0
  50. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +7 -0
  51. package/android/build/intermediates/merged_java_res/debug/mergeDebugJavaResource/feature-react-native-inapp-inspector.jar +0 -0
  52. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +7 -0
  53. package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +1 -0
  54. package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +1 -0
  55. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/META-INF/react-native-inapp-inspector_debug.kotlin_module +0 -0
  56. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/BuildConfig.class +0 -0
  57. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/InAppInspectorFloatingView$iconView$1.class +0 -0
  58. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/InAppInspectorFloatingView.class +0 -0
  59. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NativeNetworkInspectorSpec.class +0 -0
  60. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorModule$Companion.class +0 -0
  61. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorModule$frameCallback$1.class +0 -0
  62. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorModule$shakeListener$1.class +0 -0
  63. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorModule.class +0 -0
  64. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/inappinspector/NetworkInspectorPackage.class +0 -0
  65. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  66. package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +1 -0
  67. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  68. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
  69. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
  70. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
  71. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  72. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
  73. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
  74. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
  75. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  76. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
  77. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
  78. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
  79. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  80. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
  81. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  82. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  83. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
  84. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
  85. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  86. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  87. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
  88. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
  89. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream +0 -0
  90. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len +0 -0
  91. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len +0 -0
  92. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
  93. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i +0 -0
  94. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len +0 -0
  95. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  96. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  97. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
  98. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
  99. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  100. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  101. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
  102. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  103. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  104. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
  105. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
  106. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  107. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  108. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
  109. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  110. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
  111. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
  112. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
  113. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  114. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
  115. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
  116. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
  117. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
  118. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
  119. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
  120. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  121. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
  122. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
  123. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
  124. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
  125. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
  126. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
  127. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
  128. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
  129. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
  130. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +2 -0
  131. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  132. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
  133. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
  134. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
  135. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
  136. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
  137. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
  138. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  139. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
  140. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
  141. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
  142. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  143. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
  144. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
  145. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  146. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  147. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  148. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  149. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  150. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  151. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
  152. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  153. package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  154. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  155. package/android/build/outputs/aar/react-native-inapp-inspector-debug.aar +0 -0
  156. package/android/build/outputs/logs/manifest-merger-debug-report.txt +17 -0
  157. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  158. package/android/build/tmp/kotlin-classes/debug/META-INF/react-native-inapp-inspector_debug.kotlin_module +0 -0
  159. package/android/build/tmp/kotlin-classes/debug/com/inappinspector/InAppInspectorFloatingView$iconView$1.class +0 -0
  160. package/android/build/tmp/kotlin-classes/debug/com/inappinspector/InAppInspectorFloatingView.class +0 -0
  161. package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorModule$Companion.class +0 -0
  162. package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorModule$frameCallback$1.class +0 -0
  163. package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorModule$shakeListener$1.class +0 -0
  164. package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorModule.class +0 -0
  165. package/android/build/tmp/kotlin-classes/debug/com/inappinspector/NetworkInspectorPackage.class +0 -0
  166. package/bin/cli.js +6 -0
  167. package/dist/commonjs/components/HeadersSection.js +3 -2
  168. package/dist/commonjs/components/Inspector/BundleTab.js +4 -4
  169. package/dist/commonjs/components/Inspector/DebuggingTab.js +742 -427
  170. package/dist/commonjs/components/Inspector/MainScreen.js +4 -1
  171. package/dist/commonjs/components/Inspector/NetworkDetail.js +2 -2
  172. package/dist/commonjs/components/Inspector/NetworkFilterModal.js +18 -12
  173. package/dist/commonjs/components/Inspector/SettingsPanel.js +6 -4
  174. package/dist/commonjs/components/Inspector/StorageTab.js +10 -4
  175. package/dist/commonjs/components/Inspector/TabBar.js +6 -2
  176. package/dist/commonjs/components/JsonViewer.js +3 -2
  177. package/dist/commonjs/components/NetworkIcons.d.ts +4 -1
  178. package/dist/commonjs/components/NetworkIcons.js +26 -3
  179. package/dist/commonjs/components/QRCodeView.js +1 -1
  180. package/dist/commonjs/constants/version.d.ts +1 -1
  181. package/dist/commonjs/constants/version.js +1 -1
  182. package/dist/commonjs/helpers/index.d.ts +1 -0
  183. package/dist/commonjs/helpers/index.js +11 -1
  184. package/dist/commonjs/helpers/qrGenerator.d.ts +1 -0
  185. package/dist/commonjs/helpers/qrGenerator.js +356 -33
  186. package/dist/commonjs/index.d.ts +1 -0
  187. package/dist/commonjs/index.js +5 -3
  188. package/dist/commonjs/metro.d.ts +25 -0
  189. package/dist/commonjs/metro.js +478 -0
  190. package/dist/esm/components/HeadersSection.js +3 -2
  191. package/dist/esm/components/Inspector/BundleTab.js +5 -5
  192. package/dist/esm/components/Inspector/DebuggingTab.js +745 -430
  193. package/dist/esm/components/Inspector/MainScreen.js +4 -1
  194. package/dist/esm/components/Inspector/NetworkDetail.js +2 -2
  195. package/dist/esm/components/Inspector/NetworkFilterModal.js +19 -13
  196. package/dist/esm/components/Inspector/SettingsPanel.js +7 -5
  197. package/dist/esm/components/Inspector/StorageTab.js +11 -5
  198. package/dist/esm/components/Inspector/TabBar.js +7 -3
  199. package/dist/esm/components/JsonViewer.js +4 -3
  200. package/dist/esm/components/NetworkIcons.d.ts +4 -1
  201. package/dist/esm/components/NetworkIcons.js +22 -2
  202. package/dist/esm/components/QRCodeView.js +1 -1
  203. package/dist/esm/constants/version.d.ts +1 -1
  204. package/dist/esm/constants/version.js +1 -1
  205. package/dist/esm/helpers/index.d.ts +1 -0
  206. package/dist/esm/helpers/index.js +9 -0
  207. package/dist/esm/helpers/qrGenerator.d.ts +1 -0
  208. package/dist/esm/helpers/qrGenerator.js +356 -30
  209. package/dist/esm/index.d.ts +1 -0
  210. package/dist/esm/index.js +3 -2
  211. package/dist/esm/metro.d.ts +25 -0
  212. package/dist/esm/metro.js +469 -0
  213. package/metro.d.ts +1 -0
  214. package/metro.js +1 -0
  215. package/package.json +16 -5
  216. package/src/components/HeadersSection.tsx +7 -2
  217. package/src/components/Inspector/BundleTab.tsx +9 -4
  218. package/src/components/Inspector/DebuggingTab.tsx +845 -498
  219. package/src/components/Inspector/MainScreen.tsx +4 -1
  220. package/src/components/Inspector/NetworkDetail.tsx +2 -2
  221. package/src/components/Inspector/NetworkFilterModal.tsx +32 -12
  222. package/src/components/Inspector/SettingsPanel.tsx +85 -75
  223. package/src/components/Inspector/StorageTab.tsx +15 -4
  224. package/src/components/Inspector/TabBar.tsx +16 -2
  225. package/src/components/JsonViewer.tsx +8 -3
  226. package/src/components/NetworkIcons.tsx +71 -1
  227. package/src/components/QRCodeView.tsx +2 -2
  228. package/src/constants/version.ts +1 -1
  229. package/src/helpers/index.ts +15 -0
  230. package/src/helpers/qrGenerator.ts +418 -37
  231. package/src/index.tsx +5 -3
  232. package/src/metro.ts +598 -0
@@ -1,14 +1,15 @@
1
- import React, {useState, useEffect, useMemo, useCallback} from 'react';
1
+ import React, {useState, useEffect, useMemo, useCallback, useRef} from 'react';
2
2
  import {
3
3
  View,
4
4
  Text,
5
5
  ScrollView,
6
6
  StyleSheet,
7
- TextInput,
8
- TouchableOpacity,
9
7
  NativeModules,
10
- Platform,
11
8
  Share,
9
+ TouchableOpacity,
10
+ ActivityIndicator,
11
+ Animated,
12
+ Platform,
12
13
  } from 'react-native';
13
14
  import {useInspector} from './InspectorContext';
14
15
  import {AppColors} from '../../styles/AppColors';
@@ -18,32 +19,40 @@ import TouchableScale from '../TouchableScale';
18
19
  import CopyButton from '../CopyButton';
19
20
  import {copyToClipboard} from '../../helpers';
20
21
  import {showToast} from '../../helpers/toast';
21
- import {useTranslation} from '../../i18n';
22
+ import {triggerNativeHaptic} from '../../native/NativeInspector';
22
23
  import {
24
+ PackageIcon,
25
+ InfoCircleIcon,
26
+ CheckIcon,
23
27
  BoltIcon,
24
- GlobeIcon,
25
- ClockIcon,
26
- CircleCheckIcon,
27
28
  CircleXIcon,
28
- SmartphoneIcon,
29
- PackageIcon,
30
- TerminalIcon,
29
+ CopyIcon,
31
30
  ExternalLinkIcon,
31
+ SparkleIcon,
32
+ AndroidIcon,
32
33
  RepeatIcon,
33
- ShieldAlertIcon,
34
34
  } from '../NetworkIcons';
35
+ import Svg, {Path} from 'react-native-svg';
35
36
 
36
- interface PortStatus {
37
- port: number;
38
- status: 'checking' | 'active' | 'inactive';
39
- latencyMs?: number;
40
- }
37
+ const TerminalConsoleIcon = ({color = AppColors.purple, size = 13}: {color?: string; size?: number}) => (
38
+ <Svg width={size} height={size} viewBox="0 0 24 24" fill="none">
39
+ <Path d="M4 17l6-6-6-6M12 19h8" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
40
+ </Svg>
41
+ );
41
42
 
42
- const COMMON_PORTS = [8081, 8082, 8083, 19000];
43
+ interface BuildStatusData {
44
+ status: 'idle' | 'running' | 'completed' | 'failed';
45
+ scheme: string;
46
+ clean: boolean;
47
+ progress: number;
48
+ currentTask: string;
49
+ logs?: string[];
50
+ error: string | null;
51
+ apkName: string | null;
52
+ apkSize: number | null;
53
+ }
43
54
 
44
55
  export const DebuggingTab: React.FC = () => {
45
- const {t} = useTranslation();
46
-
47
56
  // Auto-detect host IP and initial port from NativeModules.SourceCode.scriptURL
48
57
  const detectedConfig = useMemo(() => {
49
58
  const scriptURL = NativeModules.SourceCode?.scriptURL || '';
@@ -69,687 +78,1025 @@ export const DebuggingTab: React.FC = () => {
69
78
  }, []);
70
79
 
71
80
  const [hostIp, setHostIp] = useState<string>(() => {
72
- // If localhost or 127.0.0.1 or 10.0.2.2, default to 192.168.1.1 or detected host
73
81
  if (
74
- detectedConfig.host === 'localhost' ||
75
- detectedConfig.host === '127.0.0.1' ||
76
- detectedConfig.host === '10.0.2.2'
82
+ detectedConfig.host &&
83
+ detectedConfig.host !== 'localhost' &&
84
+ detectedConfig.host !== '127.0.0.1' &&
85
+ detectedConfig.host !== '10.0.2.2'
77
86
  ) {
78
- return '192.168.1.15';
87
+ return detectedConfig.host;
79
88
  }
80
- return detectedConfig.host;
89
+ return '192.168.1.2';
81
90
  });
82
91
 
83
- const [selectedPort, setSelectedPort] = useState<number>(detectedConfig.port);
84
- const [apkPath, setApkPath] = useState<string>('app-debug.apk');
85
- const [activeQrTab, setActiveQrTab] = useState<'metro' | 'apk' | 'host'>('metro');
86
- const [isAutoDetecting, setIsAutoDetecting] = useState<boolean>(false);
87
- const [portsStatus, setPortsStatus] = useState<Record<number, PortStatus>>({});
92
+ const [port, setPort] = useState<number>(detectedConfig.port || 8083);
93
+ const [apkFileName, setApkFileName] = useState<string>('app-debug.apk');
94
+ const [apkSizeMb, setApkSizeMb] = useState<string | null>(null);
95
+
96
+ // Build generation state
97
+ const [selectedScheme, setSelectedScheme] = useState<'assembleRelease' | 'assembleDebug'>('assembleRelease');
98
+ const [isCleanBuild, setIsCleanBuild] = useState<boolean>(true);
99
+ const [buildStatus, setBuildStatus] = useState<BuildStatusData>({
100
+ status: 'idle',
101
+ scheme: 'assembleRelease',
102
+ clean: true,
103
+ progress: 0,
104
+ currentTask: '',
105
+ error: null,
106
+ apkName: null,
107
+ apkSize: null,
108
+ });
109
+
110
+ const pollingRef = useRef<NodeJS.Timeout | null>(null);
111
+ const progressAnim = useRef(new Animated.Value(0)).current;
112
+ const [showVerboseLogs, setShowVerboseLogs] = useState<boolean>(true);
113
+ const verboseScrollRef = useRef<ScrollView | null>(null);
114
+
115
+ // Animate progress bar smoothly
116
+ useEffect(() => {
117
+ Animated.timing(progressAnim, {
118
+ toValue: Math.max(0, Math.min(100, buildStatus.progress)),
119
+ duration: 350,
120
+ useNativeDriver: false,
121
+ }).start();
122
+ }, [buildStatus.progress, progressAnim]);
123
+
124
+ // Auto-scroll verbose console to bottom
125
+ useEffect(() => {
126
+ if (buildStatus.logs && buildStatus.logs.length > 0) {
127
+ setTimeout(() => {
128
+ verboseScrollRef.current?.scrollToEnd({ animated: true });
129
+ }, 50);
130
+ }
131
+ }, [buildStatus.logs]);
88
132
 
89
- // Auto-probe ports on mount
90
- const probePorts = useCallback(async () => {
91
- setIsAutoDetecting(true);
92
- const results: Record<number, PortStatus> = {};
133
+ // Auto-fetch dynamic IP and APK metadata from Metro / Standalone Server
134
+ const fetchMetroTelemetry = useCallback(async () => {
135
+ const hostsToTry = Array.from(
136
+ new Set([detectedConfig.host, '10.0.2.2', 'localhost', '127.0.0.1'].filter(Boolean)),
137
+ );
138
+ const portsToTry = Array.from(
139
+ new Set([detectedConfig.port, 8083, 8081, 8082].filter(Boolean)),
140
+ );
93
141
 
94
- for (const p of COMMON_PORTS) {
95
- results[p] = {port: p, status: 'checking'};
142
+ for (const h of hostsToTry) {
143
+ for (const p of portsToTry) {
144
+ try {
145
+ const controller = new AbortController();
146
+ const timeoutId = setTimeout(() => controller.abort(), 1200);
147
+ const res = await fetch(`http://${h}:${p}/__inapp_inspector/apk-info`, {
148
+ signal: controller.signal,
149
+ });
150
+ clearTimeout(timeoutId);
151
+ if (res.ok) {
152
+ const data = await res.json();
153
+ if (
154
+ data.hostIp &&
155
+ data.hostIp !== '127.0.0.1' &&
156
+ data.hostIp !== 'localhost' &&
157
+ data.hostIp !== '10.0.2.2'
158
+ ) {
159
+ setHostIp(data.hostIp);
160
+ }
161
+ if (data.port) {
162
+ setPort(data.port);
163
+ }
164
+ if (data.apkName) {
165
+ setApkFileName(data.apkName);
166
+ }
167
+ if (data.apkSize) {
168
+ setApkSizeMb((data.apkSize / (1024 * 1024)).toFixed(1));
169
+ }
170
+ return;
171
+ }
172
+ } catch {}
173
+ }
96
174
  }
97
- setPortsStatus({...results});
175
+ }, [detectedConfig.host, detectedConfig.port]);
176
+
177
+ useEffect(() => {
178
+ fetchMetroTelemetry();
179
+ }, [fetchMetroTelemetry]);
180
+
181
+ // Clean up polling interval on unmount
182
+ useEffect(() => {
183
+ return () => {
184
+ if (pollingRef.current) {
185
+ clearInterval(pollingRef.current);
186
+ }
187
+ };
188
+ }, []);
98
189
 
99
- let foundActivePort: number | null = null;
190
+ // Poll build status from Metro
191
+ const pollBuildStatus = useCallback(() => {
192
+ if (pollingRef.current) clearInterval(pollingRef.current);
100
193
 
101
- for (const p of COMMON_PORTS) {
102
- const startTime = Date.now();
194
+ const targetHost = detectedConfig.host || '10.0.2.2';
195
+ pollingRef.current = setInterval(async () => {
103
196
  try {
104
- const controller = new AbortController();
105
- const timeoutId = setTimeout(() => controller.abort(), 1500);
106
- // Ping /status endpoint of Metro Bundler
107
- const res = await fetch(`http://localhost:${p}/status`, {
108
- signal: controller.signal,
109
- });
110
- clearTimeout(timeoutId);
111
- const text = await res.text();
112
- const latency = Date.now() - startTime;
113
-
114
- if (res.ok && text.includes('packager-status:running')) {
115
- results[p] = {port: p, status: 'active', latencyMs: latency};
116
- if (!foundActivePort) foundActivePort = p;
117
- } else {
118
- results[p] = {port: p, status: 'inactive'};
197
+ const res = await fetch(`http://${targetHost}:${port}/__inapp_inspector/build-status`);
198
+ if (res.ok) {
199
+ const data: BuildStatusData = await res.json();
200
+ setBuildStatus(data);
201
+
202
+ if (data.status === 'completed') {
203
+ if (pollingRef.current) clearInterval(pollingRef.current);
204
+ triggerNativeHaptic('success');
205
+ showToast('✓ APK Build Generated Successfully!');
206
+ if (data.apkSize) {
207
+ setApkSizeMb((data.apkSize / (1024 * 1024)).toFixed(1));
208
+ }
209
+ if (data.apkName) {
210
+ setApkFileName(data.apkName);
211
+ }
212
+ fetchMetroTelemetry();
213
+ } else if (data.status === 'failed') {
214
+ if (pollingRef.current) clearInterval(pollingRef.current);
215
+ triggerNativeHaptic('error');
216
+ showToast('✕ Build Failed: ' + (data.error || 'Gradle error'));
217
+ }
119
218
  }
120
- } catch {
121
- results[p] = {port: p, status: 'inactive'};
219
+ } catch {}
220
+ }, 1000);
221
+ }, [detectedConfig.host, port, fetchMetroTelemetry]);
222
+
223
+ // Start Gradle build on computer via Metro / Standalone Server
224
+ const handleStartBuild = async () => {
225
+ triggerNativeHaptic('medium');
226
+ setBuildStatus({
227
+ status: 'running',
228
+ scheme: selectedScheme,
229
+ clean: isCleanBuild,
230
+ progress: 5,
231
+ currentTask: isCleanBuild ? 'Cleaning build cache...' : 'Initializing build...',
232
+ error: null,
233
+ apkName: null,
234
+ apkSize: null,
235
+ });
236
+
237
+ const hostsToTry = Array.from(
238
+ new Set([detectedConfig.host, '10.0.2.2', 'localhost', '127.0.0.1'].filter(Boolean)),
239
+ );
240
+ const portsToTry = Array.from(new Set([port, 8083, 8081, 8082].filter(Boolean)));
241
+
242
+ let buildTriggered = false;
243
+
244
+ for (const h of hostsToTry) {
245
+ for (const p of portsToTry) {
246
+ try {
247
+ const controller = new AbortController();
248
+ const timeoutId = setTimeout(() => controller.abort(), 2000);
249
+ const res = await fetch(
250
+ `http://${h}:${p}/__inapp_inspector/build-apk?scheme=${selectedScheme}&clean=${isCleanBuild}`,
251
+ { signal: controller.signal },
252
+ );
253
+ clearTimeout(timeoutId);
254
+ if (res.ok) {
255
+ buildTriggered = true;
256
+ pollBuildStatus();
257
+ return;
258
+ }
259
+ } catch {}
122
260
  }
123
- setPortsStatus({...results});
124
261
  }
125
262
 
126
- if (foundActivePort) {
127
- setSelectedPort(foundActivePort);
128
- showToast(`Detected Metro running on Port ${foundActivePort}!`);
263
+ if (!buildTriggered) {
264
+ setBuildStatus(prev => ({
265
+ ...prev,
266
+ status: 'failed',
267
+ error: 'Cannot reach build server. Ensure npm start or npm run serve-apk is running on host.',
268
+ }));
129
269
  }
270
+ };
130
271
 
131
- setIsAutoDetecting(false);
132
- }, []);
272
+ // Stop Gradle build on computer via Metro / Standalone Server
273
+ const handleStopBuild = async () => {
274
+ triggerNativeHaptic('warning');
275
+ if (pollingRef.current) clearInterval(pollingRef.current);
133
276
 
134
- useEffect(() => {
135
- probePorts();
136
- }, [probePorts]);
277
+ const hostsToTry = Array.from(
278
+ new Set([detectedConfig.host, '10.0.2.2', 'localhost', '127.0.0.1'].filter(Boolean)),
279
+ );
280
+ const portsToTry = Array.from(new Set([port, 8083, 8081, 8082].filter(Boolean)));
281
+
282
+ for (const h of hostsToTry) {
283
+ for (const p of portsToTry) {
284
+ try {
285
+ const controller = new AbortController();
286
+ const timeoutId = setTimeout(() => controller.abort(), 1500);
287
+ await fetch(`http://${h}:${p}/__inapp_inspector/stop-build`, {
288
+ signal: controller.signal,
289
+ });
290
+ clearTimeout(timeoutId);
291
+ } catch {}
292
+ }
293
+ }
137
294
 
138
- // Construct target URLs for QR codes
139
- const metroBundleUrl = `http://${hostIp}:${selectedPort}/index.bundle?platform=android&dev=true`;
140
- const directServerUrl = `http://${hostIp}:${selectedPort}`;
141
- const apkDownloadUrl = `http://${hostIp}:${selectedPort}/${apkPath}`;
142
- const devSettingsHost = `${hostIp}:${selectedPort}`;
295
+ setBuildStatus(prev => ({
296
+ ...prev,
297
+ status: 'idle',
298
+ currentTask: 'Build cancelled by user',
299
+ logs: [...(prev.logs || []), '🛑 Build cancelled by user.'],
300
+ }));
301
+ showToast('Build cancelled');
302
+ };
143
303
 
144
- const currentQrValue = useMemo(() => {
145
- if (activeQrTab === 'apk') return apkDownloadUrl;
146
- if (activeQrTab === 'host') return devSettingsHost;
147
- return directServerUrl;
148
- }, [activeQrTab, apkDownloadUrl, devSettingsHost, directServerUrl]);
304
+ // Construct target download URL
305
+ const apkDownloadUrl = `http://${hostIp}:${port}/${apkFileName.replace(/^\/+/, '')}`;
149
306
 
150
- const activePortInfo = portsStatus[selectedPort];
307
+ const handleShare = () => {
308
+ triggerNativeHaptic('light');
309
+ Share.share({
310
+ message: apkDownloadUrl,
311
+ title: 'Install Android APK',
312
+ });
313
+ };
314
+
315
+ const isBuilding = buildStatus.status === 'running';
151
316
 
152
317
  return (
153
318
  <ScrollView
154
- style={styles.container}
155
- contentContainerStyle={styles.content}
319
+ style={styles.scrollArea}
320
+ contentContainerStyle={styles.scrollContent}
156
321
  showsVerticalScrollIndicator={false}>
157
- {/* ─── Top Live Server Status Banner ────────────────────────────── */}
158
- <View style={styles.serverCard}>
159
- <View style={styles.serverCardTop}>
160
- <View style={styles.serverStatusLeft}>
161
- <View
162
- style={[
163
- styles.statusDot,
164
- {
165
- backgroundColor:
166
- activePortInfo?.status === 'active'
167
- ? AppColors.greenColor
168
- : activePortInfo?.status === 'checking'
169
- ? AppColors.warningIconGold
170
- : AppColors.errorColor,
171
- },
172
- ]}
173
- />
174
- <View>
175
- <View style={{flexDirection: 'row', alignItems: 'center', gap: 6}}>
176
- <Text style={styles.serverTitle}>Metro Dev Server</Text>
177
- <View style={styles.portPill}>
178
- <Text style={styles.portPillText}>Port {selectedPort}</Text>
179
- </View>
180
- </View>
181
- <Text style={styles.serverSubtitle}>
182
- {activePortInfo?.status === 'active'
183
- ? `🟢 Active & Bundling (${activePortInfo.latencyMs}ms)`
184
- : activePortInfo?.status === 'checking'
185
- ? '🟡 Probing Metro Ports...'
186
- : '🔴 Standby / Select active port'}
187
- </Text>
188
- </View>
322
+ {/* ─── Hero Card: Multi-Device APK Installer ───────────────────── */}
323
+ <View style={styles.heroCard}>
324
+ <View style={styles.heroHeader}>
325
+ <View style={styles.heroIconWrap}>
326
+ <AndroidIcon size={20} color={AppColors.white} />
327
+ </View>
328
+ <View style={{flex: 1, minWidth: 0}}>
329
+ <Text style={styles.heroTitle} numberOfLines={1}>
330
+ Multi-Device APK Installer
331
+ </Text>
332
+ <Text style={styles.heroSubtitle} numberOfLines={1}>
333
+ Scan QR code with another Android device to download
334
+ </Text>
335
+ </View>
336
+ <View style={styles.heroBadge}>
337
+ <View style={styles.pulseDot} />
338
+ <Text style={styles.heroBadgeText}>Live Metro</Text>
189
339
  </View>
190
-
191
- <TouchableScale
192
- onPress={probePorts}
193
- style={styles.scanBtn}
194
- hitSlop={8}>
195
- <RepeatIcon size={12} color={AppColors.purple} />
196
- <Text style={styles.scanBtnText}>Re-scan</Text>
197
- </TouchableScale>
198
340
  </View>
199
341
 
200
- {/* Port Selector Chips */}
201
- <View style={styles.portsRow}>
202
- {COMMON_PORTS.map(p => {
203
- const isSelected = selectedPort === p;
204
- const pInfo = portsStatus[p];
205
- const isActive = pInfo?.status === 'active';
206
- return (
207
- <TouchableOpacity
208
- key={p}
209
- activeOpacity={0.7}
210
- onPress={() => setSelectedPort(p)}
211
- style={[
212
- styles.portChip,
213
- isSelected && styles.portChipSelected,
214
- isActive && {borderColor: AppColors.greenColor},
215
- ]}>
216
- <View
217
- style={[
218
- styles.portMiniDot,
219
- {
220
- backgroundColor: isActive
221
- ? AppColors.greenColor
222
- : AppColors.grayTextWeak,
223
- },
224
- ]}
225
- />
226
- <Text
227
- style={[
228
- styles.portChipText,
229
- isSelected && styles.portChipTextSelected,
230
- ]}>
231
- {p}
232
- </Text>
233
- {isActive && (
234
- <View style={styles.liveBadge}>
235
- <Text style={styles.liveBadgeText}>LIVE</Text>
236
- </View>
237
- )}
238
- </TouchableOpacity>
239
- );
240
- })}
342
+ {/* Hero Metrics Strip (Matching DeviceInfoTab & PerformanceTab) */}
343
+ <View style={styles.heroMetricsStrip}>
344
+ <View style={styles.heroMetricItem}>
345
+ <Text style={styles.heroMetricLabel}>HOST IP</Text>
346
+ <Text style={styles.heroMetricValue} numberOfLines={1}>
347
+ {hostIp}
348
+ </Text>
349
+ </View>
350
+ <View style={styles.heroMetricDivider} />
351
+ <View style={styles.heroMetricItem}>
352
+ <Text style={styles.heroMetricLabel}>PORT</Text>
353
+ <Text style={styles.heroMetricValue}>{port}</Text>
354
+ </View>
355
+ <View style={styles.heroMetricDivider} />
356
+ <View style={styles.heroMetricItem}>
357
+ <Text style={styles.heroMetricLabel}>APK SIZE</Text>
358
+ <Text
359
+ style={[
360
+ styles.heroMetricValue,
361
+ {color: apkSizeMb ? AppColors.emerald500 : AppColors.grayTextWeak},
362
+ ]}>
363
+ {apkSizeMb ? `${apkSizeMb} MB` : 'Detected'}
364
+ </Text>
365
+ </View>
366
+ <View style={styles.heroMetricDivider} />
367
+ <View style={styles.heroMetricItem}>
368
+ <Text style={styles.heroMetricLabel}>STATUS</Text>
369
+ <Text
370
+ style={[
371
+ styles.heroMetricValue,
372
+ {color: AppColors.emerald500},
373
+ ]}>
374
+ Ready
375
+ </Text>
376
+ </View>
241
377
  </View>
242
378
  </View>
243
379
 
244
- {/* ─── Host IP Configuration Card ───────────────────────────────── */}
245
- <View style={styles.card}>
246
- <View style={styles.cardHeader}>
247
- <Text style={styles.cardTitle}>HOST IP & BUNDLE LOCATION</Text>
380
+ {/* ─── Section Card: QR Code & Direct Download ─────────────────── */}
381
+ <View style={styles.sectionCard}>
382
+ <View style={styles.sectionHeaderRow}>
383
+ <Text style={styles.sectionTitle}>QR CODE & DIRECT DOWNLOAD</Text>
248
384
  <TouchableOpacity
249
- onPress={() => {
250
- if (
251
- detectedConfig.host !== 'localhost' &&
252
- detectedConfig.host !== '127.0.0.1' &&
253
- detectedConfig.host !== '10.0.2.2'
254
- ) {
255
- setHostIp(detectedConfig.host);
256
- showToast(`Reset to detected IP: ${detectedConfig.host}`);
257
- }
258
- }}>
259
- <Text style={styles.headerActionText}>Reset to Detected</Text>
385
+ activeOpacity={0.7}
386
+ onPress={fetchMetroTelemetry}
387
+ style={styles.refreshBtn}>
388
+ <RepeatIcon size={12} color={AppColors.purple} />
389
+ <Text style={styles.refreshBtnText}>Refresh</Text>
260
390
  </TouchableOpacity>
261
391
  </View>
262
392
 
263
- <View style={styles.inputContainer}>
264
- <Text style={styles.inputPrefix}>http://</Text>
265
- <TextInput
266
- style={styles.input}
267
- value={hostIp}
268
- onChangeText={setHostIp}
269
- placeholder="192.168.1.15"
270
- placeholderTextColor={AppColors.grayTextWeak}
271
- autoCapitalize="none"
272
- autoCorrect={false}
273
- />
274
- <Text style={styles.inputSuffix}>:{selectedPort}</Text>
393
+ {/* QR Code Container */}
394
+ <View style={styles.qrCenteredWrapper}>
395
+ <View style={styles.qrInnerFrame}>
396
+ <QRCodeView
397
+ value={apkDownloadUrl}
398
+ size={235}
399
+ color={AppColors.primaryBlack}
400
+ backgroundColor={AppColors.white}
401
+ />
402
+ </View>
275
403
  </View>
276
- <Text style={styles.inputHint}>
277
- 💡 Ensure your physical Android device and Mac are connected to the same Wi-Fi network.
278
- </Text>
279
404
  </View>
280
405
 
281
- {/* ─── Interactive QR Code Generator Card ──────────────────────── */}
282
- <View style={styles.qrCard}>
283
- {/* Mode Selector Tabs */}
284
- <View style={styles.qrTabsRow}>
285
- <TouchableOpacity
286
- activeOpacity={0.7}
287
- onPress={() => setActiveQrTab('metro')}
288
- style={[
289
- styles.qrTab,
290
- activeQrTab === 'metro' && styles.qrTabActive,
291
- ]}>
292
- <BoltIcon
293
- size={13}
294
- color={activeQrTab === 'metro' ? AppColors.white : AppColors.grayText}
295
- />
296
- <Text
297
- style={[
298
- styles.qrTabText,
299
- activeQrTab === 'metro' && styles.qrTabTextActive,
300
- ]}>
301
- Metro Live Reload
302
- </Text>
303
- </TouchableOpacity>
406
+ {/* ─── Section Card: Build Generator (Gradle) ─────────────────── */}
407
+ <View style={styles.sectionCard}>
408
+ <View style={styles.sectionHeaderRow}>
409
+ <View style={{flexDirection: 'row', alignItems: 'center', gap: 6}}>
410
+ <BoltIcon size={13} color={AppColors.purple} />
411
+ <Text style={styles.sectionTitle}>BUILD GENERATOR (GRADLE)</Text>
412
+ </View>
413
+ {buildStatus.status === 'completed' && (
414
+ <View style={styles.completedBadge}>
415
+ <CheckIcon size={10} color={AppColors.emerald500} />
416
+ <Text style={styles.completedBadgeText}>100% Ready</Text>
417
+ </View>
418
+ )}
419
+ </View>
304
420
 
421
+ {/* SubTab Segmented Strip (Matching DeviceInfoTab & PerformanceTab) */}
422
+ <View style={styles.subTabStrip}>
305
423
  <TouchableOpacity
424
+ disabled={isBuilding}
306
425
  activeOpacity={0.7}
307
- onPress={() => setActiveQrTab('apk')}
426
+ onPress={() => {
427
+ triggerNativeHaptic('light');
428
+ setSelectedScheme('assembleRelease');
429
+ }}
308
430
  style={[
309
- styles.qrTab,
310
- activeQrTab === 'apk' && styles.qrTabActive,
431
+ styles.subTabItem,
432
+ selectedScheme === 'assembleRelease' && styles.subTabItemActive,
311
433
  ]}>
312
- <PackageIcon
313
- size={13}
314
- color={activeQrTab === 'apk' ? AppColors.white : AppColors.grayText}
315
- />
316
434
  <Text
317
435
  style={[
318
- styles.qrTabText,
319
- activeQrTab === 'apk' && styles.qrTabTextActive,
436
+ styles.subTabText,
437
+ selectedScheme === 'assembleRelease' && styles.subTabTextActive,
320
438
  ]}>
321
- Install Debug APK
439
+ Release (assembleRelease)
322
440
  </Text>
323
441
  </TouchableOpacity>
324
442
 
325
443
  <TouchableOpacity
444
+ disabled={isBuilding}
326
445
  activeOpacity={0.7}
327
- onPress={() => setActiveQrTab('host')}
446
+ onPress={() => {
447
+ triggerNativeHaptic('light');
448
+ setSelectedScheme('assembleDebug');
449
+ }}
328
450
  style={[
329
- styles.qrTab,
330
- activeQrTab === 'host' && styles.qrTabActive,
451
+ styles.subTabItem,
452
+ selectedScheme === 'assembleDebug' && styles.subTabItemActive,
331
453
  ]}>
332
- <SmartphoneIcon
333
- size={13}
334
- color={activeQrTab === 'host' ? AppColors.white : AppColors.grayText}
335
- />
336
454
  <Text
337
455
  style={[
338
- styles.qrTabText,
339
- activeQrTab === 'host' && styles.qrTabTextActive,
456
+ styles.subTabText,
457
+ selectedScheme === 'assembleDebug' && styles.subTabTextActive,
340
458
  ]}>
341
- Dev Host Info
459
+ 🛠 Debug (assembleDebug)
342
460
  </Text>
343
461
  </TouchableOpacity>
344
462
  </View>
345
463
 
346
- {/* QR Code Container */}
347
- <View style={styles.qrWrapper}>
348
- <QRCodeView
349
- value={currentQrValue}
350
- size={190}
351
- color={AppColors.primaryBlack}
352
- backgroundColor={AppColors.white}
353
- />
354
-
355
- <View style={styles.qrInfoBox}>
356
- <Text style={styles.qrTargetTitle}>
357
- {activeQrTab === 'apk'
358
- ? '📦 Direct APK Download URL'
359
- : activeQrTab === 'host'
360
- ? '📱 Dev Settings Bundle Host'
361
- : '⚡ Live Metro Fast-Refresh Endpoint'}
362
- </Text>
363
- <Text style={styles.qrTargetUrl} numberOfLines={2} ellipsizeMode="middle">
364
- {currentQrValue}
365
- </Text>
464
+ {/* Clean Build Checkbox */}
465
+ <TouchableOpacity
466
+ disabled={isBuilding}
467
+ activeOpacity={0.7}
468
+ onPress={() => {
469
+ triggerNativeHaptic('light');
470
+ setIsCleanBuild(!isCleanBuild);
471
+ }}
472
+ style={styles.cleanRow}>
473
+ <View
474
+ style={[
475
+ styles.checkboxBox,
476
+ isCleanBuild && styles.checkboxBoxActive,
477
+ ]}>
478
+ {isCleanBuild && <CheckIcon size={11} color={AppColors.white} />}
366
479
  </View>
367
- </View>
368
-
369
- {/* Quick Action Row */}
370
- <View style={styles.qrActionsRow}>
371
- <TouchableScale
372
- onPress={() => copyToClipboard(currentQrValue, 'QR Link')}
373
- style={styles.actionBtn}>
374
- <Text style={styles.actionBtnText}>Copy Link</Text>
375
- </TouchableScale>
480
+ <Text style={styles.cleanLabel}>
481
+ Clean build cache <Text style={styles.cleanCode}>(./gradlew clean)</Text>
482
+ </Text>
483
+ </TouchableOpacity>
376
484
 
377
- <TouchableScale
378
- onPress={() => {
379
- Share.share({
380
- message: currentQrValue,
381
- title: 'Metro Debug Link',
382
- });
383
- }}
384
- style={[styles.actionBtn, styles.actionBtnPrimary]}>
385
- <Text style={styles.actionBtnPrimaryText}>Share to Device</Text>
386
- </TouchableScale>
387
- </View>
388
- </View>
389
-
390
- {/* ─── Bare React Native Multi-Device Setup Guide ───────────────── */}
391
- <View style={styles.guideCard}>
392
- <Text style={styles.guideHeading}>📱 HOW TO CONNECT ANDROID DEVICE:</Text>
485
+ {/* Progress Display Bar (0% to 100%) */}
486
+ {isBuilding && (
487
+ <View style={styles.progressContainer}>
488
+ <View style={styles.progressTopRow}>
489
+ <View style={styles.progressTaskGroup}>
490
+ <ActivityIndicator size="small" color={AppColors.purple} />
491
+ <Text style={styles.progressTaskText} numberOfLines={1}>
492
+ {buildStatus.currentTask || 'Executing Gradle tasks...'}
493
+ </Text>
494
+ </View>
495
+ <Text style={styles.progressPercentageText}>
496
+ {buildStatus.progress}%
497
+ </Text>
498
+ </View>
393
499
 
394
- <View style={styles.stepRow}>
395
- <View style={styles.stepNumberBadge}>
396
- <Text style={styles.stepNumberText}>1</Text>
397
- </View>
398
- <View style={{flex: 1}}>
399
- <Text style={styles.stepTitle}>Connect to Same Wi-Fi</Text>
400
- <Text style={styles.stepDesc}>
401
- Make sure your Android phone is connected to the same Wi-Fi router or Mac Mobile Hotspot.
402
- </Text>
500
+ {/* Animated Progress Bar */}
501
+ <View style={styles.progressBarTrack}>
502
+ <Animated.View
503
+ style={[
504
+ styles.progressBarFill,
505
+ {
506
+ width: progressAnim.interpolate({
507
+ inputRange: [0, 100],
508
+ outputRange: ['5%', '100%'],
509
+ }),
510
+ },
511
+ ]}
512
+ />
513
+ </View>
403
514
  </View>
404
- </View>
515
+ )}
405
516
 
406
- <View style={styles.stepRow}>
407
- <View style={styles.stepNumberBadge}>
408
- <Text style={styles.stepNumberText}>2</Text>
409
- </View>
410
- <View style={{flex: 1}}>
411
- <Text style={styles.stepTitle}>Scan to Install / Connect</Text>
412
- <Text style={styles.stepDesc}>
413
- Open Android Camera or browser, scan the QR code above to download the APK or connect Metro.
517
+ {/* Error Container */}
518
+ {buildStatus.status === 'failed' && (
519
+ <View style={styles.errorContainer}>
520
+ <CircleXIcon size={13} color={AppColors.errorColor} />
521
+ <Text style={styles.errorText} numberOfLines={2}>
522
+ {buildStatus.error || 'Build execution failed.'}
414
523
  </Text>
415
524
  </View>
416
- </View>
525
+ )}
526
+
527
+ {/* Live Verbose Console Output */}
528
+ {((buildStatus.logs && buildStatus.logs.length > 0) || isBuilding) && (
529
+ <View style={styles.consoleContainer}>
530
+ <View style={styles.consoleHeaderRow}>
531
+ <View style={{flexDirection: 'row', alignItems: 'center', gap: 6}}>
532
+ <TerminalConsoleIcon color="#38BDF8" size={12} />
533
+ <Text style={styles.consoleHeaderTitle}>GRADLE VERBOSE OUTPUT</Text>
534
+ </View>
535
+ <TouchableOpacity
536
+ activeOpacity={0.7}
537
+ onPress={() => setShowVerboseLogs(!showVerboseLogs)}
538
+ style={styles.consoleToggleBtn}>
539
+ <Text style={styles.consoleToggleText}>
540
+ {showVerboseLogs ? 'Hide Console' : 'Show Console'}
541
+ </Text>
542
+ </TouchableOpacity>
543
+ </View>
544
+
545
+ {showVerboseLogs && (
546
+ <ScrollView
547
+ ref={verboseScrollRef}
548
+ style={styles.consoleLogBox}
549
+ contentContainerStyle={styles.consoleLogContent}
550
+ nestedScrollEnabled
551
+ showsVerticalScrollIndicator>
552
+ {buildStatus.logs && buildStatus.logs.length > 0 ? (
553
+ buildStatus.logs.map((logLine, idx) => {
554
+ let logColor = '#94A3B8';
555
+ if (logLine.startsWith('> Task :')) logColor = '#38BDF8';
556
+ else if (logLine.includes('BUILD SUCCESSFUL')) logColor = '#4ADE80';
557
+ else if (logLine.includes('FAILURE') || logLine.includes('error:')) logColor = '#F87171';
558
+ else if (logLine.includes('UP-TO-DATE')) logColor = '#A78BFA';
417
559
 
418
- <View style={styles.stepRow}>
419
- <View style={styles.stepNumberBadge}>
420
- <Text style={styles.stepNumberText}>3</Text>
560
+ return (
561
+ <Text key={idx} style={[styles.consoleLogLine, {color: logColor}]}>
562
+ {logLine}
563
+ </Text>
564
+ );
565
+ })
566
+ ) : (
567
+ <Text style={styles.consoleLogPlaceholder}>
568
+ Waiting for Gradle daemon output...
569
+ </Text>
570
+ )}
571
+ </ScrollView>
572
+ )}
421
573
  </View>
422
- <View style={{flex: 1}}>
423
- <Text style={styles.stepTitle}>Simultaneous Live Fast-Refresh ⚡</Text>
424
- <Text style={styles.stepDesc}>
425
- Any changes saved in VS Code will immediately update <Text style={{fontWeight: '700'}}>both the iOS Simulator and physical Android phone</Text> in real-time!
426
- </Text>
574
+ )}
575
+
576
+ {/* Action Button Row */}
577
+ {isBuilding ? (
578
+ <View style={styles.buildingActionsRow}>
579
+ <View style={styles.buildingStatusPill}>
580
+ <ActivityIndicator size="small" color={AppColors.purple} />
581
+ <Text style={styles.buildingStatusPillText} numberOfLines={1}>
582
+ Building ({buildStatus.progress}%)
583
+ </Text>
584
+ </View>
585
+
586
+ <TouchableScale
587
+ onPress={handleStopBuild}
588
+ style={styles.stopBtn}>
589
+ <CircleXIcon size={13} color={AppColors.white} />
590
+ <Text style={styles.stopBtnText}>Stop Build</Text>
591
+ </TouchableScale>
427
592
  </View>
428
- </View>
593
+ ) : (
594
+ <TouchableScale
595
+ onPress={handleStartBuild}
596
+ style={styles.generateBtn}>
597
+ <View style={styles.ctaContentRow}>
598
+ <SparkleIcon size={14} color={AppColors.white} />
599
+ <Text style={styles.generateBtnText}>
600
+ {isCleanBuild ? 'Clean & Generate Build' : 'Generate Build'}
601
+ </Text>
602
+ </View>
603
+ </TouchableScale>
604
+ )}
605
+ </View>
606
+
607
+ {/* ─── Footer Hint Note ───────────────────────────────────────── */}
608
+ <View style={styles.footerNoteRow}>
609
+ <InfoCircleIcon size={13} color={AppColors.grayTextWeak} />
610
+ <Text style={styles.footerNoteText}>
611
+ Ensure both Android devices are connected to the same Wi-Fi network.
612
+ </Text>
429
613
  </View>
430
614
  </ScrollView>
431
615
  );
432
616
  };
433
617
 
434
618
  const styles = StyleSheet.create({
435
- container: {
619
+ scrollArea: {
436
620
  flex: 1,
437
621
  backgroundColor: AppColors.contentBg,
438
622
  },
439
- content: {
623
+ scrollContent: {
440
624
  padding: 12,
441
625
  gap: 12,
442
- paddingBottom: 40,
626
+ paddingBottom: 100,
443
627
  },
444
- serverCard: {
628
+ heroCard: {
445
629
  backgroundColor: AppColors.primaryLight,
446
630
  borderRadius: 14,
447
- padding: 14,
448
631
  borderWidth: 1,
449
632
  borderColor: AppColors.grayBorderSecondary,
633
+ padding: 14,
450
634
  shadowColor: AppColors.black,
451
- shadowOffset: {width: 0, height: 2},
452
- shadowOpacity: 0.05,
635
+ shadowOpacity: 0.04,
453
636
  shadowRadius: 4,
454
- elevation: 2,
637
+ shadowOffset: {width: 0, height: 2},
638
+ elevation: 1,
455
639
  gap: 12,
456
640
  },
457
- serverCardTop: {
458
- flexDirection: 'row',
459
- alignItems: 'center',
460
- justifyContent: 'space-between',
461
- },
462
- serverStatusLeft: {
641
+ heroHeader: {
463
642
  flexDirection: 'row',
464
643
  alignItems: 'center',
465
644
  gap: 10,
466
- flex: 1,
467
645
  },
468
- statusDot: {
469
- width: 12,
470
- height: 12,
471
- borderRadius: 6,
646
+ heroIconWrap: {
647
+ width: 38,
648
+ height: 38,
649
+ borderRadius: 10,
650
+ backgroundColor: AppColors.purple,
651
+ alignItems: 'center',
652
+ justifyContent: 'center',
653
+ shadowColor: AppColors.purple,
654
+ shadowOpacity: 0.25,
655
+ shadowRadius: 4,
656
+ shadowOffset: {width: 0, height: 2},
657
+ elevation: 2,
472
658
  },
473
- serverTitle: {
659
+ heroTitle: {
474
660
  fontFamily: AppFonts.interBold,
475
661
  fontSize: 15,
476
662
  color: AppColors.primaryBlack,
663
+ letterSpacing: -0.2,
477
664
  },
478
- serverSubtitle: {
479
- fontFamily: AppFonts.interMedium,
480
- fontSize: 11,
665
+ heroSubtitle: {
666
+ fontFamily: AppFonts.interRegular,
667
+ fontSize: 11.5,
481
668
  color: AppColors.grayText,
482
- marginTop: 2,
483
- },
484
- portPill: {
485
- backgroundColor: `${AppColors.purple}18`,
486
- paddingHorizontal: 6,
487
- paddingVertical: 2,
488
- borderRadius: 6,
489
- },
490
- portPillText: {
491
- fontFamily: AppFonts.interBold,
492
- fontSize: 10,
493
- color: AppColors.purple,
669
+ marginTop: 1,
494
670
  },
495
- scanBtn: {
671
+ heroBadge: {
496
672
  flexDirection: 'row',
497
673
  alignItems: 'center',
498
674
  gap: 4,
499
- paddingHorizontal: 8,
500
- paddingVertical: 4,
675
+ backgroundColor: `${AppColors.emerald500}18`,
676
+ paddingHorizontal: 7,
677
+ paddingVertical: 3,
501
678
  borderRadius: 6,
502
- backgroundColor: `${AppColors.purple}14`,
503
- borderWidth: 1,
504
- borderColor: `${AppColors.purple}30`,
505
679
  },
506
- scanBtnText: {
507
- fontFamily: AppFonts.interBold,
508
- fontSize: 11,
509
- color: AppColors.purple,
680
+ pulseDot: {
681
+ width: 6,
682
+ height: 6,
683
+ borderRadius: 3,
684
+ backgroundColor: AppColors.emerald500,
510
685
  },
511
- portsRow: {
512
- flexDirection: 'row',
513
- gap: 8,
686
+ heroBadgeText: {
687
+ fontFamily: AppFonts.interBold,
688
+ fontSize: 9.5,
689
+ color: AppColors.emerald500,
514
690
  },
515
- portChip: {
516
- flex: 1,
691
+ heroMetricsStrip: {
517
692
  flexDirection: 'row',
518
693
  alignItems: 'center',
519
- justifyContent: 'center',
520
- gap: 4,
521
- paddingVertical: 7,
522
- borderRadius: 8,
523
694
  backgroundColor: AppColors.grayBackground,
524
- borderWidth: 1,
525
- borderColor: AppColors.grayBorderSecondary,
695
+ borderRadius: 10,
696
+ paddingVertical: 8,
697
+ paddingHorizontal: 10,
526
698
  },
527
- portChipSelected: {
528
- backgroundColor: `${AppColors.purple}18`,
529
- borderColor: AppColors.purple,
699
+ heroMetricItem: {
700
+ flex: 1,
701
+ alignItems: 'center',
702
+ paddingHorizontal: 2,
703
+ minWidth: 0,
530
704
  },
531
- portMiniDot: {
532
- width: 5,
533
- height: 5,
534
- borderRadius: 2.5,
705
+ heroMetricLabel: {
706
+ fontFamily: AppFonts.interBold,
707
+ fontSize: 8.5,
708
+ color: AppColors.grayTextWeak,
709
+ letterSpacing: 0.4,
535
710
  },
536
- portChipText: {
711
+ heroMetricValue: {
537
712
  fontFamily: AppFonts.interBold,
538
713
  fontSize: 11,
539
- color: AppColors.grayTextStrong,
540
- },
541
- portChipTextSelected: {
542
- color: AppColors.purple,
543
- },
544
- liveBadge: {
545
- backgroundColor: AppColors.greenColor,
546
- paddingHorizontal: 3,
547
- paddingVertical: 0.5,
548
- borderRadius: 3,
714
+ color: AppColors.primaryBlack,
715
+ marginTop: 2,
549
716
  },
550
- liveBadgeText: {
551
- fontFamily: AppFonts.interBold,
552
- fontSize: 7.5,
553
- color: AppColors.white,
717
+ heroMetricDivider: {
718
+ width: 1,
719
+ height: 20,
720
+ backgroundColor: AppColors.dividerColor,
554
721
  },
555
- card: {
722
+ sectionCard: {
556
723
  backgroundColor: AppColors.primaryLight,
557
724
  borderRadius: 14,
558
- padding: 14,
559
725
  borderWidth: 1,
560
726
  borderColor: AppColors.grayBorderSecondary,
727
+ padding: 14,
561
728
  shadowColor: AppColors.black,
562
- shadowOffset: {width: 0, height: 2},
563
- shadowOpacity: 0.05,
564
- shadowRadius: 4,
565
- elevation: 2,
566
- gap: 8,
729
+ shadowOpacity: 0.03,
730
+ shadowRadius: 3,
731
+ shadowOffset: {width: 0, height: 1},
732
+ elevation: 1,
733
+ gap: 12,
567
734
  },
568
- cardHeader: {
735
+ sectionHeaderRow: {
569
736
  flexDirection: 'row',
570
737
  alignItems: 'center',
571
738
  justifyContent: 'space-between',
572
739
  },
573
- cardTitle: {
740
+ sectionTitle: {
574
741
  fontFamily: AppFonts.interBold,
575
- fontSize: 11,
742
+ fontSize: 10.5,
576
743
  color: AppColors.grayTextWeak,
577
- letterSpacing: 0.6,
744
+ letterSpacing: 0.8,
745
+ textTransform: 'uppercase',
578
746
  },
579
- headerActionText: {
747
+ refreshBtn: {
748
+ flexDirection: 'row',
749
+ alignItems: 'center',
750
+ gap: 4,
751
+ paddingHorizontal: 7,
752
+ paddingVertical: 3,
753
+ borderRadius: 6,
754
+ backgroundColor: `${AppColors.purple}12`,
755
+ },
756
+ refreshBtnText: {
580
757
  fontFamily: AppFonts.interBold,
581
- fontSize: 11,
758
+ fontSize: 10,
582
759
  color: AppColors.purple,
583
760
  },
584
- inputContainer: {
761
+ qrCenteredWrapper: {
762
+ alignItems: 'center',
763
+ justifyContent: 'center',
764
+ backgroundColor: AppColors.grayBackground,
765
+ padding: 12,
766
+ borderRadius: 12,
767
+ borderWidth: 1,
768
+ borderColor: AppColors.grayBorderSecondary,
769
+ },
770
+ qrInnerFrame: {
771
+ backgroundColor: AppColors.white,
772
+ padding: 6,
773
+ borderRadius: 8,
774
+ },
775
+ urlBox: {
585
776
  flexDirection: 'row',
586
777
  alignItems: 'center',
587
778
  backgroundColor: AppColors.grayBackground,
588
779
  borderRadius: 10,
780
+ paddingLeft: 10,
781
+ paddingRight: 6,
782
+ paddingVertical: 6,
589
783
  borderWidth: 1,
590
784
  borderColor: AppColors.grayBorderSecondary,
591
- paddingHorizontal: 10,
592
- height: 40,
785
+ gap: 8,
593
786
  },
594
- inputPrefix: {
787
+ urlText: {
788
+ flex: 1,
595
789
  fontFamily: AppFonts.interMedium,
596
- fontSize: 12.5,
597
- color: AppColors.grayTextWeak,
790
+ fontSize: 11.5,
791
+ color: AppColors.skyBlue,
598
792
  },
599
- input: {
793
+ actionsRow: {
794
+ flexDirection: 'row',
795
+ gap: 10,
796
+ },
797
+ actionBtnSecondary: {
600
798
  flex: 1,
601
- fontFamily: AppFonts.interBold,
602
- fontSize: 13,
603
- color: AppColors.primaryBlack,
604
- paddingVertical: 0,
799
+ flexDirection: 'row',
800
+ alignItems: 'center',
801
+ justifyContent: 'center',
802
+ gap: 6,
803
+ paddingVertical: 9,
804
+ borderRadius: 10,
805
+ borderWidth: 1,
806
+ borderColor: AppColors.grayBorderSecondary,
807
+ backgroundColor: AppColors.grayBackground,
605
808
  },
606
- inputSuffix: {
809
+ actionBtnSecondaryText: {
607
810
  fontFamily: AppFonts.interBold,
608
- fontSize: 12.5,
609
- color: AppColors.purple,
610
- },
611
- inputHint: {
612
- fontFamily: AppFonts.interRegular,
613
- fontSize: 11,
614
- color: AppColors.grayTextWeak,
615
- lineHeight: 15,
811
+ fontSize: 12,
812
+ color: AppColors.grayTextStrong,
616
813
  },
617
- qrCard: {
618
- backgroundColor: AppColors.primaryLight,
619
- borderRadius: 14,
620
- padding: 14,
621
- borderWidth: 1,
622
- borderColor: AppColors.grayBorderSecondary,
623
- shadowColor: AppColors.black,
624
- shadowOffset: {width: 0, height: 2},
625
- shadowOpacity: 0.05,
814
+ actionBtnPrimary: {
815
+ flex: 1,
816
+ flexDirection: 'row',
817
+ alignItems: 'center',
818
+ justifyContent: 'center',
819
+ gap: 6,
820
+ paddingVertical: 9,
821
+ borderRadius: 10,
822
+ backgroundColor: AppColors.purple,
823
+ shadowColor: AppColors.purple,
824
+ shadowOpacity: 0.25,
626
825
  shadowRadius: 4,
826
+ shadowOffset: {width: 0, height: 2},
627
827
  elevation: 2,
828
+ },
829
+ actionBtnPrimaryText: {
830
+ fontFamily: AppFonts.interBold,
831
+ fontSize: 12,
832
+ color: AppColors.white,
833
+ },
834
+ completedBadge: {
835
+ flexDirection: 'row',
628
836
  alignItems: 'center',
629
- gap: 14,
837
+ gap: 3,
838
+ backgroundColor: `${AppColors.emerald500}18`,
839
+ paddingHorizontal: 6,
840
+ paddingVertical: 2,
841
+ borderRadius: 5,
842
+ },
843
+ completedBadgeText: {
844
+ fontFamily: AppFonts.interBold,
845
+ fontSize: 9.5,
846
+ color: AppColors.emerald500,
630
847
  },
631
- qrTabsRow: {
848
+ subTabStrip: {
632
849
  flexDirection: 'row',
633
850
  backgroundColor: AppColors.grayBackground,
634
- borderRadius: 10,
635
- padding: 3,
636
- width: '100%',
637
- gap: 4,
851
+ borderRadius: 8,
852
+ padding: 2,
853
+ borderWidth: 1,
854
+ borderColor: AppColors.grayBorderSecondary,
638
855
  },
639
- qrTab: {
856
+ subTabItem: {
640
857
  flex: 1,
641
- flexDirection: 'row',
858
+ paddingVertical: 7,
859
+ borderRadius: 6,
642
860
  alignItems: 'center',
643
861
  justifyContent: 'center',
644
- gap: 4,
645
- paddingVertical: 7,
646
- borderRadius: 8,
647
862
  },
648
- qrTabActive: {
863
+ subTabItemActive: {
649
864
  backgroundColor: AppColors.purple,
865
+ shadowColor: AppColors.purple,
866
+ shadowOpacity: 0.2,
867
+ shadowRadius: 3,
868
+ shadowOffset: {width: 0, height: 1},
869
+ elevation: 1,
650
870
  },
651
- qrTabText: {
871
+ subTabText: {
652
872
  fontFamily: AppFonts.interMedium,
653
873
  fontSize: 11,
654
874
  color: AppColors.grayText,
655
875
  },
656
- qrTabTextActive: {
657
- color: AppColors.white,
876
+ subTabTextActive: {
658
877
  fontFamily: AppFonts.interBold,
878
+ color: AppColors.white,
659
879
  },
660
- qrWrapper: {
880
+ cleanRow: {
881
+ flexDirection: 'row',
661
882
  alignItems: 'center',
662
- gap: 12,
883
+ gap: 8,
884
+ paddingVertical: 2,
663
885
  },
664
- qrInfoBox: {
886
+ checkboxBox: {
887
+ width: 18,
888
+ height: 18,
889
+ borderRadius: 4,
890
+ borderWidth: 1.5,
891
+ borderColor: AppColors.grayBorderSecondary,
892
+ backgroundColor: AppColors.grayBackground,
665
893
  alignItems: 'center',
666
- maxWidth: 280,
667
- gap: 2,
894
+ justifyContent: 'center',
668
895
  },
669
- qrTargetTitle: {
670
- fontFamily: AppFonts.interBold,
896
+ checkboxBoxActive: {
897
+ backgroundColor: AppColors.purple,
898
+ borderColor: AppColors.purple,
899
+ },
900
+ cleanLabel: {
901
+ fontFamily: AppFonts.interMedium,
671
902
  fontSize: 11.5,
672
- color: AppColors.primaryBlack,
903
+ color: AppColors.grayTextStrong,
673
904
  },
674
- qrTargetUrl: {
905
+ cleanCode: {
675
906
  fontFamily: AppFonts.interRegular,
907
+ color: AppColors.grayTextWeak,
676
908
  fontSize: 10.5,
677
- color: AppColors.skyBlue,
678
- textAlign: 'center',
679
909
  },
680
- qrActionsRow: {
681
- flexDirection: 'row',
682
- gap: 10,
683
- width: '100%',
684
- },
685
- actionBtn: {
686
- flex: 1,
687
- paddingVertical: 10,
910
+ progressContainer: {
911
+ backgroundColor: AppColors.grayBackground,
688
912
  borderRadius: 10,
913
+ padding: 10,
914
+ gap: 6,
689
915
  borderWidth: 1,
690
916
  borderColor: AppColors.grayBorderSecondary,
691
- backgroundColor: AppColors.grayBackground,
917
+ },
918
+ progressTopRow: {
919
+ flexDirection: 'row',
692
920
  alignItems: 'center',
693
- justifyContent: 'center',
921
+ justifyContent: 'space-between',
922
+ },
923
+ progressTaskGroup: {
924
+ flexDirection: 'row',
925
+ alignItems: 'center',
926
+ gap: 6,
927
+ flex: 1,
928
+ paddingRight: 8,
694
929
  },
695
- actionBtnText: {
930
+ progressTaskText: {
931
+ fontFamily: AppFonts.interMedium,
932
+ fontSize: 11,
933
+ color: AppColors.primaryBlack,
934
+ flex: 1,
935
+ },
936
+ progressPercentageText: {
696
937
  fontFamily: AppFonts.interBold,
697
- fontSize: 12,
698
- color: AppColors.grayTextStrong,
938
+ fontSize: 11.5,
939
+ color: AppColors.purple,
699
940
  },
700
- actionBtnPrimary: {
941
+ progressBarTrack: {
942
+ width: '100%',
943
+ height: 6,
944
+ borderRadius: 3,
945
+ backgroundColor: AppColors.grayBorderSecondary,
946
+ overflow: 'hidden',
947
+ },
948
+ progressBarFill: {
949
+ height: '100%',
701
950
  backgroundColor: AppColors.purple,
702
- borderColor: AppColors.purple,
951
+ borderRadius: 3,
703
952
  },
704
- actionBtnPrimaryText: {
705
- fontFamily: AppFonts.interBold,
706
- fontSize: 12,
707
- color: AppColors.white,
953
+ errorContainer: {
954
+ flexDirection: 'row',
955
+ alignItems: 'center',
956
+ gap: 6,
957
+ backgroundColor: `${AppColors.errorColor}12`,
958
+ padding: 8,
959
+ borderRadius: 8,
960
+ borderWidth: 1,
961
+ borderColor: `${AppColors.errorColor}25`,
708
962
  },
709
- guideCard: {
710
- backgroundColor: AppColors.primaryLight,
711
- borderRadius: 14,
712
- padding: 14,
963
+ errorText: {
964
+ fontFamily: AppFonts.interRegular,
965
+ fontSize: 11,
966
+ color: AppColors.errorColor,
967
+ flex: 1,
968
+ },
969
+ consoleContainer: {
970
+ backgroundColor: '#0F172A',
971
+ borderRadius: 10,
713
972
  borderWidth: 1,
714
- borderColor: AppColors.grayBorderSecondary,
715
- gap: 10,
973
+ borderColor: '#1E293B',
974
+ overflow: 'hidden',
975
+ marginTop: 4,
716
976
  },
717
- guideHeading: {
977
+ consoleHeaderRow: {
978
+ flexDirection: 'row',
979
+ alignItems: 'center',
980
+ justifyContent: 'space-between',
981
+ backgroundColor: '#1E293B',
982
+ paddingHorizontal: 10,
983
+ paddingVertical: 6,
984
+ },
985
+ consoleHeaderTitle: {
718
986
  fontFamily: AppFonts.interBold,
719
- fontSize: 11,
720
- color: AppColors.grayTextWeak,
721
- letterSpacing: 0.6,
987
+ fontSize: 10,
988
+ color: '#38BDF8',
989
+ letterSpacing: 0.5,
990
+ },
991
+ consoleToggleBtn: {
992
+ paddingHorizontal: 6,
993
+ paddingVertical: 2,
994
+ borderRadius: 4,
995
+ backgroundColor: 'rgba(255,255,255,0.1)',
996
+ },
997
+ consoleToggleText: {
998
+ fontFamily: AppFonts.interMedium,
999
+ fontSize: 9.5,
1000
+ color: '#94A3B8',
1001
+ },
1002
+ consoleLogBox: {
1003
+ maxHeight: 140,
1004
+ paddingHorizontal: 10,
1005
+ paddingVertical: 8,
722
1006
  },
723
- stepRow: {
1007
+ consoleLogContent: {
1008
+ gap: 3,
1009
+ },
1010
+ consoleLogLine: {
1011
+ fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
1012
+ fontSize: 10,
1013
+ lineHeight: 14,
1014
+ },
1015
+ consoleLogPlaceholder: {
1016
+ fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
1017
+ fontSize: 10,
1018
+ color: '#64748B',
1019
+ fontStyle: 'italic',
1020
+ },
1021
+ generateBtn: {
1022
+ backgroundColor: AppColors.purple,
1023
+ borderRadius: 10,
1024
+ paddingVertical: 10,
1025
+ alignItems: 'center',
1026
+ justifyContent: 'center',
1027
+ shadowColor: AppColors.purple,
1028
+ shadowOpacity: 0.25,
1029
+ shadowRadius: 4,
1030
+ shadowOffset: {width: 0, height: 2},
1031
+ elevation: 2,
1032
+ },
1033
+ generateBtnDisabled: {
1034
+ opacity: 0.7,
1035
+ },
1036
+ buildingActionsRow: {
724
1037
  flexDirection: 'row',
725
- alignItems: 'flex-start',
1038
+ alignItems: 'center',
726
1039
  gap: 10,
727
1040
  },
728
- stepNumberBadge: {
729
- width: 22,
730
- height: 22,
731
- borderRadius: 11,
732
- backgroundColor: `${AppColors.purple}18`,
1041
+ buildingStatusPill: {
1042
+ flex: 1,
1043
+ flexDirection: 'row',
733
1044
  alignItems: 'center',
734
1045
  justifyContent: 'center',
735
- marginTop: 1,
1046
+ gap: 8,
1047
+ backgroundColor: `${AppColors.purple}14`,
1048
+ borderRadius: 10,
1049
+ paddingVertical: 10,
1050
+ borderWidth: 1,
1051
+ borderColor: `${AppColors.purple}30`,
736
1052
  },
737
- stepNumberText: {
1053
+ buildingStatusPillText: {
738
1054
  fontFamily: AppFonts.interBold,
739
- fontSize: 11,
1055
+ fontSize: 12,
740
1056
  color: AppColors.purple,
741
1057
  },
742
- stepTitle: {
1058
+ stopBtn: {
1059
+ flexDirection: 'row',
1060
+ alignItems: 'center',
1061
+ justifyContent: 'center',
1062
+ gap: 6,
1063
+ backgroundColor: AppColors.errorColor,
1064
+ borderRadius: 10,
1065
+ paddingHorizontal: 16,
1066
+ paddingVertical: 10,
1067
+ shadowColor: AppColors.errorColor,
1068
+ shadowOpacity: 0.25,
1069
+ shadowRadius: 4,
1070
+ shadowOffset: {width: 0, height: 2},
1071
+ elevation: 2,
1072
+ },
1073
+ stopBtnText: {
1074
+ fontFamily: AppFonts.interBold,
1075
+ fontSize: 12,
1076
+ color: AppColors.white,
1077
+ },
1078
+ ctaContentRow: {
1079
+ flexDirection: 'row',
1080
+ alignItems: 'center',
1081
+ gap: 6,
1082
+ },
1083
+ generateBtnText: {
743
1084
  fontFamily: AppFonts.interBold,
744
1085
  fontSize: 12.5,
745
- color: AppColors.primaryBlack,
1086
+ color: AppColors.white,
746
1087
  },
747
- stepDesc: {
1088
+ footerNoteRow: {
1089
+ flexDirection: 'row',
1090
+ alignItems: 'center',
1091
+ gap: 6,
1092
+ paddingHorizontal: 8,
1093
+ },
1094
+ footerNoteText: {
748
1095
  fontFamily: AppFonts.interRegular,
749
1096
  fontSize: 11,
750
- color: AppColors.grayText,
751
- lineHeight: 16,
752
- marginTop: 1,
1097
+ color: AppColors.grayTextWeak,
1098
+ textAlign: 'center',
1099
+ flex: 1,
753
1100
  },
754
1101
  });
755
1102