Some checks failed
CI / ci (push) Has been cancelled
Captured from discussion, deliberately undetailed: permission-free contact address picker, Photon-based address autocomplete (would need INTERNET — explicit go/no-go on the no-network promise before any work), inline contact suggestions, attendee editing as its own future milestone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
141 lines
7.0 KiB
Markdown
141 lines
7.0 KiB
Markdown
# 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`) — read `CalendarContract.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 card~~ **cut**: `CalendarContract` exposes no
|
|
`Events.URL` column (only `CUSTOM_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 — `Instances` already
|
|
resolves correct per-occurrence times for display; this only matters for
|
|
editing, so it folds into v2
|
|
- `CATEGORIES`, `ATTACH` — not reliably exposed by `CalendarContract`
|
|
(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_ID` is 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 `BroadcastReceiver` for `EVENT_REMINDER`
|
|
(data scheme `content://com.android.calendar`) — wakes us at reminder time,
|
|
no foreground service.
|
|
- Read `CalendarContract.CalendarAlerts` / `Reminders`, filter to
|
|
`METHOD_ALERT` / `METHOD_DEFAULT` (skip `METHOD_EMAIL`); post on a dedicated
|
|
notification channel; tap opens event detail.
|
|
- `POST_NOTIFICATIONS` runtime 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 — 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_PICK` on 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
|
|
`Attendees` rows touches sync-adapter invitation behavior (Google vs
|
|
DAVx5 differ).
|