react-native-inapp-inspector 1.1.1 → 1.1.2

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.
@@ -189,6 +189,8 @@ const NetworkInspector = ({ enabled = true, }) => {
189
189
  const [showNetworkMenu, setShowNetworkMenu] = (0, react_1.useState)(false);
190
190
  const [showUiMenu, setShowUiMenu] = (0, react_1.useState)(false);
191
191
  const [sortOrder, setSortOrder] = (0, react_1.useState)('newest');
192
+ // #7 — sort order for the Logs (console) tab
193
+ const [logSortOrder, setLogSortOrder] = (0, react_1.useState)('newest');
192
194
  const [reqExpanded, setReqExpanded] = (0, react_1.useState)(undefined);
193
195
  const [resExpanded, setResExpanded] = (0, react_1.useState)(undefined);
194
196
  const [showReqDiff, setShowReqDiff] = (0, react_1.useState)(false);
@@ -368,6 +370,66 @@ const NetworkInspector = ({ enabled = true, }) => {
368
370
  const badgeAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
369
371
  const activePulseAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(0.4)).current;
370
372
  const unreadPulseAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
373
+ // #11 — header "clear all" icon spin/scale animation
374
+ const clearAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
375
+ // #4 — draggable floating launcher (drag anywhere on screen)
376
+ const fabPan = (0, react_1.useRef)(new react_native_1.Animated.ValueXY({ x: 0, y: 0 })).current;
377
+ const fabPanRef = (0, react_1.useRef)({ x: 0, y: 0 });
378
+ (0, react_1.useEffect)(() => {
379
+ const idX = fabPan.x.addListener(v => (fabPanRef.current.x = v.value));
380
+ const idY = fabPan.y.addListener(v => (fabPanRef.current.y = v.value));
381
+ return () => {
382
+ fabPan.x.removeListener(idX);
383
+ fabPan.y.removeListener(idY);
384
+ };
385
+ }, [fabPan]);
386
+ const fabDraggedRef = (0, react_1.useRef)(false);
387
+ const fabPanResponder = (0, react_1.useRef)(react_native_1.PanResponder.create({
388
+ // Let taps fall through to the launcher; only hijack once the
389
+ // finger actually moves, so onPress still fires on a tap.
390
+ onStartShouldSetPanResponder: () => false,
391
+ onMoveShouldSetPanResponder: (_e, g) => Math.abs(g.dx) > 4 || Math.abs(g.dy) > 4,
392
+ onPanResponderGrant: () => {
393
+ fabDraggedRef.current = true;
394
+ fabPan.setOffset({
395
+ x: fabPanRef.current.x,
396
+ y: fabPanRef.current.y,
397
+ });
398
+ fabPan.setValue({ x: 0, y: 0 });
399
+ },
400
+ onPanResponderMove: react_native_1.Animated.event([null, { dx: fabPan.x, dy: fabPan.y }], {
401
+ useNativeDriver: false,
402
+ }),
403
+ onPanResponderRelease: () => {
404
+ fabPan.flattenOffset();
405
+ // small delay so the trailing tap (if any) is ignored
406
+ setTimeout(() => {
407
+ fabDraggedRef.current = false;
408
+ }, 50);
409
+ },
410
+ onPanResponderTerminate: () => {
411
+ fabPan.flattenOffset();
412
+ fabDraggedRef.current = false;
413
+ },
414
+ })).current;
415
+ // #10 — scroll-to-top affordance for the main APIs list
416
+ const apisListRef = (0, react_1.useRef)(null);
417
+ const [showScrollTop, setShowScrollTop] = (0, react_1.useState)(false);
418
+ const runClearAllWithAnimation = (0, react_1.useCallback)(() => {
419
+ react_native_1.Animated.sequence([
420
+ react_native_1.Animated.timing(clearAnim, {
421
+ toValue: 1,
422
+ duration: 320,
423
+ useNativeDriver: true,
424
+ }),
425
+ react_native_1.Animated.timing(clearAnim, {
426
+ toValue: 0,
427
+ duration: 0,
428
+ useNativeDriver: true,
429
+ }),
430
+ ]).start();
431
+ handleClearAll();
432
+ }, [clearAnim]);
371
433
  (0, react_1.useEffect)(() => {
372
434
  if (react_native_1.Platform.OS === 'android') {
373
435
  react_native_1.UIManager.setLayoutAnimationEnabledExperimental?.(true);
@@ -792,8 +854,12 @@ const NetworkInspector = ({ enabled = true, }) => {
792
854
  result = result.filter(log => log.message.toLowerCase().includes(s) ||
793
855
  (log.caller ?? '').toLowerCase().includes(s));
794
856
  }
857
+ // #7 — apply sort order (newest/oldest first)
858
+ result = [...result].sort((a, b) => logSortOrder === 'newest'
859
+ ? b.timestamp - a.timestamp
860
+ : a.timestamp - b.timestamp);
795
861
  return result;
796
- }, [visibleConsoleLogs, logFilters, logSearch]);
862
+ }, [visibleConsoleLogs, logFilters, logSearch, logSortOrder]);
797
863
  const filteredWebViewLogs = (0, react_1.useMemo)(() => {
798
864
  let result = webViewLogs;
799
865
  if (webViewSearch) {
@@ -919,6 +985,22 @@ const NetworkInspector = ({ enabled = true, }) => {
919
985
  ]);
920
986
  return;
921
987
  }
988
+ if (activeTab === 'redux') {
989
+ react_native_1.Alert.alert('Clear Redux Timeline', 'Are you sure you want to clear the dispatched action history?', [
990
+ { text: 'Cancel', style: 'cancel' },
991
+ {
992
+ text: 'Clear All',
993
+ onPress: () => {
994
+ (0, reduxLogger_1.clearActionHistory)();
995
+ setReduxActionHistory([]);
996
+ setReduxLastActionMap({});
997
+ },
998
+ style: 'destructive',
999
+ },
1000
+ ]);
1001
+ return;
1002
+ }
1003
+ // Default: APIs tab. Only clears NETWORK logs — never touches the other tabs.
922
1004
  if (selectedLogs.size > 0) {
923
1005
  setLogs(prev => prev.filter(l => !selectedLogs.has(l.id)));
924
1006
  setSelectedLogs(new Set());
@@ -926,10 +1008,22 @@ const NetworkInspector = ({ enabled = true, }) => {
926
1008
  else {
927
1009
  react_native_1.Alert.alert('Clear Logs', 'Are you sure you want to clear all network logs?', [
928
1010
  { text: 'Cancel', style: 'cancel' },
929
- { text: 'Clear All', onPress: handleClearAll, style: 'destructive' },
1011
+ { text: 'Clear All', onPress: clearNetworkOnly, style: 'destructive' },
930
1012
  ]);
931
1013
  }
932
1014
  }
1015
+ // Clears ONLY network logs + their derived selection/filter state.
1016
+ function clearNetworkOnly() {
1017
+ (0, networkLogger_1.clearNetworkLogs)();
1018
+ setLogs([]);
1019
+ setSelectedLogs(new Set());
1020
+ setSectionFilters({});
1021
+ setCollapsedSections(new Set());
1022
+ setStatusFilters(new Set());
1023
+ setMethodFilters(new Set());
1024
+ prevLogIdsRef.current = new Set();
1025
+ logRouteMapRef.current = new Map();
1026
+ }
933
1027
  const detailTitle = (0, react_1.useMemo)(() => {
934
1028
  if (!selected)
935
1029
  return '';
@@ -1263,7 +1357,7 @@ const NetworkInspector = ({ enabled = true, }) => {
1263
1357
  })}
1264
1358
  </react_native_1.View>
1265
1359
 
1266
- {/* Preferences Section */}
1360
+ {/* UI Preferences Section */}
1267
1361
  <react_native_1.View style={{ marginTop: 8 }}>
1268
1362
  <react_native_1.Text style={{
1269
1363
  fontFamily: AppFonts_1.AppFonts.interBold,
@@ -1272,7 +1366,7 @@ const NetworkInspector = ({ enabled = true, }) => {
1272
1366
  letterSpacing: 0.6,
1273
1367
  marginBottom: 8,
1274
1368
  }}>
1275
- PREFERENCES
1369
+ UI PREFERENCES
1276
1370
  </react_native_1.Text>
1277
1371
  <react_native_1.View style={{
1278
1372
  backgroundColor: AppColors_1.AppColors.primaryLight,
@@ -2528,50 +2622,6 @@ const NetworkInspector = ({ enabled = true, }) => {
2528
2622
  const lastActionMap = reduxLastActionMap;
2529
2623
  const actionHistory = reduxActionHistory;
2530
2624
  return (<react_native_1.ScrollView style={styles_1.default.detailScroll} contentContainerStyle={{ paddingBottom: 24 }}>
2531
- {/* Top Summary Card */}
2532
- <react_native_1.View style={{
2533
- backgroundColor: AppColors_1.AppColors.primaryLight,
2534
- borderRadius: 12,
2535
- borderWidth: 1,
2536
- borderColor: AppColors_1.AppColors.grayBorderSecondary,
2537
- padding: 14,
2538
- marginHorizontal: 16,
2539
- marginTop: 12,
2540
- marginBottom: 12,
2541
- flexDirection: 'row',
2542
- alignItems: 'center',
2543
- gap: 12,
2544
- }}>
2545
- <react_native_1.View style={{
2546
- width: 44,
2547
- height: 44,
2548
- borderRadius: 10,
2549
- backgroundColor: AppColors_1.AppColors.purpleShade50,
2550
- alignItems: 'center',
2551
- justifyContent: 'center',
2552
- }}>
2553
- <NetworkIcons_1.TerminalIcon color={AppColors_1.AppColors.purple} size={20}/>
2554
- </react_native_1.View>
2555
- <react_native_1.View style={{ flex: 1 }}>
2556
- <react_native_1.Text style={{
2557
- fontFamily: AppFonts_1.AppFonts.interBold,
2558
- fontSize: 13,
2559
- color: AppColors_1.AppColors.primaryBlack,
2560
- }}>
2561
- Redux Store Snapshot
2562
- </react_native_1.Text>
2563
- <react_native_1.Text style={{
2564
- fontFamily: AppFonts_1.AppFonts.interRegular,
2565
- fontSize: 11,
2566
- color: AppColors_1.AppColors.grayText,
2567
- marginTop: 2,
2568
- }}>
2569
- Total size: {(0, helpers_1.getSize)(reduxState)} • {reducerKeys.length} Reducers
2570
- </react_native_1.Text>
2571
- </react_native_1.View>
2572
- <CopyButton_1.default value={() => reduxState} label="Overall Store"/>
2573
- </react_native_1.View>
2574
-
2575
2625
  {/* Tab View Selection Segments */}
2576
2626
  <react_native_1.View style={{
2577
2627
  flexDirection: 'row',
@@ -2579,6 +2629,7 @@ const NetworkInspector = ({ enabled = true, }) => {
2579
2629
  borderRadius: 10,
2580
2630
  padding: 3,
2581
2631
  marginHorizontal: 16,
2632
+ marginTop: 12,
2582
2633
  marginBottom: 12,
2583
2634
  borderWidth: 1,
2584
2635
  borderColor: AppColors_1.AppColors.dividerColor,
@@ -2614,6 +2665,27 @@ const NetworkInspector = ({ enabled = true, }) => {
2614
2665
  }}>
2615
2666
  Action Timeline
2616
2667
  </react_native_1.Text>
2668
+ <react_native_1.View style={{
2669
+ minWidth: 18,
2670
+ paddingHorizontal: 5,
2671
+ height: 16,
2672
+ borderRadius: 8,
2673
+ alignItems: 'center',
2674
+ justifyContent: 'center',
2675
+ backgroundColor: reduxActiveSubTab === 'timeline'
2676
+ ? 'rgba(255,255,255,0.28)'
2677
+ : AppColors_1.AppColors.dividerColor,
2678
+ }}>
2679
+ <react_native_1.Text style={{
2680
+ fontFamily: AppFonts_1.AppFonts.interBold,
2681
+ fontSize: 9,
2682
+ color: reduxActiveSubTab === 'timeline'
2683
+ ? '#FFFFFF'
2684
+ : AppColors_1.AppColors.grayText,
2685
+ }}>
2686
+ {actionHistory.length}
2687
+ </react_native_1.Text>
2688
+ </react_native_1.View>
2617
2689
  </react_native_1.View>
2618
2690
  </react_native_1.TouchableOpacity>
2619
2691
  <react_native_1.TouchableOpacity onPress={() => {
@@ -2643,6 +2715,27 @@ const NetworkInspector = ({ enabled = true, }) => {
2643
2715
  }}>
2644
2716
  Store Tree
2645
2717
  </react_native_1.Text>
2718
+ <react_native_1.View style={{
2719
+ minWidth: 18,
2720
+ paddingHorizontal: 5,
2721
+ height: 16,
2722
+ borderRadius: 8,
2723
+ alignItems: 'center',
2724
+ justifyContent: 'center',
2725
+ backgroundColor: reduxActiveSubTab === 'tree'
2726
+ ? 'rgba(255,255,255,0.28)'
2727
+ : AppColors_1.AppColors.dividerColor,
2728
+ }}>
2729
+ <react_native_1.Text style={{
2730
+ fontFamily: AppFonts_1.AppFonts.interBold,
2731
+ fontSize: 9,
2732
+ color: reduxActiveSubTab === 'tree'
2733
+ ? '#FFFFFF'
2734
+ : AppColors_1.AppColors.grayText,
2735
+ }}>
2736
+ {reducerKeys.length}
2737
+ </react_native_1.Text>
2738
+ </react_native_1.View>
2646
2739
  </react_native_1.View>
2647
2740
  </react_native_1.TouchableOpacity>
2648
2741
  </react_native_1.View>
@@ -2689,21 +2782,27 @@ const NetworkInspector = ({ enabled = true, }) => {
2689
2782
  };
2690
2783
  return (<>
2691
2784
  {hasNavigationContext && (<NavigationTracker onStateChange={setNavState}/>)}
2692
- <TouchableScale_1.default style={styles_1.default.fabWrapper} onPress={() => setVisible(true)} hitSlop={10}>
2693
- <react_native_1.Animated.View style={[styles_1.default.fabPulseRing, { transform: [{ scale: pulseAnim }] }]}/>
2694
- <NetworkIcons_1.BrandCircleIcon size={62}/>
2695
- {(logs.length > 0 || analyticsEvents.length > 0) && (<react_native_1.Animated.View style={[
2785
+ <react_native_1.Animated.View style={[styles_1.default.fabWrapper, { transform: fabPan.getTranslateTransform() }]} {...fabPanResponder.panHandlers}>
2786
+ <TouchableScale_1.default style={{ alignItems: 'center', justifyContent: 'center' }} onPress={() => {
2787
+ if (fabDraggedRef.current)
2788
+ return;
2789
+ setVisible(true);
2790
+ }} hitSlop={10}>
2791
+ <react_native_1.Animated.View style={[styles_1.default.fabPulseRing, { transform: [{ scale: pulseAnim }] }]}/>
2792
+ <NetworkIcons_1.BrandCircleIcon size={62}/>
2793
+ {(logs.length > 0 || analyticsEvents.length > 0) && (<react_native_1.Animated.View style={[
2696
2794
  styles_1.default.fabBadge,
2697
2795
  hasErrors ? styles_1.default.fabBadgeError : styles_1.default.fabBadgeNormal,
2698
2796
  { transform: [{ scale: badgeAnim }] },
2699
2797
  ]}>
2700
- <react_native_1.Text style={styles_1.default.fabBadgeText}>
2701
- {logs.length + analyticsEvents.length > 99
2798
+ <react_native_1.Text style={styles_1.default.fabBadgeText}>
2799
+ {logs.length + analyticsEvents.length > 99
2702
2800
  ? '99+'
2703
2801
  : logs.length + analyticsEvents.length}
2704
- </react_native_1.Text>
2705
- </react_native_1.Animated.View>)}
2706
- </TouchableScale_1.default>
2802
+ </react_native_1.Text>
2803
+ </react_native_1.Animated.View>)}
2804
+ </TouchableScale_1.default>
2805
+ </react_native_1.Animated.View>
2707
2806
 
2708
2807
  <react_native_1.Modal visible={visible} animationType="slide" transparent>
2709
2808
  {visible && (<ErrorBoundary_1.default onClose={closeModal}>
@@ -2733,10 +2832,27 @@ const NetworkInspector = ({ enabled = true, }) => {
2733
2832
  setSelectedEvent(null);
2734
2833
  });
2735
2834
  }} hitSlop={15} style={[
2736
- styles_1.default.iconBtnMinimal,
2835
+ {
2836
+ width: 38,
2837
+ height: 38,
2838
+ borderRadius: 19,
2839
+ alignItems: 'center',
2840
+ justifyContent: 'center',
2841
+ backgroundColor: 'rgba(255,255,255,0.18)',
2842
+ borderWidth: 1,
2843
+ borderColor: 'rgba(255,255,255,0.30)',
2844
+ },
2737
2845
  selected == null &&
2738
2846
  selectedEvent == null && { display: 'none' },
2739
2847
  ]}>
2848
+ {/* Soft outer glow to fake a blurred circle */}
2849
+ <react_native_1.View style={{
2850
+ position: 'absolute',
2851
+ width: 48,
2852
+ height: 48,
2853
+ borderRadius: 24,
2854
+ backgroundColor: 'rgba(255,255,255,0.10)',
2855
+ }}/>
2740
2856
  <NetworkIcons_1.WhiteBackNavigation />
2741
2857
  </TouchableScale_1.default>
2742
2858
 
@@ -2747,8 +2863,8 @@ const NetworkInspector = ({ enabled = true, }) => {
2747
2863
  flex: 1,
2748
2864
  }}>
2749
2865
  <react_native_1.View style={{
2750
- width: 42,
2751
- height: 42,
2866
+ width: 50,
2867
+ height: 50,
2752
2868
  borderRadius: 10,
2753
2869
  backgroundColor: 'rgba(255,255,255,0.13)',
2754
2870
  borderWidth: 1.5,
@@ -2760,13 +2876,10 @@ const NetworkInspector = ({ enabled = true, }) => {
2760
2876
  shadowRadius: 4,
2761
2877
  shadowOffset: { width: 0, height: 2 },
2762
2878
  }}>
2763
- <NetworkIcons_1.BrandSquareIcon size={36}/>
2879
+ <NetworkIcons_1.BrandSquareIcon size={45}/>
2764
2880
  </react_native_1.View>
2765
2881
  <react_native_1.View style={{ gap: 3 }}>
2766
- <react_native_1.Text style={[
2767
- styles_1.default.headerTitle,
2768
- { fontSize: 17, letterSpacing: 0.2 },
2769
- ]}>
2882
+ <react_native_1.Text style={[styles_1.default.headerTitle]}>
2770
2883
  RN InApp Inspector
2771
2884
  </react_native_1.Text>
2772
2885
  <react_native_1.View style={{
@@ -2873,21 +2986,48 @@ const NetworkInspector = ({ enabled = true, }) => {
2873
2986
  </react_native_1.Text>
2874
2987
  </react_native_1.View>
2875
2988
  <react_native_1.View style={styles_1.default.headerDetailSubRow}>
2876
- <react_native_1.View style={[
2989
+ <react_native_1.View style={{
2990
+ flexDirection: 'row',
2991
+ alignItems: 'center',
2992
+ gap: 5,
2993
+ paddingHorizontal: 8,
2994
+ paddingVertical: 3,
2995
+ borderRadius: 20,
2996
+ backgroundColor: `${(0, helpers_1.getStatusColor)(selected.status)}26`,
2997
+ borderWidth: 1,
2998
+ borderColor: `${(0, helpers_1.getStatusColor)(selected.status)}55`,
2999
+ }}>
3000
+ <react_native_1.View style={[
2877
3001
  styles_1.default.headerStatusDot,
2878
3002
  {
2879
3003
  backgroundColor: (0, helpers_1.getStatusColor)(selected.status),
2880
3004
  },
2881
3005
  ]}/>
2882
- <react_native_1.Text style={styles_1.default.headerSubTitle}>
2883
- {selected.status === 0
3006
+ <react_native_1.Text style={[
3007
+ styles_1.default.headerSubTitle,
3008
+ { fontFamily: AppFonts_1.AppFonts.interBold },
3009
+ ]}>
3010
+ {selected.status === 0
2884
3011
  ? 'Failed'
2885
- : selected.status ?? 'Pending'}{' '}
2886
- •{' '}
2887
- {selected.duration != null
3012
+ : selected.status ?? 'Pending'}
3013
+ </react_native_1.Text>
3014
+ </react_native_1.View>
3015
+ <react_native_1.View style={{
3016
+ flexDirection: 'row',
3017
+ alignItems: 'center',
3018
+ gap: 4,
3019
+ paddingHorizontal: 8,
3020
+ paddingVertical: 3,
3021
+ borderRadius: 20,
3022
+ backgroundColor: 'rgba(255,255,255,0.16)',
3023
+ }}>
3024
+ <NetworkIcons_1.ClockIcon color="#FFFFFF" size={11}/>
3025
+ <react_native_1.Text style={styles_1.default.headerSubTitle}>
3026
+ {selected.duration != null
2888
3027
  ? `${selected.duration}ms`
2889
- : '-'}
2890
- </react_native_1.Text>
3028
+ : ''}
3029
+ </react_native_1.Text>
3030
+ </react_native_1.View>
2891
3031
  </react_native_1.View>
2892
3032
  </react_native_1.View>) : selectedEvent != null ? (<react_native_1.View style={styles_1.default.headerDetailCenter}>
2893
3033
  <react_native_1.View style={styles_1.default.headerDetailRow}>
@@ -2930,7 +3070,50 @@ const NetworkInspector = ({ enabled = true, }) => {
2930
3070
  </react_native_1.View>) : null}
2931
3071
  </react_native_1.View>
2932
3072
 
2933
- <react_native_1.View style={styles_1.default.headerRight}>
3073
+ <react_native_1.View style={[
3074
+ styles_1.default.headerRight,
3075
+ selected == null &&
3076
+ selectedEvent == null && {
3077
+ flexShrink: 0,
3078
+ minWidth: 116,
3079
+ },
3080
+ ]}>
3081
+ {selected == null && selectedEvent == null && (<TouchableScale_1.default onPress={() => {
3082
+ react_native_1.Alert.alert('Clear Everything', 'This clears all tabs — APIs, Logs, Analytics, WebView and Redux timeline. Continue?', [
3083
+ { text: 'Cancel', style: 'cancel' },
3084
+ {
3085
+ text: 'Clear All',
3086
+ onPress: runClearAllWithAnimation,
3087
+ style: 'destructive',
3088
+ },
3089
+ ]);
3090
+ }} hitSlop={15} style={[
3091
+ styles_1.default.closeButtonSquare,
3092
+ {
3093
+ marginRight: 8,
3094
+ backgroundColor: 'rgba(255,255,255,0.15)',
3095
+ },
3096
+ ]}>
3097
+ <react_native_1.Animated.View style={{
3098
+ transform: [
3099
+ {
3100
+ rotate: clearAnim.interpolate({
3101
+ inputRange: [0, 1],
3102
+ outputRange: ['0deg', '-25deg'],
3103
+ }),
3104
+ },
3105
+ {
3106
+ scale: clearAnim.interpolate({
3107
+ inputRange: [0, 0.5, 1],
3108
+ outputRange: [1, 1.25, 1],
3109
+ }),
3110
+ },
3111
+ ],
3112
+ }}>
3113
+ <NetworkIcons_1.TrashIcon color="#FFFFFF" size={15}/>
3114
+ </react_native_1.Animated.View>
3115
+ </TouchableScale_1.default>)}
3116
+
2934
3117
  {selected == null && selectedEvent == null && (<TouchableScale_1.default onPress={() => setSettingsPage('main')} hitSlop={15} style={[
2935
3118
  styles_1.default.closeButtonSquare,
2936
3119
  {
@@ -3265,50 +3448,53 @@ const NetworkInspector = ({ enabled = true, }) => {
3265
3448
  filteredAnalyticsEvents.length === 0 && {
3266
3449
  flexGrow: 1,
3267
3450
  },
3268
- ]} keyboardShouldPersistTaps="handled"/>)) : activeTab === 'apis' && selected == null ? (<react_native_1.FlatList data={groupedData} keyExtractor={item => item?.id?.toString()} renderItem={renderItem} initialNumToRender={10} maxToRenderPerBatch={10} windowSize={5} removeClippedSubviews={true} ListHeaderComponent={<react_native_1.View style={{ marginTop: 8 }}>
3269
- <react_native_1.View style={styles_1.default.toolbarRow}>
3270
- <react_native_1.View style={styles_1.default.searchContainer}>
3271
- <NetworkIcons_1.SearchIcon color={AppColors_1.AppColors.grayTextWeak} size={16}/>
3272
- <react_native_1.TextInput placeholder="Search endpoints..." placeholderTextColor={AppColors_1.AppColors.grayTextWeak} value={search} onChangeText={setSearch} style={styles_1.default.searchInput} autoCorrect={false} autoCapitalize="none"/>
3273
- {search.length > 0 && (<react_native_1.Pressable onPress={() => setSearch('')} hitSlop={10} style={styles_1.default.clearBtn}>
3274
- <NetworkIcons_1.ClearIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
3275
- </react_native_1.Pressable>)}
3276
- </react_native_1.View>
3451
+ ]} keyboardShouldPersistTaps="handled"/>)) : activeTab === 'apis' && selected == null ? (<react_native_1.View style={{ flex: 1 }}>
3452
+ <react_native_1.FlatList ref={apisListRef} onScroll={e => setShowScrollTop(e.nativeEvent.contentOffset.y > 320)} scrollEventThrottle={16} data={groupedData} keyExtractor={item => item?.id?.toString()} renderItem={renderItem} initialNumToRender={10} maxToRenderPerBatch={10} windowSize={5} removeClippedSubviews={true} ListHeaderComponent={<react_native_1.View style={{ marginTop: 8 }}>
3453
+ <react_native_1.View style={styles_1.default.toolbarRow}>
3454
+ <react_native_1.View style={styles_1.default.searchContainer}>
3455
+ <NetworkIcons_1.SearchIcon color={AppColors_1.AppColors.grayTextWeak} size={16}/>
3456
+ <react_native_1.TextInput placeholder="Search endpoints..." placeholderTextColor={AppColors_1.AppColors.grayTextWeak} value={search} onChangeText={setSearch} style={styles_1.default.searchInput} autoCorrect={false} autoCapitalize="none"/>
3457
+ {search.length > 0 && (<react_native_1.Pressable onPress={() => setSearch('')} hitSlop={10} style={styles_1.default.clearBtn}>
3458
+ <NetworkIcons_1.ClearIcon color={AppColors_1.AppColors.grayTextWeak} size={14}/>
3459
+ </react_native_1.Pressable>)}
3460
+ </react_native_1.View>
3277
3461
 
3278
- <react_native_1.View style={styles_1.default.toolbarRight}>
3279
- <TouchableScale_1.default style={styles_1.default.toolbarBtn} onPress={handleDelete} hitSlop={10}>
3280
- <NetworkIcons_1.TrashIcon color={AppColors_1.AppColors.grayTextStrong} size={18}/>
3281
- {selectedLogs.size > 0 && (<react_native_1.View style={styles_1.default.trashBadge}>
3282
- <react_native_1.Text style={styles_1.default.trashBadgeText}>
3283
- {selectedLogs.size}
3284
- </react_native_1.Text>
3285
- </react_native_1.View>)}
3286
- </TouchableScale_1.default>
3462
+ <react_native_1.View style={styles_1.default.toolbarRight}>
3463
+ <TouchableScale_1.default style={styles_1.default.toolbarBtn} onPress={handleDelete} hitSlop={10}>
3464
+ <NetworkIcons_1.TrashIcon color={AppColors_1.AppColors.grayTextStrong} size={18}/>
3465
+ {selectedLogs.size > 0 && (<react_native_1.View style={styles_1.default.trashBadge}>
3466
+ <react_native_1.Text style={styles_1.default.trashBadgeText}>
3467
+ {selectedLogs.size}
3468
+ </react_native_1.Text>
3469
+ </react_native_1.View>)}
3470
+ </TouchableScale_1.default>
3287
3471
 
3288
- <TouchableScale_1.default style={styles_1.default.toolbarBtn} onPress={() => setSortOrder(o => o === 'newest' ? 'oldest' : 'newest')} hitSlop={10}>
3289
- <NetworkIcons_1.SortArrowIcon direction={sortOrder === 'newest' ? 'down' : 'up'} color={AppColors_1.AppColors.grayTextStrong} size={18}/>
3290
- </TouchableScale_1.default>
3472
+ <TouchableScale_1.default style={styles_1.default.toolbarBtn} onPress={() => setSortOrder(o => o === 'newest' ? 'oldest' : 'newest')} hitSlop={10}>
3473
+ <NetworkIcons_1.SortArrowIcon direction={sortOrder === 'newest' ? 'down' : 'up'} color={AppColors_1.AppColors.grayTextStrong} size={18}/>
3474
+ </TouchableScale_1.default>
3291
3475
 
3292
- <TouchableScale_1.default style={[
3476
+ <TouchableScale_1.default style={[
3293
3477
  styles_1.default.toolbarBtn,
3294
3478
  filtersAccordion.isOpen &&
3295
3479
  styles_1.default.toolbarBtnActive,
3296
3480
  ]} onPress={filtersAccordion.toggleOpen} hitSlop={10}>
3297
- <NetworkIcons_1.FilterIcon color={filtersAccordion.isOpen
3481
+ <NetworkIcons_1.FilterIcon color={filtersAccordion.isOpen
3298
3482
  ? AppColors_1.AppColors.purple
3299
3483
  : AppColors_1.AppColors.grayTextStrong} size={18}/>
3300
- </TouchableScale_1.default>
3484
+ </TouchableScale_1.default>
3485
+ </react_native_1.View>
3301
3486
  </react_native_1.View>
3302
- </react_native_1.View>
3303
3487
 
3304
- <react_native_1.Animated.View style={[
3488
+ <react_native_1.Animated.View style={[
3305
3489
  filtersAccordion.bodyStyle,
3306
3490
  { overflow: 'hidden' },
3307
3491
  ]}>
3308
- <react_native_1.View style={styles_1.default.filtersContainer}>
3309
- <react_native_1.Text style={styles_1.default.filtersHeading}>STATUS</react_native_1.Text>
3310
- <react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles_1.default.statusRowContent}>
3311
- {constants_1.STATUS_FILTERS.map(filter => {
3492
+ <react_native_1.View style={styles_1.default.filtersContainer}>
3493
+ <react_native_1.Text style={styles_1.default.filtersHeading}>
3494
+ STATUS
3495
+ </react_native_1.Text>
3496
+ <react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles_1.default.statusRowContent}>
3497
+ {constants_1.STATUS_FILTERS.map(filter => {
3312
3498
  const isAll = filter === 'ALL';
3313
3499
  const active = isAll
3314
3500
  ? statusFilters.size === 0
@@ -3327,38 +3513,38 @@ const NetworkInspector = ({ enabled = true, }) => {
3327
3513
  });
3328
3514
  }
3329
3515
  }} hitSlop={10}>
3330
- {active ? (<react_native_1.View style={[
3516
+ {active ? (<react_native_1.View style={[
3331
3517
  styles_1.default.statusFilterChip,
3332
3518
  styles_1.default.statusFilterActive,
3333
3519
  { overflow: 'hidden' },
3334
3520
  ]}>
3335
- <react_native_linear_gradient_1.default colors={[
3521
+ <react_native_linear_gradient_1.default colors={[
3336
3522
  AppColors_1.AppColors.purpleShade50,
3337
3523
  '#EAE5FF',
3338
3524
  ]} style={react_native_1.StyleSheet.absoluteFill} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }}/>
3339
- <react_native_1.Text style={[
3525
+ <react_native_1.Text style={[
3340
3526
  styles_1.default.statusFilterText,
3341
3527
  { color: AppColors_1.AppColors.purple },
3342
3528
  ]}>
3343
- {filter}
3344
- </react_native_1.Text>
3345
- </react_native_1.View>) : (<react_native_1.View style={styles_1.default.statusFilterChip}>
3346
- <react_native_1.Text style={styles_1.default.statusFilterText}>
3347
- {filter}
3348
- </react_native_1.Text>
3349
- </react_native_1.View>)}
3350
- </TouchableScale_1.default>);
3529
+ {filter}
3530
+ </react_native_1.Text>
3531
+ </react_native_1.View>) : (<react_native_1.View style={styles_1.default.statusFilterChip}>
3532
+ <react_native_1.Text style={styles_1.default.statusFilterText}>
3533
+ {filter}
3534
+ </react_native_1.Text>
3535
+ </react_native_1.View>)}
3536
+ </TouchableScale_1.default>);
3351
3537
  })}
3352
- </react_native_1.ScrollView>
3538
+ </react_native_1.ScrollView>
3353
3539
 
3354
- <react_native_1.Text style={[
3540
+ <react_native_1.Text style={[
3355
3541
  styles_1.default.filtersHeading,
3356
3542
  { marginTop: 16 },
3357
3543
  ]}>
3358
- METHOD
3359
- </react_native_1.Text>
3360
- <react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles_1.default.statusRowContent}>
3361
- {availableMethods.map(filter => {
3544
+ METHOD
3545
+ </react_native_1.Text>
3546
+ <react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles_1.default.statusRowContent}>
3547
+ {availableMethods.map(filter => {
3362
3548
  const isAll = filter === 'ALL';
3363
3549
  const active = isAll
3364
3550
  ? methodFilters.size === 0
@@ -3377,43 +3563,55 @@ const NetworkInspector = ({ enabled = true, }) => {
3377
3563
  });
3378
3564
  }
3379
3565
  }} hitSlop={10}>
3380
- {active ? (<react_native_1.View style={[
3566
+ {active ? (<react_native_1.View style={[
3381
3567
  styles_1.default.statusFilterChip,
3382
3568
  styles_1.default.statusFilterActive,
3383
3569
  { overflow: 'hidden' },
3384
3570
  ]}>
3385
- <react_native_linear_gradient_1.default colors={[
3571
+ <react_native_linear_gradient_1.default colors={[
3386
3572
  AppColors_1.AppColors.purpleShade50,
3387
3573
  '#EAE5FF',
3388
3574
  ]} style={react_native_1.StyleSheet.absoluteFill} start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }}/>
3389
- <react_native_1.Text style={[
3575
+ <react_native_1.Text style={[
3390
3576
  styles_1.default.statusFilterText,
3391
3577
  { color: AppColors_1.AppColors.purple },
3392
3578
  ]}>
3393
- {filter}
3394
- </react_native_1.Text>
3395
- </react_native_1.View>) : (<react_native_1.View style={styles_1.default.statusFilterChip}>
3396
- <react_native_1.Text style={styles_1.default.statusFilterText}>
3397
- {filter}
3398
- </react_native_1.Text>
3399
- </react_native_1.View>)}
3400
- </TouchableScale_1.default>);
3579
+ {filter}
3580
+ </react_native_1.Text>
3581
+ </react_native_1.View>) : (<react_native_1.View style={styles_1.default.statusFilterChip}>
3582
+ <react_native_1.Text style={styles_1.default.statusFilterText}>
3583
+ {filter}
3584
+ </react_native_1.Text>
3585
+ </react_native_1.View>)}
3586
+ </TouchableScale_1.default>);
3401
3587
  })}
3402
- </react_native_1.ScrollView>
3403
- </react_native_1.View>
3404
- </react_native_1.Animated.View>
3588
+ </react_native_1.ScrollView>
3589
+ </react_native_1.View>
3590
+ </react_native_1.Animated.View>
3405
3591
 
3406
- {(search ||
3592
+ {(search ||
3407
3593
  statusFilters.size > 0 ||
3408
3594
  methodFilters.size > 0) && (<react_native_1.Text style={styles_1.default.resultCount}>
3409
- {filteredLogs.length === logs.length
3595
+ {filteredLogs.length === logs.length
3410
3596
  ? `${logs.length} requests`
3411
3597
  : `${filteredLogs.length} of ${logs.length} filtered requests`}
3412
- </react_native_1.Text>)}
3413
- </react_native_1.View>} ListEmptyComponent={<EmptyState_1.default isSearch={search.length > 0 || statusFilters.size > 0}/>} contentContainerStyle={[
3598
+ </react_native_1.Text>)}
3599
+ </react_native_1.View>} ListEmptyComponent={<EmptyState_1.default isSearch={search.length > 0 || statusFilters.size > 0}/>} contentContainerStyle={[
3414
3600
  styles_1.default.listContent,
3415
3601
  filteredLogs.length === 0 && { flexGrow: 1 },
3416
- ]} keyboardShouldPersistTaps="handled"/>) : activeTab === 'logs' ? (<react_native_1.View style={{ flex: 1 }}>
3602
+ ]} keyboardShouldPersistTaps="handled"/>
3603
+ {showScrollTop && (<TouchableScale_1.default onPress={() => {
3604
+ apisListRef.current?.scrollToOffset({
3605
+ offset: 0,
3606
+ animated: true,
3607
+ });
3608
+ setShowScrollTop(false);
3609
+ }} hitSlop={10} style={styles_1.default.scrollTopBtn}>
3610
+ <react_native_1.View style={{ transform: [{ rotate: '180deg' }] }}>
3611
+ <NetworkIcons_1.ChevronIcon color="#FFFFFF" size={18}/>
3612
+ </react_native_1.View>
3613
+ </TouchableScale_1.default>)}
3614
+ </react_native_1.View>) : activeTab === 'logs' ? (<react_native_1.View style={{ flex: 1 }}>
3417
3615
  <react_native_1.View style={{
3418
3616
  backgroundColor: '#FFFFFF',
3419
3617
  borderBottomWidth: 1,
@@ -3433,6 +3631,9 @@ const NetworkInspector = ({ enabled = true, }) => {
3433
3631
  </react_native_1.View>
3434
3632
 
3435
3633
  <react_native_1.View style={styles_1.default.toolbarRight}>
3634
+ <TouchableScale_1.default style={styles_1.default.toolbarBtn} onPress={() => setLogSortOrder(o => o === 'newest' ? 'oldest' : 'newest')} hitSlop={10}>
3635
+ <NetworkIcons_1.SortArrowIcon color={AppColors_1.AppColors.grayTextStrong} size={18} direction={logSortOrder === 'newest' ? 'down' : 'up'}/>
3636
+ </TouchableScale_1.default>
3436
3637
  <TouchableScale_1.default style={styles_1.default.toolbarBtn} onPress={handleDelete} hitSlop={10}>
3437
3638
  <NetworkIcons_1.TrashIcon color={AppColors_1.AppColors.grayTextStrong} size={18}/>
3438
3639
  </TouchableScale_1.default>
@@ -4672,7 +4873,7 @@ const NetworkInspector = ({ enabled = true, }) => {
4672
4873
  if (!resExpanded && !showResDiff)
4673
4874
  setResExpanded(true);
4674
4875
  }}/>
4675
- {showResDiff ? (<DiffViewer_1.default oldData={prevResponseData} newData={selected.response} forceOpen={resExpanded}/>) : (<JsonViewer_1.default data={selected.response} search={detailSearch} forceOpen={resExpanded}/>)}
4876
+ {showResDiff ? (<DiffViewer_1.default oldData={prevResponseData} newData={selected.response} forceOpen={resExpanded}/>) : (<JsonViewer_1.default data={selected.response} search={detailSearch} forceOpen={resExpanded} wrap/>)}
4676
4877
  </react_native_1.View>
4677
4878
  </>)}
4678
4879
  </react_native_1.ScrollView>