refactor(android): move post save state logic to a Paging transform

Fixes #349
This commit is contained in:
Harsh Shandilya 2022-12-08 01:31:26 +05:30
parent bd5cf0f167
commit 3829abeb8f
No known key found for this signature in database
5 changed files with 23 additions and 48 deletions

View file

@ -179,7 +179,6 @@ fun LobstersApp(
NetworkPosts( NetworkPosts(
lazyPagingItems = hottestPosts, lazyPagingItems = hottestPosts,
listState = hottestListState, listState = hottestListState,
isPostSaved = viewModel::isPostSaved,
postActions = postActions, postActions = postActions,
) )
} }
@ -190,7 +189,6 @@ fun LobstersApp(
NetworkPosts( NetworkPosts(
lazyPagingItems = newestPosts, lazyPagingItems = newestPosts,
listState = newestListState, listState = newestListState,
isPostSaved = viewModel::isPostSaved,
postActions = postActions, postActions = postActions,
) )
} }

View file

@ -13,6 +13,7 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Divider import androidx.compose.material3.Divider
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import dev.msfjarvis.claw.common.posts.LobstersCard
import dev.msfjarvis.claw.common.posts.PostActions import dev.msfjarvis.claw.common.posts.PostActions
import dev.msfjarvis.claw.common.ui.decorations.MonthHeader import dev.msfjarvis.claw.common.ui.decorations.MonthHeader
import dev.msfjarvis.claw.database.local.SavedPost import dev.msfjarvis.claw.database.local.SavedPost
@ -33,9 +34,9 @@ fun DatabasePosts(
items.forEach { (month, posts) -> items.forEach { (month, posts) ->
stickyHeader { MonthHeader(month = month) } stickyHeader { MonthHeader(month = month) }
items(posts) { item -> items(posts) { item ->
ListItem( LobstersCard(
item = item, post = item,
isSaved = { true }, isSaved = true,
postActions = postActions, postActions = postActions,
) )

View file

@ -1,31 +0,0 @@
/*
* Copyright © 2021-2022 Harsh Shandilya.
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/
package dev.msfjarvis.claw.android.ui.lists
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.produceState
import androidx.compose.ui.Modifier
import dev.msfjarvis.claw.common.posts.LobstersCard
import dev.msfjarvis.claw.common.posts.PostActions
import dev.msfjarvis.claw.database.local.SavedPost
@Composable
fun ListItem(
item: SavedPost,
isSaved: suspend (SavedPost) -> Boolean,
postActions: PostActions,
modifier: Modifier = Modifier,
) {
val saved by produceState(false, item) { value = isSaved(item) }
LobstersCard(
post = item,
isSaved = saved,
postActions = postActions,
modifier = modifier,
)
}

View file

@ -27,19 +27,18 @@ import androidx.compose.ui.unit.dp
import androidx.paging.LoadState import androidx.paging.LoadState
import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.items import androidx.paging.compose.items
import dev.msfjarvis.claw.common.posts.LobstersCard
import dev.msfjarvis.claw.common.posts.PostActions import dev.msfjarvis.claw.common.posts.PostActions
import dev.msfjarvis.claw.common.posts.toDbModel import dev.msfjarvis.claw.common.posts.toDbModel
import dev.msfjarvis.claw.common.ui.NetworkError import dev.msfjarvis.claw.common.ui.NetworkError
import dev.msfjarvis.claw.common.ui.ProgressBar import dev.msfjarvis.claw.common.ui.ProgressBar
import dev.msfjarvis.claw.database.local.SavedPost
import dev.msfjarvis.claw.model.LobstersPost import dev.msfjarvis.claw.model.LobstersPost
@OptIn(ExperimentalMaterialApi::class) @OptIn(ExperimentalMaterialApi::class)
@Composable @Composable
fun NetworkPosts( fun NetworkPosts(
lazyPagingItems: LazyPagingItems<LobstersPost>, lazyPagingItems: LazyPagingItems<Pair<LobstersPost, Boolean>>,
listState: LazyListState, listState: LazyListState,
isPostSaved: suspend (SavedPost) -> Boolean,
postActions: PostActions, postActions: PostActions,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
@ -59,10 +58,10 @@ fun NetworkPosts(
) { ) {
items(lazyPagingItems) { item -> items(lazyPagingItems) { item ->
if (item != null) { if (item != null) {
val dbModel = item.toDbModel() val (post, saved) = item
ListItem( LobstersCard(
item = dbModel, post = post.toDbModel(),
isSaved = isPostSaved, isSaved = saved,
postActions = postActions, postActions = postActions,
) )

View file

@ -10,6 +10,8 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.paging.Pager import androidx.paging.Pager
import androidx.paging.PagingConfig import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import androidx.paging.map
import com.deliveryhero.whetstone.viewmodel.ContributesViewModel import com.deliveryhero.whetstone.viewmodel.ContributesViewModel
import com.slack.eithernet.ApiResult.Failure import com.slack.eithernet.ApiResult.Failure
import com.slack.eithernet.ApiResult.Success import com.slack.eithernet.ApiResult.Success
@ -43,10 +45,16 @@ constructor(
Pager(PagingConfig(pageSize = 20)) { pagingSourceFactory.create(api::getHottestPosts) } Pager(PagingConfig(pageSize = 20)) { pagingSourceFactory.create(api::getHottestPosts) }
val hottestPosts val hottestPosts
get() = hottestPostsPager.flow get() =
hottestPostsPager.flow
.map { pagingData -> pagingData.map { item -> item to isPostSaved(item.shortId) } }
.cachedIn(viewModelScope)
val newestPosts val newestPosts
get() = newestPostsPager.flow get() =
newestPostsPager.flow
.map { pagingData -> pagingData.map { item -> item to isPostSaved(item.shortId) } }
.cachedIn(viewModelScope)
private val savedPostsFlow private val savedPostsFlow
get() = savedPostsRepository.savedPosts get() = savedPostsRepository.savedPosts
@ -59,13 +67,13 @@ constructor(
return sorted.groupBy { post -> post.createdAt.toLocalDateTime().month } return sorted.groupBy { post -> post.createdAt.toLocalDateTime().month }
} }
suspend fun isPostSaved(post: SavedPost): Boolean { private suspend fun isPostSaved(shortId: String): Boolean {
return savedPostsFlow.first().any { savedPost -> savedPost.shortId == post.shortId } return savedPostsFlow.first().any { savedPost -> savedPost.shortId == shortId }
} }
fun toggleSave(post: SavedPost) { fun toggleSave(post: SavedPost) {
viewModelScope.launch(ioDispatcher) { viewModelScope.launch(ioDispatcher) {
val saved = isPostSaved(post) val saved = isPostSaved(post.shortId)
if (saved) { if (saved) {
savedPostsRepository.removePost(post) savedPostsRepository.removePost(post)
} else { } else {