Online-side mutations (e.g. deleting a tag) only update the server, not
IndexedDB, so a throttled background sync could leave the offline cache
stale for up to two minutes. Going offline in that window resurrected
deleted/stale data (e.g. a deleted tag reappearing). Removing the throttle
so every real page load pulls fresh state keeps the offline cache in
sync with whatever was just done online.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The real dashboard is server-rendered before any client JS runs, so
the first page load after reconnecting always reflects the pre-sync
database state -- the background sync then completes silently, but
nothing told that already-rendered page to update. A task created
offline would appear to vanish until the next navigation happened to
load fresh data. runBackgroundSync() now reports whether it pushed
pending changes, and both places that trigger it automatically reload
the page when it did.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Lets users create, edit, and complete tasks with no network connection,
queued locally in IndexedDB and replayed via the existing /api/sync/
protocol once back online -- the same protocol the native Android app
already uses, with zero backend changes. The service worker now routes
the dashboard's offline fallback to a small client-rendered task app
instead of the generic "you're offline" page; every other route keeps
the generic fallback.
Conflicts (server row touched elsewhere since last sync) auto-resolve
as "local wins" rather than surfacing a resolution UI. Scope is title/
status/priority/due-date only -- tags, subtasks, time tracking, and
recurrence editing offline are out of scope for this phase.
Also adds the first real test coverage for sync/views.py (previously
untested): new-item creation, soft-delete-bypasses-conflict-check,
conflict detection/discarding, and both resolve_conflict paths.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Wires up the previously-scaffolded VAPID/DeviceToken infrastructure end
to end: browser subscription flow on the Profile page's existing "Push
Notifications" toggle, a service worker push/notificationclick handler,
and server-side sending from the daily task digest. Also broadens that
digest's eligibility query so push-only users (email notifications off)
aren't silently skipped, and adds `generate_vapid_keys` since the pinned
py-vapid's own key generator is broken against current cryptography.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a manifest, service worker, and branded icons so the site can be
installed to a home screen/desktop, plus an offline fallback page so a
dropped connection shows something friendlier than the browser's default
error. Icons are rasterized from the existing favicon.svg mark via
rsvg-convert. The manifest and service worker are served through small
Django views (not raw static files) so their asset URLs pick up
WhiteNoise's content-hashed filenames in prod/selfhosted, and the service
worker is served from the site root so its scope covers the whole app.
Does not include true offline task data or Web Push notifications --
those are tracked separately as larger follow-up projects.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Recurring tasks were locked to fixed daily/weekly/biweekly/monthly/yearly
intervals. The `custom` recurrence type and `recurrence_rule` field already
existed in the model and API docs, but RRULE evaluation was a TODO stub
that silently fell back to weekly, and no UI exposed the option.
Implements real RRULE parsing via dateutil.rrule, and adds a builder UI
(day-of-week checkboxes for weekly, day-of-month or Nth-weekday for
monthly) so users can express patterns like "every other Wednesday" or
"every second Tuesday" without hand-writing RRULE strings.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Features:
- Django-based REST API with web interface
- Task management with tags, priorities, and due dates
- Time tracking with start/stop timers
- Subtasks support
- Task filtering (all, today, upcoming, overdue, completed)
- Tag-based organization with color coding
- Sorting by due date and priority
- Auto-assign tags when filtering
- Responsive 3-pane layout (sidebar, task list, detail panel)
- Task sharing between users
- Mobile-responsive design with dark mode support
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>