diff --git a/core/src/main/kotlin/plus/rua/project/CalendarViewModel.kt b/core/src/main/kotlin/plus/rua/project/CalendarViewModel.kt index e134f2b..45b2148 100644 --- a/core/src/main/kotlin/plus/rua/project/CalendarViewModel.kt +++ b/core/src/main/kotlin/plus/rua/project/CalendarViewModel.kt @@ -20,8 +20,11 @@ import kotlinx.datetime.plus import kotlinx.datetime.todayIn import plus.rua.project.ui.COLLAPSE_THRESHOLD import plus.rua.project.ui.getMonthGridInfo +import android.util.Log import kotlin.time.Clock +private const val TAG_VM = "CalendarExpand" + /** * 日历日期数据,用于网格单元格渲染。 * @@ -285,7 +288,9 @@ class CalendarViewModel( * @param delta 拖拽增量,已归一化到 [0,1] 区间 */ fun onExpandDrag(delta: Float) { + val old = _collapseProgress.value _collapseProgress.value = (_collapseProgress.value + delta).coerceIn(0f, 1f) + Log.d(TAG_VM, "onExpandDrag: delta=$delta old=$old new=${_collapseProgress.value}") } /** @@ -295,13 +300,16 @@ class CalendarViewModel( */ fun onExpandDragEnd() { val progress = _collapseProgress.value - if (progress < (1 - COLLAPSE_THRESHOLD)) { + val result = if (progress < (1 - COLLAPSE_THRESHOLD)) { _isCollapsed.value = false _collapseProgress.value = 0f + "EXPANDED" } else { _isCollapsed.value = true _collapseProgress.value = 1f + "COLLAPSED (bounce back)" } + Log.d(TAG_VM, "onExpandDragEnd: progress=$progress threshold=${1 - COLLAPSE_THRESHOLD} result=$result") } /** diff --git a/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthPage.kt b/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthPage.kt index 2834a90..b4629ad 100644 --- a/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthPage.kt +++ b/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthPage.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex +import android.util.Log import kotlinx.datetime.DatePeriod import kotlinx.datetime.LocalDate import kotlinx.datetime.minus @@ -30,6 +31,8 @@ import plus.rua.project.DayCellInfo import plus.rua.project.LunarCache import plus.rua.project.ShiftKind +private const val TAG_CMP = "CalendarExpandAnim" + /** * 月度日历网格页面,支持两阶段折叠动画。 @@ -185,7 +188,7 @@ private fun WeekRow( !hasAnchor -> weekIndex * h - collapseProgress * weeksSize * h isAnchor -> anchorIndex * h * (1f - phase1) isAbove -> weekIndex * h - phase1 * anchorIndex * h - isBelow -> weekIndex * h - phase1 * anchorIndex * h - phase2 * belowRowsHeight + isBelow -> weekIndex * h - phase1 * anchorIndex * h else -> weekIndex * h } } else 0f @@ -198,6 +201,10 @@ private fun WeekRow( else -> 1f } + if (isAnchor || isBelow) { + Log.d(TAG_CMP, "WeekRow[$weekIndex]: isAnchor=$isAnchor isAbove=$isAbove isBelow=$isBelow phase1=$phase1 phase2=$phase2 yOffsetPx=$yOffsetPx rowAlpha=$rowAlpha collapseProgress=$collapseProgress") + } + if (rowAlpha > 0.01f) { Row( modifier = Modifier diff --git a/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthView.kt b/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthView.kt index 650f28f..f22b734 100644 --- a/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthView.kt +++ b/core/src/main/kotlin/plus/rua/project/ui/CalendarMonthView.kt @@ -520,20 +520,66 @@ private fun CalendarPagerArea( modifier } - CalendarPager( - selectedDate = selectedDate, - today = today, - onDateClick = onDateClick, - onMonthChanged = onMonthChanged, - collapseProgress = collapseProgress, - rowHeightPx = rowHeightPx, - effectiveWeeks = effectiveWeeks, - shiftKindAt = shiftKindAt, - showLegalHoliday = showLegalHoliday, - onRowHeightMeasured = onRowHeightMeasured, - pagerState = pagerState, + // 延迟切换:等折叠 spring 动画完全稳定后再切到 WeekPager,避免视觉跳跃 + var showWeekPager by remember { mutableStateOf(false) } + + LaunchedEffect(isCollapsed, collapseProgress) { + if (isCollapsed && collapseProgress >= 0.999f) { + delay(50) + showWeekPager = true + } else if (!isCollapsed) { + showWeekPager = false + } + } + + AnimatedContent( + targetState = showWeekPager, + transitionSpec = { fadeIn(tween(80)) togetherWith fadeOut(tween(80)) }, + label = "pager_switch", modifier = pagerModifier - ) + ) { useWeekPager -> + if (useWeekPager) { + WeekPager( + selectedDate = selectedDate, + today = today, + onDateClick = onDateClick, + onWeekChanged = { weekMonday -> + val weekSunday = weekMonday.plus(DatePeriod(days = 6)) + val date = when { + today in weekMonday..weekSunday -> today + weekMonday.month != weekSunday.month -> { + if (weekMonday < selectedDate) { + @Suppress("DEPRECATION") + LocalDate(weekSunday.year, weekSunday.month.number, 1) + } else { + weekMonday + } + } + else -> weekMonday + } + onDateClick(date) + }, + shiftKindAt = shiftKindAt, + showLegalHoliday = showLegalHoliday, + modifier = Modifier + ) + } else { + CalendarPager( + selectedDate = selectedDate, + today = today, + onDateClick = onDateClick, + onMonthChanged = onMonthChanged, + collapseProgress = collapseProgress, + rowHeightPx = rowHeightPx, + effectiveWeeks = effectiveWeeks, + shiftKindAt = shiftKindAt, + showLegalHoliday = showLegalHoliday, + onRowHeightMeasured = onRowHeightMeasured, + pagerState = pagerState, + modifier = Modifier + ) + } + } } @Composable diff --git a/core/src/main/kotlin/plus/rua/project/ui/WeekPager.kt b/core/src/main/kotlin/plus/rua/project/ui/WeekPager.kt index 446f5cf..0992167 100644 --- a/core/src/main/kotlin/plus/rua/project/ui/WeekPager.kt +++ b/core/src/main/kotlin/plus/rua/project/ui/WeekPager.kt @@ -18,10 +18,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.unit.dp import kotlinx.coroutines.flow.drop +import kotlinx.coroutines.runBlocking import kotlinx.datetime.DatePeriod import kotlinx.datetime.LocalDate import kotlinx.datetime.daysUntil import kotlinx.datetime.plus +import plus.rua.project.DayCellInfo +import plus.rua.project.LunarCache import plus.rua.project.ShiftKind import plus.rua.project.composeTraceBeginSection import plus.rua.project.composeTraceEndSection @@ -96,6 +99,11 @@ fun WeekPager( ) { (0 until 7).forEach { dayOffset -> val date = weekMonday.plus(DatePeriod(days = dayOffset)) + val lunarData = remember(date) { + runBlocking { + LunarCache.default.getOrCompute(date) + } + } DayCell( date = date, isCurrentMonth = date.month == selectedDate.month @@ -106,7 +114,8 @@ fun WeekPager( showLegalHoliday = showLegalHoliday, onClick = { onDateClick(date) }, modifier = Modifier.weight(1f), - interactionSource = interactionSource + interactionSource = interactionSource, + lunarData = lunarData ) } }