Switch to Modifier.swipeable

Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
Harsh Shandilya 2020-11-02 01:03:54 +05:30
parent 8c162c75c5
commit a52c75601c
No known key found for this signature in database
GPG key ID: 366D7BBAD1031E80
5 changed files with 36 additions and 85 deletions

View file

@ -53,6 +53,7 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
"-Xskip-prerelease-check", "-Xskip-prerelease-check",
"-Xopt-in=kotlin.RequiresOptIn", "-Xopt-in=kotlin.RequiresOptIn",
"-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi", "-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-Xopt-in=androidx.compose.material.ExperimentalMaterialApi",
] ]
} }
} }

View file

@ -8,7 +8,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import dev.msfjarvis.lobsters.model.LobstersPost import dev.msfjarvis.lobsters.model.LobstersPost
import dev.msfjarvis.lobsters.ui.urllauncher.UrlLauncherAmbient import dev.msfjarvis.lobsters.ui.urllauncher.UrlLauncherAmbient
import dev.msfjarvis.lobsters.util.AnimatedSwipeDismiss
@Composable @Composable
fun HottestPosts( fun HottestPosts(
@ -31,17 +30,11 @@ fun HottestPosts(
if (posts.lastIndex == index) { if (posts.lastIndex == index) {
overscrollAction.invoke() overscrollAction.invoke()
} }
AnimatedSwipeDismiss( LobstersItem(
item = item, post = item,
background = {}, linkOpenAction = { post -> urlLauncher.launch(post.url.ifEmpty { post.commentsUrl }) },
content = { commentOpenAction = { post -> urlLauncher.launch(post.commentsUrl) },
LobstersItem( saveAction = saveAction,
post = item,
linkOpenAction = { post -> urlLauncher.launch(post.url.ifEmpty { post.commentsUrl }) },
commentOpenAction = { post -> urlLauncher.launch(post.commentsUrl) },
)
},
onDismiss = saveAction,
) )
} }
} }

View file

@ -6,16 +6,23 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.offsetPx
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumnFor import androidx.compose.foundation.lazy.LazyColumnFor
import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.FractionalThreshold
import androidx.compose.material.rememberSwipeableState
import androidx.compose.material.swipeable
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.gesture.scrollorientationlocking.Orientation
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.ConfigurationAmbient
import androidx.compose.ui.platform.DensityAmbient
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.ui.tooling.preview.Preview import androidx.ui.tooling.preview.Preview
@ -34,12 +41,29 @@ fun LazyItemScope.LobstersItem(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
linkOpenAction: (LobstersPost) -> Unit, linkOpenAction: (LobstersPost) -> Unit,
commentOpenAction: (LobstersPost) -> Unit, commentOpenAction: (LobstersPost) -> Unit,
saveAction: (LobstersPost) -> Unit,
) { ) {
val titleColor = if (post.isLiked) savedTitleColor else titleColor val titleColor = if (post.isLiked) savedTitleColor else titleColor
val width = with(DensityAmbient.current) {
ConfigurationAmbient.current.screenWidthDp.toDp().toPx()
}
val swipeableState = rememberSwipeableState("Not Swiped")
val anchors = mapOf(0f to "Not Swiped", width to "Fully Swiped")
if (swipeableState.offset.value >= (width / 2)) {
saveAction.invoke(post)
swipeableState.animateTo("Not Swiped")
}
Column( Column(
modifier = modifier modifier = modifier
.fillParentMaxWidth() .fillParentMaxWidth()
.swipeable(
state = swipeableState,
anchors = anchors,
thresholds = { _, _ -> FractionalThreshold(0.5f) },
orientation = Orientation.Horizontal
)
.offsetPx(swipeableState.offset)
.clickable( .clickable(
onClick = { linkOpenAction.invoke(post) }, onClick = { linkOpenAction.invoke(post) },
onLongClick = { commentOpenAction.invoke(post) }, onLongClick = { commentOpenAction.invoke(post) },
@ -119,6 +143,7 @@ fun PreviewLobstersItem() {
post = item, post = item,
linkOpenAction = {}, linkOpenAction = {},
commentOpenAction = {}, commentOpenAction = {},
saveAction = {},
) )
} }
} }

View file

@ -8,7 +8,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import dev.msfjarvis.lobsters.model.LobstersPost import dev.msfjarvis.lobsters.model.LobstersPost
import dev.msfjarvis.lobsters.ui.urllauncher.UrlLauncherAmbient import dev.msfjarvis.lobsters.ui.urllauncher.UrlLauncherAmbient
import dev.msfjarvis.lobsters.util.AnimatedSwipeDismiss
@Composable @Composable
fun SavedPosts( fun SavedPosts(
@ -27,17 +26,11 @@ fun SavedPosts(
state = listState, state = listState,
modifier = Modifier.padding(horizontal = 8.dp).then(modifier) modifier = Modifier.padding(horizontal = 8.dp).then(modifier)
) { item -> ) { item ->
AnimatedSwipeDismiss( LobstersItem(
item = item, post = item,
background = {}, linkOpenAction = { post -> urlLauncher.launch(post.url.ifEmpty { post.commentsUrl }) },
content = { commentOpenAction = { post -> urlLauncher.launch(post.commentsUrl) },
LobstersItem( saveAction = saveAction,
post = item,
linkOpenAction = { post -> urlLauncher.launch(post.url.ifEmpty { post.commentsUrl }) },
commentOpenAction = { post -> urlLauncher.launch(post.commentsUrl) },
)
},
onDismiss = saveAction,
) )
} }
} }

View file

@ -1,61 +0,0 @@
package dev.msfjarvis.lobsters.util
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
/**
* Imported from Brandon McAnsh's [Gist](https://gist.github.com/bmc08gt/fca95db3bf9fcf255d76f03ec10ea3f9).
*/
@OptIn(ExperimentalAnimationApi::class, ExperimentalMaterialApi::class)
@Composable
fun <T> AnimatedSwipeDismiss(
modifier: Modifier = Modifier,
item: T,
background: @Composable (isDismissed: Boolean) -> Unit,
content: @Composable (isDismissed: Boolean) -> Unit,
directions: Set<DismissDirection> = setOf(DismissDirection.StartToEnd, 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) }
)
}
}