wip: optimizations

This commit is contained in:
2026-05-23 15:28:40 +02:00
parent 5bf506af03
commit 155fe20862
89 changed files with 7431 additions and 392 deletions

View File

@@ -1,5 +1,6 @@
import { STORAGE_KEY_GENERAL_SETTINGS, STORAGE_KEY_LAST_VIEWED_CHAT } from '../../core/constants';
import { getUserScopedStorageKey } from '../../core/storage/current-user-storage';
import { runWhenIdle } from '../../shared/rxjs';
export interface GeneralSettings {
reopenLastViewedChat: boolean;
@@ -15,10 +16,65 @@ export interface LastViewedChatSnapshot {
channelId: string | null;
}
const pendingWrites = new Map<string, string | null>();
let flushScheduled = false;
let cancelScheduledFlush: (() => void) | null = null;
function scheduleStorageFlush(): void {
if (flushScheduled) {
return;
}
flushScheduled = true;
cancelScheduledFlush = runWhenIdle(() => {
flushScheduled = false;
cancelScheduledFlush = null;
const snapshot = Array.from(pendingWrites.entries());
pendingWrites.clear();
for (const [key, value] of snapshot) {
try {
if (value === null) {
localStorage.removeItem(key);
} else {
localStorage.setItem(key, value);
}
} catch {
// storage not available
}
}
});
}
function scheduleStorageWrite(key: string, serialised: string): void {
pendingWrites.set(key, serialised);
scheduleStorageFlush();
}
function scheduleStorageRemove(key: string): void {
pendingWrites.set(key, null);
scheduleStorageFlush();
}
function readMaybePending(key: string): string | null {
if (pendingWrites.has(key)) {
return pendingWrites.get(key) ?? null;
}
try {
return localStorage.getItem(key);
} catch {
return null;
}
}
export function loadGeneralSettingsFromStorage(): GeneralSettings {
try {
const raw = localStorage.getItem(getUserScopedStorageKey(STORAGE_KEY_GENERAL_SETTINGS))
?? localStorage.getItem(STORAGE_KEY_GENERAL_SETTINGS);
const raw = readMaybePending(getUserScopedStorageKey(STORAGE_KEY_GENERAL_SETTINGS))
?? readMaybePending(STORAGE_KEY_GENERAL_SETTINGS);
if (!raw) {
return { ...DEFAULT_GENERAL_SETTINGS };
@@ -36,17 +92,15 @@ export function saveGeneralSettingsToStorage(patch: Partial<GeneralSettings>): G
...patch
});
try {
localStorage.setItem(getUserScopedStorageKey(STORAGE_KEY_GENERAL_SETTINGS), JSON.stringify(nextSettings));
} catch {}
scheduleStorageWrite(getUserScopedStorageKey(STORAGE_KEY_GENERAL_SETTINGS), JSON.stringify(nextSettings));
return nextSettings;
}
export function loadLastViewedChatFromStorage(userId?: string | null): LastViewedChatSnapshot | null {
try {
const raw = localStorage.getItem(getUserScopedStorageKey(STORAGE_KEY_LAST_VIEWED_CHAT, userId))
?? localStorage.getItem(STORAGE_KEY_LAST_VIEWED_CHAT);
const raw = readMaybePending(getUserScopedStorageKey(STORAGE_KEY_LAST_VIEWED_CHAT, userId))
?? readMaybePending(STORAGE_KEY_LAST_VIEWED_CHAT);
if (!raw) {
return null;
@@ -75,16 +129,41 @@ export function saveLastViewedChatToStorage(snapshot: LastViewedChatSnapshot): v
return;
}
try {
localStorage.setItem(getUserScopedStorageKey(STORAGE_KEY_LAST_VIEWED_CHAT, normalised.userId), JSON.stringify(normalised));
} catch {}
scheduleStorageWrite(
getUserScopedStorageKey(STORAGE_KEY_LAST_VIEWED_CHAT, normalised.userId),
JSON.stringify(normalised)
);
}
export function clearLastViewedChatFromStorage(userId?: string | null): void {
try {
localStorage.removeItem(getUserScopedStorageKey(STORAGE_KEY_LAST_VIEWED_CHAT, userId));
localStorage.removeItem(STORAGE_KEY_LAST_VIEWED_CHAT);
} catch {}
scheduleStorageRemove(getUserScopedStorageKey(STORAGE_KEY_LAST_VIEWED_CHAT, userId));
scheduleStorageRemove(STORAGE_KEY_LAST_VIEWED_CHAT);
}
/** Force-flush any pending app-resume writes (e.g. before unload). */
export function flushAppResumeStorage(): void {
if (cancelScheduledFlush) {
cancelScheduledFlush();
cancelScheduledFlush = null;
}
flushScheduled = false;
const snapshot = Array.from(pendingWrites.entries());
pendingWrites.clear();
for (const [key, value] of snapshot) {
try {
if (value === null) {
localStorage.removeItem(key);
} else {
localStorage.setItem(key, value);
}
} catch {
// storage not available
}
}
}
function normaliseGeneralSettings(raw: Partial<GeneralSettings>): GeneralSettings {