Code-review follow-up.
- The multi-day expansion in groupAgendaDays is shared with the agenda
widget, but only the screen's summary was made day-aware — so the
widget rendered the raw "start – end" on every spanned day, the very
bug the screen fix cured. Hoist a pure agendaTimeLabel(event, day,
zone) into the shared agenda layer and resolve strings from it in both
the screen and the widget, so they label identically. (findings 1, 2)
- groupAgendaDays could silently drop an instance whose clamped span was
empty (firstDay > lastDay); floor lastDay at firstDay so a returned
instance always surfaces on at least its first visible day. (finding 3)
- agendaTimeLabel resolves the span days once instead of the summary
recomputing them 2–3× per row. (finding 5)
Finding 4 (within-day sort) needs no change: sorting by absolute start
already places a still-running multi-day event at the top of each day it
continues into, which is chronologically correct (it is ongoing from
that day's midnight), and at its real start time on its first day.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review follow-up. spanFirstDay/spanLastDay resolved every event in the
device zone, but all-day events live at UTC midnights with an exclusive
end — east of UTC (e.g. Europe/Berlin) that pushed spanLastDay onto the
next day, so a single-day all-day event reported spansMultipleDays and
leaked onto a second agenda day. Resolve all-day dates in UTC, matching
the Week view and detail card. Adds eastern-zone regression tests that
the prior UTC-only tests could not catch.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The "→" arrow convention read as unclear. Spell each day out instead:
the first day names the start ("Starts 14:00"), the last day the end
("Ends 10:00"), and whole days in between read as "All day". All-day
multi-day events stay "All day" on every day. Single-day rows unchanged.
Adds agenda_span_starts / agenda_span_ends (owes Weblate backfill).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A multi-day event repeated the same "start – end" on every day it spans
("14:00 – 14:00"), which reads as meaningless. Show only the part
relevant to each day, with a "→" marking that it carries past the day's
boundary: the first day shows the start ("14:00 →"), the last day the
end ("→ 10:00"), and whole days in between an all-day span arriving from
and continuing into their neighbours ("→ All day →"). Single-day rows are
unchanged.
Factors the span first/last-day resolution into shared EventInstance
helpers reused by groupAgendaDays and the label.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A multi-day event now appears under every day it spans, so keying its
row by instanceId alone repeated the key across days and crashed the
LazyColumn ("Key already used") on scroll. Scope the key by day.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
groupAgendaDays keyed each instance by its start day alone, so a
multi-day event surfaced only on its first day and vanished from the
rest of its span in both the Agenda screen and the agenda widget.
Expand each instance across every day from its start (clamped to the
anchor for ongoing events) through its last occupied day, bounded by the
visible window end. An event ending exactly at midnight — including the
exclusive next-midnight all-day events end at — does not reach that
boundary day.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>