react-native-inapp-inspector 2.3.19 → 2.3.21

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 (353) hide show
  1. package/README.md +14 -14
  2. package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +67 -0
  3. package/dist/commonjs/analytics.js +1 -24
  4. package/dist/commonjs/bundle.js +1 -16
  5. package/dist/commonjs/capture.js +1 -35
  6. package/dist/commonjs/components/AnalyticsDetail.js +92 -623
  7. package/dist/commonjs/components/AnalyticsEventCard.js +54 -350
  8. package/dist/commonjs/components/AnalyticsGraph.js +70 -370
  9. package/dist/commonjs/components/AnimatedEntrance.js +1 -11
  10. package/dist/commonjs/components/AppHeaderLogo.js +7 -134
  11. package/dist/commonjs/components/BrandCircleIcon.js +73 -118
  12. package/dist/commonjs/components/BrandSquareIcon.js +63 -108
  13. package/dist/commonjs/components/CodeSnippet.js +48 -623
  14. package/dist/commonjs/components/ConsoleLogCard.js +63 -537
  15. package/dist/commonjs/components/CopyButton.js +3 -89
  16. package/dist/commonjs/components/DiffViewer.js +19 -83
  17. package/dist/commonjs/components/DomainHeader.js +27 -127
  18. package/dist/commonjs/components/EmptyState.js +10 -87
  19. package/dist/commonjs/components/EndOfListFooter.js +7 -81
  20. package/dist/commonjs/components/ErrorBoundary.js +72 -566
  21. package/dist/commonjs/components/HeadersSection.js +31 -110
  22. package/dist/commonjs/components/HighlightText.js +17 -58
  23. package/dist/commonjs/components/Inspector/AboutModal.d.ts +6 -0
  24. package/dist/commonjs/components/Inspector/AboutModal.js +243 -0
  25. package/dist/commonjs/components/Inspector/AnalyticsFilterModal.js +98 -797
  26. package/dist/commonjs/components/Inspector/AnalyticsTab.js +284 -930
  27. package/dist/commonjs/components/Inspector/BundleTab.js +551 -2918
  28. package/dist/commonjs/components/Inspector/ConsoleTab.js +79 -492
  29. package/dist/commonjs/components/Inspector/CrashDetail.js +123 -672
  30. package/dist/commonjs/components/Inspector/CrashFilterModal.js +66 -498
  31. package/dist/commonjs/components/Inspector/CrashTab.js +98 -670
  32. package/dist/commonjs/components/Inspector/DebuggingTab.js +74 -875
  33. package/dist/commonjs/components/Inspector/DeviceInfoTab.js +143 -907
  34. package/dist/commonjs/components/Inspector/FabLauncher.js +42 -466
  35. package/dist/commonjs/components/Inspector/FeatureUnderDevNotice.js +6 -99
  36. package/dist/commonjs/components/Inspector/InspectorContext.js +1 -21
  37. package/dist/commonjs/components/Inspector/InspectorHeader.js +191 -1110
  38. package/dist/commonjs/components/Inspector/LogDetail.js +168 -994
  39. package/dist/commonjs/components/Inspector/MainScreen.js +52 -335
  40. package/dist/commonjs/components/Inspector/MediaGalleryTab.js +97 -644
  41. package/dist/commonjs/components/Inspector/MediaPreviewModal.js +90 -605
  42. package/dist/commonjs/components/Inspector/NavigationTracker.js +1 -12
  43. package/dist/commonjs/components/Inspector/NetworkDetail.js +89 -411
  44. package/dist/commonjs/components/Inspector/NetworkFilterModal.js +60 -576
  45. package/dist/commonjs/components/Inspector/NetworkTab.js +84 -514
  46. package/dist/commonjs/components/Inspector/NpmStarPrompt.js +18 -434
  47. package/dist/commonjs/components/Inspector/NpmUpdateToast.js +25 -298
  48. package/dist/commonjs/components/Inspector/PerformanceTab.js +182 -1397
  49. package/dist/commonjs/components/Inspector/ReduxDetail.js +188 -1089
  50. package/dist/commonjs/components/Inspector/ReduxTab.js +85 -701
  51. package/dist/commonjs/components/Inspector/SettingsPanel.js +427 -3807
  52. package/dist/commonjs/components/Inspector/SkeletonPlaceholder.js +11 -180
  53. package/dist/commonjs/components/Inspector/StorageTab.js +93 -826
  54. package/dist/commonjs/components/Inspector/TabBar.js +36 -334
  55. package/dist/commonjs/components/Inspector/UpdateAvailableModal.js +37 -412
  56. package/dist/commonjs/components/JsonViewer.js +168 -381
  57. package/dist/commonjs/components/LogCard.js +57 -567
  58. package/dist/commonjs/components/LogSyntaxHighlighter.js +11 -130
  59. package/dist/commonjs/components/MetaAccordion.js +69 -238
  60. package/dist/commonjs/components/MiniBarChart.js +3 -56
  61. package/dist/commonjs/components/MiniLineChart.js +3 -58
  62. package/dist/commonjs/components/NetworkIcons.d.ts +13 -0
  63. package/dist/commonjs/components/NetworkIcons.js +521 -1022
  64. package/dist/commonjs/components/QRCodeView.js +5 -79
  65. package/dist/commonjs/components/SectionHeader.js +15 -37
  66. package/dist/commonjs/components/SegmentedTabs.js +7 -62
  67. package/dist/commonjs/components/SkeletonPlaceholder.js +11 -180
  68. package/dist/commonjs/components/Slider.js +15 -243
  69. package/dist/commonjs/components/SourcePageCard.js +30 -89
  70. package/dist/commonjs/components/Toast.js +5 -147
  71. package/dist/commonjs/components/TouchableScale.js +3 -24
  72. package/dist/commonjs/components/TreeNode.js +55 -130
  73. package/dist/commonjs/console.js +1 -16
  74. package/dist/commonjs/constants/index.js +1 -32
  75. package/dist/commonjs/constants/telemetryConfig.js +1 -6
  76. package/dist/commonjs/constants/version.d.ts +1 -1
  77. package/dist/commonjs/constants/version.js +1 -4
  78. package/dist/commonjs/crash.js +1 -23
  79. package/dist/commonjs/customHooks/analyticsLogger.js +1 -250
  80. package/dist/commonjs/customHooks/bundleAnalyzer.js +1 -957
  81. package/dist/commonjs/customHooks/consoleLogger.js +6 -445
  82. package/dist/commonjs/customHooks/crashHandler.js +7 -656
  83. package/dist/commonjs/customHooks/logFilters.js +1 -23
  84. package/dist/commonjs/customHooks/networkLogger.js +2 -536
  85. package/dist/commonjs/customHooks/performanceTracker.js +63 -750
  86. package/dist/commonjs/customHooks/reduxLogger.js +2 -313
  87. package/dist/commonjs/customHooks/storageInspector.js +1 -435
  88. package/dist/commonjs/customHooks/useAccordion.js +1 -18
  89. package/dist/commonjs/decorators/index.js +1 -100
  90. package/dist/commonjs/helpers/gaAnalyticsRegistry.js +1 -148
  91. package/dist/commonjs/helpers/index.d.ts +1 -0
  92. package/dist/commonjs/helpers/index.js +8 -921
  93. package/dist/commonjs/helpers/memoryManager.js +1 -99
  94. package/dist/commonjs/helpers/qrGenerator.js +1 -367
  95. package/dist/commonjs/helpers/remoteConfig.js +1 -165
  96. package/dist/commonjs/helpers/searchQueryParser.js +1 -62
  97. package/dist/commonjs/helpers/settingsStore.js +1 -144
  98. package/dist/commonjs/helpers/telemetry.js +1 -501
  99. package/dist/commonjs/helpers/toast.js +1 -20
  100. package/dist/commonjs/i18n/index.js +1 -90
  101. package/dist/commonjs/i18n/locales/en.json +1 -1140
  102. package/dist/commonjs/index.js +5 -2168
  103. package/dist/commonjs/metro.js +6 -468
  104. package/dist/commonjs/native/NativeInspector.d.ts +1 -0
  105. package/dist/commonjs/native/NativeInspector.js +1 -415
  106. package/dist/commonjs/native/NativeNetworkInspector.js +1 -4
  107. package/dist/commonjs/network.js +1 -13
  108. package/dist/commonjs/performance.js +1 -29
  109. package/dist/commonjs/redux.js +1 -20
  110. package/dist/commonjs/storage.js +1 -14
  111. package/dist/commonjs/styles/AppColors.js +1 -423
  112. package/dist/commonjs/styles/AppFonts.js +1 -17
  113. package/dist/commonjs/styles/common.js +1 -190
  114. package/dist/commonjs/styles/index.d.ts +6 -0
  115. package/dist/commonjs/styles/index.js +1 -1589
  116. package/dist/commonjs/types/enums.d.ts +0 -1
  117. package/dist/commonjs/types/enums.js +1 -152
  118. package/dist/commonjs/types/index.js +1 -18
  119. package/dist/commonjs/types/interfaces.d.ts +2 -2
  120. package/dist/commonjs/types/interfaces.js +1 -2
  121. package/dist/esm/analytics.js +1 -2
  122. package/dist/esm/bundle.js +1 -2
  123. package/dist/esm/capture.js +1 -32
  124. package/dist/esm/components/AnalyticsDetail.js +171 -664
  125. package/dist/esm/components/AnalyticsEventCard.js +77 -335
  126. package/dist/esm/components/AnalyticsGraph.js +95 -357
  127. package/dist/esm/components/AnimatedEntrance.js +1 -6
  128. package/dist/esm/components/AppHeaderLogo.js +7 -94
  129. package/dist/esm/components/BrandCircleIcon.js +114 -119
  130. package/dist/esm/components/BrandSquareIcon.js +73 -78
  131. package/dist/esm/components/CodeSnippet.js +58 -595
  132. package/dist/esm/components/ConsoleLogCard.js +91 -526
  133. package/dist/esm/components/CopyButton.js +3 -51
  134. package/dist/esm/components/DiffViewer.js +22 -48
  135. package/dist/esm/components/DomainHeader.js +43 -138
  136. package/dist/esm/components/EmptyState.js +17 -56
  137. package/dist/esm/components/EndOfListFooter.js +15 -83
  138. package/dist/esm/components/ErrorBoundary.js +125 -582
  139. package/dist/esm/components/HeadersSection.js +52 -93
  140. package/dist/esm/components/HighlightText.js +17 -53
  141. package/dist/esm/components/Inspector/AboutModal.d.ts +6 -0
  142. package/dist/esm/components/Inspector/AboutModal.js +243 -0
  143. package/dist/esm/components/Inspector/AnalyticsFilterModal.js +225 -886
  144. package/dist/esm/components/Inspector/AnalyticsTab.js +296 -904
  145. package/dist/esm/components/Inspector/BundleTab.js +1175 -3502
  146. package/dist/esm/components/Inspector/ConsoleTab.js +113 -488
  147. package/dist/esm/components/Inspector/CrashDetail.js +236 -747
  148. package/dist/esm/components/Inspector/CrashFilterModal.js +149 -541
  149. package/dist/esm/components/Inspector/CrashTab.js +177 -711
  150. package/dist/esm/components/Inspector/DebuggingTab.js +164 -925
  151. package/dist/esm/components/Inspector/DeviceInfoTab.js +199 -924
  152. package/dist/esm/components/Inspector/FabLauncher.js +68 -454
  153. package/dist/esm/components/Inspector/FeatureUnderDevNotice.js +14 -70
  154. package/dist/esm/components/Inspector/InspectorContext.js +1 -12
  155. package/dist/esm/components/Inspector/InspectorHeader.js +282 -1163
  156. package/dist/esm/components/Inspector/LogDetail.js +235 -1023
  157. package/dist/esm/components/Inspector/MainScreen.js +78 -323
  158. package/dist/esm/components/Inspector/MediaGalleryTab.js +143 -650
  159. package/dist/esm/components/Inspector/MediaPreviewModal.js +138 -613
  160. package/dist/esm/components/Inspector/NavigationTracker.js +1 -10
  161. package/dist/esm/components/Inspector/NetworkDetail.js +138 -455
  162. package/dist/esm/components/Inspector/NetworkFilterModal.js +122 -597
  163. package/dist/esm/components/Inspector/NetworkTab.js +125 -517
  164. package/dist/esm/components/Inspector/NpmStarPrompt.js +58 -434
  165. package/dist/esm/components/Inspector/NpmUpdateToast.js +45 -281
  166. package/dist/esm/components/Inspector/PerformanceTab.js +393 -1570
  167. package/dist/esm/components/Inspector/ReduxDetail.js +307 -1170
  168. package/dist/esm/components/Inspector/ReduxTab.js +144 -722
  169. package/dist/esm/components/Inspector/SettingsPanel.js +643 -3985
  170. package/dist/esm/components/Inspector/SkeletonPlaceholder.js +30 -163
  171. package/dist/esm/components/Inspector/StorageTab.js +172 -866
  172. package/dist/esm/components/Inspector/TabBar.js +45 -305
  173. package/dist/esm/components/Inspector/UpdateAvailableModal.js +80 -418
  174. package/dist/esm/components/JsonViewer.js +179 -354
  175. package/dist/esm/components/LogCard.js +93 -565
  176. package/dist/esm/components/LogSyntaxHighlighter.js +11 -123
  177. package/dist/esm/components/MetaAccordion.js +136 -267
  178. package/dist/esm/components/MiniBarChart.js +3 -18
  179. package/dist/esm/components/MiniLineChart.js +3 -20
  180. package/dist/esm/components/NetworkIcons.d.ts +13 -0
  181. package/dist/esm/components/NetworkIcons.js +523 -838
  182. package/dist/esm/components/QRCodeView.js +8 -45
  183. package/dist/esm/components/SectionHeader.js +22 -39
  184. package/dist/esm/components/SegmentedTabs.js +8 -58
  185. package/dist/esm/components/SkeletonPlaceholder.js +30 -163
  186. package/dist/esm/components/Slider.js +24 -213
  187. package/dist/esm/components/SourcePageCard.js +65 -86
  188. package/dist/esm/components/Toast.js +10 -117
  189. package/dist/esm/components/TouchableScale.js +3 -19
  190. package/dist/esm/components/TreeNode.js +58 -95
  191. package/dist/esm/console.js +1 -2
  192. package/dist/esm/constants/index.js +1 -28
  193. package/dist/esm/constants/telemetryConfig.js +1 -3
  194. package/dist/esm/constants/version.d.ts +1 -1
  195. package/dist/esm/constants/version.js +1 -1
  196. package/dist/esm/crash.js +1 -2
  197. package/dist/esm/customHooks/analyticsLogger.js +1 -230
  198. package/dist/esm/customHooks/bundleAnalyzer.js +1 -944
  199. package/dist/esm/customHooks/consoleLogger.js +6 -432
  200. package/dist/esm/customHooks/crashHandler.js +7 -630
  201. package/dist/esm/customHooks/logFilters.js +1 -20
  202. package/dist/esm/customHooks/networkLogger.js +2 -519
  203. package/dist/esm/customHooks/performanceTracker.js +63 -723
  204. package/dist/esm/customHooks/reduxLogger.js +2 -293
  205. package/dist/esm/customHooks/storageInspector.js +1 -418
  206. package/dist/esm/customHooks/useAccordion.js +1 -16
  207. package/dist/esm/decorators/index.js +1 -95
  208. package/dist/esm/helpers/gaAnalyticsRegistry.js +1 -143
  209. package/dist/esm/helpers/index.d.ts +1 -0
  210. package/dist/esm/helpers/index.js +8 -861
  211. package/dist/esm/helpers/memoryManager.js +1 -91
  212. package/dist/esm/helpers/qrGenerator.js +1 -364
  213. package/dist/esm/helpers/remoteConfig.js +1 -160
  214. package/dist/esm/helpers/searchQueryParser.js +1 -59
  215. package/dist/esm/helpers/settingsStore.js +1 -134
  216. package/dist/esm/helpers/telemetry.js +1 -489
  217. package/dist/esm/helpers/toast.js +1 -15
  218. package/dist/esm/i18n/index.js +1 -78
  219. package/dist/esm/i18n/locales/en.json +1 -1140
  220. package/dist/esm/index.js +7 -1982
  221. package/dist/esm/metro.js +6 -459
  222. package/dist/esm/native/NativeInspector.d.ts +1 -0
  223. package/dist/esm/native/NativeInspector.js +1 -382
  224. package/dist/esm/native/NativeNetworkInspector.js +1 -2
  225. package/dist/esm/network.js +1 -1
  226. package/dist/esm/performance.js +1 -2
  227. package/dist/esm/redux.js +1 -1
  228. package/dist/esm/storage.js +1 -1
  229. package/dist/esm/styles/AppColors.js +1 -417
  230. package/dist/esm/styles/AppFonts.js +1 -13
  231. package/dist/esm/styles/common.js +1 -186
  232. package/dist/esm/styles/index.d.ts +6 -0
  233. package/dist/esm/styles/index.js +1 -1551
  234. package/dist/esm/types/enums.d.ts +0 -1
  235. package/dist/esm/types/enums.js +1 -149
  236. package/dist/esm/types/index.js +1 -2
  237. package/dist/esm/types/interfaces.d.ts +2 -2
  238. package/dist/esm/types/interfaces.js +1 -1
  239. package/ios/NetworkInspectorModule.mm +60 -12
  240. package/package.json +5 -3
  241. package/src/native/NativeInspector.ts +18 -0
  242. package/dist/commonjs/components/Inspector/FeedbackModal.d.ts +0 -7
  243. package/dist/commonjs/components/Inspector/FeedbackModal.js +0 -552
  244. package/dist/esm/components/Inspector/FeedbackModal.d.ts +0 -7
  245. package/dist/esm/components/Inspector/FeedbackModal.js +0 -515
  246. package/src/analytics.ts +0 -35
  247. package/src/bundle.ts +0 -25
  248. package/src/capture.ts +0 -109
  249. package/src/components/AnalyticsDetail.tsx +0 -870
  250. package/src/components/AnalyticsEventCard.tsx +0 -444
  251. package/src/components/AnalyticsGraph.tsx +0 -583
  252. package/src/components/AnimatedEntrance.tsx +0 -20
  253. package/src/components/AppHeaderLogo.tsx +0 -143
  254. package/src/components/BrandCircleIcon.tsx +0 -144
  255. package/src/components/BrandSquareIcon.tsx +0 -184
  256. package/src/components/CodeSnippet.tsx +0 -725
  257. package/src/components/ConsoleLogCard.tsx +0 -679
  258. package/src/components/CopyButton.tsx +0 -87
  259. package/src/components/DiffViewer.tsx +0 -82
  260. package/src/components/DomainHeader.tsx +0 -224
  261. package/src/components/EmptyState.tsx +0 -97
  262. package/src/components/EndOfListFooter.tsx +0 -100
  263. package/src/components/ErrorBoundary.tsx +0 -688
  264. package/src/components/HeadersSection.tsx +0 -172
  265. package/src/components/HighlightText.tsx +0 -100
  266. package/src/components/Inspector/AnalyticsFilterModal.tsx +0 -1250
  267. package/src/components/Inspector/AnalyticsTab.tsx +0 -1362
  268. package/src/components/Inspector/BundleTab.tsx +0 -4768
  269. package/src/components/Inspector/ConsoleTab.tsx +0 -726
  270. package/src/components/Inspector/CrashDetail.tsx +0 -997
  271. package/src/components/Inspector/CrashFilterModal.tsx +0 -721
  272. package/src/components/Inspector/CrashTab.tsx +0 -933
  273. package/src/components/Inspector/DebuggingTab.tsx +0 -1103
  274. package/src/components/Inspector/DeviceInfoTab.tsx +0 -1397
  275. package/src/components/Inspector/FabLauncher.tsx +0 -590
  276. package/src/components/Inspector/FeatureUnderDevNotice.tsx +0 -94
  277. package/src/components/Inspector/FeedbackModal.tsx +0 -626
  278. package/src/components/Inspector/InspectorContext.tsx +0 -28
  279. package/src/components/Inspector/InspectorHeader.tsx +0 -1583
  280. package/src/components/Inspector/LogDetail.tsx +0 -1431
  281. package/src/components/Inspector/MainScreen.tsx +0 -460
  282. package/src/components/Inspector/MediaGalleryTab.tsx +0 -829
  283. package/src/components/Inspector/MediaPreviewModal.tsx +0 -783
  284. package/src/components/Inspector/NavigationTracker.tsx +0 -13
  285. package/src/components/Inspector/NetworkDetail.tsx +0 -778
  286. package/src/components/Inspector/NetworkFilterModal.tsx +0 -730
  287. package/src/components/Inspector/NetworkTab.tsx +0 -820
  288. package/src/components/Inspector/NpmStarPrompt.tsx +0 -532
  289. package/src/components/Inspector/NpmUpdateToast.tsx +0 -387
  290. package/src/components/Inspector/PerformanceTab.tsx +0 -1967
  291. package/src/components/Inspector/ReduxDetail.tsx +0 -1651
  292. package/src/components/Inspector/ReduxTab.tsx +0 -987
  293. package/src/components/Inspector/SettingsPanel.tsx +0 -5136
  294. package/src/components/Inspector/SkeletonPlaceholder.tsx +0 -206
  295. package/src/components/Inspector/StorageTab.tsx +0 -1159
  296. package/src/components/Inspector/TabBar.tsx +0 -431
  297. package/src/components/Inspector/UpdateAvailableModal.tsx +0 -555
  298. package/src/components/JsonViewer.tsx +0 -549
  299. package/src/components/LogCard.tsx +0 -694
  300. package/src/components/LogSyntaxHighlighter.tsx +0 -178
  301. package/src/components/MetaAccordion.tsx +0 -355
  302. package/src/components/MiniBarChart.tsx +0 -42
  303. package/src/components/MiniLineChart.tsx +0 -33
  304. package/src/components/NetworkIcons.tsx +0 -2655
  305. package/src/components/QRCodeView.tsx +0 -75
  306. package/src/components/SectionHeader.tsx +0 -101
  307. package/src/components/SegmentedTabs.tsx +0 -84
  308. package/src/components/SkeletonPlaceholder.tsx +0 -206
  309. package/src/components/Slider.tsx +0 -300
  310. package/src/components/SourcePageCard.tsx +0 -150
  311. package/src/components/Toast.tsx +0 -131
  312. package/src/components/TouchableScale.tsx +0 -61
  313. package/src/components/TreeNode.tsx +0 -171
  314. package/src/console.ts +0 -24
  315. package/src/constants/index.ts +0 -41
  316. package/src/constants/telemetryConfig.ts +0 -4
  317. package/src/constants/version.ts +0 -3
  318. package/src/crash.ts +0 -32
  319. package/src/customHooks/analyticsLogger.ts +0 -336
  320. package/src/customHooks/bundleAnalyzer.ts +0 -1256
  321. package/src/customHooks/consoleLogger.ts +0 -530
  322. package/src/customHooks/crashHandler.ts +0 -944
  323. package/src/customHooks/logFilters.ts +0 -32
  324. package/src/customHooks/networkLogger.ts +0 -624
  325. package/src/customHooks/performanceTracker.ts +0 -1014
  326. package/src/customHooks/reduxLogger.ts +0 -406
  327. package/src/customHooks/storageInspector.ts +0 -513
  328. package/src/customHooks/useAccordion.tsx +0 -27
  329. package/src/decorators/index.ts +0 -184
  330. package/src/helpers/gaAnalyticsRegistry.ts +0 -204
  331. package/src/helpers/index.ts +0 -1092
  332. package/src/helpers/memoryManager.ts +0 -138
  333. package/src/helpers/qrGenerator.ts +0 -430
  334. package/src/helpers/remoteConfig.ts +0 -212
  335. package/src/helpers/searchQueryParser.ts +0 -84
  336. package/src/helpers/settingsStore.ts +0 -171
  337. package/src/helpers/telemetry.ts +0 -568
  338. package/src/helpers/toast.ts +0 -17
  339. package/src/i18n/index.ts +0 -104
  340. package/src/i18n/locales/en.json +0 -1141
  341. package/src/index.tsx +0 -2650
  342. package/src/metro.ts +0 -598
  343. package/src/network.ts +0 -22
  344. package/src/performance.ts +0 -38
  345. package/src/redux.ts +0 -23
  346. package/src/storage.ts +0 -18
  347. package/src/styles/AppColors.ts +0 -455
  348. package/src/styles/AppFonts.ts +0 -26
  349. package/src/styles/common.ts +0 -209
  350. package/src/styles/index.ts +0 -1606
  351. package/src/types/enums.ts +0 -210
  352. package/src/types/index.ts +0 -34
  353. package/src/types/interfaces.ts +0 -535
@@ -1,1583 +0,0 @@
1
- import React, {useMemo} from 'react';
2
- import {
3
- Alert,
4
- Animated,
5
- Linking,
6
- Platform,
7
- Pressable,
8
- ScrollView,
9
- Text,
10
- TouchableOpacity,
11
- useWindowDimensions,
12
- View,
13
- } from 'react-native';
14
- import LinearGradient from 'react-native-linear-gradient';
15
- import {useInspector} from './InspectorContext';
16
- import TouchableScale from '../TouchableScale';
17
- import AppHeaderLogo from '../AppHeaderLogo';
18
- import styles from '../../styles';
19
- import {AppColors} from '../../styles/AppColors';
20
- import {AppFonts} from '../../styles/AppFonts';
21
- import {METHOD_COLORS} from '../../constants';
22
- import {LIB_VERSION} from '../../constants';
23
- import {Method} from '../../types';
24
- import {
25
- getStatusColor,
26
- getAppName,
27
- formatTime,
28
- getSize,
29
- getAppVersionAndBuild,
30
- } from '../../helpers';
31
- import {
32
- getNativeDeviceMetrics,
33
- triggerNativeHaptic,
34
- } from '../../native/NativeInspector';
35
- import {ScreenCapture, CapturedMediaItem} from '../../capture';
36
- import {showToast} from '../../helpers/toast';
37
- import {UpdateAvailableModal} from './UpdateAvailableModal';
38
- import {MediaPreviewModal} from './MediaPreviewModal';
39
- import {
40
- WhiteBackNavigation,
41
- TrashIcon,
42
- SettingsIcon,
43
- CloseWhite,
44
- ChevronDownIcon,
45
- ClockIcon,
46
- SizeIcon,
47
- AppleIcon,
48
- AndroidIcon,
49
- NpmIcon,
50
- ResetIcon,
51
- BoltIcon,
52
- InfoCircleIcon,
53
- CameraIcon,
54
- VideoCameraIcon,
55
- } from '../NetworkIcons';
56
- import {useTranslation} from '../../i18n';
57
-
58
- const InspectorHeader = React.memo(() => {
59
- const {t} = useTranslation();
60
- const {
61
- modalHeightPercent,
62
- appIcon,
63
- selected,
64
- setSelected,
65
- selectedEvent,
66
- setSelectedEvent,
67
- selectedLog,
68
- setSelectedLog,
69
- selectedReduxSlice,
70
- setSelectedReduxSlice,
71
- selectedReduxAction,
72
- setSelectedReduxAction,
73
- reduxState,
74
- reduxLastActionMap,
75
- showHeaderInfo,
76
- setShowHeaderInfo,
77
- updateAvailable,
78
- latestNpmVersion,
79
- clearAnim,
80
- activePulseAnim,
81
- unreadPulseAnim,
82
- runClearAllWithAnimation,
83
- settingsPage,
84
- setSettingsPage,
85
- setSettingsActiveSubTab,
86
- isFeedbackOpen,
87
- setIsFeedbackOpen,
88
- resetToDefaults,
89
- closeModal,
90
- minimizeInspector,
91
- detailTitle,
92
- activeTab,
93
- environment,
94
- visible,
95
- selectedCrash,
96
- setSelectedCrash,
97
- refreshMediaCount,
98
- } = useInspector();
99
-
100
- const {width: windowWidth} = useWindowDimensions();
101
- const isNarrow = windowWidth < 360;
102
- const isCompact = windowWidth < 400;
103
- const isTablet = windowWidth >= 600;
104
-
105
- const [showUpdateModal, setShowUpdateModal] = React.useState<boolean>(false);
106
- const [appVersionString, setAppVersionString] = React.useState<string>(() => {
107
- return getAppVersionAndBuild().formatted;
108
- });
109
-
110
- const [isRecording, setIsRecording] = React.useState<boolean>(false);
111
- const [recordingSeconds, setRecordingSeconds] = React.useState<number>(0);
112
- const recordingTimerRef = React.useRef<any>(null);
113
-
114
- React.useEffect(() => {
115
- ScreenCapture.isRecording()
116
- .then(active => {
117
- setIsRecording(active);
118
- })
119
- .catch(() => {});
120
- }, []);
121
-
122
- React.useEffect(() => {
123
- if (isRecording) {
124
- setRecordingSeconds(0);
125
- recordingTimerRef.current = setInterval(() => {
126
- setRecordingSeconds(s => s + 1);
127
- }, 1000);
128
- } else {
129
- if (recordingTimerRef.current) {
130
- clearInterval(recordingTimerRef.current);
131
- recordingTimerRef.current = null;
132
- }
133
- setRecordingSeconds(0);
134
- }
135
- return () => {
136
- if (recordingTimerRef.current) {
137
- clearInterval(recordingTimerRef.current);
138
- }
139
- };
140
- }, [isRecording]);
141
-
142
- const [previewMediaItem, setPreviewMediaItem] =
143
- React.useState<CapturedMediaItem | null>(null);
144
-
145
- const handleTakeScreenshot = React.useCallback(async () => {
146
- try {
147
- triggerNativeHaptic('light');
148
- const result = await ScreenCapture.takeScreenshot({
149
- format: 'png',
150
- quality: 0.9,
151
- hideInspector: true,
152
- });
153
- if (result) {
154
- triggerNativeHaptic('success');
155
- const newItem: CapturedMediaItem = {
156
- id: `screenshot_${result.timestamp}.png`,
157
- type: 'image',
158
- format: result.format,
159
- uri: result.uri,
160
- filename:
161
- result.uri.split('/').pop() || `screenshot_${result.timestamp}.png`,
162
- sizeBytes: result.sizeBytes,
163
- timestamp: result.timestamp,
164
- width: result.width,
165
- height: result.height,
166
- };
167
- setPreviewMediaItem(newItem);
168
- refreshMediaCount?.().catch(() => {});
169
- showToast(t('header.screenshotCaptured'));
170
- } else {
171
- showToast(t('header.screenshotFailed'));
172
- }
173
- } catch {
174
- showToast(t('header.screenshotError'));
175
- }
176
- }, [refreshMediaCount, t]);
177
-
178
- const handleToggleVideoRecording = React.useCallback(async () => {
179
- try {
180
- if (isRecording) {
181
- triggerNativeHaptic('medium');
182
- const result = await ScreenCapture.stopRecording();
183
- setIsRecording(false);
184
- if (result) {
185
- triggerNativeHaptic('success');
186
- const newItem: CapturedMediaItem = {
187
- id: `video_${result.timestamp}.${result.format}`,
188
- type: result.format === 'gif' ? 'gif' : 'video',
189
- format: result.format,
190
- uri: result.uri,
191
- filename:
192
- result.uri.split('/').pop() ||
193
- `video_${result.timestamp}.${result.format}`,
194
- sizeBytes: result.sizeBytes,
195
- timestamp: result.timestamp,
196
- durationMs: result.durationMs,
197
- width: result.width,
198
- height: result.height,
199
- hasAudio: result.hasAudio,
200
- };
201
- setPreviewMediaItem(newItem);
202
- refreshMediaCount?.().catch(() => {});
203
- showToast(
204
- t('header.recordingSaved', {
205
- duration: (result.durationMs / 1000).toFixed(1),
206
- }),
207
- );
208
- }
209
- } else {
210
- triggerNativeHaptic('medium');
211
- const started = await ScreenCapture.startRecording({
212
- fps: 24,
213
- audioSource: 'none',
214
- });
215
- if (started) {
216
- setIsRecording(true);
217
- showToast(t('header.recordingStarted'));
218
- } else {
219
- showToast(t('header.recordingStartFailed'));
220
- }
221
- }
222
- } catch {
223
- showToast(t('header.recordingError'));
224
- setIsRecording(false);
225
- }
226
- }, [isRecording, t]);
227
-
228
- const formatTimer = (totalSeconds: number) => {
229
- const mins = Math.floor(totalSeconds / 60);
230
- const secs = totalSeconds % 60;
231
- return `${mins.toString().padStart(2, '0')}:${secs
232
- .toString()
233
- .padStart(2, '0')}`;
234
- };
235
-
236
- const envConfig = useMemo(() => {
237
- const rawEnv = (environment || (__DEV__ ? 'DEV' : 'PROD')).trim();
238
- const clean = rawEnv.toUpperCase();
239
-
240
- if (clean === 'DEV' || clean.includes('DEV') || clean === 'LOCAL') {
241
- return {
242
- label: rawEnv,
243
- bg: `${AppColors.emerald500}40`,
244
- border: `${AppColors.emerald400}8C`,
245
- text: AppColors.mintGreenBorder,
246
- };
247
- }
248
- if (clean === 'UAT' || clean === 'QA' || clean === 'TEST') {
249
- return {
250
- label: rawEnv,
251
- bg: `${AppColors.amber500}47`,
252
- border: `${AppColors.amber400}99`,
253
- text: AppColors.amberWarmBorder,
254
- };
255
- }
256
- if (clean === 'PREPROD' || clean === 'STAGE' || clean === 'STAGING') {
257
- return {
258
- label: rawEnv,
259
- bg: `${AppColors.purple500}47`,
260
- border: `${AppColors.purple400}99`,
261
- text: AppColors.violetSoftBorder,
262
- };
263
- }
264
- return {
265
- label: rawEnv,
266
- bg: `${AppColors.rose500}40`,
267
- border: `${AppColors.roseBorder}8C`,
268
- text: AppColors.errorBorder,
269
- };
270
- }, [environment]);
271
-
272
- const isDetailView =
273
- (activeTab === 'apis' && selected != null) ||
274
- (activeTab === 'analytics' && selectedEvent != null) ||
275
- (activeTab === 'logs' && selectedLog != null) ||
276
- (activeTab === 'redux' &&
277
- (selectedReduxSlice != null || selectedReduxAction != null)) ||
278
- (activeTab === 'crash' && selectedCrash != null);
279
-
280
- const isSettingsView = settingsPage !== null;
281
- const isAnySelected = isDetailView || isSettingsView || isFeedbackOpen;
282
-
283
- const settingsModuleTitle = useMemo(() => {
284
- switch (settingsPage) {
285
- case 'apis':
286
- return 'APIs (Network)';
287
- case 'logs':
288
- return 'Console Logs';
289
- case 'performance':
290
- return 'Performance Tracker';
291
- case 'bundle':
292
- return 'Bundle Analyzer';
293
- case 'crash':
294
- return 'Crash Protection';
295
- case 'analytics':
296
- return 'Analytics Logger';
297
- case 'redux':
298
- return 'Redux Inspector';
299
- default:
300
- return 'Settings & Modules';
301
- }
302
- }, [settingsPage]);
303
-
304
- const headerTopPadding =
305
- Platform.OS === 'ios' && modalHeightPercent >= 95 ? 44 : 0;
306
-
307
- const buttonSize = isNarrow ? 28 : isCompact ? 30 : 32;
308
- const logoSize = isNarrow ? 36 : isCompact ? 40 : 44;
309
-
310
- return (
311
- <>
312
- <View
313
- style={[
314
- styles.headerGradient,
315
- {
316
- minHeight: (isNarrow ? 48 : 52) + headerTopPadding,
317
- },
318
- ]}>
319
- {/* LinearGradient as absolute background layer to avoid Fabric view recycling crash.
320
- BVLinearGradient as a direct parent of conditionally-mounted children triggers
321
- RCTComponentViewRegistry 'Attempt to recycle a mounted view' assertion. */}
322
- <LinearGradient
323
- colors={[AppColors.indigo600, AppColors.violet600]}
324
- start={{x: 0, y: 0}}
325
- end={{x: 1, y: 1}}
326
- style={{
327
- position: 'absolute',
328
- top: 0,
329
- left: 0,
330
- right: 0,
331
- bottom: 0,
332
- borderTopLeftRadius: 20,
333
- borderTopRightRadius: 20,
334
- }}
335
- pointerEvents="none"
336
- />
337
- <View style={{paddingTop: headerTopPadding, width: '100%'}}>
338
- <View
339
- style={[
340
- styles.header,
341
- {
342
- width: '100%',
343
- justifyContent: 'space-between',
344
- paddingHorizontal: isNarrow ? 10 : 14,
345
- paddingVertical: isNarrow ? 6 : 8,
346
- minHeight: isNarrow ? 48 : 52,
347
- },
348
- ]}>
349
- <View
350
- style={{
351
- flexDirection: 'row',
352
- alignItems: 'center',
353
- gap: isNarrow ? 6 : 8,
354
- flex: isDetailView ? undefined : 1,
355
- flexShrink: isDetailView ? 0 : 1,
356
- minWidth: 0,
357
- }}>
358
- {isAnySelected && (
359
- <TouchableScale
360
- onPress={() => {
361
- if (isFeedbackOpen) {
362
- setIsFeedbackOpen(false);
363
- return;
364
- }
365
- if (isSettingsView) {
366
- if (settingsPage === 'main') {
367
- setSettingsPage(null);
368
- } else {
369
- setSettingsPage('main');
370
- }
371
- return;
372
- }
373
- setSelected(null);
374
- setSelectedEvent(null);
375
- setSelectedLog(null);
376
- setSelectedReduxSlice(null);
377
- setSelectedReduxAction(null);
378
- setSelectedCrash(null);
379
- }}
380
- hitSlop={15}
381
- style={{
382
- width: isNarrow ? 32 : 36,
383
- height: isNarrow ? 32 : 36,
384
- borderRadius: isNarrow ? 16 : 18,
385
- alignItems: 'center',
386
- justifyContent: 'center',
387
- backgroundColor: `${AppColors.white}2E`,
388
- borderWidth: 1,
389
- borderColor: `${AppColors.white}4D`,
390
- }}>
391
- <View
392
- style={{
393
- position: 'absolute',
394
- width: isNarrow ? 40 : 44,
395
- height: isNarrow ? 40 : 44,
396
- borderRadius: 22,
397
- backgroundColor: `${AppColors.white}1A`,
398
- }}
399
- />
400
- <WhiteBackNavigation />
401
- </TouchableScale>
402
- )}
403
-
404
- {isFeedbackOpen ? (
405
- <View style={{gap: 2, flex: 1, minWidth: 0}}>
406
- <View
407
- style={{
408
- flexDirection: 'row',
409
- alignItems: 'center',
410
- gap: 6,
411
- }}>
412
- <Text
413
- style={{
414
- fontFamily: AppFonts.interBold,
415
- fontSize: isNarrow ? 14 : 16,
416
- color: AppColors.white,
417
- letterSpacing: -0.2,
418
- }}
419
- numberOfLines={1}>
420
- Support & Feedback
421
- </Text>
422
- <View
423
- style={{
424
- backgroundColor: `${AppColors.white}26`,
425
- paddingHorizontal: isNarrow ? 4 : 6,
426
- paddingVertical: 1.5,
427
- borderRadius: 10,
428
- borderWidth: 1,
429
- borderColor: `${AppColors.white}20`,
430
- }}>
431
- <Text
432
- style={{
433
- fontFamily: AppFonts.interBold,
434
- fontSize: isNarrow ? 8 : 9,
435
- color: AppColors.white,
436
- }}>
437
- v{LIB_VERSION}
438
- </Text>
439
- </View>
440
- </View>
441
- <Text
442
- style={{
443
- fontFamily: AppFonts.interRegular,
444
- fontSize: isNarrow ? 9.5 : 10.5,
445
- color: `${AppColors.white}CC`,
446
- }}
447
- numberOfLines={1}>
448
- Direct line to maintainers & developers
449
- </Text>
450
- </View>
451
- ) : isSettingsView ? (
452
- <View style={{gap: 2, flex: 1, minWidth: 0}}>
453
- <View
454
- style={{
455
- flexDirection: 'row',
456
- alignItems: 'center',
457
- gap: 6,
458
- }}>
459
- <Text
460
- style={{
461
- fontFamily: AppFonts.interBold,
462
- fontSize: isNarrow ? 14 : 16,
463
- color: AppColors.white,
464
- letterSpacing: -0.2,
465
- }}
466
- numberOfLines={1}>
467
- {settingsModuleTitle}
468
- </Text>
469
- {settingsPage === 'main' && (
470
- <View
471
- style={{
472
- backgroundColor: `${AppColors.white}26`,
473
- paddingHorizontal: isNarrow ? 4 : 6,
474
- paddingVertical: 1.5,
475
- borderRadius: 10,
476
- borderWidth: 1,
477
- borderColor: `${AppColors.white}20`,
478
- }}>
479
- <Text
480
- style={{
481
- fontFamily: AppFonts.interBold,
482
- fontSize: isNarrow ? 8 : 9,
483
- color: AppColors.white,
484
- }}>
485
- v{LIB_VERSION}
486
- </Text>
487
- </View>
488
- )}
489
- </View>
490
- <Text
491
- style={{
492
- fontFamily: AppFonts.interRegular,
493
- fontSize: isNarrow ? 9.5 : 10.5,
494
- color: `${AppColors.white}CC`,
495
- }}
496
- numberOfLines={1}>
497
- {settingsPage === 'main'
498
- ? 'Manage modules and preferences'
499
- : 'Configure module parameters'}
500
- </Text>
501
- </View>
502
- ) : !isAnySelected ? (
503
- <View
504
- style={{
505
- flexDirection: 'row',
506
- alignItems: 'center',
507
- gap: isNarrow ? 6 : 8,
508
- flex: 1,
509
- minWidth: 0,
510
- marginRight: 4,
511
- }}>
512
- <AppHeaderLogo size={logoSize} customIcon={appIcon} />
513
- <View style={{gap: 2, flex: 1, minWidth: 0}}>
514
- <View
515
- style={{
516
- flexDirection: 'row',
517
- alignItems: 'center',
518
- gap: isNarrow ? 4 : 6,
519
- minWidth: 0,
520
- }}>
521
- <Text
522
- style={[
523
- styles.headerTitle,
524
- {
525
- fontSize: isNarrow ? 13.5 : isCompact ? 14.5 : 15.5,
526
- flexShrink: 1,
527
- paddingBottom: 0,
528
- },
529
- ]}
530
- numberOfLines={1}
531
- ellipsizeMode="tail">
532
- {getAppName()}
533
- </Text>
534
- <View
535
- style={[
536
- styles.envBadge,
537
- {
538
- backgroundColor: envConfig.bg,
539
- borderColor: envConfig.border,
540
- flexShrink: 0,
541
- paddingHorizontal: isNarrow ? 4.5 : 6,
542
- paddingVertical: 1.5,
543
- marginBottom: 0,
544
- },
545
- ]}>
546
- <Text
547
- style={[
548
- styles.envBadgeText,
549
- {
550
- color: envConfig.text,
551
- fontSize: isNarrow ? 8.5 : 9.5,
552
- },
553
- ]}>
554
- {envConfig.label}
555
- </Text>
556
- </View>
557
- {updateAvailable && (
558
- <Pressable
559
- hitSlop={10}
560
- onPress={() => setShowUpdateModal(true)}
561
- style={{
562
- flexDirection: 'row',
563
- alignItems: 'center',
564
- backgroundColor: AppColors.warningAmber,
565
- borderRadius: 5,
566
- paddingHorizontal: isNarrow ? 4 : 5.5,
567
- paddingVertical: 1.5,
568
- gap: 3,
569
- shadowColor: AppColors.warningAmber,
570
- shadowOffset: {width: 0, height: 1.5},
571
- shadowOpacity: 0.35,
572
- shadowRadius: 3,
573
- elevation: 3,
574
- flexShrink: 0,
575
- }}>
576
- <Animated.View
577
- style={{
578
- width: 5,
579
- height: 5,
580
- borderRadius: 2.5,
581
- backgroundColor: AppColors.white,
582
- opacity: activePulseAnim,
583
- transform: [{scale: unreadPulseAnim}],
584
- }}
585
- />
586
- {!isNarrow && (
587
- <Text
588
- style={{
589
- fontFamily: AppFonts.interBold,
590
- fontSize: 8.5,
591
- color: AppColors.white,
592
- letterSpacing: 0.3,
593
- }}>
594
- UPDATE
595
- </Text>
596
- )}
597
- <BoltIcon
598
- size={isNarrow ? 8 : 9}
599
- color={AppColors.white}
600
- />
601
- </Pressable>
602
- )}
603
- </View>
604
-
605
- {/* OS & NPM Version Representation */}
606
- <View
607
- style={{
608
- flexDirection: 'row',
609
- alignItems: 'center',
610
- gap: isNarrow ? 4 : 5,
611
- minWidth: 0,
612
- }}>
613
- <View
614
- style={{
615
- flexDirection: 'row',
616
- alignItems: 'center',
617
- backgroundColor: `${AppColors.white}1F`,
618
- borderRadius: 5,
619
- paddingHorizontal: isNarrow ? 4.5 : 6,
620
- paddingVertical: 2,
621
- gap: 3.5,
622
- borderWidth: 1,
623
- borderColor: `${AppColors.white}2E`,
624
- flexShrink: 1,
625
- minWidth: 0,
626
- }}>
627
- {Platform.OS === 'ios' ? (
628
- <AppleIcon
629
- color={`${AppColors.white}E6`}
630
- size={isNarrow ? 9 : 10}
631
- />
632
- ) : (
633
- <AndroidIcon
634
- color={`${AppColors.white}E6`}
635
- size={isNarrow ? 9 : 10}
636
- />
637
- )}
638
- <Text
639
- style={{
640
- fontFamily: AppFonts.interMedium,
641
- fontSize: isNarrow ? 8.5 : 9.5,
642
- color: `${AppColors.white}EB`,
643
- letterSpacing: 0.1,
644
- }}
645
- numberOfLines={1}
646
- ellipsizeMode="tail">
647
- {appVersionString}
648
- </Text>
649
- </View>
650
-
651
- <Pressable
652
- onPress={() => {
653
- if (updateAvailable) {
654
- setShowUpdateModal(true);
655
- } else {
656
- Linking.openURL(
657
- 'https://www.npmjs.com/package/react-native-inapp-inspector',
658
- ).catch(() => {});
659
- }
660
- }}
661
- style={{
662
- flexDirection: 'row',
663
- alignItems: 'center',
664
- backgroundColor: `${AppColors.white}1F`,
665
- borderRadius: 5,
666
- paddingHorizontal: isNarrow ? 4.5 : 6,
667
- paddingVertical: 2,
668
- gap: 3.5,
669
- borderWidth: 1,
670
- borderColor: `${AppColors.white}2E`,
671
- flexShrink: 0,
672
- }}>
673
- <NpmIcon
674
- size={isNarrow ? 9 : 10}
675
- color={AppColors.npmRedLight}
676
- />
677
- <Text
678
- style={{
679
- fontFamily: AppFonts.interMedium,
680
- fontSize: isNarrow ? 8.5 : 9.5,
681
- color: `${AppColors.white}EB`,
682
- letterSpacing: 0.1,
683
- }}
684
- numberOfLines={1}>
685
- v{LIB_VERSION}
686
- </Text>
687
- {updateAvailable && (
688
- <Text
689
- style={{
690
- fontFamily: AppFonts.interBold,
691
- fontSize: 8.5,
692
- color: AppColors.warningAmber,
693
- }}>
694
- ●
695
- </Text>
696
- )}
697
- </Pressable>
698
- </View>
699
- </View>
700
- </View>
701
- ) : null}
702
- </View>
703
-
704
- {isDetailView && (
705
- <View
706
- style={[
707
- styles.headerCenter,
708
- {paddingHorizontal: isNarrow ? 2 : 6},
709
- ]}>
710
- {activeTab === 'apis' && selected != null ? (
711
- <View style={styles.headerDetailCenter}>
712
- <View style={styles.headerDetailRow}>
713
- <View
714
- style={[
715
- styles.headerMethodBadge,
716
- {
717
- backgroundColor:
718
- METHOD_COLORS[selected.method as Method] ??
719
- AppColors.grayText,
720
- paddingHorizontal: isNarrow ? 5 : 6,
721
- paddingVertical: isNarrow ? 2 : 3,
722
- },
723
- ]}>
724
- <Text
725
- style={[
726
- styles.headerMethodText,
727
- {fontSize: isNarrow ? 9 : 10},
728
- ]}>
729
- {selected.method}
730
- </Text>
731
- </View>
732
- <Text
733
- style={[
734
- styles.headerDetailTitle,
735
- {fontSize: isNarrow ? 13.5 : 15},
736
- ]}
737
- numberOfLines={1}
738
- ellipsizeMode="middle">
739
- {detailTitle}
740
- </Text>
741
- </View>
742
- <View
743
- style={{
744
- flexDirection: 'row',
745
- alignItems: 'center',
746
- gap: isNarrow ? 4 : 6,
747
- marginTop: 3,
748
- paddingVertical: 1,
749
- }}>
750
- <View
751
- style={{
752
- flexDirection: 'row',
753
- alignItems: 'center',
754
- gap: 4,
755
- paddingHorizontal: isNarrow ? 6 : 8,
756
- paddingVertical: 2.5,
757
- borderRadius: 20,
758
- backgroundColor: `${getStatusColor(
759
- selected.status,
760
- )}26`,
761
- borderWidth: 1,
762
- borderColor: `${getStatusColor(selected.status)}55`,
763
- }}>
764
- <View
765
- style={[
766
- styles.headerStatusDot,
767
- {
768
- backgroundColor: getStatusColor(selected.status),
769
- width: isNarrow ? 6 : 7,
770
- height: isNarrow ? 6 : 7,
771
- },
772
- ]}
773
- />
774
- <Text
775
- style={[
776
- styles.headerSubTitle,
777
- {
778
- fontFamily: AppFonts.interBold,
779
- fontSize: isNarrow ? 10 : 11,
780
- },
781
- ]}>
782
- {selected.status === 0
783
- ? 'Failed'
784
- : selected.status ?? 'Pending'}
785
- </Text>
786
- </View>
787
- <View
788
- style={{
789
- flexDirection: 'row',
790
- alignItems: 'center',
791
- gap: 4,
792
- paddingHorizontal: isNarrow ? 6 : 8,
793
- paddingVertical: 2.5,
794
- borderRadius: 20,
795
- backgroundColor: `${AppColors.white}29`,
796
- }}>
797
- <ClockIcon
798
- color={AppColors.white}
799
- size={isNarrow ? 10 : 11}
800
- />
801
- <Text
802
- style={[
803
- styles.headerSubTitle,
804
- {fontSize: isNarrow ? 10 : 11},
805
- ]}>
806
- {selected.duration != null
807
- ? `${selected.duration}ms`
808
- : '—'}
809
- </Text>
810
- </View>
811
- {selected.response != null && (
812
- <View
813
- style={{
814
- flexDirection: 'row',
815
- alignItems: 'center',
816
- gap: 4,
817
- paddingHorizontal: isNarrow ? 6 : 8,
818
- paddingVertical: 2.5,
819
- borderRadius: 20,
820
- backgroundColor: `${AppColors.white}29`,
821
- }}>
822
- <SizeIcon
823
- color={AppColors.white}
824
- size={isNarrow ? 10 : 11}
825
- />
826
- <Text
827
- style={[
828
- styles.headerSubTitle,
829
- {fontSize: isNarrow ? 10 : 11},
830
- ]}>
831
- {getSize(selected.response)}
832
- </Text>
833
- </View>
834
- )}
835
- </View>
836
- </View>
837
- ) : activeTab === 'analytics' && selectedEvent != null ? (
838
- <View style={styles.headerDetailCenter}>
839
- <View style={styles.headerDetailRow}>
840
- <View
841
- style={[
842
- styles.headerMethodBadge,
843
- {
844
- backgroundColor:
845
- selectedEvent.source === 'firebase'
846
- ? `${AppColors.firebaseOrange}4D`
847
- : `${AppColors.purple}4D`,
848
- paddingHorizontal: isNarrow ? 5 : 6,
849
- paddingVertical: isNarrow ? 2 : 3,
850
- },
851
- ]}>
852
- <Text
853
- style={[
854
- styles.headerMethodText,
855
- {fontSize: isNarrow ? 9 : 10},
856
- ]}>
857
- {selectedEvent.source === 'firebase' ? 'FB' : 'MAN'}
858
- </Text>
859
- </View>
860
- <Text
861
- style={[
862
- styles.headerDetailTitle,
863
- {fontSize: isNarrow ? 13.5 : 15},
864
- ]}
865
- numberOfLines={1}
866
- ellipsizeMode="middle">
867
- {selectedEvent.name}
868
- </Text>
869
- </View>
870
- <View
871
- style={{
872
- flexDirection: 'row',
873
- alignItems: 'center',
874
- gap: isNarrow ? 4 : 6,
875
- marginTop: 3,
876
- paddingVertical: 1,
877
- }}>
878
- <View
879
- style={[
880
- styles.headerStatusDot,
881
- {
882
- backgroundColor:
883
- selectedEvent.source === 'firebase'
884
- ? AppColors.firebaseOrange
885
- : AppColors.purple,
886
- width: isNarrow ? 6 : 7,
887
- height: isNarrow ? 6 : 7,
888
- },
889
- ]}
890
- />
891
- <Text
892
- style={[
893
- styles.headerSubTitle,
894
- {fontSize: isNarrow ? 10 : 11},
895
- ]}>
896
- {Object.keys(selectedEvent.params).length} param
897
- {Object.keys(selectedEvent.params).length !== 1
898
- ? 's'
899
- : ''}
900
- {' · '}
901
- {selectedEvent.source}
902
- </Text>
903
- </View>
904
- </View>
905
- ) : activeTab === 'logs' && selectedLog != null ? (
906
- <View style={styles.headerDetailCenter}>
907
- <View style={styles.headerDetailRow}>
908
- <View
909
- style={[
910
- styles.headerMethodBadge,
911
- {
912
- backgroundColor:
913
- selectedLog.type === 'error'
914
- ? `${AppColors.errorColor}4D`
915
- : selectedLog.type === 'warn'
916
- ? `${AppColors.lightOrange}4D`
917
- : `${AppColors.purple}4D`,
918
- paddingHorizontal: isNarrow ? 5 : 6,
919
- paddingVertical: isNarrow ? 2 : 3,
920
- },
921
- ]}>
922
- <Text
923
- style={[
924
- styles.headerMethodText,
925
- {fontSize: isNarrow ? 9 : 10},
926
- ]}>
927
- {selectedLog.type.toUpperCase()}
928
- </Text>
929
- </View>
930
- <Text
931
- style={[
932
- styles.headerDetailTitle,
933
- {fontSize: isNarrow ? 13.5 : 15},
934
- ]}
935
- numberOfLines={1}
936
- ellipsizeMode="middle">
937
- console.
938
- {selectedLog.sourceMethod || selectedLog.type || 'log'}
939
- </Text>
940
- </View>
941
- <View
942
- style={{
943
- flexDirection: 'row',
944
- alignItems: 'center',
945
- gap: isNarrow ? 4 : 6,
946
- marginTop: 3,
947
- paddingVertical: 1,
948
- }}>
949
- <View
950
- style={{
951
- flexDirection: 'row',
952
- alignItems: 'center',
953
- gap: 4,
954
- paddingHorizontal: isNarrow ? 6 : 8,
955
- paddingVertical: 2.5,
956
- borderRadius: 20,
957
- backgroundColor: `${AppColors.white}29`,
958
- }}>
959
- <ClockIcon
960
- color={AppColors.white}
961
- size={isNarrow ? 10 : 11}
962
- />
963
- <Text
964
- style={[
965
- styles.headerSubTitle,
966
- {fontSize: isNarrow ? 10 : 11},
967
- ]}>
968
- {formatTime(selectedLog.timestamp)}
969
- </Text>
970
- </View>
971
- </View>
972
- </View>
973
- ) : activeTab === 'redux' && selectedReduxSlice != null ? (
974
- (() => {
975
- const sliceData = reduxState?.[selectedReduxSlice];
976
- const keyCount =
977
- sliceData && typeof sliceData === 'object'
978
- ? Object.keys(sliceData).length
979
- : typeof sliceData !== 'undefined'
980
- ? 1
981
- : 0;
982
- const sliceSize = getSize(sliceData);
983
- const lastAction = reduxLastActionMap[selectedReduxSlice];
984
-
985
- return (
986
- <View style={styles.headerDetailCenter}>
987
- <View style={styles.headerDetailRow}>
988
- <View
989
- style={[
990
- styles.headerMethodBadge,
991
- {
992
- backgroundColor: `${AppColors.purple}4D`,
993
- paddingHorizontal: isNarrow ? 5 : 6,
994
- paddingVertical: isNarrow ? 2 : 3,
995
- },
996
- ]}>
997
- <Text
998
- style={[
999
- styles.headerMethodText,
1000
- {fontSize: isNarrow ? 9 : 10},
1001
- ]}>
1002
- SLICE
1003
- </Text>
1004
- </View>
1005
- <Text
1006
- style={[
1007
- styles.headerDetailTitle,
1008
- {fontSize: isNarrow ? 13.5 : 15},
1009
- ]}
1010
- numberOfLines={1}
1011
- ellipsizeMode="middle">
1012
- {selectedReduxSlice}
1013
- </Text>
1014
- </View>
1015
- <View
1016
- style={{
1017
- flexDirection: 'row',
1018
- alignItems: 'center',
1019
- gap: isNarrow ? 4 : 6,
1020
- marginTop: 3,
1021
- paddingVertical: 1,
1022
- }}>
1023
- <View
1024
- style={[
1025
- styles.headerStatusDot,
1026
- {
1027
- backgroundColor: AppColors.liveGreen,
1028
- width: isNarrow ? 6 : 7,
1029
- height: isNarrow ? 6 : 7,
1030
- },
1031
- ]}
1032
- />
1033
- <Text
1034
- style={[
1035
- styles.headerSubTitle,
1036
- {fontSize: isNarrow ? 10 : 11},
1037
- ]}>
1038
- Live
1039
- </Text>
1040
- <Text
1041
- style={[
1042
- styles.headerSubTitle,
1043
- {opacity: 0.6, fontSize: isNarrow ? 10 : 11},
1044
- ]}>
1045
- •
1046
- </Text>
1047
- <Text
1048
- style={[
1049
- styles.headerSubTitle,
1050
- {fontSize: isNarrow ? 10 : 11},
1051
- ]}>
1052
- {keyCount} keys
1053
- </Text>
1054
- <Text
1055
- style={[
1056
- styles.headerSubTitle,
1057
- {opacity: 0.6, fontSize: isNarrow ? 10 : 11},
1058
- ]}>
1059
- •
1060
- </Text>
1061
- <Text
1062
- style={[
1063
- styles.headerSubTitle,
1064
- {fontSize: isNarrow ? 10 : 11},
1065
- ]}>
1066
- {sliceSize}
1067
- </Text>
1068
- {lastAction?.timestamp && (
1069
- <>
1070
- <Text
1071
- style={[
1072
- styles.headerSubTitle,
1073
- {opacity: 0.6, fontSize: isNarrow ? 10 : 11},
1074
- ]}>
1075
- •
1076
- </Text>
1077
- <View
1078
- style={{
1079
- flexDirection: 'row',
1080
- alignItems: 'center',
1081
- gap: 3,
1082
- }}>
1083
- <ClockIcon
1084
- color={AppColors.white}
1085
- size={isNarrow ? 9 : 10}
1086
- />
1087
- <Text
1088
- style={[
1089
- styles.headerSubTitle,
1090
- {fontSize: isNarrow ? 10 : 11},
1091
- ]}>
1092
- {lastAction.timestamp}
1093
- </Text>
1094
- </View>
1095
- </>
1096
- )}
1097
- </View>
1098
- </View>
1099
- );
1100
- })()
1101
- ) : activeTab === 'redux' && selectedReduxAction != null ? (
1102
- <View style={styles.headerDetailCenter}>
1103
- <View style={styles.headerDetailRow}>
1104
- <View
1105
- style={[
1106
- styles.headerMethodBadge,
1107
- {
1108
- backgroundColor: `${AppColors.brandPurple}4D`,
1109
- paddingHorizontal: isNarrow ? 5 : 6,
1110
- paddingVertical: isNarrow ? 2 : 3,
1111
- },
1112
- ]}>
1113
- <Text
1114
- style={[
1115
- styles.headerMethodText,
1116
- {fontSize: isNarrow ? 9 : 10},
1117
- ]}>
1118
- ACTION
1119
- </Text>
1120
- </View>
1121
- <Text
1122
- style={[
1123
- styles.headerDetailTitle,
1124
- {fontSize: isNarrow ? 13.5 : 15},
1125
- ]}
1126
- numberOfLines={1}
1127
- ellipsizeMode="middle">
1128
- {selectedReduxAction.type}
1129
- </Text>
1130
- </View>
1131
- <View
1132
- style={{
1133
- flexDirection: 'row',
1134
- alignItems: 'center',
1135
- gap: isNarrow ? 4 : 6,
1136
- marginTop: 3,
1137
- paddingVertical: 1,
1138
- }}>
1139
- <View
1140
- style={[
1141
- styles.headerStatusDot,
1142
- {
1143
- backgroundColor: AppColors.purple,
1144
- width: isNarrow ? 6 : 7,
1145
- height: isNarrow ? 6 : 7,
1146
- },
1147
- ]}
1148
- />
1149
- <Text
1150
- style={[
1151
- styles.headerSubTitle,
1152
- {fontSize: isNarrow ? 10 : 11},
1153
- ]}>
1154
- {selectedReduxAction.timestamp || 'Dispatched'}
1155
- </Text>
1156
- </View>
1157
- </View>
1158
- ) : activeTab === 'crash' && selectedCrash != null ? (
1159
- <View style={styles.headerDetailCenter}>
1160
- <View style={styles.headerDetailRow}>
1161
- <View
1162
- style={[
1163
- styles.headerMethodBadge,
1164
- {
1165
- backgroundColor: selectedCrash.isFatal
1166
- ? AppColors.red600
1167
- : AppColors.amber600,
1168
- paddingHorizontal: isNarrow ? 5 : 6,
1169
- paddingVertical: isNarrow ? 2 : 3,
1170
- },
1171
- ]}>
1172
- <Text
1173
- style={[
1174
- styles.headerMethodText,
1175
- {fontSize: isNarrow ? 9 : 10},
1176
- ]}>
1177
- {selectedCrash.isFatal
1178
- ? 'FATAL'
1179
- : selectedCrash.type.toUpperCase()}
1180
- </Text>
1181
- </View>
1182
- <Text
1183
- style={[
1184
- styles.headerDetailTitle,
1185
- {fontSize: isNarrow ? 13.5 : 15},
1186
- ]}
1187
- numberOfLines={1}
1188
- ellipsizeMode="middle">
1189
- {selectedCrash.name || selectedCrash.message}
1190
- </Text>
1191
- </View>
1192
- <View
1193
- style={{
1194
- flexDirection: 'row',
1195
- alignItems: 'center',
1196
- gap: isNarrow ? 4 : 6,
1197
- marginTop: 3,
1198
- paddingVertical: 1,
1199
- }}>
1200
- <View
1201
- style={[
1202
- styles.headerStatusDot,
1203
- {
1204
- backgroundColor: selectedCrash.isFatal
1205
- ? AppColors.red600
1206
- : AppColors.amber500,
1207
- width: isNarrow ? 6 : 7,
1208
- height: isNarrow ? 6 : 7,
1209
- },
1210
- ]}
1211
- />
1212
- <Text
1213
- style={[
1214
- styles.headerSubTitle,
1215
- {fontSize: isNarrow ? 10 : 11},
1216
- ]}>
1217
- {selectedCrash.timeStr ||
1218
- new Date(
1219
- selectedCrash.timestamp,
1220
- ).toLocaleTimeString()}
1221
- </Text>
1222
- {selectedCrash.deviceInfo?.platform && (
1223
- <>
1224
- <Text
1225
- style={[
1226
- styles.headerSubTitle,
1227
- {opacity: 0.6, fontSize: isNarrow ? 10 : 11},
1228
- ]}>
1229
- •
1230
- </Text>
1231
- <Text
1232
- style={[
1233
- styles.headerSubTitle,
1234
- {fontSize: isNarrow ? 10 : 11},
1235
- ]}>
1236
- {selectedCrash.deviceInfo.platform.toUpperCase()}
1237
- </Text>
1238
- </>
1239
- )}
1240
- </View>
1241
- </View>
1242
- ) : null}
1243
- </View>
1244
- )}
1245
-
1246
- <View
1247
- style={[
1248
- styles.headerRight,
1249
- {
1250
- flexDirection: 'row',
1251
- alignItems: 'center',
1252
- justifyContent: 'flex-end',
1253
- flexShrink: 0,
1254
- gap: isNarrow ? 5 : 7,
1255
- },
1256
- ]}>
1257
- {isSettingsView && (
1258
- <TouchableScale
1259
- onPress={() => {
1260
- Alert.alert(
1261
- 'Reset All Settings',
1262
- 'This restores all module visibility and UI preferences to defaults. Continue?',
1263
- [
1264
- {text: 'Cancel', style: 'cancel'},
1265
- {
1266
- text: 'Reset',
1267
- style: 'destructive',
1268
- onPress: resetToDefaults,
1269
- },
1270
- ],
1271
- );
1272
- }}
1273
- hitSlop={15}
1274
- style={[
1275
- styles.closeButtonSquare,
1276
- {
1277
- width: buttonSize,
1278
- height: buttonSize,
1279
- borderRadius: isNarrow ? 6 : 7,
1280
- },
1281
- ]}>
1282
- <ResetIcon
1283
- color={AppColors.white}
1284
- size={isNarrow ? 12 : 14}
1285
- />
1286
- </TouchableScale>
1287
- )}
1288
-
1289
- {!isAnySelected && (
1290
- <TouchableScale
1291
- accessible={true}
1292
- accessibilityRole="button"
1293
- accessibilityLabel="Settings"
1294
- onPress={() => setSettingsPage('main')}
1295
- hitSlop={15}
1296
- style={[
1297
- styles.closeButtonSquare,
1298
- {
1299
- width: buttonSize,
1300
- height: buttonSize,
1301
- borderRadius: isNarrow ? 6 : 7,
1302
- },
1303
- ]}>
1304
- <SettingsIcon
1305
- color={AppColors.white}
1306
- size={isNarrow ? 12 : 14}
1307
- />
1308
- </TouchableScale>
1309
- )}
1310
-
1311
- {/* Minimize button */}
1312
- <TouchableOpacity
1313
- onPress={minimizeInspector || closeModal}
1314
- hitSlop={{top: 12, bottom: 12, left: 12, right: 12}}
1315
- activeOpacity={0.6}
1316
- accessibilityRole="button"
1317
- accessibilityLabel={t('common.minimize', 'Minimize')}
1318
- style={[
1319
- styles.closeButtonSquare,
1320
- {
1321
- width: buttonSize,
1322
- height: buttonSize,
1323
- borderRadius: isNarrow ? 6 : 7,
1324
- },
1325
- ]}>
1326
- <ChevronDownIcon size={isNarrow ? 14 : 16} color={AppColors.white} />
1327
- </TouchableOpacity>
1328
-
1329
- {/* Close button */}
1330
- <TouchableOpacity
1331
- onPress={closeModal}
1332
- hitSlop={{top: 12, bottom: 12, left: 12, right: 12}}
1333
- activeOpacity={0.6}
1334
- accessibilityRole="button"
1335
- accessibilityLabel={t('common.close', 'Close')}
1336
- style={[
1337
- styles.closeButtonSquare,
1338
- {
1339
- width: buttonSize,
1340
- height: buttonSize,
1341
- borderRadius: isNarrow ? 6 : 7,
1342
- },
1343
- ]}>
1344
- <CloseWhite size={isNarrow ? 12 : 14} />
1345
- </TouchableOpacity>
1346
- </View>
1347
- </View>
1348
-
1349
- {/* Secondary Action Header (Sub-Toolbar) */}
1350
- {!isAnySelected && (
1351
- <View
1352
- style={{
1353
- flexDirection: 'row',
1354
- alignItems: 'center',
1355
- justifyContent: 'space-between',
1356
- paddingHorizontal: isNarrow ? 8 : 12,
1357
- paddingBottom: isNarrow ? 6 : 8,
1358
- paddingTop: 0,
1359
- gap: 6,
1360
- }}>
1361
- <View
1362
- style={{flexDirection: 'row', alignItems: 'center', gap: 6}}>
1363
- {/* Photo Capture Button */}
1364
- <TouchableScale
1365
- onPress={handleTakeScreenshot}
1366
- style={{
1367
- flexDirection: 'row',
1368
- alignItems: 'center',
1369
- gap: 4.5,
1370
- backgroundColor: `${AppColors.white}24`,
1371
- paddingHorizontal: isNarrow ? 8 : 10,
1372
- paddingVertical: isNarrow ? 4 : 5,
1373
- borderRadius: 6,
1374
- borderWidth: 1,
1375
- borderColor: `${AppColors.white}33`,
1376
- }}>
1377
- <CameraIcon
1378
- size={isNarrow ? 12 : 13}
1379
- color={AppColors.white}
1380
- />
1381
- <Text
1382
- style={{
1383
- fontFamily: AppFonts.interSemiBold,
1384
- fontSize: isNarrow ? 10 : 11,
1385
- color: AppColors.white,
1386
- }}>
1387
- {t('header.photo')}
1388
- </Text>
1389
- </TouchableScale>
1390
-
1391
- {/* Video / GIF Record Button */}
1392
- <TouchableScale
1393
- onPress={handleToggleVideoRecording}
1394
- style={{
1395
- flexDirection: 'row',
1396
- alignItems: 'center',
1397
- gap: 4.5,
1398
- backgroundColor: isRecording
1399
- ? `${AppColors.red500}33`
1400
- : `${AppColors.white}24`,
1401
- paddingHorizontal: isNarrow ? 8 : 10,
1402
- paddingVertical: isNarrow ? 4 : 5,
1403
- borderRadius: 6,
1404
- borderWidth: 1,
1405
- borderColor: isRecording
1406
- ? AppColors.red500
1407
- : `${AppColors.white}33`,
1408
- }}>
1409
- {isRecording ? (
1410
- <Animated.View
1411
- style={{
1412
- width: 6,
1413
- height: 6,
1414
- borderRadius: 3,
1415
- backgroundColor: AppColors.red500,
1416
- }}
1417
- />
1418
- ) : (
1419
- <VideoCameraIcon
1420
- size={isNarrow ? 12 : 13}
1421
- color={AppColors.white}
1422
- />
1423
- )}
1424
- <Text
1425
- style={{
1426
- fontFamily: AppFonts.interSemiBold,
1427
- fontSize: isNarrow ? 10 : 11,
1428
- color: isRecording ? AppColors.red300 : AppColors.white,
1429
- }}>
1430
- {isRecording
1431
- ? `${t('header.rec')} ${formatTimer(recordingSeconds)}`
1432
- : t('header.record')}
1433
- </Text>
1434
- </TouchableScale>
1435
- </View>
1436
-
1437
- <View
1438
- style={{flexDirection: 'row', alignItems: 'center', gap: 6}}>
1439
- {/* Clear / Trash Button with label */}
1440
- <TouchableScale
1441
- accessible={true}
1442
- accessibilityRole="button"
1443
- accessibilityLabel={t('common.clearAll')}
1444
- onPress={() => {
1445
- Alert.alert(
1446
- t('header.clearEverythingTitle'),
1447
- t('header.clearEverythingMessage'),
1448
- [
1449
- {text: t('common.cancel'), style: 'cancel'},
1450
- {
1451
- text: t('common.clearAll'),
1452
- onPress: runClearAllWithAnimation,
1453
- style: 'destructive',
1454
- },
1455
- ],
1456
- );
1457
- }}
1458
- hitSlop={10}
1459
- style={{
1460
- flexDirection: 'row',
1461
- alignItems: 'center',
1462
- gap: 4.5,
1463
- backgroundColor: `${AppColors.white}24`,
1464
- paddingHorizontal: isNarrow ? 8 : 10,
1465
- paddingVertical: isNarrow ? 4 : 5,
1466
- borderRadius: 6,
1467
- borderWidth: 1,
1468
- borderColor: `${AppColors.white}33`,
1469
- }}>
1470
- <Animated.View
1471
- style={{
1472
- transform: [
1473
- {
1474
- rotate: clearAnim.interpolate({
1475
- inputRange: [0, 1],
1476
- outputRange: ['0deg', '-25deg'],
1477
- }),
1478
- },
1479
- {
1480
- scale: clearAnim.interpolate({
1481
- inputRange: [0, 0.5, 1],
1482
- outputRange: [1, 1.25, 1],
1483
- }),
1484
- },
1485
- ],
1486
- }}>
1487
- <TrashIcon
1488
- color={AppColors.white}
1489
- size={isNarrow ? 12 : 13}
1490
- />
1491
- </Animated.View>
1492
- <Text
1493
- style={{
1494
- fontFamily: AppFonts.interSemiBold,
1495
- fontSize: isNarrow ? 10 : 11,
1496
- color: AppColors.white,
1497
- }}>
1498
- {t('common.clearAll')}
1499
- </Text>
1500
- </TouchableScale>
1501
-
1502
- {/* About Button with label */}
1503
- <TouchableScale
1504
- accessible={true}
1505
- accessibilityRole="button"
1506
- accessibilityLabel={t('header.about')}
1507
- onPress={() => {
1508
- setSettingsActiveSubTab('about');
1509
- setSettingsPage('main');
1510
- }}
1511
- hitSlop={10}
1512
- style={{
1513
- flexDirection: 'row',
1514
- alignItems: 'center',
1515
- gap: 4.5,
1516
- backgroundColor: `${AppColors.white}24`,
1517
- paddingHorizontal: isNarrow ? 8 : 10,
1518
- paddingVertical: isNarrow ? 4 : 5,
1519
- borderRadius: 6,
1520
- borderWidth: 1,
1521
- borderColor: `${AppColors.white}33`,
1522
- }}>
1523
- <InfoCircleIcon
1524
- color={AppColors.white}
1525
- size={isNarrow ? 12 : 13}
1526
- />
1527
- <Text
1528
- style={{
1529
- fontFamily: AppFonts.interSemiBold,
1530
- fontSize: isNarrow ? 10 : 11,
1531
- color: AppColors.white,
1532
- }}>
1533
- {t('header.about')}
1534
- </Text>
1535
- </TouchableScale>
1536
- </View>
1537
- </View>
1538
- )}
1539
- </View>
1540
- </View>
1541
-
1542
- {/* Dedicated Update Available Details Modal */}
1543
- <UpdateAvailableModal
1544
- visible={showUpdateModal}
1545
- latestVersion={latestNpmVersion}
1546
- onClose={() => setShowUpdateModal(false)}
1547
- />
1548
-
1549
- {/* Instant Media Preview Modal for Screenshots and Video Recordings */}
1550
- <MediaPreviewModal
1551
- item={previewMediaItem}
1552
- visible={!!previewMediaItem}
1553
- onClose={() => setPreviewMediaItem(null)}
1554
- onDelete={async item => {
1555
- await ScreenCapture.deleteMedia(item.uri);
1556
- refreshMediaCount?.().catch(() => {});
1557
- setPreviewMediaItem(null);
1558
- }}
1559
- onConvertToGif={async item => {
1560
- const gif = await ScreenCapture.convertToGif(item.uri, {
1561
- fps: 12,
1562
- width: 480,
1563
- });
1564
- if (gif) {
1565
- refreshMediaCount?.().catch(() => {});
1566
- setPreviewMediaItem({
1567
- id: `anim_${gif.timestamp}.gif`,
1568
- type: 'gif',
1569
- format: 'gif',
1570
- uri: gif.uri,
1571
- filename: gif.uri.split('/').pop() || `anim_${gif.timestamp}.gif`,
1572
- sizeBytes: gif.sizeBytes,
1573
- timestamp: gif.timestamp,
1574
- durationMs: gif.durationMs,
1575
- });
1576
- }
1577
- }}
1578
- />
1579
- </>
1580
- );
1581
- });
1582
-
1583
- export default InspectorHeader;