diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a59689..abb1261 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 three-letter form and the day view drops the weekday, rather than trailing off mid-word at large font sizes. The view switcher, the title and the agenda's range bar also line up with the grid underneath them ([#165]). +- The jump-to-today button in the toolbar now shows today's date. It drew a + generic calendar icon, which told you nothing you didn't already know from + tapping it; it now carries the current day number in an outlined box, so the + bar says what day it is as well as taking you there. It rolls over at midnight + on its own ([#220]). ### Fixed - **A long location no longer runs off the edge of its field.** The location on @@ -1611,3 +1616,4 @@ automatically, with zero telemetry and no internet permission. [#253]: https://codeberg.org/jlmakiola/calendula/issues/253 [#273]: https://codeberg.org/jlmakiola/calendula/issues/273 [#113]: https://codeberg.org/jlmakiola/calendula/issues/113 +[#220]: https://codeberg.org/jlmakiola/calendula/issues/220 diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/AppBarSpacing.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/AppBarSpacing.kt index 3c1e85f..4a12dc7 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/AppBarSpacing.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/AppBarSpacing.kt @@ -26,7 +26,8 @@ object AppBarSpacing { private val IconButtonSize = 48.dp - private val IconSize = 24.dp + /** M3's icon slot inside an icon button; the today glyph fills the same box. */ + internal val IconSize = 24.dp /** * End padding for a container-backed control that ends the bar, measured to diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/TodayAction.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/TodayAction.kt index 1234bb1..583ee4a 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/TodayAction.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/TodayAction.kt @@ -1,26 +1,81 @@ package de.jeanlucmakiola.calendula.ui.common -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Today -import androidx.compose.material3.Icon +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp import de.jeanlucmakiola.calendula.R +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toLocalDateTime + +private val GlyphShape = RoundedCornerShape(7.dp) +private val GlyphBorder = 1.5.dp + +/** + * Height of the day number. Expressed in dp and converted to sp at draw time so + * it does not follow the font scale: this is an icon glyph sharing the bar with + * stroke icons, and a two-digit day that grew with the text would push the bar + * past the width #165 measured it to. The button's content description carries + * the meaning for screen readers, so nothing is lost by holding it still. + */ +private val GlyphTextHeight = 12.dp /** * The top-bar "jump to today" icon button, shared by every calendar view's app * bar (#60). Shown in place of the fade-in FAB pill when the user moves the * today control into the toolbar; renders nothing when [show] is false, so it * drops straight into an app bar's `actions` slot without a wrapping condition. + * + * The glyph is the current day number in an outlined box rather than a generic + * calendar icon (#220), so the bar also says what day it is. Outlined rather + * than the month grid's filled circle, which reads as "this cell is today" and + * would sit heavier here than the stroke icons beside it. */ @Composable fun TodayAction(show: Boolean, onToday: () -> Unit) { if (!show) return - IconButton(onClick = onToday) { - Icon( - imageVector = Icons.Default.Today, - contentDescription = stringResource(R.string.today_jump_action), - ) + val now = rememberCurrentMinute() + // Only the day number is read, so the bar recomposes at midnight rather + // than on every minute tick. + val day by remember { + derivedStateOf { now.value.toLocalDateTime(TimeZone.currentSystemDefault()).date.day } + } + val description = stringResource(R.string.today_jump_action) + IconButton( + onClick = onToday, + modifier = Modifier.semantics { contentDescription = description }, + ) { + val textSize = with(LocalDensity.current) { GlyphTextHeight.toSp() } + Box( + modifier = Modifier + .size(AppBarSpacing.IconSize) + .border(GlyphBorder, LocalContentColor.current, GlyphShape), + contentAlignment = Alignment.Center, + ) { + Text( + text = day.toString(), + fontSize = textSize, + lineHeight = textSize, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Center, + color = LocalContentColor.current, + ) + } } } diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/day/DayScreen.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/day/DayScreen.kt index 541cea7..ba70d12 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/day/DayScreen.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/day/DayScreen.kt @@ -861,7 +861,12 @@ private fun DayLoading() { BoxWithConstraints(modifier = Modifier.fillMaxSize()) { // Same scale resolution as the loaded timeline, so the skeleton's column // doesn't resize the moment the real day arrives. - val totalHeight = scale.hourHeight(maxHeight) * 24 + val hourHeight = scale.hourHeight(maxHeight) + val totalHeight = hourHeight * 24 + // The skeleton wears the loaded column's own ground, so the arrival of + // the real day doesn't flash a solid block into a gapped grid. + val showHourGrid = LocalShowHourGrid.current + val hourPx = with(LocalDensity.current) { hourHeight.toPx() } Row( modifier = Modifier .fillMaxSize() @@ -874,7 +879,11 @@ private fun DayLoading() { .weight(1f) .height(totalHeight) .padding(horizontal = 2.dp) - .background(MaterialTheme.colorScheme.surfaceContainer), + .background( + if (showHourGrid) MaterialTheme.colorScheme.surface + else MaterialTheme.colorScheme.surfaceContainer, + ) + .hourGridCells(showHourGrid, hourPx, MaterialTheme.colorScheme.surfaceContainer), ) } } diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/week/WeekScreen.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/week/WeekScreen.kt index 8bc6dad..7c55ce1 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/week/WeekScreen.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/week/WeekScreen.kt @@ -1042,7 +1042,14 @@ private fun WeekLoading() { BoxWithConstraints(modifier = Modifier.fillMaxSize()) { // Same scale resolution as the loaded timeline, so the skeleton's // columns don't resize the moment the real week arrives. - val totalHeight = scale.hourHeight(maxHeight) * 24 + val hourHeight = scale.hourHeight(maxHeight) + val totalHeight = hourHeight * 24 + // The skeleton wears the loaded columns' own ground, so the arrival + // of the real week doesn't flash solid blocks into a gapped grid. + val showHourGrid = LocalShowHourGrid.current + val hourPx = with(LocalDensity.current) { hourHeight.toPx() } + val columnGround = if (showHourGrid) MaterialTheme.colorScheme.surface + else MaterialTheme.colorScheme.surfaceContainer Row( modifier = Modifier .fillMaxSize() @@ -1056,7 +1063,12 @@ private fun WeekLoading() { .weight(1f) .height(totalHeight) .padding(horizontal = 2.dp) - .background(MaterialTheme.colorScheme.surfaceContainer), + .background(columnGround) + .hourGridCells( + showHourGrid, + hourPx, + MaterialTheme.colorScheme.surfaceContainer, + ), ) } }