From 680bb16e97788bb95dde811a3825eac23498633c Mon Sep 17 00:00:00 2001 From: klopez4212 Date: Sun, 5 Jul 2026 09:05:22 +0100 Subject: [PATCH] Persist the work drawer state; shimmer washes toward background MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drawer: the open/closed preference reset on every chat switch, so the panel re-animated open each time a PR chat was selected. The toggle is now one persisted preference — switching chats renders the drawer in its remembered state with no animation; auto-open-on-PR remains only until the user toggles once. Shimmer: the band color moves close to the background (a whisper of primary keeps the hue) so glyphs visibly wash out as it passes — the strongest contrast against full-color text — and the highlight wash drops to a soft glow instead of a gray slab. Co-Authored-By: Claude Fable 5 --- desktop/src/features/chats/ui/ChatsScreen.tsx | 31 +++++++++++++------ .../src/shared/styles/globals/animations.css | 11 +++---- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/desktop/src/features/chats/ui/ChatsScreen.tsx b/desktop/src/features/chats/ui/ChatsScreen.tsx index b2af641d5f..5fb4be5441 100644 --- a/desktop/src/features/chats/ui/ChatsScreen.tsx +++ b/desktop/src/features/chats/ui/ChatsScreen.tsx @@ -55,6 +55,8 @@ import { normalizePubkey } from "@/shared/lib/pubkey"; import { getMentionTagPubkey } from "@/shared/lib/resolveMentionNames"; import { Button } from "@/shared/ui/button"; +const WORK_PANEL_OPEN_KEY = "buzz:chats:work-panel-open:v1"; + type ChatsScreenProps = { initialProjectId?: string | null; selectedChatId?: string | null; @@ -335,16 +337,27 @@ export function ChatsScreen({ } return null; }, [messages]); - // null = auto: open once the agent has produced a PR, closed otherwise. - // A click stores an explicit preference for the current chat. + // The drawer's open state is a single persisted preference — switching + // chats must NOT reset it (the panel used to re-animate open on every + // switch). null = never toggled: auto-open when the chat has a PR. const [workPanelPreference, setWorkPanelPreference] = React.useState< boolean | null - >(null); - const workPanelChatRef = React.useRef(selectedChatId); - if (workPanelChatRef.current !== selectedChatId) { - workPanelChatRef.current = selectedChatId; - setWorkPanelPreference(null); - } + >(() => { + try { + const raw = window.localStorage.getItem(WORK_PANEL_OPEN_KEY); + return raw === null ? null : raw === "true"; + } catch { + return null; + } + }); + const handleWorkPanelPreference = React.useCallback((next: boolean) => { + setWorkPanelPreference(next); + try { + window.localStorage.setItem(WORK_PANEL_OPEN_KEY, String(next)); + } catch { + // Best-effort persistence. + } + }, []); const isWorkPanelOpen = workPanelPreference ?? agentPullRequestHref !== null; const startManagedAgentMutation = useStartManagedAgentMutation(); const [isEnsuringDefaultAgent, setIsEnsuringDefaultAgent] = @@ -638,7 +651,7 @@ export function ChatsScreen({ } aria-pressed={isWorkPanelOpen} data-testid="toggle-work-panel" - onClick={() => setWorkPanelPreference(!isWorkPanelOpen)} + onClick={() => handleWorkPanelPreference(!isWorkPanelOpen)} size="icon" type="button" variant="ghost" diff --git a/desktop/src/shared/styles/globals/animations.css b/desktop/src/shared/styles/globals/animations.css index b1efedbb2d..1b8940f78e 100644 --- a/desktop/src/shared/styles/globals/animations.css +++ b/desktop/src/shared/styles/globals/animations.css @@ -233,19 +233,18 @@ saturated instead of graying toward the background) — a rich mid-purple band over near-white text. */ .buzz-shimmer-accent { + /* The band hugs the BACKGROUND color (a whisper of primary keeps the + hue): glyphs visibly wash out toward the background as it passes, + which is the strongest possible contrast against full-color text. */ --buzz-shimmer-highlight: color-mix( in oklab, - hsl(var(--primary)) 40%, + hsl(var(--primary)) 18%, hsl(var(--background)) ); --buzz-shimmer-band: 300%; color: inherit; } -.dark .buzz-shimmer-accent { - --buzz-shimmer-highlight: color-mix(in oklch, hsl(var(--primary)) 60%, black); -} - /* Glyph recoloring alone is too subtle at sidebar sizes — sweep a translucent highlight WASH behind the text as well (same keyframes, so band and wash move together). The wash is a soft primary tint the text @@ -256,7 +255,7 @@ 90deg, transparent 0%, transparent 40%, - hsl(var(--primary) / 0.28) 50%, + hsl(var(--primary) / 0.16) 50%, transparent 60%, transparent 100% );