From 45accd18fd6c867058219e1135f3c1870d766502 Mon Sep 17 00:00:00 2001 From: Christian Geier Date: Wed, 4 Mar 2026 17:50:31 +0100 Subject: [PATCH 1/7] feat: resizable sessions panel + full-width session titles (closes #35) --- .../src/components/resize-handle.tsx | 2 + app-prefixable/src/context/layout.tsx | 24 +++ app-prefixable/src/pages/layout.tsx | 190 +++++++++++------- 3 files changed, 148 insertions(+), 68 deletions(-) diff --git a/app-prefixable/src/components/resize-handle.tsx b/app-prefixable/src/components/resize-handle.tsx index 2c300a7..67fcf9b 100644 --- a/app-prefixable/src/components/resize-handle.tsx +++ b/app-prefixable/src/components/resize-handle.tsx @@ -8,6 +8,7 @@ export interface ResizeHandleProps { max: number onResize: (size: number) => void onCollapse?: () => void + onDragEnd?: () => void collapseThreshold?: number class?: string } @@ -55,6 +56,7 @@ export function ResizeHandle(props: ResizeHandleProps) { if (props.onCollapse && threshold > 0 && current < threshold) { props.onCollapse() } + if (props.onDragEnd) props.onDragEnd() } cleanup = () => { diff --git a/app-prefixable/src/context/layout.tsx b/app-prefixable/src/context/layout.tsx index b8749d1..bdde6de 100644 --- a/app-prefixable/src/context/layout.tsx +++ b/app-prefixable/src/context/layout.tsx @@ -11,6 +11,7 @@ const LAYOUT_STORAGE_KEY = "opencode.layout"; // Default values const DEFAULT_REVIEW_WIDTH = 320; const DEFAULT_INFO_WIDTH = 256; +const DEFAULT_SIDEBAR_WIDTH = 256; interface PanelState { opened: boolean; @@ -25,6 +26,7 @@ export type FileTab = { interface LayoutState { review: PanelState; info: PanelState; + sidebar?: { width?: number }; tabs?: FileTab[]; activeTab?: string | null; // null = Review tab, string = file path } @@ -48,6 +50,11 @@ interface LayoutContextValue { close: () => void; resize: (width: number) => void; }; + // Sidebar panel (sessions list) + sidebar: { + width: () => number; + resize: (width: number) => void; + }; // File tabs tabs: { all: () => FileTab[]; @@ -86,6 +93,9 @@ function loadState(): LayoutState { opened: parsed.info?.opened ?? false, width: parsed.info?.width ?? DEFAULT_INFO_WIDTH, }, + sidebar: { + width: parsed.sidebar?.width ?? DEFAULT_SIDEBAR_WIDTH, + }, tabs, activeTab, }; @@ -96,6 +106,7 @@ function loadState(): LayoutState { return { review: { opened: false, width: DEFAULT_REVIEW_WIDTH }, info: { opened: false, width: DEFAULT_INFO_WIDTH }, + sidebar: { width: DEFAULT_SIDEBAR_WIDTH }, tabs: [], activeTab: null, }; @@ -124,6 +135,11 @@ export function LayoutProvider(props: ParentProps) { initial.info.width ?? DEFAULT_INFO_WIDTH, ); + // Sidebar state + const [sidebarWidth, setSidebarWidth] = createSignal( + initial.sidebar?.width ?? DEFAULT_SIDEBAR_WIDTH, + ); + // File tabs state const [fileTabs, setFileTabs] = createSignal(initial.tabs ?? []); const [activeTab, setActiveTab] = createSignal( @@ -135,6 +151,7 @@ export function LayoutProvider(props: ParentProps) { saveState({ review: { opened: reviewOpened(), width: reviewWidth() }, info: { opened: infoOpened(), width: infoWidth() }, + sidebar: { width: sidebarWidth() }, tabs: fileTabs(), activeTab: activeTab(), }); @@ -181,6 +198,13 @@ export function LayoutProvider(props: ParentProps) { persist(); }, }, + sidebar: { + width: sidebarWidth, + resize: (width: number) => { + setSidebarWidth(width); + persist(); + }, + }, tabs: { all: fileTabs, active: activeTab, diff --git a/app-prefixable/src/pages/layout.tsx b/app-prefixable/src/pages/layout.tsx index df680d9..63c42c0 100644 --- a/app-prefixable/src/pages/layout.tsx +++ b/app-prefixable/src/pages/layout.tsx @@ -44,6 +44,7 @@ import { Pencil, } from "lucide-solid"; import { useSync } from "../context/sync"; +import { ResizeHandle } from "../components/resize-handle"; // Storage keys const PROJECTS_STORAGE_KEY = "opencode.projects"; @@ -107,6 +108,7 @@ export function Layout(props: ParentProps) { const [windowWidth, setWindowWidth] = createSignal( typeof window !== "undefined" ? window.innerWidth : 1200, ); + const [sidebarDragging, setSidebarDragging] = createSignal(false); // Responsive breakpoint - collapse sidebar below 900px const COLLAPSE_BREAKPOINT = 900; @@ -560,9 +562,9 @@ export function Layout(props: ParentProps) { {/* Sessions Panel (collapsible) */}
-
+
{/* Project Header with collapse toggle */}
- + {session.title || "Untitled"} @@ -764,50 +766,67 @@ export function Layout(props: ParentProps) {
-
@@ -846,10 +865,10 @@ export function Layout(props: ParentProps) {
{(session) => ( -
+
- +
+
+ +
+
)} @@ -941,6 +977,24 @@ export function Layout(props: ParentProps) {
+ {/* Sidebar resize handle */} + + { + setSidebarDragging(true); + layout.sidebar.resize(width); + }} + onDragEnd={() => setSidebarDragging(false)} + onCollapse={toggleSidebar} + collapseThreshold={100} + /> + + {/* Expand button when manually collapsed (not on settings or small screens) */} Date: Wed, 4 Mar 2026 18:05:29 +0100 Subject: [PATCH 2/7] fix: apply pointer-events and overlay bg fixes to archived sessions list --- app-prefixable/src/pages/layout.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app-prefixable/src/pages/layout.tsx b/app-prefixable/src/pages/layout.tsx index 63c42c0..5c5cd53 100644 --- a/app-prefixable/src/pages/layout.tsx +++ b/app-prefixable/src/pages/layout.tsx @@ -905,17 +905,19 @@ export function Layout(props: ParentProps) {