Files
makelore/src/stores/chat-view-preferences.ts
inman 80e8386fa6
Some checks failed
Electron E2E / Electron E2E (macos-latest) (push) Has been cancelled
Electron E2E / Electron E2E (ubuntu-latest) (push) Has been cancelled
Electron E2E / Electron E2E (windows-latest) (push) Has been cancelled
feat: update Makelore modules and conversations
2026-07-31 10:08:41 +08:00

123 lines
4.0 KiB
TypeScript

export interface ChatViewPreferences {
showThinking: boolean;
showTimestamps: boolean;
/** Include reasoning, tool summaries, and execution narration in exports. */
includeExecution: boolean;
}
type ChatViewPreferencePatch = Partial<ChatViewPreferences>;
type StoredChatViewPreferences = Record<string, ChatViewPreferencePatch>;
export const CHAT_VIEW_PREFERENCES_STORAGE_KEY = 'makelore.chat-view-preferences.v1';
export const DEFAULT_CHAT_VIEW_PREFERENCES: ChatViewPreferences = {
showThinking: true,
showTimestamps: true,
includeExecution: false,
};
function browserStorage(): Storage | undefined {
try {
return typeof window === 'undefined' ? undefined : window.localStorage;
} catch {
return undefined;
}
}
function readStoredPreferences(storage: Storage | undefined): StoredChatViewPreferences {
const preferences = Object.create(null) as StoredChatViewPreferences;
if (!storage) return preferences;
try {
const parsed = JSON.parse(storage.getItem(CHAT_VIEW_PREFERENCES_STORAGE_KEY) ?? '{}');
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return preferences;
for (const [sessionId, candidate] of Object.entries(parsed as Record<string, unknown>)) {
if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) continue;
const record = candidate as Record<string, unknown>;
preferences[sessionId] = {
...(typeof record.showThinking === 'boolean'
? { showThinking: record.showThinking }
: {}),
...(typeof record.showTimestamps === 'boolean'
? { showTimestamps: record.showTimestamps }
: {}),
...(typeof record.includeExecution === 'boolean'
? { includeExecution: record.includeExecution }
: {}),
};
}
} catch {
return preferences;
}
return preferences;
}
export function loadChatViewPreferences(
sessionId: string,
storage: Storage | undefined = browserStorage(),
): ChatViewPreferences {
const candidate = readStoredPreferences(storage)[sessionId];
return {
showThinking: typeof candidate?.showThinking === 'boolean'
? candidate.showThinking
: DEFAULT_CHAT_VIEW_PREFERENCES.showThinking,
showTimestamps: typeof candidate?.showTimestamps === 'boolean'
? candidate.showTimestamps
: DEFAULT_CHAT_VIEW_PREFERENCES.showTimestamps,
includeExecution: typeof candidate?.includeExecution === 'boolean'
? candidate.includeExecution
: DEFAULT_CHAT_VIEW_PREFERENCES.includeExecution,
};
}
export function saveChatViewPreferences(
sessionId: string,
patch: ChatViewPreferencePatch,
storage: Storage | undefined = browserStorage(),
): ChatViewPreferences {
const current = loadChatViewPreferences(sessionId, storage);
const next = {
showThinking: typeof patch.showThinking === 'boolean'
? patch.showThinking
: current.showThinking,
showTimestamps: typeof patch.showTimestamps === 'boolean'
? patch.showTimestamps
: current.showTimestamps,
includeExecution: typeof patch.includeExecution === 'boolean'
? patch.includeExecution
: current.includeExecution,
};
if (!storage) return next;
try {
const all = readStoredPreferences(storage);
all[sessionId] = next;
storage.setItem(CHAT_VIEW_PREFERENCES_STORAGE_KEY, JSON.stringify(all));
} catch {
// View preferences are best-effort and must never block the chat UI.
}
return next;
}
export function deleteChatViewPreferences(
sessionId: string,
storage: Storage | undefined = browserStorage(),
): void {
if (!storage) return;
try {
const all = readStoredPreferences(storage);
if (!Object.prototype.hasOwnProperty.call(all, sessionId)) return;
delete all[sessionId];
if (Object.keys(all).length === 0) {
storage.removeItem(CHAT_VIEW_PREFERENCES_STORAGE_KEY);
} else {
storage.setItem(CHAT_VIEW_PREFERENCES_STORAGE_KEY, JSON.stringify(all));
}
} catch {
// Host deletion already succeeded; unavailable storage must not undo it.
}
}