diff --git a/README.md b/README.md index 70a9f3a..229a950 100644 --- a/README.md +++ b/README.md @@ -98,10 +98,10 @@ The date, storage, rollover, task and undo logic lives in `src/lib/` as plain mo - **Clear input**: Press Escape while the input is focused ### Date Management -- **Switch between Today and Tomorrow**: Click the date button in the header +- **Switch between Today and Tomorrow**: Pick either one in the header. The current day is the highlighted one - **Plan ahead**: Add tasks to Tomorrow's list before you need them - **Separate lists**: Today and Tomorrow maintain independent task lists -- **Carry-over**: When a new day begins, whatever you didn't finish moves into Today. Completed tasks are cleared away with the day they belonged to. It works across gaps too. If you don't open Negotium for a week, everything still outstanding is waiting for you. +- **Carry-over**: When a new day begins, whatever you didn't finish moves into Today, and the app tells you how many tasks it brought forward so they don't look like they appeared from nowhere. Completed tasks are cleared away with the day they belonged to. It works across gaps too. If you don't open Negotium for a week, everything still outstanding is waiting for you. - **While it's open**: The app notices the day change on its own, so a tab left open overnight rolls over without a reload. ### Installing It diff --git a/src/App.svelte b/src/App.svelte index ebca6dc..0f0a80f 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -5,7 +5,7 @@ import { cubicOut } from 'svelte/easing'; import './style.css'; - import { toKey, addDays, fromKey, labelFor, formatLong } from './lib/dates.js'; + import { toKey, addDays, fromKey, formatLong } from './lib/dates.js'; import { createStorage } from './lib/storage.js'; import { rollover, msUntilNextMidnight } from './lib/rollover.js'; import * as taskOps from './lib/tasks.js'; @@ -24,7 +24,19 @@ storage.migrateLegacyKeys(); const bootNow = new Date(); + const bootTodayKey = toKey(bootNow); + const beforeRollover = storage.loadTasks(bootTodayKey).length; + let tasks = $state(rollover(storage, bootNow)); + + /** How many unfinished tasks were pulled forward from earlier days on this + * load. The app's cleverest behaviour used to happen in complete silence, + * so returning after a weekend looked like a bug rather than a feature. */ + let carriedOver = $state(Math.max(0, tasks.length - beforeRollover)); + + function dismissCarriedOver() { + carriedOver = 0; + } let newTask = $state(''); // Seeded from the class the pre-paint script in index.html already set, so // there is one source of truth and no post-mount correction to flash. @@ -474,9 +486,11 @@ return toKey(addDays(fromKey(todayKey), 1)); } - function switchDate() { + function showDay(key) { + if (key === selectedKey) return; cancelEdit(); - selectedKey = selectedKey === todayKey ? tomorrowKey() : todayKey; + dismissUndo(); + selectedKey = key; tasks = storage.loadTasks(selectedKey); } @@ -494,7 +508,10 @@ const wasViewingToday = selectedKey === todayKey; todayKey = toKey(now); + const before = storage.loadTasks(todayKey).length; const todayTasks = rollover(storage, now); + const moved = todayTasks.length - before; + if (moved > 0) carriedOver = moved; if (wasViewingToday) { selectedKey = todayKey; @@ -521,7 +538,6 @@ } const currentDateDisplay = $derived(formatLong(selectedKey)); - const buttonText = $derived(labelFor(selectedKey, todayKey)); const remainingTasks = $derived(tasks.filter(task => !task.completed).length); const completedTasks = $derived(tasks.filter(task => task.completed).length); @@ -571,15 +587,26 @@