修正个人信息主页
This commit is contained in:
@@ -1,11 +1,8 @@
|
|||||||
package com.aiosman.riderpro.ui.index.tabs.profile
|
package com.aiosman.riderpro.ui.index.tabs.profile
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
@@ -53,7 +50,9 @@ import androidx.compose.ui.draw.shadow
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.ui.layout.ContentScale
|
import androidx.compose.ui.layout.ContentScale
|
||||||
|
import androidx.compose.ui.layout.onGloballyPositioned
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
@@ -110,6 +109,7 @@ fun ProfileV3(
|
|||||||
var enabled by remember { mutableStateOf(true) }
|
var enabled by remember { mutableStateOf(true) }
|
||||||
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
|
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
|
||||||
var expanded by remember { mutableStateOf(false) }
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
var minibarExpanded by remember { mutableStateOf(false) }
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val navController = LocalNavController.current
|
val navController = LocalNavController.current
|
||||||
@@ -126,6 +126,8 @@ fun ProfileV3(
|
|||||||
val refreshState = rememberPullRefreshState(model.refreshing, onRefresh = {
|
val refreshState = rememberPullRefreshState(model.refreshing, onRefresh = {
|
||||||
model.loadProfile(pullRefresh = true)
|
model.loadProfile(pullRefresh = true)
|
||||||
})
|
})
|
||||||
|
var miniToolbarHeight by remember { mutableStateOf(0) }
|
||||||
|
val density = LocalDensity.current
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier.pullRefresh(refreshState)
|
modifier = Modifier.pullRefresh(refreshState)
|
||||||
) {
|
) {
|
||||||
@@ -141,15 +143,222 @@ fun ProfileV3(
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
.height(miniToolbarHeight.dp)
|
||||||
// 保持在最低高度和当前高度之间
|
// 保持在最低高度和当前高度之间
|
||||||
.background(Color(0xfff8f8f8))
|
.background(Color(0xfff8f8f8))
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
|
|
||||||
) {
|
) {
|
||||||
StatusBarSpacer()
|
}
|
||||||
|
// header
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.parallax(0.5f)
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(600.dp)
|
||||||
|
.verticalScroll(toolbarScrollState)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxSize()
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.graphicsLayer {
|
||||||
|
alpha = state.toolbarState.progress
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
// banner
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(bannerHeight.dp)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.let {
|
||||||
|
if (isSelf && state.toolbarState.progress == 0f) {
|
||||||
|
it.noRippleClickable {
|
||||||
|
Intent(Intent.ACTION_PICK).apply {
|
||||||
|
type = "image/*"
|
||||||
|
pickBannerImageLauncher.launch(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.shadow(
|
||||||
|
elevation = 6.dp,
|
||||||
|
shape = RoundedCornerShape(
|
||||||
|
bottomStart = 32.dp,
|
||||||
|
bottomEnd = 32.dp
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
val banner = profile?.banner
|
||||||
|
|
||||||
|
if (banner != null) {
|
||||||
|
CustomAsyncImage(
|
||||||
|
LocalContext.current,
|
||||||
|
banner,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize(),
|
||||||
|
contentDescription = "",
|
||||||
|
contentScale = ContentScale.Crop
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Image(
|
||||||
|
painter = painterResource(id = R.drawable.rider_pro_moment_demo_2),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize(),
|
||||||
|
contentDescription = "",
|
||||||
|
contentScale = ContentScale.Crop
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isSelf) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.TopEnd)
|
||||||
|
.padding(
|
||||||
|
top = statusBarPaddingValues.calculateTopPadding(),
|
||||||
|
start = 8.dp,
|
||||||
|
end = 8.dp
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(16.dp)
|
||||||
|
.clip(RoundedCornerShape(8.dp))
|
||||||
|
.shadow(
|
||||||
|
elevation = 20.dp
|
||||||
|
)
|
||||||
|
.background(Color.White.copy(alpha = 0.7f))
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(id = R.drawable.rider_pro_more_horizon),
|
||||||
|
contentDescription = "",
|
||||||
|
modifier = Modifier.noRippleClickable {
|
||||||
|
expanded = true
|
||||||
|
},
|
||||||
|
tint = Color.Black
|
||||||
|
)
|
||||||
|
}
|
||||||
|
DropdownMenu(
|
||||||
|
expanded = expanded,
|
||||||
|
onDismissRequest = { expanded = false },
|
||||||
|
width = 250,
|
||||||
|
menuItems = listOf(
|
||||||
|
MenuItem(
|
||||||
|
stringResource(R.string.logout),
|
||||||
|
R.mipmap.rider_pro_logout
|
||||||
|
) {
|
||||||
|
expanded = false
|
||||||
|
scope.launch {
|
||||||
|
onLogout()
|
||||||
|
navController.navigate(NavigationRoute.Login.route) {
|
||||||
|
popUpTo(NavigationRoute.Index.route) {
|
||||||
|
inclusive = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MenuItem(
|
||||||
|
stringResource(R.string.change_password),
|
||||||
|
R.mipmap.rider_pro_change_password
|
||||||
|
) {
|
||||||
|
expanded = false
|
||||||
|
scope.launch {
|
||||||
|
navController.navigate(NavigationRoute.ChangePasswordScreen.route)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MenuItem(
|
||||||
|
stringResource(R.string.favourites),
|
||||||
|
R.drawable.rider_pro_favourite
|
||||||
|
) {
|
||||||
|
expanded = false
|
||||||
|
scope.launch {
|
||||||
|
navController.navigate(NavigationRoute.FavouriteList.route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
// user info
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
// 个人信息
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
|
) {
|
||||||
|
profile?.let {
|
||||||
|
UserItem(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
profile?.let {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
|
) {
|
||||||
|
if (isSelf) {
|
||||||
|
SelfProfileAction {
|
||||||
|
navController.navigate(NavigationRoute.AccountEdit.route)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (it.id != AppState.UserId) {
|
||||||
|
OtherProfileAction(
|
||||||
|
it,
|
||||||
|
onFollow = {
|
||||||
|
onFollowClick()
|
||||||
|
},
|
||||||
|
onChat = {
|
||||||
|
onChatClick()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// collapsed bar
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.graphicsLayer {
|
||||||
|
alpha = 1 - state.toolbarState.progress
|
||||||
|
}
|
||||||
|
.onGloballyPositioned {
|
||||||
|
miniToolbarHeight = with(density) {
|
||||||
|
it.size.height.toDp().value.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
StatusBarSpacer()
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier,
|
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
CustomAsyncImage(
|
CustomAsyncImage(
|
||||||
@@ -168,197 +377,65 @@ fun ProfileV3(
|
|||||||
fontWeight = FontWeight.W600,
|
fontWeight = FontWeight.W600,
|
||||||
color = Color.Black
|
color = Color.Black
|
||||||
)
|
)
|
||||||
}
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
}
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.parallax(0.5f)
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(600.dp)
|
|
||||||
.graphicsLayer {
|
|
||||||
// change alpha of Image as the toolbar expands
|
|
||||||
alpha = state.toolbarState.progress
|
|
||||||
}.verticalScroll(toolbarScrollState)
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
) {
|
|
||||||
// banner
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
|
||||||
.height(bannerHeight.dp)
|
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.padding(16.dp)
|
||||||
.let {
|
) {
|
||||||
if (isSelf) {
|
Icon(
|
||||||
it.noRippleClickable {
|
painter = painterResource(id = R.drawable.rider_pro_more_horizon),
|
||||||
Intent(Intent.ACTION_PICK).apply {
|
contentDescription = "",
|
||||||
type = "image/*"
|
modifier = Modifier.noRippleClickable {
|
||||||
pickBannerImageLauncher.launch(this)
|
minibarExpanded = true
|
||||||
|
},
|
||||||
|
tint = Color.Black
|
||||||
|
)
|
||||||
|
}
|
||||||
|
DropdownMenu(
|
||||||
|
expanded = minibarExpanded,
|
||||||
|
onDismissRequest = { minibarExpanded = false },
|
||||||
|
width = 250,
|
||||||
|
menuItems = listOf(
|
||||||
|
MenuItem(
|
||||||
|
stringResource(R.string.logout),
|
||||||
|
R.mipmap.rider_pro_logout
|
||||||
|
) {
|
||||||
|
minibarExpanded = false
|
||||||
|
scope.launch {
|
||||||
|
onLogout()
|
||||||
|
navController.navigate(NavigationRoute.Login.route) {
|
||||||
|
popUpTo(NavigationRoute.Index.route) {
|
||||||
|
inclusive = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
it
|
},
|
||||||
|
MenuItem(
|
||||||
|
stringResource(R.string.change_password),
|
||||||
|
R.mipmap.rider_pro_change_password
|
||||||
|
) {
|
||||||
|
minibarExpanded = false
|
||||||
|
scope.launch {
|
||||||
|
navController.navigate(NavigationRoute.ChangePasswordScreen.route)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MenuItem(
|
||||||
|
stringResource(R.string.favourites),
|
||||||
|
R.drawable.rider_pro_favourite
|
||||||
|
) {
|
||||||
|
minibarExpanded = false
|
||||||
|
scope.launch {
|
||||||
|
navController.navigate(NavigationRoute.FavouriteList.route)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.shadow(
|
)
|
||||||
elevation = 6.dp,
|
)
|
||||||
shape = RoundedCornerShape(
|
|
||||||
bottomStart = 32.dp,
|
|
||||||
bottomEnd = 32.dp
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
val banner = profile?.banner
|
|
||||||
|
|
||||||
if (banner != null) {
|
|
||||||
CustomAsyncImage(
|
|
||||||
LocalContext.current,
|
|
||||||
banner,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize(),
|
|
||||||
contentDescription = "",
|
|
||||||
contentScale = ContentScale.Crop
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Image(
|
|
||||||
painter = painterResource(id = R.drawable.rider_pro_moment_demo_2),
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize(),
|
|
||||||
contentDescription = "",
|
|
||||||
contentScale = ContentScale.Crop
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isSelf) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.TopEnd)
|
|
||||||
.padding(
|
|
||||||
top = statusBarPaddingValues.calculateTopPadding(),
|
|
||||||
start = 8.dp,
|
|
||||||
end = 8.dp
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(16.dp)
|
|
||||||
.clip(RoundedCornerShape(8.dp))
|
|
||||||
.shadow(
|
|
||||||
elevation = 20.dp
|
|
||||||
)
|
|
||||||
.background(Color.White.copy(alpha = 0.7f))
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(id = R.drawable.rider_pro_more_horizon),
|
|
||||||
contentDescription = "",
|
|
||||||
modifier = Modifier.noRippleClickable {
|
|
||||||
expanded = true
|
|
||||||
},
|
|
||||||
tint = Color.Black
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
DropdownMenu(
|
|
||||||
expanded = expanded,
|
|
||||||
onDismissRequest = { expanded = false },
|
|
||||||
width = 250,
|
|
||||||
menuItems = listOf(
|
|
||||||
MenuItem(
|
|
||||||
stringResource(R.string.logout),
|
|
||||||
R.mipmap.rider_pro_logout
|
|
||||||
) {
|
|
||||||
expanded = false
|
|
||||||
scope.launch {
|
|
||||||
onLogout()
|
|
||||||
navController.navigate(NavigationRoute.Login.route) {
|
|
||||||
popUpTo(NavigationRoute.Index.route) {
|
|
||||||
inclusive = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MenuItem(
|
|
||||||
stringResource(R.string.change_password),
|
|
||||||
R.mipmap.rider_pro_change_password
|
|
||||||
) {
|
|
||||||
expanded = false
|
|
||||||
scope.launch {
|
|
||||||
navController.navigate(NavigationRoute.ChangePasswordScreen.route)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MenuItem(
|
|
||||||
stringResource(R.string.favourites),
|
|
||||||
R.drawable.rider_pro_favourite
|
|
||||||
) {
|
|
||||||
expanded = false
|
|
||||||
scope.launch {
|
|
||||||
navController.navigate(NavigationRoute.FavouriteList.route)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Box(
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
|
||||||
) {
|
|
||||||
// user info
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
) {
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
// 个人信息
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.padding(horizontal = 16.dp)
|
|
||||||
) {
|
|
||||||
profile?.let {
|
|
||||||
UserItem(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
profile?.let {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.padding(horizontal = 16.dp)
|
|
||||||
) {
|
|
||||||
if (isSelf) {
|
|
||||||
SelfProfileAction {
|
|
||||||
navController.navigate(NavigationRoute.AccountEdit.route)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (it.id != AppState.UserId) {
|
|
||||||
OtherProfileAction(
|
|
||||||
it,
|
|
||||||
onFollow = {
|
|
||||||
onFollowClick()
|
|
||||||
},
|
|
||||||
onChat = {
|
|
||||||
onChatClick()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// collapsed bar
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
|||||||
Reference in New Issue
Block a user