diff --git a/app/build.gradle b/app/build.gradle index af58d295..76efb824 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,7 +29,7 @@ android { tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach { kotlinOptions { - freeCompilerArgs += ["-Xallow-jvm-ir-dependencies", "-Xskip-prerelease-check"] + freeCompilerArgs += ["-Xallow-jvm-ir-dependencies", "-Xskip-prerelease-check", "-Xopt-in=kotlin.RequiresOptIn"] } } diff --git a/app/src/main/java/dev/msfjarvis/todo/ui/AnimatedSwipeDismiss.kt b/app/src/main/java/dev/msfjarvis/todo/ui/AnimatedSwipeDismiss.kt new file mode 100644 index 00000000..ee3c775c --- /dev/null +++ b/app/src/main/java/dev/msfjarvis/todo/ui/AnimatedSwipeDismiss.kt @@ -0,0 +1,58 @@ +package dev.msfjarvis.todo.ui + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.EnterTransition +import androidx.compose.animation.ExitTransition +import androidx.compose.animation.ExperimentalAnimationApi +import androidx.compose.animation.core.tween +import androidx.compose.animation.expandVertically +import androidx.compose.animation.shrinkVertically +import androidx.compose.material.DismissDirection +import androidx.compose.material.DismissValue +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.SwipeToDismiss +import androidx.compose.material.rememberDismissState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.onCommit +import androidx.compose.ui.Modifier + +@OptIn(ExperimentalAnimationApi::class, ExperimentalMaterialApi::class) +@Composable +fun AnimatedSwipeDismiss( + modifier: Modifier = Modifier, + item: T, + background: @Composable (isDismissed: Boolean) -> Unit, + content: @Composable (isDismissed: Boolean) -> Unit, + directions: Set = setOf(DismissDirection.EndToStart), + enter: EnterTransition = expandVertically(), + exit: ExitTransition = shrinkVertically( + animSpec = tween( + durationMillis = 500, + ) + ), + onDismiss: (T) -> Unit +) { + val dismissState = rememberDismissState() + val isDismissed = dismissState.isDismissed(DismissDirection.EndToStart) + + onCommit(dismissState.value) { + if (dismissState.value == DismissValue.DismissedToStart) { + onDismiss(item) + } + } + + AnimatedVisibility( + modifier = modifier, + visible = !isDismissed, + enter = enter, + exit = exit + ) { + SwipeToDismiss( + modifier = modifier, + state = dismissState, + directions = directions, + background = { background(isDismissed) }, + dismissContent = { content(isDismissed) } + ) + } +} diff --git a/app/src/main/java/dev/msfjarvis/todo/ui/ListContent.kt b/app/src/main/java/dev/msfjarvis/todo/ui/ListContent.kt new file mode 100644 index 00000000..ddf1a064 --- /dev/null +++ b/app/src/main/java/dev/msfjarvis/todo/ui/ListContent.kt @@ -0,0 +1,48 @@ +package dev.msfjarvis.todo.ui + +import androidx.compose.animation.animate +import androidx.compose.foundation.Box +import androidx.compose.foundation.ContentGravity +import androidx.compose.foundation.Icon +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumnFor +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Delete +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp + +@Composable +fun ListContent( + innerPadding: PaddingValues, + items: List, + onSwipe: (T) -> Unit, + onClick: (T) -> Unit, + modifier: Modifier = Modifier, +) { + LazyColumnFor( + modifier = modifier.padding(innerPadding), + items = items, + ) { item -> + AnimatedSwipeDismiss( + item = item, + background = { isDismissed -> + Box( + modifier = Modifier.fillMaxSize(), + backgroundColor = Color.Red, + paddingStart = 20.dp, + paddingEnd = 20.dp, + gravity = ContentGravity.CenterEnd + ) { + val alpha = animate(if (isDismissed) 0f else 1f) + Icon(Icons.Filled.Delete, tint = Color.White.copy(alpha = alpha)) + } + }, + content = { /* your item cell (feed your on click here) */ }, + onDismiss = { onSwipe(it) } + ) + } +}