From 39cc70be95068e5301c76866df7a9561f0971fec Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Mon, 20 Jul 2026 19:10:08 +0200 Subject: [PATCH] fix(month): keep the split selection inside the month that owns it (#53) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The marker could still be caught fading in on the outgoing page. Paging changes the selection immediately but the state only once the new month has loaded, so until then the content key — the state's month — is unchanged and AnimatedContent updates the page *in place*: the old grid really was told the next month's 1st was selected, and it shows that date among its trailing days. A page now marks only the days its own month owns. Selection always lands inside the month it belongs to, so nothing legitimate is lost, and the phantom goes without timing the fade against the page transition — a delay would have moved it rather than removed it, and slowed selecting a day within a page besides. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../calendula/ui/month/MonthScreen.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/month/MonthScreen.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/month/MonthScreen.kt index 4c9badf..ffde964 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/month/MonthScreen.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/month/MonthScreen.kt @@ -946,12 +946,22 @@ internal fun SplitMonthGrid( ) } week.days.forEach { day -> + val inMonth = day.month == month.month && day.year == month.year SplitDayCell( date = day, events = state.instancesByDay[day].orEmpty(), isToday = day == state.today, - isSelected = day == selected, - inMonth = day.month == month.month && day.year == month.year, + // A page marks only the days its own month owns. Paging + // moves the selection before this month's replacement + // has loaded, so for a moment the grid is asked to mark + // the *next* month's 1st — a date it shows among its + // trailing days, where the marker would fade in just + // before the page slid away. Selection always lands + // inside the month it belongs to, so scoping it here + // removes that without timing anything against the + // page transition. + isSelected = day == selected && inMonth, + inMonth = inMonth, dark = dark, onClick = { onSelectDay(day) }, modifier = Modifier.weight(1f).fillMaxHeight(),