From 0056a83a69cde9a1aa1ca6e1782ce92b5f35d8d5 Mon Sep 17 00:00:00 2001 From: m Date: Fri, 28 Aug 2026 23:41:42 +0200 Subject: [PATCH] search bar filters --- mobile/app/index.tsx | 39 +++++++++++++- mobile/components/SearchBar.tsx | 94 ++------------------------------- 2 files changed, 43 insertions(+), 90 deletions(-) diff --git a/mobile/app/index.tsx b/mobile/app/index.tsx index 7be89f5..3765b4b 100644 --- a/mobile/app/index.tsx +++ b/mobile/app/index.tsx @@ -86,6 +86,9 @@ export function HomeScreen() { const [searchQuery, setSearchQuery] = useState(''); const debouncedSearch = useDebounce(searchQuery, 250); const [filters, setFilters] = useState({ name: true, ocrText: true }); + const toggleFilter = useCallback((key: keyof SearchFilters) => { + setFilters((prev) => ({ ...prev, [key]: !prev[key] })); + }, []); const [sort, setSort] = useState({ key: 'date', direction: 'desc' }); const listRef = useRef>(null); const [keyboardOpen, setKeyboardOpen] = useState(false); @@ -99,6 +102,7 @@ export function HomeScreen() { const { data: foldersData } = useFolders(); const [moveModalVisible, setMoveModalVisible] = useState(false); const [settingsModalVisible, setSettingsModalVisible] = useState(false); + const [filterModalVisible, setFilterModalVisible] = useState(false); const [uploadModalVisible, setUploadModalVisible] = useState(false); const [globalSyncMode, setGlobalSyncMode] = useState(() => safDirectory.getGlobalSyncMode()); const [globalSyncCellular, setGlobalSyncCellular] = useState(() => safDirectory.getGlobalSyncCellular()); @@ -524,7 +528,7 @@ export function HomeScreen() { filters={filters} onFiltersChange={setFilters} sort={sort} - onSortChange={setSort} + onSettingsPress={() => setFilterModalVisible(true)} bottomPadding={keyboardOpen ? insets.bottom+8 : 0} /> )} @@ -614,6 +618,34 @@ export function HomeScreen() { + setFilterModalVisible(false)}> + setFilterModalVisible(false)}> + {}}> + Rechercher dans + toggleFilter('name')} + > + + Nom + + {filters.name && } + + + toggleFilter('ocrText')} + > + + Texte OCR + + {filters.ocrText && } + + + + + + setUploadModalVisible(false)} @@ -806,6 +838,11 @@ const styles = StyleSheet.create({ folderOptionText: { fontSize: 16, color: '#333', + flex: 1, + }, + filterCheck: { + width: 24, + alignItems: 'flex-end', }, modalOverlay: { flex: 1, diff --git a/mobile/components/SearchBar.tsx b/mobile/components/SearchBar.tsx index aca41ce..fb9f0c5 100644 --- a/mobile/components/SearchBar.tsx +++ b/mobile/components/SearchBar.tsx @@ -1,5 +1,5 @@ -import React, { useRef, useEffect } from 'react'; -import { View, TextInput, TouchableOpacity, Text, StyleSheet, Animated } from 'react-native'; +import React from 'react'; +import { View, TextInput, TouchableOpacity, Text, StyleSheet } from 'react-native'; import { MaterialIcons } from '@expo/vector-icons'; import type { ComponentProps } from 'react'; @@ -24,38 +24,12 @@ interface SearchBarProps { onClear: () => void; filters: SearchFilters; onFiltersChange: (f: SearchFilters) => void; + onSettingsPress: () => void; sort: SortState; - onSortChange: (s: SortState) => void; bottomPadding?: number; } -const FILTER_OPTIONS: { key: keyof SearchFilters; label: string; icon: IconName }[] = [ - { key: 'name', label: 'Nom', icon: 'drive-file-rename-outline' }, - { key: 'ocrText', label: 'Texte OCR', icon: 'document-scanner' }, -]; - -export function SearchBar({ query, onQueryChange, onClear, filters, onFiltersChange, sort, bottomPadding = 0 }: SearchBarProps) { - const animatedHeight = useRef(new Animated.Value(0)).current; - const [panelOpen, setPanelOpen] = React.useState(false); - - useEffect(() => { - Animated.spring(animatedHeight, { - toValue: panelOpen ? 1 : 0, - useNativeDriver: false, - tension: 60, - friction: 8, - }).start(); - }, [panelOpen]); - - const panelMaxHeight = animatedHeight.interpolate({ - inputRange: [0, 1], - outputRange: [0, 150], - }); - - const toggleFilter = (key: keyof SearchFilters) => { - onFiltersChange({ ...filters, [key]: !filters[key] }); - }; - +export function SearchBar({ query, onQueryChange, onClear, filters, onSettingsPress, sort, bottomPadding = 0 }: SearchBarProps) { const hasActiveFilter = filters.name || filters.ocrText || sort.key !== 'date'; return ( @@ -81,7 +55,7 @@ export function SearchBar({ query, onQueryChange, onClear, filters, onFiltersCha setPanelOpen(!panelOpen)} + onPress={onSettingsPress} > - - - Rechercher dans - {FILTER_OPTIONS.map((opt) => ( - toggleFilter(opt.key)} - > - - - {opt.label} - - - ))} - ); } @@ -160,42 +114,4 @@ const styles = StyleSheet.create({ iconBtnActive: { backgroundColor: '#1976D2', }, - filterPanel: { - flexDirection: 'row', - flexWrap: 'wrap', - alignItems: 'center', - paddingHorizontal: 12, - paddingBottom: 10, - gap: 8, - overflow: 'hidden', - }, - sectionLabel: { - width: '100%', - fontSize: 12, - fontWeight: '700', - color: '#666', - marginTop: 4, - textTransform: 'uppercase', - letterSpacing: 0.5, - }, - filterChip: { - flexDirection: 'row', - alignItems: 'center', - paddingHorizontal: 12, - paddingVertical: 6, - borderRadius: 16, - borderWidth: 1, - borderColor: '#1976D2', - gap: 4, - }, - filterChipActive: { - backgroundColor: '#1976D2', - }, - filterChipText: { - fontSize: 12, - color: '#1976D2', - }, - filterChipTextActive: { - color: '#fff', - }, });