mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-17 22:37:03 +05:30
Merge #60
60: Make saving a swipe action r=msfjarvis a=msfjarvis ~~This isn't ready yet, because when done we want to make this use just `Modifier.swipeable` and not actually dismiss the view.~~ Good to go now Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
commit
713706caff
6 changed files with 35 additions and 27 deletions
|
@ -53,6 +53,7 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
|
|||
"-Xskip-prerelease-check",
|
||||
"-Xopt-in=kotlin.RequiresOptIn",
|
||||
"-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
|
||||
"-Xopt-in=androidx.compose.material.ExperimentalMaterialApi",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,11 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.msfjarvis.lobsters.R
|
||||
import dev.msfjarvis.lobsters.util.IconResource
|
||||
import dev.msfjarvis.lobsters.ui.theme.savedTitleColor
|
||||
|
||||
@Composable
|
||||
fun EmptyList(saved: Boolean) {
|
||||
|
@ -24,7 +24,7 @@ fun EmptyList(saved: Boolean) {
|
|||
if (saved) {
|
||||
IconResource(
|
||||
R.drawable.ic_favorite_border_24px,
|
||||
tint = savedTitleColor,
|
||||
tint = Color(0xFFD97373),
|
||||
modifier = Modifier.padding(16.dp)
|
||||
)
|
||||
Text(stringResource(R.string.no_saved_posts))
|
||||
|
|
|
@ -6,18 +6,23 @@ import androidx.compose.foundation.clickable
|
|||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.offsetPx
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.lazy.LazyColumnFor
|
||||
import androidx.compose.foundation.lazy.LazyItemScope
|
||||
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.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.gesture.scrollorientationlocking.Orientation
|
||||
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.unit.dp
|
||||
import androidx.ui.tooling.preview.Preview
|
||||
|
@ -27,9 +32,13 @@ import dev.msfjarvis.lobsters.injection.ApiModule
|
|||
import dev.msfjarvis.lobsters.model.LobstersPost
|
||||
import dev.msfjarvis.lobsters.model.Submitter
|
||||
import dev.msfjarvis.lobsters.ui.theme.LobstersTheme
|
||||
import dev.msfjarvis.lobsters.ui.theme.savedTitleColor
|
||||
import dev.msfjarvis.lobsters.ui.theme.titleColor
|
||||
|
||||
private enum class SwipeState {
|
||||
NotSwiped,
|
||||
FullySwiped,
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LazyItemScope.LobstersItem(
|
||||
post: LobstersPost,
|
||||
|
@ -38,20 +47,29 @@ fun LazyItemScope.LobstersItem(
|
|||
commentOpenAction: (LobstersPost) -> Unit,
|
||||
saveAction: (LobstersPost) -> Unit,
|
||||
) {
|
||||
val liked = remember { mutableStateOf(false) }
|
||||
val titleColor = if (post.isLiked || liked.value) savedTitleColor else titleColor
|
||||
val width = with(DensityAmbient.current) {
|
||||
ConfigurationAmbient.current.screenWidthDp.toDp().toPx()
|
||||
}
|
||||
val swipeableState = rememberSwipeableState(SwipeState.NotSwiped)
|
||||
val anchors = mapOf(0f to SwipeState.NotSwiped, width to SwipeState.FullySwiped)
|
||||
if (swipeableState.offset.value >= (width / 2)) {
|
||||
saveAction.invoke(post)
|
||||
swipeableState.animateTo(SwipeState.NotSwiped)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillParentMaxWidth()
|
||||
.swipeable(
|
||||
state = swipeableState,
|
||||
anchors = anchors,
|
||||
thresholds = { _, _ -> FractionalThreshold(0.5f) },
|
||||
orientation = Orientation.Horizontal
|
||||
)
|
||||
.offsetPx(swipeableState.offset)
|
||||
.clickable(
|
||||
onClick = { linkOpenAction.invoke(post) },
|
||||
onLongClick = { commentOpenAction.invoke(post) },
|
||||
onDoubleClick = {
|
||||
post.isLiked = true
|
||||
liked.value = true
|
||||
saveAction.invoke(post)
|
||||
},
|
||||
),
|
||||
) {
|
||||
Text(
|
||||
|
@ -128,7 +146,8 @@ fun PreviewLobstersItem() {
|
|||
post = item,
|
||||
linkOpenAction = {},
|
||||
commentOpenAction = {},
|
||||
saveAction = {})
|
||||
saveAction = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
val titleColor = Color(0xFF7395D9)
|
||||
val savedTitleColor = Color(0xFFD97373)
|
||||
|
||||
val darkColors = darkColors(
|
||||
primary = Color.White,
|
||||
|
|
|
@ -54,15 +54,9 @@ class LobstersViewModel @ViewModelInject constructor(
|
|||
getMorePostsInternal(false)
|
||||
}
|
||||
|
||||
fun refreshPosts() {
|
||||
apiPage = 1
|
||||
getMorePostsInternal(true)
|
||||
}
|
||||
|
||||
private fun getMorePostsInternal(firstLoad: Boolean) {
|
||||
viewModelScope.launch(coroutineExceptionHandler) {
|
||||
val newPosts = lobstersApi.getHottestPosts(apiPage)
|
||||
.transformLikedFlag()
|
||||
.toList()
|
||||
if (firstLoad) {
|
||||
_posts.value = newPosts
|
||||
|
@ -79,7 +73,6 @@ class LobstersViewModel @ViewModelInject constructor(
|
|||
viewModelScope.launch {
|
||||
savedPostsDao.insertPosts(post)
|
||||
getSavedPosts()
|
||||
_posts.value = _posts.value.transformLikedFlag().toList()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,11 +80,6 @@ class LobstersViewModel @ViewModelInject constructor(
|
|||
viewModelScope.launch {
|
||||
savedPostsDao.deletePostById(post.shortId)
|
||||
getSavedPosts()
|
||||
_posts.value = _posts.value.transformLikedFlag().toList()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun List<LobstersPost>.transformLikedFlag() = map {
|
||||
it.apply { isLiked = savedPostsDao.isLiked(shortId) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,5 +23,6 @@ class LobstersPost(
|
|||
@Json(name = "submitter_user")
|
||||
val submitterUser: Submitter,
|
||||
val tags: List<String>,
|
||||
var isLiked: Boolean = false,
|
||||
@Deprecated("Retained for database compatibility as I am too lazy to write migrations")
|
||||
val isLiked: Boolean = false,
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue