react-native-inapp-inspector 1.1.13 → 1.1.15

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 (250) hide show
  1. package/README.md +9 -34
  2. package/dist/commonjs/assets/svgAssets.d.ts +3 -0
  3. package/dist/commonjs/assets/svgAssets.js +17 -0
  4. package/dist/commonjs/components/AnalyticsEventCard.d.ts +1 -14
  5. package/dist/commonjs/components/AnalyticsEventCard.js +120 -50
  6. package/dist/commonjs/components/AnalyticsGraph.d.ts +2 -6
  7. package/dist/commonjs/components/AnalyticsGraph.js +8 -8
  8. package/dist/commonjs/components/AnalyticsTabView.d.ts +15 -0
  9. package/dist/commonjs/components/AnalyticsTabView.js +157 -0
  10. package/dist/commonjs/components/AnimatedEntrance.d.ts +1 -1
  11. package/dist/commonjs/components/AnimatedEntrance.js +2 -2
  12. package/dist/commonjs/components/ApiDetailView.d.ts +22 -0
  13. package/dist/commonjs/components/ApiDetailView.js +304 -0
  14. package/dist/commonjs/components/ApisTabView.d.ts +33 -0
  15. package/dist/commonjs/components/ApisTabView.js +235 -0
  16. package/dist/commonjs/components/CodeSnippet.d.ts +1 -5
  17. package/dist/commonjs/components/CodeSnippet.js +34 -34
  18. package/dist/commonjs/components/ConsoleLogCard.d.ts +1 -8
  19. package/dist/commonjs/components/ConsoleLogCard.js +262 -442
  20. package/dist/commonjs/components/ConsoleLogDetailView.d.ts +9 -0
  21. package/dist/commonjs/components/ConsoleLogDetailView.js +278 -0
  22. package/dist/commonjs/components/ConsoleLogsTabView.d.ts +24 -0
  23. package/dist/commonjs/components/ConsoleLogsTabView.js +354 -0
  24. package/dist/commonjs/components/DiffViewer.js +4 -2
  25. package/dist/commonjs/components/DomainHeader.js +66 -41
  26. package/dist/commonjs/components/EmptyState.d.ts +2 -2
  27. package/dist/commonjs/components/EmptyState.js +2 -2
  28. package/dist/commonjs/components/EndOfListFooter.d.ts +8 -0
  29. package/dist/commonjs/components/EndOfListFooter.js +90 -0
  30. package/dist/commonjs/components/ErrorBoundary.d.ts +5 -14
  31. package/dist/commonjs/components/ErrorBoundary.js +28 -28
  32. package/dist/commonjs/components/FloatingBubble.d.ts +14 -0
  33. package/dist/commonjs/components/FloatingBubble.js +75 -0
  34. package/dist/commonjs/components/HeadersSection.js +5 -3
  35. package/dist/commonjs/components/HighlightText.d.ts +1 -1
  36. package/dist/commonjs/components/HighlightText.js +5 -7
  37. package/dist/commonjs/components/Inspector/AnalyticsTab.d.ts +3 -0
  38. package/dist/commonjs/components/Inspector/AnalyticsTab.js +232 -0
  39. package/dist/commonjs/components/Inspector/ConsoleTab.d.ts +3 -0
  40. package/dist/commonjs/components/Inspector/ConsoleTab.js +410 -0
  41. package/dist/commonjs/components/Inspector/FabLauncher.d.ts +3 -0
  42. package/dist/commonjs/components/Inspector/FabLauncher.js +54 -0
  43. package/dist/commonjs/components/Inspector/InsightsDashboard.d.ts +3 -0
  44. package/dist/commonjs/components/Inspector/InsightsDashboard.js +619 -0
  45. package/dist/commonjs/components/Inspector/InspectorContext.d.ts +5 -0
  46. package/dist/commonjs/components/Inspector/InspectorContext.js +18 -0
  47. package/dist/commonjs/components/Inspector/InspectorHeader.d.ts +3 -0
  48. package/dist/commonjs/components/Inspector/InspectorHeader.js +452 -0
  49. package/dist/commonjs/components/Inspector/LogDetail.d.ts +3 -0
  50. package/dist/commonjs/components/Inspector/LogDetail.js +963 -0
  51. package/dist/commonjs/components/Inspector/MainScreen.d.ts +3 -0
  52. package/dist/commonjs/components/Inspector/MainScreen.js +68 -0
  53. package/dist/commonjs/components/Inspector/NavigationTracker.d.ts +3 -0
  54. package/dist/commonjs/components/Inspector/NavigationTracker.js +12 -0
  55. package/dist/commonjs/components/Inspector/NetworkDetail.d.ts +3 -0
  56. package/dist/commonjs/components/Inspector/NetworkDetail.js +405 -0
  57. package/dist/commonjs/components/Inspector/NetworkTab.d.ts +3 -0
  58. package/dist/commonjs/components/Inspector/NetworkTab.js +281 -0
  59. package/dist/commonjs/components/Inspector/ReduxTab.d.ts +3 -0
  60. package/dist/commonjs/components/Inspector/ReduxTab.js +75 -0
  61. package/dist/commonjs/components/Inspector/SettingsPanel.d.ts +3 -0
  62. package/dist/commonjs/components/Inspector/SettingsPanel.js +1476 -0
  63. package/dist/commonjs/components/Inspector/TabBar.d.ts +3 -0
  64. package/dist/commonjs/components/Inspector/TabBar.js +95 -0
  65. package/dist/commonjs/components/Inspector/WebViewTab.d.ts +3 -0
  66. package/dist/commonjs/components/Inspector/WebViewTab.js +757 -0
  67. package/dist/commonjs/components/InspectorHeader.d.ts +19 -0
  68. package/dist/commonjs/components/InspectorHeader.js +329 -0
  69. package/dist/commonjs/components/InspectorTabBar.d.ts +16 -0
  70. package/dist/commonjs/components/InspectorTabBar.js +90 -0
  71. package/dist/commonjs/components/JsonViewer.d.ts +4 -1
  72. package/dist/commonjs/components/JsonViewer.js +110 -171
  73. package/dist/commonjs/components/LogCard.js +109 -86
  74. package/dist/commonjs/components/MetaAccordion.d.ts +1 -10
  75. package/dist/commonjs/components/MetaAccordion.js +23 -21
  76. package/dist/commonjs/components/NavigationTracker.d.ts +7 -0
  77. package/dist/commonjs/components/NavigationTracker.js +76 -0
  78. package/dist/commonjs/components/NetworkIcons.d.ts +6 -0
  79. package/dist/commonjs/components/NetworkIcons.js +54 -8
  80. package/dist/commonjs/components/ReduxTabView.d.ts +9 -0
  81. package/dist/commonjs/components/ReduxTabView.js +56 -0
  82. package/dist/commonjs/components/ReduxTreeView.js +241 -200
  83. package/dist/commonjs/components/SegmentedTabs.d.ts +15 -0
  84. package/dist/commonjs/components/SegmentedTabs.js +52 -0
  85. package/dist/commonjs/components/SettingsView.d.ts +13 -0
  86. package/dist/commonjs/components/SettingsView.js +328 -0
  87. package/dist/commonjs/components/TouchableScale.d.ts +2 -2
  88. package/dist/commonjs/components/TouchableScale.js +2 -2
  89. package/dist/commonjs/components/TreeNode.js +2 -2
  90. package/dist/commonjs/constants/index.js +1 -12
  91. package/dist/commonjs/constants/version.d.ts +1 -1
  92. package/dist/commonjs/constants/version.js +1 -1
  93. package/dist/commonjs/customHooks/analyticsLogger.d.ts +8 -0
  94. package/dist/commonjs/customHooks/analyticsLogger.js +42 -1
  95. package/dist/commonjs/customHooks/consoleLogger.js +137 -13
  96. package/dist/commonjs/customHooks/networkLogger.d.ts +0 -1
  97. package/dist/commonjs/customHooks/networkLogger.js +0 -1
  98. package/dist/commonjs/customHooks/reduxLogger.d.ts +2 -9
  99. package/dist/commonjs/enums/index.d.ts +39 -0
  100. package/dist/commonjs/enums/index.js +50 -0
  101. package/dist/commonjs/helpers/index.d.ts +27 -1
  102. package/dist/commonjs/helpers/index.js +187 -12
  103. package/dist/commonjs/helpers/settingsStore.d.ts +2 -24
  104. package/dist/commonjs/i18n/en.json +144 -0
  105. package/dist/commonjs/i18n/index.d.ts +2 -0
  106. package/dist/commonjs/i18n/index.js +27 -0
  107. package/dist/commonjs/i18n/locales/en.json +314 -0
  108. package/dist/commonjs/index.d.ts +2 -3
  109. package/dist/commonjs/index.js +207 -4927
  110. package/dist/commonjs/styles/AppColors.d.ts +148 -0
  111. package/dist/commonjs/styles/AppColors.js +176 -0
  112. package/dist/commonjs/styles/common.d.ts +3 -0
  113. package/dist/commonjs/styles/common.js +201 -0
  114. package/dist/commonjs/styles/index.d.ts +219 -435
  115. package/dist/commonjs/styles/index.js +312 -488
  116. package/dist/commonjs/types/enums.d.ts +9 -0
  117. package/dist/commonjs/types/enums.js +4 -0
  118. package/dist/commonjs/types/index.d.ts +4 -111
  119. package/dist/commonjs/types/index.js +16 -0
  120. package/dist/commonjs/types/interfaces.d.ts +337 -0
  121. package/dist/commonjs/types/interfaces.js +2 -0
  122. package/dist/esm/assets/svgAssets.d.ts +3 -0
  123. package/dist/esm/assets/svgAssets.js +14 -0
  124. package/dist/esm/components/AnalyticsEventCard.d.ts +1 -14
  125. package/dist/esm/components/AnalyticsEventCard.js +118 -48
  126. package/dist/esm/components/AnalyticsGraph.d.ts +2 -6
  127. package/dist/esm/components/AnalyticsGraph.js +8 -8
  128. package/dist/esm/components/AnalyticsTabView.d.ts +15 -0
  129. package/dist/esm/components/AnalyticsTabView.js +151 -0
  130. package/dist/esm/components/AnimatedEntrance.d.ts +1 -1
  131. package/dist/esm/components/AnimatedEntrance.js +2 -2
  132. package/dist/esm/components/ApiDetailView.d.ts +22 -0
  133. package/dist/esm/components/ApiDetailView.js +264 -0
  134. package/dist/esm/components/ApisTabView.d.ts +33 -0
  135. package/dist/esm/components/ApisTabView.js +196 -0
  136. package/dist/esm/components/CodeSnippet.d.ts +1 -5
  137. package/dist/esm/components/CodeSnippet.js +34 -34
  138. package/dist/esm/components/ConsoleLogCard.d.ts +1 -8
  139. package/dist/esm/components/ConsoleLogCard.js +262 -409
  140. package/dist/esm/components/ConsoleLogDetailView.d.ts +9 -0
  141. package/dist/esm/components/ConsoleLogDetailView.js +271 -0
  142. package/dist/esm/components/ConsoleLogsTabView.d.ts +24 -0
  143. package/dist/esm/components/ConsoleLogsTabView.js +348 -0
  144. package/dist/esm/components/DiffViewer.js +4 -2
  145. package/dist/esm/components/DomainHeader.js +66 -41
  146. package/dist/esm/components/EmptyState.d.ts +2 -2
  147. package/dist/esm/components/EmptyState.js +2 -2
  148. package/dist/esm/components/EndOfListFooter.d.ts +8 -0
  149. package/dist/esm/components/EndOfListFooter.js +83 -0
  150. package/dist/esm/components/ErrorBoundary.d.ts +5 -14
  151. package/dist/esm/components/ErrorBoundary.js +29 -29
  152. package/dist/esm/components/FloatingBubble.d.ts +14 -0
  153. package/dist/esm/components/FloatingBubble.js +68 -0
  154. package/dist/esm/components/HeadersSection.js +5 -3
  155. package/dist/esm/components/HighlightText.d.ts +1 -1
  156. package/dist/esm/components/HighlightText.js +5 -7
  157. package/dist/esm/components/Inspector/AnalyticsTab.d.ts +3 -0
  158. package/dist/esm/components/Inspector/AnalyticsTab.js +194 -0
  159. package/dist/esm/components/Inspector/ConsoleTab.d.ts +3 -0
  160. package/dist/esm/components/Inspector/ConsoleTab.js +372 -0
  161. package/dist/esm/components/Inspector/FabLauncher.d.ts +3 -0
  162. package/dist/esm/components/Inspector/FabLauncher.js +49 -0
  163. package/dist/esm/components/Inspector/InsightsDashboard.d.ts +3 -0
  164. package/dist/esm/components/Inspector/InsightsDashboard.js +614 -0
  165. package/dist/esm/components/Inspector/InspectorContext.d.ts +5 -0
  166. package/dist/esm/components/Inspector/InspectorContext.js +13 -0
  167. package/dist/esm/components/Inspector/InspectorHeader.d.ts +3 -0
  168. package/dist/esm/components/Inspector/InspectorHeader.js +447 -0
  169. package/dist/esm/components/Inspector/LogDetail.d.ts +3 -0
  170. package/dist/esm/components/Inspector/LogDetail.js +925 -0
  171. package/dist/esm/components/Inspector/MainScreen.d.ts +3 -0
  172. package/dist/esm/components/Inspector/MainScreen.js +63 -0
  173. package/dist/esm/components/Inspector/NavigationTracker.d.ts +3 -0
  174. package/dist/esm/components/Inspector/NavigationTracker.js +10 -0
  175. package/dist/esm/components/Inspector/NetworkDetail.d.ts +3 -0
  176. package/dist/esm/components/Inspector/NetworkDetail.js +367 -0
  177. package/dist/esm/components/Inspector/NetworkTab.d.ts +3 -0
  178. package/dist/esm/components/Inspector/NetworkTab.js +243 -0
  179. package/dist/esm/components/Inspector/ReduxTab.d.ts +3 -0
  180. package/dist/esm/components/Inspector/ReduxTab.js +70 -0
  181. package/dist/esm/components/Inspector/SettingsPanel.d.ts +3 -0
  182. package/dist/esm/components/Inspector/SettingsPanel.js +1438 -0
  183. package/dist/esm/components/Inspector/TabBar.d.ts +3 -0
  184. package/dist/esm/components/Inspector/TabBar.js +90 -0
  185. package/dist/esm/components/Inspector/WebViewTab.d.ts +3 -0
  186. package/dist/esm/components/Inspector/WebViewTab.js +752 -0
  187. package/dist/esm/components/InspectorHeader.d.ts +19 -0
  188. package/dist/esm/components/InspectorHeader.js +323 -0
  189. package/dist/esm/components/InspectorTabBar.d.ts +16 -0
  190. package/dist/esm/components/InspectorTabBar.js +84 -0
  191. package/dist/esm/components/JsonViewer.d.ts +4 -1
  192. package/dist/esm/components/JsonViewer.js +111 -172
  193. package/dist/esm/components/LogCard.js +111 -88
  194. package/dist/esm/components/MetaAccordion.d.ts +1 -10
  195. package/dist/esm/components/MetaAccordion.js +23 -21
  196. package/dist/esm/components/NavigationTracker.d.ts +7 -0
  197. package/dist/esm/components/NavigationTracker.js +39 -0
  198. package/dist/esm/components/NetworkIcons.d.ts +6 -0
  199. package/dist/esm/components/NetworkIcons.js +46 -6
  200. package/dist/esm/components/ReduxTabView.d.ts +9 -0
  201. package/dist/esm/components/ReduxTabView.js +50 -0
  202. package/dist/esm/components/ReduxTreeView.js +243 -202
  203. package/dist/esm/components/SegmentedTabs.d.ts +15 -0
  204. package/dist/esm/components/SegmentedTabs.js +47 -0
  205. package/dist/esm/components/SettingsView.d.ts +13 -0
  206. package/dist/esm/components/SettingsView.js +321 -0
  207. package/dist/esm/components/TouchableScale.d.ts +2 -2
  208. package/dist/esm/components/TouchableScale.js +2 -2
  209. package/dist/esm/components/TreeNode.js +2 -2
  210. package/dist/esm/constants/index.js +1 -12
  211. package/dist/esm/constants/version.d.ts +1 -1
  212. package/dist/esm/constants/version.js +1 -1
  213. package/dist/esm/customHooks/analyticsLogger.d.ts +8 -0
  214. package/dist/esm/customHooks/analyticsLogger.js +37 -0
  215. package/dist/esm/customHooks/consoleLogger.js +137 -13
  216. package/dist/esm/customHooks/networkLogger.d.ts +0 -1
  217. package/dist/esm/customHooks/networkLogger.js +0 -1
  218. package/dist/esm/customHooks/reduxLogger.d.ts +2 -9
  219. package/dist/esm/enums/index.d.ts +39 -0
  220. package/dist/esm/enums/index.js +47 -0
  221. package/dist/esm/helpers/index.d.ts +27 -1
  222. package/dist/esm/helpers/index.js +180 -11
  223. package/dist/esm/helpers/settingsStore.d.ts +2 -24
  224. package/dist/esm/i18n/en.json +144 -0
  225. package/dist/esm/i18n/index.d.ts +2 -0
  226. package/dist/esm/i18n/index.js +22 -0
  227. package/dist/esm/i18n/locales/en.json +314 -0
  228. package/dist/esm/index.d.ts +2 -3
  229. package/dist/esm/index.js +207 -4923
  230. package/dist/esm/styles/AppColors.d.ts +148 -0
  231. package/dist/esm/styles/AppColors.js +176 -0
  232. package/dist/esm/styles/common.d.ts +3 -0
  233. package/dist/esm/styles/common.js +197 -0
  234. package/dist/esm/styles/index.d.ts +219 -435
  235. package/dist/esm/styles/index.js +312 -488
  236. package/dist/esm/types/enums.d.ts +9 -0
  237. package/dist/esm/types/enums.js +3 -0
  238. package/dist/esm/types/index.d.ts +4 -111
  239. package/dist/esm/types/index.js +2 -1
  240. package/dist/esm/types/interfaces.d.ts +337 -0
  241. package/dist/esm/types/interfaces.js +1 -0
  242. package/example/App.tsx +88 -1
  243. package/example/android/app/build.gradle +29 -1
  244. package/example/android/app/src/main/java/com/example/MainApplication.kt +25 -0
  245. package/example/android/build.gradle +31 -4
  246. package/example/android/gradle/wrapper/gradle-wrapper.properties +1 -1
  247. package/example/android/gradle.properties +1 -0
  248. package/example/android/settings.gradle +20 -1
  249. package/example/package-lock.json +1 -1
  250. package/package.json +3 -1
@@ -0,0 +1,752 @@
1
+ import React from 'react';
2
+ import { ActivityIndicator, FlatList, Linking, Pressable, ScrollView, Text, View, } from 'react-native';
3
+ import { animateNextLayout, useInspector } from './InspectorContext';
4
+ import TouchableScale from '../TouchableScale';
5
+ import AnimatedEntrance from '../AnimatedEntrance';
6
+ import EmptyState from '../EmptyState';
7
+ import HighlightText from '../HighlightText';
8
+ import CodeSnippet from '../CodeSnippet';
9
+ import CopyButton from '../CopyButton';
10
+ import styles from '../../styles';
11
+ import { AppColors } from '../../styles/AppColors';
12
+ import { AppFonts } from '../../styles/AppFonts';
13
+ import { clearWebViewData } from '../../customHooks/webViewLogger';
14
+ import { GlobeIcon, EyeIcon, HtmlIcon, ClockIcon, TerminalIcon, CssIcon, JsIcon, TrashIcon, } from '../NetworkIcons';
15
+ let OriginalWebView = null;
16
+ try {
17
+ const RNWebView = require('react-native-webview');
18
+ OriginalWebView = RNWebView.WebView || RNWebView.default;
19
+ }
20
+ catch (e) {
21
+ // Silent fail
22
+ }
23
+ const previewInspectScript = `
24
+ (function() {
25
+ var style = document.createElement('style');
26
+ style.innerHTML = '* { cursor: pointer !important; }';
27
+ document.head.appendChild(style);
28
+
29
+ document.addEventListener('click', function(e) {
30
+ var el = e.target;
31
+ if (!el) return;
32
+
33
+ e.preventDefault();
34
+ e.stopPropagation();
35
+
36
+ var oldOutline = el.style.outline;
37
+ var oldTransition = el.style.transition;
38
+ el.style.transition = 'outline 0.15s ease';
39
+ el.style.outline = '3px solid #684B9B';
40
+ setTimeout(function() {
41
+ el.style.outline = oldOutline;
42
+ el.style.transition = oldTransition;
43
+ }, 600);
44
+
45
+ var tagName = el.tagName.toLowerCase();
46
+ var searchStr = '<' + tagName;
47
+
48
+ if (el.id) {
49
+ searchStr += ' id="' + el.id + '"';
50
+ } else if (el.className && typeof el.className === 'string') {
51
+ var firstClass = el.className.trim().split(/\\s+/)[0];
52
+ if (firstClass) {
53
+ searchStr += ' class="' + firstClass;
54
+ }
55
+ } else {
56
+ var text = (el.textContent || '').trim().substring(0, 25);
57
+ if (text) {
58
+ searchStr = text;
59
+ }
60
+ }
61
+
62
+ if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
63
+ window.ReactNativeWebView.postMessage(JSON.stringify({
64
+ type: 'preview-inspect',
65
+ tagName: tagName,
66
+ id: el.id || '',
67
+ className: typeof el.className === 'string' ? el.className : '',
68
+ searchStr: searchStr
69
+ }));
70
+ }
71
+ }, true);
72
+ })();
73
+ true;
74
+ `;
75
+ const WebViewTab = () => {
76
+ const { webViewNavHistory, webViewSearch, webViewSubTab, setWebViewSubTab, webViewLogs, webViewHtml, webViewCss, webViewJs, webViewHtmlUrl, htmlSubTab, setHtmlSubTab, isHtmlTabReady, inspectedElement, setInspectedElement, getSearchTermForTab, filteredNavHistory, isDark, } = useInspector();
77
+ if (webViewNavHistory.length === 0) {
78
+ return (<View style={styles.emptyContainer}>
79
+ <View style={styles.emptyIconWrap}>
80
+ <GlobeIcon color={AppColors.purple} size={32}/>
81
+ </View>
82
+ <Text style={styles.emptyTitle}>
83
+ No WebView Activity
84
+ </Text>
85
+ <Text style={styles.emptySub}>
86
+ Load a webpage within a connected WebView component to
87
+ inspect pages, page source, and console logs.
88
+ </Text>
89
+ </View>);
90
+ }
91
+ return (<View style={{ flex: 1 }}>
92
+ {/* ─── Current Page Address Bar (Now on top) ─── */}
93
+ {(() => {
94
+ const currentUrl = webViewNavHistory[0]?.url;
95
+ if (!currentUrl)
96
+ return null;
97
+ return (<View style={{
98
+ paddingHorizontal: 12,
99
+ paddingTop: 6,
100
+ paddingBottom: 6,
101
+ backgroundColor: AppColors.primaryLight,
102
+ borderBottomWidth: 1,
103
+ borderBottomColor: AppColors.dividerColor,
104
+ }}>
105
+ <View style={{
106
+ flexDirection: 'row',
107
+ alignItems: 'center',
108
+ backgroundColor: AppColors.grayBackground,
109
+ borderRadius: 8,
110
+ borderWidth: 1.5,
111
+ borderColor: AppColors.grayBorderSecondary,
112
+ paddingHorizontal: 10,
113
+ paddingVertical: 5,
114
+ gap: 8,
115
+ }}>
116
+ {/* Left: Lock and HTTPS label */}
117
+ <View style={{
118
+ flexDirection: 'row',
119
+ alignItems: 'center',
120
+ gap: 4,
121
+ }}>
122
+ <Text style={{ fontSize: 11 }}>🔒</Text>
123
+ <Text style={{
124
+ fontFamily: AppFonts.interBold,
125
+ fontSize: 9.5,
126
+ color: AppColors.greenColor,
127
+ letterSpacing: 0.5,
128
+ }}>
129
+ HTTPS
130
+ </Text>
131
+ </View>
132
+ <View style={{
133
+ width: 1.5,
134
+ height: 12,
135
+ backgroundColor: AppColors.grayBorderSecondary,
136
+ }}/>
137
+
138
+ {/* Middle: URL text (Address style) */}
139
+ <View style={{ flex: 1 }}>
140
+ <HighlightText text={currentUrl} search={webViewSearch} numberOfLines={1} ellipsizeMode="tail" style={{
141
+ fontFamily: AppFonts.interMedium,
142
+ fontSize: 11.5,
143
+ color: AppColors.primaryBlack,
144
+ }} highlightStyle={styles.highlight} detectLinks={false}/>
145
+ </View>
146
+
147
+ {/* Right: Copy Button */}
148
+ <CopyButton value={currentUrl} label="URL"/>
149
+
150
+ {/* Right: Globe Icon button to open browser */}
151
+ <TouchableScale onPress={() => Linking.openURL(currentUrl)} hitSlop={8} style={{
152
+ width: 26,
153
+ height: 26,
154
+ borderRadius: 13,
155
+ backgroundColor: AppColors.grayBackground,
156
+ borderWidth: 1,
157
+ borderColor: AppColors.grayBorderSecondary,
158
+ alignItems: 'center',
159
+ justifyContent: 'center',
160
+ }}>
161
+ <GlobeIcon size={11} color={AppColors.purple}/>
162
+ </TouchableScale>
163
+ </View>
164
+ </View>);
165
+ })()}
166
+
167
+ {/* ─── WebView Sub-Tabs (Now below Address Bar) ─── */}
168
+ <View style={{
169
+ backgroundColor: AppColors.primaryLight,
170
+ borderBottomWidth: 1,
171
+ borderBottomColor: AppColors.dividerColor,
172
+ paddingVertical: 6,
173
+ }}>
174
+ <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{
175
+ paddingHorizontal: 12,
176
+ flexDirection: 'row',
177
+ gap: 8,
178
+ }}>
179
+ {/* Sub-tab 1: Preview */}
180
+ <Pressable style={[
181
+ {
182
+ paddingVertical: 6,
183
+ paddingHorizontal: 14,
184
+ borderRadius: 8,
185
+ alignItems: 'center',
186
+ flexDirection: 'row',
187
+ gap: 6,
188
+ backgroundColor: 'rgba(0, 0, 0, 0.03)',
189
+ borderWidth: 1,
190
+ borderColor: 'transparent',
191
+ },
192
+ webViewSubTab === 'preview' && {
193
+ backgroundColor: AppColors.purple,
194
+ borderColor: AppColors.purple,
195
+ },
196
+ ]} onPress={() => {
197
+ animateNextLayout();
198
+ setWebViewSubTab('preview');
199
+ }}>
200
+ <EyeIcon color={webViewSubTab === 'preview'
201
+ ? '#FFFFFF'
202
+ : AppColors.grayTextWeak} size={13}/>
203
+ <Text style={{
204
+ fontFamily: webViewSubTab === 'preview'
205
+ ? AppFonts.interBold
206
+ : AppFonts.interMedium,
207
+ fontSize: 12,
208
+ color: webViewSubTab === 'preview'
209
+ ? '#FFFFFF'
210
+ : AppColors.grayTextStrong,
211
+ }}>
212
+ Preview
213
+ </Text>
214
+ </Pressable>
215
+
216
+ {/* Sub-tab 2: Page Source */}
217
+ <Pressable style={[
218
+ {
219
+ paddingVertical: 6,
220
+ paddingHorizontal: 14,
221
+ borderRadius: 8,
222
+ alignItems: 'center',
223
+ flexDirection: 'row',
224
+ gap: 6,
225
+ backgroundColor: 'rgba(0, 0, 0, 0.03)',
226
+ borderWidth: 1,
227
+ borderColor: 'transparent',
228
+ },
229
+ webViewSubTab === 'html' && {
230
+ backgroundColor: AppColors.purple,
231
+ borderColor: AppColors.purple,
232
+ },
233
+ ]} onPress={() => {
234
+ animateNextLayout();
235
+ setWebViewSubTab('html');
236
+ }}>
237
+ <HtmlIcon color={webViewSubTab === 'html'
238
+ ? '#FFFFFF'
239
+ : AppColors.grayTextWeak} size={13}/>
240
+ <Text style={{
241
+ fontFamily: webViewSubTab === 'html'
242
+ ? AppFonts.interBold
243
+ : AppFonts.interMedium,
244
+ fontSize: 12,
245
+ color: webViewSubTab === 'html'
246
+ ? '#FFFFFF'
247
+ : AppColors.grayTextStrong,
248
+ }}>
249
+ Page Source
250
+ </Text>
251
+ </Pressable>
252
+
253
+ {/* Sub-tab 3: History */}
254
+ <Pressable style={[
255
+ {
256
+ paddingVertical: 6,
257
+ paddingHorizontal: 14,
258
+ borderRadius: 8,
259
+ alignItems: 'center',
260
+ flexDirection: 'row',
261
+ gap: 6,
262
+ backgroundColor: 'rgba(0, 0, 0, 0.03)',
263
+ borderWidth: 1,
264
+ borderColor: 'transparent',
265
+ },
266
+ webViewSubTab === 'navigation' && {
267
+ backgroundColor: AppColors.purple,
268
+ borderColor: AppColors.purple,
269
+ },
270
+ ]} onPress={() => {
271
+ animateNextLayout();
272
+ setWebViewSubTab('navigation');
273
+ }}>
274
+ <ClockIcon color={webViewSubTab === 'navigation'
275
+ ? '#FFFFFF'
276
+ : AppColors.grayTextWeak} size={13}/>
277
+ <Text style={{
278
+ fontFamily: webViewSubTab === 'navigation'
279
+ ? AppFonts.interBold
280
+ : AppFonts.interMedium,
281
+ fontSize: 12,
282
+ color: webViewSubTab === 'navigation'
283
+ ? '#FFFFFF'
284
+ : AppColors.grayTextStrong,
285
+ }}>
286
+ History ({webViewNavHistory.length})
287
+ </Text>
288
+ </Pressable>
289
+
290
+ {/* Sub-tab 4: Console */}
291
+ <Pressable style={[
292
+ {
293
+ paddingVertical: 6,
294
+ paddingHorizontal: 14,
295
+ borderRadius: 8,
296
+ alignItems: 'center',
297
+ flexDirection: 'row',
298
+ gap: 6,
299
+ backgroundColor: 'rgba(0, 0, 0, 0.03)',
300
+ borderWidth: 1,
301
+ borderColor: 'transparent',
302
+ },
303
+ webViewSubTab === 'console' && {
304
+ backgroundColor: AppColors.purple,
305
+ borderColor: AppColors.purple,
306
+ },
307
+ ]} onPress={() => {
308
+ animateNextLayout();
309
+ setWebViewSubTab('console');
310
+ }}>
311
+ <TerminalIcon color={webViewSubTab === 'console'
312
+ ? '#FFFFFF'
313
+ : AppColors.grayTextWeak} size={13}/>
314
+ <Text style={{
315
+ fontFamily: webViewSubTab === 'console'
316
+ ? AppFonts.interBold
317
+ : AppFonts.interMedium,
318
+ fontSize: 12,
319
+ color: webViewSubTab === 'console'
320
+ ? '#FFFFFF'
321
+ : AppColors.grayTextStrong,
322
+ }}>
323
+ Console ({webViewLogs.length})
324
+ </Text>
325
+ </Pressable>
326
+ </ScrollView>
327
+ </View>
328
+
329
+ {webViewSubTab === 'html' ? (<View style={{ flex: 1 }}>
330
+ {webViewHtml || webViewCss || webViewJs ? (<View style={{ flex: 1 }}>
331
+ {/* Clear Inspect Banner */}
332
+ {inspectedElement && (<View style={{
333
+ flexDirection: 'row',
334
+ alignItems: 'center',
335
+ justifyContent: 'space-between',
336
+ backgroundColor: AppColors.purpleShade50,
337
+ paddingHorizontal: 12,
338
+ paddingVertical: 6,
339
+ borderBottomWidth: 1,
340
+ borderBottomColor: AppColors.dividerColor,
341
+ }}>
342
+ <Text style={{
343
+ fontFamily: AppFonts.interMedium,
344
+ fontSize: 11.5,
345
+ color: AppColors.purple,
346
+ flex: 1,
347
+ }}>
348
+ Inspecting element:{' '}
349
+ <Text style={{
350
+ fontFamily: AppFonts.interBold,
351
+ }}>
352
+ &lt;{inspectedElement.tagName}
353
+ {inspectedElement.id
354
+ ? ` id="${inspectedElement.id}"`
355
+ : ''}
356
+ {inspectedElement.className
357
+ ? ` class="${inspectedElement.className
358
+ .trim()
359
+ .split(/\s+/)[0]}"`
360
+ : ''}
361
+ &gt;
362
+ </Text>
363
+ </Text>
364
+ <Pressable onPress={() => setInspectedElement(null)} style={{
365
+ paddingHorizontal: 8,
366
+ paddingVertical: 4,
367
+ }}>
368
+ <Text style={{
369
+ fontFamily: AppFonts.interBold,
370
+ fontSize: 11,
371
+ color: AppColors.purple,
372
+ }}>
373
+ Clear Inspect
374
+ </Text>
375
+ </Pressable>
376
+ </View>)}
377
+
378
+ {/* Inner sub-tabs inside HTML source view */}
379
+ <View style={{
380
+ flexDirection: 'row',
381
+ borderBottomWidth: 1,
382
+ borderBottomColor: AppColors.dividerColor,
383
+ backgroundColor: AppColors.primaryLight,
384
+ paddingHorizontal: 12,
385
+ gap: 12,
386
+ }}>
387
+ {['html', 'css', 'javascript'].map(tab => {
388
+ const active = htmlSubTab === tab;
389
+ const label = tab === 'html'
390
+ ? 'HTML'
391
+ : tab === 'css'
392
+ ? 'CSS'
393
+ : 'JavaScript';
394
+ const activeColor = tab === 'html'
395
+ ? '#EA580C' // Orange
396
+ : tab === 'css'
397
+ ? '#2563EB' // Blue
398
+ : '#D97706'; // Dark Yellow/Amber
399
+ return (<Pressable key={tab} onPress={() => {
400
+ animateNextLayout();
401
+ setHtmlSubTab(tab);
402
+ }} style={{
403
+ paddingVertical: 8,
404
+ paddingHorizontal: 4,
405
+ borderBottomWidth: 2,
406
+ borderBottomColor: active
407
+ ? activeColor
408
+ : 'transparent',
409
+ flexDirection: 'row',
410
+ alignItems: 'center',
411
+ gap: 4,
412
+ }}>
413
+ {tab === 'html' && (<HtmlIcon color={active
414
+ ? activeColor
415
+ : AppColors.grayTextWeak} size={14}/>)}
416
+ {tab === 'css' && (<CssIcon color={active
417
+ ? activeColor
418
+ : AppColors.grayTextWeak} size={14}/>)}
419
+ {tab === 'javascript' && (<JsIcon color={active
420
+ ? activeColor
421
+ : AppColors.grayTextWeak} size={14}/>)}
422
+ <Text style={{
423
+ fontFamily: active
424
+ ? AppFonts.interBold
425
+ : AppFonts.interMedium,
426
+ fontSize: 13,
427
+ color: active
428
+ ? activeColor
429
+ : AppColors.grayTextWeak,
430
+ }}>
431
+ {label}
432
+ </Text>
433
+ </Pressable>);
434
+ })}
435
+ </View>
436
+ <View style={{ flex: 1, padding: 12 }}>
437
+ {!isHtmlTabReady ? (<View style={{
438
+ flex: 1,
439
+ justifyContent: 'center',
440
+ alignItems: 'center',
441
+ minHeight: 200,
442
+ }}>
443
+ <ActivityIndicator size="large" color={AppColors.purple}/>
444
+ </View>) : htmlSubTab === 'html' ? (webViewHtml ? (<CodeSnippet code={webViewHtml} language="html" search={getSearchTermForTab()}/>) : (<Text style={{
445
+ fontFamily: 'monospace',
446
+ fontSize: 11,
447
+ color: '#94A3B8',
448
+ padding: 12,
449
+ }}>
450
+ No HTML content captured.
451
+ </Text>)) : htmlSubTab === 'css' ? (webViewCss ? (<CodeSnippet code={webViewCss} language="css" search={getSearchTermForTab()}/>) : (<Text style={{
452
+ fontFamily: 'monospace',
453
+ fontSize: 11,
454
+ color: '#94A3B8',
455
+ padding: 12,
456
+ }}>
457
+ No CSS styles detected on this page.
458
+ </Text>)) : webViewJs ? (<CodeSnippet code={webViewJs} language="javascript" search={getSearchTermForTab()}/>) : (<Text style={{
459
+ fontFamily: 'monospace',
460
+ fontSize: 11,
461
+ color: '#94A3B8',
462
+ padding: 12,
463
+ }}>
464
+ No scripts detected on this page.
465
+ </Text>)}
466
+ </View>
467
+ </View>) : (<View style={styles.emptyContainer}>
468
+ <View style={styles.emptyIconWrap}>
469
+ <GlobeIcon color={AppColors.purple} size={32}/>
470
+ </View>
471
+ <Text style={styles.emptyTitle}>
472
+ No Page Source Captured
473
+ </Text>
474
+ <Text style={styles.emptySub}>
475
+ Load a page in the WebView to inspect its
476
+ HTML, CSS, or Javascript source.
477
+ </Text>
478
+ </View>)}
479
+ </View>) : webViewSubTab === 'navigation' ? (<FlatList data={filteredNavHistory} keyExtractor={(item, index) => `${index}-${item.timestamp}`} style={{
480
+ flex: 1,
481
+ backgroundColor: AppColors.grayBackground,
482
+ }} ListHeaderComponent={<View style={{
483
+ paddingHorizontal: 16,
484
+ paddingTop: 12,
485
+ paddingBottom: 8,
486
+ }}>
487
+ <Text style={styles.resultCount}>
488
+ Navigation History ({webViewNavHistory.length}
489
+ )
490
+ </Text>
491
+ </View>} renderItem={({ item, index, }) => {
492
+ const isLatest = index === 0;
493
+ const formatNavTime = (ts) => {
494
+ const d = new Date(ts);
495
+ return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`;
496
+ };
497
+ return (<AnimatedEntrance index={index} distance={8} style={{
498
+ marginHorizontal: 16,
499
+ marginVertical: 6,
500
+ borderRadius: 12,
501
+ borderWidth: 1,
502
+ borderColor: AppColors.grayBorderSecondary,
503
+ backgroundColor: isLatest
504
+ ? AppColors.purpleShade50
505
+ : AppColors.primaryLight,
506
+ padding: 14,
507
+ flexDirection: 'row',
508
+ alignItems: 'center',
509
+ justifyContent: 'space-between',
510
+ gap: 12,
511
+ shadowColor: '#000000',
512
+ shadowOffset: { width: 0, height: 2 },
513
+ shadowOpacity: isDark ? 0.2 : 0.04,
514
+ shadowRadius: 4,
515
+ elevation: 2,
516
+ }}>
517
+ <View style={{ flex: 1, gap: 8 }}>
518
+ {/* Top row: Title and Badge */}
519
+ <View style={{
520
+ flexDirection: 'row',
521
+ alignItems: 'center',
522
+ gap: 8,
523
+ flexWrap: 'wrap',
524
+ }}>
525
+ <Text numberOfLines={1} ellipsizeMode="tail" style={{
526
+ fontFamily: AppFonts.interBold,
527
+ fontSize: 14,
528
+ color: AppColors.primaryBlack,
529
+ flexShrink: 1,
530
+ }}>
531
+ {item.title || 'Untitled Page'}
532
+ </Text>
533
+ {isLatest && (<View style={{
534
+ flexDirection: 'row',
535
+ alignItems: 'center',
536
+ gap: 4,
537
+ backgroundColor: AppColors.greenStatus,
538
+ paddingHorizontal: 8,
539
+ paddingVertical: 3,
540
+ borderRadius: 12,
541
+ }}>
542
+ <View style={{
543
+ width: 6,
544
+ height: 6,
545
+ borderRadius: 3,
546
+ backgroundColor: AppColors.greenBaggageText,
547
+ }}/>
548
+ <Text style={{
549
+ fontFamily: AppFonts.interBold,
550
+ fontSize: 9.5,
551
+ color: AppColors.greenBaggageText,
552
+ }}>
553
+ Active
554
+ </Text>
555
+ </View>)}
556
+ </View>
557
+
558
+ {/* Middle row: URL with Globe Icon */}
559
+ <View style={{
560
+ flexDirection: 'row',
561
+ alignItems: 'center',
562
+ gap: 6,
563
+ }}>
564
+ <GlobeIcon size={12} color={AppColors.grayTextWeak}/>
565
+ <HighlightText text={item.url} search={webViewSearch} numberOfLines={2} ellipsizeMode="tail" style={{
566
+ fontFamily: AppFonts.interRegular,
567
+ fontSize: 12,
568
+ color: AppColors.grayText,
569
+ flex: 1,
570
+ }} highlightStyle={styles.highlight} detectLinks={true}/>
571
+ </View>
572
+
573
+ {/* Bottom row: Time */}
574
+ <View style={{
575
+ flexDirection: 'row',
576
+ alignItems: 'center',
577
+ gap: 6,
578
+ }}>
579
+ <ClockIcon size={11} color={AppColors.grayTextWeak}/>
580
+ <Text style={{
581
+ fontFamily: AppFonts.interRegular,
582
+ fontSize: 11,
583
+ color: AppColors.grayTextWeak,
584
+ }}>
585
+ {formatNavTime(item.timestamp)}
586
+ </Text>
587
+ </View>
588
+ </View>
589
+ <CopyButton value={item.url} label="URL"/>
590
+ </AnimatedEntrance>);
591
+ }} initialNumToRender={15} maxToRenderPerBatch={15} windowSize={7} removeClippedSubviews={true} ListEmptyComponent={<EmptyState isSearch={webViewSearch.length > 0}/>} contentContainerStyle={[
592
+ styles.listContent,
593
+ filteredNavHistory.length === 0 && {
594
+ flexGrow: 1,
595
+ },
596
+ ]} keyboardShouldPersistTaps="handled"/>) : webViewSubTab === 'console' ? (<View style={{
597
+ flex: 1,
598
+ backgroundColor: AppColors.grayBackground,
599
+ }}>
600
+ {webViewLogs.length > 0 ? (<FlatList data={webViewLogs} keyExtractor={(item) => String(item.id)} style={{ flex: 1 }} ListHeaderComponent={<View style={{
601
+ paddingHorizontal: 16,
602
+ paddingTop: 12,
603
+ paddingBottom: 8,
604
+ flexDirection: 'row',
605
+ justifyContent: 'space-between',
606
+ alignItems: 'center',
607
+ }}>
608
+ <Text style={styles.resultCount}>
609
+ Console Logs ({webViewLogs.length})
610
+ </Text>
611
+ <TouchableScale onPress={() => clearWebViewData()} style={{
612
+ padding: 6,
613
+ borderRadius: 6,
614
+ backgroundColor: AppColors.primaryLight,
615
+ borderWidth: 1,
616
+ borderColor: AppColors.grayBorderSecondary,
617
+ }}>
618
+ <TrashIcon color={AppColors.errorColor} size={14}/>
619
+ </TouchableScale>
620
+ </View>} renderItem={({ item }) => {
621
+ const logColor = item.type === 'error'
622
+ ? AppColors.errorColor
623
+ : item.type === 'warn'
624
+ ? AppColors.warningIconGold
625
+ : item.type === 'info'
626
+ ? AppColors.skyBlue
627
+ : AppColors.grayTextWeak;
628
+ const bgColor = item.type === 'error'
629
+ ? 'rgba(255, 46, 87, 0.06)'
630
+ : item.type === 'warn'
631
+ ? 'rgba(191, 162, 82, 0.08)'
632
+ : AppColors.primaryLight;
633
+ const d = new Date(item.timestamp);
634
+ const timeStr = `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`;
635
+ return (<AnimatedEntrance index={item.id} distance={8} style={{
636
+ marginHorizontal: 12,
637
+ marginVertical: 3,
638
+ borderRadius: 8,
639
+ borderWidth: 1,
640
+ borderColor: AppColors.grayBorderSecondary,
641
+ borderLeftWidth: 3,
642
+ borderLeftColor: logColor,
643
+ backgroundColor: bgColor,
644
+ padding: 10,
645
+ flexDirection: 'row',
646
+ gap: 8,
647
+ alignItems: 'flex-start',
648
+ }}>
649
+ <View style={{ paddingTop: 1 }}>
650
+ <TerminalIcon color={logColor} size={11}/>
651
+ </View>
652
+ <View style={{ flex: 1, gap: 3 }}>
653
+ <View style={{
654
+ flexDirection: 'row',
655
+ alignItems: 'center',
656
+ justifyContent: 'space-between',
657
+ }}>
658
+ <Text style={{
659
+ fontFamily: AppFonts.interBold,
660
+ fontSize: 10,
661
+ color: logColor,
662
+ textTransform: 'uppercase',
663
+ letterSpacing: 0.5,
664
+ }}>
665
+ {item.type}
666
+ </Text>
667
+ <Text style={{
668
+ fontFamily: AppFonts.interRegular,
669
+ fontSize: 10,
670
+ color: AppColors.grayTextWeak,
671
+ }}>
672
+ {timeStr}
673
+ </Text>
674
+ </View>
675
+ <Text style={{
676
+ fontFamily: AppFonts.interRegular,
677
+ fontSize: 12,
678
+ color: AppColors.primaryBlack,
679
+ lineHeight: 16,
680
+ }}>
681
+ {item.message}
682
+ </Text>
683
+ </View>
684
+ </AnimatedEntrance>);
685
+ }} initialNumToRender={20} maxToRenderPerBatch={20} windowSize={7} contentContainerStyle={[
686
+ styles.listContent,
687
+ webViewLogs.length === 0 && { flexGrow: 1 },
688
+ ]}/>) : (<View style={styles.emptyContainer}>
689
+ <View style={styles.emptyIconWrap}>
690
+ <TerminalIcon color={AppColors.purple} size={32}/>
691
+ </View>
692
+ <Text style={styles.emptyTitle}>
693
+ No Console Logs
694
+ </Text>
695
+ <Text style={styles.emptySub}>
696
+ Console logs from the WebView will appear
697
+ here.
698
+ </Text>
699
+ </View>)}
700
+ </View>) : (<View style={{
701
+ flex: 1,
702
+ backgroundColor: AppColors.grayBackground,
703
+ }}>
704
+ {webViewHtml ? (OriginalWebView ? (<OriginalWebView source={{
705
+ html: webViewHtml,
706
+ baseUrl: webViewHtmlUrl,
707
+ }} injectedJavaScript={previewInspectScript} onMessage={(event) => {
708
+ try {
709
+ const data = JSON.parse(event.nativeEvent.data);
710
+ if (data.type === 'preview-inspect') {
711
+ setInspectedElement({
712
+ tagName: data.tagName,
713
+ id: data.id,
714
+ className: data.className,
715
+ searchStr: data.searchStr,
716
+ });
717
+ setWebViewSubTab('html');
718
+ setHtmlSubTab('html');
719
+ }
720
+ }
721
+ catch (err) { }
722
+ }} style={{ flex: 1 }}/>) : (<View style={{
723
+ flex: 1,
724
+ justifyContent: 'center',
725
+ alignItems: 'center',
726
+ padding: 20,
727
+ }}>
728
+ <Text style={{
729
+ color: AppColors.grayText,
730
+ textAlign: 'center',
731
+ fontFamily: AppFonts.interMedium,
732
+ }}>
733
+ react-native-webview is not installed in the
734
+ target project. Install it to enable Preview
735
+ mode.
736
+ </Text>
737
+ </View>)) : (<View style={styles.emptyContainer}>
738
+ <View style={styles.emptyIconWrap}>
739
+ <GlobeIcon color={AppColors.purple} size={32}/>
740
+ </View>
741
+ <Text style={styles.emptyTitle}>
742
+ No Preview Available
743
+ </Text>
744
+ <Text style={styles.emptySub}>
745
+ Load a page in the WebView to see its visual
746
+ preview.
747
+ </Text>
748
+ </View>)}
749
+ </View>)}
750
+ </View>);
751
+ };
752
+ export default WebViewTab;