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