diff --git a/shared/src/commonMain/kotlin/plus/rua/project/CalendarViewModel.kt b/shared/src/commonMain/kotlin/plus/rua/project/CalendarViewModel.kt index 1cbc514..c7a3610 100644 --- a/shared/src/commonMain/kotlin/plus/rua/project/CalendarViewModel.kt +++ b/shared/src/commonMain/kotlin/plus/rua/project/CalendarViewModel.kt @@ -1,6 +1,7 @@ package plus.rua.project import androidx.compose.animation.core.Animatable +import androidx.compose.animation.core.spring import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue @@ -42,31 +43,27 @@ class CalendarViewModel(private val coroutineScope: CoroutineScope) { selectedDate = date } - fun collapse() { - if (isCollapsed) return + fun onDrag(delta: Float) { coroutineScope.launch { - _collapseAnimatable.animateTo( - targetValue = 1f, - animationSpec = androidx.compose.animation.core.spring( - dampingRatio = 0.8f, - stiffness = 400f - ) - ) - isCollapsed = true + val new = (_collapseAnimatable.value + delta).coerceIn(0f, 1f) + _collapseAnimatable.snapTo(new) } } - fun expand() { - if (!isCollapsed) return - isCollapsed = false + fun onDragEnd() { coroutineScope.launch { - _collapseAnimatable.animateTo( - targetValue = 0f, - animationSpec = androidx.compose.animation.core.spring( - dampingRatio = 0.8f, - stiffness = 400f + if (_collapseAnimatable.value > 0.5f) { + _collapseAnimatable.animateTo( + targetValue = 1f, + animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f) ) - ) + isCollapsed = true + } else { + _collapseAnimatable.animateTo( + targetValue = 0f, + animationSpec = spring(dampingRatio = 0.8f, stiffness = 400f) + ) + } } } 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 572b0d7..e351256 100644 --- a/shared/src/commonMain/kotlin/plus/rua/project/ui/BottomCard.kt +++ b/shared/src/commonMain/kotlin/plus/rua/project/ui/BottomCard.kt @@ -1,6 +1,5 @@ package plus.rua.project.ui -import androidx.compose.animation.core.animate import androidx.compose.foundation.background import androidx.compose.foundation.gestures.detectVerticalDragGestures import androidx.compose.foundation.layout.Box @@ -12,14 +11,13 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.dp -import kotlinx.coroutines.launch import plus.rua.project.CalendarViewModel @Composable @@ -27,16 +25,20 @@ fun BottomCard( viewModel: CalendarViewModel, modifier: Modifier = Modifier ) { - val coroutineScope = rememberCoroutineScope() + val density = LocalDensity.current + val dragRange = with(density) { 200.dp.toPx() } Surface( modifier = modifier .fillMaxWidth() - .pointerInput(Unit) { - detectVerticalDragGestures { _, dragAmount -> - if (dragAmount < 0 && !viewModel.isCollapsed) { - viewModel.collapse() - } + .pointerInput(viewModel.isCollapsed) { + if (viewModel.isCollapsed) return@pointerInput + detectVerticalDragGestures( + onDragEnd = { viewModel.onDragEnd() }, + onDragCancel = { viewModel.onDragEnd() } + ) { _, dragAmount -> + val delta = -dragAmount / dragRange + viewModel.onDrag(delta) } }, shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),