更新UI
This commit is contained in:
@@ -2,6 +2,6 @@ package com.aiosman.riderpro
|
||||
|
||||
object ConstVars {
|
||||
// api 地址
|
||||
const val BASE_SERVER = "http://192.168.31.250:8088"
|
||||
// const val BASE_SERVER = "https://8.137.22.101:8088"
|
||||
// const val BASE_SERVER = "http://192.168.31.250:8088"
|
||||
const val BASE_SERVER = "https://8.137.22.101:8088"
|
||||
}
|
||||
@@ -44,13 +44,12 @@ data class Moment(
|
||||
val time: String
|
||||
) {
|
||||
fun toMomentItem(): MomentEntity {
|
||||
val avatar = "${ApiClient.BASE_SERVER}${user.avatar}"
|
||||
return MomentEntity(
|
||||
id = id.toInt(),
|
||||
avatar = "${ApiClient.BASE_SERVER}${user.avatar}",
|
||||
nickname = user.nickName,
|
||||
location = "Worldwide",
|
||||
time = time,
|
||||
time = ApiClient.dateFromApiString(time),
|
||||
followStatus = false,
|
||||
momentTextContent = textContent,
|
||||
momentPicture = R.drawable.default_moment_img,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.aiosman.riderpro.exp
|
||||
|
||||
import android.icu.text.SimpleDateFormat
|
||||
import android.icu.util.Calendar
|
||||
import com.aiosman.riderpro.data.api.ApiClient
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
@@ -22,4 +23,18 @@ fun Date.timeAgo(): String {
|
||||
days < 365 -> "$days days ago"
|
||||
else -> "$years years ago"
|
||||
}
|
||||
}
|
||||
|
||||
fun Date.formatPostTime(): String {
|
||||
val now = Calendar.getInstance()
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.time = this
|
||||
val year = calendar.get(Calendar.YEAR)
|
||||
var nowYear = now.get(Calendar.YEAR)
|
||||
val dateFormat = if (year == nowYear) {
|
||||
SimpleDateFormat("MM-dd", Locale.getDefault())
|
||||
} else {
|
||||
SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||
}
|
||||
return dateFormat.format(this)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.aiosman.riderpro.model
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import java.util.Date
|
||||
|
||||
data class MomentImageEntity(
|
||||
val id: Long,
|
||||
@@ -14,7 +15,7 @@ data class MomentEntity(
|
||||
val avatar: String,
|
||||
val nickname: String,
|
||||
val location: String,
|
||||
val time: String,
|
||||
val time: Date,
|
||||
val followStatus: Boolean,
|
||||
val momentTextContent: String,
|
||||
@DrawableRes val momentPicture: Int,
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.google.gson.GsonBuilder
|
||||
import io.github.serpro69.kfaker.faker
|
||||
import java.io.File
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
|
||||
object TestDatabase {
|
||||
var momentData = emptyList<MomentEntity>()
|
||||
@@ -120,7 +121,7 @@ object TestDatabase {
|
||||
avatar = person.avatar,
|
||||
nickname = person.nickName,
|
||||
location = person.country,
|
||||
time = "2023.02.02 11:23",
|
||||
time = Date(),
|
||||
followStatus = false,
|
||||
momentTextContent = "By strongarming Ducati into giving him the factory seat.Marquez effectively …",
|
||||
momentPicture = R.drawable.default_moment_img,
|
||||
|
||||
@@ -5,6 +5,11 @@ import ImageViewer
|
||||
import ModificationListScreen
|
||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||
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
|
||||
@@ -121,7 +126,13 @@ fun NavigationController(
|
||||
}
|
||||
composable(
|
||||
route = NavigationRoute.Post.route,
|
||||
arguments = listOf(navArgument("id") { type = NavType.StringType })
|
||||
arguments = listOf(navArgument("id") { type = NavType.StringType }),
|
||||
enterTransition = {
|
||||
fadeIn(animationSpec = tween(durationMillis = 100))
|
||||
},
|
||||
exitTransition = {
|
||||
fadeOut(animationSpec = tween(durationMillis = 100))
|
||||
}
|
||||
) { backStackEntry ->
|
||||
CompositionLocalProvider(
|
||||
LocalAnimatedContentScope provides this,
|
||||
@@ -147,7 +158,16 @@ fun NavigationController(
|
||||
composable(route = NavigationRoute.Followers.route) {
|
||||
FollowerScreen()
|
||||
}
|
||||
composable(route = NavigationRoute.NewPost.route) {
|
||||
composable(
|
||||
route = NavigationRoute.NewPost.route,
|
||||
enterTransition = {
|
||||
|
||||
fadeIn(animationSpec = tween(durationMillis = 100))
|
||||
},
|
||||
exitTransition = {
|
||||
fadeOut(animationSpec = tween(durationMillis = 100))
|
||||
}
|
||||
) {
|
||||
NewPostScreen()
|
||||
}
|
||||
composable(route = NavigationRoute.EditModification.route) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.aiosman.riderpro.ui.composables
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -46,10 +47,12 @@ fun rememberImageBitmap(imageUrl: String, imageLoader: ImageLoader): Bitmap? {
|
||||
@Composable
|
||||
fun CustomAsyncImage(
|
||||
context: Context,
|
||||
imageUrl: String,
|
||||
imageUrl: String?,
|
||||
contentDescription: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
blurHash: String? = null,
|
||||
@DrawableRes
|
||||
placeholderRes: Int? = null,
|
||||
contentScale: ContentScale = ContentScale.Crop
|
||||
) {
|
||||
val imageLoader = getImageLoader(context)
|
||||
@@ -63,30 +66,35 @@ fun CustomAsyncImage(
|
||||
}
|
||||
}
|
||||
|
||||
var bitmap by remember(imageUrl) { mutableStateOf<Bitmap?>(null) }
|
||||
|
||||
LaunchedEffect(imageUrl) {
|
||||
if (bitmap == null) {
|
||||
val request = ImageRequest.Builder(context)
|
||||
.data(imageUrl)
|
||||
.crossfade(true)
|
||||
.build()
|
||||
|
||||
val result = withContext(Dispatchers.IO) {
|
||||
(imageLoader.execute(request) as? SuccessResult)?.drawable?.toBitmap()
|
||||
}
|
||||
bitmap = result
|
||||
}
|
||||
}
|
||||
// var bitmap by remember(imageUrl) { mutableStateOf<Bitmap?>(null) }
|
||||
//
|
||||
// LaunchedEffect(imageUrl) {
|
||||
// if (bitmap == null) {
|
||||
// val request = ImageRequest.Builder(context)
|
||||
// .data(imageUrl)
|
||||
// .crossfade(3000)
|
||||
// .build()
|
||||
//
|
||||
// val result = withContext(Dispatchers.IO) {
|
||||
// (imageLoader.execute(request) as? SuccessResult)?.drawable?.toBitmap()
|
||||
// }
|
||||
// bitmap = result
|
||||
// }
|
||||
// }
|
||||
|
||||
AsyncImage(
|
||||
model = bitmap ?: ImageRequest.Builder(context)
|
||||
model = ImageRequest.Builder(context)
|
||||
.data(imageUrl)
|
||||
.crossfade(true)
|
||||
.crossfade(200)
|
||||
.apply {
|
||||
if (placeholderRes != null) {
|
||||
placeholder(placeholderRes)
|
||||
return@apply
|
||||
}
|
||||
if (blurBitmap != null) {
|
||||
placeholder(blurBitmap.toDrawable(context.resources))
|
||||
}
|
||||
|
||||
}
|
||||
.build(),
|
||||
contentDescription = contentDescription,
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.aiosman.riderpro.ui.index
|
||||
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.slideInHorizontally
|
||||
import androidx.compose.animation.slideOutHorizontally
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -25,6 +27,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.navOptions
|
||||
import com.aiosman.riderpro.LocalNavController
|
||||
import com.aiosman.riderpro.ui.NavigationRoute
|
||||
import com.aiosman.riderpro.ui.index.tabs.add.AddPage
|
||||
@@ -35,6 +38,7 @@ 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.aiosman.riderpro.ui.post.NewPostViewModel
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
|
||||
@Composable
|
||||
@@ -56,7 +60,7 @@ fun IndexScreen() {
|
||||
val systemUiController = rememberSystemUiController()
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
systemUiController.setNavigationBarColor(Color.Transparent)
|
||||
// systemUiController.setNavigationBarColor(Color.Transparent)
|
||||
}
|
||||
Scaffold(
|
||||
bottomBar = {
|
||||
@@ -73,8 +77,14 @@ fun IndexScreen() {
|
||||
NavigationBarItem(
|
||||
selected = isSelected,
|
||||
onClick = {
|
||||
|
||||
if (it.route === NavigationItem.Add.route) {
|
||||
navController.navigate(NavigationRoute.NewPost.route)
|
||||
NewPostViewModel.asNewPost()
|
||||
|
||||
navController.navigate(
|
||||
NavigationRoute.NewPost.route,
|
||||
|
||||
)
|
||||
return@NavigationBarItem
|
||||
}
|
||||
model.tabIndex = idx
|
||||
|
||||
@@ -65,6 +65,7 @@ import com.aiosman.riderpro.LocalAnimatedContentScope
|
||||
import com.aiosman.riderpro.LocalNavController
|
||||
import com.aiosman.riderpro.LocalSharedTransitionScope
|
||||
import com.aiosman.riderpro.R
|
||||
import com.aiosman.riderpro.exp.timeAgo
|
||||
import com.aiosman.riderpro.model.MomentEntity
|
||||
import com.aiosman.riderpro.model.MomentImageEntity
|
||||
import com.aiosman.riderpro.ui.NavigationRoute
|
||||
@@ -76,6 +77,7 @@ import com.aiosman.riderpro.ui.composables.CustomAsyncImage
|
||||
import com.aiosman.riderpro.ui.composables.RelPostCard
|
||||
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
||||
import com.aiosman.riderpro.ui.post.NewPostViewModel
|
||||
import com.aiosman.riderpro.ui.post.PostViewModel
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -160,6 +162,7 @@ fun MomentCard(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.noRippleClickable {
|
||||
PostViewModel.preTransit(momentEntity)
|
||||
navController.navigate("Post/${momentEntity.id}")
|
||||
}
|
||||
) {
|
||||
@@ -327,7 +330,7 @@ fun MomentTopRowGroup(momentEntity: MomentEntity) {
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
MomentPostLocation(momentEntity.location)
|
||||
MomentPostTime(momentEntity.time)
|
||||
MomentPostTime(momentEntity.time.timeAgo())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -355,7 +358,6 @@ fun PostImageView(
|
||||
.aspectRatio(1f),
|
||||
) { page ->
|
||||
val image = images[page]
|
||||
with(sharedTransitionScope) {
|
||||
// AsyncBlurImage(
|
||||
// imageUrl = image.url,
|
||||
// blurHash = image.blurHash ?: "",
|
||||
@@ -375,10 +377,6 @@ fun PostImageView(
|
||||
blurHash = image.blurHash,
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = Modifier
|
||||
.sharedElement(
|
||||
rememberSharedContentState(key = image),
|
||||
animatedVisibilityScope = animatedVisibilityScope
|
||||
)
|
||||
.fillMaxSize()
|
||||
// .noRippleClickable {
|
||||
// ImageViewerViewModel.asNew(images, page)
|
||||
@@ -387,7 +385,7 @@ fun PostImageView(
|
||||
// )
|
||||
// }
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Indicator container
|
||||
|
||||
@@ -53,10 +53,12 @@ import com.aiosman.riderpro.LocalNavController
|
||||
import com.aiosman.riderpro.LocalSharedTransitionScope
|
||||
import com.aiosman.riderpro.R
|
||||
import com.aiosman.riderpro.data.AccountProfileEntity
|
||||
import com.aiosman.riderpro.exp.formatPostTime
|
||||
import com.aiosman.riderpro.model.MomentEntity
|
||||
import com.aiosman.riderpro.ui.NavigationRoute
|
||||
import com.aiosman.riderpro.ui.composables.CustomAsyncImage
|
||||
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
||||
import com.aiosman.riderpro.ui.post.PostViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
@@ -457,13 +459,13 @@ fun UserMoment(scope: LazyListScope) {
|
||||
|
||||
@Composable
|
||||
fun MomentPostUnit(momentEntity: MomentEntity) {
|
||||
TimeGroup(momentEntity.time)
|
||||
TimeGroup(momentEntity.time.formatPostTime())
|
||||
ProfileMomentCard(
|
||||
momentEntity.momentTextContent,
|
||||
momentEntity.images[0].thumbnail,
|
||||
momentEntity.likeCount.toString(),
|
||||
momentEntity.commentCount.toString(),
|
||||
momentId = momentEntity.id
|
||||
momentEntity = momentEntity
|
||||
)
|
||||
}
|
||||
|
||||
@@ -496,7 +498,7 @@ fun ProfileMomentCard(
|
||||
imageUrl: String,
|
||||
like: String,
|
||||
comment: String,
|
||||
momentId: Int
|
||||
momentEntity: MomentEntity
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@@ -505,7 +507,7 @@ fun ProfileMomentCard(
|
||||
.border(width = 1.dp, color = Color(0f, 0f, 0f, 0.1f), shape = RoundedCornerShape(6.dp))
|
||||
) {
|
||||
MomentCardTopContent(content)
|
||||
MomentCardPicture(imageUrl, momentId)
|
||||
MomentCardPicture(imageUrl, momentEntity = momentEntity)
|
||||
MomentCardOperation(like, comment)
|
||||
}
|
||||
}
|
||||
@@ -527,7 +529,7 @@ fun MomentCardTopContent(content: String) {
|
||||
|
||||
@OptIn(ExperimentalSharedTransitionApi::class)
|
||||
@Composable
|
||||
fun MomentCardPicture(imageUrl: String, momentId: Int) {
|
||||
fun MomentCardPicture(imageUrl: String, momentEntity: MomentEntity) {
|
||||
val navController = LocalNavController.current
|
||||
val sharedTransitionScope = LocalSharedTransitionScope.current
|
||||
val animatedVisibilityScope = LocalAnimatedContentScope.current
|
||||
@@ -544,10 +546,11 @@ fun MomentCardPicture(imageUrl: String, momentId: Int) {
|
||||
.fillMaxSize()
|
||||
.padding(16.dp)
|
||||
.noRippleClickable {
|
||||
PostViewModel.preTransit(momentEntity)
|
||||
navController.navigate(
|
||||
NavigationRoute.Post.route.replace(
|
||||
"{id}",
|
||||
momentId.toString()
|
||||
momentEntity.id.toString()
|
||||
)
|
||||
)
|
||||
},
|
||||
|
||||
@@ -73,6 +73,7 @@ fun NewPostScreen() {
|
||||
}
|
||||
StatusBarMaskLayout(
|
||||
darkIcons = true,
|
||||
modifier = Modifier.fillMaxSize().background(Color.White)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
||||
@@ -87,6 +87,7 @@ import com.aiosman.riderpro.data.AccountServiceImpl
|
||||
import com.aiosman.riderpro.data.TestMomentServiceImpl
|
||||
import com.aiosman.riderpro.data.TestUserServiceImpl
|
||||
import com.aiosman.riderpro.data.UserService
|
||||
import com.aiosman.riderpro.exp.formatPostTime
|
||||
import com.aiosman.riderpro.exp.timeAgo
|
||||
import com.aiosman.riderpro.model.MomentEntity
|
||||
import com.aiosman.riderpro.model.MomentImageEntity
|
||||
@@ -104,16 +105,29 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class PostViewModel(
|
||||
val postId: String
|
||||
) : ViewModel() {
|
||||
object PostViewModel : ViewModel() {
|
||||
var service: MomentService = TestMomentServiceImpl()
|
||||
var commentService: CommentService = TestCommentServiceImpl()
|
||||
var userService: UserService = TestUserServiceImpl()
|
||||
private var _commentsFlow = MutableStateFlow<PagingData<CommentEntity>>(PagingData.empty())
|
||||
val commentsFlow = _commentsFlow.asStateFlow()
|
||||
var postId: String = ""
|
||||
|
||||
// 预加载的 moment
|
||||
|
||||
var accountProfileEntity by mutableStateOf<AccountProfileEntity?>(null)
|
||||
var moment by mutableStateOf<MomentEntity?>(null)
|
||||
var accountService: AccountService = AccountServiceImpl()
|
||||
|
||||
/**
|
||||
* 预加载,在跳转到 PostScreen 之前设置好内容
|
||||
*/
|
||||
fun preTransit(momentEntity: MomentEntity?) {
|
||||
this.postId = momentEntity?.id.toString()
|
||||
this.moment = momentEntity
|
||||
this._commentsFlow = MutableStateFlow<PagingData<CommentEntity>>(PagingData.empty())
|
||||
this.accountProfileEntity = null
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
Pager(
|
||||
config = PagingConfig(pageSize = 5, enablePlaceholders = false),
|
||||
@@ -129,10 +143,6 @@ class PostViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
var accountProfileEntity by mutableStateOf<AccountProfileEntity?>(null)
|
||||
var moment by mutableStateOf<MomentEntity?>(null)
|
||||
var accountService: AccountService = AccountServiceImpl()
|
||||
|
||||
suspend fun initData() {
|
||||
moment = service.getMomentById(postId.toInt())
|
||||
moment?.let {
|
||||
@@ -220,20 +230,35 @@ class PostViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
var avatar: String? = null
|
||||
get() {
|
||||
accountProfileEntity?.avatar?.let {
|
||||
return it
|
||||
}
|
||||
moment?.avatar?.let {
|
||||
return it
|
||||
}
|
||||
return field
|
||||
}
|
||||
var nickname: String? = null
|
||||
get() {
|
||||
accountProfileEntity?.nickName?.let {
|
||||
return it
|
||||
}
|
||||
moment?.nickname?.let {
|
||||
return it
|
||||
}
|
||||
return field
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PostScreen(
|
||||
id: String,
|
||||
) {
|
||||
val viewModel = viewModel<PostViewModel>(
|
||||
key = "PostViewModel_$id",
|
||||
factory = object : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return PostViewModel(id) as T
|
||||
}
|
||||
}
|
||||
)
|
||||
val viewModel = PostViewModel
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
val commentsPagging = viewModel.commentsFlow.collectAsLazyPagingItems()
|
||||
@@ -283,8 +308,8 @@ fun PostScreen(
|
||||
.fillMaxSize()
|
||||
) {
|
||||
Header(
|
||||
avatar = viewModel.moment?.avatar,
|
||||
nickname = viewModel.moment?.nickname,
|
||||
avatar = viewModel.avatar,
|
||||
nickname = viewModel.nickname,
|
||||
userId = viewModel.moment?.authorId,
|
||||
isFollowing = viewModel.accountProfileEntity?.isFollowing ?: false,
|
||||
onFollowClick = {
|
||||
@@ -373,10 +398,15 @@ fun Header(
|
||||
.size(32.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
avatar?.let {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.clip(CircleShape)
|
||||
.background(Color.Gray.copy(alpha = 0.1f))
|
||||
) {
|
||||
CustomAsyncImage(
|
||||
context,
|
||||
it,
|
||||
avatar,
|
||||
contentDescription = "Profile Picture",
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
@@ -395,7 +425,6 @@ fun Header(
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(text = nickname ?: "", fontWeight = FontWeight.Bold)
|
||||
Box(
|
||||
@@ -441,7 +470,8 @@ fun PostImageView(
|
||||
state = pagerState,
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth().background(Color.Gray.copy(alpha = 0.1f)),
|
||||
.fillMaxWidth()
|
||||
.background(Color.Gray.copy(alpha = 0.1f)),
|
||||
) { page ->
|
||||
val image = images[page]
|
||||
with(sharedTransitionScope) {
|
||||
@@ -514,7 +544,7 @@ fun PostDetails(
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
Text(text = "12-11 发布")
|
||||
Text(text = "${momentEntity?.time?.formatPostTime()} 发布")
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(text = "${momentEntity?.commentCount ?: 0} Comments")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user