react-native-inapp-inspector 2.3.7 → 2.3.9
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/dist/commonjs/components/Inspector/AnalyticsTab.js +27 -2
- package/dist/commonjs/components/Inspector/BundleTab.js +3 -0
- package/dist/commonjs/components/Inspector/ConsoleTab.js +24 -1
- package/dist/commonjs/components/Inspector/CrashTab.js +30 -1
- package/dist/commonjs/components/Inspector/FeatureUnderDevNotice.d.ts +7 -0
- package/dist/commonjs/components/Inspector/FeatureUnderDevNotice.js +111 -0
- package/dist/commonjs/components/Inspector/InspectorHeader.js +225 -108
- package/dist/commonjs/components/Inspector/NpmUpdateToast.js +1 -1
- package/dist/commonjs/components/Inspector/PerformanceTab.js +3 -0
- package/dist/commonjs/components/Inspector/ReduxTab.js +24 -1
- package/dist/commonjs/components/Inspector/SettingsPanel.js +73 -88
- package/dist/commonjs/components/Inspector/StorageTab.js +37 -11
- package/dist/commonjs/components/Inspector/UpdateAvailableModal.js +2 -0
- package/dist/commonjs/components/LogCard.js +33 -3
- package/dist/commonjs/constants/version.d.ts +1 -1
- package/dist/commonjs/constants/version.js +1 -1
- package/dist/commonjs/customHooks/networkLogger.js +2 -0
- package/dist/commonjs/helpers/telemetry.js +34 -0
- package/dist/commonjs/index.js +3 -0
- package/dist/esm/components/Inspector/AnalyticsTab.js +29 -4
- package/dist/esm/components/Inspector/BundleTab.js +3 -0
- package/dist/esm/components/Inspector/ConsoleTab.js +26 -3
- package/dist/esm/components/Inspector/CrashTab.js +32 -3
- package/dist/esm/components/Inspector/FeatureUnderDevNotice.d.ts +7 -0
- package/dist/esm/components/Inspector/FeatureUnderDevNotice.js +74 -0
- package/dist/esm/components/Inspector/InspectorHeader.js +226 -109
- package/dist/esm/components/Inspector/NpmUpdateToast.js +1 -1
- package/dist/esm/components/Inspector/PerformanceTab.js +3 -0
- package/dist/esm/components/Inspector/ReduxTab.js +26 -3
- package/dist/esm/components/Inspector/SettingsPanel.js +73 -88
- package/dist/esm/components/Inspector/StorageTab.js +39 -13
- package/dist/esm/components/Inspector/UpdateAvailableModal.js +2 -0
- package/dist/esm/components/LogCard.js +34 -4
- package/dist/esm/constants/version.d.ts +1 -1
- package/dist/esm/constants/version.js +1 -1
- package/dist/esm/customHooks/networkLogger.js +2 -0
- package/dist/esm/helpers/telemetry.js +34 -0
- package/dist/esm/index.js +3 -0
- package/package.json +1 -1
- package/src/components/Inspector/AnalyticsTab.tsx +71 -43
- package/src/components/Inspector/BundleTab.tsx +3 -0
- package/src/components/Inspector/ConsoleTab.tsx +28 -1
- package/src/components/Inspector/CrashTab.tsx +45 -14
- package/src/components/Inspector/FeatureUnderDevNotice.tsx +94 -0
- package/src/components/Inspector/InspectorHeader.tsx +257 -115
- package/src/components/Inspector/NpmUpdateToast.tsx +1 -1
- package/src/components/Inspector/PerformanceTab.tsx +3 -0
- package/src/components/Inspector/ReduxTab.tsx +28 -1
- package/src/components/Inspector/SettingsPanel.tsx +93 -132
- package/src/components/Inspector/StorageTab.tsx +56 -27
- package/src/components/Inspector/UpdateAvailableModal.tsx +2 -0
- package/src/components/LogCard.tsx +41 -4
- package/src/constants/version.ts +1 -1
- package/src/customHooks/networkLogger.ts +2 -0
- package/src/helpers/telemetry.ts +36 -0
- package/src/index.tsx +5 -0
|
@@ -128,7 +128,7 @@ const NpmUpdateToast = () => {
|
|
|
128
128
|
react_native_1.Linking.openURL('https://www.npmjs.com/package/react-native-inapp-inspector').catch(() => { });
|
|
129
129
|
handleDismiss();
|
|
130
130
|
};
|
|
131
|
-
if (!showUpdateToast || !visible || !updateAvailable || !latestNpmVersion)
|
|
131
|
+
if (typeof __DEV__ === 'undefined' || !__DEV__ || !showUpdateToast || !visible || !updateAvailable || !latestNpmVersion)
|
|
132
132
|
return null;
|
|
133
133
|
const progressWidth = progressAnim.interpolate({
|
|
134
134
|
inputRange: [0, 1],
|
|
@@ -43,6 +43,7 @@ const TouchableScale_1 = __importDefault(require("../TouchableScale"));
|
|
|
43
43
|
const CopyButton_1 = __importDefault(require("../CopyButton"));
|
|
44
44
|
const HighlightText_1 = __importDefault(require("../HighlightText"));
|
|
45
45
|
const EndOfListFooter_1 = __importDefault(require("../EndOfListFooter"));
|
|
46
|
+
const FeatureUnderDevNotice_1 = __importDefault(require("./FeatureUnderDevNotice"));
|
|
46
47
|
const AppColors_1 = require("../../styles/AppColors");
|
|
47
48
|
const AppFonts_1 = require("../../styles/AppFonts");
|
|
48
49
|
const i18n_1 = require("../../i18n");
|
|
@@ -394,6 +395,8 @@ const PerformanceTab = react_1.default.memo(() => {
|
|
|
394
395
|
</TouchableScale_1.default>
|
|
395
396
|
</react_native_1.View>
|
|
396
397
|
|
|
398
|
+
<FeatureUnderDevNotice_1.default featureName="Performance & FPS Profiler"/>
|
|
399
|
+
|
|
397
400
|
|
|
398
401
|
<react_native_1.View style={perfStyles.categoryScrollWrapper}>
|
|
399
402
|
<react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} style={perfStyles.categoryScrollView} contentContainerStyle={perfStyles.categoryScroll}>
|
|
@@ -98,6 +98,7 @@ const getOriginBadge = (originType) => {
|
|
|
98
98
|
const ReduxTab = react_1.default.memo(() => {
|
|
99
99
|
const { t } = (0, i18n_1.useTranslation)();
|
|
100
100
|
const { reduxState, reduxLastActionMap, reduxSearch, setReduxSearch, setSelectedReduxSlice, } = (0, InspectorContext_1.useInspector)();
|
|
101
|
+
const listRef = (0, react_1.useRef)(null);
|
|
101
102
|
const [sortMode, setSortMode] = (0, react_1.useState)('latest');
|
|
102
103
|
const [isReduxPaused, setIsReduxPaused] = (0, react_1.useState)(!(0, reduxLogger_1.getReduxAutoRefresh)());
|
|
103
104
|
const handleTogglePause = (0, react_1.useCallback)(() => {
|
|
@@ -491,10 +492,32 @@ const ReduxTab = react_1.default.memo(() => {
|
|
|
491
492
|
</react_native_1.View>
|
|
492
493
|
|
|
493
494
|
|
|
494
|
-
<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={[
|
|
495
|
+
<react_native_1.FlatList ref={listRef} 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={[
|
|
495
496
|
reduxTabStyles.listContent,
|
|
496
497
|
filteredSlices.length === 0 && { flexGrow: 1 },
|
|
497
498
|
]} keyboardShouldPersistTaps="handled"/>
|
|
499
|
+
|
|
500
|
+
<TouchableScale_1.default onPress={() => {
|
|
501
|
+
try {
|
|
502
|
+
listRef.current?.scrollToOffset({
|
|
503
|
+
offset: 0,
|
|
504
|
+
animated: true,
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
catch {
|
|
508
|
+
try {
|
|
509
|
+
listRef.current?.scrollToIndex({
|
|
510
|
+
index: 0,
|
|
511
|
+
animated: true,
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
catch { }
|
|
515
|
+
}
|
|
516
|
+
}} hitSlop={12} style={styles_1.default.scrollTopBtn}>
|
|
517
|
+
<react_native_1.View style={{ transform: [{ rotate: '180deg' }] }}>
|
|
518
|
+
<NetworkIcons_1.ChevronIcon color={AppColors_1.AppColors.white} size={18}/>
|
|
519
|
+
</react_native_1.View>
|
|
520
|
+
</TouchableScale_1.default>
|
|
498
521
|
</react_native_1.View>);
|
|
499
522
|
});
|
|
500
523
|
const reduxTabStyles = react_native_1.StyleSheet.create({
|
|
@@ -313,11 +313,12 @@ const SettingsPanel = () => {
|
|
|
313
313
|
}}>
|
|
314
314
|
<react_native_1.ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, paddingBottom: 100, gap: 14 }} showsVerticalScrollIndicator={false}>
|
|
315
315
|
|
|
316
|
+
|
|
316
317
|
<react_native_1.View style={{
|
|
317
|
-
flexDirection: 'row',
|
|
318
318
|
backgroundColor: AppColors_1.AppColors.primaryLight,
|
|
319
|
-
borderRadius:
|
|
320
|
-
|
|
319
|
+
borderRadius: 13,
|
|
320
|
+
paddingVertical: 4,
|
|
321
|
+
paddingHorizontal: 4,
|
|
321
322
|
borderWidth: 1,
|
|
322
323
|
borderColor: AppColors_1.AppColors.grayBorderSecondary,
|
|
323
324
|
shadowColor: AppColors_1.AppColors.black,
|
|
@@ -325,95 +326,79 @@ const SettingsPanel = () => {
|
|
|
325
326
|
shadowRadius: 4,
|
|
326
327
|
shadowOffset: { width: 0, height: 2 },
|
|
327
328
|
}}>
|
|
328
|
-
<
|
|
329
|
-
(0, InspectorContext_1.animateNextLayout)();
|
|
330
|
-
setSettingsActiveSubTab('module');
|
|
331
|
-
}} style={{
|
|
332
|
-
flex: 1,
|
|
333
|
-
paddingVertical: 9,
|
|
329
|
+
<react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{
|
|
334
330
|
flexDirection: 'row',
|
|
335
331
|
alignItems: 'center',
|
|
336
|
-
justifyContent: 'center',
|
|
337
332
|
gap: 6,
|
|
338
|
-
|
|
339
|
-
backgroundColor: settingsActiveSubTab === 'module'
|
|
340
|
-
? AppColors_1.AppColors.purple
|
|
341
|
-
: 'transparent',
|
|
342
|
-
}}>
|
|
343
|
-
<NetworkIcons_1.LayersIcon color={settingsActiveSubTab === 'module'
|
|
344
|
-
? AppColors_1.AppColors.white
|
|
345
|
-
: AppColors_1.AppColors.grayText} size={13}/>
|
|
346
|
-
<react_native_1.Text style={{
|
|
347
|
-
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
348
|
-
fontSize: 12.5,
|
|
349
|
-
lineHeight: 16,
|
|
350
|
-
color: settingsActiveSubTab === 'module'
|
|
351
|
-
? AppColors_1.AppColors.white
|
|
352
|
-
: AppColors_1.AppColors.grayText,
|
|
353
|
-
}}>
|
|
354
|
-
{t('settings.modulesAndTools')}
|
|
355
|
-
</react_native_1.Text>
|
|
356
|
-
</TouchableScale_1.default>
|
|
357
|
-
|
|
358
|
-
<TouchableScale_1.default accessible={true} accessibilityRole="tab" accessibilityLabel={t('settings.uiPreferences')} accessibilityState={{ selected: settingsActiveSubTab === 'ui' }} onPress={() => {
|
|
359
|
-
(0, InspectorContext_1.animateNextLayout)();
|
|
360
|
-
setSettingsActiveSubTab('ui');
|
|
361
|
-
}} style={{
|
|
362
|
-
flex: 1,
|
|
363
|
-
paddingVertical: 9,
|
|
364
|
-
flexDirection: 'row',
|
|
365
|
-
alignItems: 'center',
|
|
366
|
-
justifyContent: 'center',
|
|
367
|
-
gap: 5,
|
|
368
|
-
borderRadius: 9,
|
|
369
|
-
backgroundColor: settingsActiveSubTab === 'ui'
|
|
370
|
-
? AppColors_1.AppColors.purple
|
|
371
|
-
: 'transparent',
|
|
372
|
-
}}>
|
|
373
|
-
<NetworkIcons_1.ScreenIcon color={settingsActiveSubTab === 'ui'
|
|
374
|
-
? AppColors_1.AppColors.white
|
|
375
|
-
: AppColors_1.AppColors.grayText} size={13}/>
|
|
376
|
-
<react_native_1.Text numberOfLines={1} style={{
|
|
377
|
-
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
378
|
-
fontSize: 12,
|
|
379
|
-
lineHeight: 16,
|
|
380
|
-
color: settingsActiveSubTab === 'ui'
|
|
381
|
-
? AppColors_1.AppColors.white
|
|
382
|
-
: AppColors_1.AppColors.grayText,
|
|
383
|
-
}}>
|
|
384
|
-
{t('settings.uiPreferences')}
|
|
385
|
-
</react_native_1.Text>
|
|
386
|
-
</TouchableScale_1.default>
|
|
387
|
-
|
|
388
|
-
<TouchableScale_1.default accessible={true} accessibilityRole="tab" accessibilityLabel={t('settings.ramLimits')} accessibilityState={{ selected: settingsActiveSubTab === 'limits' }} onPress={() => {
|
|
389
|
-
(0, InspectorContext_1.animateNextLayout)();
|
|
390
|
-
setSettingsActiveSubTab('limits');
|
|
391
|
-
}} style={{
|
|
392
|
-
flex: 1,
|
|
393
|
-
paddingVertical: 9,
|
|
394
|
-
flexDirection: 'row',
|
|
395
|
-
alignItems: 'center',
|
|
396
|
-
justifyContent: 'center',
|
|
397
|
-
gap: 5,
|
|
398
|
-
borderRadius: 9,
|
|
399
|
-
backgroundColor: settingsActiveSubTab === 'limits'
|
|
400
|
-
? AppColors_1.AppColors.purple
|
|
401
|
-
: 'transparent',
|
|
402
|
-
}}>
|
|
403
|
-
<NetworkIcons_1.BrainIcon color={settingsActiveSubTab === 'limits'
|
|
404
|
-
? AppColors_1.AppColors.white
|
|
405
|
-
: AppColors_1.AppColors.grayText} size={13}/>
|
|
406
|
-
<react_native_1.Text numberOfLines={1} style={{
|
|
407
|
-
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
408
|
-
fontSize: 12,
|
|
409
|
-
lineHeight: 16,
|
|
410
|
-
color: settingsActiveSubTab === 'limits'
|
|
411
|
-
? AppColors_1.AppColors.white
|
|
412
|
-
: AppColors_1.AppColors.grayText,
|
|
333
|
+
paddingHorizontal: 2,
|
|
413
334
|
}}>
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
335
|
+
{[
|
|
336
|
+
{
|
|
337
|
+
key: 'module',
|
|
338
|
+
label: t('settings.modulesAndTools', 'Modules & Tools'),
|
|
339
|
+
Icon: NetworkIcons_1.LayersIcon,
|
|
340
|
+
badge: `${allModules.filter(m => stagedTabVisibility?.[m.key] || m.key === 'apis').length}/${allModules.length}`,
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
key: 'ui',
|
|
344
|
+
label: t('settings.uiPreferences', 'UI Preferences'),
|
|
345
|
+
Icon: NetworkIcons_1.ScreenIcon,
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
key: 'limits',
|
|
349
|
+
label: t('settings.ramLimits', 'RAM & Limits'),
|
|
350
|
+
Icon: NetworkIcons_1.BrainIcon,
|
|
351
|
+
},
|
|
352
|
+
].map(tab => {
|
|
353
|
+
const isActive = settingsActiveSubTab === tab.key;
|
|
354
|
+
const IconComp = tab.Icon;
|
|
355
|
+
return (<TouchableScale_1.default key={tab.key} accessible={true} accessibilityRole="tab" accessibilityLabel={tab.label} accessibilityState={{ selected: isActive }} onPress={() => {
|
|
356
|
+
(0, InspectorContext_1.animateNextLayout)();
|
|
357
|
+
setSettingsActiveSubTab(tab.key);
|
|
358
|
+
}} style={{
|
|
359
|
+
paddingVertical: 8,
|
|
360
|
+
paddingHorizontal: 14,
|
|
361
|
+
flexDirection: 'row',
|
|
362
|
+
alignItems: 'center',
|
|
363
|
+
justifyContent: 'center',
|
|
364
|
+
gap: 6,
|
|
365
|
+
borderRadius: 9,
|
|
366
|
+
backgroundColor: isActive
|
|
367
|
+
? AppColors_1.AppColors.purple
|
|
368
|
+
: 'transparent',
|
|
369
|
+
}}>
|
|
370
|
+
<IconComp color={isActive ? AppColors_1.AppColors.white : AppColors_1.AppColors.grayText} size={13}/>
|
|
371
|
+
<react_native_1.Text style={{
|
|
372
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
373
|
+
fontSize: 12.5,
|
|
374
|
+
lineHeight: 16,
|
|
375
|
+
color: isActive
|
|
376
|
+
? AppColors_1.AppColors.white
|
|
377
|
+
: AppColors_1.AppColors.grayText,
|
|
378
|
+
}}>
|
|
379
|
+
{tab.label}
|
|
380
|
+
</react_native_1.Text>
|
|
381
|
+
{tab.badge && (<react_native_1.View style={{
|
|
382
|
+
backgroundColor: isActive
|
|
383
|
+
? 'rgba(255,255,255,0.25)'
|
|
384
|
+
: `${AppColors_1.AppColors.purple}18`,
|
|
385
|
+
paddingHorizontal: 5.5,
|
|
386
|
+
paddingVertical: 1,
|
|
387
|
+
borderRadius: 10,
|
|
388
|
+
}}>
|
|
389
|
+
<react_native_1.Text style={{
|
|
390
|
+
fontFamily: AppFonts_1.AppFonts.interBold,
|
|
391
|
+
fontSize: 9.5,
|
|
392
|
+
color: isActive
|
|
393
|
+
? AppColors_1.AppColors.white
|
|
394
|
+
: AppColors_1.AppColors.purple,
|
|
395
|
+
}}>
|
|
396
|
+
{tab.badge}
|
|
397
|
+
</react_native_1.Text>
|
|
398
|
+
</react_native_1.View>)}
|
|
399
|
+
</TouchableScale_1.default>);
|
|
400
|
+
})}
|
|
401
|
+
</react_native_1.ScrollView>
|
|
417
402
|
</react_native_1.View>
|
|
418
403
|
|
|
419
404
|
{settingsActiveSubTab === 'module' && (<react_native_1.View style={{ gap: 12 }}>
|
|
@@ -40,6 +40,7 @@ exports.StorageTab = void 0;
|
|
|
40
40
|
const react_1 = __importStar(require("react"));
|
|
41
41
|
const react_native_1 = require("react-native");
|
|
42
42
|
const TouchableScale_1 = __importDefault(require("../TouchableScale"));
|
|
43
|
+
const styles_1 = __importDefault(require("../../styles"));
|
|
43
44
|
const AppColors_1 = require("../../styles/AppColors");
|
|
44
45
|
const AppFonts_1 = require("../../styles/AppFonts");
|
|
45
46
|
const i18n_1 = require("../../i18n");
|
|
@@ -134,6 +135,7 @@ const StorageEntryCard = react_1.default.memo(function StorageEntryCard({ entry,
|
|
|
134
135
|
});
|
|
135
136
|
exports.StorageTab = react_1.default.memo(() => {
|
|
136
137
|
const { t } = (0, i18n_1.useTranslation)();
|
|
138
|
+
const listRef = (0, react_1.useRef)(null);
|
|
137
139
|
const [activeDriver, setActiveDriver] = (0, react_1.useState)('asyncStorage');
|
|
138
140
|
const [activeMMKVId, setActiveMMKVId] = (0, react_1.useState)('default');
|
|
139
141
|
const [entries, setEntries] = (0, react_1.useState)([]);
|
|
@@ -399,19 +401,43 @@ exports.StorageTab = react_1.default.memo(() => {
|
|
|
399
401
|
{isLoading ? (<react_native_1.View style={styles.loadingContainer}>
|
|
400
402
|
<react_native_1.ActivityIndicator size="small" color={AppColors_1.AppColors.purple}/>
|
|
401
403
|
<react_native_1.Text style={styles.loadingText}>Loading storage entries...</react_native_1.Text>
|
|
402
|
-
</react_native_1.View>) : (
|
|
403
|
-
|
|
404
|
-
<
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
{
|
|
404
|
+
</react_native_1.View>) : (<>
|
|
405
|
+
<react_native_1.FlatList ref={listRef} data={filteredEntries} keyExtractor={item => item.key} renderItem={renderItem} initialNumToRender={10} maxToRenderPerBatch={10} windowSize={5} removeClippedSubviews={react_native_1.Platform.OS === 'android'} style={styles.scrollArea} contentContainerStyle={styles.scrollContent} showsVerticalScrollIndicator={false} ListEmptyComponent={<react_native_1.View style={styles.emptyContainer}>
|
|
406
|
+
<react_native_1.View style={styles.emptyIconWrap}>
|
|
407
|
+
<NetworkIcons_1.DatabaseIcon size={28} color={AppColors_1.AppColors.grayTextWeak}/>
|
|
408
|
+
</react_native_1.View>
|
|
409
|
+
<react_native_1.Text style={styles.emptyTitle}>
|
|
410
|
+
{search ? 'No matching keys found' : `No ${activeDriver === 'asyncStorage' ? 'AsyncStorage' : 'MMKV'} Keys`}
|
|
411
|
+
</react_native_1.Text>
|
|
412
|
+
<react_native_1.Text style={styles.emptySubtitle}>
|
|
413
|
+
{search
|
|
411
414
|
? 'Try modifying your search query'
|
|
412
415
|
: `Storage is auto-detected. Tap "+ Add" above to create your first ${activeDriver === 'asyncStorage' ? 'AsyncStorage' : 'MMKV'} key!`}
|
|
413
|
-
|
|
414
|
-
|
|
416
|
+
</react_native_1.Text>
|
|
417
|
+
</react_native_1.View>} ListFooterComponent={<react_native_1.View style={{ height: 60 }}/>}/>
|
|
418
|
+
|
|
419
|
+
<TouchableScale_1.default onPress={() => {
|
|
420
|
+
try {
|
|
421
|
+
listRef.current?.scrollToOffset({
|
|
422
|
+
offset: 0,
|
|
423
|
+
animated: true,
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
catch {
|
|
427
|
+
try {
|
|
428
|
+
listRef.current?.scrollToIndex({
|
|
429
|
+
index: 0,
|
|
430
|
+
animated: true,
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
catch { }
|
|
434
|
+
}
|
|
435
|
+
}} hitSlop={12} style={styles_1.default.scrollTopBtn}>
|
|
436
|
+
<react_native_1.View style={{ transform: [{ rotate: '180deg' }] }}>
|
|
437
|
+
<NetworkIcons_1.ChevronIcon color={AppColors_1.AppColors.white} size={18}/>
|
|
438
|
+
</react_native_1.View>
|
|
439
|
+
</TouchableScale_1.default>
|
|
440
|
+
</>)}
|
|
415
441
|
|
|
416
442
|
|
|
417
443
|
<react_native_1.Modal visible={modalVisible} transparent animationType="fade" onRequestClose={() => setModalVisible(false)}>
|
|
@@ -68,6 +68,8 @@ const UpdateAvailableModal = ({ visible, latestVersion, onClose, }) => {
|
|
|
68
68
|
const fadeAnim = (0, react_1.useState)(new react_native_1.Animated.Value(0))[0];
|
|
69
69
|
const scaleAnim = (0, react_1.useState)(new react_native_1.Animated.Value(0.92))[0];
|
|
70
70
|
const installCommand = `npm install react-native-inapp-inspector@latest`;
|
|
71
|
+
if (typeof __DEV__ === 'undefined' || !__DEV__)
|
|
72
|
+
return null;
|
|
71
73
|
(0, react_1.useEffect)(() => {
|
|
72
74
|
if (visible) {
|
|
73
75
|
setCopied(false);
|
|
@@ -348,9 +348,39 @@ const LogCard = react_1.default.memo(function LogCard({ item, onPress, timelineM
|
|
|
348
348
|
|
|
349
349
|
|
|
350
350
|
<react_native_1.View style={styles_1.default.cardFooterRow}>
|
|
351
|
-
<react_native_1.View style={
|
|
352
|
-
<
|
|
353
|
-
|
|
351
|
+
<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, flexShrink: 1, minWidth: 0 }}>
|
|
352
|
+
<react_native_1.View style={styles_1.default.cardDateRow}>
|
|
353
|
+
<NetworkIcons_1.CalendarIcon color={AppColors_1.AppColors.grayTextWeak} size={10}/>
|
|
354
|
+
<react_native_1.Text style={styles_1.default.cardDateText}>{triggeredAt}</react_native_1.Text>
|
|
355
|
+
</react_native_1.View>
|
|
356
|
+
|
|
357
|
+
{item.caller && item.caller !== 'Unknown' && (<react_native_1.View style={[
|
|
358
|
+
styles_1.default.chip,
|
|
359
|
+
{
|
|
360
|
+
flexDirection: 'row',
|
|
361
|
+
alignItems: 'center',
|
|
362
|
+
gap: 3,
|
|
363
|
+
backgroundColor: `${AppColors_1.AppColors.skyBlue}14`,
|
|
364
|
+
borderColor: `${AppColors_1.AppColors.skyBlue}30`,
|
|
365
|
+
paddingHorizontal: 5,
|
|
366
|
+
paddingVertical: 1,
|
|
367
|
+
borderRadius: 4,
|
|
368
|
+
flexShrink: 1,
|
|
369
|
+
maxWidth: 160,
|
|
370
|
+
},
|
|
371
|
+
]}>
|
|
372
|
+
<NetworkIcons_1.PinIcon color={AppColors_1.AppColors.skyBlue} size={8.5}/>
|
|
373
|
+
<react_native_1.Text style={[
|
|
374
|
+
styles_1.default.chipText,
|
|
375
|
+
{
|
|
376
|
+
color: AppColors_1.AppColors.skyBlue,
|
|
377
|
+
fontSize: 8.5,
|
|
378
|
+
fontFamily: AppFonts_1.AppFonts.interMedium,
|
|
379
|
+
},
|
|
380
|
+
]} numberOfLines={1} ellipsizeMode="middle">
|
|
381
|
+
{item.caller}
|
|
382
|
+
</react_native_1.Text>
|
|
383
|
+
</react_native_1.View>)}
|
|
354
384
|
</react_native_1.View>
|
|
355
385
|
|
|
356
386
|
<react_native_1.View style={styles_1.default.cardFooterRight}>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "2.3.
|
|
1
|
+
export declare const LIB_VERSION = "2.3.9";
|
|
@@ -31,6 +31,8 @@ const IGNORED_URL_PATTERNS = [
|
|
|
31
31
|
/\/status(?:\?|$)/i,
|
|
32
32
|
/127\.0\.0\.1:(?:8081|8082|8083|19000|19001|19002|3000|8000)/i,
|
|
33
33
|
/localhost:(?:8081|8082|8083|19000|19001|19002|3000|8000)\/index\.bundle/i,
|
|
34
|
+
/google-analytics\.com\/mp\/collect/i,
|
|
35
|
+
/analytics\.google\.com/i,
|
|
34
36
|
];
|
|
35
37
|
function shouldIgnoreUrl(url) {
|
|
36
38
|
if (!url)
|
|
@@ -83,6 +83,36 @@ async function getOrCreateClientId() {
|
|
|
83
83
|
return `${Math.floor(100000000 + Math.random() * 900000000)}.${Math.floor(1000000000 + Math.random() * 9000000000)}`;
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
+
function isDeviceEmulator() {
|
|
87
|
+
try {
|
|
88
|
+
if (react_native_1.Platform.OS === 'android') {
|
|
89
|
+
const c = react_native_1.Platform.constants || {};
|
|
90
|
+
const model = String(c.Model || '').toLowerCase();
|
|
91
|
+
const brand = String(c.Brand || '').toLowerCase();
|
|
92
|
+
const fingerprint = String(c.Fingerprint || '').toLowerCase();
|
|
93
|
+
const hardware = String(c.Hardware || '').toLowerCase();
|
|
94
|
+
const manufacturer = String(c.Manufacturer || '').toLowerCase();
|
|
95
|
+
return (model.includes('emulator') ||
|
|
96
|
+
model.includes('sdk') ||
|
|
97
|
+
model.includes('google_sdk') ||
|
|
98
|
+
model.includes('vbox') ||
|
|
99
|
+
brand.includes('generic') ||
|
|
100
|
+
fingerprint.startsWith('generic') ||
|
|
101
|
+
hardware.includes('goldfish') ||
|
|
102
|
+
hardware.includes('ranchu') ||
|
|
103
|
+
manufacturer.includes('genymotion'));
|
|
104
|
+
}
|
|
105
|
+
if (react_native_1.Platform.OS === 'ios') {
|
|
106
|
+
const c = react_native_1.Platform.constants || {};
|
|
107
|
+
const model = String(c.Model || '').toLowerCase();
|
|
108
|
+
return model.includes('simulator') || Boolean(c.isSimulator);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
86
116
|
function getSystemMetadata(environment) {
|
|
87
117
|
const rnConstants = react_native_1.Platform.constants;
|
|
88
118
|
const rnVersion = rnConstants?.reactNativeVersion
|
|
@@ -91,6 +121,7 @@ function getSystemMetadata(environment) {
|
|
|
91
121
|
const isHermes = Boolean(typeof global.HermesInternal === 'object' && global.HermesInternal !== null);
|
|
92
122
|
const isFabric = Boolean(global?.nativeFabricUIManager !== undefined);
|
|
93
123
|
const isDev = Boolean(typeof __DEV__ !== 'undefined' && __DEV__);
|
|
124
|
+
const isEmulator = isDeviceEmulator();
|
|
94
125
|
return {
|
|
95
126
|
lib_version: version_1.LIB_VERSION,
|
|
96
127
|
platform: react_native_1.Platform.OS,
|
|
@@ -99,6 +130,9 @@ function getSystemMetadata(environment) {
|
|
|
99
130
|
is_hermes: isHermes,
|
|
100
131
|
is_fabric: isFabric,
|
|
101
132
|
is_dev: isDev,
|
|
133
|
+
is_emulator: isEmulator,
|
|
134
|
+
device_type: isEmulator ? 'emulator' : 'real_device',
|
|
135
|
+
app_mode: isDev ? 'local_mode' : 'bundled_application',
|
|
102
136
|
environment: environment || (isDev ? 'DEV' : 'PROD'),
|
|
103
137
|
engagement_time_msec: 1000,
|
|
104
138
|
};
|
package/dist/commonjs/index.js
CHANGED
|
@@ -403,6 +403,9 @@ const NetworkInspector = ({ enabled = true, storage, navigationRef, appIcon, env
|
|
|
403
403
|
return false;
|
|
404
404
|
}, [latestNpmVersion]);
|
|
405
405
|
(0, react_1.useEffect)(() => {
|
|
406
|
+
if (typeof __DEV__ === 'undefined' || !__DEV__) {
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
406
409
|
let cancelled = false;
|
|
407
410
|
fetch('https://registry.npmjs.org/react-native-inapp-inspector/latest')
|
|
408
411
|
.then(res => (res.ok ? res.json() : null))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useState, useMemo, useEffect } from 'react';
|
|
1
|
+
import React, { useCallback, useState, useMemo, useEffect, useRef } from 'react';
|
|
2
2
|
import { FlatList, Pressable, Text, TextInput, TouchableOpacity, View, } from 'react-native';
|
|
3
3
|
import { animateNextLayout, useInspector } from './InspectorContext';
|
|
4
4
|
import AnalyticsEventCard from '../AnalyticsEventCard';
|
|
@@ -13,7 +13,7 @@ import Svg, { Path, Rect, Line, Circle, G, Defs, LinearGradient as SvgLinearGrad
|
|
|
13
13
|
import TouchableScale from '../TouchableScale';
|
|
14
14
|
import { getCurrentUserId, getCurrentUserProperties, getDefaultEventParameters, getCollectionEnabled, } from '../../customHooks/analyticsLogger';
|
|
15
15
|
import { getEventCategory, } from '../../helpers';
|
|
16
|
-
import { LayersIcon, SearchIcon, ClearIcon, TrashIcon, HeaderPauseIcon, FilterIcon, CartIcon, GlobeIcon, BoltIcon, SparkleIcon, PinIcon, MoneyIcon, } from '../NetworkIcons';
|
|
16
|
+
import { LayersIcon, SearchIcon, ClearIcon, TrashIcon, HeaderPauseIcon, FilterIcon, CartIcon, GlobeIcon, BoltIcon, SparkleIcon, PinIcon, MoneyIcon, ChevronIcon, } from '../NetworkIcons';
|
|
17
17
|
const AnalyticsHeader = React.memo(() => {
|
|
18
18
|
const { t } = useTranslation();
|
|
19
19
|
const { analyticsEvents, filteredAnalyticsEvents, analyticsFilters, setAnalyticsFilters, analyticsHeaderExpanded, setAnalyticsHeaderExpanded, } = useInspector();
|
|
@@ -795,6 +795,7 @@ const AnalyticsHeader = React.memo(() => {
|
|
|
795
795
|
const AnalyticsTab = React.memo(() => {
|
|
796
796
|
const { t } = useTranslation();
|
|
797
797
|
const { filteredAnalyticsEvents, analyticsSearch, setAnalyticsSearch, handleDelete, selectedEvent, setSelectedEvent, newEventIds, logRouteMapRef, isAnalyticsLayoutReady, setIsAnalyticsLayoutReady, isAnalyticsPaused, setIsAnalyticsPaused, isAnalyticsFilterApplied, } = useInspector();
|
|
798
|
+
const listRef = useRef(null);
|
|
798
799
|
const [isFilterModalOpen, setIsFilterModalOpen] = useState(false);
|
|
799
800
|
const keyExtractor = useCallback((item, index) => item?.id?.toString() ?? index.toString(), []);
|
|
800
801
|
const renderItem = useCallback(({ item, index }) => {
|
|
@@ -922,7 +923,8 @@ const AnalyticsTab = React.memo(() => {
|
|
|
922
923
|
<AnalyticsFilterModal visible={isFilterModalOpen} onClose={() => setIsFilterModalOpen(false)}/>
|
|
923
924
|
|
|
924
925
|
<View style={{ flex: 1 }} onLayout={() => setIsAnalyticsLayoutReady(true)}>
|
|
925
|
-
{isAnalyticsLayoutReady ? (
|
|
926
|
+
{isAnalyticsLayoutReady ? (<>
|
|
927
|
+
<FlatList ref={listRef} data={filteredAnalyticsEvents} keyExtractor={keyExtractor} ListHeaderComponent={AnalyticsHeader} renderItem={renderItem} initialNumToRender={12} maxToRenderPerBatch={8} windowSize={5} removeClippedSubviews={true} renderToHardwareTextureAndroid={true} ListEmptyComponent={<EmptyState isSearch={analyticsSearch.length > 0} searchQuery={analyticsSearch} customTitle={analyticsSearch.length > 0
|
|
926
928
|
? 'No matching analytics events'
|
|
927
929
|
: 'No analytics events yet'} customSub={analyticsSearch.length > 0
|
|
928
930
|
? `No events matched "${analyticsSearch}"`
|
|
@@ -931,7 +933,30 @@ const AnalyticsTab = React.memo(() => {
|
|
|
931
933
|
filteredAnalyticsEvents.length === 0 && {
|
|
932
934
|
flexGrow: 1,
|
|
933
935
|
},
|
|
934
|
-
]} keyboardShouldPersistTaps="handled"/>
|
|
936
|
+
]} keyboardShouldPersistTaps="handled"/>
|
|
937
|
+
|
|
938
|
+
<TouchableScale onPress={() => {
|
|
939
|
+
try {
|
|
940
|
+
listRef.current?.scrollToOffset({
|
|
941
|
+
offset: 0,
|
|
942
|
+
animated: true,
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
catch {
|
|
946
|
+
try {
|
|
947
|
+
listRef.current?.scrollToIndex({
|
|
948
|
+
index: 0,
|
|
949
|
+
animated: true,
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
catch { }
|
|
953
|
+
}
|
|
954
|
+
}} hitSlop={12} style={styles.scrollTopBtn}>
|
|
955
|
+
<View style={{ transform: [{ rotate: '180deg' }] }}>
|
|
956
|
+
<ChevronIcon color={AppColors.white} size={18}/>
|
|
957
|
+
</View>
|
|
958
|
+
</TouchableScale>
|
|
959
|
+
</>) : null}
|
|
935
960
|
</View>
|
|
936
961
|
</>);
|
|
937
962
|
});
|
|
@@ -4,6 +4,7 @@ import { useTranslation, t } from '../../i18n';
|
|
|
4
4
|
import TouchableScale from '../TouchableScale';
|
|
5
5
|
import CopyButton from '../CopyButton';
|
|
6
6
|
import HighlightText from '../HighlightText';
|
|
7
|
+
import FeatureUnderDevNotice from './FeatureUnderDevNotice';
|
|
7
8
|
import { AppColors } from '../../styles/AppColors';
|
|
8
9
|
import { AppFonts } from '../../styles/AppFonts';
|
|
9
10
|
import { copyToClipboard } from '../../helpers';
|
|
@@ -788,6 +789,8 @@ const BundleTab = React.memo(() => {
|
|
|
788
789
|
</TouchableScale>
|
|
789
790
|
</View>
|
|
790
791
|
|
|
792
|
+
<FeatureUnderDevNotice featureName="Metro Bundle Analyzer"/>
|
|
793
|
+
|
|
791
794
|
|
|
792
795
|
|
|
793
796
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useMemo } from 'react';
|
|
1
|
+
import React, { useCallback, useMemo, useRef } from 'react';
|
|
2
2
|
import { FlatList, Pressable, ScrollView, Text, TextInput, View, } from 'react-native';
|
|
3
3
|
import { useInspector } from './InspectorContext';
|
|
4
4
|
import { useTranslation } from '../../i18n';
|
|
@@ -10,10 +10,11 @@ import EndOfListFooter from '../EndOfListFooter';
|
|
|
10
10
|
import styles from '../../styles';
|
|
11
11
|
import { AppColors } from '../../styles/AppColors';
|
|
12
12
|
import { AppFonts } from '../../styles/AppFonts';
|
|
13
|
-
import { SearchIcon, ClearIcon, SortArrowIcon, TrashIcon, LayersIcon, UserIcon, InfoCircleIcon, WarningTriangleIcon, ErrorCircleIcon, AnalyticsIcon, HeaderPauseIcon, } from '../NetworkIcons';
|
|
13
|
+
import { SearchIcon, ClearIcon, SortArrowIcon, TrashIcon, LayersIcon, UserIcon, InfoCircleIcon, WarningTriangleIcon, ErrorCircleIcon, AnalyticsIcon, HeaderPauseIcon, ChevronIcon, } from '../NetworkIcons';
|
|
14
14
|
const ConsoleTab = React.memo(() => {
|
|
15
15
|
const { t } = useTranslation();
|
|
16
16
|
const { logSearch, setLogSearch, logSortOrder, setLogSortOrder, handleDelete, logFilters, setLogFilters, logCounts, filteredConsoleLogs, visibleConsoleLogs, isConsolePaused, setIsConsolePaused, } = useInspector();
|
|
17
|
+
const listRef = useRef(null);
|
|
17
18
|
const renderItem = useCallback(({ item, index }) => (<AnimatedEntrance index={index} distance={8}>
|
|
18
19
|
<ConsoleLogCard item={item} searchStr={logSearch}/>
|
|
19
20
|
</AnimatedEntrance>), [logSearch]);
|
|
@@ -480,7 +481,7 @@ const ConsoleTab = React.memo(() => {
|
|
|
480
481
|
</ScrollView>
|
|
481
482
|
</View>
|
|
482
483
|
|
|
483
|
-
<FlatList data={filteredConsoleLogs} keyExtractor={keyExtractor} ListHeaderComponent={listHeader} renderItem={renderItem} initialNumToRender={12} maxToRenderPerBatch={8} windowSize={5} removeClippedSubviews={true} renderToHardwareTextureAndroid={true} ListEmptyComponent={<EmptyState isSearch={logSearch.length > 0 || logFilters.size > 0} searchQuery={logSearch} customTitle={logSearch.length > 0
|
|
484
|
+
<FlatList ref={listRef} data={filteredConsoleLogs} keyExtractor={keyExtractor} ListHeaderComponent={listHeader} renderItem={renderItem} initialNumToRender={12} maxToRenderPerBatch={8} windowSize={5} removeClippedSubviews={true} renderToHardwareTextureAndroid={true} ListEmptyComponent={<EmptyState isSearch={logSearch.length > 0 || logFilters.size > 0} searchQuery={logSearch} customTitle={logSearch.length > 0
|
|
484
485
|
? 'No matching console logs'
|
|
485
486
|
: 'No console logs'} onClearSearch={() => {
|
|
486
487
|
setLogSearch('');
|
|
@@ -489,6 +490,28 @@ const ConsoleTab = React.memo(() => {
|
|
|
489
490
|
styles.listContent,
|
|
490
491
|
filteredConsoleLogs.length === 0 && { flexGrow: 1 },
|
|
491
492
|
]} keyboardShouldPersistTaps="handled"/>
|
|
493
|
+
|
|
494
|
+
<TouchableScale onPress={() => {
|
|
495
|
+
try {
|
|
496
|
+
listRef.current?.scrollToOffset({
|
|
497
|
+
offset: 0,
|
|
498
|
+
animated: true,
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
catch {
|
|
502
|
+
try {
|
|
503
|
+
listRef.current?.scrollToIndex({
|
|
504
|
+
index: 0,
|
|
505
|
+
animated: true,
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
catch { }
|
|
509
|
+
}
|
|
510
|
+
}} hitSlop={12} style={styles.scrollTopBtn}>
|
|
511
|
+
<View style={{ transform: [{ rotate: '180deg' }] }}>
|
|
512
|
+
<ChevronIcon color={AppColors.white} size={18}/>
|
|
513
|
+
</View>
|
|
514
|
+
</TouchableScale>
|
|
492
515
|
</View>);
|
|
493
516
|
});
|
|
494
517
|
export default ConsoleTab;
|