From ab3c55dd9652cbe4a545aa0da76a8895af7ebee3 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 12 May 2026 09:53:32 +0200 Subject: [PATCH] feat(topbar): drop search box to reclaim filter-bar space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The search box on the right edge of the filter bar wasn't pulling its weight — kills it entirely along with the supporting plumbing: - FilterBar: remove input + Search icon import + local/debounced state - filterStore: drop `q`, `setQ`, plus all references in INITIAL_FILTERS, filtersToParams, hasActiveFilters, snapshotFilters - usePhotosQuery: stop passing q through filtersToParams - useFilterUrlSync: drop the `q` URL param read/write - PhotoThumbnail + PreviewView: remove the search-match banner/chip and findSearchMatch helper imports - Timeline + MemoriesView: stop subscribing to / forwarding the prop - useKeyboardShortcuts: drop the `/` and Cmd+F focus hotkeys - KeyboardHints: drop the `/` hint and the now-stale `?` collision note - delete hooks/useSearchQuery.ts (no callers) and lib/searchMatch.ts Backend /photos/search endpoint left untouched — no UI reaches it now. Co-Authored-By: Claude Opus 4.7 (1M context) --- frontend/src/components/KeyboardHints.tsx | 4 +- frontend/src/components/filter/FilterBar.tsx | 59 ------ .../src/components/memories/MemoriesView.tsx | 3 - .../src/components/preview/PreviewView.tsx | 39 ---- .../components/timeline/PhotoThumbnail.tsx | 52 ------ frontend/src/components/timeline/Timeline.tsx | 5 - frontend/src/hooks/useFilterUrlSync.ts | 4 - frontend/src/hooks/useKeyboardShortcuts.ts | 9 - frontend/src/hooks/usePhotosQuery.ts | 1 - frontend/src/hooks/useSearchQuery.ts | 37 ---- frontend/src/lib/searchMatch.ts | 175 ------------------ frontend/src/store/filterStore.ts | 9 +- 12 files changed, 2 insertions(+), 395 deletions(-) delete mode 100644 frontend/src/hooks/useSearchQuery.ts delete mode 100644 frontend/src/lib/searchMatch.ts diff --git a/frontend/src/components/KeyboardHints.tsx b/frontend/src/components/KeyboardHints.tsx index 16f8b49..4a80720 100644 --- a/frontend/src/components/KeyboardHints.tsx +++ b/frontend/src/components/KeyboardHints.tsx @@ -65,7 +65,6 @@ function getHints(opts: { { key: 'Space', action: 'Preview' }, { key: 'Tab', action: 'Library panel' }, { key: 'I', action: 'Info panel' }, - { key: '/', action: 'Search' }, ] } @@ -81,8 +80,7 @@ export function KeyboardHints() { localStorage.setItem(STORAGE_KEY, collapsed ? '1' : '0') }, [collapsed]) - // `H` toggles the panel. `?` (shift+/) collides with the global `/` - // search shortcut, so we use a plain letter instead. + // `H` toggles the panel. useHotkeys('h', () => setCollapsed((c) => !c), { preventDefault: true }) const hints = getHints({ selectedCount, currentSection, viewMode }) diff --git a/frontend/src/components/filter/FilterBar.tsx b/frontend/src/components/filter/FilterBar.tsx index 9bfacf8..06d9866 100644 --- a/frontend/src/components/filter/FilterBar.tsx +++ b/frontend/src/components/filter/FilterBar.tsx @@ -1,10 +1,8 @@ -import { useEffect, useRef, useState } from 'react' import { Star, X, ArrowDown, ArrowUp, - Search, PanelLeftOpen, PanelLeftClose, PanelRightOpen, @@ -26,7 +24,6 @@ import { import { useTagsQuery } from '../../hooks/useTagsQuery' import { FilterPill } from './FilterPill' import { COLOR_LABEL_OPTIONS } from '../../constants/colorLabels' -import { Input } from '@/components/ui/input' import { Button } from '@/components/ui/button' import { Select, @@ -37,8 +34,6 @@ import { } from '@/components/ui/select' import { MultiSelect } from '@/components/ui/multi-select' -const SEARCH_DEBOUNCE_MS = 300 - const MEDIA_TYPES: { value: MediaType; label: string }[] = [ { value: 'photo', label: 'Photo' }, { value: 'video', label: 'Video' }, @@ -112,26 +107,6 @@ export function FilterBar({ const { data: allTags = [] } = useTagsQuery() - // Search box. Local state mirrors the store so typing stays responsive - // while we debounce store writes (each store write triggers a re-fetch). - const storeQ = useFilterStore((s) => s.q) - const setStoreQ = useFilterStore((s) => s.setQ) - const [searchQuery, setSearchQuery] = useState(storeQ) - useEffect(() => { - setSearchQuery(storeQ) - }, [storeQ]) - const debounceRef = useRef(null) - useEffect(() => { - if (searchQuery === storeQ) return - if (debounceRef.current) window.clearTimeout(debounceRef.current) - debounceRef.current = window.setTimeout(() => { - setStoreQ(searchQuery) - }, SEARCH_DEBOUNCE_MS) - return () => { - if (debounceRef.current) window.clearTimeout(debounceRef.current) - } - }, [searchQuery, storeQ, setStoreQ]) - // Pre-compute pill values + active flags so the JSX stays terse. const typeActive = mediaTypes.length > 0 const typeValue = typeActive @@ -527,40 +502,6 @@ export function FilterBar({ )} - {/* Search — pinned to the right edge of the bar. Same id as before - * so the global "/" focus shortcut still finds it. */} -
- - setSearchQuery(e.target.value)} - onKeyDown={(e) => { - if (e.key === 'Escape') { - setSearchQuery('') - setStoreQ('') - e.currentTarget.blur() - } - }} - placeholder="Search photos…" - className="h-7 w-full rounded-full bg-surface-2 pl-8 pr-7 text-xs" - /> - {searchQuery && ( - - )} -
- {/* Right sidebar toggle — pinned to the far-right edge. */}