From 454453788e759fa16442e755434fbb842fa1acab Mon Sep 17 00:00:00 2001 From: bndw Date: Sat, 28 Feb 2026 21:49:29 -0800 Subject: feat: **`globals.css`** — Edit `.chat-pane`: remove `width: 3… (+7 more) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ✅ **`globals.css`** — Edit `.chat-pane`: remove `width: 380px`, add `min-width: 0`, `overflow: hidden`, `transition: width 0.2s ease` - ✅ **`globals.css`** — Insert `.chat-resize-handle`, `.chat-header`, `.chat-collapse-btn` rules after `.chat-pane` block - ✅ **`globals.css`** — Append `::-webkit-scrollbar` rules at end of file - ✅ **`ChatPane.tsx`** — Full rewrite: new props interface, header strip, conditional body, inline width style - ✅ **`App.tsx`** — Add `chatWidth` + `chatCollapsed` state with lazy localStorage initialisers - ✅ **`App.tsx`** — Add two `useEffect` persistence hooks - ✅ **`App.tsx`** — Add `handleResizeMouseDown` function - ✅ **`App.tsx`** — Update `.main-content` JSX: insert conditional resize handle div, pass new props to `` --- renderer/src/App.tsx | 42 +++++++++++++++++++ renderer/src/components/ChatPane.tsx | 80 +++++++++++++++++++++++------------- renderer/src/styles/globals.css | 77 +++++++++++++++++++++++++++++++++- 3 files changed, 169 insertions(+), 30 deletions(-) diff --git a/renderer/src/App.tsx b/renderer/src/App.tsx index 7d75196..c3eafd4 100644 --- a/renderer/src/App.tsx +++ b/renderer/src/App.tsx @@ -63,15 +63,47 @@ export function App() { () => (localStorage.getItem("cf-theme") as Theme) ?? "dark" ); + const [chatWidth, setChatWidth] = useState( + () => Number(localStorage.getItem("cf-chat-width")) || 380 + ); + const [chatCollapsed, setChatCollapsed] = useState( + () => localStorage.getItem("cf-chat-collapsed") === "true" + ); + // Keep document.documentElement in sync and persist to localStorage useEffect(() => { document.documentElement.setAttribute("data-theme", theme); localStorage.setItem("cf-theme", theme); }, [theme]); + useEffect(() => { + localStorage.setItem("cf-chat-width", String(chatWidth)); + }, [chatWidth]); + + useEffect(() => { + localStorage.setItem("cf-chat-collapsed", String(chatCollapsed)); + }, [chatCollapsed]); + const handleToggleTheme = () => setTheme((t) => (t === "dark" ? "light" : "dark")); + const handleResizeMouseDown = (e: React.MouseEvent) => { + e.preventDefault(); + const startX = e.clientX; + const startWidth = chatWidth; + const onMove = (ev: MouseEvent) => { + const delta = startX - ev.clientX; // drag left = wider chat + const next = Math.max(180, Math.min(700, startWidth + delta)); + setChatWidth(next); + }; + const onUp = () => { + document.removeEventListener("mousemove", onMove); + document.removeEventListener("mouseup", onUp); + }; + document.addEventListener("mousemove", onMove); + document.addEventListener("mouseup", onUp); + }; + const hasChanges = documentContent !== originalContent; // Clear error after 5 seconds @@ -380,6 +412,13 @@ export function App() { theme={theme} /> + {!chatCollapsed && ( +
+ )} + setChatCollapsed((c) => !c)} />
diff --git a/renderer/src/components/ChatPane.tsx b/renderer/src/components/ChatPane.tsx index 917d462..40e682c 100644 --- a/renderer/src/components/ChatPane.tsx +++ b/renderer/src/components/ChatPane.tsx @@ -7,6 +7,9 @@ interface ChatPaneProps { isLoading: boolean; disabled: boolean; placeholder: string; + collapsed: boolean; + chatWidth: number; + onToggleCollapse: () => void; } export function ChatPane({ @@ -15,6 +18,9 @@ export function ChatPane({ isLoading, disabled, placeholder, + collapsed, + chatWidth, + onToggleCollapse, }: ChatPaneProps) { const [input, setInput] = useState(""); const messagesEndRef = useRef(null); @@ -30,37 +36,53 @@ export function ChatPane({ }; return ( -
-
- {messages.map((msg) => ( -
-
{msg.content}
-
- ))} - {isLoading && ( -
-
Thinking...
-
- )} -
-
- -
- setInput(e.target.value)} - onKeyDown={(e) => e.key === "Enter" && !e.shiftKey && handleSend()} - placeholder={placeholder} - disabled={disabled || isLoading} - /> -
+ + {!collapsed && ( + <> +
+ {messages.map((msg) => ( +
+
{msg.content}
+
+ ))} + {isLoading && ( +
+
Thinking...
+
+ )} +
+
+ +
+ setInput(e.target.value)} + onKeyDown={(e) => + e.key === "Enter" && !e.shiftKey && handleSend() + } + placeholder={placeholder} + disabled={disabled || isLoading} + /> + +
+ + )}
); } diff --git a/renderer/src/styles/globals.css b/renderer/src/styles/globals.css index 8e43f3a..03c7443 100644 --- a/renderer/src/styles/globals.css +++ b/renderer/src/styles/globals.css @@ -408,10 +408,57 @@ html[data-theme="light"] .session-rename-input { /* ── Chat Pane ───────────────────────────────────────────────── */ .chat-pane { - width: 380px; display: flex; flex-direction: column; background: var(--bg-secondary); + min-width: 0; + overflow: hidden; + transition: width 0.2s ease; +} + +/* ── Chat Resize Handle ──────────────────────────────────────── */ +.chat-resize-handle { + width: 5px; + background: transparent; + cursor: col-resize; + flex-shrink: 0; + transition: background 0.15s; +} + +.chat-resize-handle:hover { + background: var(--accent); +} + +/* ── Chat Header Strip ───────────────────────────────────────── */ +.chat-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 7px 12px; + background: var(--bg-secondary); + border-bottom: 1px solid var(--border); + font-size: 11px; + letter-spacing: 0.07em; + text-transform: uppercase; + color: var(--text-secondary); + flex-shrink: 0; +} + +.chat-collapse-btn { + background: transparent; + border: 1px solid var(--border); + border-radius: 2px; + color: var(--text-secondary); + cursor: pointer; + font-size: 12px; + padding: 2px 7px; + font-family: inherit; + transition: background 0.15s, color 0.15s; +} + +.chat-collapse-btn:hover { + background: var(--bg-tertiary); + color: var(--text-primary); } .chat-messages { @@ -998,3 +1045,31 @@ html[data-theme="light"] .settings-textarea:focus { background: var(--bg-tertiary); color: var(--text-primary); } + +/* ── Scrollbars ──────────────────────────────────────────────── */ +.chat-messages::-webkit-scrollbar, +.document-content::-webkit-scrollbar, +.cm-scroller::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +.chat-messages::-webkit-scrollbar-track, +.document-content::-webkit-scrollbar-track, +.cm-scroller::-webkit-scrollbar-track { + background: var(--bg-primary); +} + +.chat-messages::-webkit-scrollbar-thumb, +.document-content::-webkit-scrollbar-thumb, +.cm-scroller::-webkit-scrollbar-thumb { + background: var(--bg-tertiary); + border-radius: 4px; + border: 2px solid var(--bg-primary); +} + +.chat-messages::-webkit-scrollbar-thumb:hover, +.document-content::-webkit-scrollbar-thumb:hover, +.cm-scroller::-webkit-scrollbar-thumb:hover { + background: var(--border); +} -- cgit v1.2.3