“我的”页面UI调整

This commit is contained in:
2025-10-16 18:06:24 +08:00
parent a99ab30c4e
commit 29490d288b

View File

@@ -98,7 +98,7 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.io.File import java.io.File
import androidx.compose.foundation.rememberScrollState
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class) @OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class)
@Composable @Composable
fun ProfileV3( fun ProfileV3(
@@ -119,7 +119,6 @@ fun ProfileV3(
postCount: Int? = null, // 新增参数用于传递帖子总数 postCount: Int? = null, // 新增参数用于传递帖子总数
) { ) {
val model = MyProfileViewModel val model = MyProfileViewModel
val state = rememberCollapsingToolbarScaffoldState()
val pagerState = rememberPagerState(pageCount = { if (isAiAccount) 1 else 2 }) val pagerState = rememberPagerState(pageCount = { if (isAiAccount) 1 else 2 })
val enabled by remember { mutableStateOf(true) } val enabled by remember { mutableStateOf(true) }
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues() val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
@@ -151,6 +150,15 @@ fun ProfileV3(
val systemUiController = rememberSystemUiController() val systemUiController = rememberSystemUiController()
val listState = rememberLazyListState() val listState = rememberLazyListState()
val gridState = rememberLazyGridState() val gridState = rememberLazyGridState()
val scrollState = rememberScrollState()
val toolbarAlpha by remember {
derivedStateOf {
val maxScroll = 500f // 最大滚动距离,可调整
val progress = (scrollState.value.coerceAtMost(maxScroll.toInt()) / maxScroll).coerceIn(0f, 1f)
progress
}
}
// observe list scrolling // observe list scrolling
val reachedListBottom by remember { val reachedListBottom by remember {
@@ -201,8 +209,6 @@ fun ProfileV3(
} }
} }
fun switchTheme() { fun switchTheme() {
// delay // delay
scope.launch { scope.launch {
@@ -281,298 +287,151 @@ fun ProfileV3(
Box( Box(
modifier = Modifier.pullRefresh(refreshState) modifier = Modifier.pullRefresh(refreshState)
) { ) {
CollapsingToolbarScaffold( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.background(AppColors.profileBackground), .verticalScroll(scrollState)
state = state, .background(AppColors.profileBackground)
scrollStrategy = ScrollStrategy.ExitUntilCollapsed, ) {
toolbarScrollable = true, // Banner
enabled = enabled, val banner = profile?.banner
toolbar = { toolbarScrollState -> if (banner != null) {
Column(
modifier = Modifier
.fillMaxWidth()
.height(miniToolbarHeight.dp)
// 保持在最低高度和当前高度之间
.background(AppColors.profileBackground)
) {
}
// header
Box( Box(
modifier = Modifier modifier = Modifier
.parallax(0.5f)
.fillMaxWidth() .fillMaxWidth()
.height(if (isAiAccount) 600.dp else 700.dp) .height(bannerHeight.dp)
.background(AppColors.profileBackground) .background(AppColors.profileBackground)
.verticalScroll(toolbarScrollState)
) { ) {
Box( Box(
modifier = Modifier.fillMaxSize()
) {
Column(
modifier = Modifier
.fillMaxWidth()
.graphicsLayer {
alpha = state.toolbarState.progress
}
) {
// banner
val banner = profile?.banner
if (banner != null) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(bannerHeight.dp)
.background(AppColors.profileBackground)
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(bannerHeight.dp - 24.dp)
.let {
if (isSelf&&isMain) {
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
),
)
) {
CustomAsyncImage(
LocalContext.current,
banner,
modifier = Modifier
.fillMaxSize(),
contentDescription = "",
contentScale = ContentScale.Crop
)
}
}
}else {
Spacer(modifier = Modifier.height(100.dp))
}
Box(
modifier = Modifier
.fillMaxWidth()
.background(AppColors.profileBackground)
) {
// user info
Column(
modifier = Modifier
.fillMaxWidth()
) {
// Spacer(modifier = Modifier.height(16.dp))
// 个人信息
Box(
modifier = Modifier.padding(horizontal = 16.dp)
) {
profile?.let {
UserItem(
accountProfileEntity = it,
postCount = postCount ?: if (isSelf) MyProfileViewModel.momentLoader.total else moments.size
)
}
}
Spacer(modifier = Modifier.height(20.dp))
profile?.let {
Box(
modifier = Modifier.padding(horizontal = 16.dp)
) {
if (isSelf) {
SelfProfileAction(
onEditProfile = {
navController.navigate(
NavigationRoute.AccountEdit.route
)
},
onPremiumClick = {
navController.navigate(NavigationRoute.VipSelPage.route)
}
)
} else {
if (it.id != AppState.UserId) {
OtherProfileAction(
it,
onFollow = {
onFollowClick()
},
onChat = {
onChatClick()
}
)
}
}
}
}
// 添加用户智能体行(智能体用户不显示)
if (!isAiAccount) {
UserAgentsRow(
userId = if (isSelf) null else profile?.id,
modifier = Modifier.padding(top = 16.dp),
onMoreClick = {
// 导航到智能体列表页面
// TODO: 实现导航逻辑
},
onAgentClick = { agent ->
// 导航到智能体详情页面
// TODO: 实现导航逻辑
},
onAvatarClick = { agent ->
// 导航到智能体个人主页
scope.launch {
try {
val userService = com.aiosman.ravenow.data.UserServiceImpl()
val profile = userService.getUserProfileByOpenId(agent.openId)
navController.navigate(
NavigationRoute.AccountProfile.route
.replace("{id}", profile.id.toString())
.replace("{isAiAccount}", "true")
)
} catch (e: Exception) {
// 处理错误
}
}
},
onAgentLongClick = { agent ->
Log.d("ProfileV3", "onAgentLongClick called for agent: ${agent.title}, isSelf: $isSelf")
if (isSelf) { // 只有自己的智能体才能长按
Log.d("ProfileV3", "Setting contextAgent and showing menu")
contextAgent = agent
showAgentMenu = true
}
}
)
}
}
}
}
}
}
//顶部导航栏
Box(modifier = Modifier.fillMaxWidth()) {
Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.graphicsLayer { .height(bannerHeight.dp - 24.dp)
alpha = 1 - state.toolbarState.progress .let {
} if (isSelf && isMain) {
.background(AppColors.profileBackground) it.noRippleClickable {
.onGloballyPositioned { Intent(Intent.ACTION_PICK).apply {
miniToolbarHeight = with(density) { type = "image/*"
it.size.height.toDp().value.toInt() pickBannerImageLauncher.launch(this)
}
}
} else {
it
} }
} }
.shadow(
elevation = 6.dp,
shape = RoundedCornerShape(
bottomStart = 32.dp,
bottomEnd = 32.dp
),
)
) { ) {
StatusBarSpacer() CustomAsyncImage(
Row( LocalContext.current,
modifier = Modifier.padding( banner,
horizontal = 16.dp, modifier = Modifier.fillMaxSize(),
vertical = 8.dp, contentDescription = "",
).noRippleClickable { contentScale = ContentScale.Crop
)
},
verticalAlignment = Alignment.CenterVertically
) {
if (!isMain) {
Image(
painter = painterResource(id = R.drawable.rider_pro_back_icon), // Replace with your image resource
contentDescription = "Back",
modifier = Modifier
.noRippleClickable {
navController.navigateUp()
}
.size(24.dp),
colorFilter = ColorFilter.tint(AppColors.text)
)
Spacer(modifier = Modifier.width(8.dp))
CustomAsyncImage(
LocalContext.current,
profile?.avatar,
modifier = Modifier
.size(32.dp)
.clip(CircleShape),
contentDescription = "",
contentScale = ContentScale.Crop
)
Spacer(modifier = Modifier.width(16.dp))
Text(
text = profile?.nickName ?: "",
fontSize = 16.sp,
fontWeight = FontWeight.W600,
color = AppColors.text
)
}
Spacer(modifier = Modifier.weight(1f))
if (isSelf&&isMain) {
Box(
modifier = Modifier
.size(24.dp)
.padding(16.dp)
)
}
}
Spacer(modifier = Modifier.height(8.dp))
} }
if (isSelf&&isMain) { }
Box( } else {
modifier = Modifier Spacer(modifier = Modifier.height(100.dp))
.align(Alignment.TopEnd) }
.padding(
top = 32.dp ,
end = 16.dp
)
.noRippleClickable {
IndexViewModel.openDrawer = true
}
) {
Box(
modifier = Modifier
.padding(16.dp)
) { // 用户信息
Icon( Box(
painter = painterResource(id = R.drawable.rider_pro_more_horizon), modifier = Modifier
contentDescription = "", .fillMaxWidth()
tint = AppColors.text .background(AppColors.profileBackground)
) .padding(horizontal = 16.dp)
} ) {
profile?.let {
UserItem(
accountProfileEntity = it,
postCount = postCount ?: if (isSelf) MyProfileViewModel.momentLoader.total else moments.size
)
}
}
Spacer(modifier = Modifier.height(20.dp))
// 操作按钮
profile?.let {
Box(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
) {
if (isSelf) {
SelfProfileAction(
onEditProfile = {
navController.navigate(NavigationRoute.AccountEdit.route)
},
onPremiumClick = {
navController.navigate(NavigationRoute.VipSelPage.route)
}
)
} else {
if (it.id != AppState.UserId) {
OtherProfileAction(
it,
onFollow = {
onFollowClick()
},
onChat = {
onChatClick()
}
)
} }
} }
} }
} }
) {
// 用户智能体行
if (!isAiAccount) {
UserAgentsRow(
userId = if (isSelf) null else profile?.id,
modifier = Modifier.padding(top = 16.dp),
onMoreClick = {
// 导航到智能体列表页面
},
onAgentClick = { agent ->
// 导航到智能体详情页面
},
onAvatarClick = { agent ->
// 导航到智能体个人主页
scope.launch {
try {
val userService = com.aiosman.ravenow.data.UserServiceImpl()
val profile = userService.getUserProfileByOpenId(agent.openId)
navController.navigate(
NavigationRoute.AccountProfile.route
.replace("{id}", profile.id.toString())
.replace("{isAiAccount}", "true")
)
} catch (e: Exception) {
// 处理错误
}
}
},
onAgentLongClick = { agent ->
Log.d("ProfileV3", "onAgentLongClick called for agent: ${agent.title}, isSelf: $isSelf")
if (isSelf) { // 只有自己的智能体才能长按
Log.d("ProfileV3", "Setting contextAgent and showing menu")
contextAgent = agent
showAgentMenu = true
}
}
)
}
// 内容
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxWidth()
.background(AppColors.profileBackground) .background(AppColors.profileBackground)
.padding(top = 8.dp)
) { ) {
UserContentPageIndicator( UserContentPageIndicator(
pagerState = pagerState, pagerState = pagerState,
@@ -581,6 +440,7 @@ fun ProfileV3(
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
HorizontalPager( HorizontalPager(
state = pagerState, state = pagerState,
modifier = Modifier.height(500.dp) // 固定滚动高度
) { idx -> ) { idx ->
when (idx) { when (idx) {
0 -> 0 ->
@@ -610,15 +470,116 @@ fun ProfileV3(
} }
} }
} }
} }
// 顶部导航栏
TopNavigationBar(
isMain = isMain,
isSelf = isSelf,
profile = profile,
navController = navController,
alpha = toolbarAlpha
)
PullRefreshIndicator( PullRefreshIndicator(
model.refreshing, model.refreshing,
refreshState, refreshState,
Modifier.align(Alignment.TopCenter) Modifier.align(Alignment.TopCenter)
) )
} }
}
//顶部导航栏组件
@Composable
fun TopNavigationBar(
isMain: Boolean,
isSelf: Boolean,
profile: AccountProfileEntity?,
navController: androidx.navigation.NavController,
alpha: Float
) {
val appColors = LocalAppTheme.current
Box(
modifier = Modifier
.fillMaxWidth()
.graphicsLayer { this.alpha = alpha } // 应用透明度
) {
Column(
modifier = Modifier
.fillMaxWidth()
.background(appColors.profileBackground)
) {
StatusBarSpacer()
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp)
.noRippleClickable {
},
verticalAlignment = Alignment.CenterVertically
) {
if (!isMain) {
Image(
painter = painterResource(id = R.drawable.rider_pro_back_icon),
contentDescription = "Back",
modifier = Modifier
.noRippleClickable {
navController.navigateUp()
}
.size(24.dp),
colorFilter = ColorFilter.tint(appColors.text)
)
Spacer(modifier = Modifier.width(8.dp))
CustomAsyncImage(
LocalContext.current,
profile?.avatar,
modifier = Modifier
.size(32.dp)
.clip(CircleShape),
contentDescription = "",
contentScale = ContentScale.Crop
)
Spacer(modifier = Modifier.width(16.dp))
Text(
text = profile?.nickName ?: "",
fontSize = 16.sp,
fontWeight = FontWeight.W600,
color = appColors.text
)
}
Spacer(modifier = Modifier.weight(1f))
if (isSelf && isMain) {
Box(
modifier = Modifier
.size(24.dp)
.padding(16.dp)
)
}
}
Spacer(modifier = Modifier.height(8.dp))
}
if (isSelf && isMain) {
Box(
modifier = Modifier
.align(Alignment.TopEnd)
.padding(top = 32.dp, end = 16.dp)
.noRippleClickable {
IndexViewModel.openDrawer = true
}
) {
Box(
modifier = Modifier.padding(16.dp)
) {
Icon(
painter = painterResource(id = R.drawable.rider_pro_more_horizon),
contentDescription = "",
tint = appColors.text
)
}
}
}
}
} }
/** /**