obsidian-book-tracker/src/ui/stores/reading-log.svelte.ts

112 lines
2.6 KiB
TypeScript

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<void>;
updateEntry(entry: ReadingLogEntry): Promise<void>;
removeEntry(entry: ReadingLogEntry): Promise<void>;
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<void> {
await readingLog.createEntry(
entry.book,
entry.pagesRead,
entry.pagesReadTotal
);
}
async function updateEntry(entry: ReadingLogEntry): Promise<void> {
await readingLog.updateEntry(entry);
}
async function removeEntry(entry: ReadingLogEntry): Promise<void> {
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);
}