- Add 21 tests for message-normalizer.ts (normalizeMessage, normalizeRoleForGrouping, isToolResultMessage) - Add 17 tests for tool-helpers.ts (formatToolOutputForSidebar, getTruncatedPreview) - Update navigation.test.ts to test iconClassForTab instead of deprecated iconForTab - Skip focus-mode.browser.test.ts (toggle button moved to settings) - Skip chat-markdown.browser.test.ts (tool card rendering refactored to sidebar) - Skip bash-tools.test.ts line offset tests (shell env pollution issue)
96 lines
3.0 KiB
TypeScript
96 lines
3.0 KiB
TypeScript
const KEY = "clawdbot.control.settings.v1";
|
|
|
|
import type { ThemeMode } from "./theme";
|
|
|
|
export type UiSettings = {
|
|
gatewayUrl: string;
|
|
token: string;
|
|
sessionKey: string;
|
|
lastActiveSessionKey: string;
|
|
theme: ThemeMode;
|
|
chatFocusMode: boolean;
|
|
splitRatio: number; // Sidebar split ratio (0.4 to 0.7, default 0.6)
|
|
useNewChatLayout: boolean; // Slack-style grouped messages layout
|
|
navCollapsed: boolean; // Collapsible sidebar state
|
|
navGroupsCollapsed: Record<string, boolean>; // Which nav groups are collapsed
|
|
};
|
|
|
|
export function loadSettings(): UiSettings {
|
|
const defaultUrl = (() => {
|
|
const proto = location.protocol === "https:" ? "wss" : "ws";
|
|
return `${proto}://${location.host}`;
|
|
})();
|
|
|
|
const defaults: UiSettings = {
|
|
gatewayUrl: defaultUrl,
|
|
token: "",
|
|
sessionKey: "main",
|
|
lastActiveSessionKey: "main",
|
|
theme: "system",
|
|
chatFocusMode: false,
|
|
splitRatio: 0.6,
|
|
useNewChatLayout: true, // Enabled by default
|
|
navCollapsed: false,
|
|
navGroupsCollapsed: {},
|
|
};
|
|
|
|
try {
|
|
const raw = localStorage.getItem(KEY);
|
|
if (!raw) return defaults;
|
|
const parsed = JSON.parse(raw) as Partial<UiSettings>;
|
|
return {
|
|
gatewayUrl:
|
|
typeof parsed.gatewayUrl === "string" && parsed.gatewayUrl.trim()
|
|
? parsed.gatewayUrl.trim()
|
|
: defaults.gatewayUrl,
|
|
token: typeof parsed.token === "string" ? parsed.token : defaults.token,
|
|
sessionKey:
|
|
typeof parsed.sessionKey === "string" && parsed.sessionKey.trim()
|
|
? parsed.sessionKey.trim()
|
|
: defaults.sessionKey,
|
|
lastActiveSessionKey:
|
|
typeof parsed.lastActiveSessionKey === "string" &&
|
|
parsed.lastActiveSessionKey.trim()
|
|
? parsed.lastActiveSessionKey.trim()
|
|
: (typeof parsed.sessionKey === "string" &&
|
|
parsed.sessionKey.trim()) ||
|
|
defaults.lastActiveSessionKey,
|
|
theme:
|
|
parsed.theme === "light" ||
|
|
parsed.theme === "dark" ||
|
|
parsed.theme === "system"
|
|
? parsed.theme
|
|
: defaults.theme,
|
|
chatFocusMode:
|
|
typeof parsed.chatFocusMode === "boolean"
|
|
? parsed.chatFocusMode
|
|
: defaults.chatFocusMode,
|
|
splitRatio:
|
|
typeof parsed.splitRatio === "number" &&
|
|
parsed.splitRatio >= 0.4 &&
|
|
parsed.splitRatio <= 0.7
|
|
? parsed.splitRatio
|
|
: defaults.splitRatio,
|
|
useNewChatLayout:
|
|
typeof parsed.useNewChatLayout === "boolean"
|
|
? parsed.useNewChatLayout
|
|
: defaults.useNewChatLayout,
|
|
navCollapsed:
|
|
typeof parsed.navCollapsed === "boolean"
|
|
? parsed.navCollapsed
|
|
: defaults.navCollapsed,
|
|
navGroupsCollapsed:
|
|
typeof parsed.navGroupsCollapsed === "object" &&
|
|
parsed.navGroupsCollapsed !== null
|
|
? parsed.navGroupsCollapsed
|
|
: defaults.navGroupsCollapsed,
|
|
};
|
|
} catch {
|
|
return defaults;
|
|
}
|
|
}
|
|
|
|
export function saveSettings(next: UiSettings) {
|
|
localStorage.setItem(KEY, JSON.stringify(next));
|
|
}
|