pref: 优化动态界面性能

This commit is contained in:
HuanCheng65 2023-05-06 00:30:52 +08:00
parent 15e9b747d9
commit 9a9934d5e1
No known key found for this signature in database
GPG Key ID: 5EC9DD60A32C7360
8 changed files with 50 additions and 38 deletions

View File

@ -111,7 +111,8 @@ val List<PbContent>.renders: List<PbContentRender>
0, 9, 27 -> {
val lastRender = renders.lastOrNull()
if (lastRender is TextContentRender) {
lastRender.append(it.text)
renders.removeLast()
renders.add(lastRender + it.text)
} else
renders.add(TextContentRender(it.text))
}
@ -136,7 +137,8 @@ val List<PbContent>.renders: List<PbContentRender>
}
val lastRender = renders.lastOrNull()
if (lastRender is TextContentRender) {
lastRender.append(text)
renders.removeLast()
renders.add(lastRender + text)
} else
renders.add(TextContentRender(text))
}
@ -149,7 +151,8 @@ val List<PbContent>.renders: List<PbContentRender>
val emoticonText = "#(${it.c})".emoticonString
val lastRender = renders.lastOrNull()
if (lastRender is TextContentRender) {
lastRender.append(emoticonText)
renders.removeLast()
renders.add(lastRender + emoticonText)
} else
renders.add(TextContentRender(emoticonText))
}
@ -190,7 +193,8 @@ val List<PbContent>.renders: List<PbContentRender>
}
val lastRender = renders.lastOrNull()
if (lastRender is TextContentRender) {
lastRender.append(text)
renders.removeLast()
renders.add(lastRender + text)
} else
renders.add(TextContentRender(text))
}

View File

@ -26,22 +26,22 @@ interface PbContentRender {
}
data class TextContentRender(
var text: AnnotatedString
val text: AnnotatedString
) : PbContentRender {
constructor(text: String) : this(AnnotatedString(text))
fun append(text: String) {
append(AnnotatedString(text))
}
fun append(text: AnnotatedString) {
this.text += text
}
@Composable
override fun Render() {
EmoticonText(text = text, fontSize = 15.sp, style = MaterialTheme.typography.body1)
}
operator fun plus(text: String): TextContentRender {
return TextContentRender(this.text + AnnotatedString(text))
}
operator fun plus(text: AnnotatedString): TextContentRender {
return TextContentRender(this.text + text)
}
}
data class PicContentRender(

View File

@ -36,6 +36,7 @@ import androidx.constraintlayout.compose.ConstraintLayout
import com.huanchengfly.tieba.post.R
import com.huanchengfly.tieba.post.api.models.protos.personalized.DislikeReason
import com.huanchengfly.tieba.post.api.models.protos.personalized.ThreadPersonalized
import com.huanchengfly.tieba.post.arch.ImmutableHolder
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
import com.huanchengfly.tieba.post.ui.widgets.compose.ClickMenu
import com.huanchengfly.tieba.post.ui.widgets.compose.VerticalGrid
@ -44,12 +45,13 @@ import com.huanchengfly.tieba.post.ui.widgets.compose.rememberMenuState
@Composable
fun Dislike(
personalized: ThreadPersonalized,
onDislike: (clickTime: Long, reasons: List<DislikeReason>) -> Unit,
personalized: ImmutableHolder<ThreadPersonalized>,
onDislike: (clickTime: Long, reasons: List<ImmutableHolder<DislikeReason>>) -> Unit,
) {
var clickTime by remember { mutableStateOf(0L) }
val selectedReasons = remember { mutableStateListOf<DislikeReason>() }
val selectedReasons = remember { mutableStateListOf<ImmutableHolder<DislikeReason>>() }
val menuState = rememberMenuState()
val dislikeResource = personalized.getImmutableList { dislikeResource }
ClickMenu(
menuState = menuState,
menuContent = {
@ -109,8 +111,8 @@ fun Dislike(
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
items(
items = personalized.dislikeResource,
span = { if (it.dislikeId == 7) 2 else 1 }
items = dislikeResource,
span = { if (it.get { dislikeId } == 7) 2 else 1 }
) {
val backgroundColor by animateColorAsState(
targetValue = if (selectedReasons.contains(it)) ExtendedTheme.colors.accent else ExtendedTheme.colors.chip
@ -119,7 +121,7 @@ fun Dislike(
targetValue = if (selectedReasons.contains(it)) ExtendedTheme.colors.onAccent else ExtendedTheme.colors.onChip
)
Text(
text = it.dislikeReason,
text = it.get { dislikeReason },
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(6.dp))

View File

@ -216,12 +216,12 @@ fun PersonalizedPage(
@Composable
private fun FeedList(
dataProvider: () -> List<ImmutableHolder<ThreadInfo>>,
personalizedDataProvider: () -> List<ThreadPersonalized>,
personalizedDataProvider: () -> List<ImmutableHolder<ThreadPersonalized>>,
refreshPositionProvider: () -> Int,
hiddenThreadIdsProvider: () -> List<Long>,
onItemClick: (ThreadInfo) -> Unit,
onAgree: (ThreadInfo) -> Unit,
onDislike: (ThreadInfo, Long, List<DislikeReason>) -> Unit,
onDislike: (ThreadInfo, Long, List<ImmutableHolder<DislikeReason>>) -> Unit,
onRefresh: () -> Unit,
state: LazyStaggeredGridState,
) {

View File

@ -62,7 +62,8 @@ class PersonalizedViewModel @Inject constructor() :
.map<PersonalizedResponse, PersonalizedPartialChange.Refresh> {
PersonalizedPartialChange.Refresh.Success(
data = it.toData(),
threadPersonalizedData = it.data_?.thread_personalized ?: emptyList(),
threadPersonalizedData = (it.data_?.thread_personalized
?: emptyList()).wrapImmutable(),
)
}
.onStart { emit(PersonalizedPartialChange.Refresh.Start) }
@ -74,7 +75,8 @@ class PersonalizedViewModel @Inject constructor() :
PersonalizedPartialChange.LoadMore.Success(
currentPage = page,
data = it.toData(),
threadPersonalizedData = it.data_?.thread_personalized ?: emptyList(),
threadPersonalizedData = (it.data_?.thread_personalized
?: emptyList()).wrapImmutable(),
)
}
.onStart { emit(PersonalizedPartialChange.LoadMore.Start) }
@ -84,10 +86,10 @@ class PersonalizedViewModel @Inject constructor() :
TiebaApi.getInstance().submitDislikeFlow(
DislikeBean(
threadId.toString(),
reasons.joinToString(",") { it.dislikeId.toString() },
reasons.joinToString(",") { it.get { dislikeId }.toString() },
forumId?.toString(),
clickTime,
reasons.joinToString(",") { it.extra },
reasons.joinToString(",") { it.get { extra } },
)
).map<CommonResponse, PersonalizedPartialChange.Dislike> { PersonalizedPartialChange.Dislike.Success(threadId) }
.catch { emit(PersonalizedPartialChange.Dislike.Failure(threadId, it)) }
@ -125,7 +127,7 @@ sealed interface PersonalizedUiIntent : UiIntent {
data class Dislike(
val forumId: Long?,
val threadId: Long,
val reasons: List<DislikeReason>,
val reasons: List<ImmutableHolder<DislikeReason>>,
val clickTime: Long
) : PersonalizedUiIntent
}
@ -256,7 +258,7 @@ sealed interface PersonalizedPartialChange : PartialChange<PersonalizedUiState>
data class Success(
val data: List<ImmutableHolder<ThreadInfo>>,
val threadPersonalizedData: List<ThreadPersonalized>,
val threadPersonalizedData: List<ImmutableHolder<ThreadPersonalized>>,
) : Refresh()
data class Failure(
@ -282,7 +284,7 @@ sealed interface PersonalizedPartialChange : PartialChange<PersonalizedUiState>
data class Success(
val currentPage: Int,
val data: List<ImmutableHolder<ThreadInfo>>,
val threadPersonalizedData: List<ThreadPersonalized>,
val threadPersonalizedData: List<ImmutableHolder<ThreadPersonalized>>,
) : LoadMore()
data class Failure(
@ -297,7 +299,7 @@ data class PersonalizedUiState(
val isLoadingMore: Boolean = false,
val currentPage: Int = 1,
val data: List<ImmutableHolder<ThreadInfo>> = emptyList(),
val threadPersonalizedData: List<ThreadPersonalized> = emptyList(),
val threadPersonalizedData: List<ImmutableHolder<ThreadPersonalized>> = emptyList(),
val hiddenThreadIds: List<Long> = emptyList(),
val refreshPosition: Int = 0,
): UiState

View File

@ -85,7 +85,7 @@ private val ImmutableHolder<Media>.url: String
@Composable
private fun DefaultUserHeader(
user: User,
user: ImmutableHolder<User>,
time: Int,
content: @Composable RowScope.() -> Unit
) {
@ -93,7 +93,7 @@ private fun DefaultUserHeader(
UserHeader(
avatar = {
Avatar(
data = StringUtil.getAvatarUrl(user.portrait),
data = user.get { StringUtil.getAvatarUrl(portrait) },
size = Sizes.Small,
contentDescription = null
)
@ -102,8 +102,8 @@ private fun DefaultUserHeader(
Text(
text = StringUtil.getUsernameAnnotatedString(
context = LocalContext.current,
username = user.name,
nickname = user.nameShow,
username = user.get { name },
nickname = user.get { nameShow },
color = LocalContentColor.current
),
color = ExtendedTheme.colors.text
@ -112,8 +112,8 @@ private fun DefaultUserHeader(
onClick = {
UserActivity.launch(
context,
user.id.toString(),
StringUtil.getAvatarUrl(user.portrait)
user.get { id }.toString(),
user.get { StringUtil.getAvatarUrl(portrait) }
)
},
desc = {
@ -315,8 +315,8 @@ fun FeedCard(
) {
Card(
header = {
val author = item.get { author }
if (author != null) {
if (item.isNotNull { author }) {
val author = item.getImmutable { author!! }
DefaultUserHeader(
user = author,
time = item.get { lastTimeInt }) { dislikeAction() }

View File

@ -8,6 +8,7 @@ import android.text.Spanned
import android.text.TextUtils
import android.text.style.ForegroundColorSpan
import android.widget.TextView
import androidx.compose.runtime.Stable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
@ -90,6 +91,7 @@ object StringUtil {
return nickname ?: ""
}
@Stable
fun getUsernameAnnotatedString(
context: Context,
username: String,
@ -110,6 +112,7 @@ object StringUtil {
}
@JvmStatic
@Stable
fun getAvatarUrl(portrait: String?): String {
if (portrait.isNullOrEmpty()) {
return ""

View File

@ -175,7 +175,8 @@
<string name="toast_play_failed">播放失败</string>
<string name="toast_cannot_view">抱歉,当前暂时无法浏览本吧</string>
<string name="tip_thread_item">第 %1$s 楼 %2$s</string>
<string name="text_ip_location">来自%1$s</string>
<string name="text_ip_location">来自%s</string>
<string name="tip_post_floor">第 %d 楼</string>
<string name="tip_floor_more_count">查看更多回复(%1$s)</string>
<string name="update_tip_title">发现新版本 %1$s(%2$s)</string>
<string name="update_tip_header">更新 · %1$s</string>