react-native-debug-toolkit 2.0.0 → 2.1.0

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 (228) hide show
  1. package/README.md +72 -72
  2. package/README.zh-CN.md +209 -0
  3. package/lib/commonjs/components/ClipboardTab.js +15 -16
  4. package/lib/commonjs/components/ClipboardTab.js.map +1 -1
  5. package/lib/commonjs/components/ConsoleLogTab.js +69 -202
  6. package/lib/commonjs/components/ConsoleLogTab.js.map +1 -1
  7. package/lib/commonjs/components/DebugPanel.js +230 -0
  8. package/lib/commonjs/components/DebugPanel.js.map +1 -0
  9. package/lib/commonjs/components/DebugView.js +66 -0
  10. package/lib/commonjs/components/DebugView.js.map +1 -0
  11. package/lib/commonjs/components/EnvironmentTab.js +22 -23
  12. package/lib/commonjs/components/EnvironmentTab.js.map +1 -1
  13. package/lib/commonjs/components/FeatureTabBar.js +182 -0
  14. package/lib/commonjs/components/FeatureTabBar.js.map +1 -0
  15. package/lib/commonjs/components/FloatIcon.js +187 -0
  16. package/lib/commonjs/components/FloatIcon.js.map +1 -0
  17. package/lib/commonjs/components/FloatPanelView.js +140 -723
  18. package/lib/commonjs/components/FloatPanelView.js.map +1 -1
  19. package/lib/commonjs/components/NavigationLogTab.js +8 -8
  20. package/lib/commonjs/components/NavigationLogTab.js.map +1 -1
  21. package/lib/commonjs/components/NetworkLogTab.js +179 -350
  22. package/lib/commonjs/components/NetworkLogTab.js.map +1 -1
  23. package/lib/commonjs/components/ThirdPartyLibsTab.js +8 -8
  24. package/lib/commonjs/components/ThirdPartyLibsTab.js.map +1 -1
  25. package/lib/commonjs/components/TrackLogTab.js +106 -248
  26. package/lib/commonjs/components/TrackLogTab.js.map +1 -1
  27. package/lib/commonjs/components/ZustandLogTab.js +148 -288
  28. package/lib/commonjs/components/ZustandLogTab.js.map +1 -1
  29. package/lib/commonjs/components/shared/CollapsibleSection.js +4 -4
  30. package/lib/commonjs/components/shared/CollapsibleSection.js.map +1 -1
  31. package/lib/commonjs/components/shared/CopyButton.js +3 -3
  32. package/lib/commonjs/components/shared/CopyButton.js.map +1 -1
  33. package/lib/commonjs/components/shared/LogListScreen.js +174 -0
  34. package/lib/commonjs/components/shared/LogListScreen.js.map +1 -0
  35. package/lib/commonjs/core/DebugToolkit.js +92 -112
  36. package/lib/commonjs/core/DebugToolkit.js.map +1 -1
  37. package/lib/commonjs/core/DebugToolkitProvider.js +30 -28
  38. package/lib/commonjs/core/DebugToolkitProvider.js.map +1 -1
  39. package/lib/commonjs/features/ClipboardFeature.js +6 -2
  40. package/lib/commonjs/features/ClipboardFeature.js.map +1 -1
  41. package/lib/commonjs/features/ConsoleLogFeature.js +66 -49
  42. package/lib/commonjs/features/ConsoleLogFeature.js.map +1 -1
  43. package/lib/commonjs/features/EnvironmentFeature.js +5 -13
  44. package/lib/commonjs/features/EnvironmentFeature.js.map +1 -1
  45. package/lib/commonjs/features/NavigationLogFeature.js +17 -38
  46. package/lib/commonjs/features/NavigationLogFeature.js.map +1 -1
  47. package/lib/commonjs/features/NetworkFeature.js +35 -256
  48. package/lib/commonjs/features/NetworkFeature.js.map +1 -1
  49. package/lib/commonjs/features/TrackFeature.js +17 -38
  50. package/lib/commonjs/features/TrackFeature.js.map +1 -1
  51. package/lib/commonjs/features/ZustandLogFeature.js +21 -38
  52. package/lib/commonjs/features/ZustandLogFeature.js.map +1 -1
  53. package/lib/commonjs/hooks/useNavigationLogger.js.map +1 -1
  54. package/lib/commonjs/index.js +7 -20
  55. package/lib/commonjs/index.js.map +1 -1
  56. package/lib/commonjs/initialize.js +19 -96
  57. package/lib/commonjs/initialize.js.map +1 -1
  58. package/lib/commonjs/interceptors/networkInterceptor.js +466 -0
  59. package/lib/commonjs/interceptors/networkInterceptor.js.map +1 -0
  60. package/lib/commonjs/utils/colors.js +48 -0
  61. package/lib/commonjs/utils/colors.js.map +1 -0
  62. package/lib/commonjs/utils/createChannelFeature.js +48 -0
  63. package/lib/commonjs/utils/createChannelFeature.js.map +1 -0
  64. package/lib/commonjs/utils/layout.js +8 -0
  65. package/lib/commonjs/utils/layout.js.map +1 -0
  66. package/lib/commonjs/utils/urlRewriterRegistry.js +14 -0
  67. package/lib/commonjs/utils/urlRewriterRegistry.js.map +1 -0
  68. package/lib/module/components/ClipboardTab.js +8 -8
  69. package/lib/module/components/ClipboardTab.js.map +1 -1
  70. package/lib/module/components/ConsoleLogTab.js +66 -199
  71. package/lib/module/components/ConsoleLogTab.js.map +1 -1
  72. package/lib/module/components/DebugPanel.js +225 -0
  73. package/lib/module/components/DebugPanel.js.map +1 -0
  74. package/lib/module/components/DebugView.js +61 -0
  75. package/lib/module/components/DebugView.js.map +1 -0
  76. package/lib/module/components/EnvironmentTab.js +3 -3
  77. package/lib/module/components/EnvironmentTab.js.map +1 -1
  78. package/lib/module/components/FeatureTabBar.js +177 -0
  79. package/lib/module/components/FeatureTabBar.js.map +1 -0
  80. package/lib/module/components/FloatIcon.js +182 -0
  81. package/lib/module/components/FloatIcon.js.map +1 -0
  82. package/lib/module/components/FloatPanelView.js +141 -723
  83. package/lib/module/components/FloatPanelView.js.map +1 -1
  84. package/lib/module/components/NavigationLogTab.js +1 -1
  85. package/lib/module/components/NavigationLogTab.js.map +1 -1
  86. package/lib/module/components/NetworkLogTab.js +167 -338
  87. package/lib/module/components/NetworkLogTab.js.map +1 -1
  88. package/lib/module/components/ThirdPartyLibsTab.js +1 -1
  89. package/lib/module/components/ThirdPartyLibsTab.js.map +1 -1
  90. package/lib/module/components/TrackLogTab.js +94 -236
  91. package/lib/module/components/TrackLogTab.js.map +1 -1
  92. package/lib/module/components/ZustandLogTab.js +136 -276
  93. package/lib/module/components/ZustandLogTab.js.map +1 -1
  94. package/lib/module/components/shared/CollapsibleSection.js +1 -1
  95. package/lib/module/components/shared/CollapsibleSection.js.map +1 -1
  96. package/lib/module/components/shared/CopyButton.js +1 -1
  97. package/lib/module/components/shared/CopyButton.js.map +1 -1
  98. package/lib/module/components/shared/LogListScreen.js +169 -0
  99. package/lib/module/components/shared/LogListScreen.js.map +1 -0
  100. package/lib/module/core/DebugToolkit.js +92 -111
  101. package/lib/module/core/DebugToolkit.js.map +1 -1
  102. package/lib/module/core/DebugToolkitProvider.js +31 -29
  103. package/lib/module/core/DebugToolkitProvider.js.map +1 -1
  104. package/lib/module/features/ClipboardFeature.js +6 -2
  105. package/lib/module/features/ClipboardFeature.js.map +1 -1
  106. package/lib/module/features/ConsoleLogFeature.js +65 -49
  107. package/lib/module/features/ConsoleLogFeature.js.map +1 -1
  108. package/lib/module/features/EnvironmentFeature.js +5 -13
  109. package/lib/module/features/EnvironmentFeature.js.map +1 -1
  110. package/lib/module/features/NavigationLogFeature.js +16 -38
  111. package/lib/module/features/NavigationLogFeature.js.map +1 -1
  112. package/lib/module/features/NetworkFeature.js +34 -255
  113. package/lib/module/features/NetworkFeature.js.map +1 -1
  114. package/lib/module/features/TrackFeature.js +16 -38
  115. package/lib/module/features/TrackFeature.js.map +1 -1
  116. package/lib/module/features/ZustandLogFeature.js +22 -38
  117. package/lib/module/features/ZustandLogFeature.js.map +1 -1
  118. package/lib/module/hooks/useNavigationLogger.js.map +1 -1
  119. package/lib/module/index.js +2 -3
  120. package/lib/module/index.js.map +1 -1
  121. package/lib/module/initialize.js +19 -95
  122. package/lib/module/initialize.js.map +1 -1
  123. package/lib/module/interceptors/networkInterceptor.js +460 -0
  124. package/lib/module/interceptors/networkInterceptor.js.map +1 -0
  125. package/lib/module/utils/colors.js +43 -0
  126. package/lib/module/utils/colors.js.map +1 -0
  127. package/lib/module/utils/createChannelFeature.js +44 -0
  128. package/lib/module/utils/createChannelFeature.js.map +1 -0
  129. package/lib/module/utils/layout.js +4 -0
  130. package/lib/module/utils/layout.js.map +1 -0
  131. package/lib/module/utils/urlRewriterRegistry.js +10 -0
  132. package/lib/module/utils/urlRewriterRegistry.js.map +1 -0
  133. package/lib/typescript/src/components/ClipboardTab.d.ts.map +1 -1
  134. package/lib/typescript/src/components/ConsoleLogTab.d.ts.map +1 -1
  135. package/lib/typescript/src/components/DebugPanel.d.ts +9 -0
  136. package/lib/typescript/src/components/DebugPanel.d.ts.map +1 -0
  137. package/lib/typescript/src/components/DebugView.d.ts +19 -0
  138. package/lib/typescript/src/components/DebugView.d.ts.map +1 -0
  139. package/lib/typescript/src/components/EnvironmentTab.d.ts.map +1 -1
  140. package/lib/typescript/src/components/FeatureTabBar.d.ts +13 -0
  141. package/lib/typescript/src/components/FeatureTabBar.d.ts.map +1 -0
  142. package/lib/typescript/src/components/FloatIcon.d.ts +12 -0
  143. package/lib/typescript/src/components/FloatIcon.d.ts.map +1 -0
  144. package/lib/typescript/src/components/FloatPanelView.d.ts +4 -59
  145. package/lib/typescript/src/components/FloatPanelView.d.ts.map +1 -1
  146. package/lib/typescript/src/components/NetworkLogTab.d.ts.map +1 -1
  147. package/lib/typescript/src/components/ThirdPartyLibsTab.d.ts.map +1 -1
  148. package/lib/typescript/src/components/TrackLogTab.d.ts.map +1 -1
  149. package/lib/typescript/src/components/ZustandLogTab.d.ts.map +1 -1
  150. package/lib/typescript/src/components/shared/LogListScreen.d.ts +21 -0
  151. package/lib/typescript/src/components/shared/LogListScreen.d.ts.map +1 -0
  152. package/lib/typescript/src/core/DebugToolkit.d.ts +11 -18
  153. package/lib/typescript/src/core/DebugToolkit.d.ts.map +1 -1
  154. package/lib/typescript/src/core/DebugToolkitProvider.d.ts +2 -5
  155. package/lib/typescript/src/core/DebugToolkitProvider.d.ts.map +1 -1
  156. package/lib/typescript/src/features/ClipboardFeature.d.ts +4 -0
  157. package/lib/typescript/src/features/ClipboardFeature.d.ts.map +1 -1
  158. package/lib/typescript/src/features/ConsoleLogFeature.d.ts +2 -0
  159. package/lib/typescript/src/features/ConsoleLogFeature.d.ts.map +1 -1
  160. package/lib/typescript/src/features/EnvironmentFeature.d.ts.map +1 -1
  161. package/lib/typescript/src/features/NavigationLogFeature.d.ts +2 -0
  162. package/lib/typescript/src/features/NavigationLogFeature.d.ts.map +1 -1
  163. package/lib/typescript/src/features/NetworkFeature.d.ts +7 -20
  164. package/lib/typescript/src/features/NetworkFeature.d.ts.map +1 -1
  165. package/lib/typescript/src/features/TrackFeature.d.ts +2 -0
  166. package/lib/typescript/src/features/TrackFeature.d.ts.map +1 -1
  167. package/lib/typescript/src/features/ZustandLogFeature.d.ts +2 -0
  168. package/lib/typescript/src/features/ZustandLogFeature.d.ts.map +1 -1
  169. package/lib/typescript/src/hooks/useNavigationLogger.d.ts +1 -8
  170. package/lib/typescript/src/hooks/useNavigationLogger.d.ts.map +1 -1
  171. package/lib/typescript/src/index.d.ts +5 -5
  172. package/lib/typescript/src/index.d.ts.map +1 -1
  173. package/lib/typescript/src/initialize.d.ts +3 -22
  174. package/lib/typescript/src/initialize.d.ts.map +1 -1
  175. package/lib/typescript/src/interceptors/networkInterceptor.d.ts +18 -0
  176. package/lib/typescript/src/interceptors/networkInterceptor.d.ts.map +1 -0
  177. package/lib/typescript/src/types/index.d.ts +26 -29
  178. package/lib/typescript/src/types/index.d.ts.map +1 -1
  179. package/lib/typescript/src/utils/colors.d.ts +21 -0
  180. package/lib/typescript/src/utils/colors.d.ts.map +1 -0
  181. package/lib/typescript/src/utils/createChannelFeature.d.ts +18 -0
  182. package/lib/typescript/src/utils/createChannelFeature.d.ts.map +1 -0
  183. package/lib/typescript/src/utils/layout.d.ts +2 -0
  184. package/lib/typescript/src/utils/layout.d.ts.map +1 -0
  185. package/lib/typescript/src/utils/urlRewriterRegistry.d.ts +7 -0
  186. package/lib/typescript/src/utils/urlRewriterRegistry.d.ts.map +1 -0
  187. package/package.json +5 -1
  188. package/src/components/ClipboardTab.tsx +8 -8
  189. package/src/components/ConsoleLogTab.tsx +49 -163
  190. package/src/components/DebugPanel.tsx +215 -0
  191. package/src/components/DebugView.tsx +80 -0
  192. package/src/components/EnvironmentTab.tsx +3 -3
  193. package/src/components/FeatureTabBar.tsx +204 -0
  194. package/src/components/FloatIcon.tsx +171 -0
  195. package/src/components/FloatPanelView.tsx +135 -647
  196. package/src/components/NavigationLogTab.tsx +1 -1
  197. package/src/components/NetworkLogTab.tsx +128 -269
  198. package/src/components/ThirdPartyLibsTab.tsx +3 -3
  199. package/src/components/TrackLogTab.tsx +53 -188
  200. package/src/components/ZustandLogTab.tsx +79 -181
  201. package/src/components/shared/CollapsibleSection.tsx +1 -1
  202. package/src/components/shared/CopyButton.tsx +1 -1
  203. package/src/components/shared/LogListScreen.tsx +164 -0
  204. package/src/core/DebugToolkit.tsx +114 -138
  205. package/src/core/DebugToolkitProvider.tsx +32 -38
  206. package/src/features/ClipboardFeature.ts +6 -2
  207. package/src/features/ConsoleLogFeature.ts +66 -68
  208. package/src/features/EnvironmentFeature.ts +5 -13
  209. package/src/features/NavigationLogFeature.ts +12 -42
  210. package/src/features/NetworkFeature.ts +43 -405
  211. package/src/features/TrackFeature.ts +14 -49
  212. package/src/features/ZustandLogFeature.ts +16 -42
  213. package/src/hooks/useNavigationLogger.ts +1 -6
  214. package/src/index.ts +5 -9
  215. package/src/initialize.ts +28 -120
  216. package/src/interceptors/networkInterceptor.ts +646 -0
  217. package/src/types/index.ts +25 -36
  218. package/src/utils/colors.ts +38 -0
  219. package/src/utils/createChannelFeature.ts +55 -0
  220. package/src/utils/layout.ts +1 -0
  221. package/src/utils/urlRewriterRegistry.ts +10 -0
  222. package/lib/commonjs/utils/constants.js +0 -135
  223. package/lib/commonjs/utils/constants.js.map +0 -1
  224. package/lib/module/utils/constants.js +0 -130
  225. package/lib/module/utils/constants.js.map +0 -1
  226. package/lib/typescript/src/utils/constants.d.ts +0 -96
  227. package/lib/typescript/src/utils/constants.d.ts.map +0 -1
  228. package/src/utils/constants.ts +0 -91
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { View, Text, FlatList, StyleSheet } from 'react-native';
3
- import { Colors } from '../utils/constants';
3
+ import { Colors } from '../utils/colors';
4
4
  import { CopyButton } from './shared/CopyButton';
5
5
  import type { DebugFeatureRenderProps, NavigationLogEntry } from '../types';
6
6
 
@@ -1,19 +1,17 @@
1
- import React, { useState, useEffect, useRef } from 'react';
1
+ import React, { useState } from 'react';
2
2
  import {
3
3
  View,
4
4
  Text,
5
- FlatList,
6
- TouchableOpacity,
7
5
  StyleSheet,
8
6
  TextInput,
9
- Animated,
10
7
  ScrollView,
11
8
  } from 'react-native';
12
- import { Colors, getMethodColor } from '../utils/constants';
9
+ import { Colors, getMethodColor } from '../utils/colors';
13
10
  import { CollapsibleSection } from './shared/CollapsibleSection';
14
11
  import { JsonView } from './shared/JsonView';
15
12
  import { CopyButton } from './shared/CopyButton';
16
13
  import { fmt } from '../utils/copyToComputer';
14
+ import { LogListScreen } from './shared/LogListScreen';
17
15
  import type { DebugFeatureRenderProps, NetworkLogEntry } from '../types';
18
16
 
19
17
  const formatSize = (data: unknown): string => {
@@ -28,154 +26,21 @@ const formatSize = (data: unknown): string => {
28
26
  }
29
27
  };
30
28
 
31
- // --- Detail view (in-panel push) ---
32
- const NetworkLogDetail: React.FC<{ log: NetworkLogEntry; onBack: () => void }> = ({
33
- log,
34
- onBack,
35
- }) => {
36
- const statusColor =
37
- log.error || (log.response && log.response.status >= 400) ? Colors.error : Colors.success;
38
-
39
- const curl = () => {
40
- let c = `curl -X ${log.request.method} '${log.request.url}'`;
41
- if (log.request.headers) {
42
- Object.entries(log.request.headers).forEach(([k, v]) => (c += ` \\\n -H '${k}: ${v}'`));
43
- }
44
- if (log.request.body) {
45
- c += ` \\\n -d '${typeof log.request.body === 'string' ? log.request.body : JSON.stringify(log.request.body)}'`;
46
- }
47
- return c;
48
- };
49
-
50
- return (
51
- <View style={s.detailWrap}>
52
- <View style={s.detailHeader}>
53
- <TouchableOpacity onPress={onBack} style={s.backBtn} activeOpacity={0.6}>
54
- <Text style={s.backIcon}>‹</Text>
55
- <Text style={s.backText}>Back</Text>
56
- </TouchableOpacity>
57
- <View style={s.detailHeaderCenter}>
58
- <View style={[s.methodBadge, { backgroundColor: getMethodColor(log.request.method) }]}>
59
- <Text style={s.methodBadgeText}>{log.request.method}</Text>
60
- </View>
61
- <View style={[s.statusPill, { backgroundColor: statusColor }]}>
62
- <Text style={s.statusPillText}>{log.response?.status ?? 'ERR'}</Text>
63
- </View>
64
- {log.duration != null && (
65
- <Text style={s.durationText}>{log.duration}ms</Text>
66
- )}
67
- </View>
68
- </View>
69
- <ScrollView style={s.detailBody} contentContainerStyle={s.detailBodyContent}>
70
- {/* URL */}
71
- <View style={s.urlCard}>
72
- <Text style={s.urlText} selectable numberOfLines={3}>
73
- {log.request.url}
74
- </Text>
75
- <CopyButton text={log.request.url} label="URL" />
76
- </View>
77
-
78
- {/* Request Body */}
79
- <CollapsibleSection title="Request Body" initiallyExpanded>
80
- {log.request.body != null ? (
81
- <View style={s.sectionWithCopy}>
82
- <CopyButton text={fmt(log.request.body)} label="Request Body" />
83
- <JsonView data={log.request.body} maxHeight={250} />
84
- </View>
85
- ) : (
86
- <Text style={s.emptySection}>No request body</Text>
87
- )}
88
- </CollapsibleSection>
89
-
90
- <CollapsibleSection title="Request Headers">
91
- {log.request.headers ? (
92
- <View style={s.sectionWithCopy}>
93
- <CopyButton text={fmt(log.request.headers)} label="Request Headers" />
94
- <JsonView data={log.request.headers} maxHeight={200} />
95
- </View>
96
- ) : (
97
- <Text style={s.emptySection}>No headers</Text>
98
- )}
99
- </CollapsibleSection>
100
-
101
- {/* Response */}
102
- <CollapsibleSection
103
- title={`Response ${formatSize(log.response?.data)}`}
104
- initiallyExpanded
105
- >
106
- {log.error && (
107
- <View style={s.errorBox}>
108
- <Text style={s.errorIcon}>⚠</Text>
109
- <Text style={s.errorText}>{log.error}</Text>
110
- </View>
111
- )}
112
- {log.response?.data != null ? (
113
- <View style={s.sectionWithCopy}>
114
- <CopyButton text={fmt(log.response.data)} label="Response Body" />
115
- <JsonView data={log.response.data} maxHeight={300} />
116
- </View>
117
- ) : (
118
- <Text style={s.emptySection}>No response body</Text>
119
- )}
120
- </CollapsibleSection>
121
-
122
- {log.response?.headers && (
123
- <CollapsibleSection title="Response Headers">
124
- <View style={s.sectionWithCopy}>
125
- <CopyButton text={fmt(log.response.headers)} label="Response Headers" />
126
- <JsonView data={log.response.headers} maxHeight={200} />
127
- </View>
128
- </CollapsibleSection>
129
- )}
130
-
131
- {/* cURL */}
132
- <CollapsibleSection title="cURL">
133
- <View style={s.sectionWithCopy}>
134
- <CopyButton text={curl()} label="cURL" />
135
- <View style={s.codeBlock}>
136
- <Text style={s.codeText} selectable>{curl()}</Text>
137
- </View>
138
- </View>
139
- </CollapsibleSection>
140
- </ScrollView>
141
- </View>
142
- );
29
+ const buildCurl = (log: NetworkLogEntry): string => {
30
+ let c = `curl -X ${log.request.method} '${log.request.url}'`;
31
+ if (log.request.headers) {
32
+ Object.entries(log.request.headers).forEach(([k, v]) => (c += ` \\\n -H '${k}: ${v}'`));
33
+ }
34
+ if (log.request.body) {
35
+ c += ` \\\n -d '${typeof log.request.body === 'string' ? log.request.body : JSON.stringify(log.request.body)}'`;
36
+ }
37
+ return c;
143
38
  };
144
39
 
145
- // --- List view ---
146
40
  export const NetworkLogTab: React.FC<DebugFeatureRenderProps<NetworkLogEntry>> = React.memo(({
147
41
  data,
148
42
  }) => {
149
- const [selectedLog, setSelectedLog] = useState<NetworkLogEntry | null>(null);
150
43
  const [search, setSearch] = useState('');
151
- const slideAnim = useRef(new Animated.Value(0)).current;
152
- const listSlideAnim = useRef(new Animated.Value(0)).current;
153
-
154
- useEffect(() => {
155
- if (selectedLog) {
156
- listSlideAnim.setValue(0);
157
- Animated.parallel([
158
- Animated.spring(slideAnim, { toValue: 1, friction: 9, tension: 60, useNativeDriver: true }),
159
- Animated.spring(listSlideAnim, { toValue: 1, friction: 9, tension: 60, useNativeDriver: true }),
160
- ]).start();
161
- } else {
162
- slideAnim.setValue(0);
163
- listSlideAnim.setValue(0);
164
- }
165
- }, [selectedLog]);
166
-
167
- const detailTranslateX = slideAnim.interpolate({
168
- inputRange: [0, 1],
169
- outputRange: [300, 0],
170
- });
171
- const listTranslateX = listSlideAnim.interpolate({
172
- inputRange: [0, 1],
173
- outputRange: [0, -60],
174
- });
175
- const listOpacity = listSlideAnim.interpolate({
176
- inputRange: [0, 1],
177
- outputRange: [1, 0],
178
- });
179
44
 
180
45
  const filtered = search
181
46
  ? data.filter(
@@ -185,43 +50,14 @@ export const NetworkLogTab: React.FC<DebugFeatureRenderProps<NetworkLogEntry>> =
185
50
  )
186
51
  : data;
187
52
 
188
- const sorted = [...filtered].sort(
189
- (a, b) => b.timestamp - a.timestamp,
190
- );
191
-
192
- const renderItem = ({ item }: { item: NetworkLogEntry }) => {
193
- const ok = !item.error && (!item.response || item.response.status < 400);
194
- const sc = ok ? Colors.success : Colors.error;
195
- return (
196
- <TouchableOpacity style={s.card} onPress={() => setSelectedLog(item)} activeOpacity={0.6}>
197
- <View style={s.cardRow}>
198
- <View style={[s.statusIndicator, { backgroundColor: sc }]} />
199
- <View style={s.cardBody}>
200
- <View style={s.cardMeta}>
201
- <Text style={[s.methodText, { color: getMethodColor(item.request.method) }]}>
202
- {item.request.method}
203
- </Text>
204
- <View style={[s.miniPill, { backgroundColor: sc }]}>
205
- <Text style={s.miniPillText}>{item.response?.status ?? 'ERR'}</Text>
206
- </View>
207
- {item.duration != null && <Text style={s.durationText}>{item.duration}ms</Text>}
208
- </View>
209
- <Text style={[s.url, !ok && { color: Colors.error }]} numberOfLines={2}>
210
- {item.request.url}
211
- </Text>
212
- <Text style={s.time}>
213
- {new Date(item.timestamp).toLocaleTimeString()}
214
- </Text>
215
- </View>
216
- </View>
217
- </TouchableOpacity>
218
- );
219
- };
53
+ const sorted = [...filtered].sort((a, b) => b.timestamp - a.timestamp);
220
54
 
221
55
  return (
222
- <View style={s.container}>
223
- {/* List */}
224
- <Animated.View style={[s.listWrap, selectedLog ? { opacity: listOpacity, transform: [{ translateX: listTranslateX }] } : null]}>
56
+ <LogListScreen
57
+ data={sorted}
58
+ reversed={false}
59
+ emptyText="No HTTP requests logged"
60
+ renderListHeader={() => (
225
61
  <View style={s.searchContainer}>
226
62
  <View style={s.searchBar}>
227
63
  <Text style={s.searchIcon}>⌕</Text>
@@ -234,45 +70,118 @@ export const NetworkLogTab: React.FC<DebugFeatureRenderProps<NetworkLogEntry>> =
234
70
  />
235
71
  </View>
236
72
  </View>
237
- {sorted.length === 0 ? (
238
- <View style={s.emptyContainer}>
239
- <Text style={s.emptyIcon}>~</Text>
240
- <Text style={s.empty}>No HTTP requests logged</Text>
73
+ )}
74
+ renderRow={(item) => {
75
+ const ok = !item.error && (!item.response || item.response.status < 400);
76
+ const sc = ok ? Colors.success : Colors.error;
77
+ return (
78
+ <View style={s.cardRow}>
79
+ <View style={[s.statusIndicator, { backgroundColor: sc }]} />
80
+ <View style={s.cardBody}>
81
+ <View style={s.cardMeta}>
82
+ <Text style={[s.methodText, { color: getMethodColor(item.request.method) }]}>
83
+ {item.request.method}
84
+ </Text>
85
+ <View style={[s.miniPill, { backgroundColor: sc }]}>
86
+ <Text style={s.miniPillText}>{item.response?.status ?? 'ERR'}</Text>
87
+ </View>
88
+ {item.duration != null && <Text style={s.durationText}>{item.duration}ms</Text>}
89
+ </View>
90
+ <Text style={[s.url, !ok && { color: Colors.error }]} numberOfLines={2}>
91
+ {item.request.url}
92
+ </Text>
93
+ <Text style={s.time}>{new Date(item.timestamp).toLocaleTimeString()}</Text>
94
+ </View>
95
+ </View>
96
+ );
97
+ }}
98
+ renderDetailHeader={(log) => {
99
+ const statusColor = log.error || (log.response && log.response.status >= 400) ? Colors.error : Colors.success;
100
+ return (
101
+ <View style={s.detailHeaderCenter}>
102
+ <View style={[s.methodBadge, { backgroundColor: getMethodColor(log.request.method) }]}>
103
+ <Text style={s.methodBadgeText}>{log.request.method}</Text>
104
+ </View>
105
+ <View style={[s.statusPill, { backgroundColor: statusColor }]}>
106
+ <Text style={s.statusPillText}>{log.response?.status ?? 'ERR'}</Text>
107
+ </View>
108
+ {log.duration != null && <Text style={s.durationText}>{log.duration}ms</Text>}
241
109
  </View>
242
- ) : (
243
- <FlatList
244
- data={sorted}
245
- renderItem={renderItem}
246
- keyExtractor={(item) => item.id}
247
- contentContainerStyle={s.listContent}
248
- initialNumToRender={20}
249
- maxToRenderPerBatch={10}
250
- windowSize={5}
251
- removeClippedSubviews={true}
252
- />
253
- )}
254
- </Animated.View>
110
+ );
111
+ }}
112
+ renderDetailBody={(log) => {
113
+ const curlStr = buildCurl(log);
114
+ return (
115
+ <ScrollView style={s.detailBody} contentContainerStyle={s.detailBodyContent}>
116
+ <View style={s.urlCard}>
117
+ <Text style={s.urlText} selectable numberOfLines={3}>{log.request.url}</Text>
118
+ <CopyButton text={log.request.url} label="URL" />
119
+ </View>
255
120
 
256
- {/* Detail (push navigation) */}
257
- {selectedLog && (
258
- <Animated.View style={[s.detailOverlay, { transform: [{ translateX: detailTranslateX }] }]}>
259
- <NetworkLogDetail log={selectedLog} onBack={() => setSelectedLog(null)} />
260
- </Animated.View>
261
- )}
262
- </View>
121
+ <CollapsibleSection title="Request Body" initiallyExpanded>
122
+ {log.request.body != null ? (
123
+ <View style={s.sectionWithCopy}>
124
+ <CopyButton text={fmt(log.request.body)} label="Request Body" />
125
+ <JsonView data={log.request.body} maxHeight={250} />
126
+ </View>
127
+ ) : (
128
+ <Text style={s.emptySection}>No request body</Text>
129
+ )}
130
+ </CollapsibleSection>
131
+
132
+ <CollapsibleSection title="Request Headers">
133
+ {log.request.headers ? (
134
+ <View style={s.sectionWithCopy}>
135
+ <CopyButton text={fmt(log.request.headers)} label="Request Headers" />
136
+ <JsonView data={log.request.headers} maxHeight={200} />
137
+ </View>
138
+ ) : (
139
+ <Text style={s.emptySection}>No headers</Text>
140
+ )}
141
+ </CollapsibleSection>
142
+
143
+ <CollapsibleSection title={`Response ${formatSize(log.response?.data)}`} initiallyExpanded>
144
+ {log.error && (
145
+ <View style={s.errorBox}>
146
+ <Text style={s.errorIcon}>⚠</Text>
147
+ <Text style={s.errorText}>{log.error}</Text>
148
+ </View>
149
+ )}
150
+ {log.response?.data != null ? (
151
+ <View style={s.sectionWithCopy}>
152
+ <CopyButton text={fmt(log.response.data)} label="Response Body" />
153
+ <JsonView data={log.response.data} maxHeight={300} />
154
+ </View>
155
+ ) : (
156
+ <Text style={s.emptySection}>No response body</Text>
157
+ )}
158
+ </CollapsibleSection>
159
+
160
+ {log.response?.headers && (
161
+ <CollapsibleSection title="Response Headers">
162
+ <View style={s.sectionWithCopy}>
163
+ <CopyButton text={fmt(log.response.headers)} label="Response Headers" />
164
+ <JsonView data={log.response.headers} maxHeight={200} />
165
+ </View>
166
+ </CollapsibleSection>
167
+ )}
168
+
169
+ <CollapsibleSection title="cURL">
170
+ <View style={s.sectionWithCopy}>
171
+ <CopyButton text={curlStr} label="cURL" />
172
+ <View style={s.codeBlock}>
173
+ <Text style={s.codeText} selectable>{curlStr}</Text>
174
+ </View>
175
+ </View>
176
+ </CollapsibleSection>
177
+ </ScrollView>
178
+ );
179
+ }}
180
+ />
263
181
  );
264
182
  });
265
183
 
266
184
  const s = StyleSheet.create({
267
- container: { flex: 1, backgroundColor: Colors.background },
268
- listWrap: {
269
- position: 'absolute',
270
- top: 0,
271
- left: 0,
272
- right: 0,
273
- bottom: 0,
274
- },
275
-
276
185
  // Search
277
186
  searchContainer: {
278
187
  paddingHorizontal: 12,
@@ -296,19 +205,7 @@ const s = StyleSheet.create({
296
205
  padding: 0,
297
206
  },
298
207
 
299
- // Empty
300
- emptyContainer: { flex: 1, alignItems: 'center', justifyContent: 'center' },
301
- emptyIcon: { fontSize: 40, color: Colors.textLight, marginBottom: 4 },
302
- empty: { textAlign: 'center', color: Colors.textLight, fontSize: 14 },
303
-
304
- // List
305
- listContent: { padding: 12 },
306
- card: {
307
- backgroundColor: Colors.surface,
308
- borderRadius: 12,
309
- marginBottom: 8,
310
- overflow: 'hidden',
311
- },
208
+ // Row
312
209
  cardRow: { flexDirection: 'row', padding: 14 },
313
210
  statusIndicator: { width: 3, borderRadius: 2, marginRight: 12 },
314
211
  cardBody: { flex: 1 },
@@ -320,45 +217,7 @@ const s = StyleSheet.create({
320
217
  url: { fontSize: 13, color: Colors.textSecondary, marginBottom: 4, lineHeight: 18 },
321
218
  time: { fontSize: 11, color: Colors.textLight },
322
219
 
323
- // Detail overlay
324
- detailOverlay: {
325
- position: 'absolute',
326
- top: 0,
327
- left: 0,
328
- right: 0,
329
- bottom: 0,
330
- backgroundColor: Colors.background,
331
- },
332
- detailWrap: { flex: 1, backgroundColor: Colors.background },
333
- detailHeader: {
334
- flexDirection: 'row',
335
- alignItems: 'center',
336
- paddingHorizontal: 8,
337
- paddingVertical: 10,
338
- backgroundColor: Colors.surface,
339
- borderBottomWidth: StyleSheet.hairlineWidth,
340
- borderBottomColor: Colors.border,
341
- },
342
- backBtn: {
343
- flexDirection: 'row',
344
- alignItems: 'center',
345
- paddingHorizontal: 6,
346
- paddingVertical: 4,
347
- borderRadius: 8,
348
- marginRight: 8,
349
- },
350
- backIcon: {
351
- fontSize: 24,
352
- fontWeight: '300',
353
- color: Colors.primary,
354
- marginTop: -2,
355
- marginRight: 2,
356
- },
357
- backText: {
358
- fontSize: 16,
359
- color: Colors.primary,
360
- fontWeight: '500',
361
- },
220
+ // Detail header
362
221
  detailHeaderCenter: {
363
222
  flexDirection: 'row',
364
223
  alignItems: 'center',
@@ -373,10 +232,10 @@ const s = StyleSheet.create({
373
232
  methodBadgeText: { color: '#FFF', fontSize: 12, fontWeight: '700' },
374
233
  statusPill: { paddingHorizontal: 9, paddingVertical: 3, borderRadius: 6 },
375
234
  statusPillText: { color: '#FFF', fontSize: 11, fontWeight: '700' },
235
+
236
+ // Detail body
376
237
  detailBody: { flex: 1 },
377
238
  detailBodyContent: { padding: 12, paddingBottom: 40 },
378
-
379
- // Detail content
380
239
  urlCard: {
381
240
  flexDirection: 'row',
382
241
  alignItems: 'center',
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
3
- import { Colors } from '../utils/constants';
4
- import type { DebugFeatureRenderProps, ThirdPartyLib } from '../types';
3
+ import { Colors } from '../utils/colors';
4
+ import type { DebugFeatureRenderProps, ThirdPartyLib, ThirdPartyLibAction } from '../types';
5
5
 
6
6
  export const ThirdPartyLibsTab: React.FC<DebugFeatureRenderProps<ThirdPartyLib>> = ({
7
7
  data,
@@ -21,7 +21,7 @@ export const ThirdPartyLibsTab: React.FC<DebugFeatureRenderProps<ThirdPartyLib>>
21
21
  <Text style={styles.libName}>{lib.name}</Text>
22
22
  <Text style={styles.libDesc}>{lib.description}</Text>
23
23
  <View style={styles.actions}>
24
- {lib.actions.map((action) => (
24
+ {lib.actions.map((action: ThirdPartyLibAction) => (
25
25
  <TouchableOpacity
26
26
  key={action.id}
27
27
  style={styles.actionButton}