// Persisted order of search result groups. // // Frontend-only preference, stored in localStorage per the `jellytau-view-mode` // precedent in library.ts — no Rust settings command backs this. // // TRACES: UR-050 | DR-066 import { writable } from "svelte/store"; import { DEFAULT_GROUP_ORDER, moveGroup, normalizeGroupOrder, reorderGroups, type SearchGroupId, } from "$lib/utils/searchScope"; const STORAGE_KEY = "jellytau-search-group-order"; function load(): SearchGroupId[] { if (typeof localStorage === "undefined") return [...DEFAULT_GROUP_ORDER]; try { const raw = localStorage.getItem(STORAGE_KEY); // A corrupt or hand-edited value must not break search rendering. return normalizeGroupOrder(raw ? JSON.parse(raw) : null); } catch { return [...DEFAULT_GROUP_ORDER]; } } function persist(order: SearchGroupId[]) { if (typeof localStorage === "undefined") return; try { localStorage.setItem(STORAGE_KEY, JSON.stringify(order)); } catch { // Quota or private-mode failure — keep the in-memory order. } } function createSearchGroupOrderStore() { const { subscribe, set, update } = writable(load()); return { subscribe, set(order: SearchGroupId[]) { const normalized = normalizeGroupOrder(order); persist(normalized); set(normalized); }, /** Move one group up (-1) or down (+1) — the keyboard-accessible path. */ move(id: SearchGroupId, delta: number) { update((order) => { const next = moveGroup(order, id, delta); persist(next); return next; }); }, /** Drop handler for drag-and-drop reordering. */ reorder(from: number, to: number) { update((order) => { const next = reorderGroups(order, from, to); persist(next); return next; }); }, reset() { const next = [...DEFAULT_GROUP_ORDER]; persist(next); set(next); }, }; } export const searchGroupOrder = createSearchGroupOrderStore();