Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5c4a73de1 |
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [2.23.1] — 2026-10-28
|
||||
|
||||
### Changed
|
||||
- **The split month view fits more events.** With a day selected, its date is no longer shown twice: the filter chip now stands in for the day's header. Tapping the chip opens the day, and its ✕ clears the filter. The day headers in the month agenda below the grid take less room too ([#142]).
|
||||
|
||||
### Fixed
|
||||
- **Event dots in the split month grid stay in place on busy days.** A day with a "+N" next to its dots used to push them further down the cell ([#142]).
|
||||
|
||||
## [2.23.0] — 2026-10-21
|
||||
|
||||
### Added
|
||||
|
||||
@@ -32,8 +32,8 @@ android {
|
||||
// (up to 2.22.3: 2.22.3 -> 22203; from 2.22.4: 2.23.0-beta.1 -> 2230001,
|
||||
// 2.22.4 -> 2220499), and CI fails if the committed one doesn't match.
|
||||
// See docs/RELEASING.md.
|
||||
versionCode = 2230099
|
||||
versionName = "2.23.0"
|
||||
versionCode = 2230199
|
||||
versionName = "2.23.1"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
@@ -59,11 +59,16 @@ import java.util.Locale
|
||||
// split style can list a day with exactly the same visual language instead of
|
||||
// growing a parallel set of event rows.
|
||||
|
||||
/**
|
||||
* A day's header; tapping it opens the Day view. [compact] trims the padding for
|
||||
* the month view's split pane, where vertical space is short (#142).
|
||||
*/
|
||||
@Composable
|
||||
internal fun AgendaDayHeader(
|
||||
date: LocalDate,
|
||||
today: LocalDate,
|
||||
onOpenDay: (LocalDate) -> Unit,
|
||||
compact: Boolean = false,
|
||||
) {
|
||||
Surface(
|
||||
color = MaterialTheme.colorScheme.surface,
|
||||
@@ -79,7 +84,12 @@ internal fun AgendaDayHeader(
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurfaceVariant
|
||||
},
|
||||
modifier = Modifier.padding(start = 28.dp, end = 28.dp, top = 16.dp, bottom = 8.dp),
|
||||
modifier = Modifier.padding(
|
||||
start = 28.dp,
|
||||
end = 28.dp,
|
||||
top = if (compact) 8.dp else 16.dp,
|
||||
bottom = if (compact) 4.dp else 8.dp,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -220,10 +230,11 @@ internal fun LazyListScope.agendaDays(
|
||||
dimmed: (EventInstance, LocalDate) -> Boolean,
|
||||
onOpenDay: (LocalDate) -> Unit,
|
||||
onEventClick: (EventInstance) -> Unit,
|
||||
compact: Boolean = false,
|
||||
) {
|
||||
days.forEach { day ->
|
||||
stickyHeader(key = "header-${day.date}") {
|
||||
AgendaDayHeader(date = day.date, today = today, onOpenDay = onOpenDay)
|
||||
AgendaDayHeader(date = day.date, today = today, onOpenDay = onOpenDay, compact = compact)
|
||||
}
|
||||
if (day.events.isEmpty()) {
|
||||
item(key = "placeholder-${day.date}") {
|
||||
@@ -251,6 +262,6 @@ internal fun LazyListScope.agendaDays(
|
||||
)
|
||||
}
|
||||
}
|
||||
item(key = "gap-${day.date}") { Spacer(Modifier.height(8.dp)) }
|
||||
item(key = "gap-${day.date}") { Spacer(Modifier.height(if (compact) 4.dp else 8.dp)) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
@@ -157,10 +158,9 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import de.jeanlucmakiola.calendula.R
|
||||
import de.jeanlucmakiola.calendula.domain.EventInstance
|
||||
import de.jeanlucmakiola.calendula.domain.hasEnded
|
||||
import de.jeanlucmakiola.calendula.ui.agenda.AgendaDayHeader
|
||||
import de.jeanlucmakiola.calendula.ui.agenda.agendaDayLabel
|
||||
import de.jeanlucmakiola.calendula.ui.agenda.AgendaEmptyDayRow
|
||||
import de.jeanlucmakiola.calendula.ui.agenda.AgendaEventRow
|
||||
import de.jeanlucmakiola.calendula.ui.agenda.agendaDayLabel
|
||||
import de.jeanlucmakiola.calendula.ui.common.formatCalendarTitle
|
||||
import de.jeanlucmakiola.calendula.ui.common.AppBarSpacing
|
||||
import de.jeanlucmakiola.calendula.ui.common.CalendarFailure
|
||||
@@ -1423,24 +1423,13 @@ private fun SplitMonthCollapsed(
|
||||
.then(paneModifier)
|
||||
.then(rememberSplitPaneSwipe(onPaneSwipeNext, onPaneSwipePrev)),
|
||||
) {
|
||||
InputChip(
|
||||
selected = true,
|
||||
onClick = onClearSelection,
|
||||
label = { Text(agendaDayLabel(selected, state.today)) },
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
Icons.Default.Close,
|
||||
contentDescription = stringResource(R.string.month_split_clear_filter),
|
||||
)
|
||||
},
|
||||
modifier = Modifier.padding(start = 16.dp),
|
||||
)
|
||||
SplitDayPane(
|
||||
date = selected,
|
||||
today = state.today,
|
||||
events = state.instancesByDay[selected],
|
||||
zone = state.zone,
|
||||
onOpenDay = onOpenDay,
|
||||
onClearSelection = onClearSelection,
|
||||
onEventClick = onEventClick,
|
||||
onCreateEvent = onCreateEvent,
|
||||
modifier = Modifier.weight(1f).fillMaxWidth(),
|
||||
@@ -1814,7 +1803,10 @@ private fun SplitDots(
|
||||
if (events.isEmpty()) return
|
||||
val soften = LocalSoftenColors.current
|
||||
val dimCutoff = LocalDimCutoff.current
|
||||
// Held to the dots' height so a "+N" doesn't grow the row and push the dots
|
||||
// down; the label overflows it evenly instead (#142).
|
||||
Row(
|
||||
modifier = Modifier.height(SPLIT_DOT_SIZE),
|
||||
horizontalArrangement = Arrangement.spacedBy(2.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
@@ -1849,6 +1841,7 @@ private fun SplitDots(
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier
|
||||
.wrapContentHeight(unbounded = true)
|
||||
.morphBounds(MonthMorphKey.Overflow(date))
|
||||
.alpha(if (allEnded(hidden, date, dimCutoff)) EventDimAlpha else 1f),
|
||||
)
|
||||
@@ -1872,7 +1865,7 @@ private fun SplitMonthAgendaPane(
|
||||
.sorted()
|
||||
val dimCutoff = LocalDimCutoff.current
|
||||
val listState = key(state.month) { rememberLazyListState() }
|
||||
LazyColumn(state = listState, contentPadding = PaddingValues(top = 8.dp, bottom = 96.dp)) {
|
||||
LazyColumn(state = listState, contentPadding = PaddingValues(top = 4.dp, bottom = 96.dp)) {
|
||||
agendaDays(
|
||||
days = days.map { AgendaDay(it, state.instancesByDay[it].orEmpty()) },
|
||||
today = state.today,
|
||||
@@ -1882,6 +1875,7 @@ private fun SplitMonthAgendaPane(
|
||||
dimmed = { event, day -> dimCutoff != null && event.isPastOn(day, dimCutoff) },
|
||||
onOpenDay = onOpenDay,
|
||||
onEventClick = onEventClick,
|
||||
compact = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1889,7 +1883,8 @@ private fun SplitMonthAgendaPane(
|
||||
/**
|
||||
* The selected day's events, in the agenda's own row vocabulary so the two
|
||||
* surfaces read as one app. The date header opens the full Day view, matching
|
||||
* the Week and Agenda headers (#37).
|
||||
* the Week and Agenda headers (#37). It is shown as the filter chip itself,
|
||||
* whose ✕ clears the day filter back to the whole month (#142).
|
||||
*/
|
||||
@Composable
|
||||
internal fun SplitDayPane(
|
||||
@@ -1899,6 +1894,7 @@ internal fun SplitDayPane(
|
||||
events: List<EventInstance>?,
|
||||
zone: TimeZone,
|
||||
onOpenDay: (LocalDate) -> Unit,
|
||||
onClearSelection: () -> Unit,
|
||||
onEventClick: (EventInstance) -> Unit,
|
||||
onCreateEvent: (LocalDate) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
@@ -1910,7 +1906,23 @@ internal fun SplitDayPane(
|
||||
val enter = itemEnter()
|
||||
val fadeSpec = rememberCalendarFadeSpec()
|
||||
Column(modifier = modifier) {
|
||||
AgendaDayHeader(date = date, today = today, onOpenDay = onOpenDay)
|
||||
InputChip(
|
||||
selected = true,
|
||||
onClick = { onOpenDay(date) },
|
||||
label = {
|
||||
Text(agendaDayLabel(date, today), style = MaterialTheme.typography.titleSmall)
|
||||
},
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
Icons.Default.Close,
|
||||
contentDescription = stringResource(R.string.month_split_clear_filter),
|
||||
modifier = Modifier
|
||||
.clip(CircleShape)
|
||||
.clickable(onClick = onClearSelection),
|
||||
)
|
||||
},
|
||||
modifier = Modifier.padding(start = 16.dp),
|
||||
)
|
||||
AnimatedContent(
|
||||
targetState = date to events,
|
||||
modifier = Modifier.weight(1f).fillMaxWidth(),
|
||||
|
||||
@@ -83,6 +83,7 @@ internal fun MonthStylePreview(
|
||||
events = sample.month.instancesByDay[today].orEmpty(),
|
||||
zone = zone,
|
||||
onOpenDay = {},
|
||||
onClearSelection = {},
|
||||
onEventClick = {},
|
||||
onCreateEvent = {},
|
||||
modifier = Modifier.fillMaxWidth().height(SPLIT_PANE_HEIGHT),
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
إصلاحات
|
||||
• يعرض عرض الشهر المقسّم أحداثًا أكثر: يظهر تاريخ اليوم المحدد مرة واحدة فقط في شريحة التصفية، وصارت رؤوس الأيام تشغل مساحة أقل.
|
||||
• لم تعد نقاط الأحداث في الشبكة المقسّمة تنزل للأسفل في الأيام التي تعرض „+N“.
|
||||
@@ -0,0 +1,3 @@
|
||||
Выпраўлена
|
||||
• Падзелены выгляд месяца змяшчае больш падзей: дата абранага дня паказваецца толькі раз, у чыпе фільтра, а загалоўкі дзён займаюць менш месца.
|
||||
• Кропкі падзей у падзеленай сетцы больш не з'язджаюць уніз у днях з «+N».
|
||||
@@ -0,0 +1,3 @@
|
||||
Opraveno
|
||||
• Rozdělený měsíční pohled pojme více událostí: vybraný den ukazuje datum jen jednou, v čipu filtru, a záhlaví dnů zabírají méně místa.
|
||||
• Tečky událostí v rozdělené mřížce už ve dnech s „+N“ nesjíždějí dolů.
|
||||
@@ -0,0 +1,3 @@
|
||||
Behoben
|
||||
• Die geteilte Monatsansicht zeigt mehr Termine: Ein gewählter Tag zeigt sein Datum nur noch einmal, im Filter-Chip, und die Tageskopfzeilen brauchen weniger Platz.
|
||||
• Die Termin-Punkte im geteilten Raster rutschen an Tagen mit „+N“ nicht mehr nach unten.
|
||||
@@ -0,0 +1,3 @@
|
||||
Fixed
|
||||
• The split month view fits more events: a selected day shows its date once, in the filter chip, and the day headers take less room.
|
||||
• Event dots in the split grid no longer drop down on days with a "+N".
|
||||
@@ -0,0 +1,3 @@
|
||||
Corregido
|
||||
• La vista mensual dividida muestra más eventos: el día seleccionado muestra su fecha una sola vez, en el chip del filtro, y las cabeceras de día ocupan menos espacio.
|
||||
• Los puntos de eventos de la cuadrícula dividida ya no bajan en los días con «+N».
|
||||
@@ -0,0 +1,3 @@
|
||||
Corrigé
|
||||
• La vue mensuelle partagée affiche plus d’événements : le jour sélectionné n’affiche plus sa date qu’une fois, dans la puce de filtre, et les en-têtes de jour prennent moins de place.
|
||||
• Les points d’événements de la grille partagée ne descendent plus les jours affichant « +N ».
|
||||
@@ -0,0 +1,3 @@
|
||||
Javítva
|
||||
• A megosztott havi nézet több eseményt mutat: a kiválasztott nap dátuma csak egyszer, a szűrőchipben jelenik meg, és a napfejlécek kevesebb helyet foglalnak.
|
||||
• A megosztott rács eseménypöttyei már nem csúsznak lejjebb a „+N” jelzésű napokon.
|
||||
@@ -0,0 +1,3 @@
|
||||
Corretto
|
||||
• La vista mensile divisa mostra più eventi: il giorno selezionato mostra la data una sola volta, nel chip del filtro, e le intestazioni dei giorni occupano meno spazio.
|
||||
• I puntini degli eventi nella griglia divisa non scendono più nei giorni con «+N».
|
||||
@@ -0,0 +1,3 @@
|
||||
修正
|
||||
• 分割月表示に表示できる予定が増えました。選択した日の日付はフィルターチップに一度だけ表示され、日付見出しも小さくなりました。
|
||||
• 「+N」が表示される日に、分割グリッドの予定ドットが下にずれなくなりました。
|
||||
@@ -0,0 +1,3 @@
|
||||
Opgelost
|
||||
• De gesplitste maandweergave toont meer afspraken: een gekozen dag toont zijn datum nog maar één keer, in de filterchip, en de dagkoppen nemen minder ruimte in.
|
||||
• De afspraakstippen in het gesplitste raster zakken niet meer weg op dagen met „+N”.
|
||||
@@ -0,0 +1,3 @@
|
||||
Poprawki
|
||||
• Podzielony widok miesiąca mieści więcej wydarzeń: wybrany dzień pokazuje datę tylko raz, w chipie filtra, a nagłówki dni zajmują mniej miejsca.
|
||||
• Kropki wydarzeń w podzielonej siatce nie zjeżdżają już w dół w dniach z „+N”.
|
||||
@@ -0,0 +1,3 @@
|
||||
Corrigido
|
||||
• A visualização mensal dividida mostra mais eventos: o dia selecionado mostra a data só uma vez, no chip do filtro, e os cabeçalhos dos dias ocupam menos espaço.
|
||||
• Os pontos de eventos na grade dividida não descem mais nos dias com “+N”.
|
||||
@@ -0,0 +1,3 @@
|
||||
Corrigido
|
||||
• A vista mensal dividida mostra mais eventos: o dia selecionado mostra a data só uma vez, no chip do filtro, e os cabeçalhos dos dias ocupam menos espaço.
|
||||
• Os pontos de eventos na grelha dividida já não descem nos dias com «+N».
|
||||
@@ -0,0 +1,3 @@
|
||||
Исправлено
|
||||
• Разделённый вид месяца вмещает больше событий: дата выбранного дня показывается один раз, в чипе фильтра, а заголовки дней занимают меньше места.
|
||||
• Точки событий в разделённой сетке больше не съезжают вниз в днях с «+N».
|
||||
@@ -0,0 +1,3 @@
|
||||
Opravené
|
||||
• Rozdelené mesačné zobrazenie pojme viac udalostí: vybraný deň ukazuje dátum len raz, v čipe filtra, a záhlavia dní zaberajú menej miesta.
|
||||
• Bodky udalostí v rozdelenej mriežke už v dňoch s „+N“ neklesajú nadol.
|
||||
@@ -0,0 +1,3 @@
|
||||
修复
|
||||
• 分割月视图可以显示更多日程:所选日期只在筛选标签中显示一次,日期标题也更紧凑。
|
||||
• 显示“+N”的日子里,分割网格中的日程圆点不再下移。
|
||||
Reference in New Issue
Block a user