diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/BlockPlacement.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/BlockPlacement.kt index 877b3b6..a886d5c 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/BlockPlacement.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/common/BlockPlacement.kt @@ -1,16 +1,50 @@ package de.jeanlucmakiola.calendula.ui.common +import androidx.compose.animation.Crossfade import androidx.compose.animation.core.FiniteAnimationSpec import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.snap import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import de.jeanlucmakiola.floret.identity.rememberReduceMotion +/** + * A timed block's own time label, crossfaded rather than replaced. The block + * keeps its identity across a move and slides to the new slot; the label is the + * one thing on it that would otherwise change in a single frame. + */ +@OptIn(ExperimentalMaterial3ExpressiveApi::class) +@Composable +fun BlockTimeLabel(label: String, color: Color, modifier: Modifier = Modifier) { + val spec: FiniteAnimationSpec = if (rememberReduceMotion()) { + snap() + } else { + MaterialTheme.motionScheme.fastEffectsSpec() + } + Crossfade( + targetState = label, + animationSpec = spec, + label = "block-time", + modifier = modifier, + ) { text -> + Text( + text = text, + style = MaterialTheme.typography.labelSmall, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + color = color, + ) + } +} + /** Where a timed block sits in its column, after tweening. */ @Immutable data class BlockPlacement(val x: Dp, val y: Dp, val width: Dp, val height: Dp) 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 3eae341..366a7da 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 @@ -80,6 +80,7 @@ import de.jeanlucmakiola.calendula.ui.common.TodayAction import de.jeanlucmakiola.calendula.ui.common.CalendarFailure import de.jeanlucmakiola.calendula.ui.common.CalendarView import de.jeanlucmakiola.calendula.ui.common.IMPLEMENTED_VIEWS +import de.jeanlucmakiola.calendula.ui.common.BlockTimeLabel import de.jeanlucmakiola.calendula.ui.common.animatedBlockPlacement import de.jeanlucmakiola.calendula.ui.common.ghostAlpha import de.jeanlucmakiola.calendula.ui.common.LocalEventMove @@ -762,11 +763,8 @@ private fun EventBlock( ) } if (showTime) { - Text( - text = timeLabel, - style = MaterialTheme.typography.labelSmall, - maxLines = 1, - overflow = TextOverflow.Ellipsis, + BlockTimeLabel( + label = timeLabel, color = eventInk(fill, alpha = SECONDARY_INK_ALPHA), ) } 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 4cf6392..eb3980d 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 @@ -89,6 +89,7 @@ import de.jeanlucmakiola.calendula.ui.common.CalendarFailure import de.jeanlucmakiola.calendula.ui.common.CalendarView import de.jeanlucmakiola.calendula.ui.common.IMPLEMENTED_VIEWS import de.jeanlucmakiola.calendula.ui.common.EventDimAlpha +import de.jeanlucmakiola.calendula.ui.common.BlockTimeLabel import de.jeanlucmakiola.calendula.ui.common.animatedBlockPlacement import de.jeanlucmakiola.calendula.ui.common.ghostAlpha import de.jeanlucmakiola.calendula.ui.common.LocalEventMove @@ -931,11 +932,8 @@ private fun EventBlock( ) } if (showTime) { - Text( - text = timeLabel, - style = MaterialTheme.typography.labelSmall, - maxLines = 1, - overflow = TextOverflow.Ellipsis, + BlockTimeLabel( + label = timeLabel, color = eventInk(fill, alpha = SECONDARY_INK_ALPHA), ) }