diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index e51c5da..6ef9f55 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from 'react' +import { useState } from 'react' import { Timeline } from './components/timeline/Timeline' import { LeftSidebar } from './components/layout/LeftSidebar' import { RightSidebar } from './components/layout/RightSidebar' @@ -18,9 +18,8 @@ import { usePhotosQuery } from './hooks/usePhotosQuery' function App() { const [leftSidebarOpen, setLeftSidebarOpen] = useState(true) - const [rightSidebarOpen, setRightSidebarOpen] = useState(false) + const [rightSidebarOpen, setRightSidebarOpen] = useState(true) 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. @@ -38,24 +37,19 @@ function App() { 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]) - + // Right sidebar stays open by default and shows whatever's selected + // (or an empty state if nothing is). User can still toggle it manually. const showRightSidebar = rightSidebarOpen && viewMode === 'grid' return (
Select photos to view details
+Select photos to view details
+
diff --git a/frontend/src/components/layout/TopBar.tsx b/frontend/src/components/layout/TopBar.tsx
index eeaf1c5..82e1b62 100644
--- a/frontend/src/components/layout/TopBar.tsx
+++ b/frontend/src/components/layout/TopBar.tsx
@@ -1,23 +1,59 @@
-import { Settings } from 'lucide-react'
+import { Settings, PanelLeftOpen, PanelRightOpen } from 'lucide-react'
import muliLogo from '../../assets/muli-logo.png'
interface TopBarProps {
onOpenSettings: () => void
+ leftSidebarOpen: boolean
+ rightSidebarOpen: boolean
+ onExpandLeft: () => void
+ onExpandRight: () => void
}
/**
* Slim top bar — logo on the left, settings gear on the right. The
* active heap badge moved into the Heaps panel in the left sidebar
* (where it actually relates to the heap rows the user navigates to).
+ *
+ * Also hosts the "expand sidebar" affordances: when a side panel is
+ * collapsed, a small panel-open icon appears on the corresponding edge
+ * so the user has a way to bring it back without hunting for the
+ * keyboard shortcut. When the panel is open, the button hides — its
+ * collapse twin lives in the panel's own header.
*/
-export function TopBar({ onOpenSettings }: TopBarProps) {
+export function TopBar({
+ onOpenSettings,
+ leftSidebarOpen,
+ rightSidebarOpen,
+ onExpandLeft,
+ onExpandRight,
+}: TopBarProps) {
return (
Mulimago