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,1651 +0,0 @@
1
- import React, {useState, useMemo, useEffect, useCallback} from 'react';
2
- import {
3
- Alert,
4
- Platform,
5
- Pressable,
6
- ScrollView,
7
- StyleSheet,
8
- Text,
9
- TextInput,
10
- ToastAndroid,
11
- TouchableOpacity,
12
- View,
13
- } from 'react-native';
14
- import {useTranslation} from '../../i18n';
15
- import {useInspector} from './InspectorContext';
16
- import SegmentedTabs from '../SegmentedTabs';
17
- import JsonViewer from '../JsonViewer';
18
- import DiffViewer from '../DiffViewer';
19
- import CopyButton from '../CopyButton';
20
- import TouchableScale from '../TouchableScale';
21
- import HighlightText from '../HighlightText';
22
- import AnimatedEntrance from '../AnimatedEntrance';
23
- import {getActionHistory} from '../../customHooks/reduxLogger';
24
- import {getSize, openInVSCode, parseStackLine} from '../../helpers';
25
- import {getCustomStorage} from '../../helpers/settingsStore';
26
- import {AppColors} from '../../styles/AppColors';
27
- import {AppFonts} from '../../styles/AppFonts';
28
- import {
29
- TerminalIcon,
30
- SearchIcon,
31
- ClearIcon,
32
- ClockIcon,
33
- LayersIcon,
34
- TrashIcon,
35
- ForwardChevronIcon,
36
- LiveStateIcon,
37
- TimelineIcon,
38
- StorageIcon,
39
- MetadataIcon,
40
- BoltIcon,
41
- AtomIcon,
42
- ScreenIcon,
43
- ListenerIcon,
44
- DocIcon,
45
- LoadingSpinnerIcon,
46
- CircleAlertIcon,
47
- ExternalLinkIcon,
48
- SizeIcon,
49
- CodeBracketsIcon,
50
- } from '../NetworkIcons';
51
-
52
- type SliceDetailSubTab = 'live' | 'timeline' | 'persisted' | 'metadata';
53
- type ActionDetailSubTab = 'payload' | 'diff' | 'stack' | 'raw';
54
-
55
- const getOriginBadge = (originType?: string) => {
56
- switch (originType) {
57
- case 'saga':
58
- return {
59
- label: 'SAGA',
60
- renderIcon: (color: string, size = 9) => (
61
- <BoltIcon color={color} size={size} />
62
- ),
63
- bg: AppColors.purple100,
64
- text: AppColors.brandPurple,
65
- border: AppColors.purple200,
66
- };
67
- case 'thunk':
68
- return {
69
- label: 'THUNK',
70
- renderIcon: (color: string, size = 9) => (
71
- <AtomIcon color={color} size={size} />
72
- ),
73
- bg: AppColors.amber100,
74
- text: AppColors.amber800Warm,
75
- border: AppColors.amber200,
76
- };
77
- case 'ui':
78
- return {
79
- label: 'UI',
80
- renderIcon: (color: string, size = 9) => (
81
- <ScreenIcon color={color} size={size} />
82
- ),
83
- bg: AppColors.sky100,
84
- text: AppColors.sky600,
85
- border: AppColors.sky400,
86
- };
87
- case 'listener':
88
- return {
89
- label: 'LISTENER',
90
- renderIcon: (color: string, size = 9) => (
91
- <ListenerIcon color={color} size={size} />
92
- ),
93
- bg: AppColors.teal100,
94
- text: AppColors.teal700,
95
- border: AppColors.teal400,
96
- };
97
- default:
98
- return {
99
- label: 'DIRECT',
100
- renderIcon: (color: string, size = 9) => (
101
- <BoltIcon color={color} size={size} />
102
- ),
103
- bg: AppColors.slate100,
104
- text: AppColors.slate700,
105
- border: AppColors.slate200,
106
- };
107
- }
108
- };
109
-
110
- const ReduxDetail = React.memo(() => {
111
- const {t} = useTranslation();
112
- const {
113
- reduxState,
114
- reduxLastActionMap,
115
- selectedReduxSlice,
116
- selectedReduxAction,
117
- setSelectedReduxSlice,
118
- } = useInspector();
119
-
120
- // Search filter within details
121
- const [detailSearch, setDetailSearch] = useState('');
122
-
123
- // Sub-tabs for Slice & Action
124
- const [sliceTab, setSliceTab] = useState<SliceDetailSubTab>('live');
125
- const [actionTab, setActionTab] = useState<ActionDetailSubTab>('payload');
126
- const [viewMode, setViewMode] = useState<'pretty' | 'raw' | 'table'>(
127
- 'pretty',
128
- );
129
-
130
- // Selected Action inside Timeline
131
- const [expandedActionId, setExpandedActionId] = useState<number | null>(null);
132
-
133
- // Persistence data for active slice
134
- const [isPersisted, setIsPersisted] = useState(false);
135
- const [persistedData, setPersistedData] = useState<any>(null);
136
-
137
- // Fetch Action History
138
- const allActionHistory = useMemo(() => {
139
- return getActionHistory();
140
- }, [reduxLastActionMap]);
141
-
142
- // Slices-filtered actions
143
- const sliceActions = useMemo(() => {
144
- if (!selectedReduxSlice) return allActionHistory;
145
- return allActionHistory.filter(action => {
146
- if (!action.affectedSlices || action.affectedSlices.length === 0)
147
- return true;
148
- return action.affectedSlices.includes(selectedReduxSlice);
149
- });
150
- }, [allActionHistory, selectedReduxSlice]);
151
-
152
- // Filtered slice actions by search query in timeline tab
153
- const filteredTimelineActions = useMemo(() => {
154
- if (!detailSearch.trim()) return sliceActions;
155
- const q = detailSearch.toLowerCase();
156
- return sliceActions.filter(action => {
157
- return (
158
- action.type.toLowerCase().includes(q) ||
159
- (action.callerFile && action.callerFile.toLowerCase().includes(q)) ||
160
- (action.payload &&
161
- JSON.stringify(action.payload).toLowerCase().includes(q))
162
- );
163
- });
164
- }, [sliceActions, detailSearch]);
165
-
166
- useEffect(() => {
167
- if (!selectedReduxSlice) return;
168
-
169
- async function checkPersistence() {
170
- try {
171
- const storage = getCustomStorage();
172
- if (!storage) {
173
- setIsPersisted(false);
174
- setPersistedData(null);
175
- return;
176
- }
177
-
178
- let raw = await storage.getItem(`persist:${selectedReduxSlice}`);
179
- if (raw) {
180
- try {
181
- setPersistedData(JSON.parse(raw));
182
- } catch {
183
- setPersistedData(raw);
184
- }
185
- setIsPersisted(true);
186
- return;
187
- }
188
-
189
- let rootRaw = await storage.getItem('persist:root');
190
- if (rootRaw) {
191
- const parsedRoot = JSON.parse(rootRaw);
192
- if (parsedRoot && parsedRoot[selectedReduxSlice] !== undefined) {
193
- const nested = parsedRoot[selectedReduxSlice];
194
- try {
195
- setPersistedData(
196
- typeof nested === 'string' ? JSON.parse(nested) : nested,
197
- );
198
- } catch {
199
- setPersistedData(nested);
200
- }
201
- setIsPersisted(true);
202
- return;
203
- }
204
- }
205
- } catch (e) {
206
- // silent catch
207
- }
208
- setIsPersisted(false);
209
- setPersistedData(null);
210
- }
211
-
212
- checkPersistence();
213
- }, [selectedReduxSlice]);
214
-
215
- const handleClearPersistence = () => {
216
- if (!selectedReduxSlice) return;
217
- Alert.alert(
218
- 'Clear Persisted State',
219
- `Are you sure you want to delete persisted storage for slice "${selectedReduxSlice}"?`,
220
- [
221
- {text: 'Cancel', style: 'cancel'},
222
- {
223
- text: 'Delete',
224
- style: 'destructive',
225
- onPress: async () => {
226
- try {
227
- const storage = getCustomStorage();
228
- if (!storage) return;
229
-
230
- if (typeof (storage as any).removeItem === 'function') {
231
- await (storage as any).removeItem(
232
- `persist:${selectedReduxSlice}`,
233
- );
234
- } else {
235
- await storage.setItem(`persist:${selectedReduxSlice}`, '');
236
- }
237
-
238
- setIsPersisted(false);
239
- setPersistedData(null);
240
- setSliceTab('live');
241
-
242
- if (Platform.OS === 'android') {
243
- ToastAndroid.show(
244
- 'Persisted state cleared',
245
- ToastAndroid.SHORT,
246
- );
247
- } else {
248
- Alert.alert('Cleared', 'Persisted state has been cleared.');
249
- }
250
- } catch (err) {
251
- Alert.alert('Error', 'Failed to clear persisted state.');
252
- }
253
- },
254
- },
255
- ],
256
- );
257
- };
258
-
259
- // ══════════════════════════════════════════════════════════════════════════
260
- // ── 1. RENDER SLICE DETAIL VIEW ───────────────────────────────────────────
261
- // ══════════════════════════════════════════════════════════════════════════
262
- if (selectedReduxSlice != null) {
263
- const sliceData = reduxState?.[selectedReduxSlice];
264
- const fieldsCount =
265
- sliceData && typeof sliceData === 'object'
266
- ? Object.keys(sliceData).length
267
- : typeof sliceData !== 'undefined'
268
- ? 1
269
- : 0;
270
- const lastAction = reduxLastActionMap[selectedReduxSlice];
271
-
272
- const sliceTabs = [
273
- {
274
- key: 'live',
275
- label: t('redux.liveState', 'Live State'),
276
- icon: (isActive: boolean) => (
277
- <LiveStateIcon
278
- color={isActive ? AppColors.white : AppColors.grayText}
279
- size={12}
280
- />
281
- ),
282
- },
283
- {
284
- key: 'timeline',
285
- label: `${t('redux.timeline', 'Timeline')} (${sliceActions.length})`,
286
- icon: (isActive: boolean) => (
287
- <TimelineIcon
288
- color={isActive ? AppColors.white : AppColors.grayText}
289
- size={12}
290
- />
291
- ),
292
- },
293
- {
294
- key: 'persisted',
295
- label: isPersisted
296
- ? t('redux.persisted', 'Persisted')
297
- : t('redux.storage', 'Storage'),
298
- icon: (isActive: boolean) => (
299
- <StorageIcon
300
- color={isActive ? AppColors.white : AppColors.grayText}
301
- size={12}
302
- />
303
- ),
304
- },
305
- {
306
- key: 'metadata',
307
- label: t('redux.metadata', 'Metadata'),
308
- icon: (isActive: boolean) => (
309
- <MetadataIcon
310
- color={isActive ? AppColors.white : AppColors.grayText}
311
- size={12}
312
- />
313
- ),
314
- },
315
- ];
316
-
317
- return (
318
- <View style={{flex: 1, backgroundColor: AppColors.grayBackground}}>
319
- {/* Info Header Bar */}
320
- <View style={reduxDetailStyles.infoBar}>
321
- <View style={reduxDetailStyles.infoTopRow}>
322
- <View
323
- style={{
324
- flexDirection: 'row',
325
- alignItems: 'center',
326
- gap: 6,
327
- flexWrap: 'wrap',
328
- flex: 1,
329
- minWidth: 0,
330
- }}>
331
- <View
332
- style={[
333
- reduxDetailStyles.methodBadge,
334
- {backgroundColor: AppColors.indigo600Alt},
335
- ]}>
336
- <Text style={reduxDetailStyles.methodBadgeText}>
337
- {t('redux.slice', 'SLICE')}
338
- </Text>
339
- </View>
340
- <Text style={reduxDetailStyles.sliceNameText} numberOfLines={1}>
341
- {selectedReduxSlice}
342
- </Text>
343
- {isPersisted ? (
344
- <View style={reduxDetailStyles.persistedChip}>
345
- <StorageIcon color={AppColors.emerald700} size={10} />
346
- <Text style={reduxDetailStyles.persistedChipText}>
347
- {t('redux.persisted', 'Persisted').toUpperCase()}
348
- </Text>
349
- </View>
350
- ) : (
351
- <View style={reduxDetailStyles.inMemoryChip}>
352
- <Text style={reduxDetailStyles.inMemoryChipText}>
353
- {t('redux.inMemory', 'In-Memory').toUpperCase()}
354
- </Text>
355
- </View>
356
- )}
357
- {lastAction?.timestamp && (
358
- <View style={reduxDetailStyles.timePill}>
359
- <ClockIcon color={AppColors.violet600} size={10} />
360
- <Text style={reduxDetailStyles.timeText}>
361
- {lastAction.timestamp}
362
- </Text>
363
- </View>
364
- )}
365
- </View>
366
-
367
- {/* Copy Button */}
368
- <CopyButton
369
- value={() => (sliceTab === 'live' ? sliceData : persistedData)}
370
- label={t('redux.sliceJson', 'Slice JSON')}
371
- />
372
- </View>
373
-
374
- {/* Sub Stats Row */}
375
- <View style={reduxDetailStyles.subStatsRow}>
376
- <View
377
- style={[
378
- reduxDetailStyles.statPill,
379
- {
380
- backgroundColor: AppColors.indigo50,
381
- borderColor: AppColors.indigo400,
382
- },
383
- ]}>
384
- <LayersIcon color={AppColors.indigo600Alt} size={11} />
385
- <Text
386
- style={[
387
- reduxDetailStyles.statLabel,
388
- {color: AppColors.indigo600Alt},
389
- ]}>
390
- {t('redux.keys', 'Keys')}:
391
- </Text>
392
- <Text
393
- style={[
394
- reduxDetailStyles.statValue,
395
- {color: AppColors.indigo600Alt},
396
- ]}>
397
- {fieldsCount}
398
- </Text>
399
- </View>
400
- <View
401
- style={[
402
- reduxDetailStyles.statPill,
403
- {
404
- backgroundColor: AppColors.sky100,
405
- borderColor: AppColors.sky400,
406
- },
407
- ]}>
408
- <Text
409
- style={[
410
- reduxDetailStyles.statLabel,
411
- {color: AppColors.sky600},
412
- ]}>
413
- {t('redux.size', 'Size')}:
414
- </Text>
415
- <Text
416
- style={[
417
- reduxDetailStyles.statValue,
418
- {color: AppColors.sky600},
419
- ]}>
420
- {getSize(sliceData)}
421
- </Text>
422
- </View>
423
- <View
424
- style={[
425
- reduxDetailStyles.statPill,
426
- {
427
- backgroundColor: AppColors.purple100,
428
- borderColor: AppColors.purple200,
429
- },
430
- ]}>
431
- <TimelineIcon color={AppColors.violet600} size={11} />
432
- <Text
433
- style={[
434
- reduxDetailStyles.statLabel,
435
- {color: AppColors.brandPurple},
436
- ]}>
437
- {t('redux.timeline', 'Timeline')}:
438
- </Text>
439
- <Text
440
- style={[
441
- reduxDetailStyles.statValue,
442
- {color: AppColors.brandPurple},
443
- ]}>
444
- {sliceActions.length}
445
- </Text>
446
- </View>
447
- {lastAction && (
448
- <View
449
- style={[
450
- reduxDetailStyles.statPill,
451
- {
452
- backgroundColor: AppColors.amber100,
453
- borderColor: AppColors.amber200,
454
- flexShrink: 1,
455
- maxWidth: 160,
456
- },
457
- ]}>
458
- <BoltIcon color={AppColors.amber800Warm} size={11} />
459
- <Text
460
- style={[
461
- reduxDetailStyles.statLabel,
462
- {color: AppColors.amber800Warm},
463
- ]}>
464
- {t('redux.last', 'Last')}:
465
- </Text>
466
- <Text
467
- style={[
468
- reduxDetailStyles.statValue,
469
- {color: AppColors.amber800Warm, flexShrink: 1},
470
- ]}
471
- numberOfLines={1}>
472
- {lastAction.type}
473
- </Text>
474
- </View>
475
- )}
476
- </View>
477
-
478
- {/* Sub-Tabs */}
479
- <SegmentedTabs
480
- tabs={sliceTabs}
481
- activeKey={sliceTab}
482
- onChange={key => setSliceTab(key as SliceDetailSubTab)}
483
- style={{marginTop: 10}}
484
- />
485
- </View>
486
-
487
- {/* Search Bar within slice (for Live, Timeline, Persisted) */}
488
- {sliceTab !== 'metadata' && (
489
- <View style={reduxDetailStyles.searchContainer}>
490
- <SearchIcon color={AppColors.grayTextWeak} size={14} />
491
- <TextInput
492
- placeholder={
493
- sliceTab === 'timeline'
494
- ? 'Search action type, file, or payload...'
495
- : 'Search keys or values...'
496
- }
497
- placeholderTextColor={AppColors.grayTextWeak}
498
- value={detailSearch}
499
- onChangeText={setDetailSearch}
500
- style={reduxDetailStyles.searchInput}
501
- autoCorrect={false}
502
- autoCapitalize="none"
503
- />
504
- {detailSearch.length > 0 && (
505
- <Pressable onPress={() => setDetailSearch('')} hitSlop={10}>
506
- <ClearIcon color={AppColors.grayTextWeak} size={14} />
507
- </Pressable>
508
- )}
509
- </View>
510
- )}
511
-
512
- {/* Content Body */}
513
- {sliceTab === 'timeline' ? (
514
- <ScrollView
515
- style={{flex: 1}}
516
- contentContainerStyle={{padding: 12, paddingBottom: 40}}
517
- keyboardShouldPersistTaps="handled">
518
- {filteredTimelineActions.length === 0 ? (
519
- <View style={reduxDetailStyles.emptyBox}>
520
- <TimelineIcon color={AppColors.grayTextWeak} size={28} />
521
- <Text style={reduxDetailStyles.emptyBoxText}>
522
- {detailSearch.trim()
523
- ? 'No actions matching your search query.'
524
- : 'No dispatched actions recorded for this slice yet.'}
525
- </Text>
526
- </View>
527
- ) : (
528
- filteredTimelineActions.map((action, aIdx) => {
529
- const isExpanded = expandedActionId === action.id;
530
- const originMeta = getOriginBadge(action.originType);
531
- const callerBasename = action.callerFile
532
- ? action.callerFile.split('/').pop()
533
- : null;
534
-
535
- return (
536
- <AnimatedEntrance key={action.id} index={aIdx} distance={6}>
537
- <TouchableScale
538
- onPress={() =>
539
- setExpandedActionId(isExpanded ? null : action.id)
540
- }
541
- style={reduxDetailStyles.timelineCard}>
542
- <View style={reduxDetailStyles.timelineHeader}>
543
- <View
544
- style={{
545
- flexDirection: 'row',
546
- alignItems: 'center',
547
- gap: 6,
548
- flex: 1,
549
- minWidth: 0,
550
- flexWrap: 'wrap',
551
- }}>
552
- <View style={reduxDetailStyles.actionBadge}>
553
- <Text style={reduxDetailStyles.actionBadgeText}>
554
- #{action.id}
555
- </Text>
556
- </View>
557
- {/* Origin Badge */}
558
- <View
559
- style={{
560
- flexDirection: 'row',
561
- alignItems: 'center',
562
- gap: 3,
563
- backgroundColor: originMeta.bg,
564
- paddingHorizontal: 5,
565
- paddingVertical: 2,
566
- borderRadius: 4,
567
- borderWidth: 1,
568
- borderColor: originMeta.border,
569
- }}>
570
- {originMeta.renderIcon(originMeta.text, 8.5)}
571
- <Text
572
- style={{
573
- fontFamily: AppFonts.interBold,
574
- fontSize: 8.5,
575
- color: originMeta.text,
576
- letterSpacing: 0.3,
577
- }}>
578
- {originMeta.label}
579
- </Text>
580
- </View>
581
-
582
- <HighlightText
583
- text={action.type}
584
- search={detailSearch}
585
- style={reduxDetailStyles.actionTitle}
586
- highlightStyle={reduxDetailStyles.highlight}
587
- />
588
- </View>
589
-
590
- <View style={reduxDetailStyles.timePill}>
591
- <ClockIcon color={AppColors.purple} size={10} />
592
- <Text style={reduxDetailStyles.timeText}>
593
- {action.timestamp}
594
- </Text>
595
- </View>
596
- </View>
597
-
598
- {/* Trigger caller preview row */}
599
- {action.callerFile && (
600
- <View
601
- style={{
602
- flexDirection: 'row',
603
- alignItems: 'center',
604
- justifyContent: 'space-between',
605
- marginTop: 6,
606
- marginBottom: 2,
607
- paddingHorizontal: 8,
608
- paddingVertical: 4,
609
- backgroundColor: AppColors.grayBackground,
610
- borderRadius: 6,
611
- borderWidth: 1,
612
- borderColor: AppColors.dividerColor,
613
- }}>
614
- <View
615
- style={{
616
- flexDirection: 'row',
617
- alignItems: 'center',
618
- gap: 5,
619
- flex: 1,
620
- minWidth: 0,
621
- }}>
622
- <DocIcon color={AppColors.sky600} size={10} />
623
- <Text
624
- style={{
625
- fontFamily: AppFonts.interMedium,
626
- fontSize: 9.5,
627
- color: AppColors.grayTextWeak,
628
- }}>
629
- {t('redux.triggeredFrom', 'Triggered From:')}
630
- </Text>
631
- <Text
632
- style={{
633
- fontFamily: AppFonts.interBold,
634
- fontSize: 9.5,
635
- color: AppColors.sky600,
636
- }}
637
- numberOfLines={1}>
638
- {callerBasename}:{action.callerLine || 1}
639
- </Text>
640
- </View>
641
-
642
- <Pressable
643
- onPress={() =>
644
- openInVSCode(
645
- action.callerFile!,
646
- action.callerLine,
647
- action.callerCol,
648
- )
649
- }
650
- hitSlop={8}
651
- style={{
652
- flexDirection: 'row',
653
- alignItems: 'center',
654
- gap: 3,
655
- backgroundColor: AppColors.sky100,
656
- paddingHorizontal: 5,
657
- paddingVertical: 2,
658
- borderRadius: 4,
659
- }}>
660
- <ExternalLinkIcon
661
- color={AppColors.sky600}
662
- size={9}
663
- />
664
- <Text
665
- style={{
666
- fontFamily: AppFonts.interBold,
667
- fontSize: 8.5,
668
- color: AppColors.sky600,
669
- }}>
670
- {t('redux.openInEditor', 'Open in Editor')}
671
- </Text>
672
- </Pressable>
673
- </View>
674
- )}
675
-
676
- {/* Expanded Payload, Diff Viewer & Call Stack */}
677
- {isExpanded ? (
678
- <View style={reduxDetailStyles.expandedContent}>
679
- {/* Call Stack Trace Box */}
680
- {action.stack ? (
681
- <View style={{marginBottom: 12}}>
682
- <Text
683
- style={reduxDetailStyles.expandedSectionTitle}>
684
- {t('redux.callStack', 'Call Stack Trace')}:
685
- </Text>
686
- <View
687
- style={{
688
- backgroundColor: AppColors.grayBackground,
689
- borderRadius: 8,
690
- padding: 8,
691
- borderWidth: 1,
692
- borderColor: AppColors.dividerColor,
693
- gap: 4,
694
- }}>
695
- {action.stack
696
- .split('\n')
697
- .map(l => l.trim())
698
- .filter(
699
- l =>
700
- l.length > 0 &&
701
- !l.includes('reduxLogger') &&
702
- !l.includes('inspectorReduxMiddleware'),
703
- )
704
- .slice(0, 8)
705
- .map((frameLine, fIdx) => {
706
- const parsed = parseStackLine(
707
- frameLine,
708
- fIdx === 0,
709
- );
710
- const isApp = parsed.frameType === 'app';
711
- return (
712
- <Pressable
713
- key={fIdx}
714
- onPress={() => {
715
- if (parsed.fileName !== 'Unknown') {
716
- openInVSCode(
717
- parsed.fullPath ||
718
- parsed.fileName,
719
- parsed.lineNumber,
720
- parsed.columnNumber,
721
- );
722
- }
723
- }}
724
- style={{
725
- flexDirection: 'row',
726
- alignItems: 'center',
727
- justifyContent: 'space-between',
728
- paddingVertical: 3,
729
- borderBottomWidth: fIdx < 7 ? 0.5 : 0,
730
- borderBottomColor:
731
- AppColors.dividerColor,
732
- }}>
733
- <View style={{flex: 1, minWidth: 0}}>
734
- <Text
735
- style={{
736
- fontFamily: isApp
737
- ? AppFonts.interBold
738
- : AppFonts.interRegular,
739
- fontSize: 9.5,
740
- color: isApp
741
- ? AppColors.primaryBlack
742
- : AppColors.grayTextWeak,
743
- }}
744
- numberOfLines={1}>
745
- {parsed.functionName || 'anonymous'}
746
- </Text>
747
- <Text
748
- style={{
749
- fontFamily: AppFonts.interRegular,
750
- fontSize: 8.5,
751
- color: isApp
752
- ? AppColors.sky600
753
- : AppColors.grayTextWeak,
754
- }}
755
- numberOfLines={1}>
756
- {parsed.fileName}:
757
- {parsed.lineNumber || 1}:
758
- {parsed.columnNumber || 1}
759
- </Text>
760
- </View>
761
- {isApp && (
762
- <ExternalLinkIcon
763
- color={AppColors.sky600}
764
- size={10}
765
- />
766
- )}
767
- </Pressable>
768
- );
769
- })}
770
- </View>
771
- </View>
772
- ) : null}
773
-
774
- {action.payload !== undefined && (
775
- <View style={{marginBottom: 12}}>
776
- <Text
777
- style={reduxDetailStyles.expandedSectionTitle}>
778
- {t('redux.actionPayload', 'Action Payload:')}
779
- </Text>
780
- <JsonViewer
781
- data={action.payload}
782
- search={detailSearch}
783
- forceOpen={true}
784
- wrap={true}
785
- />
786
- </View>
787
- )}
788
-
789
- <Text style={reduxDetailStyles.expandedSectionTitle}>
790
- {t(
791
- 'redux.stateChangesDiff',
792
- 'State Changes (Diff):',
793
- )}
794
- </Text>
795
- <DiffViewer
796
- oldData={
797
- action.prevState?.[selectedReduxSlice] || {}
798
- }
799
- newData={
800
- action.nextState?.[selectedReduxSlice] || {}
801
- }
802
- forceOpen={true}
803
- />
804
- </View>
805
- ) : (
806
- <View style={reduxDetailStyles.collapsedPrompt}>
807
- <Text style={reduxDetailStyles.collapsedPromptText}>
808
- {t(
809
- 'redux.tapToInspectAction',
810
- 'Tap to inspect action payload & diff changes',
811
- )}
812
- </Text>
813
- <ForwardChevronIcon
814
- color={AppColors.grayTextWeak}
815
- size={12}
816
- />
817
- </View>
818
- )}
819
- </TouchableScale>
820
- </AnimatedEntrance>
821
- );
822
- })
823
- )}
824
- </ScrollView>
825
- ) : sliceTab === 'metadata' ? (
826
- <ScrollView
827
- style={{flex: 1}}
828
- contentContainerStyle={{padding: 12, paddingBottom: 40}}
829
- keyboardShouldPersistTaps="handled">
830
- <View style={reduxDetailStyles.metadataCard}>
831
- {[
832
- {label: 'Slice Name', value: selectedReduxSlice},
833
- {label: 'Root Keys Count', value: `${fieldsCount} keys`},
834
- {label: 'In-Memory State Size', value: getSize(sliceData)},
835
- {
836
- label: 'Persistence Status',
837
- value: isPersisted
838
- ? `Persisted (${getSize(persistedData)})`
839
- : 'Not Persisted (In-Memory)',
840
- },
841
- {
842
- label: 'Dispatched Actions History',
843
- value: `${sliceActions.length} recorded actions`,
844
- },
845
- {
846
- label: 'Last Dispatched Action',
847
- value: lastAction ? lastAction.type : 'None',
848
- },
849
- {
850
- label: 'Last Action Timestamp',
851
- value: lastAction ? lastAction.timestamp : 'Initial',
852
- },
853
- ].map((row, rIdx) => (
854
- <View
855
- key={rIdx}
856
- style={[
857
- reduxDetailStyles.metaRow,
858
- rIdx === 6 && {borderBottomWidth: 0},
859
- ]}>
860
- <Text style={reduxDetailStyles.metaLabel}>{row.label}</Text>
861
- <Text
862
- style={reduxDetailStyles.metaValue}
863
- selectable
864
- numberOfLines={2}>
865
- {row.value}
866
- </Text>
867
- </View>
868
- ))}
869
-
870
- {isPersisted && (
871
- <TouchableOpacity
872
- style={reduxDetailStyles.clearPersistBtn}
873
- onPress={handleClearPersistence}>
874
- <TrashIcon color={AppColors.errorColor} size={14} />
875
- <Text style={reduxDetailStyles.clearPersistText}>
876
- Clear Persisted Storage For This Slice
877
- </Text>
878
- </TouchableOpacity>
879
- )}
880
- </View>
881
- </ScrollView>
882
- ) : sliceTab === 'persisted' ? (
883
- <View style={{flex: 1, padding: 10}}>
884
- {isPersisted ? (
885
- <View style={{flex: 1}}>
886
- <View style={reduxDetailStyles.persistedInfoCard}>
887
- <View
888
- style={{
889
- flexDirection: 'row',
890
- alignItems: 'center',
891
- justifyContent: 'space-between',
892
- }}>
893
- <View
894
- style={{
895
- flexDirection: 'row',
896
- alignItems: 'center',
897
- gap: 6,
898
- }}>
899
- <StorageIcon color={AppColors.emerald700} size={14} />
900
- <Text style={reduxDetailStyles.persistedInfoTitle}>
901
- Stored in persistent storage ({getSize(persistedData)})
902
- </Text>
903
- </View>
904
- <TouchableOpacity
905
- style={reduxDetailStyles.clearPersistMiniBtn}
906
- onPress={handleClearPersistence}>
907
- <TrashIcon color={AppColors.errorColor} size={12} />
908
- <Text style={reduxDetailStyles.clearPersistMiniText}>
909
- Clear
910
- </Text>
911
- </TouchableOpacity>
912
- </View>
913
- </View>
914
- <View style={{flex: 1, marginTop: 8}}>
915
- <JsonViewer
916
- data={persistedData}
917
- search={detailSearch}
918
- forceOpen={detailSearch.length > 0 ? true : undefined}
919
- mode={viewMode}
920
- onModeChange={setViewMode}
921
- fullHeight={true}
922
- wrap={true}
923
- />
924
- </View>
925
- </View>
926
- ) : (
927
- <View style={reduxDetailStyles.emptyBox}>
928
- <StorageIcon color={AppColors.grayTextWeak} size={32} />
929
- <Text style={reduxDetailStyles.emptyBoxTitle}>
930
- Not Persisted in Storage
931
- </Text>
932
- <Text style={reduxDetailStyles.emptyBoxText}>
933
- This slice is not stored in AsyncStorage or redux-persist.
934
- State exists purely in active JavaScript memory.
935
- </Text>
936
- </View>
937
- )}
938
- </View>
939
- ) : (
940
- /* Live State JsonViewer: Direct flex: 1 with fullHeight to prevent nested scroll conflicts */
941
- <View style={{flex: 1, padding: 10}}>
942
- <JsonViewer
943
- data={sliceData}
944
- search={detailSearch}
945
- forceOpen={detailSearch.length > 0 ? true : undefined}
946
- mode={viewMode}
947
- onModeChange={setViewMode}
948
- fullHeight={true}
949
- wrap={true}
950
- />
951
- </View>
952
- )}
953
- </View>
954
- );
955
- }
956
-
957
- // ══════════════════════════════════════════════════════════════════════════
958
- // ── 2. RENDER ACTION DETAIL VIEW (when an action is selected directly) ────
959
- // ══════════════════════════════════════════════════════════════════════════
960
- if (selectedReduxAction != null) {
961
- const originMeta = getOriginBadge(selectedReduxAction.originType);
962
- const callerBasename = selectedReduxAction.callerFile
963
- ? selectedReduxAction.callerFile.split('/').pop()
964
- : null;
965
-
966
- const actionTabs = [
967
- {
968
- key: 'payload',
969
- label: t('redux.payload', 'Payload'),
970
- icon: (isActive: boolean) => (
971
- <CodeBracketsIcon
972
- color={isActive ? AppColors.white : AppColors.grayText}
973
- size={12}
974
- />
975
- ),
976
- },
977
- {
978
- key: 'diff',
979
- label: t('redux.diff', 'State Diff'),
980
- icon: (isActive: boolean) => (
981
- <TimelineIcon
982
- color={isActive ? AppColors.white : AppColors.grayText}
983
- size={12}
984
- />
985
- ),
986
- },
987
- {
988
- key: 'stack',
989
- label: t('redux.callStack', 'Call Stack'),
990
- icon: (isActive: boolean) => (
991
- <DocIcon
992
- color={isActive ? AppColors.white : AppColors.grayText}
993
- size={12}
994
- />
995
- ),
996
- },
997
- {
998
- key: 'raw',
999
- label: 'Raw Action',
1000
- icon: (isActive: boolean) => (
1001
- <LiveStateIcon
1002
- color={isActive ? AppColors.white : AppColors.grayText}
1003
- size={12}
1004
- />
1005
- ),
1006
- },
1007
- ];
1008
-
1009
- return (
1010
- <View style={{flex: 1, backgroundColor: AppColors.grayBackground}}>
1011
- {/* Top Info Bar */}
1012
- <View style={reduxDetailStyles.infoBar}>
1013
- <View style={reduxDetailStyles.infoTopRow}>
1014
- <View
1015
- style={{
1016
- flexDirection: 'row',
1017
- alignItems: 'center',
1018
- gap: 6,
1019
- flexWrap: 'wrap',
1020
- flex: 1,
1021
- minWidth: 0,
1022
- }}>
1023
- <View style={reduxDetailStyles.actionBadge}>
1024
- <Text style={reduxDetailStyles.actionBadgeText}>
1025
- #{selectedReduxAction.id}
1026
- </Text>
1027
- </View>
1028
- {/* Origin Badge */}
1029
- <View
1030
- style={{
1031
- flexDirection: 'row',
1032
- alignItems: 'center',
1033
- gap: 3,
1034
- backgroundColor: originMeta.bg,
1035
- paddingHorizontal: 5,
1036
- paddingVertical: 2,
1037
- borderRadius: 4,
1038
- borderWidth: 1,
1039
- borderColor: originMeta.border,
1040
- }}>
1041
- {originMeta.renderIcon(originMeta.text, 8.5)}
1042
- <Text
1043
- style={{
1044
- fontFamily: AppFonts.interBold,
1045
- fontSize: 8.5,
1046
- color: originMeta.text,
1047
- letterSpacing: 0.3,
1048
- }}>
1049
- {originMeta.label}
1050
- </Text>
1051
- </View>
1052
- <Text style={reduxDetailStyles.sliceNameText} numberOfLines={1}>
1053
- {selectedReduxAction.type}
1054
- </Text>
1055
- {selectedReduxAction.timestamp && (
1056
- <View style={reduxDetailStyles.timePill}>
1057
- <ClockIcon color={AppColors.purple} size={10} />
1058
- <Text style={reduxDetailStyles.timeText}>
1059
- {selectedReduxAction.timestamp}
1060
- </Text>
1061
- </View>
1062
- )}
1063
- </View>
1064
-
1065
- {/* Copy Button */}
1066
- <CopyButton value={() => selectedReduxAction} label="Copy Action" />
1067
- </View>
1068
-
1069
- {/* Sub Stats Row */}
1070
- <View style={reduxDetailStyles.subStatsRow}>
1071
- {selectedReduxAction.affectedSlices &&
1072
- selectedReduxAction.affectedSlices.length > 0 && (
1073
- <View
1074
- style={[
1075
- reduxDetailStyles.statPill,
1076
- {
1077
- backgroundColor: AppColors.indigo50,
1078
- borderColor: AppColors.indigo400,
1079
- },
1080
- ]}>
1081
- <LayersIcon color={AppColors.indigo600Alt} size={11} />
1082
- <Text
1083
- style={[
1084
- reduxDetailStyles.statLabel,
1085
- {color: AppColors.indigo600Alt},
1086
- ]}>
1087
- Slices:
1088
- </Text>
1089
- <Text
1090
- style={[
1091
- reduxDetailStyles.statValue,
1092
- {color: AppColors.indigo600Alt},
1093
- ]}>
1094
- {selectedReduxAction.affectedSlices.join(', ')}
1095
- </Text>
1096
- </View>
1097
- )}
1098
- <View
1099
- style={[
1100
- reduxDetailStyles.statPill,
1101
- {
1102
- backgroundColor: AppColors.sky100,
1103
- borderColor: AppColors.sky400,
1104
- },
1105
- ]}>
1106
- <Text
1107
- style={[
1108
- reduxDetailStyles.statLabel,
1109
- {color: AppColors.sky600},
1110
- ]}>
1111
- Payload Size:
1112
- </Text>
1113
- <Text
1114
- style={[
1115
- reduxDetailStyles.statValue,
1116
- {color: AppColors.sky600},
1117
- ]}>
1118
- {getSize(selectedReduxAction.payload)}
1119
- </Text>
1120
- </View>
1121
- </View>
1122
-
1123
- {/* Triggered from caller preview row */}
1124
- {selectedReduxAction.callerFile && (
1125
- <View
1126
- style={{
1127
- flexDirection: 'row',
1128
- alignItems: 'center',
1129
- justifyContent: 'space-between',
1130
- marginTop: 8,
1131
- paddingHorizontal: 8,
1132
- paddingVertical: 4,
1133
- backgroundColor: AppColors.grayBackground,
1134
- borderRadius: 6,
1135
- borderWidth: 1,
1136
- borderColor: AppColors.dividerColor,
1137
- }}>
1138
- <View
1139
- style={{
1140
- flexDirection: 'row',
1141
- alignItems: 'center',
1142
- gap: 5,
1143
- flex: 1,
1144
- minWidth: 0,
1145
- }}>
1146
- <DocIcon color={AppColors.sky600} size={10} />
1147
- <Text
1148
- style={{
1149
- fontFamily: AppFonts.interMedium,
1150
- fontSize: 9.5,
1151
- color: AppColors.grayTextWeak,
1152
- }}>
1153
- Triggered from:
1154
- </Text>
1155
- <Text
1156
- style={{
1157
- fontFamily: AppFonts.interBold,
1158
- fontSize: 9.5,
1159
- color: AppColors.sky600,
1160
- }}
1161
- numberOfLines={1}>
1162
- {callerBasename}:{selectedReduxAction.callerLine || 1}
1163
- </Text>
1164
- </View>
1165
-
1166
- <Pressable
1167
- onPress={() =>
1168
- openInVSCode(
1169
- selectedReduxAction.callerFile!,
1170
- selectedReduxAction.callerLine,
1171
- selectedReduxAction.callerCol,
1172
- )
1173
- }
1174
- hitSlop={8}
1175
- style={{
1176
- flexDirection: 'row',
1177
- alignItems: 'center',
1178
- gap: 3,
1179
- backgroundColor: AppColors.sky100,
1180
- paddingHorizontal: 5,
1181
- paddingVertical: 2,
1182
- borderRadius: 4,
1183
- }}>
1184
- <ExternalLinkIcon color={AppColors.sky600} size={9} />
1185
- <Text
1186
- style={{
1187
- fontFamily: AppFonts.interBold,
1188
- fontSize: 8.5,
1189
- color: AppColors.sky600,
1190
- }}>
1191
- Open in Editor
1192
- </Text>
1193
- </Pressable>
1194
- </View>
1195
- )}
1196
-
1197
- {/* Sub-Tabs */}
1198
- <SegmentedTabs
1199
- tabs={actionTabs}
1200
- activeKey={actionTab}
1201
- onChange={key => setActionTab(key as ActionDetailSubTab)}
1202
- style={{marginTop: 10}}
1203
- />
1204
- </View>
1205
-
1206
- {/* Content Body */}
1207
- {actionTab === 'payload' ? (
1208
- <View style={{flex: 1, padding: 10}}>
1209
- {selectedReduxAction.payload !== undefined ? (
1210
- <JsonViewer
1211
- data={selectedReduxAction.payload}
1212
- search={detailSearch}
1213
- forceOpen={true}
1214
- fullHeight={true}
1215
- wrap={true}
1216
- />
1217
- ) : (
1218
- <View style={reduxDetailStyles.emptyBox}>
1219
- <Text style={reduxDetailStyles.emptyBoxText}>
1220
- This action has no payload dispatched.
1221
- </Text>
1222
- </View>
1223
- )}
1224
- </View>
1225
- ) : actionTab === 'diff' ? (
1226
- <ScrollView
1227
- style={{flex: 1}}
1228
- contentContainerStyle={{padding: 12, paddingBottom: 40}}
1229
- keyboardShouldPersistTaps="handled">
1230
- <DiffViewer
1231
- oldData={selectedReduxAction.prevState || {}}
1232
- newData={selectedReduxAction.nextState || {}}
1233
- forceOpen={true}
1234
- />
1235
- </ScrollView>
1236
- ) : actionTab === 'stack' ? (
1237
- <ScrollView
1238
- style={{flex: 1}}
1239
- contentContainerStyle={{padding: 12, paddingBottom: 40}}
1240
- keyboardShouldPersistTaps="handled">
1241
- {selectedReduxAction.stack ? (
1242
- <View
1243
- style={{
1244
- backgroundColor: AppColors.white,
1245
- borderRadius: 10,
1246
- padding: 10,
1247
- borderWidth: 1,
1248
- borderColor: AppColors.dividerColor,
1249
- }}>
1250
- <Text style={reduxDetailStyles.expandedSectionTitle}>
1251
- Dispatched from call stack:
1252
- </Text>
1253
- {selectedReduxAction.stack
1254
- .split('\n')
1255
- .map(l => l.trim())
1256
- .filter(
1257
- l =>
1258
- l.length > 0 &&
1259
- !l.includes('reduxLogger') &&
1260
- !l.includes('inspectorReduxMiddleware'),
1261
- )
1262
- .map((frameLine, fIdx) => {
1263
- const parsed = parseStackLine(frameLine, fIdx === 0);
1264
- const isApp = parsed.frameType === 'app';
1265
- return (
1266
- <Pressable
1267
- key={fIdx}
1268
- onPress={() => {
1269
- if (parsed.fileName !== 'Unknown') {
1270
- openInVSCode(
1271
- parsed.fullPath || parsed.fileName,
1272
- parsed.lineNumber,
1273
- parsed.columnNumber,
1274
- );
1275
- }
1276
- }}
1277
- style={{
1278
- flexDirection: 'row',
1279
- alignItems: 'center',
1280
- justifyContent: 'space-between',
1281
- paddingVertical: 5,
1282
- borderBottomWidth: 0.5,
1283
- borderBottomColor: AppColors.dividerColor,
1284
- }}>
1285
- <View style={{flex: 1, minWidth: 0}}>
1286
- <Text
1287
- style={{
1288
- fontFamily: isApp
1289
- ? AppFonts.interBold
1290
- : AppFonts.interRegular,
1291
- fontSize: 10.5,
1292
- color: isApp
1293
- ? AppColors.primaryBlack
1294
- : AppColors.grayTextWeak,
1295
- }}
1296
- numberOfLines={1}>
1297
- {parsed.functionName || 'anonymous'}
1298
- </Text>
1299
- <Text
1300
- style={{
1301
- fontFamily: AppFonts.interRegular,
1302
- fontSize: 9,
1303
- color: isApp
1304
- ? AppColors.sky600
1305
- : AppColors.grayTextWeak,
1306
- }}
1307
- numberOfLines={1}>
1308
- {parsed.fileName}:{parsed.lineNumber || 1}:
1309
- {parsed.columnNumber || 1}
1310
- </Text>
1311
- </View>
1312
- {isApp && (
1313
- <ExternalLinkIcon
1314
- color={AppColors.sky600}
1315
- size={11}
1316
- />
1317
- )}
1318
- </Pressable>
1319
- );
1320
- })}
1321
- </View>
1322
- ) : (
1323
- <View style={reduxDetailStyles.emptyBox}>
1324
- <Text style={reduxDetailStyles.emptyBoxText}>
1325
- No call stack trace captured for this action.
1326
- </Text>
1327
- </View>
1328
- )}
1329
- </ScrollView>
1330
- ) : (
1331
- <View style={{flex: 1, padding: 10}}>
1332
- <JsonViewer
1333
- data={selectedReduxAction}
1334
- forceOpen={true}
1335
- fullHeight={true}
1336
- wrap={true}
1337
- />
1338
- </View>
1339
- )}
1340
- </View>
1341
- );
1342
- }
1343
-
1344
- return (
1345
- <View style={reduxDetailStyles.emptyBox}>
1346
- <TerminalIcon color={AppColors.purple} size={32} />
1347
- <Text style={reduxDetailStyles.emptyBoxTitle}>
1348
- No Redux Slice Selected
1349
- </Text>
1350
- <Text style={reduxDetailStyles.emptyBoxText}>
1351
- Select a slice from the Redux tab to inspect its state and dispatched
1352
- actions.
1353
- </Text>
1354
- </View>
1355
- );
1356
- });
1357
-
1358
- const reduxDetailStyles = StyleSheet.create({
1359
- infoBar: {
1360
- backgroundColor: AppColors.white,
1361
- padding: 12,
1362
- borderBottomWidth: 1,
1363
- borderBottomColor: AppColors.dividerColor,
1364
- },
1365
- infoTopRow: {
1366
- flexDirection: 'row',
1367
- alignItems: 'center',
1368
- justifyContent: 'space-between',
1369
- marginBottom: 8,
1370
- },
1371
- methodBadge: {
1372
- paddingHorizontal: 7,
1373
- paddingVertical: 2.5,
1374
- borderRadius: 5,
1375
- },
1376
- methodBadgeText: {
1377
- fontFamily: AppFonts.interBold,
1378
- fontSize: 9.5,
1379
- color: AppColors.white,
1380
- letterSpacing: 0.4,
1381
- },
1382
- sliceNameText: {
1383
- fontFamily: AppFonts.interBold,
1384
- fontSize: 14,
1385
- color: AppColors.primaryBlack,
1386
- flexShrink: 1,
1387
- },
1388
- persistedChip: {
1389
- flexDirection: 'row',
1390
- alignItems: 'center',
1391
- gap: 3.5,
1392
- backgroundColor: AppColors.mintGreenBg,
1393
- paddingHorizontal: 6,
1394
- paddingVertical: 2,
1395
- borderRadius: 4,
1396
- borderWidth: 1,
1397
- borderColor: AppColors.mintGreenBorder,
1398
- },
1399
- persistedChipText: {
1400
- fontFamily: AppFonts.interBold,
1401
- fontSize: 9,
1402
- color: AppColors.mintGreenText,
1403
- },
1404
- inMemoryChip: {
1405
- backgroundColor: AppColors.indigo50,
1406
- paddingHorizontal: 6,
1407
- paddingVertical: 2,
1408
- borderRadius: 4,
1409
- borderWidth: 1,
1410
- borderColor: AppColors.blueBorder,
1411
- },
1412
- inMemoryChipText: {
1413
- fontFamily: AppFonts.interBold,
1414
- fontSize: 9,
1415
- color: AppColors.indigo600Alt,
1416
- },
1417
- subStatsRow: {
1418
- flexDirection: 'row',
1419
- alignItems: 'center',
1420
- gap: 6,
1421
- flexWrap: 'wrap',
1422
- },
1423
- statPill: {
1424
- flexDirection: 'row',
1425
- alignItems: 'center',
1426
- gap: 4,
1427
- backgroundColor: AppColors.grayBackground,
1428
- paddingHorizontal: 6,
1429
- paddingVertical: 2.5,
1430
- borderRadius: 5,
1431
- borderWidth: 1,
1432
- borderColor: AppColors.dividerColor,
1433
- },
1434
- statPillText: {
1435
- fontFamily: AppFonts.interMedium,
1436
- fontSize: 10,
1437
- color: AppColors.grayText,
1438
- },
1439
- statLabel: {
1440
- fontFamily: AppFonts.interBold,
1441
- fontSize: 10,
1442
- color: AppColors.grayTextWeak,
1443
- },
1444
- statValue: {
1445
- fontFamily: AppFonts.interBold,
1446
- fontSize: 10.5,
1447
- color: AppColors.primaryBlack,
1448
- },
1449
- searchContainer: {
1450
- flexDirection: 'row',
1451
- alignItems: 'center',
1452
- backgroundColor: AppColors.white,
1453
- borderRadius: 8,
1454
- marginHorizontal: 12,
1455
- marginTop: 10,
1456
- paddingHorizontal: 10,
1457
- borderWidth: 1,
1458
- borderColor: AppColors.dividerColor,
1459
- height: 36,
1460
- gap: 8,
1461
- },
1462
- searchInput: {
1463
- flex: 1,
1464
- fontFamily: AppFonts.interRegular,
1465
- fontSize: 12,
1466
- color: AppColors.primaryBlack,
1467
- padding: 0,
1468
- },
1469
- timelineCard: {
1470
- backgroundColor: AppColors.white,
1471
- borderRadius: 10,
1472
- padding: 12,
1473
- marginBottom: 8,
1474
- borderWidth: 1,
1475
- borderColor: AppColors.dividerColor,
1476
- shadowColor: AppColors.primaryBlack,
1477
- shadowOffset: {width: 0, height: 1},
1478
- shadowOpacity: 0.03,
1479
- shadowRadius: 3,
1480
- elevation: 1,
1481
- },
1482
- timelineHeader: {
1483
- flexDirection: 'row',
1484
- alignItems: 'center',
1485
- gap: 8,
1486
- },
1487
- actionBadge: {
1488
- backgroundColor: AppColors.indigo50,
1489
- paddingHorizontal: 6,
1490
- paddingVertical: 2,
1491
- borderRadius: 4,
1492
- borderWidth: 1,
1493
- borderColor: AppColors.blueBorder,
1494
- },
1495
- actionBadgeText: {
1496
- fontFamily: AppFonts.interBold,
1497
- fontSize: 9.5,
1498
- color: AppColors.indigo600Alt,
1499
- },
1500
- actionTitle: {
1501
- flex: 1,
1502
- fontFamily: AppFonts.interBold,
1503
- fontSize: 12.5,
1504
- color: AppColors.primaryBlack,
1505
- },
1506
- timePill: {
1507
- flexDirection: 'row',
1508
- alignItems: 'center',
1509
- gap: 3,
1510
- backgroundColor: `${AppColors.purple}14`,
1511
- paddingHorizontal: 6,
1512
- paddingVertical: 2,
1513
- borderRadius: 4,
1514
- },
1515
- timeText: {
1516
- fontFamily: AppFonts.interMedium,
1517
- fontSize: 10,
1518
- color: AppColors.purple,
1519
- },
1520
- collapsedPrompt: {
1521
- flexDirection: 'row',
1522
- alignItems: 'center',
1523
- justifyContent: 'space-between',
1524
- marginTop: 8,
1525
- paddingTop: 6,
1526
- borderTopWidth: 1,
1527
- borderTopColor: AppColors.dividerColor,
1528
- },
1529
- collapsedPromptText: {
1530
- fontFamily: AppFonts.interRegular,
1531
- fontSize: 10.5,
1532
- color: AppColors.grayTextWeak,
1533
- },
1534
- expandedContent: {
1535
- marginTop: 10,
1536
- paddingTop: 10,
1537
- borderTopWidth: 1,
1538
- borderTopColor: AppColors.dividerColor,
1539
- },
1540
- expandedSectionTitle: {
1541
- fontFamily: AppFonts.interBold,
1542
- fontSize: 11,
1543
- color: AppColors.grayTextStrong,
1544
- marginBottom: 6,
1545
- },
1546
- metadataCard: {
1547
- backgroundColor: AppColors.white,
1548
- borderRadius: 12,
1549
- padding: 12,
1550
- borderWidth: 1,
1551
- borderColor: AppColors.dividerColor,
1552
- shadowColor: AppColors.primaryBlack,
1553
- shadowOffset: {width: 0, height: 1},
1554
- shadowOpacity: 0.03,
1555
- shadowRadius: 3,
1556
- elevation: 1,
1557
- },
1558
- metaRow: {
1559
- flexDirection: 'row',
1560
- justifyContent: 'space-between',
1561
- alignItems: 'center',
1562
- paddingVertical: 10,
1563
- borderBottomWidth: 1,
1564
- borderBottomColor: AppColors.dividerColor,
1565
- },
1566
- metaLabel: {
1567
- fontFamily: AppFonts.interMedium,
1568
- fontSize: 12,
1569
- color: AppColors.grayTextWeak,
1570
- },
1571
- metaValue: {
1572
- fontFamily: AppFonts.interBold,
1573
- fontSize: 12,
1574
- color: AppColors.primaryBlack,
1575
- maxWidth: '60%',
1576
- textAlign: 'right',
1577
- },
1578
- persistedInfoCard: {
1579
- backgroundColor: AppColors.mintGreenBg,
1580
- borderRadius: 8,
1581
- borderWidth: 1,
1582
- borderColor: AppColors.mintGreenBorder,
1583
- padding: 10,
1584
- },
1585
- persistedInfoTitle: {
1586
- fontFamily: AppFonts.interBold,
1587
- fontSize: 11,
1588
- color: AppColors.mintGreenText,
1589
- },
1590
- clearPersistMiniBtn: {
1591
- flexDirection: 'row',
1592
- alignItems: 'center',
1593
- gap: 3,
1594
- backgroundColor: AppColors.errorCardBg,
1595
- paddingHorizontal: 6,
1596
- paddingVertical: 2.5,
1597
- borderRadius: 4,
1598
- },
1599
- clearPersistMiniText: {
1600
- fontFamily: AppFonts.interBold,
1601
- fontSize: 9.5,
1602
- color: AppColors.errorColor,
1603
- },
1604
- clearPersistBtn: {
1605
- flexDirection: 'row',
1606
- alignItems: 'center',
1607
- justifyContent: 'center',
1608
- gap: 6,
1609
- backgroundColor: AppColors.errorCardBg,
1610
- borderWidth: 1,
1611
- borderColor: AppColors.errorBorder,
1612
- borderRadius: 8,
1613
- paddingVertical: 10,
1614
- marginTop: 14,
1615
- },
1616
- clearPersistText: {
1617
- fontFamily: AppFonts.interBold,
1618
- fontSize: 12,
1619
- color: AppColors.errorColor,
1620
- },
1621
- emptyBox: {
1622
- backgroundColor: AppColors.white,
1623
- borderRadius: 12,
1624
- padding: 24,
1625
- alignItems: 'center',
1626
- justifyContent: 'center',
1627
- borderWidth: 1,
1628
- borderColor: AppColors.dividerColor,
1629
- margin: 12,
1630
- gap: 8,
1631
- },
1632
- emptyBoxTitle: {
1633
- fontFamily: AppFonts.interBold,
1634
- fontSize: 14,
1635
- color: AppColors.primaryBlack,
1636
- },
1637
- emptyBoxText: {
1638
- fontFamily: AppFonts.interMedium,
1639
- fontSize: 12,
1640
- color: AppColors.grayTextWeak,
1641
- textAlign: 'center',
1642
- lineHeight: 18,
1643
- },
1644
- highlight: {
1645
- backgroundColor: AppColors.yellowHighlight,
1646
- color: AppColors.amber800Warm,
1647
- fontFamily: AppFonts.interBold,
1648
- },
1649
- });
1650
-
1651
- export default ReduxDetail;