diff --git a/apps/x/apps/main/src/main.ts b/apps/x/apps/main/src/main.ts index 7ade72e3..42c9f3fd 100644 --- a/apps/x/apps/main/src/main.ts +++ b/apps/x/apps/main/src/main.ts @@ -112,6 +112,8 @@ function createWindow() { const win = new BrowserWindow({ width: 1280, height: 800, + minWidth: 600, + minHeight: 480, show: false, // Don't show until ready backgroundColor: "#252525", // Prevent white flash (matches dark mode) titleBarStyle: "hiddenInset", diff --git a/apps/x/apps/renderer/src/components/sidebar-content.tsx b/apps/x/apps/renderer/src/components/sidebar-content.tsx index 7e41783e..3fcb1acc 100644 --- a/apps/x/apps/renderer/src/components/sidebar-content.tsx +++ b/apps/x/apps/renderer/src/components/sidebar-content.tsx @@ -205,7 +205,7 @@ function formatRunTime(ts: string): string { } function SyncStatusBar() { - const { state, isMobile } = useSidebar() + const { state } = useSidebar() const [activeServices, setActiveServices] = useState>(new Map()) const [popoverOpen, setPopoverOpen] = useState(false) const [logEvents, setLogEvents] = useState([]) @@ -301,7 +301,7 @@ function SyncStatusBar() { return ( <> - {!isMobile && isCollapsed && isSyncing && ( + {isCollapsed && isSyncing && (
void - openMobile: boolean - setOpenMobile: (open: boolean) => void - isMobile: boolean toggleSidebar: () => void sidebarWidth: number setSidebarWidth: (width: number) => void @@ -70,8 +59,6 @@ function SidebarProvider({ open?: boolean onOpenChange?: (open: boolean) => void }) { - const isMobile = useIsMobile() - const [openMobile, setOpenMobile] = React.useState(false) const [sidebarWidth, setSidebarWidth] = React.useState(SIDEBAR_WIDTH) const [isResizing, setIsResizing] = React.useState(false) @@ -94,10 +81,35 @@ function SidebarProvider({ [setOpenProp, open] ) + // Auto-collapse sidebar when window is too narrow, re-expand when wide enough + const autoCollapsedRef = React.useRef(false) + React.useEffect(() => { + const mql = window.matchMedia(`(max-width: ${SIDEBAR_AUTO_COLLAPSE_WIDTH - 1}px)`) + const onChange = () => { + if (mql.matches && open) { + // Window became narrow — auto-collapse + autoCollapsedRef.current = true + setOpen(false) + } else if (!mql.matches && !open && autoCollapsedRef.current) { + // Window became wide again — restore if we auto-collapsed it + autoCollapsedRef.current = false + setOpen(true) + } + } + // Check on mount + if (mql.matches && open) { + autoCollapsedRef.current = true + setOpen(false) + } + mql.addEventListener("change", onChange) + return () => mql.removeEventListener("change", onChange) + }, [open, setOpen]) + // Helper to toggle the sidebar. const toggleSidebar = React.useCallback(() => { - return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open) - }, [isMobile, setOpen, setOpenMobile]) + autoCollapsedRef.current = false // User manually toggled, don't auto-restore + return setOpen((open) => !open) + }, [setOpen]) // We add a state so that we can do data-state="expanded" or "collapsed". // This makes it easier to style the sidebar with Tailwind classes. @@ -108,16 +120,13 @@ function SidebarProvider({ state, open, setOpen, - isMobile, - openMobile, - setOpenMobile, toggleSidebar, sidebarWidth, setSidebarWidth, isResizing, setIsResizing, }), - [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar, sidebarWidth, isResizing] + [state, open, setOpen, toggleSidebar, sidebarWidth, isResizing] ) return ( @@ -161,7 +170,7 @@ function Sidebar({ variant?: "sidebar" | "floating" | "inset" collapsible?: "offcanvas" | "icon" | "none" }) { - const { isMobile, state, openMobile, setOpenMobile } = useSidebar() + const { state } = useSidebar() if (collapsible === "none") { return ( @@ -178,34 +187,9 @@ function Sidebar({ ) } - if (isMobile) { - return ( - - - - Sidebar - Displays the mobile sidebar. - -
{children}
-
-
- ) - } - return (