更新消息功能

This commit is contained in:
2024-08-20 19:48:12 +08:00
parent 6137e1c3b5
commit 5228fde035
18 changed files with 1077 additions and 259 deletions

View File

@@ -13,32 +13,53 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
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.LocalNavController
import com.aiosman.riderpro.R
import com.aiosman.riderpro.data.AccountFollow
import com.aiosman.riderpro.ui.NavigationRoute
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.aiosman.riderpro.ui.comment.NoticeScreenHeader
import com.aiosman.riderpro.ui.composables.CustomAsyncImage
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import kotlinx.coroutines.launch
@Preview
@Composable
fun FollowerScreen() {
val scope = rememberCoroutineScope()
StatusBarMaskLayout(
modifier = Modifier.padding(horizontal = 16.dp)
) {
val model = FollowerViewModel
var dataFlow = model.followerItemsFlow
var followers = dataFlow.collectAsLazyPagingItems()
NoticeScreenHeader("FOLLOWERS")
Spacer(modifier = Modifier.height(28.dp))
LaunchedEffect(Unit) {
model.updateNotice()
}
LazyColumn(
modifier = Modifier.weight(1f)
) {
item {
repeat(20) {
FollowerItem()
items(followers.itemCount) { index ->
followers[index]?.let { follower ->
FollowerItem(follower) {
scope.launch {
model.followUser(follower.userId)
}
}
}
}
}
@@ -47,7 +68,12 @@ fun FollowerScreen() {
@Composable
fun FollowerItem() {
fun FollowerItem(
item: AccountFollow,
onFollow: () -> Unit = {}
) {
val context = LocalContext.current
val navController = LocalNavController.current
Box(
modifier = Modifier.padding(horizontal = 24.dp, vertical = 16.dp)
) {
@@ -55,37 +81,52 @@ fun FollowerItem() {
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
Image(
painter = painterResource(id = R.drawable.default_avatar),
contentDescription = "Follower",
modifier = Modifier.size(40.dp)
CustomAsyncImage(
context = context,
imageUrl = item.avatar,
contentDescription = item.nickname,
modifier = Modifier
.size(40.dp)
.noRippleClickable {
navController.navigate(
NavigationRoute.AccountProfile.route.replace(
"{id}",
item.userId.toString()
)
)
}
)
Spacer(modifier = Modifier.width(12.dp))
Column(
modifier = Modifier.weight(1f)
) {
Text("Username", fontWeight = FontWeight.Bold, fontSize = 16.sp)
Spacer(modifier = Modifier.height(5.dp))
Text("Username", fontSize = 12.sp, color = Color(0x99000000))
Text(item.nickname, fontWeight = FontWeight.Bold, fontSize = 16.sp)
}
Box {
Image(
painter = painterResource(id = R.drawable.follow_bg),
contentDescription = "Like",
modifier = Modifier
.width(79.dp)
.height(24.dp)
)
Text(
"FOLLOW",
fontSize = 14.sp,
color = Color(0xFFFFFFFF),
modifier = Modifier.align(
Alignment.Center
if (!item.isFollowing) {
Box(
modifier = Modifier.noRippleClickable {
onFollow()
}
) {
Image(
painter = painterResource(id = R.drawable.follow_bg),
contentDescription = "Follow",
modifier = Modifier
.width(79.dp)
.height(24.dp)
)
)
Text(
"FOLLOW",
fontSize = 14.sp,
color = Color(0xFFFFFFFF),
modifier = Modifier.align(
Alignment.Center
)
)
}
}
}
}
}

View File

@@ -0,0 +1,70 @@
package com.aiosman.riderpro.ui.follower
import android.icu.util.Calendar
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.cachedIn
import androidx.paging.map
import com.aiosman.riderpro.data.AccountFollow
import com.aiosman.riderpro.data.AccountService
import com.aiosman.riderpro.data.FollowItemPagingSource
import com.aiosman.riderpro.data.TestAccountServiceImpl
import com.aiosman.riderpro.data.TestUserServiceImpl
import com.aiosman.riderpro.data.UserService
import com.aiosman.riderpro.data.api.ApiClient
import com.aiosman.riderpro.data.api.UpdateNoticeRequestBody
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
object FollowerViewModel : ViewModel() {
private val accountService: AccountService = TestAccountServiceImpl()
private val userService: UserService = TestUserServiceImpl()
private val _followerItemsFlow =
MutableStateFlow<PagingData<AccountFollow>>(PagingData.empty())
val followerItemsFlow = _followerItemsFlow.asStateFlow()
init {
viewModelScope.launch {
Pager(
config = PagingConfig(pageSize = 5, enablePlaceholders = false),
pagingSourceFactory = {
FollowItemPagingSource(
accountService
)
}
).flow.cachedIn(viewModelScope).collectLatest {
_followerItemsFlow.value = it
}
}
}
private fun updateIsFollow(id: Int) {
val currentPagingData = _followerItemsFlow.value
val updatedPagingData = currentPagingData.map { follow ->
if (follow.userId == id) {
follow.copy(isFollowing = true)
} else {
follow
}
}
_followerItemsFlow.value = updatedPagingData
}
suspend fun followUser(userId: Int) {
userService.followUser(userId.toString())
updateIsFollow(userId)
}
suspend fun updateNotice() {
var now = Calendar.getInstance().time
accountService.updateNotice(
UpdateNoticeRequestBody(
lastLookFollowTime = ApiClient.formatTime(now)
)
)
}
}