Files
fusion/packages/dashboard/app/hooks/useSessionBannerPref.ts
gsxdsm 5398bc7fc1 fix: persist session banner dismissals and add hide-banner setting
- Stop overwriting AI session titles with the "Planning session" fallback
  during cross-tab broadcasts before initialPlan has hydrated on resume.
- Persist SessionNotificationBanner dismissals to localStorage keyed by
  updatedAt so they survive refresh and auto-re-show on the next event.
- Add Settings → Appearance toggle to hide the banner entirely.
- Drop the inner scrollbar on the planning question list; let the outer
  pane handle all scrolling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 13:08:07 -07:00

46 lines
1.3 KiB
TypeScript

import { useSyncExternalStore } from "react";
const STORAGE_KEY = "fusion:hide-session-banners";
const EVENT_NAME = "fusion:session-banner-pref-changed";
function read(): boolean {
if (typeof window === "undefined") return false;
try {
return window.localStorage.getItem(STORAGE_KEY) === "1";
} catch {
return false;
}
}
function subscribe(onChange: () => void): () => void {
if (typeof window === "undefined") return () => {};
const handleStorage = (e: StorageEvent) => {
if (e.key === STORAGE_KEY) onChange();
};
const handleCustom = () => onChange();
window.addEventListener("storage", handleStorage);
window.addEventListener(EVENT_NAME, handleCustom);
return () => {
window.removeEventListener("storage", handleStorage);
window.removeEventListener(EVENT_NAME, handleCustom);
};
}
export function setSessionBannersHidden(hidden: boolean): void {
if (typeof window === "undefined") return;
try {
if (hidden) {
window.localStorage.setItem(STORAGE_KEY, "1");
} else {
window.localStorage.removeItem(STORAGE_KEY);
}
window.dispatchEvent(new Event(EVENT_NAME));
} catch {
// ignore
}
}
export function useSessionBannersHidden(): boolean {
return useSyncExternalStore(subscribe, read, () => false);
}