From 633b17f91c55a5bed786fd143f4fd0b05d7b3ad8 Mon Sep 17 00:00:00 2001 From: HuanCheng65 <22636177+HuanCheng65@users.noreply.github.com> Date: Sun, 8 Oct 2023 22:06:13 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=83=A8=E5=88=86=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=20key=20=E5=AF=BC=E8=87=B4=E9=97=AA=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tieba/post/ui/models/ThreadItemData.kt | 12 +++++++- .../threadlist/ForumThreadListViewModel.kt | 7 +++-- .../page/main/explore/concern/ConcernPage.kt | 5 ++-- .../main/explore/concern/ConcernViewModel.kt | 29 ++++++++++++------- .../personalized/PersonalizedViewModel.kt | 19 +++++++----- 5 files changed, 49 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/models/ThreadItemData.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/models/ThreadItemData.kt index 868878c6..588a3d78 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/models/ThreadItemData.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/models/ThreadItemData.kt @@ -7,6 +7,8 @@ import com.huanchengfly.tieba.post.api.models.protos.personalized.ThreadPersonal import com.huanchengfly.tieba.post.arch.ImmutableHolder import com.huanchengfly.tieba.post.utils.BlockManager.shouldBlock import com.huanchengfly.tieba.post.utils.appPreferences +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList @Immutable data class ThreadItemData( @@ -14,4 +16,12 @@ data class ThreadItemData( val blocked: Boolean = thread.get { shouldBlock() }, val personalized: ImmutableHolder? = null, val hidden: Boolean = blocked && App.INSTANCE.appPreferences.hideBlockedContent, -) \ No newline at end of file +) + +fun List.distinctById(): ImmutableList { + return distinctBy { + it.thread.get { + id + } + }.toImmutableList() +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/forum/threadlist/ForumThreadListViewModel.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/forum/threadlist/ForumThreadListViewModel.kt index 4535b59f..59c42107 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/forum/threadlist/ForumThreadListViewModel.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/forum/threadlist/ForumThreadListViewModel.kt @@ -20,6 +20,7 @@ import com.huanchengfly.tieba.post.arch.UiState import com.huanchengfly.tieba.post.arch.wrapImmutable import com.huanchengfly.tieba.post.repository.FrsPageRepository import com.huanchengfly.tieba.post.ui.models.ThreadItemData +import com.huanchengfly.tieba.post.ui.models.distinctById import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -248,7 +249,7 @@ sealed interface ForumThreadListPartialChange : PartialChange oldState.copy( isRefreshing = false, forumRuleTitle = forumRuleTitle, - threadList = threadList.toImmutableList(), + threadList = threadList.distinctById(), threadListIds = threadListIds.toImmutableList(), goodClassifies = goodClassifies.toImmutableList(), goodClassifyId = goodClassifyId, @@ -281,7 +282,7 @@ sealed interface ForumThreadListPartialChange : PartialChange oldState.copy(isRefreshing = true) is Success -> oldState.copy( isRefreshing = false, - threadList = threadList.toImmutableList(), + threadList = threadList.distinctById(), threadListIds = threadListIds.toImmutableList(), goodClassifies = goodClassifies.toImmutableList(), goodClassifyId = goodClassifyId, @@ -313,7 +314,7 @@ sealed interface ForumThreadListPartialChange : PartialChange oldState.copy(isLoadingMore = true) is Success -> oldState.copy( isLoadingMore = false, - threadList = (oldState.threadList + threadList).toImmutableList(), + threadList = (oldState.threadList + threadList).distinctById(), threadListIds = threadListIds.toImmutableList(), currentPage = currentPage, hasMore = hasMore diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/explore/concern/ConcernPage.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/explore/concern/ConcernPage.kt index 8c1ba60f..9fbe03cd 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/explore/concern/ConcernPage.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/explore/concern/ConcernPage.kt @@ -34,6 +34,7 @@ import com.huanchengfly.tieba.post.ui.widgets.compose.LazyLoad import com.huanchengfly.tieba.post.ui.widgets.compose.LoadMoreLayout import com.huanchengfly.tieba.post.ui.widgets.compose.MyLazyColumn import com.huanchengfly.tieba.post.ui.widgets.compose.VerticalDivider +import kotlinx.collections.immutable.persistentListOf @OptIn(ExperimentalMaterialApi::class) @Composable @@ -59,7 +60,7 @@ fun ConcernPage( ) val data by viewModel.uiState.collectPartialAsState( prop1 = ConcernUiState::data, - initial = emptyList() + initial = persistentListOf() ) val pullRefreshState = rememberPullRefreshState( refreshing = isRefreshing, @@ -89,7 +90,7 @@ fun ConcernPage( ) { itemsIndexed( items = data, - key = { _, item -> "${item.recommendType}_${item.recommendUserList.size}_${item.threadList?.id}" }, + key = { _, item -> "${item.recommendType}_${item.threadList?.id}" }, contentType = { _, item -> item.recommendType } ) { index, item -> Container { diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/explore/concern/ConcernViewModel.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/explore/concern/ConcernViewModel.kt index a9125d71..28e862ee 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/explore/concern/ConcernViewModel.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/explore/concern/ConcernViewModel.kt @@ -17,6 +17,9 @@ import com.huanchengfly.tieba.post.arch.UiIntent import com.huanchengfly.tieba.post.arch.UiState import com.huanchengfly.tieba.post.utils.appPreferences import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch @@ -91,23 +94,29 @@ class ConcernViewModel @Inject constructor() : } sealed interface ConcernUiIntent : UiIntent { - object Refresh : ConcernUiIntent + data object Refresh : ConcernUiIntent data class LoadMore(val pageTag: String) : ConcernUiIntent data class Agree( val threadId: Long, val postId: Long, - val hasAgree: Int + val hasAgree: Int, ) : ConcernUiIntent } +internal fun List.distinctById(): ImmutableList { + return distinctBy { + it.threadList?.id + }.toImmutableList() +} + sealed interface ConcernPartialChange : PartialChange { sealed class Agree private constructor() : ConcernPartialChange { private fun List.updateAgreeStatus( threadId: Long, - hasAgree: Int - ) : List { + hasAgree: Int, + ): ImmutableList { return map { val threadInfo = it.threadList if (threadInfo == null) it @@ -118,7 +127,7 @@ sealed interface ConcernPartialChange : PartialChange { threadInfo } ) - } + }.toImmutableList() } override fun reduce(oldState: ConcernUiState): ConcernUiState = @@ -157,14 +166,14 @@ sealed interface ConcernPartialChange : PartialChange { Start -> oldState.copy(isRefreshing = true) is Success -> oldState.copy( isRefreshing = false, - data = data, + data = data.distinctById(), hasMore = hasMore, nextPageTag = nextPageTag, ) is Failure -> oldState.copy(isRefreshing = false) } - object Start: Refresh() + data object Start : Refresh() data class Success( val data: List, @@ -183,14 +192,14 @@ sealed interface ConcernPartialChange : PartialChange { Start -> oldState.copy(isLoadingMore = true) is Success -> oldState.copy( isLoadingMore = false, - data = oldState.data + data, + data = (oldState.data + data).distinctById(), hasMore = hasMore, nextPageTag = nextPageTag, ) is Failure -> oldState.copy(isLoadingMore = false) } - object Start: LoadMore() + data object Start : LoadMore() data class Success( val data: List, @@ -209,7 +218,7 @@ data class ConcernUiState( val isLoadingMore: Boolean = false, val hasMore: Boolean = true, val nextPageTag: String = "", - val data: List = emptyList(), + val data: ImmutableList = persistentListOf(), ): UiState sealed interface ConcernUiEvent : UiEvent \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/explore/personalized/PersonalizedViewModel.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/explore/personalized/PersonalizedViewModel.kt index defe67d2..5dcd5c98 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/explore/personalized/PersonalizedViewModel.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/main/explore/personalized/PersonalizedViewModel.kt @@ -21,6 +21,7 @@ import com.huanchengfly.tieba.post.arch.wrapImmutable import com.huanchengfly.tieba.post.models.DislikeBean import com.huanchengfly.tieba.post.repository.PersonalizedRepository import com.huanchengfly.tieba.post.ui.models.ThreadItemData +import com.huanchengfly.tieba.post.ui.models.distinctById import com.huanchengfly.tieba.post.utils.appPreferences import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.collections.immutable.ImmutableList @@ -276,12 +277,16 @@ sealed interface PersonalizedPartialChange : PartialChange override fun reduce(oldState: PersonalizedUiState): PersonalizedUiState = when (this) { Start -> oldState.copy(isRefreshing = true) - is Success -> oldState.copy( - isRefreshing = false, - currentPage = 1, - data = (data + oldState.data).toImmutableList(), - refreshPosition = if (oldState.data.isEmpty()) 0 else data.size - ) + is Success -> { + val oldSize = oldState.data.size + val newData = (data + oldState.data).distinctById() + oldState.copy( + isRefreshing = false, + currentPage = 1, + data = newData, + refreshPosition = if (oldState.data.isEmpty()) 0 else (newData.size - oldSize), + ) + } is Failure -> oldState.copy( isRefreshing = false, @@ -307,7 +312,7 @@ sealed interface PersonalizedPartialChange : PartialChange is Success -> oldState.copy( isLoadingMore = false, currentPage = currentPage, - data = (oldState.data + data).toImmutableList(), + data = (oldState.data + data).distinctById(), ) is Failure -> oldState.copy(