diff --git a/README.md b/README.md index 94b4407..70a9f3a 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Built with Svelte for speed and simplicity. No overwhelming features, no endless ### Core Functionality - ✅ **Add, complete, and delete tasks** with smooth animations -- ↩️ **Undo** - `Cmd/Ctrl+Z` brings back a deleted task, in its original position +- ↩️ **Undo** - Deleted something by mistake? An Undo button appears, and `Cmd/Ctrl+Z` works too. The task returns to its original position - 📅 **Today & Tomorrow lists** - Plan ahead with separate task lists - 🔄 **Unfinished work carries over** - When a new day begins, tasks you didn't finish move to Today; completed ones are cleared away - ✏️ **Edit a task** - Fix a typo without deleting and retyping it @@ -92,7 +92,7 @@ The date, storage, rollover, task and undo logic lives in `src/lib/` as plain mo - **Complete a task**: Click the checkbox next to the task - **Edit a task**: Click its text. Enter saves, Escape cancels, and clicking away saves too - **Delete a task**: Click the delete icon on the task (it shows on hover, and is always visible on touch), or press `Delete` with the task focused -- **Undo a delete**: Press `Cmd/Ctrl+Z`. The task returns to where it was +- **Undo a delete**: An Undo button appears for a few seconds after anything is removed. `Cmd/Ctrl+Z` does the same. Either way the task returns to where it was - **Move a task to Tomorrow**: Click the arrow on the task, or press `Alt+→`. From Tomorrow, the arrow points back and `Alt+←` returns it to Today - **Reorder tasks**: Drag with a mouse, long-press then drag on touch, or focus a task and press `Alt+↑`/`Alt+↓` - **Clear input**: Press Escape while the input is focused diff --git a/src/App.svelte b/src/App.svelte index 246e3ee..ebca6dc 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -62,6 +62,7 @@ if (index === -1) return; undoStack.push({ type: 'delete', task: tasks[index], index }); setTasks(taskOps.deleteTask(tasks, id)); + showUndo('Task deleted'); } function clearCompleted() { @@ -74,6 +75,7 @@ if (removed.length === 0) return; undoStack.push({ type: 'clearCompleted', removed }); setTasks(taskOps.clearCompleted(tasks)); + showUndo(removed.length === 1 ? '1 completed task cleared' : `${removed.length} completed tasks cleared`); } const viewingToday = $derived(selectedKey === todayKey); @@ -129,9 +131,35 @@ tasks = moveTaskToDay(storage, selectedKey, destination, taskId); } + /** + * Undo used to be reachable only by Cmd/Ctrl+Z, which nothing announced and + * which does not exist on a phone at all. This is the one moment it is worth + * saying something: right after work disappears. It carries the shortcut too, + * so a keyboard user learns it once, here, rather than from a README. + */ + let undoNotice = $state(null); + let undoNoticeTimer = null; + + const UNDO_NOTICE_MS = 7000; + const shortcutLabel = /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent) + ? '\u2318Z' + : 'Ctrl+Z'; + + function showUndo(message) { + undoNotice = message; + clearTimeout(undoNoticeTimer); + undoNoticeTimer = setTimeout(() => { undoNotice = null; }, UNDO_NOTICE_MS); + } + + function dismissUndo() { + clearTimeout(undoNoticeTimer); + undoNotice = null; + } + function undo() { const entry = undoStack.pop(); if (entry) setTasks(applyUndo(tasks, entry)); + dismissUndo(); } function toggleTheme() { @@ -736,3 +764,12 @@ + +{#if undoNotice} +