react-native-vconsole 0.0.1 → 0.3.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 (49) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +39 -9
  3. package/Vconsole.podspec +25 -0
  4. package/android/build.gradle +61 -129
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +1 -2
  7. package/android/src/main/AndroidManifestNew.xml +2 -0
  8. package/android/src/main/java/com/vconsole/VconsoleModule.kt +80 -0
  9. package/android/src/main/java/com/vconsole/VconsolePackage.kt +17 -0
  10. package/ios/Vconsole.h +6 -0
  11. package/ios/Vconsole.mm +64 -0
  12. package/lib/module/VConsole.js +780 -0
  13. package/lib/module/VConsole.js.map +1 -0
  14. package/lib/module/core/consoleProxy.js +86 -0
  15. package/lib/module/core/consoleProxy.js.map +1 -0
  16. package/lib/module/core/xhrProxy.js +247 -0
  17. package/lib/module/core/xhrProxy.js.map +1 -0
  18. package/lib/module/index.js +24 -0
  19. package/lib/module/index.js.map +1 -0
  20. package/lib/module/package.json +1 -0
  21. package/lib/module/types.js +2 -0
  22. package/lib/module/types.js.map +1 -0
  23. package/lib/typescript/package.json +1 -0
  24. package/lib/typescript/src/VConsole.d.ts +6 -0
  25. package/lib/typescript/src/VConsole.d.ts.map +1 -0
  26. package/lib/typescript/src/core/consoleProxy.d.ts +9 -0
  27. package/lib/typescript/src/core/consoleProxy.d.ts.map +1 -0
  28. package/lib/typescript/src/core/xhrProxy.d.ts +12 -0
  29. package/lib/typescript/src/core/xhrProxy.d.ts.map +1 -0
  30. package/lib/typescript/src/index.d.ts +9 -0
  31. package/lib/typescript/src/index.d.ts.map +1 -0
  32. package/lib/typescript/src/types.d.ts +37 -0
  33. package/lib/typescript/src/types.d.ts.map +1 -0
  34. package/package.json +138 -25
  35. package/src/VConsole.tsx +887 -0
  36. package/src/core/consoleProxy.ts +108 -0
  37. package/src/core/xhrProxy.ts +319 -0
  38. package/src/index.tsx +36 -0
  39. package/src/types.ts +42 -0
  40. package/android/README.md +0 -14
  41. package/android/src/main/java/wiki/qdc/rn/vconsole/ReactNativeVconsoleModule.java +0 -27
  42. package/android/src/main/java/wiki/qdc/rn/vconsole/ReactNativeVconsolePackage.java +0 -23
  43. package/index.js +0 -5
  44. package/ios/.DS_Store +0 -0
  45. package/ios/ReactNativeVconsole.h +0 -5
  46. package/ios/ReactNativeVconsole.m +0 -13
  47. package/ios/ReactNativeVconsole.xcodeproj/project.pbxproj +0 -281
  48. package/ios/ReactNativeVconsole.xcworkspace/contents.xcworkspacedata +0 -7
  49. package/react-native-vconsole.podspec +0 -28
@@ -0,0 +1,780 @@
1
+ "use strict";
2
+
3
+ import { useEffect, useMemo, useRef, useState } from 'react';
4
+ import { Animated, Clipboard, Dimensions, FlatList, NativeModules, PanResponder, Platform, Pressable, StatusBar, StyleSheet, Text, View, ScrollView } from 'react-native';
5
+ import { clearLogEntries, getLogEntries, installConsoleProxy, subscribeLogEntries, uninstallConsoleProxy } from "./core/consoleProxy.js";
6
+ import { clearNetworkEntries, getNetworkEntries, installXhrProxy, subscribeNetworkEntries, uninstallXhrProxy } from "./core/xhrProxy.js";
7
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
+ const BUTTON_WIDTH = 88;
9
+ const BUTTON_HEIGHT = 36;
10
+ const PANEL_HEIGHT_RATIO = 7 / 9;
11
+ const EMPTY_FILTER = [];
12
+ const LOG_SUB_TABS = ['All', 'log', 'info', 'warn', 'error'];
13
+ const ROOT_TABS = ['Log', 'Network', 'System', 'App'];
14
+ const LOG_THEME = {
15
+ log: {
16
+ backgroundColor: '#FFFFFF',
17
+ color: '#111111'
18
+ },
19
+ info: {
20
+ backgroundColor: '#FFFFFF',
21
+ color: '#246BFD'
22
+ },
23
+ warn: {
24
+ backgroundColor: '#FFF8E6',
25
+ color: '#A65A00'
26
+ },
27
+ error: {
28
+ backgroundColor: '#FFECEC',
29
+ color: '#9C1C1C'
30
+ }
31
+ };
32
+ function clamp(value, min, max) {
33
+ return Math.min(Math.max(value, min), max);
34
+ }
35
+ function getDisplayValue(value) {
36
+ if (typeof value === 'string') {
37
+ return value;
38
+ }
39
+ try {
40
+ return JSON.stringify(value);
41
+ } catch {
42
+ return String(value);
43
+ }
44
+ }
45
+ function copyToClipboard(value) {
46
+ Clipboard.setString(value);
47
+ }
48
+ function prettyText(value) {
49
+ if (value === undefined) {
50
+ return '';
51
+ }
52
+ if (typeof value === 'string') {
53
+ return value;
54
+ }
55
+ try {
56
+ return JSON.stringify(value, null, 2);
57
+ } catch {
58
+ return String(value);
59
+ }
60
+ }
61
+ function buildNetworkCopyText(item) {
62
+ const status = item.status ?? '-';
63
+ const duration = typeof item.durationMs === 'number' ? `${item.durationMs}ms` : '-';
64
+ return [`${item.method} ${item.url}`, `status ${status} duration ${duration}`, `request headers\n${prettyText(item.requestHeaders)}`, `request body\n${prettyText(item.requestBody)}`, `response headers\n${prettyText(item.responseHeaders)}`, `response data\n${prettyText(item.responseData)}`].join('\n');
65
+ }
66
+ function ObjectTree({
67
+ value,
68
+ nodeKey,
69
+ expandedMap,
70
+ onToggle
71
+ }) {
72
+ if (value === null || value === undefined) {
73
+ return /*#__PURE__*/_jsx(Text, {
74
+ style: styles.valuePrimitive,
75
+ children: String(value)
76
+ });
77
+ }
78
+ const valueType = typeof value;
79
+ if (valueType !== 'object') {
80
+ return /*#__PURE__*/_jsx(Text, {
81
+ style: styles.valuePrimitive,
82
+ selectable: true,
83
+ children: getDisplayValue(value)
84
+ });
85
+ }
86
+ const isArray = Array.isArray(value);
87
+ const entries = Object.entries(value);
88
+ const opened = !!expandedMap[nodeKey];
89
+ return /*#__PURE__*/_jsxs(View, {
90
+ style: styles.treeNode,
91
+ children: [/*#__PURE__*/_jsxs(Pressable, {
92
+ onPress: () => onToggle(nodeKey),
93
+ style: styles.treeHeader,
94
+ children: [/*#__PURE__*/_jsx(Text, {
95
+ style: styles.arrow,
96
+ children: opened ? '▼' : '▶'
97
+ }), /*#__PURE__*/_jsx(Text, {
98
+ style: styles.treeLabel,
99
+ children: isArray ? `Array(${entries.length})` : `Object(${entries.length})`
100
+ })]
101
+ }), opened ? /*#__PURE__*/_jsx(View, {
102
+ style: styles.treeChildren,
103
+ children: entries.map(([key, item]) => /*#__PURE__*/_jsxs(View, {
104
+ style: styles.treeChildRow,
105
+ children: [/*#__PURE__*/_jsxs(Text, {
106
+ style: styles.treeKey,
107
+ children: [key, ": "]
108
+ }), /*#__PURE__*/_jsx(ObjectTree, {
109
+ value: item,
110
+ nodeKey: `${nodeKey}.${key}`,
111
+ expandedMap: expandedMap,
112
+ onToggle: onToggle
113
+ })]
114
+ }, `${nodeKey}.${key}`))
115
+ }) : null]
116
+ });
117
+ }
118
+ function ListSeparator() {
119
+ return /*#__PURE__*/_jsx(View, {
120
+ style: styles.separator
121
+ });
122
+ }
123
+ function useFlatListRefs() {
124
+ const allRef = useRef(null);
125
+ const logRef = useRef(null);
126
+ const infoRef = useRef(null);
127
+ const warnRef = useRef(null);
128
+ const errorRef = useRef(null);
129
+ return useMemo(() => ({
130
+ All: allRef,
131
+ log: logRef,
132
+ info: infoRef,
133
+ warn: warnRef,
134
+ error: errorRef
135
+ }), [allRef, errorRef, infoRef, logRef, warnRef]);
136
+ }
137
+ export function VConsole({
138
+ enable = true,
139
+ filter = EMPTY_FILTER
140
+ }) {
141
+ const nativeModule = NativeModules.Vconsole;
142
+ const {
143
+ width,
144
+ height
145
+ } = Dimensions.get('window');
146
+ const topInset = Platform.select({
147
+ ios: 44,
148
+ android: (StatusBar.currentHeight ?? 0) + 8,
149
+ default: 24
150
+ });
151
+ const bottomInset = Platform.select({
152
+ ios: 34,
153
+ android: 56,
154
+ default: 24
155
+ });
156
+ const minX = 0;
157
+ const maxX = width - BUTTON_WIDTH;
158
+ const minY = topInset;
159
+ const maxY = height - bottomInset - BUTTON_HEIGHT;
160
+ const initialY = clamp(height - bottomInset - BUTTON_HEIGHT - 12, minY, maxY);
161
+ const dragPosition = useRef(new Animated.ValueXY({
162
+ x: 12,
163
+ y: initialY
164
+ })).current;
165
+ const dragStartPoint = useRef({
166
+ x: 12,
167
+ y: initialY
168
+ });
169
+ const [panelVisible, setPanelVisible] = useState(false);
170
+ const [activeTab, setActiveTab] = useState('Log');
171
+ const [logSubTab, setLogSubTab] = useState('All');
172
+ const [logEntries, setLogEntries] = useState([]);
173
+ const [networkEntries, setNetworkEntries] = useState([]);
174
+ const [expandedMap, setExpandedMap] = useState({});
175
+ const [systemInfo, setSystemInfo] = useState(null);
176
+ const [appInfo, setAppInfo] = useState(null);
177
+ const panelHeight = Math.floor(height * PANEL_HEIGHT_RATIO);
178
+ const panelTranslateY = useRef(new Animated.Value(panelHeight)).current;
179
+ const logListRefs = useFlatListRefs();
180
+ const networkListRef = useRef(null);
181
+ const normalizedFilter = useMemo(() => filter.map(item => item.trim().toLowerCase()).filter(Boolean), [filter]);
182
+ useEffect(() => {
183
+ if (!enable) {
184
+ setPanelVisible(false);
185
+ return;
186
+ }
187
+ installConsoleProxy();
188
+ installXhrProxy({
189
+ filterHosts: normalizedFilter
190
+ });
191
+ const unsubscribeLog = subscribeLogEntries(setLogEntries);
192
+ const unsubscribeNetwork = subscribeNetworkEntries(setNetworkEntries);
193
+ setLogEntries(getLogEntries());
194
+ setNetworkEntries(getNetworkEntries());
195
+ return () => {
196
+ unsubscribeLog();
197
+ unsubscribeNetwork();
198
+ uninstallConsoleProxy();
199
+ uninstallXhrProxy();
200
+ };
201
+ }, [enable, normalizedFilter]);
202
+ useEffect(() => {
203
+ dragPosition.stopAnimation(value => {
204
+ const nextX = clamp(value.x, minX, maxX);
205
+ const nextY = clamp(value.y, minY, maxY);
206
+ dragPosition.setValue({
207
+ x: nextX,
208
+ y: nextY
209
+ });
210
+ dragStartPoint.current = {
211
+ x: nextX,
212
+ y: nextY
213
+ };
214
+ });
215
+ }, [dragPosition, maxX, maxY, minX, minY]);
216
+ useEffect(() => {
217
+ if (panelVisible && activeTab === 'System' && !systemInfo) {
218
+ nativeModule?.getSystemInfo?.().then(result => setSystemInfo(result)).catch(() => undefined);
219
+ }
220
+ if (panelVisible && activeTab === 'App' && !appInfo) {
221
+ nativeModule?.getAppInfo?.().then(result => setAppInfo(result)).catch(() => undefined);
222
+ }
223
+ }, [activeTab, appInfo, nativeModule, panelVisible, systemInfo]);
224
+ const panResponder = useMemo(() => PanResponder.create({
225
+ onMoveShouldSetPanResponder: () => true,
226
+ onPanResponderGrant: () => {
227
+ dragPosition.stopAnimation(value => {
228
+ dragStartPoint.current = {
229
+ x: value.x,
230
+ y: value.y
231
+ };
232
+ });
233
+ },
234
+ onPanResponderMove: (_, gestureState) => {
235
+ const nextX = clamp(dragStartPoint.current.x + gestureState.dx, minX, maxX);
236
+ const nextY = clamp(dragStartPoint.current.y + gestureState.dy, minY, maxY);
237
+ dragPosition.setValue({
238
+ x: nextX,
239
+ y: nextY
240
+ });
241
+ },
242
+ onPanResponderRelease: () => {
243
+ dragPosition.stopAnimation(value => {
244
+ dragStartPoint.current = {
245
+ x: value.x,
246
+ y: value.y
247
+ };
248
+ });
249
+ }
250
+ }), [dragPosition, maxX, maxY, minX, minY]);
251
+ const openPanel = () => {
252
+ setPanelVisible(true);
253
+ panelTranslateY.setValue(panelHeight);
254
+ Animated.timing(panelTranslateY, {
255
+ toValue: 0,
256
+ duration: 220,
257
+ useNativeDriver: true
258
+ }).start();
259
+ };
260
+ const closePanel = () => {
261
+ Animated.timing(panelTranslateY, {
262
+ toValue: panelHeight,
263
+ duration: 220,
264
+ useNativeDriver: true
265
+ }).start(({
266
+ finished
267
+ }) => {
268
+ if (finished) {
269
+ setPanelVisible(false);
270
+ }
271
+ });
272
+ };
273
+ const logDataByTab = useMemo(() => ({
274
+ All: logEntries,
275
+ log: logEntries.filter(item => item.level === 'log'),
276
+ info: logEntries.filter(item => item.level === 'info'),
277
+ warn: logEntries.filter(item => item.level === 'warn'),
278
+ error: logEntries.filter(item => item.level === 'error')
279
+ }), [logEntries]);
280
+ const onToggleNode = key => {
281
+ setExpandedMap(prev => ({
282
+ ...prev,
283
+ [key]: !prev[key]
284
+ }));
285
+ };
286
+ const scrollLogTop = () => {
287
+ logListRefs[logSubTab].current?.scrollToOffset({
288
+ offset: 0,
289
+ animated: true
290
+ });
291
+ };
292
+ const scrollLogBottom = () => {
293
+ logListRefs[logSubTab].current?.scrollToEnd({
294
+ animated: true
295
+ });
296
+ };
297
+ const scrollNetworkTop = () => {
298
+ networkListRef.current?.scrollToOffset({
299
+ offset: 0,
300
+ animated: true
301
+ });
302
+ };
303
+ const scrollNetworkBottom = () => {
304
+ networkListRef.current?.scrollToEnd({
305
+ animated: true
306
+ });
307
+ };
308
+ const renderRootTab = tab => /*#__PURE__*/_jsx(Pressable, {
309
+ style: [styles.topTabButton, activeTab === tab && styles.topTabButtonActive],
310
+ onPress: () => setActiveTab(tab),
311
+ children: /*#__PURE__*/_jsx(Text, {
312
+ style: [styles.topTabText, activeTab === tab && styles.topTabTextActive],
313
+ children: tab
314
+ })
315
+ }, tab);
316
+ const renderActionButton = (label, onPress) => /*#__PURE__*/_jsx(Pressable, {
317
+ style: styles.actionButton,
318
+ onPress: onPress,
319
+ children: /*#__PURE__*/_jsx(Text, {
320
+ style: styles.actionButtonText,
321
+ children: label
322
+ })
323
+ }, label);
324
+ const renderLogItem = ({
325
+ item
326
+ }) => {
327
+ const levelTheme = LOG_THEME[item.level];
328
+ return /*#__PURE__*/_jsxs(View, {
329
+ style: [styles.listItem, {
330
+ backgroundColor: levelTheme.backgroundColor
331
+ }],
332
+ children: [/*#__PURE__*/_jsxs(View, {
333
+ style: styles.listItemMain,
334
+ children: [/*#__PURE__*/_jsxs(Text, {
335
+ style: [styles.logLevelText, {
336
+ color: levelTheme.color
337
+ }],
338
+ children: ["[", item.level.toUpperCase(), "]"]
339
+ }), /*#__PURE__*/_jsx(View, {
340
+ style: styles.logPayload,
341
+ children: item.args.map((arg, index) => /*#__PURE__*/_jsx(ObjectTree, {
342
+ value: arg,
343
+ nodeKey: `${item.id}.arg.${index}`,
344
+ expandedMap: expandedMap,
345
+ onToggle: onToggleNode
346
+ }, `${item.id}.arg.${index}`))
347
+ })]
348
+ }), /*#__PURE__*/_jsx(Pressable, {
349
+ style: styles.copyButton,
350
+ onPress: () => copyToClipboard(item.text),
351
+ children: /*#__PURE__*/_jsx(Text, {
352
+ style: styles.copyButtonText,
353
+ children: "\u590D\u5236"
354
+ })
355
+ })]
356
+ });
357
+ };
358
+ const renderNetworkItem = ({
359
+ item
360
+ }) => {
361
+ return /*#__PURE__*/_jsxs(View, {
362
+ style: styles.listItem,
363
+ children: [/*#__PURE__*/_jsxs(View, {
364
+ style: styles.listItemMain,
365
+ children: [/*#__PURE__*/_jsxs(Text, {
366
+ style: styles.networkTitle,
367
+ children: [item.method, " ", item.url]
368
+ }), /*#__PURE__*/_jsxs(Text, {
369
+ style: styles.networkLabel,
370
+ children: ["Status: ", item.status ?? '-', ' ', "Duration:", ' ', typeof item.durationMs === 'number' ? `${item.durationMs}ms` : '-']
371
+ }), /*#__PURE__*/_jsxs(View, {
372
+ style: styles.networkBlock,
373
+ children: [/*#__PURE__*/_jsx(Text, {
374
+ style: styles.networkLabel,
375
+ children: "Request Headers"
376
+ }), /*#__PURE__*/_jsx(ObjectTree, {
377
+ value: item.requestHeaders,
378
+ nodeKey: `${item.id}.requestHeaders`,
379
+ expandedMap: expandedMap,
380
+ onToggle: onToggleNode
381
+ })]
382
+ }), /*#__PURE__*/_jsxs(View, {
383
+ style: styles.networkBlock,
384
+ children: [/*#__PURE__*/_jsx(Text, {
385
+ style: styles.networkLabel,
386
+ children: "Request Payload"
387
+ }), /*#__PURE__*/_jsx(ObjectTree, {
388
+ value: item.requestBody ?? '',
389
+ nodeKey: `${item.id}.requestBody`,
390
+ expandedMap: expandedMap,
391
+ onToggle: onToggleNode
392
+ })]
393
+ }), /*#__PURE__*/_jsxs(View, {
394
+ style: styles.networkBlock,
395
+ children: [/*#__PURE__*/_jsx(Text, {
396
+ style: styles.networkLabel,
397
+ children: "Response Headers"
398
+ }), /*#__PURE__*/_jsx(ObjectTree, {
399
+ value: item.responseHeaders,
400
+ nodeKey: `${item.id}.responseHeaders`,
401
+ expandedMap: expandedMap,
402
+ onToggle: onToggleNode
403
+ })]
404
+ }), /*#__PURE__*/_jsxs(View, {
405
+ style: styles.networkBlock,
406
+ children: [/*#__PURE__*/_jsx(Text, {
407
+ style: styles.networkLabel,
408
+ children: "Response Data"
409
+ }), /*#__PURE__*/_jsx(ScrollView, {
410
+ horizontal: true,
411
+ children: /*#__PURE__*/_jsx(ObjectTree, {
412
+ value: item.responseData ?? '',
413
+ nodeKey: `${item.id}.responseData`,
414
+ expandedMap: expandedMap,
415
+ onToggle: onToggleNode
416
+ })
417
+ })]
418
+ })]
419
+ }), /*#__PURE__*/_jsx(Pressable, {
420
+ style: styles.copyButton,
421
+ onPress: () => copyToClipboard(buildNetworkCopyText(item)),
422
+ children: /*#__PURE__*/_jsx(Text, {
423
+ style: styles.copyButtonText,
424
+ children: "\u590D\u5236"
425
+ })
426
+ })]
427
+ });
428
+ };
429
+ const renderLogPanel = () => /*#__PURE__*/_jsxs(View, {
430
+ style: styles.contentArea,
431
+ children: [/*#__PURE__*/_jsx(View, {
432
+ style: styles.subTabRow,
433
+ children: LOG_SUB_TABS.map(tab => /*#__PURE__*/_jsx(Pressable, {
434
+ style: [styles.subTabButton, logSubTab === tab && styles.subTabButtonActive],
435
+ onPress: () => setLogSubTab(tab),
436
+ children: /*#__PURE__*/_jsx(Text, {
437
+ style: [styles.subTabText, logSubTab === tab && styles.subTabTextActive],
438
+ children: tab
439
+ })
440
+ }, tab))
441
+ }), /*#__PURE__*/_jsx(View, {
442
+ style: styles.logListsWrap,
443
+ children: LOG_SUB_TABS.map(tab => /*#__PURE__*/_jsx(View, {
444
+ style: [styles.listHost, logSubTab !== tab && styles.hidden],
445
+ children: /*#__PURE__*/_jsx(FlatList, {
446
+ ref: logListRefs[tab],
447
+ data: logDataByTab[tab],
448
+ keyExtractor: item => `${tab}-${item.id}`,
449
+ renderItem: renderLogItem,
450
+ ItemSeparatorComponent: ListSeparator
451
+ })
452
+ }, tab))
453
+ }), /*#__PURE__*/_jsxs(View, {
454
+ style: styles.actionsRow,
455
+ children: [renderActionButton('Clear', () => {
456
+ clearLogEntries();
457
+ setExpandedMap({});
458
+ }), renderActionButton('Top', scrollLogTop), renderActionButton('Bottom', scrollLogBottom), renderActionButton('Hide', closePanel)]
459
+ })]
460
+ });
461
+ const renderNetworkPanel = () => /*#__PURE__*/_jsxs(View, {
462
+ style: styles.contentArea,
463
+ children: [/*#__PURE__*/_jsx(FlatList, {
464
+ ref: networkListRef,
465
+ data: networkEntries,
466
+ keyExtractor: item => `network-${item.id}`,
467
+ renderItem: renderNetworkItem,
468
+ ItemSeparatorComponent: ListSeparator
469
+ }), /*#__PURE__*/_jsxs(View, {
470
+ style: styles.actionsRow,
471
+ children: [renderActionButton('Clear', () => {
472
+ clearNetworkEntries();
473
+ setExpandedMap({});
474
+ }), renderActionButton('Top', scrollNetworkTop), renderActionButton('Bottom', scrollNetworkBottom), renderActionButton('Hide', closePanel)]
475
+ })]
476
+ });
477
+ const renderSystemPanel = () => /*#__PURE__*/_jsxs(View, {
478
+ style: styles.contentArea,
479
+ children: [/*#__PURE__*/_jsxs(View, {
480
+ style: styles.infoCard,
481
+ children: [/*#__PURE__*/_jsxs(Text, {
482
+ style: styles.infoText,
483
+ children: ["\u5382\u5546/\u54C1\u724C: ", systemInfo?.manufacturer ?? '-']
484
+ }), /*#__PURE__*/_jsxs(Text, {
485
+ style: styles.infoText,
486
+ children: ["\u673A\u578B: ", systemInfo?.model ?? '-']
487
+ }), /*#__PURE__*/_jsxs(Text, {
488
+ style: styles.infoText,
489
+ children: ["\u7CFB\u7EDF\u7248\u672C: ", systemInfo?.osVersion ?? '-']
490
+ }), Platform.OS === 'android' ? /*#__PURE__*/_jsxs(Text, {
491
+ style: styles.infoText,
492
+ children: ["\u7F51\u7EDC\u7C7B\u578B: ", systemInfo?.networkType ?? '-']
493
+ }) : null, Platform.OS === 'android' ? /*#__PURE__*/_jsxs(Text, {
494
+ style: styles.infoText,
495
+ children: ["\u7F51\u7EDC\u53EF\u8FBE: ", systemInfo?.isNetworkReachable ? 'true' : 'false']
496
+ }) : null, /*#__PURE__*/_jsxs(Text, {
497
+ style: styles.infoText,
498
+ children: ["\u603B\u5185\u5B58: ", systemInfo?.totalMemory ?? 0]
499
+ }), Platform.OS === 'android' ? /*#__PURE__*/_jsxs(Text, {
500
+ style: styles.infoText,
501
+ children: ["\u53EF\u7528\u5185\u5B58: ", systemInfo?.availableMemory ?? 0]
502
+ }) : null]
503
+ }), /*#__PURE__*/_jsx(View, {
504
+ style: styles.actionsRow,
505
+ children: renderActionButton('Hide', closePanel)
506
+ })]
507
+ });
508
+ const renderAppPanel = () => /*#__PURE__*/_jsxs(View, {
509
+ style: styles.contentArea,
510
+ children: [/*#__PURE__*/_jsxs(View, {
511
+ style: styles.infoCard,
512
+ children: [/*#__PURE__*/_jsxs(Text, {
513
+ style: styles.infoText,
514
+ children: ["App Version: ", appInfo?.appVersion ?? '-']
515
+ }), /*#__PURE__*/_jsxs(Text, {
516
+ style: styles.infoText,
517
+ children: ["Build Number: ", appInfo?.buildNumber ?? '-']
518
+ })]
519
+ }), /*#__PURE__*/_jsx(View, {
520
+ style: styles.actionsRow,
521
+ children: renderActionButton('Hide', closePanel)
522
+ })]
523
+ });
524
+ if (!enable) {
525
+ return null;
526
+ }
527
+ return /*#__PURE__*/_jsxs(View, {
528
+ pointerEvents: "box-none",
529
+ style: StyleSheet.absoluteFill,
530
+ children: [!panelVisible ? /*#__PURE__*/_jsx(Animated.View, {
531
+ style: [styles.floatingButtonWrap, {
532
+ transform: dragPosition.getTranslateTransform()
533
+ }],
534
+ ...panResponder.panHandlers,
535
+ children: /*#__PURE__*/_jsx(Pressable, {
536
+ style: styles.floatingButton,
537
+ onPress: openPanel,
538
+ children: /*#__PURE__*/_jsx(Text, {
539
+ style: styles.floatingButtonText,
540
+ children: "vConsole"
541
+ })
542
+ })
543
+ }) : null, panelVisible ? /*#__PURE__*/_jsxs(View, {
544
+ style: styles.overlayWrap,
545
+ children: [/*#__PURE__*/_jsx(Pressable, {
546
+ style: styles.mask,
547
+ onPress: closePanel
548
+ }), /*#__PURE__*/_jsxs(Animated.View, {
549
+ style: [styles.panel, {
550
+ height: panelHeight,
551
+ transform: [{
552
+ translateY: panelTranslateY
553
+ }]
554
+ }],
555
+ children: [/*#__PURE__*/_jsx(View, {
556
+ style: styles.topTabRow,
557
+ children: ROOT_TABS.map(renderRootTab)
558
+ }), activeTab === 'Log' ? renderLogPanel() : null, activeTab === 'Network' ? renderNetworkPanel() : null, activeTab === 'System' ? renderSystemPanel() : null, activeTab === 'App' ? renderAppPanel() : null]
559
+ })]
560
+ }) : null]
561
+ });
562
+ }
563
+ const styles = StyleSheet.create({
564
+ floatingButtonWrap: {
565
+ position: 'absolute',
566
+ zIndex: 9999
567
+ },
568
+ floatingButton: {
569
+ width: BUTTON_WIDTH,
570
+ height: BUTTON_HEIGHT,
571
+ borderRadius: 12,
572
+ backgroundColor: '#22A455',
573
+ justifyContent: 'center',
574
+ alignItems: 'center'
575
+ },
576
+ floatingButtonText: {
577
+ color: '#FFFFFF',
578
+ fontSize: 12,
579
+ fontWeight: '600'
580
+ },
581
+ overlayWrap: {
582
+ ...StyleSheet.absoluteFillObject,
583
+ justifyContent: 'flex-end'
584
+ },
585
+ mask: {
586
+ ...StyleSheet.absoluteFillObject,
587
+ backgroundColor: 'rgba(0, 0, 0, 0.25)'
588
+ },
589
+ panel: {
590
+ width: '100%',
591
+ backgroundColor: '#FFFFFF',
592
+ borderTopLeftRadius: 14,
593
+ borderTopRightRadius: 14,
594
+ overflow: 'hidden'
595
+ },
596
+ topTabRow: {
597
+ flexDirection: 'row',
598
+ borderBottomWidth: StyleSheet.hairlineWidth,
599
+ borderBottomColor: '#D9D9D9',
600
+ paddingHorizontal: 8,
601
+ paddingVertical: 8
602
+ },
603
+ topTabButton: {
604
+ paddingHorizontal: 12,
605
+ paddingVertical: 8,
606
+ borderRadius: 8
607
+ },
608
+ topTabButtonActive: {
609
+ backgroundColor: '#EEF5FF'
610
+ },
611
+ topTabText: {
612
+ color: '#444444',
613
+ fontSize: 13,
614
+ fontWeight: '500'
615
+ },
616
+ topTabTextActive: {
617
+ color: '#246BFD'
618
+ },
619
+ contentArea: {
620
+ flex: 1,
621
+ paddingBottom: 16
622
+ },
623
+ subTabRow: {
624
+ flexDirection: 'row',
625
+ paddingHorizontal: 8,
626
+ paddingVertical: 8,
627
+ borderBottomWidth: StyleSheet.hairlineWidth,
628
+ borderBottomColor: '#E0E0E0'
629
+ },
630
+ subTabButton: {
631
+ marginRight: 8,
632
+ paddingHorizontal: 10,
633
+ paddingVertical: 6,
634
+ borderRadius: 8
635
+ },
636
+ subTabButtonActive: {
637
+ backgroundColor: '#EEF5FF'
638
+ },
639
+ subTabText: {
640
+ color: '#666666',
641
+ fontSize: 12
642
+ },
643
+ subTabTextActive: {
644
+ color: '#246BFD'
645
+ },
646
+ logListsWrap: {
647
+ flex: 1
648
+ },
649
+ listHost: {
650
+ flex: 1
651
+ },
652
+ hidden: {
653
+ display: 'none'
654
+ },
655
+ listItem: {
656
+ paddingHorizontal: 10,
657
+ paddingVertical: 10,
658
+ flexDirection: 'column',
659
+ position: 'relative'
660
+ },
661
+ listItemMain: {
662
+ flex: 1,
663
+ marginRight: 8
664
+ },
665
+ separator: {
666
+ height: StyleSheet.hairlineWidth,
667
+ backgroundColor: '#DFDFDF'
668
+ },
669
+ logLevelText: {
670
+ fontSize: 11,
671
+ fontWeight: '700',
672
+ marginBottom: 4
673
+ },
674
+ logPayload: {
675
+ flex: 1
676
+ },
677
+ copyButton: {
678
+ position: 'absolute',
679
+ right: 8,
680
+ top: 8,
681
+ borderWidth: StyleSheet.hairlineWidth,
682
+ borderColor: '#D0D0D0',
683
+ borderRadius: 6,
684
+ paddingVertical: 4,
685
+ paddingHorizontal: 8
686
+ },
687
+ copyButtonText: {
688
+ fontSize: 11,
689
+ color: '#333333'
690
+ },
691
+ valuePrimitive: {
692
+ color: '#222222',
693
+ fontSize: 12,
694
+ flexShrink: 1
695
+ },
696
+ treeNode: {
697
+ flexDirection: 'column',
698
+ marginBottom: 4
699
+ },
700
+ treeHeader: {
701
+ flexDirection: 'row',
702
+ alignItems: 'center'
703
+ },
704
+ arrow: {
705
+ color: '#666666',
706
+ fontSize: 11,
707
+ marginRight: 4
708
+ },
709
+ treeLabel: {
710
+ color: '#444444',
711
+ fontSize: 12,
712
+ fontWeight: '500'
713
+ },
714
+ treeChildren: {
715
+ marginLeft: 14,
716
+ marginTop: 4
717
+ },
718
+ treeChildRow: {
719
+ flexDirection: 'row',
720
+ alignItems: 'flex-start',
721
+ marginBottom: 2
722
+ },
723
+ treeChildColumn: {
724
+ flexDirection: 'column',
725
+ alignItems: 'flex-start',
726
+ marginBottom: 2
727
+ },
728
+ treeKey: {
729
+ color: '#666666',
730
+ fontSize: 12
731
+ },
732
+ networkTitle: {
733
+ fontSize: 12,
734
+ color: '#111111',
735
+ fontWeight: '600',
736
+ marginBottom: 6
737
+ },
738
+ networkBlock: {
739
+ marginTop: 2,
740
+ marginBottom: 2
741
+ },
742
+ networkLabel: {
743
+ fontSize: 12,
744
+ color: '#444444',
745
+ marginBottom: 2
746
+ },
747
+ actionsRow: {
748
+ borderTopWidth: StyleSheet.hairlineWidth,
749
+ borderTopColor: '#E1E1E1',
750
+ paddingHorizontal: 8,
751
+ paddingVertical: 8,
752
+ flexDirection: 'row',
753
+ justifyContent: 'space-around'
754
+ },
755
+ actionButton: {
756
+ minWidth: 62,
757
+ borderRadius: 8,
758
+ borderWidth: StyleSheet.hairlineWidth,
759
+ borderColor: '#D0D0D0',
760
+ paddingHorizontal: 10,
761
+ paddingVertical: 7,
762
+ alignItems: 'center'
763
+ },
764
+ actionButtonText: {
765
+ color: '#333333',
766
+ fontSize: 12,
767
+ fontWeight: '500'
768
+ },
769
+ infoCard: {
770
+ flex: 1,
771
+ paddingHorizontal: 12,
772
+ paddingVertical: 12
773
+ },
774
+ infoText: {
775
+ fontSize: 13,
776
+ color: '#222222',
777
+ marginBottom: 8
778
+ }
779
+ });
780
+ //# sourceMappingURL=VConsole.js.map