更新代码

This commit is contained in:
2024-09-07 20:26:15 +08:00
parent 49aea88b0b
commit 03a4db8a4b
12 changed files with 370 additions and 63 deletions

View File

@@ -4,10 +4,9 @@ import android.content.Context
object ConstVars { object ConstVars {
// api 地址 // api 地址
// const val BASE_SERVER = "http://192.168.31.190:8088" // const val BASE_SERVER = "http://192.168.31.190:8088" const val BASE_SERVER = "https://8.137.22.101:8088"
const val BASE_SERVER = "http://192.168.31.36:8088" // const val BASE_SERVER = "http://192.168.31.36:8088"
// const val BASE_SERVER = "https://8.137.22.101:8088"
const val MOMENT_LIKE_CHANNEL_ID = "moment_like" const val MOMENT_LIKE_CHANNEL_ID = "moment_like"
const val MOMENT_LIKE_CHANNEL_NAME = "Moment Like" const val MOMENT_LIKE_CHANNEL_NAME = "Moment Like"
@@ -16,6 +15,7 @@ object ConstVars {
enum class ErrorCode(val code: Int) { enum class ErrorCode(val code: Int) {
USER_EXIST(10001) USER_EXIST(10001)
} }
fun Context.getErrorMessageCode(code: Int?): String { fun Context.getErrorMessageCode(code: Int?): String {
return when (code) { return when (code) {
10001 -> getString(R.string.error_10001_user_exist) 10001 -> getString(R.string.error_10001_user_exist)

View File

@@ -21,7 +21,8 @@ interface CommentService {
pageNumber: Int, pageNumber: Int,
postId: Int? = null, postId: Int? = null,
postUser: Int? = null, postUser: Int? = null,
selfNotice: Boolean? = null selfNotice: Boolean? = null,
order: String? = null
): ListContainer<CommentEntity> ): ListContainer<CommentEntity>
/** /**
@@ -48,6 +49,12 @@ interface CommentService {
* @param commentId 评论ID * @param commentId 评论ID
*/ */
suspend fun updateReadStatus(commentId: Int) suspend fun updateReadStatus(commentId: Int)
/**
* 删除评论
* @param commentId 评论ID
*/
suspend fun DeleteComment(commentId: Int)
} }
/** /**
@@ -119,13 +126,15 @@ class CommentRemoteDataSource(
pageNumber: Int, pageNumber: Int,
postId: Int?, postId: Int?,
postUser: Int?, postUser: Int?,
selfNotice: Boolean? selfNotice: Boolean?,
order: String?
): ListContainer<CommentEntity> { ): ListContainer<CommentEntity> {
return commentService.getComments( return commentService.getComments(
pageNumber, pageNumber,
postId, postId,
postUser = postUser, postUser = postUser,
selfNotice = selfNotice selfNotice = selfNotice,
order = order
) )
} }
} }
@@ -136,12 +145,14 @@ class CommentServiceImpl : CommentService {
pageNumber: Int, pageNumber: Int,
postId: Int?, postId: Int?,
postUser: Int?, postUser: Int?,
selfNotice: Boolean? selfNotice: Boolean?,
order: String?
): ListContainer<CommentEntity> { ): ListContainer<CommentEntity> {
val resp = ApiClient.api.getComments( val resp = ApiClient.api.getComments(
page = pageNumber, page = pageNumber,
postId = postId, postId = postId,
postUser = postUser, postUser = postUser,
order = order,
selfNotice = selfNotice?.let { selfNotice = selfNotice?.let {
if (it) 1 else 0 if (it) 1 else 0
} }
@@ -175,4 +186,8 @@ class CommentServiceImpl : CommentService {
return return
} }
override suspend fun DeleteComment(commentId: Int) {
val resp = ApiClient.api.deleteComment(commentId)
return
}
} }

View File

@@ -174,6 +174,7 @@ interface RiderProAPI {
@Query("pageSize") pageSize: Int = 20, @Query("pageSize") pageSize: Int = 20,
@Query("postUser") postUser: Int? = null, @Query("postUser") postUser: Int? = null,
@Query("selfNotice") selfNotice: Int? = 0, @Query("selfNotice") selfNotice: Int? = 0,
@Query("order") order: String? = null,
): Response<ListContainer<Comment>> ): Response<ListContainer<Comment>>
@GET("account/my") @GET("account/my")
@@ -257,4 +258,9 @@ interface RiderProAPI {
@Path("id") id: Int @Path("id") id: Int
): Response<Unit> ): Response<Unit>
@DELETE("comment/{id}")
suspend fun deleteComment(
@Path("id") id: Int
): Response<Unit>
} }

View File

@@ -26,7 +26,8 @@ class CommentPagingSource(
private val remoteDataSource: CommentRemoteDataSource, private val remoteDataSource: CommentRemoteDataSource,
private val postId: Int? = null, private val postId: Int? = null,
private val postUser: Int? = null, private val postUser: Int? = null,
private val selfNotice: Boolean? = null private val selfNotice: Boolean? = null,
private val order: String? = null
) : PagingSource<Int, CommentEntity>() { ) : PagingSource<Int, CommentEntity>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, CommentEntity> { override suspend fun load(params: LoadParams<Int>): LoadResult<Int, CommentEntity> {
return try { return try {
@@ -35,7 +36,8 @@ class CommentPagingSource(
pageNumber = currentPage, pageNumber = currentPage,
postId = postId, postId = postId,
postUser = postUser, postUser = postUser,
selfNotice = selfNotice selfNotice = selfNotice,
order = order
) )
LoadResult.Page( LoadResult.Page(
data = comments.list, data = comments.list,

View File

@@ -2,6 +2,7 @@ package com.aiosman.riderpro.ui.comment
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
@@ -17,8 +18,11 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
@@ -48,6 +52,7 @@ import androidx.paging.PagingConfig
import androidx.paging.PagingData import androidx.paging.PagingData
import androidx.paging.cachedIn import androidx.paging.cachedIn
import androidx.paging.compose.collectAsLazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems
import com.aiosman.riderpro.AppState
import com.aiosman.riderpro.R import com.aiosman.riderpro.R
import com.aiosman.riderpro.data.CommentRemoteDataSource import com.aiosman.riderpro.data.CommentRemoteDataSource
import com.aiosman.riderpro.data.CommentService import com.aiosman.riderpro.data.CommentService
@@ -55,7 +60,9 @@ import com.aiosman.riderpro.data.CommentServiceImpl
import com.aiosman.riderpro.entity.CommentEntity import com.aiosman.riderpro.entity.CommentEntity
import com.aiosman.riderpro.entity.CommentPagingSource import com.aiosman.riderpro.entity.CommentPagingSource
import com.aiosman.riderpro.ui.modifiers.noRippleClickable import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import com.aiosman.riderpro.ui.post.CommentMenuModal
import com.aiosman.riderpro.ui.post.CommentsSection import com.aiosman.riderpro.ui.post.CommentsSection
import com.aiosman.riderpro.ui.post.OrderSelectionComponent
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -67,12 +74,21 @@ class CommentModalViewModel(
val postId: Int? val postId: Int?
) : ViewModel() { ) : ViewModel() {
val commentService: CommentService = CommentServiceImpl() val commentService: CommentService = CommentServiceImpl()
var commentText by mutableStateOf("") var commentText by mutableStateOf("")
var order by mutableStateOf("like")
val commentsFlow = MutableStateFlow<PagingData<CommentEntity>>(PagingData.empty()) val commentsFlow = MutableStateFlow<PagingData<CommentEntity>>(PagingData.empty())
init { init {
reloadComments() reloadComments()
} }
fun updateDeleteComment(commentId: Int) {
viewModelScope.launch {
commentService.DeleteComment(commentId)
reloadComments()
}
}
fun reloadComments() { fun reloadComments() {
viewModelScope.launch { viewModelScope.launch {
Pager( Pager(
@@ -80,7 +96,8 @@ class CommentModalViewModel(
pagingSourceFactory = { pagingSourceFactory = {
CommentPagingSource( CommentPagingSource(
CommentRemoteDataSource(commentService), CommentRemoteDataSource(commentService),
postId postId,
order = order
) )
} }
).flow.cachedIn(viewModelScope).collectLatest { ).flow.cachedIn(viewModelScope).collectLatest {
@@ -109,9 +126,11 @@ class CommentModalViewModel(
* @param onCommentAdded 评论添加回调 * @param onCommentAdded 评论添加回调
* @param onDismiss 关闭回调 * @param onDismiss 关闭回调
*/ */
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun CommentModalContent( fun CommentModalContent(
postId: Int? = null, postId: Int? = null,
commentCount: Int = 0,
onCommentAdded: () -> Unit = {}, onCommentAdded: () -> Unit = {},
onDismiss: () -> Unit = {} onDismiss: () -> Unit = {}
) { ) {
@@ -127,7 +146,8 @@ fun CommentModalContent(
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
model.reloadComments() model.reloadComments()
} }
var showCommentMenu by remember { mutableStateOf(false) }
var contextComment by remember { mutableStateOf<CommentEntity?>(null) }
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val comments = model.commentsFlow.collectAsLazyPagingItems() val comments = model.commentsFlow.collectAsLazyPagingItems()
val insets = WindowInsets val insets = WindowInsets
@@ -142,6 +162,29 @@ fun CommentModalContent(
onDismiss() onDismiss()
} }
} }
if (showCommentMenu) {
ModalBottomSheet(
onDismissRequest = {
showCommentMenu = false
},
containerColor = Color.White,
sheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = true
),
dragHandle = {},
shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
windowInsets = WindowInsets(0)
) {
CommentMenuModal(
onDeleteClick = {
showCommentMenu = false
contextComment?.let {
model.updateDeleteComment(it.id)
}
}
)
}
}
suspend fun sendComment() { suspend fun sendComment() {
if (model.commentText.isNotEmpty()) { if (model.commentText.isNotEmpty()) {
softwareKeyboardController?.hide() softwareKeyboardController?.hide()
@@ -169,24 +212,51 @@ fun CommentModalContent(
HorizontalDivider( HorizontalDivider(
color = Color(0xFFF7F7F7) color = Color(0xFFF7F7F7)
) )
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = stringResource(id = R.string.comment_count, commentCount),
fontSize = 14.sp,
color = Color(0xff666666)
)
OrderSelectionComponent {
model.order = it
model.reloadComments()
}
}
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp) .padding(horizontal = 16.dp)
.weight(1f) .weight(1f)
) { ) {
CommentsSection(lazyPagingItems = comments, onLike = { commentEntity: CommentEntity -> CommentsSection(
scope.launch { lazyPagingItems = comments,
if (commentEntity.liked) { onLike = { commentEntity: CommentEntity ->
model.commentService.dislikeComment(commentEntity.id) scope.launch {
} else { if (commentEntity.liked) {
model.commentService.likeComment(commentEntity.id) model.commentService.dislikeComment(commentEntity.id)
} else {
model.commentService.likeComment(commentEntity.id)
}
model.reloadComments()
} }
model.reloadComments() },
} onLongClick = { commentEntity: CommentEntity ->
}) { if (AppState.UserId?.toLong() == commentEntity.author) {
} contextComment = commentEntity
showCommentMenu = true
}
},
onWillCollapse = {
},
)
} }
Column( Column(
modifier = Modifier modifier = Modifier

View File

@@ -53,6 +53,7 @@ import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder
import com.aiosman.riderpro.ui.composables.CustomAsyncImage import com.aiosman.riderpro.ui.composables.CustomAsyncImage
import com.aiosman.riderpro.ui.composables.StatusBarSpacer import com.aiosman.riderpro.ui.composables.StatusBarSpacer
import com.aiosman.riderpro.ui.modifiers.noRippleClickable import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import com.aiosman.riderpro.ui.post.PostViewModel
import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.google.accompanist.systemuicontroller.rememberSystemUiController
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -72,8 +73,6 @@ fun NotificationsScreen() {
MessageListViewModel.initData() MessageListViewModel.initData()
} }
}) })
val navigationBarPaddings =
WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() + 48.dp
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
systemUiController.setNavigationBarColor(Color.Transparent) systemUiController.setNavigationBarColor(Color.Transparent)
MessageListViewModel.initData() MessageListViewModel.initData()
@@ -128,12 +127,17 @@ fun NotificationsScreen() {
comments[index]?.let { comment -> comments[index]?.let { comment ->
CommentNoticeItem(comment) { CommentNoticeItem(comment) {
MessageListViewModel.updateReadStatus(comment.id) MessageListViewModel.updateReadStatus(comment.id)
navController.navigate( MessageListViewModel.viewModelScope.launch {
NavigationRoute.Post.route.replace( PostViewModel.postId = comment.postId.toString()
"{id}", PostViewModel.initData()
comment.postId.toString() navController.navigate(
NavigationRoute.Post.route.replace(
"{id}",
comment.postId.toString()
)
) )
) }
} }
} }
} }

View File

@@ -484,9 +484,13 @@ fun MomentBottomOperateRowGroup(
} }
} }
) { ) {
CommentModalContent(postId = momentEntity.id, onCommentAdded = { CommentModalContent(
onAddComment() postId = momentEntity.id,
}) commentCount = momentEntity.commentCount,
onCommentAdded = {
onAddComment()
}
)
} }
} }
Box( Box(

View File

@@ -158,4 +158,19 @@ object MomentViewModel : ViewModel() {
} }
_momentsFlow.value = updatedPagingData _momentsFlow.value = updatedPagingData
} }
/**
* 更新动态评论数
*/
fun updateMomentCommentCount(id: Int,delta: Int) {
val currentPagingData = _momentsFlow.value
val updatedPagingData = currentPagingData.map { momentItem ->
if (momentItem.id == id) {
momentItem.copy(commentCount = momentItem.commentCount + delta)
} else {
momentItem
}
}
_momentsFlow.value = updatedPagingData
}
} }

View File

@@ -5,6 +5,8 @@ import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@@ -79,6 +81,7 @@ import com.aiosman.riderpro.ui.imageviewer.ImageViewerViewModel
import com.aiosman.riderpro.ui.modifiers.noRippleClickable import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun PostScreen( fun PostScreen(
id: String, id: String,
@@ -86,11 +89,35 @@ fun PostScreen(
val viewModel = PostViewModel val viewModel = PostViewModel
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val commentsPagging = viewModel.commentsFlow.collectAsLazyPagingItems() val commentsPagging = viewModel.commentsFlow.collectAsLazyPagingItems()
val showMenuModal by remember { mutableStateOf(false) }
val navController = LocalNavController.current val navController = LocalNavController.current
var showCommentMenu by remember { mutableStateOf(false) }
var contextComment by remember { mutableStateOf<CommentEntity?>(null) }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
viewModel.initData() viewModel.initData()
} }
if (showCommentMenu) {
ModalBottomSheet(
onDismissRequest = {
showCommentMenu = false
},
containerColor = Color.White,
sheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = true
),
dragHandle = {},
shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
windowInsets = WindowInsets(0)
) {
CommentMenuModal(
onDeleteClick = {
showCommentMenu = false
contextComment?.let {
viewModel.deleteComment(it.id)
}
}
)
}
}
Scaffold( Scaffold(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
bottomBar = { bottomBar = {
@@ -183,7 +210,8 @@ fun PostScreen(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp), .padding(horizontal = 16.dp),
horizontalArrangement = Arrangement.SpaceBetween horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) { ) {
Text( Text(
text = stringResource( text = stringResource(
@@ -191,10 +219,14 @@ fun PostScreen(
(viewModel.moment?.commentCount ?: 0) (viewModel.moment?.commentCount ?: 0)
), fontSize = 14.sp ), fontSize = 14.sp
) )
Spacer(modifier = Modifier.weight(1f))
OrderSelectionComponent() {
viewModel.order = it
viewModel.reloadComment()
}
} }
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
} }
items(commentsPagging.itemCount) { idx -> items(commentsPagging.itemCount) { idx ->
@@ -202,17 +234,26 @@ fun PostScreen(
Box( Box(
modifier = Modifier.padding(horizontal = 16.dp) modifier = Modifier.padding(horizontal = 16.dp)
) { ) {
CommentItem(item, onLike = { CommentItem(
scope.launch { item,
if (item.liked) { onLike = {
viewModel.unlikeComment(item.id) scope.launch {
} else { if (item.liked) {
viewModel.likeComment(item.id) viewModel.unlikeComment(item.id)
} else {
viewModel.likeComment(item.id)
}
} }
},
onLongClick = {
if (AppState.UserId != item.id) {
return@CommentItem
}
showCommentMenu = true
contextComment = item
} }
}) )
} }
} }
item { item {
Spacer(modifier = Modifier.height(72.dp)) Spacer(modifier = Modifier.height(72.dp))
@@ -329,17 +370,19 @@ fun Header(
) )
} }
} }
Spacer(modifier = Modifier.weight(1f)) if (AppState.UserId == userId) {
Box { Spacer(modifier = Modifier.weight(1f))
Image( Box {
modifier = Modifier Image(
.height(20.dp) modifier = Modifier
.noRippleClickable { .height(20.dp)
expanded = true .noRippleClickable {
}, expanded = true
painter = painterResource(id = R.drawable.rider_pro_more_horizon), },
contentDescription = "" painter = painterResource(id = R.drawable.rider_pro_more_horizon),
) contentDescription = ""
)
}
} }
} }
} }
@@ -416,7 +459,6 @@ fun PostImageView(
} }
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable @Composable
fun PostDetails( fun PostDetails(
momentEntity: MomentEntity? momentEntity: MomentEntity?
@@ -444,7 +486,8 @@ fun CommentsSection(
lazyPagingItems: LazyPagingItems<CommentEntity>, lazyPagingItems: LazyPagingItems<CommentEntity>,
scrollState: LazyListState = rememberLazyListState(), scrollState: LazyListState = rememberLazyListState(),
onLike: (CommentEntity) -> Unit, onLike: (CommentEntity) -> Unit,
onWillCollapse: (Boolean) -> Unit onLongClick: (CommentEntity) -> Unit,
onWillCollapse: (Boolean) -> Unit,
) { ) {
LazyColumn( LazyColumn(
state = scrollState, modifier = Modifier state = scrollState, modifier = Modifier
@@ -453,9 +496,15 @@ fun CommentsSection(
) { ) {
items(lazyPagingItems.itemCount) { idx -> items(lazyPagingItems.itemCount) { idx ->
val item = lazyPagingItems[idx] ?: return@items val item = lazyPagingItems[idx] ?: return@items
CommentItem(item, onLike = { CommentItem(
onLike(item) item,
}) onLike = {
onLike(item)
},
onLongClick = {
onLongClick(item)
}
)
} }
} }
@@ -473,11 +522,25 @@ fun CommentsSection(
} }
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun CommentItem(commentEntity: CommentEntity, onLike: () -> Unit = {}) { fun CommentItem(
commentEntity: CommentEntity,
onLike: () -> Unit = {},
onLongClick: () -> Unit = {}
) {
val context = LocalContext.current val context = LocalContext.current
val navController = LocalNavController.current val navController = LocalNavController.current
Column { Column(
modifier = Modifier
.fillMaxWidth()
.combinedClickable(
indication = null,
interactionSource = remember { MutableInteractionSource() },
onClick = {},
onLongClick = onLongClick
)
) {
Row(modifier = Modifier.padding(vertical = 8.dp)) { Row(modifier = Modifier.padding(vertical = 8.dp)) {
Box( Box(
modifier = Modifier modifier = Modifier
@@ -676,3 +739,99 @@ fun PostMenuModal(
} }
} }
} }
@Composable
fun CommentMenuModal(
onDeleteClick: () -> Unit = {}
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 24.dp, horizontal = 24.dp)
) {
Row(
modifier = Modifier
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier,
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Box(
modifier = Modifier
.clip(CircleShape)
.background(Color(0xFFE5E5E5))
.padding(8.dp)
.noRippleClickable {
onDeleteClick()
}
) {
Image(
painter = painterResource(id = R.drawable.rider_pro_delete),
contentDescription = "Delete",
modifier = Modifier.size(24.dp),
colorFilter = ColorFilter.tint(Color.Black)
)
}
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Delete",
fontSize = 14.sp,
fontWeight = FontWeight.Bold
)
}
}
}
}
@Composable
fun OrderSelectionComponent(
onSelected: (String) -> Unit = {}
) {
var selectedOrder by remember { mutableStateOf("like") }
val orders = listOf(
"like" to stringResource(R.string.order_comment_default),
"earliest" to stringResource(R.string.order_comment_earliest),
"latest" to stringResource(R.string.order_comment_latest)
)
Box(
modifier = Modifier
.clip(RoundedCornerShape(8.dp))
.background(Color(0xFFEEEEEE))
) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
.padding(4.dp)
.clip(RoundedCornerShape(6.dp))
) {
orders.forEach { order ->
Box(
modifier = Modifier
.noRippleClickable {
selectedOrder = order.first
onSelected(order.first)
}
.background(
if (
selectedOrder == order.first
) Color.White else Color.Transparent
)
.padding(vertical = 2.dp, horizontal = 8.dp),
) {
Text(
text = order.second,
color = Color.Black,
fontSize = 12.sp
)
}
}
}
}
}

View File

@@ -36,6 +36,7 @@ object PostViewModel : ViewModel() {
private var _commentsFlow = MutableStateFlow<PagingData<CommentEntity>>(PagingData.empty()) private var _commentsFlow = MutableStateFlow<PagingData<CommentEntity>>(PagingData.empty())
val commentsFlow = _commentsFlow.asStateFlow() val commentsFlow = _commentsFlow.asStateFlow()
var postId: String = "" var postId: String = ""
var order: String by mutableStateOf("like")
// 预加载的 moment // 预加载的 moment
@@ -71,7 +72,8 @@ object PostViewModel : ViewModel() {
pagingSourceFactory = { pagingSourceFactory = {
CommentPagingSource( CommentPagingSource(
CommentRemoteDataSource(commentService), CommentRemoteDataSource(commentService),
postId = postId.toInt() postId = postId.toInt(),
order = order
) )
} }
).flow.cachedIn(viewModelScope).collectLatest { ).flow.cachedIn(viewModelScope).collectLatest {
@@ -82,6 +84,20 @@ object PostViewModel : ViewModel() {
suspend fun initData() { suspend fun initData() {
moment = service.getMomentById(postId.toInt()) moment = service.getMomentById(postId.toInt())
accountProfileEntity = userService.getUserProfile(moment?.authorId.toString())
viewModelScope.launch {
Pager(
config = PagingConfig(pageSize = 5, enablePlaceholders = false),
pagingSourceFactory = {
CommentPagingSource(
CommentRemoteDataSource(commentService),
postId = postId.toInt()
)
}
).flow.cachedIn(viewModelScope).collectLatest {
_commentsFlow.value = it
}
}
// moment?.let { // moment?.let {
// accountProfileEntity = userService.getUserProfile(it.authorId.toString()) // accountProfileEntity = userService.getUserProfile(it.authorId.toString())
// } // }
@@ -168,6 +184,16 @@ object PostViewModel : ViewModel() {
accountProfileEntity = accountProfileEntity?.copy(isFollowing = false) accountProfileEntity = accountProfileEntity?.copy(isFollowing = false)
} }
} }
fun deleteComment(commentId: Int) {
viewModelScope.launch {
commentService.DeleteComment(commentId)
moment = moment?.copy(commentCount = moment?.commentCount?.minus(1) ?: 0)
reloadComment()
moment?.let {
MomentViewModel.updateMomentCommentCount(it.id, -1)
}
}
}
var avatar: String? = null var avatar: String? = null
get() { get() {

View File

@@ -54,4 +54,7 @@
<string name="bio">个性签名</string> <string name="bio">个性签名</string>
<string name="nickname">昵称</string> <string name="nickname">昵称</string>
<string name="comment">评论</string> <string name="comment">评论</string>
<string name="order_comment_default">默认</string>
<string name="order_comment_latest">最新</string>
<string name="order_comment_earliest">最早</string>
</resources> </resources>

View File

@@ -53,4 +53,7 @@
<string name="bio">Signature</string> <string name="bio">Signature</string>
<string name="nickname">Name</string> <string name="nickname">Name</string>
<string name="comment">Comment</string> <string name="comment">Comment</string>
<string name="order_comment_default">Default</string>
<string name="order_comment_latest">Latest</string>
<string name="order_comment_earliest">Earliest</string>
</resources> </resources>