import { get, writable } from "svelte/store"; import { debounce, WEEKDAYS } from "../utils"; import { taskToThing } from "../models/task"; import { getThingAll, saveSolidDatasetAt, setThing, removeThing, } from "@inrupt/solid-client"; import { fetch } from "@inrupt/solid-client-authn-browser"; import podInfo from "./podInfoStore"; import { addToast } from "./toastStore"; import { DateTime } from "luxon"; const DEBOUNCE_TIME_SYNC = 2000; const taskStore = writable([]); const { update, set, subscribe } = taskStore; const addTask = (task: Omit) => { const podUrl = get(podInfo).podUrl; update(tasks => [ ...tasks, { ...task, id: `${podUrl}/tasks/default#${Date.now()}` }, ]); }; const updateTask = (taskId: string, taskUpdate: Partial) => { update(tasks => tasks.map(task => { if (task.id === taskId) return { ...task, ...taskUpdate }; return task; }) ); if (taskUpdate.done) { const task = get(taskStore).find(item => item.id === taskId); const now = DateTime.now(); const datetime = task?.dueDate ? DateTime.fromJSDate(task.dueDate) : now let weekday = WEEKDAYS[task?.byDay as string]; let dueDate: DateTime | null = null; if (task?.byDay && !task.byMonthWeek) { dueDate = datetime.set({ weekday }); if (dueDate <= now) dueDate = dueDate.plus({ week: 1 }) } else if (task?.byMonthDay) { dueDate = datetime.set({ day: task.byMonthDay }) if (dueDate <= now) dueDate = dueDate.plus({ month: 1 }) } else if (task?.byDay && task?.byMonthWeek) { dueDate = datetime.set({ weekday, weekNumber: task.byMonthWeek }) if (dueDate <= now) dueDate = dueDate.plus({ month: 1 }) } if (dueDate) { console.log(`Tâche replanifiée pour le ${dueDate.toISODate()}`) addTask({ ...task, dueDate: dueDate.toJSDate(), done: false, endTime: undefined }); } } }; const deleteTask = (taskId: string) => { update(tasks => tasks.filter(task => task.id !== taskId)); }; // Sync tasks with pod data let init = false; subscribe( debounce(async (tasks: Task[]) => { if (!init) return (init = true); let taskDataset = get(podInfo).tasksDataset; if (!taskDataset) throw new Error("No tasks dataset. Can't write to pod."); const currentDatasetThings = getThingAll(taskDataset); const updatedDatasetThings = tasks.map(taskToThing); // Add task things to dataset for (const taskThing of updatedDatasetThings) { taskDataset = setThing(taskDataset, taskThing); } // Remove deleted tasks from dataset const removedThings = currentDatasetThings.filter( thing => !updatedDatasetThings.find(thg => thg.url === thing.url) ); for (const removedThing of removedThings) { taskDataset = removeThing(taskDataset, removedThing); } const podUrl = get(podInfo).podUrl; const savedSolidDataset = await saveSolidDatasetAt( `${podUrl}/tasks/default`, taskDataset, { fetch: fetch } ); podInfo.update(store => ({ ...store, tasksDataset: savedSolidDataset })); addToast("Tâches enregistrées vers le pod."); }, DEBOUNCE_TIME_SYNC) ); export default { set, update, subscribe, addTask, updateTask, deleteTask };