chore(dashboard): address copilot review nits on #16861

- App.tsx doc comment: replace stale ChatPageHost reference with
  'persistent chat host block rendered inline near the bottom of this
  file' so readers can find the actual code.
- App.tsx persistent host: show a small spinner on /chat while plugin
  manifests are loading instead of a blank content area.  Direct
  /chat deep-links used to paint empty for up to ~2s in the worst
  case (plugin-registration safety timeout) because both the route
  sink (null) and the persistent host (!pluginsLoading gate) render
  nothing during that window.  Non-chat routes stay empty as before.
- ChatPage.tsx: rename setter to match the 'raw' state — useState
  now destructures as [mobilePanelOpenRaw, setMobilePanelOpenRaw],
  and all four call sites (closeMobilePanel, matchMedia listener,
  open-button onClick, plus destructure) updated accordingly.  No
  behavior change; matches the 'raw vs derived' convention the
  original comment set up.
This commit is contained in:
Teknium 2026-04-28 01:22:55 -07:00 committed by Teknium
parent d293e0051e
commit db305bba8b
2 changed files with 41 additions and 20 deletions

View file

@ -128,11 +128,11 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
// /chat re-runs the effect (derived flips back to true) and re-locks.
// Keying on the raw state would leak the body.overflow="hidden" across
// tabs because the dep wouldn't change on tab switch.
const [mobilePanelOpenRaw, setMobilePanelOpen] = useState(false);
const [mobilePanelOpenRaw, setMobilePanelOpenRaw] = useState(false);
const mobilePanelOpen = isActive && mobilePanelOpenRaw;
const { setEnd } = usePageHeader();
const { t } = useI18n();
const closeMobilePanel = useCallback(() => setMobilePanelOpen(false), []);
const closeMobilePanel = useCallback(() => setMobilePanelOpenRaw(false), []);
const modelToolsLabel = useMemo(
() => `${t.app.modelToolsSheetTitle} ${t.app.modelToolsSheetSubtitle}`,
[t.app.modelToolsSheetSubtitle, t.app.modelToolsSheetTitle],
@ -174,7 +174,7 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
useEffect(() => {
const mql = window.matchMedia("(min-width: 1024px)");
const onChange = (e: MediaQueryListEvent) => {
if (e.matches) setMobilePanelOpen(false);
if (e.matches) setMobilePanelOpenRaw(false);
};
mql.addEventListener("change", onChange);
return () => mql.removeEventListener("change", onChange);
@ -194,7 +194,7 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
setEnd(
<button
type="button"
onClick={() => setMobilePanelOpen(true)}
onClick={() => setMobilePanelOpenRaw(true)}
className={cn(
"inline-flex items-center gap-1.5 rounded border border-current/20",
"px-2 py-1 text-[0.65rem] font-medium tracking-wide normal-case",