react-native-inapp-inspector 2.0.5 → 2.0.6
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 +11 -0
- package/dist/commonjs/components/Inspector/AuditTab.d.ts +3 -0
- package/dist/commonjs/components/Inspector/AuditTab.js +741 -0
- package/dist/commonjs/components/Inspector/DeviceTab.d.ts +3 -0
- package/dist/commonjs/components/Inspector/DeviceTab.js +717 -0
- package/dist/commonjs/components/Inspector/InspectorHeader.js +28 -25
- package/dist/commonjs/components/Inspector/MainScreen.js +15 -2
- package/dist/commonjs/components/Inspector/NetworkDetail.js +15 -0
- package/dist/commonjs/components/Inspector/PerformanceHud.d.ts +7 -0
- package/dist/commonjs/components/Inspector/PerformanceHud.js +210 -0
- package/dist/commonjs/components/Inspector/PerformanceTab.js +30 -18
- package/dist/commonjs/components/Inspector/RequestReplayModal.d.ts +9 -0
- package/dist/commonjs/components/Inspector/RequestReplayModal.js +792 -0
- package/dist/commonjs/components/Inspector/RequestReplayView.d.ts +8 -0
- package/dist/commonjs/components/Inspector/RequestReplayView.js +871 -0
- package/dist/commonjs/components/Inspector/SettingsPanel.js +326 -15
- package/dist/commonjs/components/Inspector/StorageTab.d.ts +3 -0
- package/dist/commonjs/components/Inspector/StorageTab.js +610 -0
- package/dist/commonjs/components/Inspector/TabBar.js +23 -2
- package/dist/commonjs/components/NetworkIcons.d.ts +12 -0
- package/dist/commonjs/components/NetworkIcons.js +72 -3
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/storageInspector.d.ts +13 -0
- package/dist/commonjs/customHooks/storageInspector.js +179 -0
- package/dist/commonjs/helpers/deviceInfo.d.ts +4 -0
- package/dist/commonjs/helpers/deviceInfo.js +94 -0
- package/dist/commonjs/helpers/index.d.ts +2 -0
- package/dist/commonjs/helpers/index.js +12 -1
- package/dist/commonjs/helpers/packageAuditor.d.ts +5 -0
- package/dist/commonjs/helpers/packageAuditor.js +182 -0
- package/dist/commonjs/i18n/locales/en.json +3 -2
- package/dist/commonjs/index.d.ts +1 -0
- package/dist/commonjs/index.js +113 -9
- package/dist/commonjs/native/NativeInspector.d.ts +1 -0
- package/dist/commonjs/types/enums.d.ts +7 -0
- package/dist/commonjs/types/enums.js +7 -0
- package/dist/commonjs/types/interfaces.d.ts +73 -0
- package/dist/esm/components/Inspector/AuditTab.d.ts +3 -0
- package/dist/esm/components/Inspector/AuditTab.js +702 -0
- package/dist/esm/components/Inspector/DeviceTab.d.ts +3 -0
- package/dist/esm/components/Inspector/DeviceTab.js +678 -0
- package/dist/esm/components/Inspector/InspectorHeader.js +28 -25
- package/dist/esm/components/Inspector/MainScreen.js +15 -2
- package/dist/esm/components/Inspector/NetworkDetail.js +16 -1
- package/dist/esm/components/Inspector/PerformanceHud.d.ts +7 -0
- package/dist/esm/components/Inspector/PerformanceHud.js +170 -0
- package/dist/esm/components/Inspector/PerformanceTab.js +31 -19
- package/dist/esm/components/Inspector/RequestReplayModal.d.ts +9 -0
- package/dist/esm/components/Inspector/RequestReplayModal.js +752 -0
- package/dist/esm/components/Inspector/RequestReplayView.d.ts +8 -0
- package/dist/esm/components/Inspector/RequestReplayView.js +831 -0
- package/dist/esm/components/Inspector/SettingsPanel.js +327 -16
- package/dist/esm/components/Inspector/StorageTab.d.ts +3 -0
- package/dist/esm/components/Inspector/StorageTab.js +571 -0
- package/dist/esm/components/Inspector/TabBar.js +24 -3
- package/dist/esm/components/NetworkIcons.d.ts +12 -0
- package/dist/esm/components/NetworkIcons.js +57 -0
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/storageInspector.d.ts +13 -0
- package/dist/esm/customHooks/storageInspector.js +170 -0
- package/dist/esm/helpers/deviceInfo.d.ts +4 -0
- package/dist/esm/helpers/deviceInfo.js +89 -0
- package/dist/esm/helpers/index.d.ts +2 -0
- package/dist/esm/helpers/index.js +10 -0
- package/dist/esm/helpers/packageAuditor.d.ts +5 -0
- package/dist/esm/helpers/packageAuditor.js +173 -0
- package/dist/esm/i18n/locales/en.json +3 -2
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +109 -8
- package/dist/esm/native/NativeInspector.d.ts +1 -0
- package/dist/esm/types/enums.d.ts +7 -0
- package/dist/esm/types/enums.js +7 -0
- package/dist/esm/types/interfaces.d.ts +73 -0
- package/ios/NetworkInspectorModule.mm +12 -5
- package/package.json +4 -1
|
@@ -52,7 +52,7 @@ const telemetry_1 = require("../../helpers/telemetry");
|
|
|
52
52
|
const UpdateAvailableModal_1 = require("./UpdateAvailableModal");
|
|
53
53
|
const NetworkIcons_1 = require("../NetworkIcons");
|
|
54
54
|
const InspectorHeader = react_1.default.memo(() => {
|
|
55
|
-
const { modalHeightPercent, appIcon, selected, setSelected, selectedEvent, setSelectedEvent, selectedLog, setSelectedLog, selectedReduxSlice, setSelectedReduxSlice, selectedReduxAction, setSelectedReduxAction, reduxState, reduxLastActionMap, showHeaderInfo, setShowHeaderInfo, updateAvailable, latestNpmVersion, clearAnim, activePulseAnim, unreadPulseAnim, runClearAllWithAnimation, settingsPage, setSettingsPage, resetToDefaults, closeModal, detailTitle, activeTab, environment, visible, selectedCrash, setSelectedCrash, } = (0, InspectorContext_1.useInspector)();
|
|
55
|
+
const { modalHeightPercent, appIcon, selected, setSelected, selectedEvent, setSelectedEvent, selectedLog, setSelectedLog, selectedReduxSlice, setSelectedReduxSlice, selectedReduxAction, setSelectedReduxAction, reduxState, reduxLastActionMap, showHeaderInfo, setShowHeaderInfo, updateAvailable, latestNpmVersion, clearAnim, activePulseAnim, unreadPulseAnim, runClearAllWithAnimation, settingsPage, setSettingsPage, resetToDefaults, closeModal, detailTitle, activeTab, environment, visible, selectedCrash, setSelectedCrash, deviceInfo, } = (0, InspectorContext_1.useInspector)();
|
|
56
56
|
const [showUpdateModal, setShowUpdateModal] = react_1.default.useState(false);
|
|
57
57
|
const [isTelemetryActive, setIsTelemetryActive] = react_1.default.useState(false);
|
|
58
58
|
const telemetryPulseAnim = react_1.default.useRef(new react_native_1.Animated.Value(1)).current;
|
|
@@ -302,38 +302,44 @@ const InspectorHeader = react_1.default.memo(() => {
|
|
|
302
302
|
</react_native_1.Pressable>)}
|
|
303
303
|
</react_native_1.View>
|
|
304
304
|
|
|
305
|
-
{/* OS & NPM Version
|
|
305
|
+
{/* OS & NPM Version Common Chip Bar */}
|
|
306
306
|
<react_native_1.View style={{
|
|
307
307
|
flexDirection: 'row',
|
|
308
308
|
alignItems: 'center',
|
|
309
309
|
gap: 5,
|
|
310
310
|
minWidth: 0,
|
|
311
311
|
}}>
|
|
312
|
+
{/* Unified Platform & Build Chip */}
|
|
312
313
|
<react_native_1.View style={{
|
|
313
314
|
flexDirection: 'row',
|
|
314
315
|
alignItems: 'center',
|
|
315
|
-
backgroundColor:
|
|
316
|
-
borderRadius:
|
|
317
|
-
paddingHorizontal: 6,
|
|
318
|
-
paddingVertical: 2,
|
|
319
|
-
gap: 4,
|
|
316
|
+
backgroundColor: 'rgba(255, 255, 255, 0.16)',
|
|
317
|
+
borderRadius: 6,
|
|
318
|
+
paddingHorizontal: 6.5,
|
|
319
|
+
paddingVertical: 2.5,
|
|
320
|
+
gap: 4.5,
|
|
320
321
|
borderWidth: 1,
|
|
321
|
-
borderColor:
|
|
322
|
+
borderColor: 'rgba(255, 255, 255, 0.28)',
|
|
322
323
|
flexShrink: 0,
|
|
323
324
|
}}>
|
|
324
|
-
{react_native_1.Platform.OS === 'ios' ? (<NetworkIcons_1.AppleIcon color=
|
|
325
|
+
{react_native_1.Platform.OS === 'ios' ? (<NetworkIcons_1.AppleIcon color="#FFFFFF" size={10.5}/>) : (<NetworkIcons_1.AndroidIcon color="#FFFFFF" size={10.5}/>)}
|
|
325
326
|
<react_native_1.Text style={{
|
|
326
|
-
fontFamily: AppFonts_1.AppFonts.
|
|
327
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
327
328
|
fontSize: 9.5,
|
|
328
|
-
color:
|
|
329
|
+
color: '#FFFFFF',
|
|
329
330
|
letterSpacing: 0.1,
|
|
330
331
|
}} numberOfLines={1}>
|
|
331
332
|
{react_native_1.Platform.OS === 'ios'
|
|
332
|
-
? `iOS ${react_native_1.Platform.Version}
|
|
333
|
-
|
|
333
|
+
? `iOS ${String(deviceInfo?.osVersion || react_native_1.Platform.Version).replace(/^(ios\s*)+/i, '').trim()}${deviceInfo?.buildNumber || deviceInfo?.appVersion
|
|
334
|
+
? ` (${deviceInfo.buildNumber || deviceInfo.appVersion})`
|
|
335
|
+
: ''}`
|
|
336
|
+
: `Android ${String(deviceInfo?.osVersion || react_native_1.Platform.Version).replace(/^(android\s*)+/i, '').trim()}${deviceInfo?.buildNumber || deviceInfo?.appVersion
|
|
337
|
+
? ` (${deviceInfo.buildNumber || deviceInfo.appVersion})`
|
|
338
|
+
: ''}`}
|
|
334
339
|
</react_native_1.Text>
|
|
335
340
|
</react_native_1.View>
|
|
336
341
|
|
|
342
|
+
{/* Unified NPM Version Chip */}
|
|
337
343
|
<react_native_1.Pressable onPress={() => {
|
|
338
344
|
if (updateAvailable) {
|
|
339
345
|
setShowUpdateModal(true);
|
|
@@ -342,26 +348,23 @@ const InspectorHeader = react_1.default.memo(() => {
|
|
|
342
348
|
react_native_1.Linking.openURL('https://www.npmjs.com/package/react-native-inapp-inspector').catch(() => { });
|
|
343
349
|
}
|
|
344
350
|
}} style={{
|
|
345
|
-
backgroundColor: '
|
|
346
|
-
borderRadius:
|
|
347
|
-
paddingHorizontal: 6,
|
|
348
|
-
paddingVertical: 2,
|
|
351
|
+
backgroundColor: 'rgba(255, 255, 255, 0.16)',
|
|
352
|
+
borderRadius: 6,
|
|
353
|
+
paddingHorizontal: 6.5,
|
|
354
|
+
paddingVertical: 2.5,
|
|
349
355
|
flexDirection: 'row',
|
|
350
356
|
alignItems: 'center',
|
|
351
357
|
gap: 4,
|
|
358
|
+
borderWidth: 1,
|
|
359
|
+
borderColor: 'rgba(255, 255, 255, 0.28)',
|
|
352
360
|
flexShrink: 0,
|
|
353
|
-
shadowColor: '#000000',
|
|
354
|
-
shadowOffset: { width: 0, height: 1 },
|
|
355
|
-
shadowOpacity: 0.15,
|
|
356
|
-
shadowRadius: 2,
|
|
357
|
-
elevation: 2,
|
|
358
361
|
}}>
|
|
359
|
-
<NetworkIcons_1.NpmIcon size={11} color="#
|
|
362
|
+
<NetworkIcons_1.NpmIcon size={11} color="#FF6B6B"/>
|
|
360
363
|
<react_native_1.Text style={{
|
|
361
364
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
362
365
|
fontSize: 9.5,
|
|
363
|
-
color: '#
|
|
364
|
-
letterSpacing: 0.
|
|
366
|
+
color: '#FFFFFF',
|
|
367
|
+
letterSpacing: 0.15,
|
|
365
368
|
}} numberOfLines={1}>
|
|
366
369
|
v{constants_2.LIB_VERSION}
|
|
367
370
|
</react_native_1.Text>
|
|
@@ -55,6 +55,9 @@ const BundleTab_1 = __importDefault(require("./BundleTab"));
|
|
|
55
55
|
const PerformanceTab_1 = __importDefault(require("./PerformanceTab"));
|
|
56
56
|
const CrashTab_1 = __importDefault(require("./CrashTab"));
|
|
57
57
|
const CrashDetail_1 = __importDefault(require("./CrashDetail"));
|
|
58
|
+
const StorageTab_1 = __importDefault(require("./StorageTab"));
|
|
59
|
+
const DeviceTab_1 = __importDefault(require("./DeviceTab"));
|
|
60
|
+
const AuditTab_1 = __importDefault(require("./AuditTab"));
|
|
58
61
|
const SettingsPanel_1 = __importDefault(require("./SettingsPanel"));
|
|
59
62
|
const TelemetryConsentModal_1 = __importDefault(require("./TelemetryConsentModal"));
|
|
60
63
|
const NpmUpdateToast_1 = __importDefault(require("./NpmUpdateToast"));
|
|
@@ -62,8 +65,9 @@ const Toast_1 = __importDefault(require("../Toast"));
|
|
|
62
65
|
const styles_1 = __importDefault(require("../../styles"));
|
|
63
66
|
const AppColors_1 = require("../../styles/AppColors");
|
|
64
67
|
const NavigationTracker_1 = __importDefault(require("./NavigationTracker"));
|
|
68
|
+
const PerformanceHud_1 = __importDefault(require("./PerformanceHud"));
|
|
65
69
|
const MainScreen = () => {
|
|
66
|
-
const { visible, modalAnimationType, closeModal, modalHeightPercent, selected, selectedEvent, selectedLog, selectedReduxSlice, selectedReduxAction, selectedCrash, settingsPage, activeTab, isReady, isEnabled, useNativeFab, hasNavigationContext, setNavState, } = (0, InspectorContext_1.useInspector)();
|
|
70
|
+
const { visible, setVisible, switchActiveTab, modalAnimationType, closeModal, modalHeightPercent, selected, selectedEvent, selectedLog, selectedReduxSlice, selectedReduxAction, selectedCrash, settingsPage, activeTab, isReady, isEnabled, isPerformanceHudEnabled, useNativeFab, hasNavigationContext, setNavState, } = (0, InspectorContext_1.useInspector)();
|
|
67
71
|
const isDetailActive = (activeTab === 'apis' && selected != null) ||
|
|
68
72
|
(activeTab === 'analytics' && selectedEvent != null) ||
|
|
69
73
|
(activeTab === 'logs' && selectedLog != null) ||
|
|
@@ -104,10 +108,16 @@ const MainScreen = () => {
|
|
|
104
108
|
}).start();
|
|
105
109
|
}, [activeTab]);
|
|
106
110
|
return (<>
|
|
107
|
-
|
|
111
|
+
<react_native_1.View pointerEvents="box-none" style={react_native_1.StyleSheet.absoluteFillObject}>
|
|
112
|
+
{(react_native_1.Platform.OS === 'ios' || react_native_1.Platform.OS === 'android') &&
|
|
108
113
|
isEnabled &&
|
|
109
114
|
!visible &&
|
|
110
115
|
!useNativeFab && <FabLauncher_1.default />}
|
|
116
|
+
{isEnabled && !visible && isPerformanceHudEnabled && (<PerformanceHud_1.default visible={true} onPress={() => {
|
|
117
|
+
setVisible(true);
|
|
118
|
+
switchActiveTab('performance');
|
|
119
|
+
}}/>)}
|
|
120
|
+
</react_native_1.View>
|
|
111
121
|
<react_native_1.Modal visible={visible} animationType={modalAnimationType} transparent statusBarTranslucent={true}>
|
|
112
122
|
{visible && (<ErrorBoundary_1.default onClose={closeModal}>
|
|
113
123
|
<react_native_1.View style={styles_1.default.modalBackdrop}>
|
|
@@ -151,6 +161,9 @@ const MainScreen = () => {
|
|
|
151
161
|
{activeTab === 'logs' && <ConsoleTab_1.default />}
|
|
152
162
|
{activeTab === 'analytics' && <AnalyticsTab_1.default />}
|
|
153
163
|
{activeTab === 'redux' && <ReduxTab_1.default />}
|
|
164
|
+
{activeTab === 'storage' && <StorageTab_1.default />}
|
|
165
|
+
{activeTab === 'device' && <DeviceTab_1.default />}
|
|
166
|
+
{activeTab === 'audit' && <AuditTab_1.default />}
|
|
154
167
|
{activeTab === 'bundle' && <BundleTab_1.default />}
|
|
155
168
|
{activeTab === 'performance' && <PerformanceTab_1.default />}
|
|
156
169
|
{activeTab === 'crash' && <CrashTab_1.default />}
|
|
@@ -22,8 +22,10 @@ const AppFonts_1 = require("../../styles/AppFonts");
|
|
|
22
22
|
const constants_1 = require("../../constants");
|
|
23
23
|
const helpers_1 = require("../../helpers");
|
|
24
24
|
const NetworkIcons_1 = require("../NetworkIcons");
|
|
25
|
+
const RequestReplayView_1 = __importDefault(require("./RequestReplayView"));
|
|
25
26
|
const NetworkDetail = react_1.default.memo(() => {
|
|
26
27
|
const { t } = (0, i18n_1.useTranslation)();
|
|
28
|
+
const [isReplayScreenActive, setIsReplayScreenActive] = react_1.default.useState(false);
|
|
27
29
|
const { selected, detailDisplayUrl, apiDetailActiveTab, setApiDetailActiveTab, detailSearch, setDetailSearch, reqExpanded, setReqExpanded, resExpanded, setResExpanded, showReqDiff, setShowReqDiff, showResDiff, setShowResDiff, prevRequestData, prevResponseData, logRouteMapRef, } = (0, InspectorContext_1.useInspector)();
|
|
28
30
|
const handleOpenUrl = () => {
|
|
29
31
|
react_native_1.Alert.alert(t('common.openInBrowser') || 'Open in Browser', `${t('common.openInBrowserPrompt') || 'Are you sure you want to open this URL in your external browser?'}\n\n${detailDisplayUrl}`, [
|
|
@@ -47,6 +49,9 @@ const NetworkDetail = react_1.default.memo(() => {
|
|
|
47
49
|
};
|
|
48
50
|
if (!selected)
|
|
49
51
|
return null;
|
|
52
|
+
if (isReplayScreenActive) {
|
|
53
|
+
return (<RequestReplayView_1.default request={selected} onBack={() => setIsReplayScreenActive(false)}/>);
|
|
54
|
+
}
|
|
50
55
|
return (<react_native_1.View style={{ flex: 1 }}>
|
|
51
56
|
{/* Non-scrollable details header */}
|
|
52
57
|
<react_native_1.View style={{ paddingHorizontal: 6, paddingTop: 4 }}>
|
|
@@ -252,6 +257,16 @@ const NetworkDetail = react_1.default.memo(() => {
|
|
|
252
257
|
</react_native_1.View>
|
|
253
258
|
|
|
254
259
|
<react_native_1.View style={styles_1.default.detailInfoRight}>
|
|
260
|
+
<TouchableScale_1.default style={[
|
|
261
|
+
styles_1.default.iconSquareBtn,
|
|
262
|
+
{
|
|
263
|
+
backgroundColor: `${AppColors_1.AppColors.purple}15`,
|
|
264
|
+
borderColor: `${AppColors_1.AppColors.purple}30`,
|
|
265
|
+
borderWidth: 1,
|
|
266
|
+
},
|
|
267
|
+
]} onPress={() => setIsReplayScreenActive(true)} accessible={true} accessibilityRole="button" accessibilityLabel="Edit & Resend Request" hitSlop={12}>
|
|
268
|
+
<NetworkIcons_1.ReplayIcon color={AppColors_1.AppColors.purple} size={14}/>
|
|
269
|
+
</TouchableScale_1.default>
|
|
255
270
|
<TouchableScale_1.default style={[styles_1.default.iconSquareBtn, { backgroundColor: `${AppColors_1.AppColors.sky600}15` }]} onPress={handleOpenUrl} hitSlop={12}>
|
|
256
271
|
<NetworkIcons_1.ExternalLinkIcon color={AppColors_1.AppColors.sky600} size={14}/>
|
|
257
272
|
</TouchableScale_1.default>
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.PerformanceHud = void 0;
|
|
40
|
+
const react_1 = __importStar(require("react"));
|
|
41
|
+
const react_native_1 = require("react-native");
|
|
42
|
+
const TouchableScale_1 = __importDefault(require("../TouchableScale"));
|
|
43
|
+
const AppColors_1 = require("../../styles/AppColors");
|
|
44
|
+
const AppFonts_1 = require("../../styles/AppFonts");
|
|
45
|
+
const NativeInspector_1 = require("../../native/NativeInspector");
|
|
46
|
+
const PerformanceHud = ({ visible, onPress, }) => {
|
|
47
|
+
const [fps, setFps] = (0, react_1.useState)(60);
|
|
48
|
+
const [ramMb, setRamMb] = (0, react_1.useState)(45);
|
|
49
|
+
// Pan / Drag positioning
|
|
50
|
+
const pan = (0, react_1.useRef)(new react_native_1.Animated.ValueXY({ x: 16, y: react_native_1.Platform.OS === 'ios' ? 56 : 36 })).current;
|
|
51
|
+
const panResponder = (0, react_1.useRef)(react_native_1.PanResponder.create({
|
|
52
|
+
onStartShouldSetPanResponder: () => false,
|
|
53
|
+
onMoveShouldSetPanResponder: (_, gestureState) => {
|
|
54
|
+
return Math.abs(gestureState.dx) > 4 || Math.abs(gestureState.dy) > 4;
|
|
55
|
+
},
|
|
56
|
+
onPanResponderGrant: () => {
|
|
57
|
+
pan.setOffset({
|
|
58
|
+
// @ts-ignore
|
|
59
|
+
x: pan.x._value,
|
|
60
|
+
// @ts-ignore
|
|
61
|
+
y: pan.y._value,
|
|
62
|
+
});
|
|
63
|
+
pan.setValue({ x: 0, y: 0 });
|
|
64
|
+
},
|
|
65
|
+
onPanResponderMove: react_native_1.Animated.event([null, { dx: pan.x, dy: pan.y }], {
|
|
66
|
+
useNativeDriver: false,
|
|
67
|
+
}),
|
|
68
|
+
onPanResponderRelease: () => {
|
|
69
|
+
pan.flattenOffset();
|
|
70
|
+
},
|
|
71
|
+
})).current;
|
|
72
|
+
// Real-time FPS Calculation via requestAnimationFrame
|
|
73
|
+
(0, react_1.useEffect)(() => {
|
|
74
|
+
if (!visible)
|
|
75
|
+
return;
|
|
76
|
+
let frameCount = 0;
|
|
77
|
+
let lastTime = performance.now();
|
|
78
|
+
let animId;
|
|
79
|
+
const loop = (now) => {
|
|
80
|
+
frameCount++;
|
|
81
|
+
const elapsed = now - lastTime;
|
|
82
|
+
if (elapsed >= 500) {
|
|
83
|
+
const currentFps = Math.min(60, Math.round((frameCount * 1000) / elapsed));
|
|
84
|
+
setFps(currentFps);
|
|
85
|
+
frameCount = 0;
|
|
86
|
+
lastTime = now;
|
|
87
|
+
}
|
|
88
|
+
animId = requestAnimationFrame(loop);
|
|
89
|
+
};
|
|
90
|
+
animId = requestAnimationFrame(loop);
|
|
91
|
+
return () => {
|
|
92
|
+
cancelAnimationFrame(animId);
|
|
93
|
+
};
|
|
94
|
+
}, [visible]);
|
|
95
|
+
// Memory Metrics Polling
|
|
96
|
+
(0, react_1.useEffect)(() => {
|
|
97
|
+
if (!visible)
|
|
98
|
+
return;
|
|
99
|
+
const interval = setInterval(async () => {
|
|
100
|
+
try {
|
|
101
|
+
const metrics = await (0, NativeInspector_1.getNativeDeviceMetrics)();
|
|
102
|
+
if (metrics && metrics.residentMemory != null) {
|
|
103
|
+
const mb = metrics.residentMemory / (1024 * 1024);
|
|
104
|
+
setRamMb(Math.round(mb));
|
|
105
|
+
}
|
|
106
|
+
else if (metrics && metrics.usedRAM != null) {
|
|
107
|
+
const mb = metrics.usedRAM / (1024 * 1024);
|
|
108
|
+
setRamMb(Math.round(mb));
|
|
109
|
+
}
|
|
110
|
+
else if (typeof performance !== 'undefined' &&
|
|
111
|
+
// @ts-ignore
|
|
112
|
+
performance.memory?.usedJSHeapSize) {
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
const mb = performance.memory.usedJSHeapSize / (1024 * 1024);
|
|
115
|
+
setRamMb(Math.round(mb));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// Safe fallback
|
|
120
|
+
}
|
|
121
|
+
}, 1500);
|
|
122
|
+
return () => clearInterval(interval);
|
|
123
|
+
}, [visible]);
|
|
124
|
+
if (!visible)
|
|
125
|
+
return null;
|
|
126
|
+
const fpsColor = fps >= 55
|
|
127
|
+
? AppColors_1.AppColors.greenColor
|
|
128
|
+
: fps >= 35
|
|
129
|
+
? AppColors_1.AppColors.warningIconGold
|
|
130
|
+
: AppColors_1.AppColors.errorColor;
|
|
131
|
+
return (<react_native_1.Animated.View {...panResponder.panHandlers} style={[
|
|
132
|
+
styles.hudContainer,
|
|
133
|
+
{
|
|
134
|
+
transform: pan.getTranslateTransform(),
|
|
135
|
+
},
|
|
136
|
+
]}>
|
|
137
|
+
<TouchableScale_1.default onPress={onPress} style={styles.hudInner}>
|
|
138
|
+
{/* FPS Indicator */}
|
|
139
|
+
<react_native_1.View style={styles.metricItem}>
|
|
140
|
+
<react_native_1.View style={[styles.statusDot, { backgroundColor: fpsColor }]}/>
|
|
141
|
+
<react_native_1.Text style={[styles.metricValue, { color: fpsColor }]}>{fps}</react_native_1.Text>
|
|
142
|
+
<react_native_1.Text style={styles.metricUnit}>FPS</react_native_1.Text>
|
|
143
|
+
</react_native_1.View>
|
|
144
|
+
|
|
145
|
+
<react_native_1.View style={styles.divider}/>
|
|
146
|
+
|
|
147
|
+
{/* RAM / Heap Indicator */}
|
|
148
|
+
<react_native_1.View style={styles.metricItem}>
|
|
149
|
+
<react_native_1.Text style={styles.metricIcon}>⚡</react_native_1.Text>
|
|
150
|
+
<react_native_1.Text style={styles.metricValue}>{ramMb}</react_native_1.Text>
|
|
151
|
+
<react_native_1.Text style={styles.metricUnit}>MB</react_native_1.Text>
|
|
152
|
+
</react_native_1.View>
|
|
153
|
+
</TouchableScale_1.default>
|
|
154
|
+
</react_native_1.Animated.View>);
|
|
155
|
+
};
|
|
156
|
+
exports.PerformanceHud = PerformanceHud;
|
|
157
|
+
const styles = react_native_1.StyleSheet.create({
|
|
158
|
+
hudContainer: {
|
|
159
|
+
position: 'absolute',
|
|
160
|
+
top: 0,
|
|
161
|
+
left: 0,
|
|
162
|
+
zIndex: 999998,
|
|
163
|
+
elevation: 999998,
|
|
164
|
+
},
|
|
165
|
+
hudInner: {
|
|
166
|
+
flexDirection: 'row',
|
|
167
|
+
alignItems: 'center',
|
|
168
|
+
backgroundColor: 'rgba(15, 23, 42, 0.88)',
|
|
169
|
+
borderRadius: 20,
|
|
170
|
+
borderWidth: 1,
|
|
171
|
+
borderColor: 'rgba(255, 255, 255, 0.18)',
|
|
172
|
+
paddingHorizontal: 10,
|
|
173
|
+
paddingVertical: 5,
|
|
174
|
+
gap: 8,
|
|
175
|
+
shadowColor: AppColors_1.AppColors.black,
|
|
176
|
+
shadowOpacity: 0.35,
|
|
177
|
+
shadowRadius: 6,
|
|
178
|
+
shadowOffset: { width: 0, height: 2 },
|
|
179
|
+
},
|
|
180
|
+
metricItem: {
|
|
181
|
+
flexDirection: 'row',
|
|
182
|
+
alignItems: 'center',
|
|
183
|
+
gap: 4,
|
|
184
|
+
},
|
|
185
|
+
statusDot: {
|
|
186
|
+
width: 6,
|
|
187
|
+
height: 6,
|
|
188
|
+
borderRadius: 3,
|
|
189
|
+
},
|
|
190
|
+
metricIcon: {
|
|
191
|
+
fontSize: 10,
|
|
192
|
+
},
|
|
193
|
+
metricValue: {
|
|
194
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
195
|
+
fontSize: 11.5,
|
|
196
|
+
color: AppColors_1.AppColors.white,
|
|
197
|
+
},
|
|
198
|
+
metricUnit: {
|
|
199
|
+
fontFamily: AppFonts_1.AppFonts.interRegular,
|
|
200
|
+
fontSize: 9,
|
|
201
|
+
color: 'rgba(255, 255, 255, 0.65)',
|
|
202
|
+
letterSpacing: 0.2,
|
|
203
|
+
},
|
|
204
|
+
divider: {
|
|
205
|
+
width: 1,
|
|
206
|
+
height: 12,
|
|
207
|
+
backgroundColor: 'rgba(255, 255, 255, 0.2)',
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
exports.default = exports.PerformanceHud;
|
|
@@ -411,24 +411,33 @@ const PerformanceTab = react_1.default.memo(() => {
|
|
|
411
411
|
<react_native_1.View style={perfStyles.categoryScrollWrapper}>
|
|
412
412
|
<react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} style={perfStyles.categoryScrollView} contentContainerStyle={perfStyles.categoryScroll}>
|
|
413
413
|
{[
|
|
414
|
-
{ key: 'ALL', label: t('performance.catAll') },
|
|
415
|
-
{ key: 'JANKY', label: t('performance.catJanky') },
|
|
416
|
-
{ key: 'NAVIGATION', label: t('performance.catNavigation') },
|
|
417
|
-
{ key: 'RENDER', label: t('performance.catRender') },
|
|
418
|
-
{ key: 'MEMORY', label: t('performance.catMemory') },
|
|
419
|
-
{ key: 'IO', label: t('performance.catIo') },
|
|
414
|
+
{ key: 'ALL', label: t('performance.catAll'), icon: 'all' },
|
|
415
|
+
{ key: 'JANKY', label: t('performance.catJanky'), icon: 'janky' },
|
|
416
|
+
{ key: 'NAVIGATION', label: t('performance.catNavigation'), icon: 'nav' },
|
|
417
|
+
{ key: 'RENDER', label: t('performance.catRender'), icon: 'render' },
|
|
418
|
+
{ key: 'MEMORY', label: t('performance.catMemory'), icon: 'memory' },
|
|
419
|
+
{ key: 'IO', label: t('performance.catIo'), icon: 'io' },
|
|
420
420
|
].map(cat => {
|
|
421
421
|
const isSelected = filterCategory === cat.key;
|
|
422
|
+
const iconColor = isSelected ? AppColors_1.AppColors.white : AppColors_1.AppColors.grayText;
|
|
422
423
|
return (<TouchableScale_1.default key={cat.key} onPress={() => setFilterCategory(cat.key)} style={[
|
|
423
424
|
perfStyles.categoryChip,
|
|
424
425
|
isSelected && perfStyles.categoryChipActive,
|
|
425
426
|
]}>
|
|
426
|
-
<react_native_1.
|
|
427
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 5 }}>
|
|
428
|
+
{cat.icon === 'all' && <NetworkIcons_1.SparklesIcon size={12} color={iconColor}/>}
|
|
429
|
+
{cat.icon === 'janky' && <NetworkIcons_1.WarningTriangleIcon size={12} color={isSelected ? AppColors_1.AppColors.white : AppColors_1.AppColors.errorColor}/>}
|
|
430
|
+
{cat.icon === 'nav' && <NetworkIcons_1.MapIcon size={12} color={iconColor}/>}
|
|
431
|
+
{cat.icon === 'render' && <NetworkIcons_1.AtomIcon size={12} color={iconColor}/>}
|
|
432
|
+
{cat.icon === 'memory' && <NetworkIcons_1.BrainIcon size={12} color={iconColor}/>}
|
|
433
|
+
{cat.icon === 'io' && <NetworkIcons_1.GlobeIcon size={12} color={iconColor}/>}
|
|
434
|
+
<react_native_1.Text style={[
|
|
427
435
|
perfStyles.categoryChipText,
|
|
428
436
|
isSelected && perfStyles.categoryChipTextActive,
|
|
429
437
|
]}>
|
|
430
|
-
|
|
431
|
-
|
|
438
|
+
{cat.label}
|
|
439
|
+
</react_native_1.Text>
|
|
440
|
+
</react_native_1.View>
|
|
432
441
|
</TouchableScale_1.default>);
|
|
433
442
|
})}
|
|
434
443
|
</react_native_1.ScrollView>
|
|
@@ -439,13 +448,13 @@ const PerformanceTab = react_1.default.memo(() => {
|
|
|
439
448
|
{/* ── 1. REAL-TIME FPS SCORECARD & SMOOTH AREA GRAPH ── */}
|
|
440
449
|
<react_native_1.View style={perfStyles.heroCard}>
|
|
441
450
|
<react_native_1.View style={perfStyles.heroHeaderRow}>
|
|
442
|
-
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap:
|
|
443
|
-
<NetworkIcons_1.PerformanceIcon color={AppColors_1.AppColors.purple} size={
|
|
444
|
-
<react_native_1.View>
|
|
445
|
-
<react_native_1.Text style={perfStyles.heroTitle}>
|
|
451
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 8, flex: 1 }}>
|
|
452
|
+
<NetworkIcons_1.PerformanceIcon color={AppColors_1.AppColors.purple} size={18}/>
|
|
453
|
+
<react_native_1.View style={{ flex: 1 }}>
|
|
454
|
+
<react_native_1.Text style={perfStyles.heroTitle} numberOfLines={1}>
|
|
446
455
|
{t('performance.fpsAreaChartTitle')}
|
|
447
456
|
</react_native_1.Text>
|
|
448
|
-
<react_native_1.Text style={perfStyles.heroSubTitle}>
|
|
457
|
+
<react_native_1.Text style={perfStyles.heroSubTitle} numberOfLines={1}>
|
|
449
458
|
{t('performance.fpsAreaChartSub')}
|
|
450
459
|
</react_native_1.Text>
|
|
451
460
|
</react_native_1.View>
|
|
@@ -1160,18 +1169,21 @@ const perfStyles = react_native_1.StyleSheet.create({
|
|
|
1160
1169
|
color: AppColors_1.AppColors.grayTextWeak,
|
|
1161
1170
|
},
|
|
1162
1171
|
fpsStatsGrid: {
|
|
1172
|
+
flex: 1,
|
|
1163
1173
|
flexDirection: 'row',
|
|
1164
1174
|
alignItems: 'center',
|
|
1165
|
-
|
|
1175
|
+
justifyContent: 'space-around',
|
|
1176
|
+
marginLeft: 8,
|
|
1166
1177
|
},
|
|
1167
1178
|
statItem: {
|
|
1168
1179
|
alignItems: 'center',
|
|
1169
|
-
|
|
1180
|
+
flex: 1,
|
|
1170
1181
|
},
|
|
1171
1182
|
statLabel: {
|
|
1172
|
-
fontFamily: AppFonts_1.AppFonts.
|
|
1173
|
-
fontSize:
|
|
1183
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
1184
|
+
fontSize: 9.5,
|
|
1174
1185
|
color: AppColors_1.AppColors.grayTextWeak,
|
|
1186
|
+
textAlign: 'center',
|
|
1175
1187
|
},
|
|
1176
1188
|
statValue: {
|
|
1177
1189
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { NetworkLog } from '../../types';
|
|
3
|
+
interface RequestReplayModalProps {
|
|
4
|
+
visible: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
request: NetworkLog;
|
|
7
|
+
}
|
|
8
|
+
export declare const RequestReplayModal: React.FC<RequestReplayModalProps>;
|
|
9
|
+
export default RequestReplayModal;
|