点赞和评论

This commit is contained in:
2024-07-30 14:28:13 +08:00
parent 406caa3702
commit 0730fdea68
10 changed files with 357 additions and 93 deletions

View File

@@ -12,6 +12,7 @@ interface CommentService {
suspend fun getComments(pageNumber: Int, postId: Int? = null): ListContainer<Comment>
suspend fun createComment(postId: Int, content: String, authorId: Int): Comment
suspend fun likeComment(commentId: Int)
suspend fun dislikeComment(commentId: Int)
}
@@ -25,7 +26,7 @@ data class Comment(
val postId: Int = 0,
val avatar: String,
val author: Int,
val liked: Boolean,
var liked: Boolean,
)
class CommentPagingSource(
@@ -82,6 +83,12 @@ class TestCommentServiceImpl : CommentService {
)
}
rawList = rawList.sortedBy { -it.id }
rawList.forEach {
val myLikeIdList = TestDatabase.likeCommentList.filter { it.second == 1 }.map { it.first }
if (myLikeIdList.contains(it.id)) {
it.liked = true
}
}
val currentSublist = rawList.subList(from, min(to, rawList.size))
return ListContainer(
total = rawList.size,
@@ -121,7 +128,18 @@ class TestCommentServiceImpl : CommentService {
it
}
}
TestDatabase.likeCommentList += Pair(commentId, 1)
}
override suspend fun dislikeComment(commentId: Int) {
TestDatabase.comment = TestDatabase.comment.map {
if (it.id == commentId) {
it.copy(likes = it.likes - 1)
} else {
it
}
}
TestDatabase.likeCommentList = TestDatabase.likeCommentList.filter { it.first != commentId }
}
companion object {

View File

@@ -10,6 +10,7 @@ import kotlin.math.min
interface MomentService {
suspend fun getMomentById(id: Int): MomentItem
suspend fun likeMoment(id: Int)
suspend fun dislikeMoment(id: Int)
suspend fun getMoments(
pageNumber: Int,
author: Int? = null,
@@ -81,6 +82,10 @@ class TestMomentServiceImpl() : MomentService {
testMomentBackend.likeMoment(id)
}
override suspend fun dislikeMoment(id: Int) {
testMomentBackend.dislikeMoment(id)
}
}
class TestMomentBackend(
@@ -113,6 +118,12 @@ class TestMomentBackend(
)
}
val currentSublist = rawList.subList(from, min(to, rawList.size))
currentSublist.forEach {
val myLikeIdList = TestDatabase.likeMomentList.filter { it.second == 1 }.map { it.first }
if (myLikeIdList.contains(it.id)) {
it.liked = true
}
}
// delay
kotlinx.coroutines.delay(loadDelay)
return ListContainer(
@@ -124,7 +135,14 @@ class TestMomentBackend(
}
suspend fun getMomentById(id: Int): MomentItem {
return TestDatabase.momentData[id]
var moment = TestDatabase.momentData.first {
it.id == id
}
val isLike = TestDatabase.likeMomentList.any {
it.first == id && it.second == 1
}
moment = moment.copy(liked = isLike)
return moment
}
suspend fun likeMoment(id: Int) {
@@ -133,6 +151,17 @@ class TestMomentBackend(
}
val newMoment = oldMoment.copy(likeCount = oldMoment.likeCount + 1)
TestDatabase.updateMomentById(id, newMoment)
TestDatabase.likeMomentList += Pair(id, 1)
}
suspend fun dislikeMoment(id: Int) {
val oldMoment = TestDatabase.momentData.first {
it.id == id
}
val newMoment = oldMoment.copy(likeCount = oldMoment.likeCount - 1)
TestDatabase.updateMomentById(id, newMoment)
TestDatabase.likeMomentList = TestDatabase.likeMomentList.filter {
it.first != id
}
}
}

View File

@@ -17,5 +17,6 @@ data class MomentItem(
val shareCount: Int,
val favoriteCount: Int,
val images: List<String> = emptyList(),
val authorId: Int = 0
val authorId: Int = 0,
var liked: Boolean = false,
)

View File

@@ -39,13 +39,14 @@ object TestDatabase {
)
var followList = emptyList<Pair<Int, Int>>()
var likeCommentList = emptyList<Pair<Int, Int>>()
var likeMomentList = emptyList<Pair<Int, Int>>()
init {
val faker = faker {
this.fakerConfig {
locale = "en"
}
}
accountData = (0..100).toList().mapIndexed { idx, _ ->
accountData = (0..20).toList().mapIndexed { idx, _ ->
AccountProfile(
id = idx,
followerCount = 0,
@@ -58,7 +59,7 @@ object TestDatabase {
)
}
// make a random follow rel
for (i in 0..500) {
for (i in 0..100) {
var person1 = accountData.random()
var persion2 = accountData.random()
followList += Pair(person1.id, persion2.id)
@@ -74,10 +75,11 @@ object TestDatabase {
}
}
momentData = (0..200).toList().mapIndexed { idx, _ ->
momentData = (0..60).toList().mapIndexed { idx, _ ->
val person = accountData.random()
// make fake comment
for (i in 0..faker.random.nextInt(0, 5)) {
val commentCount = faker.random.nextInt(0, 50)
for (i in 0..commentCount) {
commentIdCounter += 1
val commentPerson = accountData.random()
var newComment = Comment(
@@ -100,6 +102,11 @@ object TestDatabase {
}
comment += newComment
}
val likeCount = faker.random.nextInt(0, 5)
for (i in 0..likeCount) {
val likePerson = accountData.random()
likeMomentList += Pair(idx, likePerson.id)
}
MomentItem(
id = idx,
avatar = person.avatar,
@@ -109,8 +116,8 @@ object TestDatabase {
followStatus = false,
momentTextContent = "By strongarming Ducati into giving him the factory seat.Marquez effectively …",
momentPicture = R.drawable.default_moment_img,
likeCount = faker.random.nextInt(0, 100),
commentCount = faker.random.nextInt(0, 100),
likeCount = likeCount,
commentCount = commentCount + 1,
shareCount = faker.random.nextInt(0, 100),
favoriteCount = faker.random.nextInt(0, 100),
images = imageList.shuffled().take(3),

View File

@@ -58,8 +58,8 @@ import kotlinx.coroutines.launch
class CommentModalViewModel(
postId: Int?
):ViewModel(){
val commentService:CommentService = TestCommentServiceImpl()
) : ViewModel() {
val commentService: CommentService = TestCommentServiceImpl()
val commentsFlow: Flow<PagingData<Comment>> = Pager(
config = PagingConfig(pageSize = 20, enablePlaceholders = false),
pagingSourceFactory = {
@@ -70,10 +70,16 @@ class CommentModalViewModel(
}
).flow.cachedIn(viewModelScope)
}
@Preview
@Composable
fun CommentModalContent(postId: Int? = null, onDismiss: () -> Unit = {}) {
fun CommentModalContent(
postId: Int? = null,
onCommentAdded: () -> Unit = {},
onDismiss: () -> Unit = {}
) {
val model = viewModel<CommentModalViewModel>(
key = "CommentModalViewModel_$postId",
factory = object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return CommentModalViewModel(postId) as T
@@ -102,6 +108,7 @@ fun CommentModalContent(postId: Int? = null, onDismiss: () -> Unit = {}) {
commentText = ""
}
comments.refresh()
onCommentAdded()
}
Column(
modifier = Modifier
@@ -129,8 +136,7 @@ fun CommentModalContent(postId: Int? = null, onDismiss: () -> Unit = {}) {
.padding(horizontal = 16.dp)
.weight(1f)
) {
CommentsSection(lazyPagingItems = comments, onLike = {
comment: Comment ->
CommentsSection(lazyPagingItems = comments, onLike = { comment: Comment ->
scope.launch {
model.commentService.likeComment(comment.id)
comments.refresh()

View File

@@ -24,9 +24,9 @@ import kotlinx.coroutines.launch
@Composable
fun AnimatedLikeIcon(
modifier: Modifier = Modifier,
liked: Boolean = false,
onClick: (() -> Unit)? = null
) {
var liked by remember { mutableStateOf(false) }
val animatableRotation = remember { Animatable(0f) }
val animatedColor by animateColorAsState(targetValue = if (liked) Color(0xFFd83737) else Color.Black)
val scope = rememberCoroutineScope()
@@ -52,13 +52,11 @@ fun AnimatedLikeIcon(
)
}
Box(contentAlignment = Alignment.Center, modifier = Modifier.noRippleClickable {
liked = !liked
onClick?.invoke()
// Trigger shake animation
scope.launch {
shake()
}
}) {
Image(
painter = painterResource(id = R.drawable.rider_pro_like),

View File

@@ -6,13 +6,16 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -22,9 +25,11 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.aiosman.riderpro.R
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
@Composable
fun EditCommentBottomModal() {
fun EditCommentBottomModal(onSend: (String) -> Unit = {}) {
var text by remember { mutableStateOf("") }
Box(
modifier = Modifier
.fillMaxWidth()
@@ -49,8 +54,10 @@ fun EditCommentBottomModal() {
) {
BasicTextField(
value = "",
onValueChange = { },
value = text,
onValueChange = {
text = it
},
modifier = Modifier
.fillMaxWidth(),
textStyle = TextStyle(
@@ -67,10 +74,11 @@ fun EditCommentBottomModal() {
contentDescription = "Send",
modifier = Modifier
.size(32.dp)
.noRippleClickable {
onSend(text)
text = ""
},
)
}
}
}

View File

@@ -58,21 +58,28 @@ import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import kotlinx.coroutines.launch
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun MomentsList() {
val model = MomentViewModel
var dataFlow = model.momentsFlow
var moments = dataFlow.collectAsLazyPagingItems()
val scope = rememberCoroutineScope()
LazyColumn {
items(moments.itemCount) { idx ->
val momentItem = moments[idx] ?: return@items
MomentCard(momentItem = momentItem, onLikeClick = {
MomentCard(momentItem = momentItem,
onAddComment = {
scope.launch {
model.onAddComment(momentItem.id)
}
},
onLikeClick = {
scope.launch {
if (momentItem.liked) {
model.dislikeMoment(momentItem.id)
} else {
model.likeMoment(momentItem.id)
// moments.refresh()
}
}
})
}
@@ -83,7 +90,8 @@ fun MomentsList() {
@Composable
fun MomentCard(
momentItem: MomentItem,
onLikeClick: () -> Unit
onLikeClick: () -> Unit,
onAddComment: () -> Unit = {}
) {
val navController = LocalNavController.current
Column(
@@ -103,7 +111,12 @@ fun MomentCard(
.fillMaxHeight()
.weight(1f)
ModificationListHeader()
MomentBottomOperateRowGroup(momentOperateBtnBoxModifier, momentItem = momentItem, onLikeClick = onLikeClick)
MomentBottomOperateRowGroup(
momentOperateBtnBoxModifier,
momentItem = momentItem,
onLikeClick = onLikeClick,
onAddComment = onAddComment
)
}
}
@@ -214,8 +227,15 @@ fun MomentTopRowGroup(momentItem: MomentItem) {
AsyncImage(
momentItem.avatar,
contentDescription = "",
modifier = Modifier.size(40.dp).noRippleClickable {
navController.navigate(NavigationRoute.AccountProfile.route.replace("{id}", momentItem.authorId.toString()))
modifier = Modifier
.size(40.dp)
.noRippleClickable {
navController.navigate(
NavigationRoute.AccountProfile.route.replace(
"{id}",
momentItem.authorId.toString()
)
)
},
contentScale = ContentScale.Crop
)
@@ -310,6 +330,7 @@ fun MomentOperateBtn(count: String, content: @Composable () -> Unit) {
fun MomentBottomOperateRowGroup(
modifier: Modifier,
onLikeClick: () -> Unit = {},
onAddComment: () -> Unit = {},
momentItem: MomentItem
) {
var systemUiController = rememberSystemUiController()
@@ -323,7 +344,10 @@ fun MomentBottomOperateRowGroup(
)
) {
systemUiController.setNavigationBarColor(Color(0xfff7f7f7))
CommentModalContent(postId = momentItem.id) {
CommentModalContent(postId = momentItem.id, onCommentAdded = {
showCommentModal = false
onAddComment()
}) {
systemUiController.setNavigationBarColor(Color.Black)
}
}
@@ -338,8 +362,14 @@ fun MomentBottomOperateRowGroup(
contentAlignment = Alignment.Center
) {
MomentOperateBtn(count = momentItem.likeCount.toString()) {
AnimatedLikeIcon(modifier = Modifier.size(24.dp)) {
AnimatedLikeIcon(
modifier = Modifier.size(24.dp),
liked = momentItem.liked
) {
onLikeClick()
}
}
}
@@ -352,19 +382,28 @@ fun MomentBottomOperateRowGroup(
},
contentAlignment = Alignment.Center
) {
MomentOperateBtn(icon = R.drawable.rider_pro_moment_comment, count = momentItem.commentCount.toString())
MomentOperateBtn(
icon = R.drawable.rider_pro_moment_comment,
count = momentItem.commentCount.toString()
)
}
Box(
modifier = modifier,
contentAlignment = Alignment.Center
) {
MomentOperateBtn(icon = R.drawable.rider_pro_share, count = momentItem.shareCount.toString())
MomentOperateBtn(
icon = R.drawable.rider_pro_share,
count = momentItem.shareCount.toString()
)
}
Box(
modifier = modifier,
contentAlignment = Alignment.Center
) {
MomentOperateBtn(icon = R.drawable.rider_pro_favoriate, count = momentItem.favoriteCount.toString())
MomentOperateBtn(
icon = R.drawable.rider_pro_favoriate,
count = momentItem.favoriteCount.toString()
)
}
}
}

View File

@@ -31,22 +31,23 @@ object MomentViewModel : ViewModel() {
val profile = accountService.getMyAccountProfile()
Pager(
config = PagingConfig(pageSize = 5, enablePlaceholders = false),
pagingSourceFactory = { MomentPagingSource(
pagingSourceFactory = {
MomentPagingSource(
MomentRemoteDataSource(momentService),
timelineId = profile.id
) }
)
}
).flow.cachedIn(viewModelScope).collectLatest {
_momentsFlow.value = it
}
}
}
suspend fun likeMoment(id: Int) {
momentService.likeMoment(id)
fun updateLikeCount(id: Int) {
val currentPagingData = _momentsFlow.value
val updatedPagingData = currentPagingData.map { momentItem ->
if (momentItem.id == id) {
momentItem.copy(likeCount = momentItem.likeCount + 1)
momentItem.copy(likeCount = momentItem.likeCount + 1, liked = true)
} else {
momentItem
}
@@ -54,4 +55,42 @@ object MomentViewModel : ViewModel() {
_momentsFlow.value = updatedPagingData
}
suspend fun likeMoment(id: Int) {
momentService.likeMoment(id)
updateLikeCount(id)
}
fun updateCommentCount(id: Int) {
val currentPagingData = _momentsFlow.value
val updatedPagingData = currentPagingData.map { momentItem ->
if (momentItem.id == id) {
momentItem.copy(commentCount = momentItem.commentCount + 1)
} else {
momentItem
}
}
_momentsFlow.value = updatedPagingData
}
suspend fun onAddComment(id: Int) {
val currentPagingData = _momentsFlow.value
updateCommentCount(id)
}
fun updateDislikeMomentById(id: Int) {
val currentPagingData = _momentsFlow.value
val updatedPagingData = currentPagingData.map { momentItem ->
if (momentItem.id == id) {
momentItem.copy(likeCount = momentItem.likeCount - 1, liked = false)
} else {
momentItem
}
}
_momentsFlow.value = updatedPagingData
}
suspend fun dislikeMoment(id: Int) {
momentService.dislikeMoment(id)
updateDislikeMomentById(id)
}
}

View File

@@ -58,11 +58,17 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.cachedIn
import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.collectAsLazyPagingItems
import androidx.paging.map
import coil.compose.AsyncImage
import com.aiosman.riderpro.LocalNavController
import com.aiosman.riderpro.R
@@ -71,66 +77,154 @@ import com.aiosman.riderpro.data.AccountService
import com.aiosman.riderpro.data.Comment
import com.aiosman.riderpro.data.CommentPagingSource
import com.aiosman.riderpro.data.CommentRemoteDataSource
import com.aiosman.riderpro.data.CommentService
import com.aiosman.riderpro.data.TestCommentServiceImpl
import com.aiosman.riderpro.data.MomentService
import com.aiosman.riderpro.data.TestAccountServiceImpl
import com.aiosman.riderpro.data.TestMomentServiceImpl
import com.aiosman.riderpro.model.MomentItem
import com.aiosman.riderpro.ui.NavigationRoute
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.aiosman.riderpro.ui.composables.BottomNavigationPlaceholder
import com.aiosman.riderpro.ui.composables.EditCommentBottomModal
import com.aiosman.riderpro.ui.index.tabs.moment.MomentViewModel
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun PostScreen(
id: String,
) {
class PostViewModel(
val postId: String
) : ViewModel() {
var service: MomentService = TestMomentServiceImpl()
var commentService: CommentService = TestCommentServiceImpl()
private var _commentsFlow = MutableStateFlow<PagingData<Comment>>(PagingData.empty())
val commentsFlow = _commentsFlow.asStateFlow()
var commentSource = CommentPagingSource(
CommentRemoteDataSource(TestCommentServiceImpl())
)
val commentsFlow: Flow<PagingData<Comment>> = Pager(
init {
viewModelScope.launch {
Pager(
config = PagingConfig(pageSize = 5, enablePlaceholders = false),
pagingSourceFactory = { commentSource }
).flow
val lazyPagingItems = commentsFlow.collectAsLazyPagingItems()
var showCollapseContent by remember { mutableStateOf(true) }
val scrollState = rememberLazyListState()
val uiController = rememberSystemUiController()
var moment by remember { mutableStateOf<MomentItem?>(null) }
var accountProfile by remember { mutableStateOf<AccountProfile?>(null) }
pagingSourceFactory = {
CommentPagingSource(
CommentRemoteDataSource(commentService),
postId = postId.toInt()
)
}
).flow.cachedIn(viewModelScope).collectLatest {
_commentsFlow.value = it
}
}
}
var accountProfile by mutableStateOf<AccountProfile?>(null)
var moment by mutableStateOf<MomentItem?>(null)
var accountService: AccountService = TestAccountServiceImpl()
LaunchedEffect(Unit) {
uiController.setNavigationBarColor(Color.White)
moment = service.getMomentById(id.toInt())
suspend fun initData() {
moment = service.getMomentById(postId.toInt())
moment?.let {
accountProfile = accountService.getAccountProfileById(it.authorId)
}
}
suspend fun likeComment(commentId: Int) {
commentService.likeComment(commentId)
val currentPagingData = commentsFlow.value
val updatedPagingData = currentPagingData.map { comment ->
if (comment.id == commentId) {
comment.copy(liked = !comment.liked)
} else {
comment
}
}
_commentsFlow.value = updatedPagingData
}
suspend fun createComment(content: String) {
commentService.createComment(postId.toInt(), content, 1)
MomentViewModel.updateCommentCount(postId.toInt())
}
suspend fun likeMoment() {
moment?.let {
service.likeMoment(it.id)
moment = moment?.copy(likeCount = moment?.likeCount?.plus(1) ?: 0, liked = true)
MomentViewModel.updateLikeCount(it.id)
}
}
suspend fun dislikeMoment() {
moment?.let {
service.dislikeMoment(it.id)
moment = moment?.copy(likeCount = moment?.likeCount?.minus(1) ?: 0, liked = false)
// update home list
MomentViewModel.updateDislikeMomentById(it.id)
}
}
}
@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 scope = rememberCoroutineScope()
val commentsPagging = viewModel.commentsFlow.collectAsLazyPagingItems()
var showCollapseContent by remember { mutableStateOf(true) }
val scrollState = rememberLazyListState()
val uiController = rememberSystemUiController()
LaunchedEffect(Unit) {
uiController.setNavigationBarColor(Color.White)
viewModel.initData()
}
StatusBarMaskLayout {
Scaffold(
modifier = Modifier.fillMaxSize(),
bottomBar = { BottomNavigationBar() }
bottomBar = {
BottomNavigationBar(
onLikeClick = {
scope.launch {
if (viewModel.moment?.liked == true) {
viewModel.dislikeMoment()
} else {
viewModel.likeMoment()
}
}
},
onCreateComment = {
scope.launch {
viewModel.createComment(it)
commentsPagging.refresh()
}
},
momentItem = viewModel.moment
)
}
) {
it
Column(
modifier = Modifier
.fillMaxSize()
) {
Header(accountProfile)
Header(viewModel.accountProfile)
Column(modifier = Modifier.animateContentSize()) {
AnimatedVisibility(visible = showCollapseContent) {
// collapse content
Column(
modifier = Modifier
.fillMaxWidth()
) {
Box(
modifier = Modifier
@@ -140,13 +234,13 @@ fun PostScreen(
) {
PostImageView(
id,
moment?.images ?: emptyList()
viewModel.moment?.images ?: emptyList()
)
}
PostDetails(
id,
moment
viewModel.moment
)
}
}
@@ -156,7 +250,14 @@ fun PostScreen(
.fillMaxWidth()
) {
CommentsSection(lazyPagingItems = lazyPagingItems, scrollState, onLike = {}) {
CommentsSection(
lazyPagingItems = commentsPagging,
scrollState,
onLike = { comment: Comment ->
scope.launch {
viewModel.likeComment(comment.id)
}
}) {
showCollapseContent = it
}
}
@@ -182,7 +283,6 @@ fun Header(accountProfile: AccountProfile?) {
navController.popBackStack()
}
.size(32.dp)
)
Spacer(modifier = Modifier.width(8.dp))
accountProfile?.let {
@@ -191,7 +291,15 @@ fun Header(accountProfile: AccountProfile?) {
contentDescription = "Profile Picture",
modifier = Modifier
.size(40.dp)
.clip(CircleShape),
.clip(CircleShape)
.noRippleClickable {
navController.navigate(
NavigationRoute.AccountProfile.route.replace(
"{id}",
accountProfile.id.toString()
)
)
},
contentScale = ContentScale.Crop
)
}
@@ -298,11 +406,9 @@ fun PostDetails(
)
Text(text = "12-11 发布")
Spacer(modifier = Modifier.height(8.dp))
Text(text = "共231条评论")
Text(text = "${momentItem?.commentCount ?: 0} Comments")
}
}
@Composable
@@ -319,7 +425,7 @@ fun CommentsSection(
) {
items(lazyPagingItems.itemCount) { idx ->
val item = lazyPagingItems[idx] ?: return@items
CommentItem(item,onLike={
CommentItem(item, onLike = {
onLike(item)
})
}
@@ -339,7 +445,7 @@ fun CommentsSection(
@Composable
fun CommentItem(comment: Comment,onLike:()->Unit = {}) {
fun CommentItem(comment: Comment, onLike: () -> Unit = {}) {
Column {
Row(modifier = Modifier.padding(vertical = 8.dp)) {
AsyncImage(
@@ -361,7 +467,11 @@ fun CommentItem(comment: Comment,onLike:()->Unit = {}) {
IconButton(onClick = {
onLike()
}) {
Icon(Icons.Filled.Favorite, contentDescription = "Like")
Icon(
Icons.Filled.Favorite,
contentDescription = "Like",
tint = if (comment.liked) Color.Red else Color.Gray
)
}
Text(text = comment.likes.toString())
}
@@ -379,7 +489,11 @@ fun CommentItem(comment: Comment,onLike:()->Unit = {}) {
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BottomNavigationBar() {
fun BottomNavigationBar(
onCreateComment: (String) -> Unit = {},
onLikeClick: () -> Unit = {},
momentItem: MomentItem?
) {
val systemUiController = rememberSystemUiController()
var showCommentModal by remember { mutableStateOf(false) }
if (showCommentModal) {
@@ -392,7 +506,10 @@ fun BottomNavigationBar() {
dragHandle = {},
shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
) {
EditCommentBottomModal()
EditCommentBottomModal() {
onCreateComment(it)
showCommentModal = false
}
}
}
Column(
@@ -427,10 +544,12 @@ fun BottomNavigationBar() {
}
IconButton(
onClick = { /*TODO*/ }) {
Icon(Icons.Filled.Favorite, contentDescription = "Send")
onClick = {
onLikeClick()
}) {
Icon(Icons.Filled.Favorite, contentDescription = "like", tint = if (momentItem?.liked == true) Color.Red else Color.Gray)
}
Text(text = "2077")
Text(text = momentItem?.likeCount.toString())
IconButton(
onClick = { /*TODO*/ }) {
Icon(Icons.Filled.Star, contentDescription = "Send")