From 1186e3a8a55ffa6948f393699375520304713f75 Mon Sep 17 00:00:00 2001 From: AllenTom Date: Wed, 11 Sep 2024 22:21:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiosman/riderpro/data/AccountService.kt | 55 +++++++- .../com/aiosman/riderpro/entity/Account.kt | 19 ++- .../aiosman/riderpro/ui/composables/Image.kt | 8 +- .../ui/favourite/FavouriteNoticeScreen.kt | 4 +- .../com/aiosman/riderpro/ui/like/LikePage.kt | 133 ++++++++++++++++-- 5 files changed, 195 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/aiosman/riderpro/data/AccountService.kt b/app/src/main/java/com/aiosman/riderpro/data/AccountService.kt index 9abb524..67d3274 100644 --- a/app/src/main/java/com/aiosman/riderpro/data/AccountService.kt +++ b/app/src/main/java/com/aiosman/riderpro/data/AccountService.kt @@ -10,6 +10,7 @@ import com.aiosman.riderpro.data.api.UpdateNoticeRequestBody import com.aiosman.riderpro.entity.AccountFavouriteEntity import com.aiosman.riderpro.entity.AccountLikeEntity import com.aiosman.riderpro.entity.AccountProfileEntity +import com.aiosman.riderpro.entity.NoticeCommentEntity import com.aiosman.riderpro.entity.NoticePostEntity import com.aiosman.riderpro.entity.NoticeUserEntity import com.google.gson.annotations.SerializedName @@ -102,6 +103,34 @@ data class NoticePost( } } +//"comment": { +// "id": 103, +// "content": "ppp", +// "time": "2024-09-08 15:31:37" +//} +data class NoticeComment( + @SerializedName("id") + val id: Int, + @SerializedName("content") + val content: String, + @SerializedName("time") + val time: String, + @SerializedName("replyComment") + val replyComment: NoticeComment?, + @SerializedName("postId") + val postId: Int, +) { + fun toNoticeCommentEntity(): NoticeCommentEntity { + return NoticeCommentEntity( + id = id, + content = content, + postId = postId, + time = ApiClient.dateFromApiString(time), + replyComment = replyComment?.toNoticeCommentEntity() + ) + } +} + /** * 消息关联用户 */ @@ -137,19 +166,26 @@ data class AccountLike( val isUnread: Boolean, // 动态 @SerializedName("post") - val post: NoticePost, + val post: NoticePost?, + @SerializedName("comment") + val comment: NoticeComment?, // 点赞用户 @SerializedName("user") val user: NoticeUser, // 点赞时间 @SerializedName("likeTime") val likeTime: String, + // 动态ID + @SerializedName("postId") + val postId: Int, ) { fun toAccountLikeEntity(): AccountLikeEntity { return AccountLikeEntity( - post = post.toNoticePostEntity(), + post = post?.toNoticePostEntity(), + comment = comment?.toNoticeCommentEntity(), user = user.toNoticeUserEntity(), - likeTime = ApiClient.dateFromApiString(likeTime) + likeTime = ApiClient.dateFromApiString(likeTime), + postId = postId ) } } @@ -302,7 +338,7 @@ interface AccountService { */ suspend fun updateNotice(payload: UpdateNoticeRequestBody) - suspend fun registerMessageChannel(client:String,identifier:String) + suspend fun registerMessageChannel(client: String, identifier: String) } class AccountServiceImpl : AccountService { @@ -320,8 +356,13 @@ class AccountServiceImpl : AccountService { override suspend fun loginUserWithPassword(loginName: String, password: String): UserAuth { val resp = ApiClient.api.login(LoginUserRequestBody(loginName, password)) - val body = resp.body() ?: throw ServiceException("Failed to login") - return UserAuth(0, body.token) + if (!resp.isSuccessful) { + parseErrorResponse(resp.errorBody())?.let { + throw it.toServiceException() + } + throw ServiceException("Failed to register") + } + return UserAuth(0, resp.body()?.token) } override suspend fun loginUserWithGoogle(googleId: String): UserAuth { @@ -411,7 +452,7 @@ class AccountServiceImpl : AccountService { } override suspend fun registerMessageChannel(client: String, identifier: String) { - ApiClient.api.registerMessageChannel(RegisterMessageChannelRequestBody(client,identifier)) + ApiClient.api.registerMessageChannel(RegisterMessageChannelRequestBody(client, identifier)) } } \ No newline at end of file diff --git a/app/src/main/java/com/aiosman/riderpro/entity/Account.kt b/app/src/main/java/com/aiosman/riderpro/entity/Account.kt index 290cfe3..d71aa40 100644 --- a/app/src/main/java/com/aiosman/riderpro/entity/Account.kt +++ b/app/src/main/java/com/aiosman/riderpro/entity/Account.kt @@ -14,11 +14,15 @@ import java.util.Date */ data class AccountLikeEntity( // 动态 - val post: NoticePostEntity, + val post: NoticePostEntity?, + // 回复评论 + val comment: NoticeCommentEntity?, // 点赞用户 val user: NoticeUserEntity, // 点赞时间 val likeTime: Date, + // 动态ID + val postId: Int ) /** @@ -71,6 +75,19 @@ data class NoticePostEntity( val time: Date, ) +data class NoticeCommentEntity( + // 评论ID + val id: Int, + // 评论内容 + val content: String, + // 评论时间 + val time: Date, + // 引用评论 + val replyComment: NoticeCommentEntity?, + // 动态 + val postId: Int, +) + /** * 消息关联的用户 */ diff --git a/app/src/main/java/com/aiosman/riderpro/ui/composables/Image.kt b/app/src/main/java/com/aiosman/riderpro/ui/composables/Image.kt index a95001c..f077bc9 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/composables/Image.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/composables/Image.kt @@ -49,7 +49,7 @@ fun rememberImageBitmap(imageUrl: String, imageLoader: ImageLoader): Bitmap? { @Composable fun CustomAsyncImage( - context: Context, + context: Context? = null, imageUrl: String?, contentDescription: String?, modifier: Modifier = Modifier, @@ -58,7 +58,9 @@ fun CustomAsyncImage( placeholderRes: Int? = null, contentScale: ContentScale = ContentScale.Crop ) { - val imageLoader = getImageLoader(context) + val localContext = LocalContext.current + + val imageLoader = getImageLoader(context ?: localContext) // val blurBitmap = remember(blurHash) { // blurHash?.let { // BlurHashDecoder.decode( @@ -86,7 +88,7 @@ fun CustomAsyncImage( // } AsyncImage( - model = ImageRequest.Builder(context) + model = ImageRequest.Builder(context ?: localContext) .data(imageUrl) .crossfade(200) .build(), diff --git a/app/src/main/java/com/aiosman/riderpro/ui/favourite/FavouriteNoticeScreen.kt b/app/src/main/java/com/aiosman/riderpro/ui/favourite/FavouriteNoticeScreen.kt index 720c366..16af645 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/favourite/FavouriteNoticeScreen.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/favourite/FavouriteNoticeScreen.kt @@ -18,7 +18,7 @@ import com.aiosman.riderpro.R import com.aiosman.riderpro.ui.comment.NoticeScreenHeader import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder -import com.aiosman.riderpro.ui.like.ActionNoticeItem +import com.aiosman.riderpro.ui.like.ActionPostNoticeItem /** * 收藏消息界面 @@ -59,7 +59,7 @@ fun FavouriteNoticeScreen() { items(favourites.itemCount) { val favouriteItem = favourites[it] if (favouriteItem != null) { - ActionNoticeItem( + ActionPostNoticeItem( avatar = favouriteItem.user.avatar, nickName = favouriteItem.user.nickName, likeTime = favouriteItem.favoriteTime, diff --git a/app/src/main/java/com/aiosman/riderpro/ui/like/LikePage.kt b/app/src/main/java/com/aiosman/riderpro/ui/like/LikePage.kt index 80b1673..30b2ec0 100644 --- a/app/src/main/java/com/aiosman/riderpro/ui/like/LikePage.kt +++ b/app/src/main/java/com/aiosman/riderpro/ui/like/LikePage.kt @@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.text.ClickableText import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -20,21 +21,30 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.paging.compose.collectAsLazyPagingItems +import com.aiosman.riderpro.AppState import com.aiosman.riderpro.LocalNavController import com.aiosman.riderpro.R +import com.aiosman.riderpro.entity.AccountLikeEntity import com.aiosman.riderpro.exp.timeAgo import com.aiosman.riderpro.ui.NavigationRoute import com.aiosman.riderpro.ui.comment.NoticeScreenHeader +import com.aiosman.riderpro.ui.composables.AnimatedLikeIcon import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder import com.aiosman.riderpro.ui.composables.CustomAsyncImage import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout +import com.aiosman.riderpro.ui.index.tabs.profile.MyProfileViewModel import com.aiosman.riderpro.ui.modifiers.noRippleClickable import java.util.Date @@ -77,15 +87,20 @@ fun LikeNoticeScreen() { items(likes.itemCount) { val likeItem = likes[it] if (likeItem != null) { - ActionNoticeItem( - avatar = likeItem.user.avatar, - nickName = likeItem.user.nickName, - likeTime = likeItem.likeTime, - thumbnail = likeItem.post.images[0].thumbnail, - action = "like", - userId = likeItem.user.id, - postId = likeItem.post.id - ) + likeItem.post?.let { post -> + ActionPostNoticeItem( + avatar = likeItem.user.avatar, + nickName = likeItem.user.nickName, + likeTime = likeItem.likeTime, + thumbnail = post.images[0].thumbnail, + action = "like", + userId = likeItem.user.id, + postId = post.id + ) + } + likeItem.comment?.let { comment -> + LikeCommentNoticeItem(likeItem) + } } } item { @@ -98,7 +113,7 @@ fun LikeNoticeScreen() { @Composable -fun ActionNoticeItem( +fun ActionPostNoticeItem( avatar: String, nickName: String, likeTime: Date, @@ -146,7 +161,12 @@ fun ActionNoticeItem( } ) { Text(nickName, fontWeight = FontWeight.Bold, fontSize = 16.sp) - Spacer(modifier = Modifier.height(5.dp)) + Spacer(modifier = Modifier.height(2.dp)) + when (action) { + "like" -> Text("Like your post") + "favourite" -> Text("Favourite your post") + } + Spacer(modifier = Modifier.height(2.dp)) Row { Text(likeTime.timeAgo(context), fontSize = 12.sp, color = Color(0x99000000)) } @@ -159,4 +179,95 @@ fun ActionNoticeItem( ) } } +} + +@Composable +fun LikeCommentNoticeItem( + item: AccountLikeEntity +) { + val navController = LocalNavController.current + val context = LocalContext.current + Box( + modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp).noRippleClickable { + item.comment?.postId.let { + navController.navigate( + NavigationRoute.Post.route.replace( + "{id}", + it.toString() + ) + ) + } + + } + ) { + Column( + + ) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.Top, + ) { + CustomAsyncImage( + imageUrl = item.user.avatar, + modifier = Modifier + .size(48.dp) + .clip(CircleShape), + contentDescription = "Like your comment" + ) + Spacer(modifier = Modifier.width(12.dp)) + Column( + modifier = Modifier + .weight(1f) + ) { + Text(item.user.nickName, fontWeight = FontWeight.Bold, fontSize = 16.sp) + Spacer(modifier = Modifier.height(2.dp)) + Text("Like your comment") + Spacer(modifier = Modifier.height(2.dp)) + Row { + Text( + item.likeTime.timeAgo(context), + fontSize = 12.sp, + color = Color(0x99000000) + ) + } + } + } + Spacer(modifier = Modifier.height(12.dp)) + Row( + modifier = Modifier.padding(start = 48.dp) + ) { + Box( + modifier = Modifier + .size(24.dp) + .background(Color.Gray.copy(alpha = 0.1f)) + ) { + CustomAsyncImage( + context = context, + imageUrl = MyProfileViewModel.avatar, + contentDescription = "Comment Profile Picture", + modifier = Modifier.size(24.dp), + contentScale = ContentScale.Crop + ) + } + Spacer(modifier = Modifier.width(8.dp)) + Column( + modifier = Modifier.weight(1f) + ) { + Text( + text = MyProfileViewModel.nickName, + fontWeight = FontWeight.W600, + fontSize = 14.sp + ) + Text( + text = item.comment?.content ?: "", + fontSize = 12.sp, + color = Color(0x99000000) + ) + } + } + + + } + + } } \ No newline at end of file