Files
calendula/app/src
Jean-Luc Makiolaandmakiolaj 90245b6893
Beta — Codeberg pre-release / detect (push) Successful in 6s
Beta — Codeberg pre-release / beta (push) Skipped
Midnight-to-midnight events as all-day, and event status (#296, #388) (#472)
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
2026-11-03 14:13:35 +01:00
..