react-native-inapp-inspector 2.0.7 → 2.2.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.
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +0 -11
- package/dist/commonjs/components/Inspector/InspectorHeader.js +25 -28
- package/dist/commonjs/components/Inspector/MainScreen.js +2 -19
- package/dist/commonjs/components/Inspector/NetworkDetail.js +0 -15
- package/dist/commonjs/components/Inspector/PerformanceTab.js +18 -30
- package/dist/commonjs/components/Inspector/SettingsPanel.js +49 -448
- package/dist/commonjs/components/Inspector/TabBar.js +2 -23
- package/dist/commonjs/components/NetworkIcons.d.ts +0 -12
- package/dist/commonjs/components/NetworkIcons.js +3 -72
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/helpers/index.d.ts +0 -2
- package/dist/commonjs/helpers/index.js +1 -12
- package/dist/commonjs/helpers/settingsStore.d.ts +1 -1
- package/dist/commonjs/helpers/settingsStore.js +2 -4
- package/dist/commonjs/i18n/locales/en.json +2 -3
- package/dist/commonjs/index.d.ts +0 -1
- package/dist/commonjs/index.js +9 -127
- package/dist/commonjs/native/NativeInspector.d.ts +0 -1
- package/dist/commonjs/types/enums.d.ts +0 -7
- package/dist/commonjs/types/enums.js +0 -7
- package/dist/commonjs/types/interfaces.d.ts +0 -77
- package/dist/esm/components/Inspector/InspectorHeader.js +25 -28
- package/dist/esm/components/Inspector/MainScreen.js +2 -19
- package/dist/esm/components/Inspector/NetworkDetail.js +1 -16
- package/dist/esm/components/Inspector/PerformanceTab.js +19 -31
- package/dist/esm/components/Inspector/SettingsPanel.js +50 -449
- package/dist/esm/components/Inspector/TabBar.js +3 -24
- package/dist/esm/components/NetworkIcons.d.ts +0 -12
- package/dist/esm/components/NetworkIcons.js +0 -57
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/helpers/index.d.ts +0 -2
- package/dist/esm/helpers/index.js +0 -10
- package/dist/esm/helpers/settingsStore.d.ts +1 -1
- package/dist/esm/helpers/settingsStore.js +2 -4
- package/dist/esm/i18n/locales/en.json +2 -3
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.js +8 -123
- package/dist/esm/native/NativeInspector.d.ts +0 -1
- package/dist/esm/types/enums.d.ts +0 -7
- package/dist/esm/types/enums.js +0 -7
- package/dist/esm/types/interfaces.d.ts +0 -77
- package/ios/NetworkInspectorModule.mm +5 -12
- package/package.json +1 -4
- package/dist/commonjs/components/Inspector/AuditTab.d.ts +0 -3
- package/dist/commonjs/components/Inspector/AuditTab.js +0 -741
- package/dist/commonjs/components/Inspector/DeviceTab.d.ts +0 -3
- package/dist/commonjs/components/Inspector/DeviceTab.js +0 -717
- package/dist/commonjs/components/Inspector/FirstTimeWalkthroughModal.d.ts +0 -7
- package/dist/commonjs/components/Inspector/FirstTimeWalkthroughModal.js +0 -600
- package/dist/commonjs/components/Inspector/PerformanceHud.d.ts +0 -7
- package/dist/commonjs/components/Inspector/PerformanceHud.js +0 -210
- package/dist/commonjs/components/Inspector/RequestReplayModal.d.ts +0 -9
- package/dist/commonjs/components/Inspector/RequestReplayModal.js +0 -792
- package/dist/commonjs/components/Inspector/RequestReplayView.d.ts +0 -8
- package/dist/commonjs/components/Inspector/RequestReplayView.js +0 -871
- package/dist/commonjs/components/Inspector/StorageTab.d.ts +0 -3
- package/dist/commonjs/components/Inspector/StorageTab.js +0 -610
- package/dist/commonjs/customHooks/storageInspector.d.ts +0 -13
- package/dist/commonjs/customHooks/storageInspector.js +0 -179
- package/dist/commonjs/helpers/deviceInfo.d.ts +0 -4
- package/dist/commonjs/helpers/deviceInfo.js +0 -94
- package/dist/commonjs/helpers/packageAuditor.d.ts +0 -5
- package/dist/commonjs/helpers/packageAuditor.js +0 -182
- package/dist/esm/components/Inspector/AuditTab.d.ts +0 -3
- package/dist/esm/components/Inspector/AuditTab.js +0 -702
- package/dist/esm/components/Inspector/DeviceTab.d.ts +0 -3
- package/dist/esm/components/Inspector/DeviceTab.js +0 -678
- package/dist/esm/components/Inspector/FirstTimeWalkthroughModal.d.ts +0 -7
- package/dist/esm/components/Inspector/FirstTimeWalkthroughModal.js +0 -560
- package/dist/esm/components/Inspector/PerformanceHud.d.ts +0 -7
- package/dist/esm/components/Inspector/PerformanceHud.js +0 -170
- package/dist/esm/components/Inspector/RequestReplayModal.d.ts +0 -9
- package/dist/esm/components/Inspector/RequestReplayModal.js +0 -752
- package/dist/esm/components/Inspector/RequestReplayView.d.ts +0 -8
- package/dist/esm/components/Inspector/RequestReplayView.js +0 -831
- package/dist/esm/components/Inspector/StorageTab.d.ts +0 -3
- package/dist/esm/components/Inspector/StorageTab.js +0 -571
- package/dist/esm/customHooks/storageInspector.d.ts +0 -13
- package/dist/esm/customHooks/storageInspector.js +0 -170
- package/dist/esm/helpers/deviceInfo.d.ts +0 -4
- package/dist/esm/helpers/deviceInfo.js +0 -89
- package/dist/esm/helpers/packageAuditor.d.ts +0 -5
- package/dist/esm/helpers/packageAuditor.js +0 -173
|
@@ -1,678 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect, useMemo } from 'react';
|
|
2
|
-
import { Platform, ScrollView, StyleSheet, Text, TextInput, View, } from 'react-native';
|
|
3
|
-
import { useInspector } from './InspectorContext';
|
|
4
|
-
import TouchableScale from '../TouchableScale';
|
|
5
|
-
import { AppColors } from '../../styles/AppColors';
|
|
6
|
-
import { AppFonts } from '../../styles/AppFonts';
|
|
7
|
-
import { copyToClipboard, formatBytes } from '../../helpers';
|
|
8
|
-
import { showToast } from '../../helpers/toast';
|
|
9
|
-
import { DevicePhoneIcon, AppleIcon, AndroidIcon, CopyIcon, CodeIcon, SearchIcon, ClearIcon, CpuIcon, FingerprintIcon, MonitorIcon, } from '../NetworkIcons';
|
|
10
|
-
import { getNativeDeviceMetrics } from '../../native/NativeInspector';
|
|
11
|
-
export const DeviceTab = React.memo(() => {
|
|
12
|
-
const { deviceInfo } = useInspector();
|
|
13
|
-
const [activeSubTab, setActiveSubTab] = useState('overview');
|
|
14
|
-
const [nativeMetrics, setNativeMetrics] = useState(null);
|
|
15
|
-
const [search, setSearch] = useState('');
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
let cancelled = false;
|
|
18
|
-
getNativeDeviceMetrics().then(metrics => {
|
|
19
|
-
if (!cancelled && metrics) {
|
|
20
|
-
setNativeMetrics(metrics);
|
|
21
|
-
}
|
|
22
|
-
}).catch(() => { });
|
|
23
|
-
return () => {
|
|
24
|
-
cancelled = true;
|
|
25
|
-
};
|
|
26
|
-
}, []);
|
|
27
|
-
const deviceId = nativeMetrics?.deviceId || deviceInfo.deviceId || 'UNKNOWN-DEVICE-ID';
|
|
28
|
-
const handleCopyDeviceId = () => {
|
|
29
|
-
copyToClipboard(deviceId, 'Device ID');
|
|
30
|
-
showToast('Copied Device ID to clipboard!');
|
|
31
|
-
};
|
|
32
|
-
const handleCopyDiagnostics = () => {
|
|
33
|
-
const fullReport = {
|
|
34
|
-
...deviceInfo,
|
|
35
|
-
deviceId,
|
|
36
|
-
nativeMetrics: nativeMetrics || undefined,
|
|
37
|
-
};
|
|
38
|
-
copyToClipboard(JSON.stringify(fullReport, null, 2), 'Device Diagnostics Report');
|
|
39
|
-
showToast('Copied full system diagnostics!');
|
|
40
|
-
};
|
|
41
|
-
// Sub-tabs list
|
|
42
|
-
const subTabs = [
|
|
43
|
-
{ key: 'overview', label: 'Overview', icon: 'device' },
|
|
44
|
-
{ key: 'hardware', label: 'Hardware', icon: 'cpu' },
|
|
45
|
-
{ key: 'display', label: 'Display', icon: 'monitor' },
|
|
46
|
-
{ key: 'runtime', label: 'Runtime', icon: 'code' },
|
|
47
|
-
{ key: 'raw', label: 'Raw JSON', icon: 'raw' },
|
|
48
|
-
];
|
|
49
|
-
const InfoRow = ({ label, value, badge, badgeColor, copyable, }) => {
|
|
50
|
-
const strVal = value !== undefined && value !== null ? String(value) : '—';
|
|
51
|
-
return (<View style={styles.infoRow}>
|
|
52
|
-
<Text style={styles.infoLabel}>{label}</Text>
|
|
53
|
-
<View style={styles.infoValueRow}>
|
|
54
|
-
{badge && (<View style={[
|
|
55
|
-
styles.inlineBadge,
|
|
56
|
-
{
|
|
57
|
-
backgroundColor: badgeColor
|
|
58
|
-
? `${badgeColor}18`
|
|
59
|
-
: `${AppColors.purple}18`,
|
|
60
|
-
borderColor: badgeColor
|
|
61
|
-
? `${badgeColor}40`
|
|
62
|
-
: `${AppColors.purple}40`,
|
|
63
|
-
},
|
|
64
|
-
]}>
|
|
65
|
-
<Text style={[
|
|
66
|
-
styles.inlineBadgeText,
|
|
67
|
-
{ color: badgeColor || AppColors.purple },
|
|
68
|
-
]}>
|
|
69
|
-
{badge}
|
|
70
|
-
</Text>
|
|
71
|
-
</View>)}
|
|
72
|
-
<Text style={styles.infoValue} numberOfLines={2}>
|
|
73
|
-
{strVal}
|
|
74
|
-
</Text>
|
|
75
|
-
{copyable && strVal !== '—' && (<TouchableScale onPress={() => {
|
|
76
|
-
copyToClipboard(strVal, label);
|
|
77
|
-
showToast(`Copied ${label}!`);
|
|
78
|
-
}} style={styles.inlineCopyBtn}>
|
|
79
|
-
<CopyIcon size={12} color={AppColors.purple}/>
|
|
80
|
-
</TouchableScale>)}
|
|
81
|
-
</View>
|
|
82
|
-
</View>);
|
|
83
|
-
};
|
|
84
|
-
// Filtered raw json representation
|
|
85
|
-
const rawReportJson = useMemo(() => {
|
|
86
|
-
const data = {
|
|
87
|
-
deviceId,
|
|
88
|
-
platform: deviceInfo.platform,
|
|
89
|
-
deviceModel: deviceInfo.deviceModel,
|
|
90
|
-
osVersion: deviceInfo.osVersion,
|
|
91
|
-
appName: deviceInfo.appName,
|
|
92
|
-
bundleId: deviceInfo.bundleId,
|
|
93
|
-
appVersion: deviceInfo.appVersion,
|
|
94
|
-
buildNumber: deviceInfo.buildNumber,
|
|
95
|
-
reactNativeVersion: deviceInfo.reactNativeVersion,
|
|
96
|
-
jsEngine: deviceInfo.jsEngine,
|
|
97
|
-
isHermes: deviceInfo.isHermes,
|
|
98
|
-
isFabric: deviceInfo.isFabric,
|
|
99
|
-
isTurboModule: deviceInfo.isTurboModule,
|
|
100
|
-
arch: deviceInfo.arch,
|
|
101
|
-
screenWidth: deviceInfo.screenWidth,
|
|
102
|
-
screenHeight: deviceInfo.screenHeight,
|
|
103
|
-
screenScale: deviceInfo.screenScale,
|
|
104
|
-
screenFontScale: deviceInfo.screenFontScale,
|
|
105
|
-
statusBarHeight: deviceInfo.statusBarHeight,
|
|
106
|
-
locale: deviceInfo.locale,
|
|
107
|
-
timeZone: deviceInfo.timeZone,
|
|
108
|
-
isDevice: deviceInfo.isDevice,
|
|
109
|
-
nativeMetrics: nativeMetrics || undefined,
|
|
110
|
-
};
|
|
111
|
-
if (!search || search.trim().length === 0) {
|
|
112
|
-
return JSON.stringify(data, null, 2);
|
|
113
|
-
}
|
|
114
|
-
const q = search.toLowerCase();
|
|
115
|
-
const filtered = {};
|
|
116
|
-
for (const [k, v] of Object.entries(data)) {
|
|
117
|
-
if (k.toLowerCase().includes(q) ||
|
|
118
|
-
String(JSON.stringify(v)).toLowerCase().includes(q)) {
|
|
119
|
-
filtered[k] = v;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return JSON.stringify(filtered, null, 2);
|
|
123
|
-
}, [deviceInfo, deviceId, nativeMetrics, search]);
|
|
124
|
-
return (<View style={styles.container}>
|
|
125
|
-
{/* ─── Top Segmented Tab Layout ────────────────────────────────────────── */}
|
|
126
|
-
<View style={styles.tabBarWrapper}>
|
|
127
|
-
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.subTabBarContainer}>
|
|
128
|
-
{subTabs.map(tab => {
|
|
129
|
-
const isTabActive = activeSubTab === tab.key;
|
|
130
|
-
const iconColor = isTabActive ? AppColors.white : AppColors.grayText;
|
|
131
|
-
return (<TouchableScale key={tab.key} onPress={() => setActiveSubTab(tab.key)} style={[
|
|
132
|
-
styles.subTabButton,
|
|
133
|
-
isTabActive && styles.subTabButtonActive,
|
|
134
|
-
]}>
|
|
135
|
-
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 5 }}>
|
|
136
|
-
{tab.key === 'overview' && <DevicePhoneIcon size={12} color={iconColor}/>}
|
|
137
|
-
{tab.key === 'hardware' && <CpuIcon size={12} color={iconColor}/>}
|
|
138
|
-
{tab.key === 'display' && <MonitorIcon size={12} color={iconColor}/>}
|
|
139
|
-
{tab.key === 'runtime' && <CodeIcon size={12} color={iconColor}/>}
|
|
140
|
-
{tab.key === 'raw' && <CopyIcon size={12} color={iconColor}/>}
|
|
141
|
-
<Text style={[
|
|
142
|
-
styles.subTabText,
|
|
143
|
-
isTabActive && styles.subTabTextActive,
|
|
144
|
-
]}>
|
|
145
|
-
{tab.label}
|
|
146
|
-
</Text>
|
|
147
|
-
</View>
|
|
148
|
-
</TouchableScale>);
|
|
149
|
-
})}
|
|
150
|
-
</ScrollView>
|
|
151
|
-
</View>
|
|
152
|
-
|
|
153
|
-
<ScrollView style={styles.scrollArea} contentContainerStyle={styles.contentContainer} showsVerticalScrollIndicator={false}>
|
|
154
|
-
{/* ─── Hero Device ID Banner (Universal across tabs) ───────────────────── */}
|
|
155
|
-
<View style={styles.deviceIdHeroCard}>
|
|
156
|
-
<View style={styles.deviceIdHeader}>
|
|
157
|
-
<View style={styles.deviceIdBadgeRow}>
|
|
158
|
-
<View style={styles.platformBadge}>
|
|
159
|
-
{deviceInfo.platform === 'ios' ? (<AppleIcon size={14} color={AppColors.purple}/>) : (<AndroidIcon size={14} color={AppColors.purple}/>)}
|
|
160
|
-
<Text style={styles.platformBadgeText}>
|
|
161
|
-
{deviceInfo.platform === 'ios' ? 'Apple iOS' : 'Google Android'}
|
|
162
|
-
</Text>
|
|
163
|
-
</View>
|
|
164
|
-
<View style={styles.idTypeBadge}>
|
|
165
|
-
<FingerprintIcon size={12} color={AppColors.purple}/>
|
|
166
|
-
<Text style={styles.idTypeBadgeText}>
|
|
167
|
-
{deviceInfo.platform === 'ios' ? 'IDFV / Vendor ID' : 'Android ID'}
|
|
168
|
-
</Text>
|
|
169
|
-
</View>
|
|
170
|
-
</View>
|
|
171
|
-
|
|
172
|
-
<TouchableScale onPress={handleCopyDeviceId} style={styles.copyIdPill}>
|
|
173
|
-
<CopyIcon size={11} color={AppColors.white}/>
|
|
174
|
-
<Text style={styles.copyIdPillText}>Copy ID</Text>
|
|
175
|
-
</TouchableScale>
|
|
176
|
-
</View>
|
|
177
|
-
|
|
178
|
-
<Text style={styles.deviceIdValue} selectable numberOfLines={1}>
|
|
179
|
-
{deviceId}
|
|
180
|
-
</Text>
|
|
181
|
-
</View>
|
|
182
|
-
|
|
183
|
-
{/* ─── 1. OVERVIEW SUB-TAB ─────────────────────────────────────────────── */}
|
|
184
|
-
{activeSubTab === 'overview' && (<>
|
|
185
|
-
<View style={styles.headerBanner}>
|
|
186
|
-
<View style={styles.headerLeft}>
|
|
187
|
-
<View style={styles.deviceIconBox}>
|
|
188
|
-
{deviceInfo.platform === 'ios' ? (<AppleIcon size={22} color={AppColors.purple}/>) : (<AndroidIcon size={22} color={AppColors.purple}/>)}
|
|
189
|
-
</View>
|
|
190
|
-
<View style={{ flex: 1 }}>
|
|
191
|
-
<Text style={styles.deviceTitle}>{deviceInfo.deviceModel}</Text>
|
|
192
|
-
<Text style={styles.deviceSubtitle}>{deviceInfo.osVersion}</Text>
|
|
193
|
-
</View>
|
|
194
|
-
</View>
|
|
195
|
-
|
|
196
|
-
<TouchableScale onPress={handleCopyDiagnostics} style={styles.copyDiagnosticsBtn}>
|
|
197
|
-
<CopyIcon size={12} color={AppColors.white}/>
|
|
198
|
-
<Text style={styles.copyDiagnosticsText}>Copy Report</Text>
|
|
199
|
-
</TouchableScale>
|
|
200
|
-
</View>
|
|
201
|
-
|
|
202
|
-
{/* Quick Spec Matrix */}
|
|
203
|
-
<View style={styles.matrixGrid}>
|
|
204
|
-
<View style={styles.matrixCard}>
|
|
205
|
-
<Text style={styles.matrixLabel}>ENGINE</Text>
|
|
206
|
-
<Text style={styles.matrixValue}>{deviceInfo.jsEngine}</Text>
|
|
207
|
-
<Text style={styles.matrixSub}>
|
|
208
|
-
{deviceInfo.isHermes ? '⚡ Bytecode' : 'JIT Runtime'}
|
|
209
|
-
</Text>
|
|
210
|
-
</View>
|
|
211
|
-
<View style={styles.matrixCard}>
|
|
212
|
-
<Text style={styles.matrixLabel}>ARCHITECTURE</Text>
|
|
213
|
-
<Text style={styles.matrixValue}>
|
|
214
|
-
{deviceInfo.isFabric ? 'Fabric' : 'Paper'}
|
|
215
|
-
</Text>
|
|
216
|
-
<Text style={styles.matrixSub}>
|
|
217
|
-
{deviceInfo.arch || 'arm64'}
|
|
218
|
-
</Text>
|
|
219
|
-
</View>
|
|
220
|
-
<View style={styles.matrixCard}>
|
|
221
|
-
<Text style={styles.matrixLabel}>REACT NATIVE</Text>
|
|
222
|
-
<Text style={styles.matrixValue}>v{deviceInfo.reactNativeVersion}</Text>
|
|
223
|
-
<Text style={styles.matrixSub}>Framework</Text>
|
|
224
|
-
</View>
|
|
225
|
-
<View style={styles.matrixCard}>
|
|
226
|
-
<Text style={styles.matrixLabel}>DISPLAY</Text>
|
|
227
|
-
<Text style={styles.matrixValue}>
|
|
228
|
-
{deviceInfo.screenWidth}×{deviceInfo.screenHeight}
|
|
229
|
-
</Text>
|
|
230
|
-
<Text style={styles.matrixSub}>@{deviceInfo.screenScale}x Density</Text>
|
|
231
|
-
</View>
|
|
232
|
-
</View>
|
|
233
|
-
|
|
234
|
-
{/* App Overview Summary */}
|
|
235
|
-
<View style={styles.card}>
|
|
236
|
-
<View style={styles.cardTitleRow}>
|
|
237
|
-
<CodeIcon size={14} color={AppColors.purple}/>
|
|
238
|
-
<Text style={styles.cardTitle}>APPLICATION IDENTITY</Text>
|
|
239
|
-
</View>
|
|
240
|
-
<View style={styles.cardBody}>
|
|
241
|
-
<InfoRow label="Application Name" value={deviceInfo.appName} copyable/>
|
|
242
|
-
<InfoRow label="Bundle / Package ID" value={deviceInfo.bundleId} copyable/>
|
|
243
|
-
<InfoRow label="Version" value={`${deviceInfo.appVersion} (${deviceInfo.buildNumber})`}/>
|
|
244
|
-
<InfoRow label="Environment" value={deviceInfo.isDevice ? 'Physical Hardware Device' : 'Simulator / Emulator'} badge={deviceInfo.isDevice ? 'Physical' : 'Simulator'} badgeColor={deviceInfo.isDevice ? AppColors.emerald600 : AppColors.purple}/>
|
|
245
|
-
</View>
|
|
246
|
-
</View>
|
|
247
|
-
</>)}
|
|
248
|
-
|
|
249
|
-
{/* ─── 2. HARDWARE SUB-TAB ─────────────────────────────────────────────── */}
|
|
250
|
-
{activeSubTab === 'hardware' && (<>
|
|
251
|
-
<View style={styles.card}>
|
|
252
|
-
<View style={styles.cardTitleRow}>
|
|
253
|
-
<CpuIcon size={15} color={AppColors.purple}/>
|
|
254
|
-
<Text style={styles.cardTitle}>HARDWARE & IDENTIFIERS</Text>
|
|
255
|
-
</View>
|
|
256
|
-
<View style={styles.cardBody}>
|
|
257
|
-
<InfoRow label="Device Model" value={deviceInfo.deviceModel} copyable/>
|
|
258
|
-
<InfoRow label="Platform OS" value={deviceInfo.osVersion}/>
|
|
259
|
-
<InfoRow label="Device ID" value={deviceId} copyable/>
|
|
260
|
-
<InfoRow label="CPU Architecture" value={deviceInfo.arch || nativeMetrics?.cpuAbi || 'arm64'}/>
|
|
261
|
-
{nativeMetrics?.apiLevel !== undefined && (<InfoRow label="Android API Level" value={`API ${nativeMetrics.apiLevel}`}/>)}
|
|
262
|
-
</View>
|
|
263
|
-
</View>
|
|
264
|
-
|
|
265
|
-
{/* Memory / RAM */}
|
|
266
|
-
<View style={styles.card}>
|
|
267
|
-
<View style={styles.cardTitleRow}>
|
|
268
|
-
<CpuIcon size={15} color={AppColors.purple}/>
|
|
269
|
-
<Text style={styles.cardTitle}>SYSTEM MEMORY & RAM</Text>
|
|
270
|
-
</View>
|
|
271
|
-
<View style={styles.cardBody}>
|
|
272
|
-
{nativeMetrics?.totalRAM ? (<>
|
|
273
|
-
<InfoRow label="Total RAM" value={formatBytes(nativeMetrics.totalRAM)}/>
|
|
274
|
-
<InfoRow label="Available Free RAM" value={nativeMetrics.freeRAM ? formatBytes(nativeMetrics.freeRAM) : '—'} badge={nativeMetrics.isLowMemory ? 'Low Memory' : 'Healthy'} badgeColor={nativeMetrics.isLowMemory ? AppColors.errorColor : AppColors.emerald600}/>
|
|
275
|
-
</>) : (<InfoRow label="JS Heap Limit" value={deviceInfo.memoryMb ? `${deviceInfo.memoryMb} MB` : 'Dynamic Runtime'}/>)}
|
|
276
|
-
{nativeMetrics?.residentMemory ? (<InfoRow label="App Resident Memory" value={formatBytes(nativeMetrics.residentMemory)}/>) : null}
|
|
277
|
-
{nativeMetrics?.nativeHeapAllocated ? (<InfoRow label="Native Heap Allocated" value={formatBytes(nativeMetrics.nativeHeapAllocated)}/>) : null}
|
|
278
|
-
</View>
|
|
279
|
-
</View>
|
|
280
|
-
|
|
281
|
-
{/* Storage & Power */}
|
|
282
|
-
<View style={styles.card}>
|
|
283
|
-
<View style={styles.cardTitleRow}>
|
|
284
|
-
<DevicePhoneIcon size={15} color={AppColors.purple}/>
|
|
285
|
-
<Text style={styles.cardTitle}>STORAGE & BATTERY</Text>
|
|
286
|
-
</View>
|
|
287
|
-
<View style={styles.cardBody}>
|
|
288
|
-
{nativeMetrics?.totalStorage ? (<InfoRow label="Total Storage" value={formatBytes(nativeMetrics.totalStorage)}/>) : null}
|
|
289
|
-
{nativeMetrics?.freeStorage ? (<InfoRow label="Free Disk Space" value={formatBytes(nativeMetrics.freeStorage)}/>) : null}
|
|
290
|
-
{nativeMetrics?.batteryPercent !== undefined && (<InfoRow label="Battery Level" value={`${Math.round(nativeMetrics.batteryPercent)}%`} badge={nativeMetrics.isCharging ? 'Charging' : 'Discharging'} badgeColor={nativeMetrics.isCharging ? AppColors.emerald600 : AppColors.purple}/>)}
|
|
291
|
-
<InfoRow label="Hardware Type" value={deviceInfo.isDevice ? 'Physical Device' : 'Virtual Simulator'}/>
|
|
292
|
-
</View>
|
|
293
|
-
</View>
|
|
294
|
-
</>)}
|
|
295
|
-
|
|
296
|
-
{/* ─── 3. DISPLAY SUB-TAB ──────────────────────────────────────────────── */}
|
|
297
|
-
{activeSubTab === 'display' && (<View style={styles.card}>
|
|
298
|
-
<View style={styles.cardTitleRow}>
|
|
299
|
-
<MonitorIcon size={15} color={AppColors.purple}/>
|
|
300
|
-
<Text style={styles.cardTitle}>DISPLAY & VIEWPORT METRICS</Text>
|
|
301
|
-
</View>
|
|
302
|
-
<View style={styles.cardBody}>
|
|
303
|
-
<InfoRow label="Logical Resolution" value={`${deviceInfo.screenWidth} × ${deviceInfo.screenHeight} dp`} copyable/>
|
|
304
|
-
<InfoRow label="Physical Pixels" value={`${Math.round(deviceInfo.screenWidth * deviceInfo.screenScale)} × ${Math.round(deviceInfo.screenHeight * deviceInfo.screenScale)} px`}/>
|
|
305
|
-
<InfoRow label="Pixel Density Scale" value={`@${deviceInfo.screenScale}x (${Math.round(deviceInfo.screenScale * 160)} dpi)`} badge={`@${deviceInfo.screenScale}x`} badgeColor={AppColors.purple}/>
|
|
306
|
-
<InfoRow label="Font Scaling Factor" value={`${deviceInfo.screenFontScale}x`}/>
|
|
307
|
-
<InfoRow label="Status Bar Inset" value={`${deviceInfo.statusBarHeight} px`}/>
|
|
308
|
-
<InfoRow label="Aspect Ratio" value={`${(deviceInfo.screenHeight / deviceInfo.screenWidth).toFixed(2)} : 1`}/>
|
|
309
|
-
</View>
|
|
310
|
-
</View>)}
|
|
311
|
-
|
|
312
|
-
{/* ─── 4. RUNTIME SUB-TAB ──────────────────────────────────────────────── */}
|
|
313
|
-
{activeSubTab === 'runtime' && (<>
|
|
314
|
-
<View style={styles.card}>
|
|
315
|
-
<View style={styles.cardTitleRow}>
|
|
316
|
-
<CodeIcon size={15} color={AppColors.purple}/>
|
|
317
|
-
<Text style={styles.cardTitle}>JAVASCRIPT & CORE RUNTIME</Text>
|
|
318
|
-
</View>
|
|
319
|
-
<View style={styles.cardBody}>
|
|
320
|
-
<InfoRow label="JS Engine" value={deviceInfo.isHermes ? 'Hermes Bytecode Engine' : 'JavaScriptCore (JSC)'} badge={deviceInfo.isHermes ? 'Hermes' : 'JSC'} badgeColor={deviceInfo.isHermes ? AppColors.emerald600 : AppColors.purple}/>
|
|
321
|
-
<InfoRow label="React Native" value={`v${deviceInfo.reactNativeVersion}`} copyable/>
|
|
322
|
-
<InfoRow label="New Architecture" value={deviceInfo.isFabric ? 'Enabled (Fabric C++)' : 'Disabled (Paper)'} badge={deviceInfo.isFabric ? 'Fabric' : 'Paper'} badgeColor={deviceInfo.isFabric ? AppColors.emerald600 : AppColors.grayTextWeak}/>
|
|
323
|
-
<InfoRow label="TurboModules" value={deviceInfo.isTurboModule ? 'Active' : 'Disabled'}/>
|
|
324
|
-
<InfoRow label="CPU Architecture" value={deviceInfo.arch || 'arm64'}/>
|
|
325
|
-
</View>
|
|
326
|
-
</View>
|
|
327
|
-
|
|
328
|
-
<View style={styles.card}>
|
|
329
|
-
<View style={styles.cardTitleRow}>
|
|
330
|
-
<Text style={styles.cardTitle}>INTERNATIONALIZATION & LOCALE</Text>
|
|
331
|
-
</View>
|
|
332
|
-
<View style={styles.cardBody}>
|
|
333
|
-
<InfoRow label="Timezone" value={deviceInfo.timeZone || 'UTC'} copyable/>
|
|
334
|
-
<InfoRow label="Locale Identifier" value={deviceInfo.locale || 'en_US'} copyable/>
|
|
335
|
-
</View>
|
|
336
|
-
</View>
|
|
337
|
-
</>)}
|
|
338
|
-
|
|
339
|
-
{/* ─── 5. RAW JSON SUB-TAB ─────────────────────────────────────────────── */}
|
|
340
|
-
{activeSubTab === 'raw' && (<View style={styles.card}>
|
|
341
|
-
<View style={styles.rawHeaderRow}>
|
|
342
|
-
<View style={styles.rawSearchBox}>
|
|
343
|
-
<SearchIcon size={13} color={AppColors.grayTextWeak}/>
|
|
344
|
-
<TextInput style={styles.rawSearchInput} value={search} onChangeText={setSearch} placeholder="Filter JSON fields..." placeholderTextColor={AppColors.grayTextWeak} autoCapitalize="none" autoCorrect={false}/>
|
|
345
|
-
{search.length > 0 && (<TouchableScale onPress={() => setSearch('')}>
|
|
346
|
-
<ClearIcon size={14} color={AppColors.grayTextWeak}/>
|
|
347
|
-
</TouchableScale>)}
|
|
348
|
-
</View>
|
|
349
|
-
|
|
350
|
-
<TouchableScale onPress={handleCopyDiagnostics} style={styles.copyDiagnosticsBtn}>
|
|
351
|
-
<CopyIcon size={12} color={AppColors.white}/>
|
|
352
|
-
<Text style={styles.copyDiagnosticsText}>Copy All</Text>
|
|
353
|
-
</TouchableScale>
|
|
354
|
-
</View>
|
|
355
|
-
|
|
356
|
-
<ScrollView horizontal style={styles.rawScroll}>
|
|
357
|
-
<Text style={styles.rawText} selectable>
|
|
358
|
-
{rawReportJson}
|
|
359
|
-
</Text>
|
|
360
|
-
</ScrollView>
|
|
361
|
-
</View>)}
|
|
362
|
-
|
|
363
|
-
<View style={{ height: 40 }}/>
|
|
364
|
-
</ScrollView>
|
|
365
|
-
</View>);
|
|
366
|
-
});
|
|
367
|
-
const styles = StyleSheet.create({
|
|
368
|
-
container: {
|
|
369
|
-
flex: 1,
|
|
370
|
-
backgroundColor: AppColors.grayBackground,
|
|
371
|
-
},
|
|
372
|
-
tabBarWrapper: {
|
|
373
|
-
backgroundColor: AppColors.contentBg,
|
|
374
|
-
borderBottomWidth: 1,
|
|
375
|
-
borderBottomColor: AppColors.grayBorderSecondary,
|
|
376
|
-
paddingVertical: 8,
|
|
377
|
-
},
|
|
378
|
-
subTabBarContainer: {
|
|
379
|
-
paddingHorizontal: 12,
|
|
380
|
-
flexDirection: 'row',
|
|
381
|
-
gap: 8,
|
|
382
|
-
alignItems: 'center',
|
|
383
|
-
},
|
|
384
|
-
subTabButton: {
|
|
385
|
-
paddingHorizontal: 14,
|
|
386
|
-
paddingVertical: 7,
|
|
387
|
-
borderRadius: 20,
|
|
388
|
-
backgroundColor: AppColors.grayBackground,
|
|
389
|
-
borderWidth: 1,
|
|
390
|
-
borderColor: AppColors.grayBorderSecondary,
|
|
391
|
-
},
|
|
392
|
-
subTabButtonActive: {
|
|
393
|
-
backgroundColor: AppColors.purple,
|
|
394
|
-
borderColor: AppColors.purple,
|
|
395
|
-
},
|
|
396
|
-
subTabText: {
|
|
397
|
-
fontSize: 12,
|
|
398
|
-
fontFamily: AppFonts.interMedium,
|
|
399
|
-
color: AppColors.grayText,
|
|
400
|
-
},
|
|
401
|
-
subTabTextActive: {
|
|
402
|
-
color: AppColors.white,
|
|
403
|
-
fontFamily: AppFonts.interBold,
|
|
404
|
-
},
|
|
405
|
-
scrollArea: {
|
|
406
|
-
flex: 1,
|
|
407
|
-
},
|
|
408
|
-
contentContainer: {
|
|
409
|
-
padding: 12,
|
|
410
|
-
},
|
|
411
|
-
deviceIdHeroCard: {
|
|
412
|
-
backgroundColor: AppColors.contentBg,
|
|
413
|
-
borderRadius: 14,
|
|
414
|
-
padding: 14,
|
|
415
|
-
marginBottom: 12,
|
|
416
|
-
borderWidth: 1,
|
|
417
|
-
borderColor: `${AppColors.purple}30`,
|
|
418
|
-
shadowColor: AppColors.purple,
|
|
419
|
-
shadowOffset: { width: 0, height: 2 },
|
|
420
|
-
shadowOpacity: 0.06,
|
|
421
|
-
shadowRadius: 6,
|
|
422
|
-
elevation: 2,
|
|
423
|
-
},
|
|
424
|
-
deviceIdHeader: {
|
|
425
|
-
flexDirection: 'row',
|
|
426
|
-
alignItems: 'center',
|
|
427
|
-
justifyContent: 'space-between',
|
|
428
|
-
marginBottom: 8,
|
|
429
|
-
},
|
|
430
|
-
deviceIdBadgeRow: {
|
|
431
|
-
flexDirection: 'row',
|
|
432
|
-
alignItems: 'center',
|
|
433
|
-
gap: 6,
|
|
434
|
-
},
|
|
435
|
-
platformBadge: {
|
|
436
|
-
flexDirection: 'row',
|
|
437
|
-
alignItems: 'center',
|
|
438
|
-
gap: 4,
|
|
439
|
-
backgroundColor: `${AppColors.purple}14`,
|
|
440
|
-
paddingHorizontal: 8,
|
|
441
|
-
paddingVertical: 4,
|
|
442
|
-
borderRadius: 6,
|
|
443
|
-
borderWidth: 1,
|
|
444
|
-
borderColor: `${AppColors.purple}30`,
|
|
445
|
-
},
|
|
446
|
-
platformBadgeText: {
|
|
447
|
-
fontSize: 11,
|
|
448
|
-
fontFamily: AppFonts.interBold,
|
|
449
|
-
color: AppColors.purple,
|
|
450
|
-
},
|
|
451
|
-
idTypeBadge: {
|
|
452
|
-
flexDirection: 'row',
|
|
453
|
-
alignItems: 'center',
|
|
454
|
-
gap: 4,
|
|
455
|
-
backgroundColor: `${AppColors.purple}10`,
|
|
456
|
-
paddingHorizontal: 8,
|
|
457
|
-
paddingVertical: 4,
|
|
458
|
-
borderRadius: 6,
|
|
459
|
-
},
|
|
460
|
-
idTypeBadgeText: {
|
|
461
|
-
fontSize: 11,
|
|
462
|
-
fontFamily: AppFonts.interMedium,
|
|
463
|
-
color: AppColors.purple,
|
|
464
|
-
},
|
|
465
|
-
copyIdPill: {
|
|
466
|
-
flexDirection: 'row',
|
|
467
|
-
alignItems: 'center',
|
|
468
|
-
gap: 4,
|
|
469
|
-
backgroundColor: AppColors.purple,
|
|
470
|
-
paddingHorizontal: 10,
|
|
471
|
-
paddingVertical: 4,
|
|
472
|
-
borderRadius: 14,
|
|
473
|
-
},
|
|
474
|
-
copyIdPillText: {
|
|
475
|
-
fontSize: 11,
|
|
476
|
-
fontFamily: AppFonts.interBold,
|
|
477
|
-
color: AppColors.white,
|
|
478
|
-
},
|
|
479
|
-
deviceIdValue: {
|
|
480
|
-
fontSize: 12,
|
|
481
|
-
fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
|
|
482
|
-
color: AppColors.black,
|
|
483
|
-
letterSpacing: 0.5,
|
|
484
|
-
backgroundColor: AppColors.grayBackground,
|
|
485
|
-
paddingHorizontal: 10,
|
|
486
|
-
paddingVertical: 6,
|
|
487
|
-
borderRadius: 8,
|
|
488
|
-
},
|
|
489
|
-
headerBanner: {
|
|
490
|
-
flexDirection: 'row',
|
|
491
|
-
alignItems: 'center',
|
|
492
|
-
justifyContent: 'space-between',
|
|
493
|
-
backgroundColor: AppColors.contentBg,
|
|
494
|
-
borderRadius: 14,
|
|
495
|
-
padding: 14,
|
|
496
|
-
marginBottom: 12,
|
|
497
|
-
borderWidth: 1,
|
|
498
|
-
borderColor: AppColors.grayBorderSecondary,
|
|
499
|
-
},
|
|
500
|
-
headerLeft: {
|
|
501
|
-
flexDirection: 'row',
|
|
502
|
-
alignItems: 'center',
|
|
503
|
-
gap: 12,
|
|
504
|
-
flex: 1,
|
|
505
|
-
},
|
|
506
|
-
deviceIconBox: {
|
|
507
|
-
width: 44,
|
|
508
|
-
height: 44,
|
|
509
|
-
borderRadius: 12,
|
|
510
|
-
backgroundColor: `${AppColors.purple}15`,
|
|
511
|
-
alignItems: 'center',
|
|
512
|
-
justifyContent: 'center',
|
|
513
|
-
},
|
|
514
|
-
deviceTitle: {
|
|
515
|
-
fontSize: 15,
|
|
516
|
-
fontFamily: AppFonts.interBold,
|
|
517
|
-
color: AppColors.black,
|
|
518
|
-
},
|
|
519
|
-
deviceSubtitle: {
|
|
520
|
-
fontSize: 12,
|
|
521
|
-
fontFamily: AppFonts.interMedium,
|
|
522
|
-
color: AppColors.grayText,
|
|
523
|
-
marginTop: 2,
|
|
524
|
-
},
|
|
525
|
-
copyDiagnosticsBtn: {
|
|
526
|
-
flexDirection: 'row',
|
|
527
|
-
alignItems: 'center',
|
|
528
|
-
gap: 5,
|
|
529
|
-
backgroundColor: AppColors.purple,
|
|
530
|
-
paddingHorizontal: 12,
|
|
531
|
-
paddingVertical: 6,
|
|
532
|
-
borderRadius: 8,
|
|
533
|
-
},
|
|
534
|
-
copyDiagnosticsText: {
|
|
535
|
-
fontSize: 12,
|
|
536
|
-
fontFamily: AppFonts.interBold,
|
|
537
|
-
color: AppColors.white,
|
|
538
|
-
},
|
|
539
|
-
matrixGrid: {
|
|
540
|
-
flexDirection: 'row',
|
|
541
|
-
flexWrap: 'wrap',
|
|
542
|
-
gap: 8,
|
|
543
|
-
marginBottom: 12,
|
|
544
|
-
},
|
|
545
|
-
matrixCard: {
|
|
546
|
-
flex: 1,
|
|
547
|
-
minWidth: '47%',
|
|
548
|
-
backgroundColor: AppColors.contentBg,
|
|
549
|
-
borderRadius: 12,
|
|
550
|
-
padding: 12,
|
|
551
|
-
borderWidth: 1,
|
|
552
|
-
borderColor: AppColors.grayBorderSecondary,
|
|
553
|
-
},
|
|
554
|
-
matrixLabel: {
|
|
555
|
-
fontSize: 10,
|
|
556
|
-
fontFamily: AppFonts.interBold,
|
|
557
|
-
color: AppColors.grayTextWeak,
|
|
558
|
-
letterSpacing: 0.5,
|
|
559
|
-
marginBottom: 4,
|
|
560
|
-
},
|
|
561
|
-
matrixValue: {
|
|
562
|
-
fontSize: 14,
|
|
563
|
-
fontFamily: AppFonts.interBold,
|
|
564
|
-
color: AppColors.black,
|
|
565
|
-
marginBottom: 2,
|
|
566
|
-
},
|
|
567
|
-
matrixSub: {
|
|
568
|
-
fontSize: 11,
|
|
569
|
-
fontFamily: AppFonts.interMedium,
|
|
570
|
-
color: AppColors.purple,
|
|
571
|
-
},
|
|
572
|
-
card: {
|
|
573
|
-
backgroundColor: AppColors.contentBg,
|
|
574
|
-
borderRadius: 14,
|
|
575
|
-
padding: 14,
|
|
576
|
-
marginBottom: 12,
|
|
577
|
-
borderWidth: 1,
|
|
578
|
-
borderColor: AppColors.grayBorderSecondary,
|
|
579
|
-
},
|
|
580
|
-
cardTitleRow: {
|
|
581
|
-
flexDirection: 'row',
|
|
582
|
-
alignItems: 'center',
|
|
583
|
-
gap: 6,
|
|
584
|
-
marginBottom: 12,
|
|
585
|
-
paddingBottom: 8,
|
|
586
|
-
borderBottomWidth: 1,
|
|
587
|
-
borderBottomColor: AppColors.grayBorderSecondary,
|
|
588
|
-
},
|
|
589
|
-
cardTitle: {
|
|
590
|
-
fontSize: 12,
|
|
591
|
-
fontFamily: AppFonts.interBold,
|
|
592
|
-
color: AppColors.grayTextWeak,
|
|
593
|
-
letterSpacing: 0.5,
|
|
594
|
-
},
|
|
595
|
-
cardBody: {
|
|
596
|
-
gap: 10,
|
|
597
|
-
},
|
|
598
|
-
infoRow: {
|
|
599
|
-
flexDirection: 'row',
|
|
600
|
-
alignItems: 'center',
|
|
601
|
-
justifyContent: 'space-between',
|
|
602
|
-
paddingVertical: 3,
|
|
603
|
-
gap: 8,
|
|
604
|
-
},
|
|
605
|
-
infoLabel: {
|
|
606
|
-
fontSize: 12,
|
|
607
|
-
fontFamily: AppFonts.interMedium,
|
|
608
|
-
color: AppColors.grayText,
|
|
609
|
-
flexShrink: 0,
|
|
610
|
-
},
|
|
611
|
-
infoValueRow: {
|
|
612
|
-
flexDirection: 'row',
|
|
613
|
-
alignItems: 'center',
|
|
614
|
-
gap: 6,
|
|
615
|
-
flex: 1,
|
|
616
|
-
justifyContent: 'flex-end',
|
|
617
|
-
},
|
|
618
|
-
infoValue: {
|
|
619
|
-
fontSize: 12,
|
|
620
|
-
fontFamily: AppFonts.interMedium,
|
|
621
|
-
color: AppColors.black,
|
|
622
|
-
textAlign: 'right',
|
|
623
|
-
flexShrink: 1,
|
|
624
|
-
},
|
|
625
|
-
inlineBadge: {
|
|
626
|
-
paddingHorizontal: 6,
|
|
627
|
-
paddingVertical: 2,
|
|
628
|
-
borderRadius: 4,
|
|
629
|
-
borderWidth: 1,
|
|
630
|
-
},
|
|
631
|
-
inlineBadgeText: {
|
|
632
|
-
fontSize: 10,
|
|
633
|
-
fontFamily: AppFonts.interBold,
|
|
634
|
-
},
|
|
635
|
-
inlineCopyBtn: {
|
|
636
|
-
padding: 3,
|
|
637
|
-
borderRadius: 4,
|
|
638
|
-
backgroundColor: `${AppColors.purple}14`,
|
|
639
|
-
},
|
|
640
|
-
rawHeaderRow: {
|
|
641
|
-
flexDirection: 'row',
|
|
642
|
-
alignItems: 'center',
|
|
643
|
-
justifyContent: 'space-between',
|
|
644
|
-
gap: 8,
|
|
645
|
-
marginBottom: 12,
|
|
646
|
-
},
|
|
647
|
-
rawSearchBox: {
|
|
648
|
-
flex: 1,
|
|
649
|
-
flexDirection: 'row',
|
|
650
|
-
alignItems: 'center',
|
|
651
|
-
gap: 6,
|
|
652
|
-
backgroundColor: AppColors.grayBackground,
|
|
653
|
-
borderRadius: 8,
|
|
654
|
-
paddingHorizontal: 8,
|
|
655
|
-
paddingVertical: 4,
|
|
656
|
-
borderWidth: 1,
|
|
657
|
-
borderColor: AppColors.grayBorderSecondary,
|
|
658
|
-
},
|
|
659
|
-
rawSearchInput: {
|
|
660
|
-
flex: 1,
|
|
661
|
-
fontSize: 12,
|
|
662
|
-
fontFamily: AppFonts.interRegular,
|
|
663
|
-
color: AppColors.black,
|
|
664
|
-
paddingVertical: 0,
|
|
665
|
-
},
|
|
666
|
-
rawScroll: {
|
|
667
|
-
backgroundColor: AppColors.grayBackground,
|
|
668
|
-
borderRadius: 10,
|
|
669
|
-
padding: 10,
|
|
670
|
-
},
|
|
671
|
-
rawText: {
|
|
672
|
-
fontSize: 11,
|
|
673
|
-
fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
|
|
674
|
-
color: AppColors.black,
|
|
675
|
-
lineHeight: 16,
|
|
676
|
-
},
|
|
677
|
-
});
|
|
678
|
-
export default DeviceTab;
|