import { resolve } from '$app/paths'; import { browser } from '$app/environment'; import { goto, invalidate } from '$app/navigation'; import { page } from '$app/state'; import { deleteLibrary } from '$lib/api'; import type { Library } from '$lib/schema'; import { getContext, setContext } from 'svelte'; import { toast } from 'svelte-sonner'; export class LibraryState { libraries = $state([]); activeLibrary = $state(undefined); createDialogOpen = $state(false); constructor(libraries: Library[]) { this.libraries = libraries; const activeLibrary = this.libraries.find((lib) => lib.id.toString() === page.params.libraryId); let previousLibrary: Library | undefined; if (browser) { previousLibrary = this.libraries.find( (lib) => lib.id.toString() === localStorage.getItem('previousLibraryId') ); } this.activeLibrary = activeLibrary || previousLibrary || libraries[0]; } async setActive(libraryId: number) { this.activeLibrary = this.libraries.find((lib) => lib.id === libraryId) || this.libraries[0]; if (browser) { localStorage.setItem('previousLibraryId', this.activeLibrary.id.toString()); await goto(resolve('/(root)/(library)/library/[libraryId]/view', { libraryId: String(libraryId) }), { invalidate: ['app:libraries'] }); } } updateLibraries(libraries: Library[]) { this.libraries = libraries; // Update the current library as it may have been removed if (!this.libraries.find((lib) => this.activeLibrary?.id === lib.id)) this.activeLibrary = libraries[0] || undefined; } async deleteLibrary(libraryId: number) { // Store library with its original index const libIndex = this.libraries.findIndex((lib) => lib.id === libraryId); const deletionSnapshot = { library: this.libraries[libIndex], index: libIndex }; // Optimistically delete the library this.libraries = this.libraries.filter((lib) => lib.id !== libraryId); try { // Delete library via API await deleteLibrary(libraryId); toast.success(`Deleted library '${deletionSnapshot.library}'`); } catch (err) { // Delete failed; restore library at its original position this.libraries.splice(deletionSnapshot.index, 0, deletionSnapshot.library); toast.error('Failed to delete library'); console.error('Failed to delete library: ', err); } } addLibrary(library: Library) { this.libraries.push(library); } openLibraryCreateDialog() { this.createDialogOpen = true; } } const LIBRARY_KEY = Symbol('LIBRARY'); export function setLibraryState(libraries: Library[]) { return setContext(LIBRARY_KEY, new LibraryState(libraries)); } export function getLibraryState() { return getContext>(LIBRARY_KEY); }