Add useLocalStorage hook for the console toggle

Move the instance console chat/log toggle persistence into a generic useLocalStorage hook that defers the write so it never blocks the toggle update.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
bbassieandClaude Opus 4.8 committed 2026-06-25 02:31:49 +00:00
1 parent 92f607a864
commit 6feb9c2762
2 files changed
+36 -7

No files matched your search

@@ -25,6 +25,7 @@ import { useHost } from "../model/host";
import InstanceStatusTag from "./InstanceStatusTag";
import Link from "./Link";
import { instancePublicAddress } from "../util/instance";
import useLocalStorage from "../util/useLocalStorage";
import { MetricRelativeDate } from "./system_metrics";
type MenuItem = Required<MenuProps>["items"][number];
@@ -180,9 +181,7 @@ export default function InstanceViewPage() {
let params = useParams();
let instanceId = Number(params.id);
const [maxLevel, setMaxLevel] = useState<keyof typeof lib.levels>("server");
const [actionsOnly, setActionsOnly] = useState<boolean>(
() => localStorage.getItem(consoleActionsOnlyKey) !== "false"
);
const [actionsOnly, setActionsOnly] = useLocalStorage(consoleActionsOnlyKey, true);
let navigate = useNavigate();
@@ -239,10 +238,7 @@ export default function InstanceViewPage() {
checkedChildren="Chat"
unCheckedChildren="Log"
checked={actionsOnly}
onChange={value => {
setActionsOnly(value);
localStorage.setItem(consoleActionsOnlyKey, String(value));
}}
onChange={setActionsOnly}
/>
<SelectMaxLogLevel
value={maxLevel}
@@ -0,0 +1,33 @@
import { useState } from "react";
/**
* Persist a JSON-serialisable value in localStorage. Behaves like useState, but
* seeds the initial value from localStorage and writes changes back. The write
* is deferred to a later task so it never blocks the state update / re-render.
*/
export default function useLocalStorage<T>(key: string, defaultValue: T): [T, (value: T) => void] {
const [value, setValue] = useState<T>(() => {
const stored = localStorage.getItem(key);
if (stored === null) {
return defaultValue;
}
try {
return JSON.parse(stored) as T;
} catch {
return defaultValue;
}
});
function set(next: T) {
setValue(next);
setTimeout(() => {
try {
localStorage.setItem(key, JSON.stringify(next));
} catch {
// Ignore storage errors (e.g. quota exceeded or storage disabled).
}
}, 0);
}
return [value, set];
}