✨ Remove task
Tim Izzo tim@octree.ch
Sun, 02 Feb 2025 18:08:55 +0100
4 files changed,
75 insertions(+),
7 deletions(-)
M
src/lib/components/TaskItem.svelte
→
src/lib/components/TaskItem.svelte
@@ -2,6 +2,7 @@ <script lang="ts">
import type { FormEventHandler } from "svelte/elements"; import tasksStore from "../store/tasksStore"; import { debounce } from "../utils"; + import { getShortcutActions } from "./taskShortcuts.svelte"; let { task }: { task: Task } = $props();@@ -11,7 +12,8 @@
const onUpdateName: FormEventHandler<HTMLDivElement> = event => { const element = event.target as HTMLElement; const newValue = element.innerText?.trim(); - tasksStore.updateTask(task.id, { name: newValue }); + if (newValue) tasksStore.updateTask(task.id, { name: newValue }); + else tasksStore.deleteTask(task.id); }; const onUpdateDone: FormEventHandler<HTMLInputElement> = e => {@@ -27,6 +29,16 @@ let dueDate;
if (rawDate) dueDate = new Date(rawDate); tasksStore.updateTask(task.id, { dueDate }); }; + + const onDelete = () => { + tasksStore.deleteTask(task.id); + }; + + const { onKeyDown, onKeyUp } = getShortcutActions({ + x: onDelete, + Backspace: onDelete, + l: () => console.log({ task }), + }); </script> <li class="list-row flex items-center gap-4 p-2" id={task.id}>@@ -38,10 +50,13 @@ onchange={onUpdateDone}
/> <div class="flex w-full justify-between"> <div + role="form" contenteditable autocorrect="off" oninput={debounce(onUpdateName, 750)} class:line-through={task.done} + onkeydown={onKeyDown} + onkeyup={onKeyUp} > {@html parseContent(task.name)} </div>@@ -51,7 +66,7 @@ value={task.dueDate?.toISOString().split("T")[0]}
onchange={onUpdateDueDate} class:text-red-400={task.dueDate && task.dueDate < new Date()} class:text-primary={task.dueDate && task.dueDate >= new Date()} - class="rounded px-1" + class="rounded px-1 h-fit" /> </div> </li>
A
src/lib/components/taskShortcuts.svelte.ts
@@ -0,0 +1,37 @@
+type Actions = Record<string, () => void>; + +export const getShortcutActions = (actions: Actions) => { + let isCtrlDown = $state(false); + let isAltDown = $state(false); + let actionKey = $state(""); + + const onKeyDown = event => { + switch (event.key) { + case "Control": + isCtrlDown = true; + break; + case "Alt": + isAltDown = true; + break; + default: + if (isCtrlDown && isAltDown) { + actionKey = event.key; + console.log("ACTION APPLY", actionKey); + actions[actionKey]?.(); + } + } + }; + + const onKeyUp = event => { + switch (event.key) { + case "Control": + isCtrlDown = false; + break; + case "Alt": + isAltDown = false; + break; + } + }; + + return { onKeyDown, onKeyUp }; +};
M
src/lib/store/tasksStore.ts
→
src/lib/store/tasksStore.ts
@@ -1,7 +1,12 @@
import { get, writable } from "svelte/store"; import { debounce } from "../utils"; import { taskToThing } from "../models/task"; -import { saveSolidDatasetAt, setThing } from "@inrupt/solid-client"; +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";@@ -39,9 +44,20 @@
let taskDataset = get(podInfo).tasksDataset; if (!taskDataset) throw new Error("No tasks dataset. Can't write to pod."); - for (const task of tasks) { - const thing = taskToThing(task); - taskDataset = setThing(taskDataset, thing); + 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;
M
src/pages/Home.svelte
→
src/pages/Home.svelte
@@ -49,7 +49,7 @@ }
}); </script> -<main class="w-xl max-w-full mx-auto p-4"> +<main class="w-3xl max-w-full mx-auto p-4"> {#if sessionInfo.isLoggedIn} <div class="flex justify-between"> <h1 class="text-2xl mb-4">kōi</h1>