fix: open detail from list (#105)

* fix: sort type not changed, items not found

* fix: prevent opening old details from list
This commit is contained in:
Diego Beraldin 2023-11-06 08:57:46 +01:00 committed by GitHub
parent e771aa3d5e
commit 26272ebbbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 273 additions and 132 deletions

View File

@ -395,7 +395,7 @@ class CommunityDetailScreen(
} }
} }
} }
items(uiState.posts) { post -> items(uiState.posts, { it.id }) { post ->
SwipeableCard( SwipeableCard(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
enabled = uiState.swipeActionsEnabled && !isOnOtherInstance, enabled = uiState.swipeActionsEnabled && !isOnOtherInstance,

View File

@ -84,29 +84,45 @@ class CommunityDetailViewModel(
CommunityDetailMviModel.Intent.LoadNextPage -> loadNextPage() CommunityDetailMviModel.Intent.LoadNextPage -> loadNextPage()
CommunityDetailMviModel.Intent.Refresh -> refresh() CommunityDetailMviModel.Intent.Refresh -> refresh()
is CommunityDetailMviModel.Intent.DownVotePost -> toggleDownVotePost( is CommunityDetailMviModel.Intent.DownVotePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
feedback = intent.feedback, toggleDownVotePost(
) post = post,
feedback = intent.feedback,
)
}
}
is CommunityDetailMviModel.Intent.SavePost -> toggleSavePost( is CommunityDetailMviModel.Intent.SavePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
feedback = intent.feedback, toggleSavePost(
) post = post,
feedback = intent.feedback,
)
}
}
is CommunityDetailMviModel.Intent.UpVotePost -> toggleUpVotePost( is CommunityDetailMviModel.Intent.UpVotePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
feedback = intent.feedback, toggleUpVotePost(
) post = post,
feedback = intent.feedback,
)
}
}
CommunityDetailMviModel.Intent.HapticIndication -> hapticFeedback.vibrate() CommunityDetailMviModel.Intent.HapticIndication -> hapticFeedback.vibrate()
is CommunityDetailMviModel.Intent.ChangeSort -> applySortType(intent.value) is CommunityDetailMviModel.Intent.ChangeSort -> applySortType(intent.value)
CommunityDetailMviModel.Intent.Subscribe -> subscribe() CommunityDetailMviModel.Intent.Subscribe -> subscribe()
CommunityDetailMviModel.Intent.Unsubscribe -> unsubscribe() CommunityDetailMviModel.Intent.Unsubscribe -> unsubscribe()
is CommunityDetailMviModel.Intent.DeletePost -> handlePostDelete(intent.id) is CommunityDetailMviModel.Intent.DeletePost -> handlePostDelete(intent.id)
is CommunityDetailMviModel.Intent.SharePost -> share( is CommunityDetailMviModel.Intent.SharePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
) share(
post = post,
)
}
}
CommunityDetailMviModel.Intent.Block -> blockCommunity() CommunityDetailMviModel.Intent.Block -> blockCommunity()
CommunityDetailMviModel.Intent.BlockInstance -> blockInstance() CommunityDetailMviModel.Intent.BlockInstance -> blockInstance()
@ -115,7 +131,11 @@ class CommunityDetailViewModel(
} }
CommunityDetailMviModel.Intent.ClearRead -> clearRead() CommunityDetailMviModel.Intent.ClearRead -> clearRead()
is CommunityDetailMviModel.Intent.Hide -> hide(post = uiState.value.posts.first { it.id == intent.id }) is CommunityDetailMviModel.Intent.Hide -> {
uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
hide(post = post)
}
}
} }
} }

View File

@ -78,10 +78,11 @@ class ListingTypeBottomSheet(
.fillMaxWidth() .fillMaxWidth()
.onClick( .onClick(
rememberCallback { rememberCallback {
notificationCenter.getObserver( notificationCenter.getAllObservers(
NotificationCenterContractKeys.ChangeFeedType NotificationCenterContractKeys.ChangeFeedType
) ).forEach {
?.invoke(value) it.invoke(value)
}
navigationCoordinator.getBottomNavigator()?.hide() navigationCoordinator.getBottomNavigator()?.hide()
}, },
), ),

View File

@ -112,12 +112,11 @@ internal class SortBottomSheetMain(
SortBottomSheetTop() SortBottomSheetTop()
) )
} else { } else {
notificationCenter.getObserver( notificationCenter.getAllObservers(
NotificationCenterContractKeys.ChangeSortType NotificationCenterContractKeys.ChangeSortType
) ).forEach {
?.also { it.invoke(value)
it.invoke(value) }
}
navigationCoordinator.getBottomNavigator()?.hide() navigationCoordinator.getBottomNavigator()?.hide()
} }
}, },
@ -201,8 +200,10 @@ internal class SortBottomSheetTop(
.fillMaxWidth() .fillMaxWidth()
.onClick( .onClick(
rememberCallback { rememberCallback {
notificationCenter.getObserver(NotificationCenterContractKeys.ChangeSortType) notificationCenter.getAllObservers(
?.also { NotificationCenterContractKeys.ChangeSortType
)
.forEach {
it.invoke(value) it.invoke(value)
} }
navigationCoordinator.getBottomNavigator()?.hide() navigationCoordinator.getBottomNavigator()?.hide()

View File

@ -364,7 +364,7 @@ class UserDetailScreen(
} }
} }
} }
items(uiState.posts) { post -> items(uiState.posts, { it.id }) { post ->
SwipeableCard( SwipeableCard(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
enabled = uiState.swipeActionsEnabled, enabled = uiState.swipeActionsEnabled,
@ -536,7 +536,7 @@ class UserDetailScreen(
) )
} }
} }
items(uiState.comments) { comment -> items(uiState.comments, { it.id }) { comment ->
SwipeableCard( SwipeableCard(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
enabled = uiState.swipeActionsEnabled, enabled = uiState.swipeActionsEnabled,

View File

@ -93,44 +93,68 @@ class UserDetailViewModel(
when (intent) { when (intent) {
is UserDetailMviModel.Intent.ChangeSort -> applySortType(intent.value) is UserDetailMviModel.Intent.ChangeSort -> applySortType(intent.value)
is UserDetailMviModel.Intent.ChangeSection -> changeSection(intent.section) is UserDetailMviModel.Intent.ChangeSection -> changeSection(intent.section)
is UserDetailMviModel.Intent.DownVoteComment -> toggleDownVoteComment( is UserDetailMviModel.Intent.DownVoteComment -> {
comment = uiState.value.comments.first { it.id == intent.id }, uiState.value.comments.firstOrNull { it.id == intent.id }?.also { comment ->
feedback = intent.feedback, toggleDownVoteComment(
) comment = comment,
feedback = intent.feedback,
)
}
}
is UserDetailMviModel.Intent.DownVotePost -> { is UserDetailMviModel.Intent.DownVotePost -> {
toggleDownVote( uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
post = uiState.value.posts.first { it.id == intent.id }, toggleDownVote(
feedback = intent.feedback, post = post,
) feedback = intent.feedback,
)
}
} }
UserDetailMviModel.Intent.HapticIndication -> hapticFeedback.vibrate() UserDetailMviModel.Intent.HapticIndication -> hapticFeedback.vibrate()
UserDetailMviModel.Intent.LoadNextPage -> loadNextPage() UserDetailMviModel.Intent.LoadNextPage -> loadNextPage()
UserDetailMviModel.Intent.Refresh -> refresh() UserDetailMviModel.Intent.Refresh -> refresh()
is UserDetailMviModel.Intent.SaveComment -> toggleSaveComment( is UserDetailMviModel.Intent.SaveComment -> {
comment = uiState.value.comments.first { it.id == intent.id }, uiState.value.comments.firstOrNull { it.id == intent.id }?.also { comment ->
feedback = intent.feedback, toggleSaveComment(
) comment = comment,
feedback = intent.feedback,
)
}
}
is UserDetailMviModel.Intent.SavePost -> toggleSave( is UserDetailMviModel.Intent.SavePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
feedback = intent.feedback, toggleSave(
) post = post,
feedback = intent.feedback,
)
}
}
is UserDetailMviModel.Intent.UpVoteComment -> toggleUpVoteComment( is UserDetailMviModel.Intent.UpVoteComment -> {
comment = uiState.value.comments.first { it.id == intent.id }, uiState.value.comments.firstOrNull { it.id == intent.id }?.also { comment ->
feedback = intent.feedback, toggleUpVoteComment(
) comment = comment,
feedback = intent.feedback,
)
}
}
is UserDetailMviModel.Intent.UpVotePost -> toggleUpVote( is UserDetailMviModel.Intent.UpVotePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
feedback = intent.feedback, toggleUpVote(
) post = post,
feedback = intent.feedback,
)
}
}
is UserDetailMviModel.Intent.SharePost -> share( is UserDetailMviModel.Intent.SharePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
) share(post = post)
}
}
UserDetailMviModel.Intent.Block -> blockUser() UserDetailMviModel.Intent.Block -> blockUser()
UserDetailMviModel.Intent.BlockInstance -> blockInstance() UserDetailMviModel.Intent.BlockInstance -> blockInstance()

View File

@ -10,9 +10,23 @@ fun rememberCallback(key: Any = Unit, block: () -> Unit): () -> Unit {
} }
} }
@Composable
fun rememberCallback(key1: Any = Unit, key2: Any, block: () -> Unit): () -> Unit {
return remember(key1, key2) {
block
}
}
@Composable @Composable
fun <T, U> rememberCallbackArgs(key: Any = Unit, block: (T) -> U): (T) -> U { fun <T, U> rememberCallbackArgs(key: Any = Unit, block: (T) -> U): (T) -> U {
return remember(key) { return remember(key) {
block block
} }
} }
@Composable
fun <T, U> rememberCallbackArgs(key1: Any = Unit, key2: Any, block: (T) -> U): (T) -> U {
return remember(key1, key2) {
block
}
}

View File

@ -60,6 +60,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Floatin
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createpost.CreatePostScreen import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createpost.CreatePostScreen
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getDrawerCoordinator import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getDrawerCoordinator
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getFabNestedScrollConnection import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getFabNestedScrollConnection
@ -279,7 +280,7 @@ class PostListScreen : Screen {
} }
} }
} }
items(uiState.posts) { post -> items(uiState.posts, key = { it.id }) { post ->
SwipeableCard( SwipeableCard(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
enabled = uiState.swipeActionsEnabled, enabled = uiState.swipeActionsEnabled,
@ -362,13 +363,13 @@ class PostListScreen : Screen {
), ),
) )
}, },
// onReply = rememberCallback(model) { onReply = rememberCallback(model) {
// val screen = CreateCommentScreen( val screen = CreateCommentScreen(
// originalPost = post, originalPost = post,
// ) )
// bottomSheetNavigator.show(screen) navigationCoordinator.getBottomNavigator()?.show(screen)
// }, },
onImageClick = rememberCallbackArgs(model) { url -> onImageClick = rememberCallbackArgs(model, post) { url ->
model.reduce(PostListMviModel.Intent.MarkAsRead(post.id)) model.reduce(PostListMviModel.Intent.MarkAsRead(post.id))
navigationCoordinator.getRootNavigator()?.push( navigationCoordinator.getRootNavigator()?.push(
ZoomableImageScreen(url) ZoomableImageScreen(url)

View File

@ -141,30 +141,46 @@ class PostListViewModel(
is PostListMviModel.Intent.ChangeSort -> applySortType(intent.value) is PostListMviModel.Intent.ChangeSort -> applySortType(intent.value)
is PostListMviModel.Intent.ChangeListing -> applyListingType(intent.value) is PostListMviModel.Intent.ChangeListing -> applyListingType(intent.value)
is PostListMviModel.Intent.DownVotePost -> toggleDownVote( is PostListMviModel.Intent.DownVotePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
feedback = intent.feedback, toggleDownVote(
) post = post,
feedback = intent.feedback,
)
}
}
is PostListMviModel.Intent.SavePost -> toggleSave( is PostListMviModel.Intent.SavePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
feedback = intent.feedback, toggleSave(
) post = post,
feedback = intent.feedback,
)
}
}
is PostListMviModel.Intent.UpVotePost -> toggleUpVote( is PostListMviModel.Intent.UpVotePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
feedback = intent.feedback, toggleUpVote(
) post = post,
feedback = intent.feedback,
)
}
}
PostListMviModel.Intent.HapticIndication -> hapticFeedback.vibrate() PostListMviModel.Intent.HapticIndication -> hapticFeedback.vibrate()
is PostListMviModel.Intent.HandlePostUpdate -> handlePostUpdate(intent.post) is PostListMviModel.Intent.HandlePostUpdate -> handlePostUpdate(intent.post)
is PostListMviModel.Intent.DeletePost -> handlePostDelete(intent.id) is PostListMviModel.Intent.DeletePost -> handlePostDelete(intent.id)
is PostListMviModel.Intent.SharePost -> { is PostListMviModel.Intent.SharePost -> {
share(post = uiState.value.posts.first { it.id == intent.id }) uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
share(post = post)
}
} }
is PostListMviModel.Intent.MarkAsRead -> { is PostListMviModel.Intent.MarkAsRead -> {
markAsRead(post = uiState.value.posts.first { it.id == intent.id }) uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
markAsRead(post = post)
}
} }
PostListMviModel.Intent.ClearRead -> clearRead() PostListMviModel.Intent.ClearRead -> clearRead()

View File

@ -181,7 +181,7 @@ internal object ProfileLoggedScreen : Tab {
} }
} }
} }
items(uiState.posts) { post -> items(uiState.posts, { it.id }) { post ->
PostCard( PostCard(
post = post, post = post,
postLayout = uiState.postLayout, postLayout = uiState.postLayout,
@ -288,7 +288,7 @@ internal object ProfileLoggedScreen : Tab {
) )
} }
} }
items(uiState.comments) { comment -> items(uiState.comments, { it.id }) { comment ->
CommentCard( CommentCard(
modifier = Modifier.background(MaterialTheme.colorScheme.background), modifier = Modifier.background(MaterialTheme.colorScheme.background),
comment = comment, comment = comment,

View File

@ -115,39 +115,65 @@ class ProfileLoggedViewModel(
refresh() refresh()
} }
is ProfileLoggedMviModel.Intent.SharePost -> share( is ProfileLoggedMviModel.Intent.SharePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
) share(post = post)
}
}
is ProfileLoggedMviModel.Intent.DownVoteComment -> toggleDownVoteComment( is ProfileLoggedMviModel.Intent.DownVoteComment -> {
comment = uiState.value.comments.first { it.id == intent.id }, uiState.value.comments.firstOrNull { it.id == intent.id }?.also { comment ->
feedback = intent.feedback, toggleDownVoteComment(
) comment = comment,
feedback = intent.feedback,
)
}
}
is ProfileLoggedMviModel.Intent.DownVotePost -> toggleDownVotePost( is ProfileLoggedMviModel.Intent.DownVotePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
feedback = intent.feedback, toggleDownVotePost(
) post = post,
feedback = intent.feedback,
)
}
}
is ProfileLoggedMviModel.Intent.SaveComment -> toggleSaveComment( is ProfileLoggedMviModel.Intent.SaveComment -> {
comment = uiState.value.comments.first { it.id == intent.id }, uiState.value.comments.firstOrNull { it.id == intent.id }?.also { comment ->
feedback = intent.feedback, toggleSaveComment(
) comment = comment,
feedback = intent.feedback,
)
}
}
is ProfileLoggedMviModel.Intent.SavePost -> toggleSavePost( is ProfileLoggedMviModel.Intent.SavePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
feedback = intent.feedback, toggleSavePost(
) post = post,
feedback = intent.feedback,
)
}
}
is ProfileLoggedMviModel.Intent.UpVoteComment -> toggleUpVoteComment( is ProfileLoggedMviModel.Intent.UpVoteComment -> {
comment = uiState.value.comments.first { it.id == intent.id }, uiState.value.comments.firstOrNull { it.id == intent.id }?.also { comment ->
feedback = intent.feedback, toggleUpVoteComment(
) comment = comment,
feedback = intent.feedback,
)
}
}
is ProfileLoggedMviModel.Intent.UpVotePost -> toggleUpVotePost( is ProfileLoggedMviModel.Intent.UpVotePost -> {
post = uiState.value.posts.first { it.id == intent.id }, uiState.value.posts.firstOrNull { it.id == intent.id }?.also { post ->
feedback = intent.feedback, toggleUpVotePost(
) post = post,
feedback = intent.feedback,
)
}
}
} }
} }

View File

@ -301,7 +301,15 @@ class ExploreScreen : Screen {
} }
} }
} }
items(uiState.results) { result -> items(uiState.results, key = {
when (it) {
is PostModel -> "post" + it.id
is CommentModel -> "comment" + it.id
is UserModel -> "user" + it.id
is CommunityModel -> "community" + it.id
else -> ""
}
}) { result ->
when (result) { when (result) {
is CommunityModel -> { is CommunityModel -> {
CommunityItem( CommunityItem(

View File

@ -130,35 +130,65 @@ class ExploreViewModel(
is ExploreMviModel.Intent.SetListingType -> changeListingType(intent.value) is ExploreMviModel.Intent.SetListingType -> changeListingType(intent.value)
is ExploreMviModel.Intent.SetSortType -> changeSortType(intent.value) is ExploreMviModel.Intent.SetSortType -> changeSortType(intent.value)
is ExploreMviModel.Intent.SetResultType -> changeResultType(intent.value) is ExploreMviModel.Intent.SetResultType -> changeResultType(intent.value)
is ExploreMviModel.Intent.DownVotePost -> toggleDownVote( is ExploreMviModel.Intent.DownVotePost -> {
post = uiState.value.results.first { (it as? PostModel)?.id == intent.id } as PostModel, uiState.value.results.firstOrNull { (it as? PostModel)?.id == intent.id }
feedback = intent.feedback, ?.also { post ->
) toggleDownVote(
post = post as PostModel,
feedback = intent.feedback,
)
}
}
is ExploreMviModel.Intent.SavePost -> toggleSave( is ExploreMviModel.Intent.SavePost -> {
post = uiState.value.results.first { (it as? PostModel)?.id == intent.id } as PostModel, uiState.value.results.firstOrNull { (it as? PostModel)?.id == intent.id }
feedback = intent.feedback, ?.also { post ->
) toggleSave(
post = post as PostModel,
feedback = intent.feedback,
)
}
}
is ExploreMviModel.Intent.UpVotePost -> toggleUpVote( is ExploreMviModel.Intent.UpVotePost -> {
post = uiState.value.results.first { (it as? PostModel)?.id == intent.id } as PostModel, uiState.value.results.firstOrNull { (it as? PostModel)?.id == intent.id }
feedback = intent.feedback, ?.also { post ->
) toggleUpVote(
post = post as PostModel,
feedback = intent.feedback,
)
}
}
is ExploreMviModel.Intent.DownVoteComment -> toggleDownVoteComment( is ExploreMviModel.Intent.DownVoteComment -> {
comment = uiState.value.results.first { (it as? CommentModel)?.id == intent.id } as CommentModel, uiState.value.results.firstOrNull { (it as? CommentModel)?.id == intent.id }
feedback = intent.feedback, ?.also { comment ->
) toggleDownVoteComment(
comment = comment as CommentModel,
feedback = intent.feedback,
)
}
}
is ExploreMviModel.Intent.SaveComment -> toggleSaveComment( is ExploreMviModel.Intent.SaveComment -> {
comment = uiState.value.results.first { (it as? CommentModel)?.id == intent.id } as CommentModel, uiState.value.results.firstOrNull { (it as? CommentModel)?.id == intent.id }
feedback = intent.feedback, ?.also { comment ->
) toggleSaveComment(
comment = comment as CommentModel,
feedback = intent.feedback,
)
}
}
is ExploreMviModel.Intent.UpVoteComment -> toggleUpVoteComment( is ExploreMviModel.Intent.UpVoteComment -> {
comment = uiState.value.results.first { (it as? CommentModel)?.id == intent.id } as CommentModel, uiState.value.results.firstOrNull { (it as? CommentModel)?.id == intent.id }
feedback = intent.feedback, ?.also { comment ->
) toggleUpVoteComment(
comment = comment as CommentModel,
feedback = intent.feedback,
)
}
}
} }
} }