mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-09 12:58:43 +01:00
fix: post not updated in list when upvoted or downvoted from detail screen
This commit is contained in:
parent
c47bb2be0a
commit
a7ca24bdea
@ -72,6 +72,7 @@ val commonUiModule = module {
|
||||
postsRepository = get(),
|
||||
hapticFeedback = get(),
|
||||
keyStore = get(),
|
||||
notificationCenter = get(),
|
||||
)
|
||||
}
|
||||
factory {
|
||||
|
@ -5,6 +5,7 @@ import com.github.diegoberaldin.racconforlemmy.core.utils.HapticFeedback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.KeyStoreKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.TemporaryKeyStore
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||
@ -180,7 +181,9 @@ class PostDetailViewModel(
|
||||
post = post,
|
||||
voted = newValue,
|
||||
)
|
||||
notificationCenter.send(NotificationCenter.Event.PostUpdate(newPost))
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.PostUpdate)?.also {
|
||||
it.invoke(newPost)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
mvi.updateState { it.copy(post = post) }
|
||||
@ -210,7 +213,9 @@ class PostDetailViewModel(
|
||||
post = post,
|
||||
downVoted = newValue,
|
||||
)
|
||||
notificationCenter.send(NotificationCenter.Event.PostUpdate(newPost))
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.PostUpdate)?.also {
|
||||
it.invoke(newPost)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
mvi.updateState { it.copy(post = post) }
|
||||
@ -239,7 +244,9 @@ class PostDetailViewModel(
|
||||
post = post,
|
||||
saved = newValue,
|
||||
)
|
||||
notificationCenter.send(NotificationCenter.Event.PostUpdate(newPost))
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.PostUpdate)?.also {
|
||||
it.invoke(newPost)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
mvi.updateState { it.copy(post = post) }
|
||||
@ -278,7 +285,6 @@ class PostDetailViewModel(
|
||||
comment = comment,
|
||||
voted = newValue,
|
||||
)
|
||||
notificationCenter.send(NotificationCenter.Event.CommentUpdate(newComment))
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
mvi.updateState {
|
||||
@ -324,7 +330,6 @@ class PostDetailViewModel(
|
||||
comment = comment,
|
||||
downVoted = newValue,
|
||||
)
|
||||
notificationCenter.send(NotificationCenter.Event.CommentUpdate(newComment))
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
mvi.updateState {
|
||||
@ -373,7 +378,6 @@ class PostDetailViewModel(
|
||||
comment = comment,
|
||||
saved = newValue,
|
||||
)
|
||||
notificationCenter.send(NotificationCenter.Event.CommentUpdate(newComment))
|
||||
} catch (e: Throwable) {
|
||||
e.printStackTrace()
|
||||
mvi.updateState {
|
||||
|
@ -4,6 +4,8 @@ import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.racconforlemmy.core.utils.HapticFeedback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.KeyStoreKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.TemporaryKeyStore
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||
@ -24,13 +26,25 @@ class UserPostsViewModel(
|
||||
private val postsRepository: PostsRepository,
|
||||
private val hapticFeedback: HapticFeedback,
|
||||
private val keyStore: TemporaryKeyStore,
|
||||
private val notificationCenter: NotificationCenter,
|
||||
) : ScreenModel,
|
||||
MviModel<UserPostsMviModel.Intent, UserPostsMviModel.UiState, UserPostsMviModel.Effect> by mvi {
|
||||
|
||||
private var currentPage: Int = 1
|
||||
|
||||
fun finalize() {
|
||||
notificationCenter.removeObserver(this::class.simpleName.orEmpty())
|
||||
}
|
||||
|
||||
override fun onStarted() {
|
||||
mvi.onStarted()
|
||||
|
||||
notificationCenter.addObserver({
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdate)
|
||||
|
||||
mvi.scope.launch(Dispatchers.IO) {
|
||||
val user = userRepository.get(user.id)
|
||||
if (user != null) {
|
||||
@ -248,4 +262,18 @@ class UserPostsViewModel(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePostUpdate(post: PostModel) {
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
posts = it.posts.map { p ->
|
||||
if (p.id == post.id) {
|
||||
post
|
||||
} else {
|
||||
p
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ object DefaultNotificationCenter : NotificationCenter {
|
||||
}
|
||||
|
||||
override fun addObserver(observer: (Any) -> Unit, key: String, contract: String) {
|
||||
removeObserver(key)
|
||||
|
||||
val mapKey = key to contract
|
||||
registry[mapKey] = observer
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.notifications
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
|
||||
/**
|
||||
@ -13,8 +11,6 @@ interface NotificationCenter {
|
||||
* Available event types.
|
||||
*/
|
||||
sealed interface Event {
|
||||
data class PostUpdate(val post: PostModel) : Event
|
||||
data class CommentUpdate(val comment: CommentModel) : Event
|
||||
object Logout : Event
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.notifications
|
||||
|
||||
object NotificationCenterContractKeys {
|
||||
const val PostUpdate = "postUpdate"
|
||||
}
|
@ -16,6 +16,7 @@ interface PostListMviModel :
|
||||
data class UpVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val index: Int, val feedback: Boolean = false) : Intent
|
||||
data class HandlePostUpdate(val post: PostModel) : Intent
|
||||
object HapticIndication : Intent
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ListingType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.home.di.getHomeScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.home.ui.HomeTab
|
||||
|
@ -5,6 +5,7 @@ import com.github.diegoberaldin.racconforlemmy.core.utils.HapticFeedback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.KeyStoreKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.preferences.TemporaryKeyStore
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.ApiConfigurationRepository
|
||||
@ -35,6 +36,10 @@ class PostListViewModel(
|
||||
|
||||
private var currentPage: Int = 1
|
||||
|
||||
fun finalize() {
|
||||
notificationCenter.removeObserver(this::class.simpleName.orEmpty())
|
||||
}
|
||||
|
||||
override fun reduce(intent: PostListMviModel.Intent) {
|
||||
when (intent) {
|
||||
PostListMviModel.Intent.LoadNextPage -> loadNextPage()
|
||||
@ -57,15 +62,13 @@ class PostListViewModel(
|
||||
)
|
||||
|
||||
PostListMviModel.Intent.HapticIndication -> hapticFeedback.vibrate()
|
||||
is PostListMviModel.Intent.HandlePostUpdate -> handlePostUpdate(intent.post)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDisposed() {
|
||||
mvi.onDisposed()
|
||||
}
|
||||
|
||||
override fun onStarted() {
|
||||
mvi.onStarted()
|
||||
|
||||
val listingType = keyStore[KeyStoreKeys.DefaultListingType, 0].toListingType()
|
||||
val sortType = keyStore[KeyStoreKeys.DefaultPostSortType, 0].toSortType()
|
||||
mvi.updateState {
|
||||
@ -77,33 +80,18 @@ class PostListViewModel(
|
||||
)
|
||||
}
|
||||
|
||||
notificationCenter.addObserver({
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdate)
|
||||
|
||||
mvi.scope.launch(Dispatchers.Main) {
|
||||
identityRepository.authToken.map { !it.isNullOrEmpty() }.onEach { isLogged ->
|
||||
mvi.updateState {
|
||||
it.copy(isLogged = isLogged)
|
||||
}
|
||||
}.launchIn(this)
|
||||
notificationCenter.events
|
||||
.onEach { evt ->
|
||||
when (evt) {
|
||||
is NotificationCenter.Event.PostUpdate -> {
|
||||
val newPost = evt.post
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
posts = it.posts.map { p ->
|
||||
if (p.id == newPost.id) {
|
||||
newPost
|
||||
} else {
|
||||
p
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}.launchIn(this)
|
||||
notificationCenter.events
|
||||
.onEach { evt ->
|
||||
when (evt) {
|
||||
@ -328,4 +316,18 @@ class PostListViewModel(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePostUpdate(post: PostModel) {
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
posts = it.posts.map { p ->
|
||||
if (p.id == post.id) {
|
||||
post
|
||||
} else {
|
||||
p
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,10 @@ package com.github.diegoberaldin.raccoonforlemmy.feature.profile.content.logged.
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.SortType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostsRepository
|
||||
@ -18,14 +21,25 @@ class ProfilePostsViewModel(
|
||||
private val savedOnly: Boolean = false,
|
||||
private val identityRepository: IdentityRepository,
|
||||
private val userRepository: UserRepository,
|
||||
private val notificationCenter: NotificationCenter,
|
||||
) : ScreenModel,
|
||||
MviModel<ProfilePostsMviModel.Intent, ProfilePostsMviModel.UiState, ProfilePostsMviModel.Effect> by mvi {
|
||||
|
||||
private var currentPage: Int = 1
|
||||
|
||||
fun finalize() {
|
||||
notificationCenter.removeObserver(this::class.simpleName.orEmpty())
|
||||
}
|
||||
|
||||
override fun onStarted() {
|
||||
mvi.onStarted()
|
||||
|
||||
notificationCenter.addObserver({
|
||||
(it as? PostModel)?.also { post ->
|
||||
handlePostUpdate(post)
|
||||
}
|
||||
}, this::class.simpleName.orEmpty(), NotificationCenterContractKeys.PostUpdate)
|
||||
|
||||
if (mvi.uiState.value.posts.isEmpty()) {
|
||||
refresh()
|
||||
}
|
||||
@ -79,4 +93,18 @@ class ProfilePostsViewModel(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePostUpdate(post: PostModel) {
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
posts = it.posts.map { p ->
|
||||
if (p.id == post.id) {
|
||||
post
|
||||
} else {
|
||||
p
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ val profileTabModule = module {
|
||||
savedOnly = params[1],
|
||||
identityRepository = get(),
|
||||
userRepository = get(),
|
||||
notificationCenter = get(),
|
||||
)
|
||||
}
|
||||
factory { params ->
|
||||
|
Loading…
x
Reference in New Issue
Block a user