diff --git a/frontend/src/lib/stores/sectionCache.ts b/frontend/src/lib/stores/sectionCache.ts new file mode 100644 index 0000000..be7b3ff --- /dev/null +++ b/frontend/src/lib/stores/sectionCache.ts @@ -0,0 +1,37 @@ +// In-memory, per-section view cache. When you leave a list (Files, Tags, …) for +// another section and come back, the page restores its loaded items, pagination +// cursors and scroll position from here instead of refetching from scratch. +// +// Kept deliberately simple: a plain module-level Map that lives for the session. +// No TTL — a snapshot is taken from the page's current state on the way out, so +// it already reflects local mutations (deletes, uploads, tag edits). It is +// dropped on a full reload, and each page validates the snapshot's `resetKey` +// (sort/filter/search) before trusting it, so a stale query never restores. + +export type SectionKey = 'files' | 'tags' | 'categories' | 'pools'; + +interface Snapshot { + /** Scroll offset of the list's scroller at capture time. */ + scrollTop: number; + /** Page-specific state blob; opaque to this module. */ + data: T; + savedAt: number; +} + +const cache = new Map>(); + +export function saveSection(key: SectionKey, scrollTop: number, data: T): void { + cache.set(key, { scrollTop, data, savedAt: Date.now() }); +} + +/** Read and remove a section's snapshot (restore consumes it). */ +export function takeSection(key: SectionKey): { scrollTop: number; data: T } | null { + const snap = cache.get(key) as Snapshot | undefined; + if (!snap) return null; + cache.delete(key); + return { scrollTop: snap.scrollTop, data: snap.data }; +} + +export function clearSection(key: SectionKey): void { + cache.delete(key); +} diff --git a/frontend/src/routes/files/+page.svelte b/frontend/src/routes/files/+page.svelte index 646d3f5..dd72e48 100644 --- a/frontend/src/routes/files/+page.svelte +++ b/frontend/src/routes/files/+page.svelte @@ -1,6 +1,7 @@