Skip to content

Commit

Permalink
Update dependencies
Browse files Browse the repository at this point in the history
Co-authored-by: Patryk Goworowski <[email protected]>
  • Loading branch information
patrickmichalik and Gowsky committed Dec 17, 2024
1 parent b5c2948 commit da83456
Show file tree
Hide file tree
Showing 12 changed files with 123 additions and 135 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.patrykandpatryk.liftapp.domain.text.StringProvider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.update

object PreviewResource {
val stringProvider: StringProvider
Expand Down Expand Up @@ -46,6 +47,10 @@ object PreviewResource {
override suspend fun set(value: T) {
flow.value = value
}

override suspend fun update(function: (T) -> T) {
flow.update(function)
}
}
}
}
140 changes: 68 additions & 72 deletions core/src/main/kotlin/com/patrykandpatryk/liftapp/core/ui/Backdrop.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.patrykandpatryk.liftapp.core.ui

import androidx.compose.animation.core.spring
import androidx.compose.animation.splineBasedDecay
import androidx.compose.animation.core.LinearOutSlowInEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.gestures.AnchoredDraggableDefaults
import androidx.compose.foundation.gestures.AnchoredDraggableState
import androidx.compose.foundation.gestures.DraggableAnchors
import androidx.compose.foundation.gestures.FlingBehavior
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.ScrollScope
import androidx.compose.foundation.gestures.anchoredDraggable
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.Composable
Expand All @@ -16,56 +19,40 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.Velocity
import androidx.compose.ui.unit.dp
import kotlin.math.roundToInt

enum class BackdropValue {
Opened,
Open,
Closed,
}

@Immutable
data class BackdropState(
val initialState: BackdropValue = BackdropValue.Closed,
private val density: Density,
) {
internal val anchoredDraggableState =
AnchoredDraggableState<BackdropValue>(
initialValue = BackdropValue.Closed,
positionalThreshold = { distance -> distance / 2 },
velocityThreshold = { with(density) { 200.dp.toPx() } },
snapAnimationSpec = spring(),
decayAnimationSpec = splineBasedDecay(density),
)

val nestedScrollConnection: NestedScrollConnection =
BackdropNestedScrollConnection(anchoredDraggableState)
data class BackdropState(val initialValue: BackdropValue) {
internal val anchoredDraggableState = AnchoredDraggableState(initialValue)

val isOpened: Boolean by derivedStateOf {
anchoredDraggableState.currentValue == BackdropValue.Opened
val isOpen: Boolean by derivedStateOf {
anchoredDraggableState.currentValue == BackdropValue.Open
}

val offset: Float by derivedStateOf {
anchoredDraggableState.offset - anchoredDraggableState.anchors.minAnchor()
anchoredDraggableState.offset -
anchoredDraggableState.anchors.positionOf(BackdropValue.Closed)
}

val offsetFraction: Float by derivedStateOf {
offset /
(anchoredDraggableState.anchors.maxAnchor() -
anchoredDraggableState.anchors.minAnchor())
(anchoredDraggableState.anchors.positionOf(BackdropValue.Open) -
anchoredDraggableState.anchors.positionOf(BackdropValue.Closed))
}
}

@Composable
fun rememberBackdropState(initialState: BackdropValue = BackdropValue.Closed): BackdropState {
val density = LocalDensity.current
return remember(initialState, density) { BackdropState(initialState, density) }
}
fun rememberBackdropState(initialState: BackdropValue = BackdropValue.Closed) =
remember(initialState) { BackdropState(initialState) }

@Composable
fun Backdrop(
Expand All @@ -76,10 +63,19 @@ fun Backdrop(
state: BackdropState = rememberBackdropState(),
content: @Composable () -> Unit,
) {
val flingBehavior =
AnchoredDraggableDefaults.flingBehavior(
state = state.anchoredDraggableState,
animationSpec = tween(easing = LinearOutSlowInEasing),
)
val scrollConnection =
remember(state.anchoredDraggableState, flingBehavior) {
BackdropNestedScrollConnection(state.anchoredDraggableState, flingBehavior)
}
Layout(
content = {
Box { backContent() }
Box { content() }
Box(Modifier.nestedScroll(scrollConnection)) { content() }
},
measurePolicy = { measurables, constraints ->
val backdrop = measurables[0].measure(constraints)
Expand All @@ -96,34 +92,41 @@ fun Backdrop(

state.anchoredDraggableState.updateAnchors(
DraggableAnchors {
BackdropValue.Open at backdropOpenLength
BackdropValue.Closed at backPeekHeight.toPx()
BackdropValue.Opened at backdropOpenLength
}
)
layout(constraints.maxWidth, constraints.maxHeight) {
backdrop.place(0, 0)
front.place(0, state.anchoredDraggableState.offset.roundToInt())
}
},
modifier = modifier.anchoredDraggable(state.anchoredDraggableState, Orientation.Vertical),
modifier =
modifier.anchoredDraggable(
state = state.anchoredDraggableState,
orientation = Orientation.Vertical,
flingBehavior = flingBehavior,
),
)
}

private class BackdropNestedScrollConnection(
private val anchoredDraggableState: AnchoredDraggableState<BackdropValue>
private val anchoredDraggableState: AnchoredDraggableState<BackdropValue>,
private val flingBehavior: FlingBehavior,
) : NestedScrollConnection {
var blockDrag: Boolean? = null
var blockScroll: Boolean? = null
var lastPositiveScrollSource: NestedScrollSource? = null
val scrollScope =
object : ScrollScope {
override fun scrollBy(pixels: Float) = anchoredDraggableState.dispatchRawDelta(pixels)
}

override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset =
override fun onPreScroll(available: Offset, source: NestedScrollSource) =
if (
blockScroll == true ||
available.y < 0 &&
anchoredDraggableState.offset != anchoredDraggableState.anchors.minAnchor()
available.y < 0 &&
anchoredDraggableState.offset !=
anchoredDraggableState.anchors.positionOf(BackdropValue.Closed)
) {
blockScroll = true
anchoredDraggableState.dispatchRawDelta(available.y)
available
Offset(0f, anchoredDraggableState.dispatchRawDelta(available.y))
} else {
Offset.Zero
}
Expand All @@ -133,43 +136,36 @@ private class BackdropNestedScrollConnection(
available: Offset,
source: NestedScrollSource,
): Offset {
if (blockDrag == null) blockDrag = available.y == 0f
return when {
available.y > 0 -> {
val consumedY =
if (blockDrag == true) {
0f
} else {
anchoredDraggableState.dispatchRawDelta(available.y)
}
Offset(available.x, consumedY)
}

blockScroll == true -> Offset(0f, available.y)
else -> Offset.Zero
if (available.y <= 0) return Offset.Zero
lastPositiveScrollSource = source
return if (source == NestedScrollSource.UserInput) {
Offset(0f, anchoredDraggableState.dispatchRawDelta(available.y))
} else {
Offset.Zero
}
}

override suspend fun onPreFling(available: Velocity): Velocity =
override suspend fun onPreFling(available: Velocity) =
if (
available.y < 0 &&
anchoredDraggableState.offset != anchoredDraggableState.anchors.minAnchor()
anchoredDraggableState.offset !=
anchoredDraggableState.anchors.positionOf(BackdropValue.Closed)
) {
anchoredDraggableState.settle(available.y / 4)
with(flingBehavior) { scrollScope.performFling(available.y) }
Velocity(0f, available.y)
} else {
val consumedVelocityY =
when {
available.y > 0f && blockDrag == true -> 0f
blockScroll == true -> available.y
else -> anchoredDraggableState.settle(available.y)
}
Velocity(0f, consumedVelocityY)
Velocity.Zero
}

override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
blockDrag = null
blockScroll = null
return Velocity(0f, anchoredDraggableState.settle(available.y))
}
override suspend fun onPostFling(consumed: Velocity, available: Velocity) =
if (
available.y >= 0 &&
lastPositiveScrollSource != null &&
lastPositiveScrollSource == NestedScrollSource.UserInput
) {
with(flingBehavior) { scrollScope.performFling(available.y) }
Velocity(0f, available.y)
} else {
Velocity.Zero
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ data class Dimens(
@Immutable
data class Swipe(
val fractionalThreshold: Float = .4f,
val velocityThreshold: Dp = 124.dp,
val backgroundVisibilityThreshold: Dp = 56.dp,
val swipeElevation: Dp = 2.dp,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ fun rememberTimePickerState(
minute: Int,
is24h: Boolean = true,
) =
remember(keys = arrayOf(is24h, hour, minute)) {
remember(is24h, hour, minute) {
TimePickerState(isShowing = isShowing, hour = hour, minute = minute, is24h = is24h)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.patrykandpatryk.liftapp.core.ui.swipe

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.splineBasedDecay
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.AnchoredDraggableState
import androidx.compose.foundation.gestures.DraggableAnchors
Expand Down Expand Up @@ -30,7 +28,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.zIndex
Expand All @@ -47,20 +44,7 @@ fun SwipeContainer(
modifier: Modifier = Modifier,
onDismiss: () -> Unit,
) {
val dimens = LocalDimens.current
val density = LocalDensity.current
val velocityThreshold = with(density) { dimens.swipe.velocityThreshold.toPx() }

val anchoredDraggableState = remember {
AnchoredDraggableState(
initialValue = SwipeContainerState.Idle,
positionalThreshold = { dimens.swipe.fractionalThreshold * it },
velocityThreshold = { velocityThreshold },
snapAnimationSpec = spring(),
decayAnimationSpec = splineBasedDecay(density),
)
}

val anchoredDraggableState = remember { AnchoredDraggableState(SwipeContainerState.Idle) }
val swipeOffset = anchoredDraggableState.offset.takeIf { it.isFinite() }.orZero
var containerWidth by remember { mutableFloatStateOf(1f) }
val swipeProgress = swipeOffset / containerWidth
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update

class TestPreferenceRepository : PreferenceRepository {

Expand Down Expand Up @@ -67,5 +68,9 @@ class TestPreferenceRepository : PreferenceRepository {
override suspend fun set(value: T) {
impl.value = value
}

override suspend fun update(function: (T) -> T) {
impl.update(function)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package com.patrykandpatryk.liftapp.feature.newexercise.ui
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExposedDropdownMenuAnchorType
import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MenuAnchorType
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
Expand Down Expand Up @@ -79,7 +79,9 @@ fun <T> DropdownMenu(
) {
Column {
OutlinedTextField(
modifier = Modifier.menuAnchor(MenuAnchorType.PrimaryNotEditable).fillMaxWidth(),
modifier =
Modifier.menuAnchor(ExposedDropdownMenuAnchorType.PrimaryNotEditable)
.fillMaxWidth(),
readOnly = true,
value = getItemsText(selectedItems),
onValueChange = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ fun ExerciseListPicker(
text = exercise.name.getDisplayName(),
style = MaterialTheme.typography.titleLarge,
modifier =
Modifier.onPositionChange { offset, viewPortOffset ->
Modifier.onPositionChange { offset, _ ->
positionOffset.floatValue = abs(offset)
}
.graphicsLayer {
alpha =
if (positionOffset.floatValue == 0f || !backdropState.isOpened) {
if (positionOffset.floatValue == 0f || !backdropState.isOpen) {
1f
} else {
backdropState.offsetFraction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
Expand Down Expand Up @@ -93,7 +92,7 @@ fun WorkoutScreen(
state = backdropState,
modifier = Modifier.padding(paddingValues).imePadding(),
) {
Column(modifier = Modifier.nestedScroll(backdropState.nestedScrollConnection)) {
Column {
SinHorizontalDivider(
bottomBackgroundColor = MaterialTheme.colorScheme.background
)
Expand Down
Loading

0 comments on commit da83456

Please sign in to comment.