更新部分UI

This commit is contained in:
2024-08-25 21:02:51 +08:00
parent b4004663cd
commit b788ab0dba
7 changed files with 156 additions and 147 deletions

View File

@@ -1,6 +1,7 @@
package com.aiosman.riderpro.data.api
import android.icu.text.SimpleDateFormat
import android.icu.util.TimeZone
import com.aiosman.riderpro.AppStore
import com.aiosman.riderpro.ConstVars
import okhttp3.Interceptor
@@ -85,9 +86,13 @@ object ApiClient {
}
fun dateFromApiString(apiString: String): Date {
val timeFormat = ApiClient.TIME_FORMAT
val timeFormat = TIME_FORMAT
val simpleDateFormat = SimpleDateFormat(timeFormat, Locale.getDefault())
simpleDateFormat.timeZone = TimeZone.getTimeZone("UTC")
val date = simpleDateFormat.parse(apiString)
return date
simpleDateFormat.timeZone = TimeZone.getDefault()
val localDateString = simpleDateFormat.format(date)
return simpleDateFormat.parse(localDateString)
}
}

View File

@@ -4,6 +4,7 @@ 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.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -14,6 +15,8 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
@@ -22,6 +25,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -40,7 +44,9 @@ 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
import kotlinx.coroutines.launch
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun IndexScreen() {
val model = IndexViewModel
@@ -51,13 +57,13 @@ fun IndexScreen() {
val item = listOf(
NavigationItem.Home,
NavigationItem.Search,
// NavigationItem.Street,
NavigationItem.Add,
// NavigationItem.Message,
NavigationItem.Notification,
NavigationItem.Profile
)
val systemUiController = rememberSystemUiController()
val pagerState = rememberPagerState(pageCount = { item.size })
val coroutineScope = rememberCoroutineScope()
LaunchedEffect(Unit) {
systemUiController.setNavigationBarColor(Color.Transparent)
@@ -77,16 +83,14 @@ fun IndexScreen() {
NavigationBarItem(
selected = isSelected,
onClick = {
if (it.route === NavigationItem.Add.route) {
NewPostViewModel.asNewPost()
navController.navigate(
NavigationRoute.NewPost.route,
)
navController.navigate(NavigationRoute.NewPost.route)
return@NavigationBarItem
}
coroutineScope.launch {
pagerState.scrollToPage(idx)
}
model.tabIndex = idx
},
colors = NavigationBarItemColors(
@@ -108,43 +112,21 @@ fun IndexScreen() {
}
)
}
}
}
) { innerPadding ->
Box(
modifier = Modifier
) {
when (model.tabIndex) {
0 -> Box(
modifier = Modifier.padding(innerPadding)
) {
Home()
}
1 -> Box(
modifier = Modifier.padding(innerPadding)
) {
SearchScreen()
}
// 1 -> Street()
2 -> Box(
modifier = Modifier.padding(innerPadding)
) { Add() }
// 3 -> Box(
// modifier = Modifier.padding(innerPadding)
// ) { Video() }
3 -> Box(
modifier = Modifier.padding(innerPadding)
) {
Notifications()
}
4 -> Box(
modifier = Modifier.padding(innerPadding)
) { Profile() }
HorizontalPager(
state = pagerState,
modifier = Modifier.padding(innerPadding),
beyondBoundsPageCount = 5,
userScrollEnabled = false
) { page ->
when (page) {
0 -> Home()
1 -> SearchScreen()
2 -> Add()
3 -> Notifications()
4 -> Profile()
}
}
}

View File

@@ -90,7 +90,6 @@ fun MomentsList() {
var moments = dataFlow.collectAsLazyPagingItems()
val scope = rememberCoroutineScope()
var refreshing by remember { mutableStateOf(false) }
moments.loadState
val state = rememberPullRefreshState(refreshing, onRefresh = {
model.refreshPager()
})

View File

@@ -3,40 +3,67 @@ package com.aiosman.riderpro.ui.index.tabs.profile
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.AppStore
import com.aiosman.riderpro.entity.AccountProfileEntity
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 com.aiosman.riderpro.data.UserServiceImpl
import com.aiosman.riderpro.entity.MomentEntity
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
object MyProfileViewModel {
val service: AccountService = AccountServiceImpl()
object MyProfileViewModel : ViewModel() {
val accountService: AccountService = AccountServiceImpl()
val momentService: MomentService = MomentServiceImpl()
val userService = UserServiceImpl()
var profile by mutableStateOf<AccountProfileEntity?>(null)
var momentsFlow by mutableStateOf<Flow<PagingData<MomentEntity>>?>(null)
suspend fun loadProfile() {
profile = service.getMyAccountProfile()
momentsFlow = Pager(
config = PagingConfig(pageSize = 5, enablePlaceholders = false),
pagingSourceFactory = {
MomentPagingSource(
MomentRemoteDataSource(MomentServiceImpl()),
author = profile?.id ?: 0,
private var _momentsFlow = MutableStateFlow<PagingData<MomentEntity>>(PagingData.empty())
var momentsFlow = _momentsFlow.asStateFlow()
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 {
profile = accountService.getMyAccountProfile()
val profile = accountService.getMyAccountProfile()
Pager(
config = PagingConfig(pageSize = 5, enablePlaceholders = false),
pagingSourceFactory = {
MomentPagingSource(
MomentRemoteDataSource(momentService),
author = profile.id
)
}
).flow.cachedIn(viewModelScope).collectLatest {
_momentsFlow.value = it
}
).flow
}
}
suspend fun logout() {
service.getMyAccountProfile()
accountService.getMyAccountProfile()
AppStore.apply {
token = null
rememberMe = false
@@ -44,10 +71,12 @@ object MyProfileViewModel {
}
}
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
}

View File

@@ -1,5 +1,6 @@
package com.aiosman.riderpro.ui.index.tabs.profile
import android.util.Log
import androidx.annotation.DrawableRes
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.foundation.Image
@@ -11,6 +12,7 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
@@ -19,6 +21,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
@@ -55,6 +58,7 @@ import com.aiosman.riderpro.exp.formatPostTime
import com.aiosman.riderpro.entity.MomentEntity
import com.aiosman.riderpro.ui.NavigationRoute
import com.aiosman.riderpro.ui.composables.CustomAsyncImage
import com.aiosman.riderpro.ui.index.tabs.moment.MomentCard
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
import com.aiosman.riderpro.ui.post.PostViewModel
import kotlinx.coroutines.launch
@@ -65,19 +69,17 @@ fun ProfilePage() {
val model = MyProfileViewModel
var expanded by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
Log.d("ProfilePage", "loadProfile")
model.loadProfile()
}
val moments = model.momentsFlow?.collectAsLazyPagingItems()
val moments = model.momentsFlow.collectAsLazyPagingItems()
val navController: NavController = LocalNavController.current
val scope = rememberCoroutineScope()
Box {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(bottom = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top,
) {
LazyColumn(
modifier = Modifier
.fillMaxSize(),
) {
item {
Box(
modifier = Modifier
@@ -132,18 +134,19 @@ fun ProfilePage() {
model.profile?.let {
UserInformation(accountProfileEntity = it)
}
RidingStyle()
}
moments?.let {
items(it.itemCount) { idx ->
val momentItem = it[idx] ?: return@items
MomentPostUnit(momentItem)
}
// RidingStyle()
}
items(moments.itemCount) { idx ->
val momentItem = moments[idx] ?: return@items
MomentPostUnit(momentItem)
// MomentCard(momentItem)
}
}
}
@Composable
@@ -289,12 +292,12 @@ fun UserInformationBasic(modifier: Modifier, accountProfileEntity: AccountProfil
fontSize = 12.sp,
color = Color.Gray
)
Text(
modifier = Modifier.padding(top = 4.dp),
text = "Member since Jun 4.2019",
fontSize = 12.sp,
color = Color.Gray
)
// Text(
// modifier = Modifier.padding(top = 4.dp),
// text = "Member since Jun 4.2019",
// fontSize = 12.sp,
// color = Color.Gray
// )
}
}
@@ -525,37 +528,30 @@ fun MomentCardTopContent(content: String) {
}
}
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun MomentCardPicture(imageUrl: String, momentEntity: MomentEntity) {
val navController = LocalNavController.current
val sharedTransitionScope = LocalSharedTransitionScope.current
val animatedVisibilityScope = LocalAnimatedContentScope.current
val context = LocalContext.current
with(sharedTransitionScope) {
CustomAsyncImage(
context,
imageUrl,
modifier = Modifier
.sharedElement(
rememberSharedContentState(key = imageUrl),
animatedVisibilityScope = animatedVisibilityScope
)
.fillMaxSize()
.padding(16.dp)
.noRippleClickable {
PostViewModel.preTransit(momentEntity)
navController.navigate(
NavigationRoute.Post.route.replace(
"{id}",
momentEntity.id.toString()
)
CustomAsyncImage(
context,
imageUrl,
modifier = Modifier
.fillMaxSize()
.aspectRatio(1f)
.padding(16.dp)
.noRippleClickable {
PostViewModel.preTransit(momentEntity)
navController.navigate(
NavigationRoute.Post.route.replace(
"{id}",
momentEntity.id.toString()
)
},
contentDescription = "",
contentScale = ContentScale.FillWidth
)
}
)
},
contentDescription = "",
contentScale = ContentScale.Crop
)
}

View File

@@ -171,22 +171,22 @@ fun SignupScreen() {
) {
navController.navigate(NavigationRoute.EmailSignUp.route)
}
Spacer(modifier = Modifier.height(16.dp))
ActionButton(
modifier = Modifier
.width(345.dp)
.height(48.dp),
text = "CONTINUE WITH FACEBOOK".uppercase(),
backgroundImage = R.mipmap.rider_pro_signup_facebook_bg,
leading = {
Image(
painter = painterResource(id = R.mipmap.rider_pro_signup_facebook),
contentDescription = "Facebook",
modifier = Modifier.size(24.dp)
)
Spacer(modifier = Modifier.width(8.dp))
}
)
// Spacer(modifier = Modifier.height(16.dp))
// ActionButton(
// modifier = Modifier
// .width(345.dp)
// .height(48.dp),
// text = "CONTINUE WITH FACEBOOK".uppercase(),
// backgroundImage = R.mipmap.rider_pro_signup_facebook_bg,
// leading = {
// Image(
// painter = painterResource(id = R.mipmap.rider_pro_signup_facebook),
// contentDescription = "Facebook",
// modifier = Modifier.size(24.dp)
// )
// Spacer(modifier = Modifier.width(8.dp))
// }
// )
Spacer(modifier = Modifier.height(16.dp))
ActionButton(
modifier = Modifier
@@ -204,28 +204,26 @@ fun SignupScreen() {
text = "CONTINUE WITH GOOGLE".uppercase(),
backgroundImage = R.mipmap.rider_pro_signup_white_bg
) {
// val signInIntent = googleSignInClient.signInIntent
// launcher.launch(signInIntent)
googleLogin()
}
Spacer(modifier = Modifier.height(16.dp))
Box(
modifier = Modifier
.width(345.dp)
.height(48.dp)
.clip(RoundedCornerShape(8.dp))
.background(Color.Black)
) {
Text(
"Sign in with Apple",
color = Color.White,
modifier = Modifier.align(Alignment.Center),
fontSize = 16.sp,
fontWeight = FontWeight.Bold
)
}
// Spacer(modifier = Modifier.height(16.dp))
// Box(
// modifier = Modifier
// .width(345.dp)
// .height(48.dp)
// .clip(RoundedCornerShape(8.dp))
// .background(Color.Black)
//
// ) {
// Text(
// "Sign in with Apple",
// color = Color.White,
// modifier = Modifier.align(Alignment.Center),
// fontSize = 16.sp,
// fontWeight = FontWeight.Bold
// )
// }
Spacer(modifier = Modifier.height(40.dp))
Row(
verticalAlignment = Alignment.CenterVertically,

View File

@@ -90,7 +90,7 @@ fun AccountProfile(id:String) {
},
)
}
RidingStyle()
// RidingStyle()
}
if (items != null) {
items(items.itemCount) { idx ->