Devlog #1
Table of Contents
Devlog — 11 May 2026#
TL;DR — Biggest UX week in a while. Onboarding got rebuilt from scratch with animations that actually show off the app. Task archiving is live end-to-end. Forgot password finally works — and users complete it on pages served directly from the API, no separate frontend required.
User-facing features#
Onboarding rebuilt. New 5-page carousel with a Bauhaus-inspired visual language and animated illustrations — live countdown timer, pulsing watch-sync ripples, a heatmap that randomises itself. First impressions now look like the rest of the app instead of a placeholder from six months ago.
Forgot password flow, end to end. Request a reset link, click it, land on a page the API serves itself, set a new password. Done. The new-password field was also being sent under the wrong key — so anyone who tried this before today got a silent failure. That’s patched.
Task archiving. Completed tasks from prior days auto-archive overnight. Manual archive/unarchive via swipe or the overflow menu. Archived tasks are browsable from the side drawer, grouped by date, with full descriptions on tap. Syncs across devices via the backend.
Swipe gestures redesigned. Right = done. Left = archive. Delete is overflow-menu only now — accidental deletes were a real thing. First-time users get a one-time animated swipe hint so they don’t just stare at the list.
Undo instead of “are you sure?” Archive and delete now show a timed snackbar with undo — four seconds for archive, five for delete. Confirmation dialogs gone.
Task editing quality of life. Attributes row animates out of the way when you’re typing. Overflow menu on each card for quick actions without entering edit mode.
Rectangular watch complication. Session type and time remaining on any watch face that supports the rectangular slot.
Animations throughout. Task removal, stat counter ticks, FAB entrance, loading transitions, shimmer skeleton on first load. Less jarring.
Haptic feedback. Distinct patterns for timer start, pause, and completion.
Context-aware empty states. Task list, statistics, and archive now have actual messaging instead of blank screens.
Accessibility pass. Dynamic content descriptions, properly-sized touch targets, TalkBack navigation across all major screens.
Technical improvements#
Play Integrity attestation. API requests are now verified against Google’s Play Integrity API. Backend middleware rejects calls that fail — android + backend shipped together. Raises the cost of running a spoofed client meaningfully.
Email delivery fixed, twice. Switched to OVH SMTP with per-handshake logging so “why didn’t the email arrive” stops being a black box. Then immediately found that outgoing messages were missing
DateandMessage-IDheaders — some providers were silently dropping them. Both fixed within a day.Sync reliability. Sync events scoped correctly so loading indicators don’t get stuck. Exponential backoff on the sync worker for transient failures. EventBus buffer increased — the old limit was quietly causing main thread stalls under load.
Duplicate timer session guard. Starting a timer while one is already running now silently no-ops. Embarrassingly easy bug to reproduce, embarrassingly late to fix.
Statistics are reactive. Stats screen updates via events instead of polling. Less main-thread work, more accurate numbers post-sync.
Auth interceptor unblocked. Token refresh no longer uses blocking calls on OkHttp’s dispatcher threads — replaced with a thread-safe in-memory cache. Under concurrent requests the old approach was a slow-motion deadlock.
Security: user enumeration hardened. Forgot-password response time is now constant regardless of whether the email exists. One-liner fix.