mirror of
https://github.com/block/buzz.git
synced 2026-11-13 12:51:34 +00:00
Persist the work drawer state; shimmer washes toward background
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 <noreply@anthropic.com>
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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%
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user