This commit is contained in:
2024-08-22 20:57:32 +08:00
parent 5228fde035
commit e7b75f8519
10 changed files with 212 additions and 148 deletions

View File

@@ -78,7 +78,9 @@ data class Image(
@SerializedName("url")
val url: String,
@SerializedName("thumbnail")
val thumbnail: String
val thumbnail: String,
@SerializedName("blurHash")
val blurHash: String?
)
data class User(

View File

@@ -37,7 +37,7 @@ 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.message.NotificationsScreen
import com.aiosman.riderpro.ui.index.tabs.message.NotificationsScreen
import com.aiosman.riderpro.ui.modification.EditModificationScreen
import com.aiosman.riderpro.ui.post.NewPostScreen
import com.aiosman.riderpro.ui.post.PostScreen

View File

@@ -26,11 +26,13 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import com.aiosman.riderpro.ui.index.tabs.add.AddPage
import com.aiosman.riderpro.ui.index.tabs.message.NotificationsScreen
import com.aiosman.riderpro.ui.index.tabs.moment.MomentsList
import com.aiosman.riderpro.ui.index.tabs.profile.ProfilePage
import com.aiosman.riderpro.ui.index.tabs.search.SearchScreen
import com.aiosman.riderpro.ui.index.tabs.shorts.ShortVideo
import com.aiosman.riderpro.ui.index.tabs.street.StreetPage
import com.aiosman.riderpro.ui.message.MessagePage
import com.google.accompanist.systemuicontroller.rememberSystemUiController
@Composable
@@ -45,6 +47,7 @@ fun IndexScreen() {
// NavigationItem.Street,
NavigationItem.Add,
// NavigationItem.Message,
NavigationItem.Notification,
NavigationItem.Profile
)
val systemUiController = rememberSystemUiController()
@@ -101,6 +104,7 @@ fun IndexScreen() {
) {
Home()
}
1 -> Box(
modifier = Modifier.padding(innerPadding)
) {
@@ -115,9 +119,14 @@ fun IndexScreen() {
// 3 -> Box(
// modifier = Modifier.padding(innerPadding)
// ) { Video() }
3 -> Box(
modifier = Modifier.padding(innerPadding)
) {
Notifications()
}
4 -> Box(
modifier = Modifier.padding(innerPadding)
) { Profile() }
}
}
@@ -206,3 +215,19 @@ fun Profile() {
ProfilePage()
}
}
@Composable
fun Notifications() {
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setStatusBarColor(Color.Transparent, darkIcons = true)
}
Column(
modifier = Modifier
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
NotificationsScreen()
}
}

View File

@@ -33,6 +33,11 @@ sealed class NavigationItem(
selectedIcon = { ImageVector.vectorResource(R.drawable.rider_pro_video) }
)
data object Notification : NavigationItem("Notification",
icon = { ImageVector.vectorResource(R.drawable.rider_pro_notification) },
selectedIcon = { ImageVector.vectorResource(R.drawable.rider_pro_notification) }
)
data object Profile : NavigationItem("Profile",
icon = { ImageVector.vectorResource(R.drawable.rider_pro_profile) },
selectedIcon = { ImageVector.vectorResource(R.drawable.rider_pro_profile_filed) }

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro.ui.message
package com.aiosman.riderpro.ui.index.tabs.message
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -32,7 +32,6 @@ import androidx.compose.ui.unit.sp
import androidx.paging.compose.collectAsLazyPagingItems
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.R
import com.aiosman.riderpro.data.Comment
import com.aiosman.riderpro.data.CommentEntity
import com.aiosman.riderpro.exp.timeAgo
import com.aiosman.riderpro.ui.NavigationRoute
@@ -49,80 +48,82 @@ fun NotificationsScreen() {
val model = MessageListViewModel
val navController = LocalNavController.current
val systemUiController = rememberSystemUiController()
var dataFlow = model.commentItemsFlow
var dataFlow = MessageListViewModel.commentItemsFlow
var comments = dataFlow.collectAsLazyPagingItems()
LaunchedEffect(Unit) {
systemUiController.setNavigationBarColor(Color.Transparent)
model.initData()
MessageListViewModel.initData()
}
StatusBarMaskLayout(darkIcons = true) {
Column(
Column(
modifier = Modifier.fillMaxSize()
) {
Box(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.padding(horizontal = 24.dp, vertical = 16.dp)
) {
Box(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 16.dp)
Image(
painter = painterResource(id = R.drawable.rider_pro_message_title),
contentDescription = "Back",
modifier = Modifier.width(120.dp)
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
horizontalArrangement = Arrangement.SpaceBetween,
) {
NotificationIndicator(
MessageListViewModel.likeNoticeCount,
R.drawable.rider_pro_like,
"LIKE"
) {
Image(
painter = painterResource(id = R.drawable.rider_pro_message_title),
contentDescription = "Back",
modifier = Modifier.width(120.dp)
)
navController.navigate(NavigationRoute.Likes.route)
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
horizontalArrangement = Arrangement.SpaceBetween,
NotificationIndicator(
MessageListViewModel.followNoticeCount,
R.drawable.rider_pro_followers,
"FOLLOWERS"
) {
NotificationIndicator(model.likeNoticeCount, R.drawable.rider_pro_like, "LIKE") {
navController.navigate(NavigationRoute.Likes.route)
}
NotificationIndicator(
model.followNoticeCount,
R.drawable.rider_pro_followers,
"FOLLOWERS"
) {
navController.navigate(NavigationRoute.Followers.route)
}
NotificationIndicator(
model.favouriteNoticeCount,
R.drawable.rider_pro_favoriate,
"Favourites"
) {
navController.navigate(NavigationRoute.FavouritesScreen.route)
}
navController.navigate(NavigationRoute.Followers.route)
}
HorizontalDivider(color = Color(0xFFEbEbEb), modifier = Modifier.padding(16.dp))
NotificationCounterItem(model.commentNoticeCount)
LazyColumn(
modifier = Modifier
.weight(1f)
.fillMaxSize()
NotificationIndicator(
MessageListViewModel.favouriteNoticeCount,
R.drawable.rider_pro_favoriate,
"Favourites"
) {
items(comments.itemCount) { index ->
comments[index]?.let { comment ->
CommentItem(comment) {
model.updateReadStatus(comment.id)
navController.navigate(
NavigationRoute.Post.route.replace(
"{id}",
comment.postId.toString()
)
navController.navigate(NavigationRoute.FavouritesScreen.route)
}
}
HorizontalDivider(color = Color(0xFFEbEbEb), modifier = Modifier.padding(16.dp))
NotificationCounterItem(MessageListViewModel.commentNoticeCount)
LazyColumn(
modifier = Modifier
.weight(1f)
.fillMaxSize()
) {
items(comments.itemCount) { index ->
comments[index]?.let { comment ->
CommentItem(comment) {
MessageListViewModel.updateReadStatus(comment.id)
navController.navigate(
NavigationRoute.Post.route.replace(
"{id}",
comment.postId.toString()
)
}
)
}
}
item {
BottomNavigationPlaceholder()
}
}
item {
BottomNavigationPlaceholder()
}
}
}
}
@Composable

View File

@@ -1,4 +1,4 @@
package com.aiosman.riderpro.ui.message
package com.aiosman.riderpro.ui.index.tabs.message
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf

View File

@@ -2,10 +2,12 @@ package com.aiosman.riderpro.ui.index.tabs.moment
import androidx.annotation.DrawableRes
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -21,6 +23,9 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Build
@@ -42,6 +47,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
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
@@ -59,6 +65,7 @@ import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.LocalSharedTransitionScope
import com.aiosman.riderpro.R
import com.aiosman.riderpro.model.MomentEntity
import com.aiosman.riderpro.model.MomentImageEntity
import com.aiosman.riderpro.ui.NavigationRoute
import com.aiosman.riderpro.ui.comment.CommentModalContent
import com.aiosman.riderpro.ui.composables.AnimatedCounter
@@ -66,6 +73,7 @@ import com.aiosman.riderpro.ui.composables.AnimatedFavouriteIcon
import com.aiosman.riderpro.ui.composables.AnimatedLikeIcon
import com.aiosman.riderpro.ui.composables.CustomAsyncImage
import com.aiosman.riderpro.ui.composables.RelPostCard
import com.aiosman.riderpro.ui.imageviewer.ImageViewerViewModel
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import com.aiosman.riderpro.ui.post.NewPostViewModel
import com.google.accompanist.systemuicontroller.rememberSystemUiController
@@ -140,7 +148,11 @@ fun MomentCard(
Column(
modifier = Modifier.fillMaxWidth()
) {
MomentTopRowGroup(momentEntity = momentEntity)
Box(
modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp)
) {
MomentTopRowGroup(momentEntity = momentEntity)
}
Column(
modifier = Modifier
.fillMaxWidth()
@@ -154,7 +166,7 @@ fun MomentCard(
.fillMaxHeight()
.weight(1f)
// ModificationListHeader()
if (!hideAction){
if (!hideAction) {
MomentBottomOperateRowGroup(
momentOperateBtnBoxModifier,
momentEntity = momentEntity,
@@ -274,8 +286,6 @@ fun MomentTopRowGroup(momentEntity: MomentEntity) {
val context = LocalContext.current
Row(
modifier = Modifier
.height(40.dp)
.padding(top = 0.dp, bottom = 0.dp, start = 24.dp, end = 24.dp)
) {
CustomAsyncImage(
context,
@@ -320,45 +330,108 @@ fun MomentTopRowGroup(momentEntity: MomentEntity) {
}
}
@OptIn(ExperimentalSharedTransitionApi::class)
@OptIn(ExperimentalFoundationApi::class, ExperimentalSharedTransitionApi::class)
@Composable
fun PostImageView(
postId: String,
images: List<MomentImageEntity>,
) {
val pagerState = rememberPagerState(pageCount = { images.size })
val navController = LocalNavController.current
val sharedTransitionScope = LocalSharedTransitionScope.current
val animatedVisibilityScope = LocalAnimatedContentScope.current
val context = LocalContext.current
Column(
modifier = Modifier.fillMaxWidth()
) {
HorizontalPager(
state = pagerState,
modifier = Modifier
.fillMaxWidth()
.aspectRatio(1f),
) { page ->
val image = images[page]
with(sharedTransitionScope) {
CustomAsyncImage(
context,
image.thumbnail,
contentDescription = "Image",
contentScale = ContentScale.Crop,
modifier = Modifier
.sharedElement(
rememberSharedContentState(key = image),
animatedVisibilityScope = animatedVisibilityScope
)
.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))
}
}
}
}
}
@Composable
fun MomentContentGroup(
momentEntity: MomentEntity,
) {
val displayImageUrl = momentEntity.images.firstOrNull()
val sharedTransitionScope = LocalSharedTransitionScope.current
val animatedVisibilityScope = LocalAnimatedContentScope.current
val context = LocalContext.current
Text(
text = "${momentEntity.momentTextContent}",
modifier = Modifier
.fillMaxWidth()
.padding(top = 22.dp, bottom = 16.dp, start = 24.dp, end = 24.dp),
fontSize = 16.sp
)
if (momentEntity.momentTextContent.isNotEmpty()) {
Text(
text = momentEntity.momentTextContent,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 8.dp),
fontSize = 16.sp
)
}
if (momentEntity.relMoment != null) {
RelPostCard(
momentEntity = momentEntity.relMoment!!,
modifier = Modifier.background(Color(0xFFF8F8F8))
)
} else {
displayImageUrl?.let {
with(sharedTransitionScope) {
CustomAsyncImage(
context,
it.thumbnail,
modifier = Modifier
.sharedElement(
rememberSharedContentState(key = it),
animatedVisibilityScope = animatedVisibilityScope
)
.fillMaxWidth()
.aspectRatio(1f),
contentScale = ContentScale.Crop,
contentDescription = ""
)
}
Box(
modifier = Modifier.fillMaxWidth()
) {
PostImageView(
postId = momentEntity.id.toString(),
images = momentEntity.images
)
}
}

View File

@@ -374,50 +374,6 @@ fun CommunicationOperatorGroup(
}
}
if (isSelf) {
Box(
modifier = Modifier
.size(width = 142.dp, height = 40.dp)
.padding(start = 6.dp)
.clickable {
navController.navigate("MyMessage")
},
contentAlignment = Alignment.Center
) {
Image(
modifier = Modifier.fillMaxSize(),
painter = painterResource(id = R.drawable.rider_pro_profile_message),
contentDescription = ""
)
Text(
text = "MESSAGE",
fontSize = 16.sp,
color = Color.White,
style = TextStyle(fontWeight = FontWeight.Bold)
)
}
// Box(
// modifier = Modifier
// .size(width = 142.dp, height = 40.dp)
// .clickable {
// navController.navigate("ProfileTimeline")
// },
// contentAlignment = Alignment.Center
// ) {
// Image(
// modifier = Modifier.fillMaxSize(),
// painter = painterResource(id = R.drawable.rider_pro_profile_follow),
// contentDescription = ""
// )
// Text(
// text = "GALLERY",
// fontSize = 16.sp,
// color = Color.White,
// style = TextStyle(fontWeight = FontWeight.Bold)
// )
// }
}
}
}

View File

@@ -70,10 +70,10 @@ fun SearchScreen() {
modifier = Modifier
.background(Color.White)
.fillMaxSize()
.padding(start = 16.dp, end = 16.dp, top = 24.dp)
) {
SearchInput(
modifier = Modifier.fillMaxWidth(),
modifier = Modifier.fillMaxWidth().padding(top = 16.dp, start = 24.dp, end = 24.dp),
text = model.searchText,
onTextChange = {
model.searchText = it
@@ -125,7 +125,7 @@ fun SearchInput(
.clip(shape = RoundedCornerShape(8.dp))
.background(Color(0xFFEEEEEE))
.padding(horizontal = 16.dp, vertical = 16.dp)
.padding(horizontal = 16.dp, vertical = 8.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically

View File

@@ -52,9 +52,11 @@ 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.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
@@ -109,7 +111,7 @@ class PostViewModel(
) : ViewModel() {
var service: MomentService = TestMomentServiceImpl()
var commentService: CommentService = TestCommentServiceImpl()
var userService : UserService = TestUserServiceImpl()
var userService: UserService = TestUserServiceImpl()
private var _commentsFlow = MutableStateFlow<PagingData<CommentEntity>>(PagingData.empty())
val commentsFlow = _commentsFlow.asStateFlow()
@@ -308,7 +310,6 @@ fun PostScreen(
modifier = Modifier
.fillMaxWidth()
.aspectRatio(1f)
) {
PostImageView(
id,
@@ -403,7 +404,8 @@ fun Header(
modifier = Modifier
.height(20.dp)
.wrapContentWidth()
.padding(start = 6.dp).noRippleClickable {
.padding(start = 6.dp)
.noRippleClickable {
onFollowClick()
},
contentAlignment = Alignment.Center
@@ -441,7 +443,7 @@ fun PostImageView(
state = pagerState,
modifier = Modifier
.weight(1f)
.fillMaxWidth(),
.fillMaxWidth().background(Color.Gray.copy(alpha = 0.1f)),
) { page ->
val image = images[page]
with(sharedTransitionScope) {
@@ -449,7 +451,7 @@ fun PostImageView(
context,
image.thumbnail,
contentDescription = "Image",
contentScale = ContentScale.Fit,
contentScale = ContentScale.Crop,
modifier = Modifier
.sharedElement(
rememberSharedContentState(key = image),
@@ -661,7 +663,7 @@ fun BottomNavigationBar(
onLikeClick()
}) {
Icon(
Icons.Filled.Favorite,
imageVector = ImageVector.vectorResource(id = R.drawable.rider_pro_like),
contentDescription = "like",
tint = if (momentEntity?.liked == true) Color.Red else Color.Gray
)
@@ -673,7 +675,7 @@ fun BottomNavigationBar(
}
) {
Icon(
Icons.Filled.Star,
imageVector = ImageVector.vectorResource(id = R.drawable.rider_pro_favoriate),
contentDescription = "Favourite",
tint = if (momentEntity?.isFavorite == true) Color.Red else Color.Gray
)