Blog · release
Latch 0.16.1
Hands-free, first slice. A refused save never throws your words away, a bout you did earlier is one form, and the page says which bout is which. No schema change, no migration.
- A refused save keeps what you typed (#40). A refusal on a form that carried words (a note,
a reflection, a confession, a reason, a caption) or an answered slider used to flash and
redirect, which brought the page back empty. Now the page it came from comes back with
everything you sent and the reason beside the form (HTTP 422). The kit forms fill themselves
back in on the server; every other form is refilled from the same snapshot by
app.js. A slider you never moved was never sent, so it comes back unanswered. A refusal on a form with nothing typed still redirects, as before. A test walks the route table: every web form that takes words must refuse into a re-render, or say why it can't. - Finishing a bout shows when it started and won't take an end before that. ↶ it all happened earlier — log it as a past bout throws away a bout started now by mistake and writes the real one, from→to, with everything already filled in.
- 📝 Log one from earlier (#41): the items, play or wear, from + to (or from + minutes), how it ended, the questions, a note and anything used, in one submit. It lands at the real times (↶ logged later) in the calendar, the bout list, the hours and the log. Caged comes from the lock at the start, and a bout told more than two days after it ended earns no XP. It refuses an end before the start, and overlap with a still-open bout of the same item. It's the pup's alone, like every kit write.
- Kit says which is which: 🦴 Play is a session that ends somehow; 🧺 Wear is time something is on. Each has now and from earlier.
- Progress → "By activity" is gone (#39). The calendar shows each activity in its own colour, and Trends has the hours per week; the 26-week strips only repeated both.
- The survey slider's "unnamed until moved" script moved from the end page into
app.js, so the new form shares it.