feat: 楼中楼楼主标识
This commit is contained in:
parent
2edb341451
commit
518d99f707
|
|
@ -326,23 +326,23 @@ val User.bawuType: String?
|
||||||
} else null
|
} else null
|
||||||
|
|
||||||
val Post.subPostContents: ImmutableList<AnnotatedString>
|
val Post.subPostContents: ImmutableList<AnnotatedString>
|
||||||
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()
|
?: persistentListOf()
|
||||||
|
|
||||||
@OptIn(ExperimentalTextApi::class)
|
@OptIn(ExperimentalTextApi::class)
|
||||||
val SubPostList.contentText: AnnotatedString
|
fun SubPostList.getContentText(threadAuthorId: Long? = null): AnnotatedString {
|
||||||
get() {
|
|
||||||
val context = App.INSTANCE
|
val context = App.INSTANCE
|
||||||
val accentColor = Color(ThemeUtils.getColorByAttr(context, R.attr.colorNewPrimary))
|
val accentColor = Color(ThemeUtils.getColorByAttr(context, R.attr.colorNewPrimary))
|
||||||
|
|
||||||
val userNameString = buildAnnotatedString {
|
val userNameString = buildAnnotatedString {
|
||||||
withStyle(
|
val annotation = pushStringAnnotation("user", "${author?.id}")
|
||||||
style = SpanStyle(
|
val style = pushStyle(
|
||||||
|
SpanStyle(
|
||||||
color = accentColor,
|
color = accentColor,
|
||||||
fontWeight = FontWeight.Bold
|
fontWeight = FontWeight.Bold
|
||||||
)
|
)
|
||||||
) {
|
)
|
||||||
withAnnotation("user", "${author?.id}") {
|
|
||||||
append(
|
append(
|
||||||
StringUtil.getUsernameAnnotatedString(
|
StringUtil.getUsernameAnnotatedString(
|
||||||
context,
|
context,
|
||||||
|
|
@ -350,12 +350,15 @@ val SubPostList.contentText: AnnotatedString
|
||||||
author?.nameShow
|
author?.nameShow
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
pop(style)
|
||||||
|
if (author?.id == threadAuthorId) {
|
||||||
|
appendInlineContent("Lz")
|
||||||
|
}
|
||||||
append(": ")
|
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 }
|
return userNameString + contentStrings.reduce { acc, annotatedString -> acc + annotatedString }
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.huanchengfly.tieba.post.repository
|
package com.huanchengfly.tieba.post.repository
|
||||||
|
|
||||||
import com.huanchengfly.tieba.post.api.TiebaApi
|
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.models.protos.pbPage.PbPageResponse
|
||||||
import com.huanchengfly.tieba.post.api.retrofit.exception.TiebaUnknownException
|
import com.huanchengfly.tieba.post.api.retrofit.exception.TiebaUnknownException
|
||||||
import com.huanchengfly.tieba.post.ui.page.thread.ThreadPageFrom
|
import com.huanchengfly.tieba.post.ui.page.thread.ThreadPageFrom
|
||||||
|
|
@ -58,6 +59,9 @@ object PbPageRepository {
|
||||||
?: userList.first { user -> user.id == subPost.author_id }
|
?: 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(
|
response.copy(
|
||||||
data_ = response.data_.copy(
|
data_ = response.data_.copy(
|
||||||
post_list = postList,
|
post_list = postList,
|
||||||
first_floor_post = firstPost
|
first_floor_post = firstPost,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,12 @@ data class TextContentRender(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Render() {
|
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 {
|
override fun toAnnotationString(): AnnotatedString {
|
||||||
|
|
@ -220,6 +225,7 @@ fun PbContentText(
|
||||||
textDecoration: TextDecoration? = null,
|
textDecoration: TextDecoration? = null,
|
||||||
textAlign: TextAlign? = null,
|
textAlign: TextAlign? = null,
|
||||||
lineHeight: TextUnit = TextUnit.Unspecified,
|
lineHeight: TextUnit = TextUnit.Unspecified,
|
||||||
|
lineSpacing: TextUnit = 0.sp,
|
||||||
overflow: TextOverflow = TextOverflow.Clip,
|
overflow: TextOverflow = TextOverflow.Clip,
|
||||||
softWrap: Boolean = true,
|
softWrap: Boolean = true,
|
||||||
maxLines: Int = Int.MAX_VALUE,
|
maxLines: Int = Int.MAX_VALUE,
|
||||||
|
|
@ -227,7 +233,7 @@ fun PbContentText(
|
||||||
emoticonSize: Float = 0.9f,
|
emoticonSize: Float = 0.9f,
|
||||||
inlineContent: Map<String, InlineTextContent> = emptyMap(),
|
inlineContent: Map<String, InlineTextContent> = emptyMap(),
|
||||||
onTextLayout: (TextLayoutResult) -> Unit = {},
|
onTextLayout: (TextLayoutResult) -> Unit = {},
|
||||||
style: TextStyle = LocalTextStyle.current
|
style: TextStyle = LocalTextStyle.current,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
|
@ -271,7 +277,7 @@ fun PbContentText(
|
||||||
textDecoration = textDecoration,
|
textDecoration = textDecoration,
|
||||||
textAlign = textAlign,
|
textAlign = textAlign,
|
||||||
lineHeight = lineHeight,
|
lineHeight = lineHeight,
|
||||||
lineSpacing = 0.8.sp,
|
lineSpacing = lineSpacing,
|
||||||
overflow = overflow,
|
overflow = overflow,
|
||||||
softWrap = softWrap,
|
softWrap = softWrap,
|
||||||
maxLines = maxLines,
|
maxLines = maxLines,
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,10 @@ internal fun SubPostsContent(
|
||||||
prop1 = SubPostsUiState::forum,
|
prop1 = SubPostsUiState::forum,
|
||||||
initial = null
|
initial = null
|
||||||
)
|
)
|
||||||
|
val thread by viewModel.uiState.collectPartialAsState(
|
||||||
|
prop1 = SubPostsUiState::thread,
|
||||||
|
initial = null
|
||||||
|
)
|
||||||
val post by viewModel.uiState.collectPartialAsState(
|
val post by viewModel.uiState.collectPartialAsState(
|
||||||
prop1 = SubPostsUiState::post,
|
prop1 = SubPostsUiState::post,
|
||||||
initial = null
|
initial = null
|
||||||
|
|
@ -432,6 +436,7 @@ internal fun SubPostsContent(
|
||||||
subPost = item,
|
subPost = item,
|
||||||
contentRenders = subPostsContentRenders[index],
|
contentRenders = subPostsContentRenders[index],
|
||||||
canDelete = { it.author_id == account?.uid?.toLongOrNull() },
|
canDelete = { it.author_id == account?.uid?.toLongOrNull() },
|
||||||
|
threadAuthorId = thread?.get { author?.id },
|
||||||
onAgree = {
|
onAgree = {
|
||||||
val hasAgreed = it.agree?.hasAgree != 0
|
val hasAgreed = it.agree?.hasAgree != 0
|
||||||
viewModel.send(
|
viewModel.send(
|
||||||
|
|
@ -490,7 +495,7 @@ private fun getDescText(
|
||||||
private fun SubPostItem(
|
private fun SubPostItem(
|
||||||
subPost: ImmutableHolder<SubPostList>,
|
subPost: ImmutableHolder<SubPostList>,
|
||||||
contentRenders: ImmutableList<PbContentRender>,
|
contentRenders: ImmutableList<PbContentRender>,
|
||||||
threadAuthorId: Long = 0L,
|
threadAuthorId: Long? = null,
|
||||||
canDelete: (SubPostList) -> Boolean = { false },
|
canDelete: (SubPostList) -> Boolean = { false },
|
||||||
onAgree: (SubPostList) -> Unit = {},
|
onAgree: (SubPostList) -> Unit = {},
|
||||||
onReplyClick: (SubPostList) -> Unit = {},
|
onReplyClick: (SubPostList) -> Unit = {},
|
||||||
|
|
|
||||||
|
|
@ -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.Post
|
||||||
import com.huanchengfly.tieba.post.api.models.protos.SimpleForum
|
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.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.contentRenders
|
||||||
import com.huanchengfly.tieba.post.api.models.protos.pbFloor.PbFloorResponse
|
import com.huanchengfly.tieba.post.api.models.protos.pbFloor.PbFloorResponse
|
||||||
import com.huanchengfly.tieba.post.api.models.protos.renders
|
import com.huanchengfly.tieba.post.api.models.protos.renders
|
||||||
|
|
@ -74,11 +75,13 @@ class SubPostsViewModel @Inject constructor() :
|
||||||
val post = checkNotNull(response.data_?.post)
|
val post = checkNotNull(response.data_?.post)
|
||||||
val page = checkNotNull(response.data_?.page)
|
val page = checkNotNull(response.data_?.page)
|
||||||
val forum = checkNotNull(response.data_?.forum)
|
val forum = checkNotNull(response.data_?.forum)
|
||||||
|
val thread = checkNotNull(response.data_?.thread)
|
||||||
val anti = checkNotNull(response.data_?.anti)
|
val anti = checkNotNull(response.data_?.anti)
|
||||||
val subPosts = response.data_?.subpost_list.orEmpty()
|
val subPosts = response.data_?.subpost_list.orEmpty()
|
||||||
SubPostsPartialChange.Load.Success(
|
SubPostsPartialChange.Load.Success(
|
||||||
anti.wrapImmutable(),
|
anti.wrapImmutable(),
|
||||||
forum.wrapImmutable(),
|
forum.wrapImmutable(),
|
||||||
|
thread.wrapImmutable(),
|
||||||
post.wrapImmutable(),
|
post.wrapImmutable(),
|
||||||
post.contentRenders,
|
post.contentRenders,
|
||||||
subPosts.wrapImmutable(),
|
subPosts.wrapImmutable(),
|
||||||
|
|
@ -202,6 +205,7 @@ sealed interface SubPostsPartialChange : PartialChange<SubPostsUiState> {
|
||||||
totalPage = totalPage,
|
totalPage = totalPage,
|
||||||
totalCount = totalCount,
|
totalCount = totalCount,
|
||||||
forum = forum,
|
forum = forum,
|
||||||
|
thread = thread,
|
||||||
post = post,
|
post = post,
|
||||||
postContentRenders = postContentRenders,
|
postContentRenders = postContentRenders,
|
||||||
subPosts = subPosts,
|
subPosts = subPosts,
|
||||||
|
|
@ -217,6 +221,7 @@ sealed interface SubPostsPartialChange : PartialChange<SubPostsUiState> {
|
||||||
data class Success(
|
data class Success(
|
||||||
val anti: ImmutableHolder<Anti>,
|
val anti: ImmutableHolder<Anti>,
|
||||||
val forum: ImmutableHolder<SimpleForum>,
|
val forum: ImmutableHolder<SimpleForum>,
|
||||||
|
val thread: ImmutableHolder<ThreadInfo>,
|
||||||
val post: ImmutableHolder<Post>,
|
val post: ImmutableHolder<Post>,
|
||||||
val postContentRenders: ImmutableList<PbContentRender>,
|
val postContentRenders: ImmutableList<PbContentRender>,
|
||||||
val subPosts: ImmutableList<ImmutableHolder<SubPostList>>,
|
val subPosts: ImmutableList<ImmutableHolder<SubPostList>>,
|
||||||
|
|
@ -374,6 +379,7 @@ data class SubPostsUiState(
|
||||||
|
|
||||||
val anti: ImmutableHolder<Anti>? = null,
|
val anti: ImmutableHolder<Anti>? = null,
|
||||||
val forum: ImmutableHolder<SimpleForum>? = null,
|
val forum: ImmutableHolder<SimpleForum>? = null,
|
||||||
|
val thread: ImmutableHolder<ThreadInfo>? = null,
|
||||||
val post: ImmutableHolder<Post>? = null,
|
val post: ImmutableHolder<Post>? = null,
|
||||||
val postContentRenders: ImmutableList<PbContentRender> = persistentListOf(),
|
val postContentRenders: ImmutableList<PbContentRender> = persistentListOf(),
|
||||||
val subPosts: ImmutableList<ImmutableHolder<SubPostList>> = persistentListOf(),
|
val subPosts: ImmutableList<ImmutableHolder<SubPostList>> = persistentListOf(),
|
||||||
|
|
|
||||||
|
|
@ -1762,16 +1762,24 @@ private fun SubPostItem(
|
||||||
onOpenSubPosts(subPostList.get { id })
|
onOpenSubPosts(subPostList.get { id })
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
ProvideTextStyle(value = MaterialTheme.typography.body2.copy(color = ExtendedTheme.colors.text)) {
|
||||||
PbContentText(
|
PbContentText(
|
||||||
text = subPostContent,
|
text = subPostContent,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
color = ExtendedTheme.colors.text,
|
|
||||||
fontSize = 13.sp,
|
fontSize = 13.sp,
|
||||||
style = MaterialTheme.typography.body2,
|
|
||||||
emoticonSize = 0.9f,
|
emoticonSize = 0.9f,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
maxLines = 4,
|
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
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -184,8 +184,6 @@ class ThreadViewModel @Inject constructor() :
|
||||||
),
|
),
|
||||||
response.data_.page.has_prev != 0,
|
response.data_.page.has_prev != 0,
|
||||||
firstPost?.contentRenders,
|
firstPost?.contentRenders,
|
||||||
notFirstPosts.map { it.contentRenders },
|
|
||||||
notFirstPosts.map { it.subPostContents }.toImmutableList(),
|
|
||||||
postId,
|
postId,
|
||||||
seeLz,
|
seeLz,
|
||||||
sortType,
|
sortType,
|
||||||
|
|
@ -653,8 +651,6 @@ sealed interface ThreadPartialChange : PartialChange<ThreadUiState> {
|
||||||
val nextPagePostId: Long,
|
val nextPagePostId: Long,
|
||||||
val hasPrevious: Boolean,
|
val hasPrevious: Boolean,
|
||||||
val firstPostContentRenders: List<PbContentRender>?,
|
val firstPostContentRenders: List<PbContentRender>?,
|
||||||
val contentRenders: List<ImmutableList<PbContentRender>>,
|
|
||||||
val subPostContents: List<ImmutableList<AnnotatedString>>,
|
|
||||||
val postId: Long = 0,
|
val postId: Long = 0,
|
||||||
val seeLz: Boolean = false,
|
val seeLz: Boolean = false,
|
||||||
val sortType: Int = 0,
|
val sortType: Int = 0,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue