Moment 页面优化

- Moment 页面新增图片索引指示器
- 调整 Moment 页面布局,增加间距
- 优化 Moment 页面加载逻辑
This commit is contained in:
2024-09-02 23:14:38 +08:00
parent 48b1b1fe51
commit 51c8eaa9ef
4 changed files with 147 additions and 139 deletions

View File

@@ -8,8 +8,6 @@ import androidx.compose.animation.SharedTransitionLayout
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.navigationBars
@@ -36,14 +34,14 @@ import com.aiosman.riderpro.ui.gallery.OfficialGalleryScreen
import com.aiosman.riderpro.ui.gallery.OfficialPhotographerScreen
import com.aiosman.riderpro.ui.gallery.ProfileTimelineScreen
import com.aiosman.riderpro.ui.index.IndexScreen
import com.aiosman.riderpro.ui.index.tabs.message.NotificationsScreen
import com.aiosman.riderpro.ui.index.tabs.search.SearchScreen
import com.aiosman.riderpro.ui.like.LikeScreen
import com.aiosman.riderpro.ui.location.LocationDetailScreen
import com.aiosman.riderpro.ui.login.EmailSignupScreen
import com.aiosman.riderpro.ui.login.LoginPage
import com.aiosman.riderpro.ui.login.SignupScreen
import com.aiosman.riderpro.ui.login.UserAuthScreen
import com.aiosman.riderpro.ui.index.tabs.message.NotificationsScreen
import com.aiosman.riderpro.ui.index.tabs.search.SearchScreen
import com.aiosman.riderpro.ui.modification.EditModificationScreen
import com.aiosman.riderpro.ui.post.NewPostImageGridScreen
import com.aiosman.riderpro.ui.post.NewPostScreen
@@ -130,10 +128,10 @@ fun NavigationController(
route = NavigationRoute.Post.route,
arguments = listOf(navArgument("id") { type = NavType.StringType }),
enterTransition = {
fadeIn(animationSpec = tween(durationMillis = 100))
fadeIn(animationSpec = tween(durationMillis = 50))
},
exitTransition = {
fadeOut(animationSpec = tween(durationMillis = 100))
fadeOut(animationSpec = tween(durationMillis = 50))
}
) { backStackEntry ->
CompositionLocalProvider(

View File

@@ -63,9 +63,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.paging.LoadState
import androidx.paging.compose.collectAsLazyPagingItems
import com.aiosman.riderpro.LocalAnimatedContentScope
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.LocalSharedTransitionScope
import com.aiosman.riderpro.R
import com.aiosman.riderpro.entity.MomentEntity
import com.aiosman.riderpro.entity.MomentImageEntity
@@ -148,6 +146,7 @@ fun MomentsList() {
}
}
)
Box(modifier = Modifier.height(16.dp).fillMaxWidth().background(Color(0xFFF0F2F5)))
}
}
PullRefreshIndicator(refreshing, state, Modifier.align(Alignment.TopCenter))
@@ -163,12 +162,13 @@ fun MomentCard(
onAddComment: () -> Unit = {},
hideAction: Boolean = false
) {
var imageIndex by remember { mutableStateOf(0) }
val navController = LocalNavController.current
Column(
modifier = Modifier.fillMaxWidth()
) {
Box(
modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp)
modifier = Modifier.padding(start = 24.dp, end = 24.dp, top = 16.dp, bottom = 8.dp)
) {
MomentTopRowGroup(momentEntity = momentEntity)
}
@@ -180,15 +180,13 @@ fun MomentCard(
navController.navigate("Post/${momentEntity.id}")
}
) {
MomentContentGroup(momentEntity = momentEntity)
MomentContentGroup(
momentEntity = momentEntity,
onPageChange = { index -> imageIndex = index }
)
}
val momentOperateBtnBoxModifier = Modifier
.fillMaxHeight()
.weight(1f)
// ModificationListHeader()
if (!hideAction) {
MomentBottomOperateRowGroup(
momentOperateBtnBoxModifier,
momentEntity = momentEntity,
onLikeClick = onLikeClick,
onAddComment = onAddComment,
@@ -197,10 +195,10 @@ fun MomentCard(
NewPostViewModel.relPostId = momentEntity.id
navController.navigate(NavigationRoute.NewPost.route)
},
onFavoriteClick = onFavoriteClick
onFavoriteClick = onFavoriteClick,
imageIndex = imageIndex
)
}
}
}
@@ -294,7 +292,7 @@ fun MomentPostLocation(location: String) {
@Composable
fun MomentPostTime(time: String) {
Text(
modifier = Modifier.padding(start = 8.dp),
modifier = Modifier,
text = time, color = Color(0f, 0f, 0f, 0.6f),
fontSize = 12.sp
)
@@ -343,8 +341,10 @@ fun MomentTopRowGroup(momentEntity: MomentEntity) {
.height(21.dp),
verticalAlignment = Alignment.CenterVertically
) {
MomentPostLocation(momentEntity.location)
MomentPostTime(momentEntity.time.timeAgo(context))
Spacer(modifier = Modifier.width(8.dp))
MomentPostLocation(momentEntity.location)
}
}
}
@@ -353,13 +353,13 @@ fun MomentTopRowGroup(momentEntity: MomentEntity) {
@OptIn(ExperimentalFoundationApi::class, ExperimentalSharedTransitionApi::class)
@Composable
fun PostImageView(
postId: String,
images: List<MomentImageEntity>,
onPageChange: (Int) -> Unit = {}
) {
val pagerState = rememberPagerState(pageCount = { images.size })
val navController = LocalNavController.current
val sharedTransitionScope = LocalSharedTransitionScope.current
val animatedVisibilityScope = LocalAnimatedContentScope.current
LaunchedEffect(pagerState.currentPage) {
onPageChange(pagerState.currentPage)
}
val context = LocalContext.current
Column(
@@ -372,18 +372,6 @@ fun PostImageView(
.aspectRatio(1f),
) { page ->
val image = images[page]
// AsyncBlurImage(
// imageUrl = image.url,
// blurHash = image.blurHash ?: "",
// contentDescription = "Image",
// contentScale = ContentScale.Crop,
// modifier = Modifier
// .sharedElement(
// rememberSharedContentState(key = image),
// animatedVisibilityScope = animatedVisibilityScope
// )
// .fillMaxSize()
// )
CustomAsyncImage(
context,
image.thumbnail,
@@ -392,43 +380,34 @@ fun PostImageView(
contentScale = ContentScale.Crop,
modifier = Modifier
.fillMaxSize()
// .noRippleClickable {
// ImageViewerViewModel.asNew(images, page)
// navController.navigate(
// NavigationRoute.ImageViewer.route
// )
// }
)
}
// Indicator container
if (images.size > 1) {
Row(
modifier = Modifier
.padding(8.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
images.forEachIndexed { index, _ ->
Box(
modifier = Modifier
.size(8.dp)
.clip(CircleShape)
.background(
if (pagerState.currentPage == index) Color.Red else Color.Gray.copy(
alpha = 0.5f
)
)
.padding(4.dp)
)
Spacer(modifier = Modifier.width(8.dp))
}
}
}
// if (images.size > 1) {
// Row(
// modifier = Modifier
// .padding(8.dp)
// .fillMaxWidth(),
// horizontalArrangement = Arrangement.Center
// ) {
// images.forEachIndexed { index, _ ->
// Box(
// modifier = Modifier
// .size(8.dp)
// .clip(CircleShape)
// .background(
// if (pagerState.currentPage == index) Color.Red else Color.Gray.copy(
// alpha = 0.5f
// )
// )
// .padding(4.dp)
// )
// Spacer(modifier = Modifier.width(8.dp))
// }
// }
// }
}
@@ -437,13 +416,14 @@ fun PostImageView(
@Composable
fun MomentContentGroup(
momentEntity: MomentEntity,
onPageChange: (Int) -> Unit = {}
) {
if (momentEntity.momentTextContent.isNotEmpty()) {
Text(
text = momentEntity.momentTextContent,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 8.dp),
.padding(start = 24.dp,end = 24.dp, bottom = 8.dp),
fontSize = 16.sp
)
}
@@ -457,8 +437,8 @@ fun MomentContentGroup(
modifier = Modifier.fillMaxWidth()
) {
PostImageView(
postId = momentEntity.id.toString(),
images = momentEntity.images
images = momentEntity.images,
onPageChange = onPageChange
)
}
}
@@ -493,7 +473,9 @@ fun MomentOperateBtn(count: String, content: @Composable () -> Unit) {
AnimatedCounter(
count = count.toInt(),
fontSize = 14,
modifier = Modifier.padding(start = 7.dp)
modifier = Modifier
.padding(start = 7.dp)
.width(24.dp)
)
}
}
@@ -501,12 +483,12 @@ fun MomentOperateBtn(count: String, content: @Composable () -> Unit) {
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MomentBottomOperateRowGroup(
modifier: Modifier,
onLikeClick: () -> Unit = {},
onAddComment: () -> Unit = {},
onFavoriteClick: () -> Unit = {},
onShareClick: () -> Unit = {},
momentEntity: MomentEntity
momentEntity: MomentEntity,
imageIndex: Int = 0
) {
var showCommentModal by remember { mutableStateOf(false) }
if (showCommentModal) {
@@ -528,76 +510,98 @@ fun MomentBottomOperateRowGroup(
}
}
) {
// systemUiController.setNavigationBarColor(Color(0xfff7f7f7))
CommentModalContent(postId = momentEntity.id, onCommentAdded = {
showCommentModal = false
onAddComment()
}) {
// systemUiController.setNavigationBarColor(Color.Black)
}
})
}
}
Row(
Box(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.padding(horizontal = 16.dp)
) {
Box(
modifier = modifier,
contentAlignment = Alignment.Center
Row(
modifier = Modifier.fillMaxSize()
) {
MomentOperateBtn(count = momentEntity.likeCount.toString()) {
AnimatedLikeIcon(
modifier = Modifier.size(24.dp),
liked = momentEntity.liked
) {
onLikeClick()
}
}
}
Box(
modifier = modifier.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
Box(
modifier = Modifier.fillMaxHeight(),
contentAlignment = Alignment.Center
) {
showCommentModal = true
},
contentAlignment = Alignment.Center
) {
MomentOperateBtn(
icon = R.drawable.rider_pro_moment_comment,
count = momentEntity.commentCount.toString()
)
}
// Box(
// modifier = modifier.noRippleClickable {
// onShareClick()
// },
// contentAlignment = Alignment.Center
// ) {
// MomentOperateBtn(
// icon = R.drawable.rider_pro_share,
// count = momentEntity.shareCount.toString()
// )
// }
Box(
modifier = modifier.noRippleClickable {
onFavoriteClick()
},
contentAlignment = Alignment.Center
) {
MomentOperateBtn(count = momentEntity.favoriteCount.toString()) {
AnimatedFavouriteIcon(
modifier = Modifier.size(24.dp),
isFavourite = momentEntity.isFavorite
) {
onFavoriteClick()
MomentOperateBtn(count = momentEntity.likeCount.toString()) {
AnimatedLikeIcon(
modifier = Modifier.size(24.dp),
liked = momentEntity.liked
) {
onLikeClick()
}
}
}
Spacer(modifier = Modifier.width(4.dp))
Box(
modifier = Modifier
.fillMaxHeight()
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
) {
showCommentModal = true
},
contentAlignment = Alignment.Center
) {
MomentOperateBtn(
icon = R.drawable.rider_pro_moment_comment,
count = momentEntity.commentCount.toString()
)
}
Spacer(modifier = Modifier.weight(1f))
Box(
modifier = Modifier
.fillMaxHeight()
.noRippleClickable {
onFavoriteClick()
},
contentAlignment = Alignment.Center
) {
MomentOperateBtn(count = momentEntity.favoriteCount.toString()) {
AnimatedFavouriteIcon(
modifier = Modifier.size(24.dp),
isFavourite = momentEntity.isFavorite
) {
onFavoriteClick()
}
}
}
}
if (momentEntity.images.size > 1) {
Row(
modifier = Modifier.fillMaxSize(),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
momentEntity.images.forEachIndexed { index, _ ->
Box(
modifier = Modifier
.size(4.dp)
.clip(CircleShape)
.background(
if (imageIndex == index) Color.Red else Color.Gray.copy(
alpha = 0.5f
)
)
.padding(1.dp)
)
Spacer(modifier = Modifier.width(8.dp))
}
}
}
}
}
@Composable

View File

@@ -143,9 +143,9 @@ object PostViewModel : ViewModel() {
suspend fun initData() {
moment = service.getMomentById(postId.toInt())
moment?.let {
accountProfileEntity = userService.getUserProfile(it.authorId.toString())
}
// moment?.let {
// accountProfileEntity = userService.getUserProfile(it.authorId.toString())
// }
}
suspend fun likeComment(commentId: Int) {
@@ -321,7 +321,8 @@ fun PostScreen(
)
LazyColumn(
modifier = Modifier
.fillMaxWidth().weight(1f)
.fillMaxWidth()
.weight(1f)
) {
item {
Box(
@@ -588,23 +589,27 @@ fun CommentItem(commentEntity: CommentEntity, onLike: () -> Unit = {}) {
val navController = LocalNavController.current
Column {
Row(modifier = Modifier.padding(vertical = 8.dp)) {
CustomAsyncImage(
context = context,
imageUrl = commentEntity.avatar,
contentDescription = "Comment Profile Picture",
Box(
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
.noRippleClickable {
.background(Color.Gray.copy(alpha = 0.1f)).noRippleClickable {
navController.navigate(
NavigationRoute.AccountProfile.route.replace(
"{id}",
commentEntity.author.toString()
)
)
},
contentScale = ContentScale.Crop
)
}
) {
CustomAsyncImage(
context = context,
imageUrl = commentEntity.avatar,
contentDescription = "Comment Profile Picture",
modifier = Modifier.size(40.dp),
contentScale = ContentScale.Crop
)
}
Spacer(modifier = Modifier.width(8.dp))
Column(
modifier = Modifier.weight(1f)

View File

@@ -32,6 +32,7 @@ fun AccountProfile(id: String) {
LaunchedEffect(Unit) {
model.loadProfile(id)
}
LazyColumn(
modifier = Modifier
.fillMaxSize()