更新个人主页功能

- 优化用户主页数据加载逻辑
- 调整用户主页UI显示
- 修复关注按钮文案问题
This commit is contained in:
2024-09-01 21:37:15 +08:00
parent 1a62bf26e4
commit a4ab6f0ab7
4 changed files with 139 additions and 94 deletions

View File

@@ -32,19 +32,6 @@ object MyProfileViewModel : ViewModel() {
private var _momentsFlow = MutableStateFlow<PagingData<MomentEntity>>(PagingData.empty()) private var _momentsFlow = MutableStateFlow<PagingData<MomentEntity>>(PagingData.empty())
var momentsFlow = _momentsFlow.asStateFlow() var momentsFlow = _momentsFlow.asStateFlow()
fun loadProfile(){ fun loadProfile(){
// momentsFlow = Pager(
// config = PagingConfig(pageSize = 5, enablePlaceholders = false),
// pagingSourceFactory = {
// MomentPagingSource(
// MomentRemoteDataSource(MomentServiceImpl()),
// author = profile?.id ?: 0,
//
// )
// }
// ).flow.cachedIn(viewModelScope).collectLatest {
// MomentViewModel._momentsFlow.value = it
// }
viewModelScope.launch { viewModelScope.launch {
profile = accountService.getMyAccountProfile() profile = accountService.getMyAccountProfile()
val profile = accountService.getMyAccountProfile() val profile = accountService.getMyAccountProfile()

View File

@@ -253,7 +253,7 @@ fun UserInformation(
UserInformationBasic(userInfoModifier, accountProfileEntity) UserInformationBasic(userInfoModifier, accountProfileEntity)
UserInformationFollowing(userInfoModifier, accountProfileEntity) UserInformationFollowing(userInfoModifier, accountProfileEntity)
} }
UserInformationSlogan() UserInformationSlogan(accountProfileEntity)
CommunicationOperatorGroup( CommunicationOperatorGroup(
isSelf = isSelf, isSelf = isSelf,
isFollowing = accountProfileEntity.isFollowing, isFollowing = accountProfileEntity.isFollowing,
@@ -370,11 +370,10 @@ fun UserInformationFollowing(modifier: Modifier, accountProfileEntity: AccountPr
} }
@Composable @Composable
fun UserInformationSlogan() { fun UserInformationSlogan(accountProfileEntity: AccountProfileEntity) {
val model = MyProfileViewModel
Text( Text(
modifier = Modifier.padding(top = 23.dp), modifier = Modifier.padding(top = 23.dp),
text = model.bio, text = accountProfileEntity.bio,
fontSize = 13.sp, fontSize = 13.sp,
color = Color.Black, color = Color.Black,
style = TextStyle(fontWeight = FontWeight.Bold) style = TextStyle(fontWeight = FontWeight.Bold)
@@ -408,7 +407,7 @@ fun CommunicationOperatorGroup(
contentDescription = "" contentDescription = ""
) )
Text( Text(
text = if (isFollowing) "FOLLOWING" else "FOLLOW", text = if (isFollowing) stringResource(R.string.following_upper) else stringResource(R.string.follow_upper),
fontSize = 16.sp, fontSize = 16.sp,
color = Color.White, color = Color.White,
style = TextStyle(fontWeight = FontWeight.Bold) style = TextStyle(fontWeight = FontWeight.Bold)

View File

@@ -1,69 +1,37 @@
package com.aiosman.riderpro.ui.profile package com.aiosman.riderpro.ui.profile
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.compose.collectAsLazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems
import com.aiosman.riderpro.entity.AccountProfileEntity import com.aiosman.riderpro.R
import com.aiosman.riderpro.entity.MomentPagingSource import com.aiosman.riderpro.ui.composables.CustomAsyncImage
import com.aiosman.riderpro.entity.MomentRemoteDataSource
import com.aiosman.riderpro.entity.MomentServiceImpl
import com.aiosman.riderpro.data.UserServiceImpl
import com.aiosman.riderpro.data.UserService
import com.aiosman.riderpro.entity.MomentEntity
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
import com.aiosman.riderpro.ui.index.tabs.profile.CarGroup
import com.aiosman.riderpro.ui.index.tabs.profile.MomentPostUnit import com.aiosman.riderpro.ui.index.tabs.profile.MomentPostUnit
import com.aiosman.riderpro.ui.index.tabs.profile.RidingStyle
import com.aiosman.riderpro.ui.index.tabs.profile.UserInformation import com.aiosman.riderpro.ui.index.tabs.profile.UserInformation
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@Composable @Composable
fun AccountProfile(id:String) { fun AccountProfile(id: String) {
val userService: UserService = UserServiceImpl() val model = AccountProfileViewModel
var userProfile by remember { mutableStateOf<AccountProfileEntity?>(null) }
val momentService = MomentServiceImpl()
var momentsFlow by remember { mutableStateOf<Flow<PagingData<MomentEntity>>?>(null) }
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val items = model.momentsFlow.collectAsLazyPagingItems()
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
userProfile = userService.getUserProfile(id) model.loadProfile(id)
momentsFlow = Pager(
config = PagingConfig(pageSize = 5, enablePlaceholders = false),
pagingSourceFactory = {
MomentPagingSource(
MomentRemoteDataSource(momentService),
author = id.toInt()
)
} }
).flow
}
val items = momentsFlow?.collectAsLazyPagingItems()
val systemUiController = rememberSystemUiController()
LaunchedEffect(Unit) {
systemUiController.setNavigationBarColor(
color = androidx.compose.ui.graphics.Color.Transparent
)
}
StatusBarMaskLayout(
modifier = Modifier.fillMaxSize(),
useNavigationBarMask = false
) {
LazyColumn( LazyColumn(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
@@ -72,19 +40,43 @@ fun AccountProfile(id:String) {
verticalArrangement = Arrangement.Top, verticalArrangement = Arrangement.Top,
) { ) {
item { item {
CarGroup() Box(
userProfile?.let { modifier = Modifier
.fillMaxWidth()
) {
val banner = model.profile?.banner
if (banner != null) {
CustomAsyncImage(
LocalContext.current,
banner,
modifier = Modifier
.fillMaxWidth()
.height(400.dp),
contentDescription = "",
contentScale = ContentScale.Crop
)
} else {
Image(
painter = painterResource(id = R.drawable.rider_pro_moment_demo_2),
modifier = Modifier
.fillMaxWidth()
.height(400.dp),
contentDescription = "",
contentScale = ContentScale.Crop
)
}
}
model.profile?.let {
UserInformation( UserInformation(
isSelf = false, isSelf = false,
accountProfileEntity = it, accountProfileEntity = it,
onFollowClick = { onFollowClick = {
scope.launch { scope.launch {
if (it.isFollowing) { if (it.isFollowing) {
userService.unFollowUser(id) model.unFollowUser(id)
userProfile = userProfile?.copy(isFollowing = false)
} else { } else {
userService.followUser(id) model.followUser(id)
userProfile = userProfile?.copy(isFollowing = true)
} }
} }
}, },
@@ -92,13 +84,12 @@ fun AccountProfile(id:String) {
} }
// RidingStyle() // RidingStyle()
} }
if (items != null) {
items(items.itemCount) { idx -> items(items.itemCount) { idx ->
val momentItem = items[idx] ?: return@items val momentItem = items[idx] ?: return@items
MomentPostUnit(momentItem) MomentPostUnit(momentItem)
} }
}
}
} }
} }

View File

@@ -1,4 +1,72 @@
package com.aiosman.riderpro.ui.profile package com.aiosman.riderpro.ui.profile
object AccountProfileViewModel { import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
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 com.aiosman.riderpro.data.AccountService
import com.aiosman.riderpro.data.AccountServiceImpl
import com.aiosman.riderpro.data.MomentService
import com.aiosman.riderpro.data.UserServiceImpl
import com.aiosman.riderpro.entity.AccountProfileEntity
import com.aiosman.riderpro.entity.MomentEntity
import com.aiosman.riderpro.entity.MomentPagingSource
import com.aiosman.riderpro.entity.MomentRemoteDataSource
import com.aiosman.riderpro.entity.MomentServiceImpl
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
object AccountProfileViewModel : ViewModel() {
var profileId by mutableStateOf(0)
val accountService: AccountService = AccountServiceImpl()
val momentService: MomentService = MomentServiceImpl()
val userService = UserServiceImpl()
var profile by mutableStateOf<AccountProfileEntity?>(null)
private var _momentsFlow = MutableStateFlow<PagingData<MomentEntity>>(PagingData.empty())
var momentsFlow = _momentsFlow.asStateFlow()
fun loadProfile(id: String) {
viewModelScope.launch {
if (profileId == profile?.id){
return@launch
}
profile = userService.getUserProfile(id)
Pager(
config = PagingConfig(pageSize = 5, enablePlaceholders = false),
pagingSourceFactory = {
MomentPagingSource(
MomentRemoteDataSource(momentService),
author = profile!!.id
)
}
).flow.cachedIn(viewModelScope).collectLatest {
_momentsFlow.value = it
}
}
}
fun followUser(userId: String) {
viewModelScope.launch {
userService.followUser(userId)
profile = profile?.copy(followerCount = profile!!.followerCount + 1, isFollowing = true)
}
}
fun unFollowUser(userId: String) {
viewModelScope.launch {
userService.unFollowUser(userId)
profile = profile?.copy(followerCount = profile!!.followerCount - 1, isFollowing = false)
}
}
val followerCount get() = profile?.followerCount ?: 0
val followingCount get() = profile?.followingCount ?: 0
val bio get() = profile?.bio ?: ""
val nickName get() = profile?.nickName ?: ""
val avatar get() = profile?.avatar
} }