Commit Graph

6 Commits

Author SHA1 Message Date
Aculix Technologies 00d1e211fe feat: kanban-style drag feedback with a real drop gap
The old feedback was a card faded to 0.4 opacity and a 3px line above the
target. The fade read as "disabled" rather than "held", and a thin line is
a weak signal for where something lands.

The dragged card lifts now: full opacity, accent border, raised shadow, a
small scale and tilt. Cards it passes slide by the space it vacated, which
opens a real gap at the destination. The gap can't disagree with where the
card lands, because it is where the card lands.

Also fixes something found while building it. targetIndexFor measured live
rects, but those rows carry the shift transforms the drag applies, so the
midpoints used to pick the target moved as a result of picking it and the
choice oscillated. Slot geometry is captured once at drag start, relative
to the list so scrolling mid-drag is fine.

The displacement rule moves to src/lib/drag.js with tests. Its up/down
boundaries are where off-by-ones live.
2026-08-16 01:27:44 +05:30
Aculix Technologies 143fcc205d fix: undo no longer swallowed when focus is in the task input
Cmd/Ctrl+Z did nothing in normal use. The handler bailed out whenever the
event target was an input, which was meant to protect the field's own text
undo. But the add-task input is where focus usually sits: you click it to
add a task and stay there, and on macOS clicking a button doesn't move
focus. So the guard killed undo in the one situation it exists for, right
after deleting something.

It now defers to the field only when the field actually holds text. An
empty input has nothing to restore.

The decision moves to src/lib/shortcuts.js as a pure function, because the
inline version couldn't be tested. Shift+Cmd+Z means redo and no longer
triggers an undo.
2026-08-16 01:20:55 +05:30
Aculix Technologies f0fd6c1a65 feat: add pure task operations and bounded undo stack
Task operations become pure functions over arrays.

Ids move from Date.now() to crypto.randomUUID(), with a fallback for
non-secure contexts, since people do self-host this over plain HTTP on a
LAN.

Undo gets its own module so tasks.js stays pure. It covers single deletes
and clear-completed batches, and clamps indices because the list can
change between recording an entry and undoing it.
2026-08-15 23:52:33 +05:30
Aculix Technologies 5ce5b13ecd feat: add day-rollover with multi-day carry-forward
Replaces checkAndMigrateTasks, which never ran. Its guard compared
currentDate, set from new Date() at init, against a fresh new Date() a few
milliseconds later in onMount, so it was never true. Unfinished tasks have
been sitting under old date keys ever since.

The rule now: unfinished tasks from every prior day move into today,
oldest first, ahead of whatever is already there. Completed ones are
dropped and the old key deleted. It spans gaps, which the original never
did even in theory, since it only looked one day back.

now is a parameter. That's the part that makes the boundary testable.
2026-08-15 23:51:36 +05:30
Aculix Technologies d69c68ccef feat: add resilient storage module with legacy key migration
A factory over an injectable backend, so persistence can be tested without
a DOM.

Fixes the unguarded JSON.parse that would white-screen the app on one bad
value, and falls back to memory when localStorage itself throws (Safari
private mode, full quota).

migrateLegacyKeys converts old "Sat Aug 15 2026" keys in place. It's
idempotent, and it leaves anything it can't parse alone rather than
deleting it.
2026-08-15 23:50:20 +05:30
Aculix Technologies e81e7ef8e7 feat: add date-key module with local-time formatting
Switches task keys to ISO YYYY-MM-DD. They sort, so finding every day
before today is a string compare instead of re-parsing each key.

Two things worth knowing. fromKey builds from date parts rather than
parsing a bare ISO string, which gets read as UTC and lands on the wrong
day west of Greenwich. addDays goes through setDate, so it stays on the
same calendar day across a DST change instead of adding a flat 24 hours.
2026-08-15 23:49:29 +05:30