From 23ea1fca974f0d2656e68089a773b518e04c068f Mon Sep 17 00:00:00 2001 From: Arjun <6592213+arkml@users.noreply.github.com> Date: Fri, 5 Jun 2026 00:37:31 +0530 Subject: [PATCH] add pane size config in settings --- apps/x/apps/renderer/src/App.tsx | 19 +++++++++++--- .../renderer/src/components/chat-sidebar.tsx | 11 ++++++-- .../src/components/settings-dialog.tsx | 26 ++++++++++++++++++- .../renderer/src/contexts/theme-context.tsx | 22 +++++++++++++++- 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/apps/x/apps/renderer/src/App.tsx b/apps/x/apps/renderer/src/App.tsx index 3d905694..df85e06b 100644 --- a/apps/x/apps/renderer/src/App.tsx +++ b/apps/x/apps/renderer/src/App.tsx @@ -166,6 +166,7 @@ function AutoScrollPre({ className, children }: { className?: string; children: } const DEFAULT_SIDEBAR_WIDTH = 256 +const DEFAULT_CHAT_PANE_WIDTH = 460 const wikiLinkRegex = /\[\[([^[\]]+)\]\]/g const graphPalette = [ { hue: 210, sat: 72, light: 52 }, @@ -737,7 +738,7 @@ function ContentHeader({ } function App() { - const { chatPanePlacement } = useTheme() + const { chatPanePlacement, chatPaneSize } = useTheme() const isChatPaneInMiddle = chatPanePlacement === 'middle' type ShortcutPane = 'left' | 'right' @@ -5250,6 +5251,17 @@ function App() { const isRightPaneContext = Boolean(selectedPath || isGraphOpen || isSuggestedTopicsOpen || isMeetingsOpen || isLiveNotesOpen || isBgTasksOpen || isEmailOpen || isWorkspaceOpen || isKnowledgeViewOpen || isChatHistoryOpen || isHomeOpen || isBrowserOpen) const isRightPaneOnlyMode = isRightPaneContext && isChatSidebarOpen && isRightPaneMaximized const shouldCollapseLeftPane = isRightPaneOnlyMode + const nonChatPaneStyle = React.useMemo(() => { + const style: React.CSSProperties = { maxWidth: insetMaxWidth } + if (!isRightPaneContext || !isChatSidebarOpen || isRightPaneMaximized) return style + if (chatPaneSize === 'chat-equal') { + return { ...style, width: 0, flex: '1 1 0' } + } + if (chatPaneSize === 'chat-bigger') { + return { ...style, width: DEFAULT_CHAT_PANE_WIDTH, flex: '0 0 auto' } + } + return style + }, [chatPaneSize, insetMaxWidth, isChatSidebarOpen, isRightPaneContext, isRightPaneMaximized]) // Collapsing: pin max-width to the snapshot px (no transition) for one frame so it's // binding immediately (no flex jump), then animate to 0. Expanding goes back to 100% // — its non-binding range lands at the end of the range, where it isn't visible. @@ -5331,7 +5343,7 @@ function App() { insetAnimateMaxWidth && "transition-[max-width] duration-200 ease-linear", shouldCollapseLeftPane && "pointer-events-none select-none" )} - style={{ maxWidth: insetMaxWidth }} + style={nonChatPaneStyle} aria-hidden={shouldCollapseLeftPane} onMouseDownCapture={() => setActiveShortcutPane('left')} onFocusCapture={() => setActiveShortcutPane('left')} @@ -6002,8 +6014,9 @@ function App() { {isRightPaneContext && ( { if (typeof window === 'undefined') return MAX_WIDTH @@ -508,8 +512,11 @@ export function ChatSidebar({ // not add extra width to the right and overflow the app viewport. return { width: 0, flex: '1 1 auto' } } + if (paneSize === 'chat-equal' || paneSize === 'chat-bigger') { + return { width: 0, flex: '1 1 0' } + } return { width, flex: '0 0 auto' } - }, [isOpen, isMaximized, width]) + }, [isOpen, isMaximized, paneSize, width]) return (
- {!isMaximized && ( + {!isMaximized && isResizable && (
@@ -259,6 +259,30 @@ function AppearanceSettings() { onClick={() => setChatPanePlacement("middle")} />
+

Chat size

+

+ Choose how much width chat gets when another pane is open +

+
+ setChatPaneSize("chat-smaller")} + /> + setChatPaneSize("chat-equal")} + /> + setChatPaneSize("chat-bigger")} + /> +
) diff --git a/apps/x/apps/renderer/src/contexts/theme-context.tsx b/apps/x/apps/renderer/src/contexts/theme-context.tsx index 03e7bc93..04df59e7 100644 --- a/apps/x/apps/renderer/src/contexts/theme-context.tsx +++ b/apps/x/apps/renderer/src/contexts/theme-context.tsx @@ -4,6 +4,7 @@ import * as React from "react" export type Theme = "light" | "dark" | "system" export type ChatPanePlacement = "right" | "middle" +export type ChatPaneSize = "chat-smaller" | "chat-equal" | "chat-bigger" type ThemeContextProps = { theme: Theme @@ -11,17 +12,24 @@ type ThemeContextProps = { setTheme: (theme: Theme) => void chatPanePlacement: ChatPanePlacement setChatPanePlacement: (placement: ChatPanePlacement) => void + chatPaneSize: ChatPaneSize + setChatPaneSize: (size: ChatPaneSize) => void } const ThemeContext = React.createContext(null) const STORAGE_KEY = "rowboat-theme" const CHAT_PANE_PLACEMENT_STORAGE_KEY = "rowboat-chat-pane-placement" +const CHAT_PANE_SIZE_STORAGE_KEY = "rowboat-chat-pane-size" function isChatPanePlacement(value: string | null): value is ChatPanePlacement { return value === "right" || value === "middle" } +function isChatPaneSize(value: string | null): value is ChatPaneSize { + return value === "chat-smaller" || value === "chat-equal" || value === "chat-bigger" +} + function getSystemTheme(): "light" | "dark" { if (typeof window === "undefined") return "light" return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" @@ -52,6 +60,11 @@ export function ThemeProvider({ const stored = localStorage.getItem(CHAT_PANE_PLACEMENT_STORAGE_KEY) return isChatPanePlacement(stored) ? stored : "right" }) + const [chatPaneSize, setChatPaneSizeState] = React.useState(() => { + if (typeof window === "undefined") return "chat-smaller" + const stored = localStorage.getItem(CHAT_PANE_SIZE_STORAGE_KEY) + return isChatPaneSize(stored) ? stored : "chat-smaller" + }) const [resolvedTheme, setResolvedTheme] = React.useState<"light" | "dark">(() => { if (theme === "system") return getSystemTheme() @@ -94,6 +107,11 @@ export function ThemeProvider({ setChatPanePlacementState(placement) }, []) + const setChatPaneSize = React.useCallback((size: ChatPaneSize) => { + localStorage.setItem(CHAT_PANE_SIZE_STORAGE_KEY, size) + setChatPaneSizeState(size) + }, []) + const contextValue = React.useMemo( () => ({ theme, @@ -101,8 +119,10 @@ export function ThemeProvider({ setTheme, chatPanePlacement, setChatPanePlacement, + chatPaneSize, + setChatPaneSize, }), - [theme, resolvedTheme, setTheme, chatPanePlacement, setChatPanePlacement] + [theme, resolvedTheme, setTheme, chatPanePlacement, setChatPanePlacement, chatPaneSize, setChatPaneSize] ) return (