feat(common): add swipe action for saving posts

This commit is contained in:
Harsh Shandilya 2023-11-07 13:09:05 +05:30
parent c721b8b1da
commit 7a648a77b0
No known key found for this signature in database
3 changed files with 35 additions and 48 deletions

View file

@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Start work on integrating Shiori (https://github.com/go-shiori/shiori/) as a * Start work on integrating Shiori (https://github.com/go-shiori/shiori/) as a
remote backup target for saved posts remote backup target for saved posts
* Make top app bar color match bottom bar * Make top app bar color match bottom bar
* Add a left-to-right swipe action to save a post
## [1.37.0] - 2023-10-06 ## [1.37.0] - 2023-10-06

View file

@ -8,10 +8,15 @@ package dev.msfjarvis.claw.android.ui.lists
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.Reply import androidx.compose.material.icons.automirrored.filled.Reply
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.FavoriteBorder
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.produceState import androidx.compose.runtime.produceState
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.graphics.vector.rememberVectorPainter
import dev.msfjarvis.claw.common.posts.LobstersCard import dev.msfjarvis.claw.common.posts.LobstersCard
@ -29,20 +34,37 @@ fun LobstersListItem(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val read by produceState(false, item.shortId) { value = isRead(item.shortId) } val read by produceState(false, item.shortId) { value = isRead(item.shortId) }
var saved by remember(item.shortId) { mutableStateOf(isSaved(item)) }
val commentsAction = val commentsAction =
SwipeAction( SwipeAction(
icon = rememberVectorPainter(Icons.AutoMirrored.Filled.Reply), icon = rememberVectorPainter(Icons.AutoMirrored.Filled.Reply),
background = MaterialTheme.colorScheme.tertiary, background = MaterialTheme.colorScheme.tertiary,
onSwipe = { postActions.viewCommentsPage(item.commentsUrl) }, onSwipe = { postActions.viewCommentsPage(item.commentsUrl) },
) )
val saveAction =
SwipeAction(
icon =
rememberVectorPainter(if (saved) Icons.Filled.Favorite else Icons.Filled.FavoriteBorder),
background = MaterialTheme.colorScheme.tertiary,
onSwipe = {
postActions.toggleSave(item)
saved = isSaved(item)
},
)
SwipeableActionsBox( SwipeableActionsBox(
startActions = listOf(saveAction),
endActions = listOf(commentsAction), endActions = listOf(commentsAction),
) { ) {
LobstersCard( LobstersCard(
post = item, post = item,
isSaved = isSaved(item), isSaved = saved,
isRead = read, isRead = read,
postActions = postActions, viewComments = postActions::viewComments,
toggleSave = { post ->
postActions.toggleSave(post)
saved = isSaved(post)
},
viewPost = postActions::viewPost,
modifier = modifier, modifier = modifier,
) )
} }

View file

@ -36,10 +36,6 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
@ -52,9 +48,6 @@ import dev.msfjarvis.claw.common.theme.LobstersTheme
import dev.msfjarvis.claw.common.ui.NetworkImage import dev.msfjarvis.claw.common.ui.NetworkImage
import dev.msfjarvis.claw.common.ui.preview.ThemePreviews import dev.msfjarvis.claw.common.ui.preview.ThemePreviews
import dev.msfjarvis.claw.database.local.SavedPost import dev.msfjarvis.claw.database.local.SavedPost
import dev.msfjarvis.claw.model.LinkMetadata
import dev.msfjarvis.claw.model.LobstersPostDetails
import dev.msfjarvis.claw.model.User
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
@ -63,15 +56,16 @@ fun LobstersCard(
post: SavedPost, post: SavedPost,
isSaved: Boolean, isSaved: Boolean,
isRead: Boolean, isRead: Boolean,
postActions: PostActions, viewComments: (String) -> Unit,
toggleSave: (SavedPost) -> Unit,
viewPost: (String, String, String) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
var localSavedState by remember(post, isSaved) { mutableStateOf(isSaved) }
Box( Box(
modifier = modifier =
modifier modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { postActions.viewPost(post.shortId, post.url, post.commentsUrl) } .clickable { viewPost(post.shortId, post.url, post.commentsUrl) }
.background(MaterialTheme.colorScheme.background) .background(MaterialTheme.colorScheme.background)
.padding(start = 16.dp, top = 16.dp, end = 4.dp, bottom = 16.dp), .padding(start = 16.dp, top = 16.dp, end = 4.dp, bottom = 16.dp),
) { ) {
@ -90,12 +84,8 @@ fun LobstersCard(
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
SaveButton( SaveButton(
isSaved = localSavedState, isSaved = isSaved,
modifier = modifier = Modifier.clickable(role = Role.Button) { toggleSave(post) },
Modifier.clickable(role = Role.Button) {
localSavedState = !localSavedState
postActions.toggleSave(post)
},
) )
HorizontalDivider(modifier = Modifier.width(48.dp)) HorizontalDivider(modifier = Modifier.width(48.dp))
CommentsButton( CommentsButton(
@ -103,7 +93,7 @@ fun LobstersCard(
modifier = modifier =
Modifier.clickable( Modifier.clickable(
role = Role.Button, role = Role.Button,
onClick = { postActions.viewComments(post.shortId) }, onClick = { viewComments(post.shortId) },
), ),
) )
} }
@ -267,35 +257,9 @@ fun LobstersCardPreview() {
), ),
isRead = true, isRead = true,
isSaved = true, isSaved = true,
postActions = viewPost = { _, _, _ -> },
object : PostActions { viewComments = {},
override fun viewPost(postId: String, postUrl: String, commentsUrl: String) {} toggleSave = {},
override fun viewComments(postId: String) {}
override fun viewCommentsPage(commentsUrl: String) {}
override fun toggleSave(post: SavedPost) {}
override suspend fun getComments(postId: String): LobstersPostDetails {
return LobstersPostDetails(
shortId = "ooga",
title = "Simple Anomaly Detection Using Plain SQL",
url = "https://hakibenita.com/sql-anomaly-detection",
createdAt = "2020-09-21T08:04:24.000-05:00",
commentCount = 1,
commentsUrl = "https://lobste.rs/s/q1hh1g/simple_anomaly_detection_using_plain_sql",
tags = listOf("databases", "apis"),
description = "",
submitter = User("Haki", "", "", "", ""),
comments = emptyList(),
)
}
override suspend fun getLinkMetadata(url: String): LinkMetadata {
return LinkMetadata("", "")
}
},
) )
} }
} }