diff --git a/app/src/main/java/com/huanchengfly/tieba/post/api/models/protos/Extensions.kt b/app/src/main/java/com/huanchengfly/tieba/post/api/models/protos/Extensions.kt index 27d4cfe3..e444cb5b 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/api/models/protos/Extensions.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/api/models/protos/Extensions.kt @@ -326,36 +326,39 @@ val User.bawuType: String? } else null val Post.subPostContents: ImmutableList - get() = sub_post_list?.sub_post_list?.map { it.contentText }?.toImmutableList() + get() = sub_post_list?.sub_post_list?.map { it.getContentText(origin_thread_info?.author?.id) } + ?.toImmutableList() ?: persistentListOf() @OptIn(ExperimentalTextApi::class) -val SubPostList.contentText: AnnotatedString - get() { - val context = App.INSTANCE - val accentColor = Color(ThemeUtils.getColorByAttr(context, R.attr.colorNewPrimary)) +fun SubPostList.getContentText(threadAuthorId: Long? = null): AnnotatedString { + val context = App.INSTANCE + val accentColor = Color(ThemeUtils.getColorByAttr(context, R.attr.colorNewPrimary)) - val userNameString = buildAnnotatedString { - withStyle( - style = SpanStyle( - color = accentColor, - fontWeight = FontWeight.Bold - ) - ) { - withAnnotation("user", "${author?.id}") { - append( - StringUtil.getUsernameAnnotatedString( - context, - author?.name ?: "", - author?.nameShow - ) - ) - append(": ") - } - } + val userNameString = buildAnnotatedString { + val annotation = pushStringAnnotation("user", "${author?.id}") + val style = pushStyle( + SpanStyle( + color = accentColor, + fontWeight = FontWeight.Bold + ) + ) + append( + StringUtil.getUsernameAnnotatedString( + context, + author?.name ?: "", + author?.nameShow + ) + ) + pop(style) + if (author?.id == threadAuthorId) { + appendInlineContent("Lz") } + append(": ") + pop(annotation) + } - val contentStrings = content.renders.map { it.toAnnotationString() } + val contentStrings = content.renders.map { it.toAnnotationString() } - return userNameString + contentStrings.reduce { acc, annotatedString -> acc + annotatedString } - } \ No newline at end of file + return userNameString + contentStrings.reduce { acc, annotatedString -> acc + annotatedString } +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/repository/PbPageRepository.kt b/app/src/main/java/com/huanchengfly/tieba/post/repository/PbPageRepository.kt index faa426aa..469b30de 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/repository/PbPageRepository.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/repository/PbPageRepository.kt @@ -1,6 +1,7 @@ package com.huanchengfly.tieba.post.repository import com.huanchengfly.tieba.post.api.TiebaApi +import com.huanchengfly.tieba.post.api.models.protos.OriginThreadInfo import com.huanchengfly.tieba.post.api.models.protos.pbPage.PbPageResponse import com.huanchengfly.tieba.post.api.retrofit.exception.TiebaUnknownException import com.huanchengfly.tieba.post.ui.page.thread.ThreadPageFrom @@ -58,6 +59,9 @@ object PbPageRepository { ?: userList.first { user -> user.id == subPost.author_id } ) } + ), + origin_thread_info = OriginThreadInfo( + author = response.data_.thread.author ) ) } @@ -79,7 +83,7 @@ object PbPageRepository { response.copy( data_ = response.data_.copy( post_list = postList, - first_floor_post = firstPost + first_floor_post = firstPost, ) ) } diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/common/PbContentRender.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/common/PbContentRender.kt index 55c87d35..a1d2a8ba 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/common/PbContentRender.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/common/PbContentRender.kt @@ -70,7 +70,12 @@ data class TextContentRender( @Composable override fun Render() { - PbContentText(text = text, fontSize = 15.sp, style = MaterialTheme.typography.body1) + PbContentText( + text = text, + fontSize = 15.sp, + style = MaterialTheme.typography.body1, + lineSpacing = 0.8.sp + ) } override fun toAnnotationString(): AnnotatedString { @@ -220,6 +225,7 @@ fun PbContentText( textDecoration: TextDecoration? = null, textAlign: TextAlign? = null, lineHeight: TextUnit = TextUnit.Unspecified, + lineSpacing: TextUnit = 0.sp, overflow: TextOverflow = TextOverflow.Clip, softWrap: Boolean = true, maxLines: Int = Int.MAX_VALUE, @@ -227,7 +233,7 @@ fun PbContentText( emoticonSize: Float = 0.9f, inlineContent: Map = emptyMap(), onTextLayout: (TextLayoutResult) -> Unit = {}, - style: TextStyle = LocalTextStyle.current + style: TextStyle = LocalTextStyle.current, ) { val context = LocalContext.current @@ -271,7 +277,7 @@ fun PbContentText( textDecoration = textDecoration, textAlign = textAlign, lineHeight = lineHeight, - lineSpacing = 0.8.sp, + lineSpacing = lineSpacing, overflow = overflow, softWrap = softWrap, maxLines = maxLines, diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/subposts/SubPostsPage.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/subposts/SubPostsPage.kt index 597f85b7..c155f3e4 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/subposts/SubPostsPage.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/subposts/SubPostsPage.kt @@ -171,6 +171,10 @@ internal fun SubPostsContent( prop1 = SubPostsUiState::forum, initial = null ) + val thread by viewModel.uiState.collectPartialAsState( + prop1 = SubPostsUiState::thread, + initial = null + ) val post by viewModel.uiState.collectPartialAsState( prop1 = SubPostsUiState::post, initial = null @@ -432,6 +436,7 @@ internal fun SubPostsContent( subPost = item, contentRenders = subPostsContentRenders[index], canDelete = { it.author_id == account?.uid?.toLongOrNull() }, + threadAuthorId = thread?.get { author?.id }, onAgree = { val hasAgreed = it.agree?.hasAgree != 0 viewModel.send( @@ -490,7 +495,7 @@ private fun getDescText( private fun SubPostItem( subPost: ImmutableHolder, contentRenders: ImmutableList, - threadAuthorId: Long = 0L, + threadAuthorId: Long? = null, canDelete: (SubPostList) -> Boolean = { false }, onAgree: (SubPostList) -> Unit = {}, onReplyClick: (SubPostList) -> Unit = {}, diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/subposts/SubPostsViewModel.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/subposts/SubPostsViewModel.kt index 8e6b3533..561be7e4 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/subposts/SubPostsViewModel.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/subposts/SubPostsViewModel.kt @@ -8,6 +8,7 @@ import com.huanchengfly.tieba.post.api.models.protos.Anti import com.huanchengfly.tieba.post.api.models.protos.Post import com.huanchengfly.tieba.post.api.models.protos.SimpleForum import com.huanchengfly.tieba.post.api.models.protos.SubPostList +import com.huanchengfly.tieba.post.api.models.protos.ThreadInfo import com.huanchengfly.tieba.post.api.models.protos.contentRenders import com.huanchengfly.tieba.post.api.models.protos.pbFloor.PbFloorResponse import com.huanchengfly.tieba.post.api.models.protos.renders @@ -74,11 +75,13 @@ class SubPostsViewModel @Inject constructor() : val post = checkNotNull(response.data_?.post) val page = checkNotNull(response.data_?.page) val forum = checkNotNull(response.data_?.forum) + val thread = checkNotNull(response.data_?.thread) val anti = checkNotNull(response.data_?.anti) val subPosts = response.data_?.subpost_list.orEmpty() SubPostsPartialChange.Load.Success( anti.wrapImmutable(), forum.wrapImmutable(), + thread.wrapImmutable(), post.wrapImmutable(), post.contentRenders, subPosts.wrapImmutable(), @@ -202,6 +205,7 @@ sealed interface SubPostsPartialChange : PartialChange { totalPage = totalPage, totalCount = totalCount, forum = forum, + thread = thread, post = post, postContentRenders = postContentRenders, subPosts = subPosts, @@ -217,6 +221,7 @@ sealed interface SubPostsPartialChange : PartialChange { data class Success( val anti: ImmutableHolder, val forum: ImmutableHolder, + val thread: ImmutableHolder, val post: ImmutableHolder, val postContentRenders: ImmutableList, val subPosts: ImmutableList>, @@ -374,6 +379,7 @@ data class SubPostsUiState( val anti: ImmutableHolder? = null, val forum: ImmutableHolder? = null, + val thread: ImmutableHolder? = null, val post: ImmutableHolder? = null, val postContentRenders: ImmutableList = persistentListOf(), val subPosts: ImmutableList> = persistentListOf(), diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/thread/ThreadPage.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/thread/ThreadPage.kt index ce604deb..324b3c6d 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/thread/ThreadPage.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/thread/ThreadPage.kt @@ -1762,16 +1762,24 @@ private fun SubPostItem( onOpenSubPosts(subPostList.get { id }) } ) { - PbContentText( - text = subPostContent, - modifier = modifier, - color = ExtendedTheme.colors.text, - fontSize = 13.sp, - style = MaterialTheme.typography.body2, - emoticonSize = 0.9f, - overflow = TextOverflow.Ellipsis, - maxLines = 4, - ) + ProvideTextStyle(value = MaterialTheme.typography.body2.copy(color = ExtendedTheme.colors.text)) { + PbContentText( + text = subPostContent, + modifier = modifier, + fontSize = 13.sp, + emoticonSize = 0.9f, + overflow = TextOverflow.Ellipsis, + maxLines = 4, + lineSpacing = 0.4.sp, + inlineContent = mapOf( + "Lz" to buildChipInlineContent( + stringResource(id = R.string.tip_lz), + backgroundColor = ExtendedTheme.colors.textSecondary.copy(alpha = 0.1f), + color = ExtendedTheme.colors.textSecondary + ), + ) + ) + } } } diff --git a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/thread/ThreadViewModel.kt b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/thread/ThreadViewModel.kt index d494d7b0..d8f7db10 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/ui/page/thread/ThreadViewModel.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/ui/page/thread/ThreadViewModel.kt @@ -184,8 +184,6 @@ class ThreadViewModel @Inject constructor() : ), response.data_.page.has_prev != 0, firstPost?.contentRenders, - notFirstPosts.map { it.contentRenders }, - notFirstPosts.map { it.subPostContents }.toImmutableList(), postId, seeLz, sortType, @@ -653,8 +651,6 @@ sealed interface ThreadPartialChange : PartialChange { val nextPagePostId: Long, val hasPrevious: Boolean, val firstPostContentRenders: List?, - val contentRenders: List>, - val subPostContents: List>, val postId: Long = 0, val seeLz: Boolean = false, val sortType: Int = 0,