pref: 性能优化
This commit is contained in:
parent
ad2ea7eefd
commit
c7c646d7de
|
|
@ -8,40 +8,11 @@ import kotlinx.collections.immutable.toImmutableList
|
|||
@Stable
|
||||
class StableHolder<T>(val item: T) {
|
||||
operator fun component1(): T = item
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as StableHolder<*>
|
||||
|
||||
if (item != other.item) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return item?.hashCode() ?: 0
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
class ImmutableHolder<T>(val item: T) {
|
||||
operator fun component1(): T = item
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as ImmutableHolder<*>
|
||||
|
||||
if (item != other.item) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return item?.hashCode() ?: 0
|
||||
}
|
||||
|
||||
@Stable
|
||||
fun get(): T = item
|
||||
|
|
|
|||
|
|
@ -42,11 +42,13 @@ import com.huanchengfly.tieba.post.ui.widgets.compose.ClickMenu
|
|||
import com.huanchengfly.tieba.post.ui.widgets.compose.VerticalGrid
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.items
|
||||
import com.huanchengfly.tieba.post.ui.widgets.compose.rememberMenuState
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
@Composable
|
||||
fun Dislike(
|
||||
personalized: ImmutableHolder<ThreadPersonalized>,
|
||||
onDislike: (clickTime: Long, reasons: List<ImmutableHolder<DislikeReason>>) -> Unit,
|
||||
onDislike: (clickTime: Long, reasons: ImmutableList<ImmutableHolder<DislikeReason>>) -> Unit,
|
||||
) {
|
||||
var clickTime by remember { mutableStateOf(0L) }
|
||||
val selectedReasons = remember { mutableStateListOf<ImmutableHolder<DislikeReason>>() }
|
||||
|
|
@ -88,7 +90,7 @@ fun Dislike(
|
|||
.background(color = ExtendedTheme.colors.primary)
|
||||
.clickable {
|
||||
dismiss()
|
||||
onDislike(clickTime, selectedReasons)
|
||||
onDislike(clickTime, selectedReasons.toImmutableList())
|
||||
}
|
||||
.padding(vertical = 4.dp, horizontal = 8.dp),
|
||||
color = ExtendedTheme.colors.onAccent,
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ import com.huanchengfly.tieba.post.ui.widgets.compose.FeedCard
|
|||
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.VerticalDivider
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
|
@ -94,11 +96,11 @@ fun PersonalizedPage(
|
|||
)
|
||||
val data by viewModel.uiState.collectPartialAsState(
|
||||
prop1 = PersonalizedUiState::data,
|
||||
initial = emptyList()
|
||||
initial = persistentListOf()
|
||||
)
|
||||
val threadPersonalizedData by viewModel.uiState.collectPartialAsState(
|
||||
prop1 = PersonalizedUiState::threadPersonalizedData,
|
||||
initial = emptyList()
|
||||
initial = persistentListOf()
|
||||
)
|
||||
val refreshPosition by viewModel.uiState.collectPartialAsState(
|
||||
prop1 = PersonalizedUiState::refreshPosition,
|
||||
|
|
@ -106,7 +108,7 @@ fun PersonalizedPage(
|
|||
)
|
||||
val hiddenThreadIds by viewModel.uiState.collectPartialAsState(
|
||||
prop1 = PersonalizedUiState::hiddenThreadIds,
|
||||
initial = emptyList()
|
||||
initial = persistentListOf()
|
||||
)
|
||||
val pullRefreshState = rememberPullRefreshState(
|
||||
refreshing = isRefreshing,
|
||||
|
|
@ -246,14 +248,14 @@ private fun BoxScope.RefreshTip(refreshCount: Int) {
|
|||
@Composable
|
||||
private fun FeedList(
|
||||
state: LazyListState,
|
||||
dataProvider: () -> List<ImmutableHolder<ThreadInfo>>,
|
||||
personalizedDataProvider: () -> List<ImmutableHolder<ThreadPersonalized>?>,
|
||||
dataProvider: () -> ImmutableList<ImmutableHolder<ThreadInfo>>,
|
||||
personalizedDataProvider: () -> ImmutableList<ImmutableHolder<ThreadPersonalized>?>,
|
||||
refreshPositionProvider: () -> Int,
|
||||
hiddenThreadIdsProvider: () -> List<Long>,
|
||||
hiddenThreadIdsProvider: () -> ImmutableList<Long>,
|
||||
onItemClick: (ThreadInfo) -> Unit,
|
||||
onItemReplyClick: (ThreadInfo) -> Unit,
|
||||
onAgree: (ThreadInfo) -> Unit,
|
||||
onDislike: (ThreadInfo, Long, List<ImmutableHolder<DislikeReason>>) -> Unit,
|
||||
onDislike: (ThreadInfo, Long, ImmutableList<ImmutableHolder<DislikeReason>>) -> Unit,
|
||||
onRefresh: () -> Unit,
|
||||
onOpenForum: (forumName: String) -> Unit = {},
|
||||
) {
|
||||
|
|
@ -312,8 +314,10 @@ private fun FeedList(
|
|||
onClick = onItemClick,
|
||||
onReplyClick = onItemReplyClick,
|
||||
onAgree = onAgree,
|
||||
onClickForum = {
|
||||
onOpenForum(it.name)
|
||||
onClickForum = remember {
|
||||
{
|
||||
onOpenForum(it.name)
|
||||
}
|
||||
}
|
||||
) {
|
||||
if (personalized != null) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ import com.huanchengfly.tieba.post.arch.wrapImmutable
|
|||
import com.huanchengfly.tieba.post.models.DislikeBean
|
||||
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
|
||||
|
|
@ -30,7 +33,6 @@ import kotlinx.coroutines.flow.flatMapConcat
|
|||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import okhttp3.internal.toImmutableList
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
|
|
@ -156,8 +158,8 @@ sealed interface PersonalizedPartialChange : PartialChange<PersonalizedUiState>
|
|||
sealed class Agree private constructor() : PersonalizedPartialChange {
|
||||
private fun List<ImmutableHolder<ThreadInfo>>.updateAgreeStatus(
|
||||
threadId: Long,
|
||||
hasAgree: Int
|
||||
): List<ImmutableHolder<ThreadInfo>> {
|
||||
hasAgree: Int,
|
||||
): ImmutableList<ImmutableHolder<ThreadInfo>> {
|
||||
return map {
|
||||
val threadInfo = it.get()
|
||||
if (threadInfo.threadId == threadId) {
|
||||
|
|
@ -193,7 +195,7 @@ sealed interface PersonalizedPartialChange : PartialChange<PersonalizedUiState>
|
|||
} else {
|
||||
threadInfo
|
||||
}
|
||||
}.map { wrapImmutable(it) }
|
||||
}.wrapImmutable()
|
||||
}
|
||||
|
||||
override fun reduce(oldState: PersonalizedUiState): PersonalizedUiState =
|
||||
|
|
@ -231,14 +233,14 @@ sealed interface PersonalizedPartialChange : PartialChange<PersonalizedUiState>
|
|||
when (this) {
|
||||
is Start -> {
|
||||
if (!oldState.hiddenThreadIds.contains(threadId)) {
|
||||
oldState.copy(hiddenThreadIds = oldState.hiddenThreadIds + threadId)
|
||||
oldState.copy(hiddenThreadIds = (oldState.hiddenThreadIds + threadId).toImmutableList())
|
||||
} else {
|
||||
oldState
|
||||
}
|
||||
}
|
||||
is Success -> {
|
||||
if (!oldState.hiddenThreadIds.contains(threadId)) {
|
||||
oldState.copy(hiddenThreadIds = oldState.hiddenThreadIds + threadId)
|
||||
oldState.copy(hiddenThreadIds = (oldState.hiddenThreadIds + threadId).toImmutableList())
|
||||
} else {
|
||||
oldState
|
||||
}
|
||||
|
|
@ -267,8 +269,8 @@ sealed interface PersonalizedPartialChange : PartialChange<PersonalizedUiState>
|
|||
is Success -> oldState.copy(
|
||||
isRefreshing = false,
|
||||
currentPage = 1,
|
||||
data = data + oldState.data,
|
||||
threadPersonalizedData = threadPersonalizedData + oldState.threadPersonalizedData,
|
||||
data = (data + oldState.data).toImmutableList(),
|
||||
threadPersonalizedData = (threadPersonalizedData + oldState.threadPersonalizedData).toImmutableList(),
|
||||
refreshPosition = if (oldState.data.isEmpty()) 0 else data.size
|
||||
)
|
||||
is Failure -> oldState.copy(isRefreshing = false)
|
||||
|
|
@ -293,8 +295,8 @@ sealed interface PersonalizedPartialChange : PartialChange<PersonalizedUiState>
|
|||
is Success -> oldState.copy(
|
||||
isLoadingMore = false,
|
||||
currentPage = currentPage,
|
||||
data = oldState.data + data,
|
||||
threadPersonalizedData = oldState.threadPersonalizedData + threadPersonalizedData,
|
||||
data = (oldState.data + data).toImmutableList(),
|
||||
threadPersonalizedData = (oldState.threadPersonalizedData + threadPersonalizedData).toImmutableList(),
|
||||
)
|
||||
is Failure -> oldState.copy(isLoadingMore = false)
|
||||
}
|
||||
|
|
@ -318,9 +320,9 @@ data class PersonalizedUiState(
|
|||
val isRefreshing: Boolean = true,
|
||||
val isLoadingMore: Boolean = false,
|
||||
val currentPage: Int = 1,
|
||||
val data: List<ImmutableHolder<ThreadInfo>> = emptyList(),
|
||||
val threadPersonalizedData: List<ImmutableHolder<ThreadPersonalized>?> = emptyList(),
|
||||
val hiddenThreadIds: List<Long> = emptyList(),
|
||||
val data: ImmutableList<ImmutableHolder<ThreadInfo>> = persistentListOf(),
|
||||
val threadPersonalizedData: ImmutableList<ImmutableHolder<ThreadPersonalized>?> = persistentListOf(),
|
||||
val hiddenThreadIds: ImmutableList<Long> = persistentListOf(),
|
||||
val refreshPosition: Int = 0,
|
||||
): UiState
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue