import { useEffect, useState } from 'react' import { Timeline } from './components/timeline/Timeline' import { LeftSidebar } from './components/layout/LeftSidebar' import { RightSidebar } from './components/layout/RightSidebar' import { TopBar } from './components/layout/TopBar' import { ScanProgress } from './components/ScanProgress' import { ToastContainer } from './components/ToastContainer' import { KeyboardHints } from './components/KeyboardHints' import { AppFooter } from './components/AppFooter' import { PreviewView } from './components/preview/PreviewView' import { FilterBar } from './components/filter/FilterBar' import { DiscardActionBar } from './components/discard/DiscardActionBar' import { SettingsDialog } from './components/dialogs/SettingsDialog' import { usePhotoStore } from './store/photoStore' import { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts' import { useFilterUrlSync } from './hooks/useFilterUrlSync' import { usePhotosQuery } from './hooks/usePhotosQuery' function App() { const [leftSidebarOpen, setLeftSidebarOpen] = useState(true) const [rightSidebarOpen, setRightSidebarOpen] = useState(false) const [settingsOpen, setSettingsOpen] = useState(false) const selectedPhotos = usePhotoStore((state) => state.selectedPhotos) const viewMode = usePhotoStore((state) => state.viewMode) // Bidirectional sync of filter store with URL query params. useFilterUrlSync() // Subscribe to the same photos query the Timeline uses, so the keyboard // "open preview on first photo" path can read from the live cache regardless // of what filter key it's stored under. const { data: allPhotos } = usePhotosQuery() // Set up global keyboard shortcuts useKeyboardShortcuts({ onToggleLeftSidebar: () => setLeftSidebarOpen(!leftSidebarOpen), onToggleRightSidebar: () => setRightSidebarOpen(!rightSidebarOpen), getFirstPhotoId: () => allPhotos?.[0]?.id ?? null, }) // Auto-show right sidebar when photos are selected — but only in grid mode, // so leaving the preview doesn't fight the user's prior sidebar state. // Lives in an effect (not the render body) to avoid setState-during-render // and the cascading re-renders the audit caught. useEffect(() => { if (viewMode !== 'grid') return if (selectedPhotos.length > 0 && !rightSidebarOpen) { setRightSidebarOpen(true) } else if (selectedPhotos.length === 0 && rightSidebarOpen) { setRightSidebarOpen(false) } }, [viewMode, selectedPhotos.length, rightSidebarOpen]) const showRightSidebar = rightSidebarOpen && viewMode === 'grid' return (