Devlog #10
Table of Contents
Devlog — 2026-08-03#
TL;DR#
Sync reliability and widgets dominated the week. Task conflict resolution was rebuilt around version numbers instead of timestamps, closing several silent data-loss bugs (stale overwrites, invisible completions, conflicts that vanished without a dialog). Today’s-tasks home screen widgets shipped on both Android and iOS, plus a new watch complication and iOS quick actions. Also landed: a new ABANDONED task status end-to-end, inline goal editing, and a pile of webapp UI fixes. Three releases (1.8.0 → 1.8.2).
User-facing features#
- New ABANDONED task status: mark a task as deliberately skipped instead of forcing it to DONE or deleting it — kept distinct in history and in recurring series, on both mobile and web.
- Today’s-tasks home screen widgets on Android and iOS (due/overdue tasks plus the daily habit task), with a wide Android widget supporting checkboxes and quick-add. iOS also got StandBy dock support and Home Screen long-press quick actions (add task / start pomodoro / start flow), matching Android’s existing launcher shortcuts.
- watchOS gained a second complication showing the focus task plus due/overdue counts, matching the morning digest.
- Goals: editing moved inline onto the horizon card — no more separate edit sheet or detail screen — with finished tasks and past goals visible right on the card. Webapp goals page reworked to lead with the nearest horizon first and combine the daily-habit card with “also on today’s plate” into one row.
- Task search now surfaces tasks finished in the last 7 days (struck-through, and not selectable where finishing a task wouldn’t make sense), so you can log a session against something just completed.
- iOS Day/Week/Month statistics screen fixed — it was stuck on a permanent loading spinner.
- Several sync bugs that could silently lose or overwrite data are fixed: editing the same task from two devices no longer lets the stale edit win; completions made on one device now reliably show up on others and in Goal Planner history; conflicts caught during background sync now persist and get badged instead of silently disappearing.
- Auth: a temporary server error or rate-limit during sync could throw away a still-valid 30-day refresh token and force a re-login — fixed on both Android and iOS.
- Webapp fixes: quick-add via the “n” key now actually opens the task modal instead of navigating to a dead page; task card action buttons no longer squeeze the title down to a couple words (moved behind an overflow menu, also now usable on touch, not just hover); the keyboard shortcuts panel is readable again (was rendering transparent); a stopped timer no longer gets stuck with no Start button; task creation no longer silently fails when certain reminder options are picked.
Technical improvements#
- Task sync conflict resolution consolidated onto one version-based rule shared across sync paths, replacing two drifted implementations that compared timestamps on one path and versions on another. Conflict state is now persisted to the local database instead of living in memory, so it survives process death and surfaces even for conflicts detected while the app is in the background.
- Backend now exposes task version and completion history over the sync and REST APIs, and fixed several mutation paths that were bumping the edit timestamp but not the version — the gap that let stale clients overwrite newer edits without any conflict being flagged.
- Mobile observability config (trace/log export endpoint and token) now comes from the server instead of being baked into the app build, so rotating credentials no longer requires a release. Android debug builds now actually export traces (previously silently disabled), and mobile logs now ship alongside traces instead of being invisible.
- Network layer now retries on cold-start connection timeouts, not just 5xx/429 responses — closes a gap where a cold backend instance spinning up produced an unhandled error on the first request.
- Reduced Sentry noise: expected 401s hit during token refresh no longer get reported as errors.
- iOS: fixed a stuck-pointer bug where holding the timer’s stop button could cascade into unintended break/skip actions on the button that recomposes underneath it.