更新部分UI
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
@@ -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(
|
||||
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(MomentServiceImpl()),
|
||||
author = profile?.id ?: 0,
|
||||
|
||||
MomentRemoteDataSource(momentService),
|
||||
author = profile.id
|
||||
)
|
||||
}
|
||||
).flow
|
||||
).flow.cachedIn(viewModelScope).collectLatest {
|
||||
_momentsFlow.value = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
||||
}
|
||||
@@ -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,18 +69,16 @@ 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,
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
item {
|
||||
Box(
|
||||
@@ -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,23 +528,16 @@ 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()
|
||||
.aspectRatio(1f)
|
||||
.padding(16.dp)
|
||||
.noRippleClickable {
|
||||
PostViewModel.preTransit(momentEntity)
|
||||
@@ -553,9 +549,9 @@ fun MomentCardPicture(imageUrl: String, momentEntity: MomentEntity) {
|
||||
)
|
||||
},
|
||||
contentDescription = "",
|
||||
contentScale = ContentScale.FillWidth
|
||||
contentScale = ContentScale.Crop
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -90,7 +90,7 @@ fun AccountProfile(id:String) {
|
||||
},
|
||||
)
|
||||
}
|
||||
RidingStyle()
|
||||
// RidingStyle()
|
||||
}
|
||||
if (items != null) {
|
||||
items(items.itemCount) { idx ->
|
||||
|
||||
Reference in New Issue
Block a user