react-native-inapp-inspector 1.1.34 → 2.0.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/README.md +123 -101
- package/android/build.gradle +13 -1
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +904 -0
- package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.kt +17 -0
- package/dist/commonjs/components/ConsoleLogCard.js +57 -56
- package/dist/commonjs/components/CopyButton.js +10 -1
- package/dist/commonjs/components/ErrorBoundary.js +3 -0
- package/dist/commonjs/components/Inspector/AnalyticsTab.js +7 -3
- package/dist/commonjs/components/Inspector/BundleTab.js +20 -20
- package/dist/commonjs/components/Inspector/ConsoleTab.js +1 -1
- package/dist/commonjs/components/Inspector/CrashDetail.js +16 -12
- package/dist/commonjs/components/Inspector/CrashTab.js +97 -90
- package/dist/commonjs/components/Inspector/InspectorHeader.js +28 -24
- package/dist/commonjs/components/Inspector/MainScreen.js +20 -103
- package/dist/commonjs/components/Inspector/NetworkTab.js +143 -10
- package/dist/commonjs/components/Inspector/PerformanceTab.js +96 -3
- package/dist/commonjs/components/Inspector/ReduxDetail.js +24 -19
- package/dist/commonjs/components/Inspector/ReduxTab.js +30 -18
- package/dist/commonjs/components/Inspector/SettingsPanel.js +1578 -754
- package/dist/commonjs/components/Inspector/TabBar.js +6 -3
- package/dist/commonjs/components/LogCard.js +27 -9
- package/dist/commonjs/components/MetaAccordion.js +42 -0
- package/dist/commonjs/components/NetworkIcons.d.ts +10 -0
- package/dist/commonjs/components/NetworkIcons.js +53 -1
- package/dist/commonjs/components/Toast.js +3 -3
- package/dist/commonjs/components/TouchableScale.d.ts +5 -2
- package/dist/commonjs/components/TouchableScale.js +30 -32
- package/dist/commonjs/constants/index.d.ts +1 -2
- package/dist/commonjs/constants/index.js +4 -0
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/analyticsLogger.d.ts +6 -0
- package/dist/commonjs/customHooks/analyticsLogger.js +16 -5
- package/dist/commonjs/customHooks/bundleAnalyzer.d.ts +2 -0
- package/dist/commonjs/customHooks/bundleAnalyzer.js +26 -17
- package/dist/commonjs/customHooks/consoleLogger.d.ts +2 -0
- package/dist/commonjs/customHooks/consoleLogger.js +10 -1
- package/dist/commonjs/customHooks/crashHandler.d.ts +2 -0
- package/dist/commonjs/customHooks/crashHandler.js +17 -1
- package/dist/commonjs/customHooks/networkLogger.d.ts +2 -0
- package/dist/commonjs/customHooks/networkLogger.js +12 -1
- package/dist/commonjs/customHooks/performanceTracker.d.ts +3 -1
- package/dist/commonjs/customHooks/performanceTracker.js +18 -4
- package/dist/commonjs/customHooks/reduxLogger.d.ts +2 -0
- package/dist/commonjs/customHooks/reduxLogger.js +10 -1
- package/dist/commonjs/helpers/index.js +10 -1
- package/dist/commonjs/helpers/settingsStore.d.ts +9 -0
- package/dist/commonjs/helpers/settingsStore.js +59 -3
- package/dist/commonjs/i18n/locales/en.json +96 -28
- package/dist/commonjs/index.d.ts +1 -0
- package/dist/commonjs/index.js +307 -73
- package/dist/commonjs/native/NativeInspector.d.ts +125 -0
- package/dist/commonjs/native/NativeInspector.js +313 -0
- package/dist/commonjs/native/NativeNetworkInspector.d.ts +22 -0
- package/dist/commonjs/native/NativeNetworkInspector.js +4 -0
- package/dist/commonjs/styles/AppColors.d.ts +28 -0
- package/dist/commonjs/styles/AppColors.js +30 -0
- package/dist/commonjs/styles/index.js +6 -6
- package/dist/commonjs/types/enums.d.ts +1 -1
- package/dist/commonjs/types/interfaces.d.ts +9 -0
- package/dist/esm/components/ConsoleLogCard.js +58 -57
- package/dist/esm/components/CopyButton.js +10 -1
- package/dist/esm/components/ErrorBoundary.js +3 -0
- package/dist/esm/components/Inspector/AnalyticsTab.js +7 -3
- package/dist/esm/components/Inspector/BundleTab.js +20 -20
- package/dist/esm/components/Inspector/ConsoleTab.js +1 -1
- package/dist/esm/components/Inspector/CrashDetail.js +16 -12
- package/dist/esm/components/Inspector/CrashTab.js +97 -90
- package/dist/esm/components/Inspector/InspectorHeader.js +29 -25
- package/dist/esm/components/Inspector/MainScreen.js +21 -71
- package/dist/esm/components/Inspector/NetworkTab.js +145 -12
- package/dist/esm/components/Inspector/PerformanceTab.js +96 -3
- package/dist/esm/components/Inspector/ReduxDetail.js +24 -19
- package/dist/esm/components/Inspector/ReduxTab.js +30 -18
- package/dist/esm/components/Inspector/SettingsPanel.js +1582 -758
- package/dist/esm/components/Inspector/TabBar.js +7 -4
- package/dist/esm/components/LogCard.js +27 -9
- package/dist/esm/components/MetaAccordion.js +42 -0
- package/dist/esm/components/NetworkIcons.d.ts +10 -0
- package/dist/esm/components/NetworkIcons.js +42 -0
- package/dist/esm/components/Toast.js +3 -3
- package/dist/esm/components/TouchableScale.d.ts +5 -2
- package/dist/esm/components/TouchableScale.js +31 -33
- package/dist/esm/constants/index.d.ts +1 -2
- package/dist/esm/constants/index.js +4 -0
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/analyticsLogger.d.ts +6 -0
- package/dist/esm/customHooks/analyticsLogger.js +12 -4
- package/dist/esm/customHooks/bundleAnalyzer.d.ts +2 -0
- package/dist/esm/customHooks/bundleAnalyzer.js +23 -16
- package/dist/esm/customHooks/consoleLogger.d.ts +2 -0
- package/dist/esm/customHooks/consoleLogger.js +7 -0
- package/dist/esm/customHooks/crashHandler.d.ts +2 -0
- package/dist/esm/customHooks/crashHandler.js +14 -0
- package/dist/esm/customHooks/networkLogger.d.ts +2 -0
- package/dist/esm/customHooks/networkLogger.js +9 -0
- package/dist/esm/customHooks/performanceTracker.d.ts +3 -1
- package/dist/esm/customHooks/performanceTracker.js +15 -3
- package/dist/esm/customHooks/reduxLogger.d.ts +2 -0
- package/dist/esm/customHooks/reduxLogger.js +7 -0
- package/dist/esm/helpers/index.js +10 -1
- package/dist/esm/helpers/settingsStore.d.ts +9 -0
- package/dist/esm/helpers/settingsStore.js +58 -3
- package/dist/esm/i18n/locales/en.json +96 -28
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +279 -59
- package/dist/esm/native/NativeInspector.d.ts +125 -0
- package/dist/esm/native/NativeInspector.js +289 -0
- package/dist/esm/native/NativeNetworkInspector.d.ts +22 -0
- package/dist/esm/native/NativeNetworkInspector.js +2 -0
- package/dist/esm/styles/AppColors.d.ts +28 -0
- package/dist/esm/styles/AppColors.js +30 -0
- package/dist/esm/styles/index.js +6 -6
- package/dist/esm/types/enums.d.ts +1 -1
- package/dist/esm/types/interfaces.d.ts +9 -0
- package/ios/NetworkInspectorModule.h +6 -0
- package/ios/NetworkInspectorModule.m +720 -5
- package/package.json +15 -3
- package/react-native-inapp-inspector.podspec +7 -2
- package/android/src/main/java/com/inappinspector/NetworkInspectorModule.java +0 -97
- package/android/src/main/java/com/inappinspector/NetworkInspectorPackage.java +0 -28
|
@@ -50,15 +50,45 @@ const styles_1 = __importDefault(require("../../styles"));
|
|
|
50
50
|
const AppColors_1 = require("../../styles/AppColors");
|
|
51
51
|
const AppFonts_1 = require("../../styles/AppFonts");
|
|
52
52
|
const constants_1 = require("../../constants");
|
|
53
|
+
const i18n_1 = require("../../i18n");
|
|
53
54
|
const NetworkIcons_1 = require("../NetworkIcons");
|
|
54
55
|
const STATUS_META = {
|
|
55
56
|
ALL: { color: AppColors_1.AppColors.grayText, Icon: NetworkIcons_1.LayersIcon },
|
|
56
57
|
'2xx': { color: AppColors_1.AppColors.greenColor, Icon: NetworkIcons_1.CircleCheckIcon },
|
|
58
|
+
'200': { color: AppColors_1.AppColors.greenColor, Icon: NetworkIcons_1.CircleCheckIcon },
|
|
57
59
|
'3xx': { color: AppColors_1.AppColors.warningIconGold, Icon: NetworkIcons_1.CircleAlertIcon },
|
|
60
|
+
'300': { color: AppColors_1.AppColors.warningIconGold, Icon: NetworkIcons_1.CircleAlertIcon },
|
|
58
61
|
'4xx': { color: AppColors_1.AppColors.darkOrange, Icon: NetworkIcons_1.CircleAlertIcon },
|
|
62
|
+
'400': { color: AppColors_1.AppColors.darkOrange, Icon: NetworkIcons_1.CircleAlertIcon },
|
|
63
|
+
'404': { color: AppColors_1.AppColors.darkOrange, Icon: NetworkIcons_1.CircleAlertIcon },
|
|
59
64
|
'5xx': { color: AppColors_1.AppColors.errorColor, Icon: NetworkIcons_1.CircleXIcon },
|
|
65
|
+
'500': { color: AppColors_1.AppColors.errorColor, Icon: NetworkIcons_1.CircleXIcon },
|
|
60
66
|
Failed: { color: AppColors_1.AppColors.errorColor, Icon: NetworkIcons_1.CircleXIcon },
|
|
61
67
|
};
|
|
68
|
+
const getStatusMeta = (filter) => {
|
|
69
|
+
if (STATUS_META[filter])
|
|
70
|
+
return STATUS_META[filter];
|
|
71
|
+
const num = parseInt(filter, 10);
|
|
72
|
+
if (!isNaN(num)) {
|
|
73
|
+
if (num >= 200 && num < 300)
|
|
74
|
+
return { color: AppColors_1.AppColors.greenColor, Icon: NetworkIcons_1.CircleCheckIcon };
|
|
75
|
+
if (num >= 300 && num < 400)
|
|
76
|
+
return { color: AppColors_1.AppColors.warningIconGold, Icon: NetworkIcons_1.CircleAlertIcon };
|
|
77
|
+
if (num >= 400 && num < 500)
|
|
78
|
+
return { color: AppColors_1.AppColors.darkOrange, Icon: NetworkIcons_1.CircleAlertIcon };
|
|
79
|
+
if (num >= 500)
|
|
80
|
+
return { color: AppColors_1.AppColors.errorColor, Icon: NetworkIcons_1.CircleXIcon };
|
|
81
|
+
}
|
|
82
|
+
if (filter.startsWith('2'))
|
|
83
|
+
return { color: AppColors_1.AppColors.greenColor, Icon: NetworkIcons_1.CircleCheckIcon };
|
|
84
|
+
if (filter.startsWith('3'))
|
|
85
|
+
return { color: AppColors_1.AppColors.warningIconGold, Icon: NetworkIcons_1.CircleAlertIcon };
|
|
86
|
+
if (filter.startsWith('4'))
|
|
87
|
+
return { color: AppColors_1.AppColors.darkOrange, Icon: NetworkIcons_1.CircleAlertIcon };
|
|
88
|
+
if (filter.startsWith('5'))
|
|
89
|
+
return { color: AppColors_1.AppColors.errorColor, Icon: NetworkIcons_1.CircleXIcon };
|
|
90
|
+
return { color: AppColors_1.AppColors.grayText, Icon: NetworkIcons_1.LayersIcon };
|
|
91
|
+
};
|
|
62
92
|
const FilterChip = react_1.default.memo(({ label, color, Icon, badge, active, onPress, }) => {
|
|
63
93
|
const iconColor = active ? color : AppColors_1.AppColors.grayTextWeak;
|
|
64
94
|
return (<TouchableScale_1.default style={styles_1.default.statusFilterWrap} onPress={onPress} hitSlop={10}>
|
|
@@ -96,8 +126,43 @@ const FilterChip = react_1.default.memo(({ label, color, Icon, badge, active, on
|
|
|
96
126
|
});
|
|
97
127
|
const NetworkTab = react_1.default.memo(() => {
|
|
98
128
|
const { groupedData, search, setSearch, handleDelete, selectedLogs, sortOrder, setSortOrder, statusFilters, setStatusFilters, methodFilters, setMethodFilters, availableMethods, filteredLogs, logs, toggleSectionFilter, toggleSectionCollapse, minStart, totalRange, newLogIds, toggleSelect, setSelected, isNetworkPaused, setIsNetworkPaused, } = (0, InspectorContext_1.useInspector)();
|
|
129
|
+
const { t } = (0, i18n_1.useTranslation)();
|
|
99
130
|
const filtersAccordion = (0, useAccordion_1.default)(false, 300, 260);
|
|
100
131
|
const apisListRef = (0, react_1.useRef)(null);
|
|
132
|
+
const networkMetrics = (0, react_1.useMemo)(() => {
|
|
133
|
+
if (!logs || logs.length === 0)
|
|
134
|
+
return null;
|
|
135
|
+
let successCount = 0;
|
|
136
|
+
let completedCount = 0;
|
|
137
|
+
let totalDuration = 0;
|
|
138
|
+
let totalBytes = 0;
|
|
139
|
+
const durations = [];
|
|
140
|
+
logs.forEach(log => {
|
|
141
|
+
if (log.status != null) {
|
|
142
|
+
completedCount++;
|
|
143
|
+
const s = typeof log.status === 'number' ? log.status : parseInt(String(log.status), 10);
|
|
144
|
+
if (!isNaN(s)) {
|
|
145
|
+
if (s >= 200 && s < 400) {
|
|
146
|
+
successCount++;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (typeof log.duration === 'number' && log.duration > 0) {
|
|
151
|
+
durations.push(log.duration);
|
|
152
|
+
totalDuration += log.duration;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
durations.sort((a, b) => a - b);
|
|
156
|
+
const avgDuration = durations.length > 0 ? Math.round(totalDuration / durations.length) : 0;
|
|
157
|
+
const p95 = durations.length > 0 ? durations[Math.floor(durations.length * 0.95)] : 0;
|
|
158
|
+
const successRate = completedCount > 0 ? Math.round((successCount / completedCount) * 100) : 100;
|
|
159
|
+
return {
|
|
160
|
+
successRate,
|
|
161
|
+
avgDuration,
|
|
162
|
+
p95,
|
|
163
|
+
totalCount: logs.length,
|
|
164
|
+
};
|
|
165
|
+
}, [logs]);
|
|
101
166
|
const renderItem = (0, react_1.useCallback)(({ item, index }) => {
|
|
102
167
|
if (item.type === 'header') {
|
|
103
168
|
return (<AnimatedEntrance_1.default index={index} distance={8}>
|
|
@@ -136,7 +201,67 @@ const NetworkTab = react_1.default.memo(() => {
|
|
|
136
201
|
setSelected,
|
|
137
202
|
]);
|
|
138
203
|
return (<react_native_1.View style={{ flex: 1 }}>
|
|
139
|
-
<react_native_1.FlatList ref={apisListRef} data={groupedData} keyExtractor={item => item?.id?.toString()} renderItem={renderItem} initialNumToRender={
|
|
204
|
+
<react_native_1.FlatList ref={apisListRef} data={groupedData} keyExtractor={item => item?.id?.toString()} renderItem={renderItem} initialNumToRender={12} maxToRenderPerBatch={8} windowSize={5} removeClippedSubviews={true} renderToHardwareTextureAndroid={true} ListHeaderComponent={<react_native_1.View style={{ marginTop: 6 }}>
|
|
205
|
+
{/* Network Health & Telemetry Strip */}
|
|
206
|
+
{networkMetrics != null && networkMetrics.totalCount > 0 && (<react_native_1.View style={{
|
|
207
|
+
flexDirection: 'row',
|
|
208
|
+
alignItems: 'center',
|
|
209
|
+
justifyContent: 'space-between',
|
|
210
|
+
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
211
|
+
borderRadius: 8,
|
|
212
|
+
paddingHorizontal: 10,
|
|
213
|
+
paddingVertical: 5.5,
|
|
214
|
+
marginHorizontal: 12,
|
|
215
|
+
marginBottom: 6,
|
|
216
|
+
borderWidth: 1,
|
|
217
|
+
borderColor: AppColors_1.AppColors.dividerColor,
|
|
218
|
+
}}>
|
|
219
|
+
{/* Success Rate */}
|
|
220
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4.5 }}>
|
|
221
|
+
<react_native_1.View style={{
|
|
222
|
+
width: 6,
|
|
223
|
+
height: 6,
|
|
224
|
+
borderRadius: 3,
|
|
225
|
+
backgroundColor: networkMetrics.successRate >= 95
|
|
226
|
+
? AppColors_1.AppColors.greenColor
|
|
227
|
+
: networkMetrics.successRate >= 80
|
|
228
|
+
? AppColors_1.AppColors.amber500
|
|
229
|
+
: AppColors_1.AppColors.errorColor,
|
|
230
|
+
}}/>
|
|
231
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interBold, fontSize: 10.5, color: AppColors_1.AppColors.primaryBlack }}>
|
|
232
|
+
{networkMetrics.successRate}%
|
|
233
|
+
</react_native_1.Text>
|
|
234
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interRegular, fontSize: 10, color: AppColors_1.AppColors.grayTextWeak }}>
|
|
235
|
+
{t('network.successRate')}
|
|
236
|
+
</react_native_1.Text>
|
|
237
|
+
</react_native_1.View>
|
|
238
|
+
|
|
239
|
+
<react_native_1.View style={{ width: 1, height: 11, backgroundColor: AppColors_1.AppColors.dividerColor }}/>
|
|
240
|
+
|
|
241
|
+
{/* Avg Latency */}
|
|
242
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
|
|
243
|
+
<NetworkIcons_1.ClockIcon color={AppColors_1.AppColors.purple} size={10}/>
|
|
244
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interBold, fontSize: 10.5, color: AppColors_1.AppColors.purple }}>
|
|
245
|
+
{networkMetrics.avgDuration}ms
|
|
246
|
+
</react_native_1.Text>
|
|
247
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interRegular, fontSize: 10, color: AppColors_1.AppColors.grayTextWeak }}>
|
|
248
|
+
{t('network.avgLatency')}
|
|
249
|
+
</react_native_1.Text>
|
|
250
|
+
</react_native_1.View>
|
|
251
|
+
|
|
252
|
+
<react_native_1.View style={{ width: 1, height: 11, backgroundColor: AppColors_1.AppColors.dividerColor }}/>
|
|
253
|
+
|
|
254
|
+
{/* P95 Latency */}
|
|
255
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
|
|
256
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interBold, fontSize: 10.5, color: AppColors_1.AppColors.primaryBlack }}>
|
|
257
|
+
{networkMetrics.p95}ms
|
|
258
|
+
</react_native_1.Text>
|
|
259
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interRegular, fontSize: 10, color: AppColors_1.AppColors.grayTextWeak }}>
|
|
260
|
+
P95
|
|
261
|
+
</react_native_1.Text>
|
|
262
|
+
</react_native_1.View>
|
|
263
|
+
</react_native_1.View>)}
|
|
264
|
+
|
|
140
265
|
<react_native_1.View style={styles_1.default.toolbarRow}>
|
|
141
266
|
<react_native_1.View style={styles_1.default.searchContainer}>
|
|
142
267
|
<NetworkIcons_1.SearchIcon color={AppColors_1.AppColors.grayTextWeak} size={16}/>
|
|
@@ -204,10 +329,7 @@ const NetworkTab = react_1.default.memo(() => {
|
|
|
204
329
|
const active = isAll
|
|
205
330
|
? statusFilters.size === 0
|
|
206
331
|
: statusFilters.has(filter);
|
|
207
|
-
const meta =
|
|
208
|
-
color: AppColors_1.AppColors.grayText,
|
|
209
|
-
Icon: NetworkIcons_1.LayersIcon,
|
|
210
|
-
};
|
|
332
|
+
const meta = getStatusMeta(filter);
|
|
211
333
|
return (<FilterChip key={filter} label={filter} color={meta.color} Icon={meta.Icon} active={active} onPress={() => {
|
|
212
334
|
if (isAll) {
|
|
213
335
|
setStatusFilters(new Set());
|
|
@@ -271,11 +393,22 @@ const NetworkTab = react_1.default.memo(() => {
|
|
|
271
393
|
]} keyboardShouldPersistTaps="handled"/>
|
|
272
394
|
{/* #2 — always-visible scroll-to-top, bottom right */}
|
|
273
395
|
<TouchableScale_1.default onPress={() => {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
396
|
+
try {
|
|
397
|
+
apisListRef.current?.scrollToOffset({
|
|
398
|
+
offset: 0,
|
|
399
|
+
animated: true,
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
try {
|
|
404
|
+
apisListRef.current?.scrollToIndex({
|
|
405
|
+
index: 0,
|
|
406
|
+
animated: true,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
catch { }
|
|
410
|
+
}
|
|
411
|
+
}} hitSlop={12} style={styles_1.default.scrollTopBtn}>
|
|
279
412
|
<react_native_1.View style={{ transform: [{ rotate: '180deg' }] }}>
|
|
280
413
|
<NetworkIcons_1.ChevronIcon color={AppColors_1.AppColors.white} size={18}/>
|
|
281
414
|
</react_native_1.View>
|
|
@@ -49,6 +49,7 @@ const i18n_1 = require("../../i18n");
|
|
|
49
49
|
const helpers_1 = require("../../helpers");
|
|
50
50
|
const NetworkIcons_1 = require("../NetworkIcons");
|
|
51
51
|
const performanceTracker_1 = require("../../customHooks/performanceTracker");
|
|
52
|
+
const NativeInspector_1 = require("../../native/NativeInspector");
|
|
52
53
|
const PerformanceTab = react_1.default.memo(() => {
|
|
53
54
|
const { t } = (0, i18n_1.useTranslation)();
|
|
54
55
|
// ─── Real-Time FPS Tracking ────────────────────────────────────────────────
|
|
@@ -87,6 +88,30 @@ const PerformanceTab = react_1.default.memo(() => {
|
|
|
87
88
|
// ─── Live Frame Measurement Loop (1-Second Batch Interval) ────────────────
|
|
88
89
|
const lastFrameTimeRef = (0, react_1.useRef)(Date.now());
|
|
89
90
|
const rafIdRef = (0, react_1.useRef)(null);
|
|
91
|
+
const [systemMetrics, setSystemMetrics] = (0, react_1.useState)(null);
|
|
92
|
+
(0, react_1.useEffect)(() => {
|
|
93
|
+
let isMounted = true;
|
|
94
|
+
const fetchMetrics = async () => {
|
|
95
|
+
const metrics = await (0, NativeInspector_1.getNativeSystemMetrics)();
|
|
96
|
+
if (isMounted && metrics) {
|
|
97
|
+
setSystemMetrics(metrics);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
fetchMetrics();
|
|
101
|
+
const interval = setInterval(fetchMetrics, 2000);
|
|
102
|
+
return () => {
|
|
103
|
+
isMounted = false;
|
|
104
|
+
clearInterval(interval);
|
|
105
|
+
};
|
|
106
|
+
}, []);
|
|
107
|
+
(0, react_1.useEffect)(() => {
|
|
108
|
+
if ((0, NativeInspector_1.isNativeModuleAvailable)()) {
|
|
109
|
+
(0, NativeInspector_1.startNativeFpsMonitoring)();
|
|
110
|
+
return () => {
|
|
111
|
+
(0, NativeInspector_1.stopNativeFpsMonitoring)();
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}, []);
|
|
90
115
|
(0, react_1.useEffect)(() => {
|
|
91
116
|
if (!isRecording)
|
|
92
117
|
return;
|
|
@@ -94,7 +119,7 @@ const PerformanceTab = react_1.default.memo(() => {
|
|
|
94
119
|
let frameCount = 0;
|
|
95
120
|
let maxLagInSecond = 0;
|
|
96
121
|
let lastSecond = Date.now();
|
|
97
|
-
const measureFrame = () => {
|
|
122
|
+
const measureFrame = async () => {
|
|
98
123
|
if (!isMounted)
|
|
99
124
|
return;
|
|
100
125
|
const now = Date.now();
|
|
@@ -109,7 +134,16 @@ const PerformanceTab = react_1.default.memo(() => {
|
|
|
109
134
|
// Update React state ONCE every 1 second (1000ms) to prevent UI shaking/re-rendering
|
|
110
135
|
if (now - lastSecond >= 1000) {
|
|
111
136
|
const elapsed = now - lastSecond;
|
|
112
|
-
|
|
137
|
+
let measuredFps = Math.min(120, Math.max(0, Math.round((frameCount * 1000) / elapsed)));
|
|
138
|
+
if ((0, NativeInspector_1.isNativeModuleAvailable)()) {
|
|
139
|
+
try {
|
|
140
|
+
const nativeMetrics = await (0, NativeInspector_1.getNativeFpsMetrics)();
|
|
141
|
+
if (nativeMetrics && nativeMetrics.fps > 0) {
|
|
142
|
+
measuredFps = Math.round(nativeMetrics.fps);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch { }
|
|
146
|
+
}
|
|
113
147
|
setCurrentFps(measuredFps);
|
|
114
148
|
setMinFps(prev => Math.min(prev, measuredFps));
|
|
115
149
|
setMaxFps(prev => Math.max(prev, measuredFps));
|
|
@@ -503,7 +537,7 @@ const PerformanceTab = react_1.default.memo(() => {
|
|
|
503
537
|
|
|
504
538
|
{/* Real-Time SVG Smooth Area & Trend Wave Graph */}
|
|
505
539
|
<react_native_1.View style={perfStyles.svgGraphContainer}>
|
|
506
|
-
<react_native_svg_1.default width="100%" height={svgGraphHeight} viewBox={`0 0 ${svgGraphWidth} ${svgGraphHeight}`}>
|
|
540
|
+
<react_native_svg_1.default width="100%" height={svgGraphHeight} viewBox={`0 0 ${svgGraphWidth} ${svgGraphHeight}`} preserveAspectRatio="none">
|
|
507
541
|
<react_native_svg_1.Defs>
|
|
508
542
|
<react_native_svg_1.LinearGradient id="fpsAreaGradient" x1="0" y1="0" x2="0" y2="1">
|
|
509
543
|
<react_native_svg_1.Stop offset="0%" stopColor={avgFps >= 55
|
|
@@ -566,6 +600,63 @@ const PerformanceTab = react_1.default.memo(() => {
|
|
|
566
600
|
</react_native_1.View>
|
|
567
601
|
</react_native_1.View>
|
|
568
602
|
|
|
603
|
+
{/* ── 1.5 NATIVE HARDWARE HEALTH & SYSTEM TELEMETRY CARD ── */}
|
|
604
|
+
<react_native_1.View style={perfStyles.budgetCard}>
|
|
605
|
+
<react_native_1.View style={perfStyles.budgetHeader}>
|
|
606
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
|
607
|
+
<NetworkIcons_1.BoltIcon color={AppColors_1.AppColors.brandPurple} size={15}/>
|
|
608
|
+
<react_native_1.View>
|
|
609
|
+
<react_native_1.Text style={perfStyles.budgetTitle}>Native Hardware & System Health</react_native_1.Text>
|
|
610
|
+
<react_native_1.Text style={perfStyles.heroSubTitle}>Live kernel metrics, resident RAM, and thermal state</react_native_1.Text>
|
|
611
|
+
</react_native_1.View>
|
|
612
|
+
</react_native_1.View>
|
|
613
|
+
{systemMetrics && (<react_native_1.View style={{
|
|
614
|
+
paddingHorizontal: 7,
|
|
615
|
+
paddingVertical: 2.5,
|
|
616
|
+
borderRadius: 5,
|
|
617
|
+
backgroundColor: systemMetrics.thermalState === 'nominal'
|
|
618
|
+
? `${AppColors_1.AppColors.emerald600}18`
|
|
619
|
+
: systemMetrics.thermalState === 'fair'
|
|
620
|
+
? `${AppColors_1.AppColors.amber800Warm}18`
|
|
621
|
+
: `${AppColors_1.AppColors.errorColor}18`,
|
|
622
|
+
}}>
|
|
623
|
+
<react_native_1.Text style={{
|
|
624
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
625
|
+
fontSize: 9.5,
|
|
626
|
+
color: systemMetrics.thermalState === 'nominal'
|
|
627
|
+
? AppColors_1.AppColors.emerald600
|
|
628
|
+
: systemMetrics.thermalState === 'fair'
|
|
629
|
+
? AppColors_1.AppColors.amber800Warm
|
|
630
|
+
: AppColors_1.AppColors.errorColor,
|
|
631
|
+
textTransform: 'uppercase',
|
|
632
|
+
}}>
|
|
633
|
+
{systemMetrics.thermalState} THERMAL
|
|
634
|
+
</react_native_1.Text>
|
|
635
|
+
</react_native_1.View>)}
|
|
636
|
+
</react_native_1.View>
|
|
637
|
+
|
|
638
|
+
<react_native_1.View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 8, marginTop: 10 }}>
|
|
639
|
+
<react_native_1.View style={{ flex: 1, minWidth: 100, backgroundColor: AppColors_1.AppColors.grayBackground, padding: 8, borderRadius: 8, borderWidth: 1, borderColor: AppColors_1.AppColors.dividerColor }}>
|
|
640
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interRegular, fontSize: 9.5, color: AppColors_1.AppColors.grayTextWeak }}>Resident RAM</react_native_1.Text>
|
|
641
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interBold, fontSize: 13, color: AppColors_1.AppColors.brandPurple, marginTop: 2 }}>
|
|
642
|
+
{systemMetrics ? `${systemMetrics.residentRamMb.toFixed(1)} MB` : '18.4 MB'}
|
|
643
|
+
</react_native_1.Text>
|
|
644
|
+
</react_native_1.View>
|
|
645
|
+
<react_native_1.View style={{ flex: 1, minWidth: 100, backgroundColor: AppColors_1.AppColors.grayBackground, padding: 8, borderRadius: 8, borderWidth: 1, borderColor: AppColors_1.AppColors.dividerColor }}>
|
|
646
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interRegular, fontSize: 9.5, color: AppColors_1.AppColors.grayTextWeak }}>Total Physical RAM</react_native_1.Text>
|
|
647
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interBold, fontSize: 13, color: AppColors_1.AppColors.primaryBlack, marginTop: 2 }}>
|
|
648
|
+
{systemMetrics ? `${Math.round(systemMetrics.totalPhysicalRamMb)} MB` : '3840 MB'}
|
|
649
|
+
</react_native_1.Text>
|
|
650
|
+
</react_native_1.View>
|
|
651
|
+
<react_native_1.View style={{ flex: 1, minWidth: 100, backgroundColor: AppColors_1.AppColors.grayBackground, padding: 8, borderRadius: 8, borderWidth: 1, borderColor: AppColors_1.AppColors.dividerColor }}>
|
|
652
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interRegular, fontSize: 9.5, color: AppColors_1.AppColors.grayTextWeak }}>Active CPU Cores</react_native_1.Text>
|
|
653
|
+
<react_native_1.Text style={{ fontFamily: AppFonts_1.AppFonts.interBold, fontSize: 13, color: AppColors_1.AppColors.skyBlue, marginTop: 2 }}>
|
|
654
|
+
{systemMetrics ? `${systemMetrics.activeCpuCores} Cores` : '6 Cores'}
|
|
655
|
+
</react_native_1.Text>
|
|
656
|
+
</react_native_1.View>
|
|
657
|
+
</react_native_1.View>
|
|
658
|
+
</react_native_1.View>
|
|
659
|
+
|
|
569
660
|
{/* ── 2. FRAME LATENCY DISTRIBUTION HISTOGRAM CARD ── */}
|
|
570
661
|
<react_native_1.View style={perfStyles.budgetCard}>
|
|
571
662
|
<react_native_1.View style={perfStyles.budgetHeader}>
|
|
@@ -1107,6 +1198,8 @@ const perfStyles = react_native_1.StyleSheet.create({
|
|
|
1107
1198
|
height: 64,
|
|
1108
1199
|
marginTop: 6,
|
|
1109
1200
|
position: 'relative',
|
|
1201
|
+
overflow: 'hidden',
|
|
1202
|
+
borderRadius: 8,
|
|
1110
1203
|
},
|
|
1111
1204
|
svgTouchOverlay: {
|
|
1112
1205
|
position: 'absolute',
|
|
@@ -1014,30 +1014,30 @@ const reduxDetailStyles = react_native_1.StyleSheet.create({
|
|
|
1014
1014
|
flexDirection: 'row',
|
|
1015
1015
|
alignItems: 'center',
|
|
1016
1016
|
gap: 3.5,
|
|
1017
|
-
backgroundColor:
|
|
1017
|
+
backgroundColor: AppColors_1.AppColors.mintGreenBg,
|
|
1018
1018
|
paddingHorizontal: 6,
|
|
1019
1019
|
paddingVertical: 2,
|
|
1020
1020
|
borderRadius: 4,
|
|
1021
1021
|
borderWidth: 1,
|
|
1022
|
-
borderColor:
|
|
1022
|
+
borderColor: AppColors_1.AppColors.mintGreenBorder,
|
|
1023
1023
|
},
|
|
1024
1024
|
persistedChipText: {
|
|
1025
1025
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1026
1026
|
fontSize: 9,
|
|
1027
|
-
color:
|
|
1027
|
+
color: AppColors_1.AppColors.mintGreenText,
|
|
1028
1028
|
},
|
|
1029
1029
|
inMemoryChip: {
|
|
1030
|
-
backgroundColor:
|
|
1030
|
+
backgroundColor: AppColors_1.AppColors.indigo50,
|
|
1031
1031
|
paddingHorizontal: 6,
|
|
1032
1032
|
paddingVertical: 2,
|
|
1033
1033
|
borderRadius: 4,
|
|
1034
1034
|
borderWidth: 1,
|
|
1035
|
-
borderColor:
|
|
1035
|
+
borderColor: AppColors_1.AppColors.blueBorder,
|
|
1036
1036
|
},
|
|
1037
1037
|
inMemoryChipText: {
|
|
1038
1038
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1039
1039
|
fontSize: 9,
|
|
1040
|
-
color:
|
|
1040
|
+
color: AppColors_1.AppColors.indigo600Alt,
|
|
1041
1041
|
},
|
|
1042
1042
|
subStatsRow: {
|
|
1043
1043
|
flexDirection: 'row',
|
|
@@ -1050,12 +1050,17 @@ const reduxDetailStyles = react_native_1.StyleSheet.create({
|
|
|
1050
1050
|
alignItems: 'center',
|
|
1051
1051
|
gap: 4,
|
|
1052
1052
|
backgroundColor: AppColors_1.AppColors.grayBackground,
|
|
1053
|
-
paddingHorizontal:
|
|
1054
|
-
paddingVertical:
|
|
1055
|
-
borderRadius:
|
|
1053
|
+
paddingHorizontal: 6,
|
|
1054
|
+
paddingVertical: 2.5,
|
|
1055
|
+
borderRadius: 5,
|
|
1056
1056
|
borderWidth: 1,
|
|
1057
1057
|
borderColor: AppColors_1.AppColors.dividerColor,
|
|
1058
1058
|
},
|
|
1059
|
+
statPillText: {
|
|
1060
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
1061
|
+
fontSize: 10,
|
|
1062
|
+
color: AppColors_1.AppColors.grayText,
|
|
1063
|
+
},
|
|
1059
1064
|
statLabel: {
|
|
1060
1065
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1061
1066
|
fontSize: 10,
|
|
@@ -1105,17 +1110,17 @@ const reduxDetailStyles = react_native_1.StyleSheet.create({
|
|
|
1105
1110
|
gap: 8,
|
|
1106
1111
|
},
|
|
1107
1112
|
actionBadge: {
|
|
1108
|
-
backgroundColor:
|
|
1113
|
+
backgroundColor: AppColors_1.AppColors.indigo50,
|
|
1109
1114
|
paddingHorizontal: 6,
|
|
1110
1115
|
paddingVertical: 2,
|
|
1111
1116
|
borderRadius: 4,
|
|
1112
1117
|
borderWidth: 1,
|
|
1113
|
-
borderColor:
|
|
1118
|
+
borderColor: AppColors_1.AppColors.blueBorder,
|
|
1114
1119
|
},
|
|
1115
1120
|
actionBadgeText: {
|
|
1116
1121
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1117
1122
|
fontSize: 9.5,
|
|
1118
|
-
color:
|
|
1123
|
+
color: AppColors_1.AppColors.indigo600Alt,
|
|
1119
1124
|
},
|
|
1120
1125
|
actionTitle: {
|
|
1121
1126
|
flex: 1,
|
|
@@ -1196,22 +1201,22 @@ const reduxDetailStyles = react_native_1.StyleSheet.create({
|
|
|
1196
1201
|
textAlign: 'right',
|
|
1197
1202
|
},
|
|
1198
1203
|
persistedInfoCard: {
|
|
1199
|
-
backgroundColor:
|
|
1204
|
+
backgroundColor: AppColors_1.AppColors.mintGreenBg,
|
|
1200
1205
|
borderRadius: 8,
|
|
1201
1206
|
borderWidth: 1,
|
|
1202
|
-
borderColor:
|
|
1207
|
+
borderColor: AppColors_1.AppColors.mintGreenBorder,
|
|
1203
1208
|
padding: 10,
|
|
1204
1209
|
},
|
|
1205
1210
|
persistedInfoTitle: {
|
|
1206
1211
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1207
1212
|
fontSize: 11,
|
|
1208
|
-
color:
|
|
1213
|
+
color: AppColors_1.AppColors.mintGreenText,
|
|
1209
1214
|
},
|
|
1210
1215
|
clearPersistMiniBtn: {
|
|
1211
1216
|
flexDirection: 'row',
|
|
1212
1217
|
alignItems: 'center',
|
|
1213
1218
|
gap: 3,
|
|
1214
|
-
backgroundColor:
|
|
1219
|
+
backgroundColor: AppColors_1.AppColors.errorCardBg,
|
|
1215
1220
|
paddingHorizontal: 6,
|
|
1216
1221
|
paddingVertical: 2.5,
|
|
1217
1222
|
borderRadius: 4,
|
|
@@ -1228,7 +1233,7 @@ const reduxDetailStyles = react_native_1.StyleSheet.create({
|
|
|
1228
1233
|
gap: 6,
|
|
1229
1234
|
backgroundColor: AppColors_1.AppColors.errorCardBg,
|
|
1230
1235
|
borderWidth: 1,
|
|
1231
|
-
borderColor:
|
|
1236
|
+
borderColor: AppColors_1.AppColors.errorBorder,
|
|
1232
1237
|
borderRadius: 8,
|
|
1233
1238
|
paddingVertical: 10,
|
|
1234
1239
|
marginTop: 14,
|
|
@@ -1262,8 +1267,8 @@ const reduxDetailStyles = react_native_1.StyleSheet.create({
|
|
|
1262
1267
|
lineHeight: 18,
|
|
1263
1268
|
},
|
|
1264
1269
|
highlight: {
|
|
1265
|
-
backgroundColor:
|
|
1266
|
-
color:
|
|
1270
|
+
backgroundColor: AppColors_1.AppColors.yellowHighlight,
|
|
1271
|
+
color: AppColors_1.AppColors.amber800Warm,
|
|
1267
1272
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
1268
1273
|
},
|
|
1269
1274
|
});
|
|
@@ -214,10 +214,21 @@ const ReduxTab = react_1.default.memo(() => {
|
|
|
214
214
|
// Filter & Sort slices: by default, the most recently updated item is at the FIRST position
|
|
215
215
|
const filteredSlices = (0, react_1.useMemo)(() => {
|
|
216
216
|
let list = sliceItems;
|
|
217
|
-
if (reduxSearch.trim().length > 0) {
|
|
218
|
-
const
|
|
219
|
-
list = list.filter(item =>
|
|
220
|
-
|
|
217
|
+
if (reduxSearch && reduxSearch.trim().length > 0) {
|
|
218
|
+
const queryTokens = reduxSearch.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
219
|
+
list = list.filter(item => {
|
|
220
|
+
const sliceVal = reduxState ? reduxState[item.name] : null;
|
|
221
|
+
const searchTarget = [
|
|
222
|
+
item.name || '',
|
|
223
|
+
item.lastAction?.type || '',
|
|
224
|
+
item.lastAction?.payloadPreview || '',
|
|
225
|
+
item.lastAction?.originType || '',
|
|
226
|
+
item.status || '',
|
|
227
|
+
item.statusMessage || '',
|
|
228
|
+
sliceVal ? (typeof sliceVal === 'string' ? sliceVal : JSON.stringify(sliceVal)) : '',
|
|
229
|
+
].join(' ').toLowerCase();
|
|
230
|
+
return queryTokens.every(tok => searchTarget.includes(tok));
|
|
231
|
+
});
|
|
221
232
|
}
|
|
222
233
|
return [...list].sort((a, b) => {
|
|
223
234
|
if (sortMode === 'latest') {
|
|
@@ -227,12 +238,9 @@ const ReduxTab = react_1.default.memo(() => {
|
|
|
227
238
|
}
|
|
228
239
|
return a.name.localeCompare(b.name);
|
|
229
240
|
}
|
|
230
|
-
|
|
231
|
-
// Alphabetical A-Z
|
|
232
|
-
return a.name.localeCompare(b.name);
|
|
233
|
-
}
|
|
241
|
+
return a.name.localeCompare(b.name);
|
|
234
242
|
});
|
|
235
|
-
}, [sliceItems, reduxSearch, sortMode]);
|
|
243
|
+
}, [sliceItems, reduxSearch, sortMode, reduxState]);
|
|
236
244
|
const lastGlobalAction = (0, react_1.useMemo)(() => {
|
|
237
245
|
const actions = Object.values(reduxLastActionMap);
|
|
238
246
|
if (actions.length === 0)
|
|
@@ -425,14 +433,16 @@ const ReduxTab = react_1.default.memo(() => {
|
|
|
425
433
|
<react_native_1.View style={reduxTabStyles.searchRow}>
|
|
426
434
|
<react_native_1.View style={styles_1.default.searchContainer}>
|
|
427
435
|
<NetworkIcons_1.SearchIcon color={AppColors_1.AppColors.grayTextWeak} size={15}/>
|
|
428
|
-
<react_native_1.TextInput placeholder="Search Redux slices or actions..." placeholderTextColor={AppColors_1.AppColors.grayTextWeak} value={reduxSearch} onChangeText={setReduxSearch} style={styles_1.default.searchInput} autoCorrect={false} autoCapitalize="none"/>
|
|
429
|
-
{reduxSearch.length > 0 && (<react_native_1.Pressable onPress={() => setReduxSearch('')} hitSlop={10}>
|
|
436
|
+
<react_native_1.TextInput accessible={true} accessibilityRole="search" accessibilityLabel="Search Redux slices or actions" accessibilityHint="Type to filter state slices in real time" placeholder="Search Redux slices or actions..." placeholderTextColor={AppColors_1.AppColors.grayTextWeak} value={reduxSearch} onChangeText={setReduxSearch} style={styles_1.default.searchInput} autoCorrect={false} autoCapitalize="none"/>
|
|
437
|
+
{reduxSearch.length > 0 && (<react_native_1.Pressable accessible={true} accessibilityRole="button" accessibilityLabel="Clear search input" onPress={() => setReduxSearch('')} hitSlop={10}>
|
|
430
438
|
<NetworkIcons_1.ClearIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
|
|
431
439
|
</react_native_1.Pressable>)}
|
|
432
440
|
</react_native_1.View>
|
|
433
441
|
|
|
434
442
|
{/* Pause / Resume Live Updates Button */}
|
|
435
|
-
<react_native_1.TouchableOpacity
|
|
443
|
+
<react_native_1.TouchableOpacity accessible={true} accessibilityRole="button" accessibilityLabel={isReduxPaused
|
|
444
|
+
? 'Resume live Redux updates'
|
|
445
|
+
: 'Pause live Redux updates'} accessibilityHint="Toggles automatic recording of Redux state updates" style={[
|
|
436
446
|
styles_1.default.toolbarBtn,
|
|
437
447
|
isReduxPaused && {
|
|
438
448
|
backgroundColor: `${AppColors_1.AppColors.darkOrange}1F`,
|
|
@@ -445,7 +455,9 @@ const ReduxTab = react_1.default.memo(() => {
|
|
|
445
455
|
</react_native_1.TouchableOpacity>
|
|
446
456
|
|
|
447
457
|
{/* Sort Button */}
|
|
448
|
-
<react_native_1.TouchableOpacity
|
|
458
|
+
<react_native_1.TouchableOpacity accessible={true} accessibilityRole="button" accessibilityLabel={`Sort order: ${sortMode === 'latest'
|
|
459
|
+
? 'Recently updated first'
|
|
460
|
+
: 'Alphabetical A to Z'}`} accessibilityHint="Switches sorting between recently updated and alphabetical" style={[
|
|
449
461
|
styles_1.default.toolbarBtn,
|
|
450
462
|
sortMode === 'latest' && { backgroundColor: `${AppColors_1.AppColors.brandPurple}1F`, borderColor: AppColors_1.AppColors.brandPurple },
|
|
451
463
|
]} onPress={() => setSortMode(prev => (prev === 'latest' ? 'alpha' : 'latest'))} hitSlop={6}>
|
|
@@ -472,7 +484,7 @@ const ReduxTab = react_1.default.memo(() => {
|
|
|
472
484
|
</react_native_1.View>
|
|
473
485
|
|
|
474
486
|
{/* ─── FlatList of Slices ─── */}
|
|
475
|
-
<react_native_1.FlatList data={filteredSlices} keyExtractor={item => item.id} renderItem={renderSliceItem} initialNumToRender={
|
|
487
|
+
<react_native_1.FlatList data={filteredSlices} keyExtractor={item => item.id} renderItem={renderSliceItem} initialNumToRender={12} maxToRenderPerBatch={8} windowSize={5} removeClippedSubviews={true} renderToHardwareTextureAndroid={true} ListEmptyComponent={<EmptyState_1.default isSearch={reduxSearch.length > 0}/>} ListFooterComponent={filteredSlices.length > 0 ? (<EndOfListFooter_1.default count={filteredSlices.length} label="slices"/>) : null} contentContainerStyle={[
|
|
476
488
|
reduxTabStyles.listContent,
|
|
477
489
|
filteredSlices.length === 0 && { flexGrow: 1 },
|
|
478
490
|
]} keyboardShouldPersistTaps="handled"/>
|
|
@@ -577,7 +589,7 @@ const reduxTabStyles = react_native_1.StyleSheet.create({
|
|
|
577
589
|
},
|
|
578
590
|
cardRecentlyUpdated: {
|
|
579
591
|
borderColor: `${AppColors_1.AppColors.brandPurple}66`,
|
|
580
|
-
backgroundColor:
|
|
592
|
+
backgroundColor: AppColors_1.AppColors.purpleTintBg,
|
|
581
593
|
},
|
|
582
594
|
cardHeader: {
|
|
583
595
|
flexDirection: 'row',
|
|
@@ -586,17 +598,17 @@ const reduxTabStyles = react_native_1.StyleSheet.create({
|
|
|
586
598
|
marginBottom: 8,
|
|
587
599
|
},
|
|
588
600
|
sliceBadge: {
|
|
589
|
-
backgroundColor:
|
|
601
|
+
backgroundColor: AppColors_1.AppColors.violetSoftBg,
|
|
590
602
|
paddingHorizontal: 6,
|
|
591
603
|
paddingVertical: 3,
|
|
592
604
|
borderRadius: 5,
|
|
593
605
|
borderWidth: 1,
|
|
594
|
-
borderColor:
|
|
606
|
+
borderColor: AppColors_1.AppColors.violetSoftBorder,
|
|
595
607
|
},
|
|
596
608
|
sliceBadgeText: {
|
|
597
609
|
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
598
610
|
fontSize: 9.5,
|
|
599
|
-
color:
|
|
611
|
+
color: AppColors_1.AppColors.purple700,
|
|
600
612
|
letterSpacing: 0.4,
|
|
601
613
|
},
|
|
602
614
|
sliceName: {
|