Combines #470 and #471 into one PR. ## Midnight-to-midnight events (#296) A timed event that starts and ends on local midnight now displays as an all-day event: - Day/week: in the all-day strip instead of the time grid. - Month and month widget: a bar with no start time. - Agenda and agenda widget: "All day". - Sorting: with the all-day events. - Countdown widget: skipped in next-event mode like other all-day events, with the all-day label when pinned. - Reminder notification: the text names the day(s) instead of 00:00 – 00:00. The event itself stays timed. The detail sheet still shows 00:00 – 00:00, and reminders still fire at their own lead time before 00:00, since that is what the stored reminder says. Midnight is checked in the device zone, so a feed event stored as 22:00Z only counts as whole-day at UTC+2. Search results are left as they are. Dragging or resizing a block in the timeline so it lands exactly on midnight to midnight moves it to the all-day strip. The floating copy and the selection are dropped right away. Display priority is now computed once per event, not on every sort comparison. ## Event status (#388) The calendar views now use the event's own status (Events.STATUS), not just your reply to an invite: - Cancelled events are struck through and sorted last, the same as declined invites. This applies to day/week, month, agenda, search and the widgets. The countdown widget skips them in both modes, and the week-strip widget leaves them out of its count and dots. - Tentative events get the outline used for unanswered invites (in-app grids). An event that is both cancelled and an open invite is struck through, not outlined. - Cancelled standalone events and cancelled series are no longer hidden. Cancelled exception rows (a single occurrence deleted from a series) are still filtered out, matched by ORIGINAL_ID or ORIGINAL_SYNC_ID. - The editor has a new optional Status field after Availability, built on floret-kit's new `SegmentedChoiceCard` (Availability uses it too). A new event writes STATUS only when it isn't Confirmed, an edit writes it only when it changed. - `isDeclined` was renamed to `isCrossedOut`, and a new `isOutlined` covers both cases. Deviations from the issue: - The editor offers Confirmed and Tentative only. Cancelled is offered only for an event that's already cancelled, so it can be put back. Google treats a cancelled event as deleted, so letting people pick it would silently delete Google events. - A cancelled series can't be edited or moved one occurrence at a time. "Only this event" is left out of the scope prompts, because Android saves a cancelled single occurrence as a deleted one. A drag that could only move the single occurrence is refused. - The widgets don't draw outlines for unanswered invites either, so tentative events look filled there. Depends on jlmakiola/floret-kit#27. The submodule is pinned to its branch, so that PR has to land on floret-kit main and the pin has to be moved before release. Closes #296 Closes #388 Co-authored-by: Jean-Luc Makiola <business@jeanlucmakiola.de> Reviewed-on: https://codeberg.org/jlmakiola/calendula/pulls/472
Documentation map
Where to look for what:
| Document | What it is |
|---|---|
../CONTRIBUTING.md |
How to contribute: issue-first workflow, which branch to target, translations, the rules a change is reviewed against |
BUILDING.md |
Building from source: submodule, JDK/SDK requirements, Gradle tasks, what CI runs |
ARCHITECTURE.md |
Orientation tour: principles, layers, navigation, recurring-write / conflict / reminder pipelines, testing |
RELEASING.md |
Release process: versioning, the merge-driven pipeline, the two-forge split, secrets, key custody |
../CHANGELOG.md |
Release history (Keep a Changelog, SemVer) |
| Issues + milestones | The roadmap: what's planned, in progress and shipped. A milestone maps to its release/vX.Y.Z branch |
../.planning/PROJECT.md |
What the project is: core value, stack + version pins, constraints, naming, forge/release infrastructure |
design/ |
Per-feature design notes kept for features whose provider behaviour is worth recording |
../fastlane/metadata/android/ |
Store metadata (single source of truth) for every app language, mapped in store-locales.txt: descriptions, title, graphics. Harvested directly by the official F-Droid repo, pushed to Google Play with every release, validated by ../scripts/check_store_listing.py; transformed into the self-hosted repo layout at release time by ../scripts/fastlane_to_fdroid_localized.sh |
../fdroid-metadata/ |
App-level F-Droid control file (*.yml: Categories, License, links) for the self-hosted repo's fdroid update |
fdroid-official/ |
Recipe and notes for publishing to the official F-Droid repo (reproducible build + developer-signed binary) |
Planning lives in the issue tracker and its milestones, not in this repository.
.planning/PROJECT.md describes the project itself.
ARCHITECTURE.md is updated with the code and is the place to record a lesson
learned about the calendar provider.