feat: 用户页面贴子点赞
This commit is contained in:
parent
0be799a772
commit
e711e6e4df
|
|
@ -160,6 +160,36 @@ fun SubPostList.updateAgreeStatus(
|
|||
this
|
||||
}
|
||||
|
||||
fun PostInfoList.updateAgreeStatus(
|
||||
hasAgree: Int,
|
||||
) = if (agree != null) {
|
||||
if (hasAgree != agree.hasAgree) {
|
||||
if (hasAgree == 1) {
|
||||
copy(
|
||||
agree = agree.copy(
|
||||
agreeNum = agree.agreeNum + 1,
|
||||
diffAgreeNum = agree.diffAgreeNum + 1,
|
||||
hasAgree = 1
|
||||
),
|
||||
agree_num = agree_num + 1
|
||||
)
|
||||
} else {
|
||||
copy(
|
||||
agree = agree.copy(
|
||||
agreeNum = agree.agreeNum - 1,
|
||||
diffAgreeNum = agree.diffAgreeNum - 1,
|
||||
hasAgree = 0
|
||||
),
|
||||
agree_num = agree_num - 1
|
||||
)
|
||||
}
|
||||
} else {
|
||||
this
|
||||
}
|
||||
} else {
|
||||
this
|
||||
}
|
||||
|
||||
private val PbContent.picUrl: String
|
||||
get() =
|
||||
ImageUtil.getUrl(
|
||||
|
|
|
|||
|
|
@ -214,7 +214,15 @@ fun UserPostPage(
|
|||
)
|
||||
)
|
||||
},
|
||||
onAgreeItem = {},
|
||||
onAgreeItem = {
|
||||
viewModel.send(
|
||||
UserPostUiIntent.Agree(
|
||||
it.thread_id,
|
||||
it.post_id,
|
||||
it.agree?.hasAgree ?: 0
|
||||
)
|
||||
)
|
||||
},
|
||||
onClickReply = {
|
||||
navigator.navigate(
|
||||
ThreadPageDestination(
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
package com.huanchengfly.tieba.post.ui.page.user.post
|
||||
|
||||
import com.huanchengfly.tieba.post.App
|
||||
import com.huanchengfly.tieba.post.R
|
||||
import com.huanchengfly.tieba.post.api.TiebaApi
|
||||
import com.huanchengfly.tieba.post.api.models.AgreeBean
|
||||
import com.huanchengfly.tieba.post.api.models.protos.PostInfoList
|
||||
import com.huanchengfly.tieba.post.api.models.protos.updateAgreeStatus
|
||||
import com.huanchengfly.tieba.post.api.models.protos.userPost.UserPostResponse
|
||||
import com.huanchengfly.tieba.post.api.retrofit.exception.getErrorMessage
|
||||
import com.huanchengfly.tieba.post.arch.BaseViewModel
|
||||
import com.huanchengfly.tieba.post.arch.CommonUiEvent
|
||||
import com.huanchengfly.tieba.post.arch.ImmutableHolder
|
||||
import com.huanchengfly.tieba.post.arch.PartialChange
|
||||
import com.huanchengfly.tieba.post.arch.PartialChangeProducer
|
||||
|
|
@ -33,6 +39,18 @@ class UserPostViewModel @Inject constructor() :
|
|||
override fun createPartialChangeProducer(): PartialChangeProducer<UserPostUiIntent, UserPostPartialChange, UserPostUiState> =
|
||||
UserPostPartialChangeProducer
|
||||
|
||||
override fun dispatchEvent(partialChange: UserPostPartialChange): UiEvent? =
|
||||
when (partialChange) {
|
||||
is UserPostPartialChange.Agree.Failure -> CommonUiEvent.Toast(
|
||||
App.INSTANCE.getString(
|
||||
R.string.toast_agree_failed,
|
||||
partialChange.error.getErrorMessage()
|
||||
)
|
||||
)
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
private object UserPostPartialChangeProducer :
|
||||
PartialChangeProducer<UserPostUiIntent, UserPostPartialChange, UserPostUiState> {
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
|
@ -42,6 +60,8 @@ class UserPostViewModel @Inject constructor() :
|
|||
.flatMapConcat { it.toPartialChangeFlow() },
|
||||
intentFlow.filterIsInstance<UserPostUiIntent.LoadMore>()
|
||||
.flatMapConcat { it.toPartialChangeFlow() },
|
||||
intentFlow.filterIsInstance<UserPostUiIntent.Agree>()
|
||||
.flatMapConcat { it.toPartialChangeFlow() }
|
||||
)
|
||||
|
||||
private fun UserPostUiIntent.Refresh.toPartialChangeFlow(): Flow<UserPostPartialChange> =
|
||||
|
|
@ -74,6 +94,25 @@ class UserPostViewModel @Inject constructor() :
|
|||
}
|
||||
.onStart { emit(UserPostPartialChange.LoadMore.Start) }
|
||||
.catch { emit(UserPostPartialChange.LoadMore.Failure(it)) }
|
||||
|
||||
private fun UserPostUiIntent.Agree.toPartialChangeFlow(): Flow<UserPostPartialChange.Agree> =
|
||||
TiebaApi.getInstance()
|
||||
.opAgreeFlow(
|
||||
threadId.toString(), postId.toString(), hasAgree, objType = 3
|
||||
)
|
||||
.map<AgreeBean, UserPostPartialChange.Agree> {
|
||||
UserPostPartialChange.Agree.Success(threadId, postId, hasAgree xor 1)
|
||||
}
|
||||
.onStart {
|
||||
emit(
|
||||
UserPostPartialChange.Agree.Start(
|
||||
threadId,
|
||||
postId,
|
||||
hasAgree xor 1
|
||||
)
|
||||
)
|
||||
}
|
||||
.catch { emit(UserPostPartialChange.Agree.Failure(threadId, postId, hasAgree, it)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +127,12 @@ sealed interface UserPostUiIntent : UiIntent {
|
|||
val isThread: Boolean,
|
||||
val page: Int,
|
||||
) : UserPostUiIntent
|
||||
|
||||
data class Agree(
|
||||
val threadId: Long,
|
||||
val postId: Long,
|
||||
val hasAgree: Int,
|
||||
) : UserPostUiIntent
|
||||
}
|
||||
|
||||
sealed interface UserPostPartialChange : PartialChange<UserPostUiState> {
|
||||
|
|
@ -168,6 +213,75 @@ sealed interface UserPostPartialChange : PartialChange<UserPostUiState> {
|
|||
val error: Throwable,
|
||||
) : LoadMore()
|
||||
}
|
||||
|
||||
sealed class Agree : UserPostPartialChange {
|
||||
private fun List<ImmutableHolder<PostInfoList>>.updateAgreeStatus(
|
||||
threadId: Long,
|
||||
postId: Long,
|
||||
hasAgree: Int,
|
||||
): ImmutableList<ImmutableHolder<PostInfoList>> {
|
||||
return map {
|
||||
val (postInfo) = it
|
||||
if (postInfo.thread_id == threadId && postInfo.post_id == postId) {
|
||||
postInfo.updateAgreeStatus(hasAgree)
|
||||
} else {
|
||||
postInfo
|
||||
}
|
||||
}.wrapImmutable()
|
||||
}
|
||||
|
||||
override fun reduce(oldState: UserPostUiState): UserPostUiState =
|
||||
when (this) {
|
||||
is Start -> {
|
||||
oldState.copy(
|
||||
posts = oldState.posts.updateAgreeStatus(
|
||||
threadId,
|
||||
postId,
|
||||
hasAgree
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is Success -> {
|
||||
oldState.copy(
|
||||
posts = oldState.posts.updateAgreeStatus(
|
||||
threadId,
|
||||
postId,
|
||||
hasAgree
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
is Failure -> {
|
||||
oldState.copy(
|
||||
posts = oldState.posts.updateAgreeStatus(
|
||||
threadId,
|
||||
postId,
|
||||
hasAgree
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class Start(
|
||||
val threadId: Long,
|
||||
val postId: Long,
|
||||
val hasAgree: Int,
|
||||
) : Agree()
|
||||
|
||||
data class Success(
|
||||
val threadId: Long,
|
||||
val postId: Long,
|
||||
val hasAgree: Int,
|
||||
) : Agree()
|
||||
|
||||
data class Failure(
|
||||
val threadId: Long,
|
||||
val postId: Long,
|
||||
val hasAgree: Int,
|
||||
val error: Throwable,
|
||||
) : Agree()
|
||||
}
|
||||
}
|
||||
|
||||
data class UserPostUiState(
|
||||
|
|
|
|||
Loading…
Reference in New Issue