import type { ReadingLog, ReadingLogEntry } from "@utils/ReadingLog"; import { getContext, setContext } from "svelte"; import { createDateFilter, type DateFilterStore } from "./date-filter.svelte"; export interface ReadingLogStore extends DateFilterStore { get entries(): ReadingLogEntry[]; addEntry(entry: ReadingLogEntry): Promise; updateEntry(entry: ReadingLogEntry): Promise; removeEntry(entry: ReadingLogEntry): Promise; destroy(): void; } export function createReadingLog(readingLog: ReadingLog): ReadingLogStore { let entries: ReadingLogEntry[] = $state(readingLog.getEntries()); const dateFilter = createDateFilter( () => entries, (entry) => entry.createdAt, true ); async function addEntry(entry: ReadingLogEntry): Promise { await readingLog.createEntry( entry.book, entry.pagesRead, entry.pagesReadTotal ); } async function updateEntry(entry: ReadingLogEntry): Promise { await readingLog.updateEntry(entry); } async function removeEntry(entry: ReadingLogEntry): Promise { await readingLog.removeEntry(entry); } const loadHandler = readingLog.on("load", (payload) => { entries = payload.entries; }); const createdHandler = readingLog.on("created", (payload) => { entries.push(payload.entry); }); const updatedHandler = readingLog.on("updated", (payload) => { const index = entries.findIndex( (entry) => entry.id === payload.entry.id ); if (index !== -1) { entries[index] = payload.entry; } }); const removedHandler = readingLog.on("removed", (payload) => { const index = entries.findIndex( (entry) => entry.id === payload.entry.id ); if (index !== -1) { entries.splice(index, 1); } }); const sortedData = $derived( dateFilter.filteredData.sort((a, b) => a.createdAt.diff(b.createdAt)) ); return { get entries() { return sortedData; }, get filterYear() { return dateFilter.filterYear; }, set filterYear(value) { dateFilter.filterYear = value; }, get filterMonth() { return dateFilter.filterMonth; }, set filterMonth(value) { dateFilter.filterMonth = value; }, get filterYears() { return dateFilter.filterYears; }, get filterMonths() { return dateFilter.filterMonths; }, addEntry, updateEntry, removeEntry, destroy() { loadHandler.off(); createdHandler.off(); updatedHandler.off(); removedHandler.off(); }, }; } const READING_LOG_KEY = Symbol("readingLog"); export function setReadingLogContext(state: ReadingLogStore) { setContext(READING_LOG_KEY, state); } export function getReadingLogContext(): ReadingLogStore { return getContext(READING_LOG_KEY); }