From c1e0484cba5a6c672412f2b5e14aab9e48f6571b Mon Sep 17 00:00:00 2001 From: xfy Date: Thu, 14 May 2026 17:02:44 +0800 Subject: [PATCH] Add pull-down gesture to expand from collapsed week view back to month view Co-Authored-By: Claude Opus 4.7 --- .../plus/rua/project/CalendarViewModel.kt | 26 +++++++++++++++++++ .../kotlin/plus/rua/project/ui/BottomCard.kt | 25 +++++++++++++----- .../plus/rua/project/ui/CalendarMonthView.kt | 3 ++- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/shared/src/commonMain/kotlin/plus/rua/project/CalendarViewModel.kt b/shared/src/commonMain/kotlin/plus/rua/project/CalendarViewModel.kt index d2eeb7c..d670687 100644 --- a/shared/src/commonMain/kotlin/plus/rua/project/CalendarViewModel.kt +++ b/shared/src/commonMain/kotlin/plus/rua/project/CalendarViewModel.kt @@ -74,6 +74,32 @@ class CalendarViewModel(private val coroutineScope: CoroutineScope) { } } + // 折叠状态下下拉恢复:delta 为负值(向下拖)推动 progress 向 0 + fun onExpandDrag(delta: Float) { + coroutineScope.launch { + val new = (_collapseAnimatable.value + delta).coerceIn(0f, 1f) + _collapseAnimatable.snapTo(new) + } + } + + // 下拉超过 50% 时自动展开到月视图,否则回弹到周视图 + fun onExpandDragEnd() { + coroutineScope.launch { + if (_collapseAnimatable.value < 0.5f) { + _collapseAnimatable.animateTo( + targetValue = 0f, + animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f) + ) + isCollapsed = false + } else { + _collapseAnimatable.animateTo( + targetValue = 1f, + animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f) + ) + } + } + } + /** * 计算给定日期的 ISO 8601 周号。 * diff --git a/shared/src/commonMain/kotlin/plus/rua/project/ui/BottomCard.kt b/shared/src/commonMain/kotlin/plus/rua/project/ui/BottomCard.kt index 005c748..61e7c27 100644 --- a/shared/src/commonMain/kotlin/plus/rua/project/ui/BottomCard.kt +++ b/shared/src/commonMain/kotlin/plus/rua/project/ui/BottomCard.kt @@ -38,13 +38,24 @@ fun BottomCard( modifier = modifier .fillMaxWidth() .pointerInput(viewModel.isCollapsed) { - if (viewModel.isCollapsed) return@pointerInput - detectVerticalDragGestures( - onDragEnd = { viewModel.onDragEnd() }, - onDragCancel = { viewModel.onDragEnd() } - ) { _, dragAmount -> - val delta = -dragAmount / dragRange - viewModel.onDrag(delta) + if (viewModel.isCollapsed) { + // 折叠状态:下拉恢复到月视图 + detectVerticalDragGestures( + onDragEnd = { viewModel.onExpandDragEnd() }, + onDragCancel = { viewModel.onExpandDragEnd() } + ) { _, dragAmount -> + val delta = -dragAmount / dragRange + viewModel.onExpandDrag(delta) + } + } else { + // 展开状态:上拉折叠到周视图 + detectVerticalDragGestures( + onDragEnd = { viewModel.onDragEnd() }, + onDragCancel = { viewModel.onDragEnd() } + ) { _, dragAmount -> + val delta = -dragAmount / dragRange + viewModel.onDrag(delta) + } } }, shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp), diff --git a/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthView.kt b/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthView.kt index e277695..8f69e76 100644 --- a/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthView.kt +++ b/shared/src/commonMain/kotlin/plus/rua/project/ui/CalendarMonthView.kt @@ -106,7 +106,8 @@ fun CalendarMonthView( weekdayHeaderHeightPx = size.height } ) - if (viewModel.isCollapsed) { + // 完全折叠且无动画时显示 WeekPager,否则显示 CalendarPager(含下拉恢复过程) + if (viewModel.isCollapsed && viewModel.collapseProgress >= 1f) { WeekPager( selectedDate = viewModel.selectedDate, today = today,