README gains a real install path: add the self-hosted repo (apps.dev.jeanlucmakiola.de/dev/fdroid/repo, fingerprint inline and as an add-repo link), search, install. Verified live against the repo index. Roadmap gains the approved daily-driver idea backlog (unscheduled): slot-tap create, drag & drop rescheduling, agenda view, pinch-zoom, reminder snooze/dismiss + default reminder, duplicate event, per-event color, .ics share/receive, app shortcuts, jump-to-date — plus the consciously rejected list (network-dependent features, NL quick entry). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8.2 KiB
Calendula — Roadmap
v0.x — Pre-Release
| Version | Milestone | Status |
|---|---|---|
| v0.1 | Foundation & CI | complete |
| v0.2 | Data Layer & Permission Flow | complete |
| v0.3 | Month + Week + Day views, view switcher | complete |
| v0.4 | Event Detail (S4) + humanized recurrence | complete |
| v0.5 | Calendar filter (M3) + Settings (M4) | complete |
| v0.6 | Full event read — surface every readable field | complete |
| v1.0 | First public release — polish pass, F-Droid | complete |
Delivery ran ahead of the original table: Day view (S3) shipped in v0.3 and Event Detail (S4) in v0.4, so the Filter/Settings milestone became v0.5.
Jump-to-date (the date-picker half of M2) was cut from scope and will not ship. The "Today" half of M2 already shipped in v0.5 (drawer entry).
v0.6 — Full event read
Round out the read-only model so a detail view shows everything the system
actually stores, before write support starts. Scope = CalendarContract
columns we don't yet read/display:
- Reminders (
VALARM) — readCalendarContract.Reminders, list lead times - Status — Confirmed / Tentative / Cancelled (cancelled shown struck-through)
- Availability (
TRANSP) — Free / Busy chip - Attendee extras — role (required / optional / organizer) + the user's own
SELF_ATTENDEE_STATUS - Timezone (
EVENT_TIMEZONE) — shown only when it differs from the device zone - URL —
tappable link cardcut:CalendarContractexposes noEvents.URLcolumn (onlyCUSTOM_APP_URI, an originating-app deep-link). URLs are instead surfaced by linkifying the description text - Access level / class (private / confidential) — small chip (optional, trivial)
All of the above shipped in v0.6.0 (2026-06-11).
Deliberately out of v0.6:
- Recurrence exception / modified-occurrence badges —
Instancesalready resolves correct per-occurrence times for display; this only matters for editing, so it folds into v2 CATEGORIES,ATTACH— not reliably exposed byCalendarContract(provider limitation, not our choice)
v1.0 — First Public Release — shipped 2026-06-11
All V1 features shipped, polished, on F-Droid. Read-only calendar. Cut directly after v0.6 (full event read) plus the onboarding-screen polish pass.
Polish backlog (pre-1.0)
Redesign the initial grant-access (permission) screen— done (Material 3 Expressive onboarding, shipped in v0.6.0 / v1.0.0)
v2.0 — Write Support (complete, shipped 2026-06-11)
Delivered in four releasable slices (plan:
docs/superpowers/plans/2026-06-11-03-write-support.md). The V1 spec is a
guide here, not a contract — scope per slice is decided as we go.
| Version | Milestone | Status |
|---|---|---|
| v1.1 | Write foundation — WRITE_CALENDAR, read-only-calendar detection, delete (series + single occurrence) |
complete (shipped 2026-06-11) |
| v1.2 | Create event — form, FAB, last-used-calendar preselect | complete (shipped 2026-06-11) |
| v1.2.1 | Form polish after on-device review — card design system, optional fields + settings defaults, OptionCard dialogs, expressive motion | complete (shipped 2026-06-11) |
| v1.3 | Edit event — shared form, scoped recurring writes (this / following / all), recurrence picker | complete (shipped 2026-06-11) |
| v1.4 | Reminder notifications — see below | complete (shipped 2026-06-11) |
| v2.0 | Conflict dialog, polish pass (store copy refresh, F-Droid screenshots), release | complete (shipped 2026-06-11) |
v2.0 scope was re-cut on 2026-06-11, after v1.4:
- Occurrence edit already shipped early, in v1.3.
- Quick-add is cut from scope: the full form already opens prefilled (visible day, last-used calendar, optional fields hidden), so the sheet would only save one screen transition while adding a second create-surface to maintain. Revisit only if real-world feedback says creation feels heavy.
- Calendar switching while editing moves to the v3 backlog (sync-adapter
minefield:
CALENDAR_IDis sync-adapter-owned, AOSP locks the field; an honest implementation is copy+delete like Google Calendar, with sync-identity and attendee side effects). - Conflict dialog stays (plan 03, decision 5): on save, compare against the row as it was when the form loaded; on external change, ask overwrite / discard. Closes the silent-clobber gap on synced calendars.
v1.4 — Reminder Notifications
Essential, not nice-to-have: Calendula targets users for whom it is their
only calendar app, so reminder delivery can't be delegated to Google/OEM
Calendar. The calendar provider schedules reminders and broadcasts
android.intent.action.EVENT_REMINDER, but it does not post the visible
notification — a calendar app must. We become that app (the Etar model).
Scope:
- Manifest-registered
BroadcastReceiverforEVENT_REMINDER(data schemecontent://com.android.calendar) — wakes us at reminder time, no foreground service. - Read
CalendarContract.CalendarAlerts/Reminders, filter toMETHOD_ALERT/METHOD_DEFAULT(skipMETHOD_EMAIL); post on a dedicated notification channel; tap opens event detail. POST_NOTIFICATIONSruntime permission (API 33+) — requested in onboarding.- Onboarding step: (a) request
POST_NOTIFICATIONS, (b) in-app reminders toggle, default ON, with copy warning that a second calendar app with notifications on will cause duplicate reminders. Mirrored into Settings (reversible).
Deliberately deferred (add only if needed):
- Snooze / dismiss notification actions (Etar has them)
- Battery-optimization exemption prompt for delivery reliability
v3.0 — Power-User Features
- Home-screen widget
- Full-text search
- Tablet / foldable layouts
- Optional: ICS file import (drag-and-drop)
- Optional: move event to another calendar (copy+delete model with a consequences warning — deferred from v2.0, see above)
Order is indicative — community feedback after V1 may re-prioritize.
Idea backlog — Daily-driver polish (captured 2026-06-11, all approved as ideas, unscheduled)
Interaction:
- Tap/long-press an empty slot in day/week → create form prefilled with that time
- Drag & drop rescheduling in day/week (recurring drops reuse the scope dialog) — big-ticket, own slice
- Agenda view (fourth view: upcoming events grouped by day; natural widget data source)
- Pinch-to-zoom time scale in day/week
Reminders, round two:
- Snooze + dismiss actions on the notification (snooze needs an exact-alarm/WorkManager decision)
- Settings default reminder applied to new events
Event niceties:
- Duplicate event (detail action → prefilled create form)
- Per-event color (
Events.EVENT_COLOR, OptionCard picker in the form) - Share event as .ics + open/receive .ics into a prefilled create form (front-runs v3 ICS import)
Small delights:
- App shortcuts (launcher long-press → New event), maybe a quick-settings tile
- Jump to date (un-cut from V1 — drawer date picker)
Consciously rejected: travel time / weather / smart suggestions (network, core-promise conflict), natural-language quick entry (high effort, locale-fragile, prefilled form already covers fast entry).
Idea backlog — Locations & People (captured 2026-06-11, undecided)
Beyond classic calendar-client scope; discussed, deliberately not planned in detail yet:
- Contact address picker for the location field via the system picker
(
ACTION_PICKon postal addresses) — one-shot, needs no READ_CONTACTS, fits the privacy story. Same mechanism later for picking emails. - OSM address autocomplete in the location field (type "Brandenburger Tor" → tap suggestion → resolved address inserted). Backend would be Photon (Nominatim's public policy forbids autocomplete). Requires the INTERNET permission — first dent in the "no network access" promise; if built: opt-in (off by default), honest copy, configurable endpoint for self-hosters, onboarding footnote + F-Droid copy reworded. This trade-off is an explicit go/no-go decision before any work starts.
- Inline contact suggestions while typing (needs READ_CONTACTS) — only if the picker proves clunky.
- Attendee editing / invites from contacts — own milestone; writing
Attendeesrows touches sync-adapter invitation behavior (Google vs DAVx5 differ).