import { FC, useRef, useState } from "react"; import { View, StyleSheet, ScrollView, GestureResponderEvent, } from "react-native"; import QueryStatus from "./QueryStatus"; import useQueryStatusCounts from "../../hooks/useQueryStatusCounts"; interface QueryStatusCountProps { activeFilter?: string | null; onFilterChange?: (filter: string | null) => void; } /** * Horizontal status filter bar for queries with scroll-aware tap handling to prevent misfires. */ const QueryStatusCount: FC = ({ activeFilter, onFilterChange, }) => { const { fresh, stale, fetching, paused, inactive } = useQueryStatusCounts(); // Scroll state management like ChipTabs const [isScrolling, setIsScrolling] = useState(false); const touchStartX = useRef(0); const touchStartY = useRef(0); const handleFilterClick = (filter: string, event?: GestureResponderEvent) => { if (event) { // Calculate distance moved during touch (like ChipTabs) const dx = Math.abs(event.nativeEvent.pageX - touchStartX.current); const dy = Math.abs(event.nativeEvent.pageY - touchStartY.current); // If touch moved more than 5px in any direction, it's a swipe, not a tap if (dx > 5 || dy > 5 || isScrolling) { return; // Don't trigger filter change } } if (onFilterChange) { // Toggle filter: if already active, clear it; otherwise set it onFilterChange(activeFilter === filter ? null : filter); } }; const handleTouchStart = (event: GestureResponderEvent) => { touchStartX.current = event.nativeEvent.pageX; touchStartY.current = event.nativeEvent.pageY; }; return ( setIsScrolling(true)} onScrollEndDrag={() => setTimeout(() => setIsScrolling(false), 300)} onMomentumScrollBegin={() => setIsScrolling(true)} onMomentumScrollEnd={() => setTimeout(() => setIsScrolling(false), 300)} > handleFilterClick("fresh", event)} onTouchStart={handleTouchStart} showLabel={true} // Always show labels now /> handleFilterClick("fetching", event)} onTouchStart={handleTouchStart} showLabel={true} // Always show labels now /> handleFilterClick("paused", event)} onTouchStart={handleTouchStart} showLabel={true} // Always show labels now /> handleFilterClick("stale", event)} onTouchStart={handleTouchStart} showLabel={true} // Always show labels now /> handleFilterClick("inactive", event)} onTouchStart={handleTouchStart} showLabel={true} // Always show labels now /> ); }; const styles = StyleSheet.create({ queryStatusContainer: { // Container for ScrollView - take full width flex: 1, minWidth: 0, }, scrollView: { // ScrollView itself styles flex: 1, }, scrollContent: { // ScrollView content styles flexDirection: "row", alignItems: "center", gap: 8, // Spacing between chips paddingHorizontal: 4, // Small padding on ends paddingVertical: 4, flexGrow: 1, // Allow content to grow to fill available space }, }); export default QueryStatusCount;