Merge pull request #82 from Kevinlinpr/zhong_1

UI调整
This commit is contained in:
2025-11-18 21:46:08 +08:00
committed by GitHub
22 changed files with 384 additions and 287 deletions

View File

@@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
@@ -34,8 +35,11 @@ import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewModelScope
@@ -565,10 +569,27 @@ fun AddAgentScreen() {
.padding(horizontal = 16.dp)
.align(Alignment.Start)
) {
val density = LocalDensity.current
val textMeasurer = rememberTextMeasurer()
val autoLabel = stringResource(R.string.create_agent_auto)
val measuredTextWidth = remember(autoLabel, textMeasurer) {
textMeasurer.measure(
text = AnnotatedString(autoLabel),
style = TextStyle(
color = appColors.text,
fontWeight = FontWeight.W600,
fontSize = 14.sp
)
).size.width
}
val textWidthDp = with(density) { measuredTextWidth.toDp() }
val contentWidth = 24.dp + 18.dp + 8.dp + textWidthDp
val boxWidth = if (contentWidth > 140.dp) 250.dp else 140.dp
Box(
modifier = Modifier
.align(Alignment.Start)
.width(140.dp)
.width(boxWidth)
.height(40.dp)
.shadow(
elevation = 10.dp,
@@ -616,7 +637,7 @@ fun AddAgentScreen() {
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = stringResource(R.string.create_agent_auto),
text = autoLabel,
color = appColors.text,
fontWeight = FontWeight.W600,
fontSize = 14.sp

View File

@@ -21,6 +21,10 @@ import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.rememberLottieComposition
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -433,10 +437,10 @@ fun AddMemberAiAgentListScreen(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
text = "加载中...",
color = AppColors.secondaryText,
fontSize = 14.sp
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(80.dp)
)
}
} else {
@@ -465,10 +469,10 @@ fun AddMemberAiAgentListScreen(
.padding(16.dp),
contentAlignment = Alignment.Center
) {
Text(
text = "加载更多...",
color = AppColors.secondaryText,
fontSize = 14.sp
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(80.dp)
)
}
}
@@ -533,10 +537,10 @@ fun AddMemberFriendListScreen(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
text = "加载中...",
color = AppColors.secondaryText,
fontSize = 14.sp
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(80.dp)
)
}
} else {
@@ -565,10 +569,10 @@ fun AddMemberFriendListScreen(
.padding(16.dp),
contentAlignment = Alignment.Center
) {
Text(
text = "加载更多...",
color = AppColors.secondaryText,
fontSize = 14.sp
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(80.dp)
)
}
}

View File

@@ -11,6 +11,10 @@ import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.rememberLottieComposition
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -78,10 +82,10 @@ fun AiAgentListScreen(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
text = "加载中...",
color = AppColors.secondaryText,
fontSize = 14.sp
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(80.dp)
)
}
} else {
@@ -111,10 +115,10 @@ fun AiAgentListScreen(
.padding(16.dp),
contentAlignment = Alignment.Center
) {
Text(
text = "加载更多...",
color = AppColors.secondaryText,
fontSize = 14.sp
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(80.dp)
)
}
}

View File

@@ -11,6 +11,10 @@ import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.rememberLottieComposition
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -78,10 +82,10 @@ fun FriendListScreen(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
text = "加载中...",
color = AppColors.secondaryText,
fontSize = 14.sp
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(80.dp)
)
}
} else {
@@ -111,10 +115,10 @@ fun FriendListScreen(
.padding(16.dp),
contentAlignment = Alignment.Center
) {
Text(
text = "加载更多...",
color = AppColors.secondaryText,
fontSize = 14.sp
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(80.dp)
)
}
}

View File

@@ -399,7 +399,7 @@ fun GroupChatInfoScreen(groupId: String) {
)
Spacer(modifier = Modifier.width(10.dp))
Text(
text = "群资料设置",
text = stringResource(R.string.group_chat_info_group_settings),
style = androidx.compose.ui.text.TextStyle(
color = AppColors.text,
fontSize = 15.sp

View File

@@ -41,6 +41,7 @@ import android.widget.Toast
import androidx.compose.ui.graphics.Brush
import com.aiosman.ravenow.ui.composables.CustomAsyncImage
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.stringResource
@Composable
fun GroupMemoryManageContent(
@@ -79,7 +80,7 @@ fun GroupMemoryManageContent(
) {
// 中间标题 - 绝对居中,不受其他组件影响
Text(
text = "记忆管理",
text = stringResource(R.string.group_chat_info_memory_manage2),
style = TextStyle(
color = Color.Black,
fontSize = 17.sp,
@@ -107,7 +108,7 @@ fun GroupMemoryManageContent(
colorFilter = ColorFilter.tint(Color.Black)
)
Text(
text = "返回",
text = stringResource(R.string.back_upper),
style = TextStyle(
color = Color.Black,
fontSize = 15.sp,
@@ -148,7 +149,7 @@ fun GroupMemoryManageContent(
) {
Row(horizontalArrangement = Arrangement.spacedBy(16.dp), verticalAlignment = Alignment.CenterVertically) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text("已付费:", style = TextStyle(color = Color(0x993C3C43), fontSize = 13.sp))
Text(stringResource(R.string.memory_paid), style = TextStyle(color = Color(0x993C3C43), fontSize = 13.sp))
Spacer(Modifier.width(3.dp))
Text(
"${quota?.purchasedCount ?: 0}",
@@ -156,7 +157,7 @@ fun GroupMemoryManageContent(
)
}
Row(verticalAlignment = Alignment.CenterVertically) {
Text("已使用:", style = TextStyle(color = Color(0x993C3C43), fontSize = 13.sp))
Text(stringResource(R.string.memory_used), style = TextStyle(color = Color(0x993C3C43), fontSize = 13.sp))
Spacer(Modifier.width(3.dp))
Text(
"${quota?.currentCount ?: 0}",
@@ -165,7 +166,7 @@ fun GroupMemoryManageContent(
}
}
Row(verticalAlignment = Alignment.CenterVertically) {
Text("可用上限:", style = TextStyle(color = Color(0x993C3C43), fontSize = 13.sp))
Text(stringResource(R.string.upper_limit), style = TextStyle(color = Color(0x993C3C43), fontSize = 13.sp))
Spacer(Modifier.width(3.dp))
Text(
"50",
@@ -235,12 +236,12 @@ fun GroupMemoryManageContent(
Spacer(Modifier.height(10.dp))
Text(
text = "暂无记忆",
text = stringResource(R.string.no_memory),
style = TextStyle(color = Color.Black, fontSize = 16.sp, fontWeight = FontWeight.SemiBold)
)
Spacer(Modifier.height(6.dp))
Text(
text = "点击上方按钮添加群记忆",
text = stringResource(R.string.add_memory),
style = TextStyle(color = Color.Black, fontSize = 14.sp, fontWeight = FontWeight.Normal)
)
}

View File

@@ -70,6 +70,7 @@ import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@@ -574,38 +575,33 @@ fun SideMenuContent(
// 顶部状态栏间距
val statusBarHeight = WindowInsets.systemBars.asPaddingValues().calculateTopPadding()
// 扫一扫功能入口 - 右边距离右边66pt
Row(
modifier = Modifier
.align(Alignment.TopEnd)
.offset(x = (-112).dp, y = 88.dp)
.noRippleClickable {
// 扫一扫功能:跳转到扫码页面
coroutineScope.launch {
onClose()
navController.navigate(NavigationRoute.ScanQr.route)
}
},
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
// 扫一扫图标(使用现有图标或占位)
Image(
painter = painterResource(id = R.mipmap.sao),
contentDescription = null,
modifier = Modifier.size(24.dp),
colorFilter = ColorFilter.tint(iconColor)
)
}
// 绝对定位的"扫一扫"文字上方71.5dp右侧66dp
// 扫一扫功能入口
Row(
modifier = Modifier
.align(Alignment.TopEnd)
.offset(x = (-60).dp, y = 88.dp)
.noRippleClickable {
coroutineScope.launch {
onClose()
navController.navigate(NavigationRoute.ScanQr.route)
}
},
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Image(
painter = painterResource(id = R.mipmap.sao),
contentDescription = null,
modifier = Modifier.size(24.dp),
colorFilter = ColorFilter.tint(iconColor)
)
Text(
text = stringResource(R.string.scan_qr),
fontSize = 14.sp,
color = textColor,
modifier = Modifier
.align(Alignment.TopEnd)
.offset(x = (-66).dp, y = 91.5.dp)
textAlign = TextAlign.Center
)
}
// QR码图标 - 右边距离右边112dp上边距离上边68pt
Image(
painter = painterResource(id = R.mipmap.qr_code_icon),

View File

@@ -91,6 +91,10 @@ import androidx.compose.ui.graphics.Brush
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.ui.platform.LocalConfiguration
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.rememberLottieComposition
// 检测是否接近列表底部的扩展函数
fun LazyListState.isScrolledToEnd(buffer: Int = 3): Boolean {
@@ -382,25 +386,19 @@ fun Agent() {
}
}
// 加载更多指示器(仅在展示发现更多时显示)
// 加载更多指示器(仅在展示"发现更多"时显示)
if (viewModel.isLoadingMore) {
item {
Row(
Box(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 24.dp),
horizontalArrangement = Arrangement.Center
contentAlignment = Alignment.Center
) {
androidx.compose.material3.CircularProgressIndicator(
modifier = Modifier.size(24.dp),
color = AppColors.text,
strokeWidth = 2.dp
)
Spacer(modifier = Modifier.width(12.dp))
androidx.compose.material3.Text(
text = "加载中...",
color = AppColors.secondaryText,
fontSize = 14.sp
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(80.dp)
)
}
}
@@ -920,26 +918,16 @@ fun ChatRoomCard(
modifier = Modifier
.size(120.dp)
.background(
color = AppColors.background,
color = Color.Transparent,
shape = RoundedCornerShape(12.dp)
),
contentAlignment = Alignment.Center
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
CircularProgressIndicator(
modifier = Modifier.size(32.dp),
color = AppColors.main
)
Spacer(modifier = Modifier.height(12.dp))
androidx.compose.material3.Text(
text = "加入中...",
fontSize = 14.sp,
color = AppColors.text
)
}
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(96.dp)
)
}
}
}

View File

@@ -49,6 +49,10 @@ import com.aiosman.ravenow.ui.composables.rememberDebouncer
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
import com.aiosman.ravenow.utils.NetworkUtils
import com.aiosman.ravenow.ui.network.ReloadButton
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.rememberLottieComposition
/**
* 智能体聊天列表页面
@@ -187,9 +191,10 @@ fun AgentChatListScreen() {
.padding(16.dp),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator(
modifier = Modifier.size(24.dp),
color = AppColors.main
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(80.dp)
)
}
}

View File

@@ -35,6 +35,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@@ -212,7 +214,7 @@ fun NewsCommentModal(
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "${currentCommentCount}条评论",
text = stringResource(R.string.comment_count, currentCommentCount),
fontSize = 15.sp,
fontWeight = FontWeight.Bold,
color = AppColors.text
@@ -237,24 +239,53 @@ fun NewsCommentModal(
.fillMaxWidth()
.weight(1f)
) {
LazyColumn {
item {
CommentContent(
viewModel = commentViewModel,
onLongClick = { comment ->
showCommentMenu = true
contextComment = comment
},
onReply = { parentComment, _, _, _ ->
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.COMMENT_MOMENT)) {
debouncedNavigation {
navController.navigate(NavigationRoute.Login.route)
}
} else {
replyComment = parentComment
}
}
val isCommentListEmpty = !commentViewModel.isLoading &&
currentCommentCount == 0 &&
commentViewModel.commentsList.isEmpty() &&
commentViewModel.addedCommentList.isEmpty()
if (isCommentListEmpty) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(bottom = 32.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = painterResource(id = R.mipmap.invalid_name_3),
contentDescription = null,
modifier = Modifier
.width(160.dp)
.height(130.dp)
)
Spacer(modifier = Modifier.height(12.dp))
Text(
text = stringResource(R.string.news_no_comments),
fontSize = 15.sp,
color = AppColors.text
)
}
} else {
LazyColumn {
item {
CommentContent(
viewModel = commentViewModel,
onLongClick = { comment ->
showCommentMenu = true
contextComment = comment
},
onReply = { parentComment, _, _, _ ->
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.COMMENT_MOMENT)) {
debouncedNavigation {
navController.navigate(NavigationRoute.Login.route)
}
} else {
replyComment = parentComment
}
}
)
}
}
}
}

View File

@@ -17,6 +17,7 @@ import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.pager.VerticalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -401,7 +402,7 @@ fun NewsItem(
count = "",
isActive = false,
text = stringResource(R.string.share),
textSize = 8.sp
textSize = 8.sp,
)
}
}
@@ -425,7 +426,7 @@ fun NewsActionButton(
Row(
modifier = modifier
.width(60.dp)
.defaultMinSize(minWidth = 60.dp)
.background(
color = AppColors.secondaryBackground,
shape = RoundedCornerShape(16.dp)
@@ -449,7 +450,8 @@ fun NewsActionButton(
Spacer(modifier = Modifier.width(4.dp))
Text(
text = count,
fontSize = 12.sp,
fontSize = 8.sp,
fontWeight = FontWeight.Bold,
color = AppColors.text
)
}
@@ -458,7 +460,8 @@ fun NewsActionButton(
Text(
text = text,
fontSize = textSize,
color = AppColors.text
color = AppColors.text,
fontWeight = FontWeight.Bold
)
}
}

View File

@@ -6,10 +6,14 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.pager.VerticalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.Text
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.rememberLottieComposition
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -75,17 +79,11 @@ fun RecommendScreen() {
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
CircularProgressIndicator(color = AppColors.main)
Text(
text = "加载中...",
modifier = Modifier.padding(top = 16.dp),
color = AppColors.text,
fontSize = 14.sp
)
}
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(96.dp)
)
}
}

View File

@@ -3,11 +3,13 @@ package com.aiosman.ravenow.ui.index.tabs.moment.tabs.shorts
import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.rememberLottieComposition
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -77,19 +79,11 @@ fun ShortVideoScreen(
.background(AppColors.background),
contentAlignment = Alignment.Center
) {
Column(
modifier = Modifier.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = androidx.compose.foundation.layout.Arrangement.Center
) {
CircularProgressIndicator(color = AppColors.main)
Text(
text = "加载中...",
modifier = Modifier.padding(top = 16.dp),
color = AppColors.text,
fontSize = 14.sp
)
}
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(96.dp)
)
}
}
// 错误状态
@@ -130,10 +124,10 @@ fun ShortVideoScreen(
.background(AppColors.background),
contentAlignment = Alignment.Center
) {
Text(
text = "准备加载...",
color = AppColors.text,
fontSize = 16.sp
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(80.dp)
)
}
}

View File

@@ -25,6 +25,10 @@ import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
import com.airbnb.lottie.compose.rememberLottieComposition
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -184,9 +188,10 @@ fun GroupChatEmptyContent(
.padding(16.dp),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator(
modifier = Modifier.size(24.dp),
color = AppColors.main
LottieAnimation(
composition = rememberLottieComposition(LottieCompositionSpec.Asset("star_Loader.lottie")).value,
iterations = LottieConstants.IterateForever,
modifier = Modifier.size(80.dp)
)
}
}

View File

@@ -10,10 +10,12 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
@@ -102,40 +104,21 @@ fun UserItem(
// 统计数据
Row(
modifier = Modifier.weight(1f),
modifier = Modifier
.weight(1f)
.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(0.dp),
verticalAlignment = Alignment.CenterVertically
) {
// 帖子数
Column(
modifier = Modifier
.width(80.dp)
.height(40.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = postCount.toString(),
fontWeight = FontWeight.Medium,
fontSize = 15.sp,
color = AppColors.text,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(2.dp))
Text(
text = stringResource(R.string.posts),
fontWeight = FontWeight.Normal,
fontSize = 11.sp,
color = AppColors.text,
textAlign = TextAlign.Center
)
}
StatColumn(
modifier = Modifier.weight(1f),
value = postCount.toString(),
label = stringResource(R.string.posts)
)
// 粉丝数
Column(
StatColumn(
modifier = Modifier
.width(80.dp)
.height(40.dp)
.weight(1f)
.noRippleClickable {
followerDebouncer {
navController.navigate(
@@ -146,32 +129,13 @@ fun UserItem(
)
}
},
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = formattedFollowerCount,
fontWeight = FontWeight.Medium,
fontSize = 15.sp,
color = AppColors.text,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(2.dp))
Text(
text = stringResource(R.string.followers_upper),
fontWeight = FontWeight.Normal,
fontSize = 11.sp,
color = AppColors.text,
textAlign = TextAlign.Center
)
}
value = formattedFollowerCount,
label = stringResource(R.string.followers_upper)
)
// 关注数
Column(
StatColumn(
modifier = Modifier
.width(80.dp)
.height(40.dp)
.offset(x = 6.dp)
.weight(1f)
.noRippleClickable {
followingDebouncer {
navController.navigate(
@@ -182,25 +146,9 @@ fun UserItem(
)
}
},
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = accountProfileEntity.followingCount.toString(),
fontWeight = FontWeight.Medium,
fontSize = 15.sp,
color = AppColors.text,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(2.dp))
Text(
text = stringResource(R.string.following_upper),
fontWeight = FontWeight.Normal,
fontSize = 11.sp,
color = AppColors.text,
textAlign = TextAlign.Center
)
}
value = accountProfileEntity.followingCount.toString(),
label = stringResource(R.string.following_upper)
)
}
}
@@ -290,6 +238,38 @@ fun UserItem(
}
}
@Composable
private fun StatColumn(
modifier: Modifier = Modifier,
value: String,
label: String
) {
val AppColors = LocalAppTheme.current
Column(
modifier = modifier
.heightIn(min = 40.dp)
.wrapContentWidth(Alignment.CenterHorizontally),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = value,
fontWeight = FontWeight.Medium,
fontSize = 15.sp,
color = AppColors.text,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(2.dp))
Text(
text = label,
fontWeight = FontWeight.Normal,
fontSize = 11.sp,
color = AppColors.text,
textAlign = TextAlign.Center
)
}
}
@Composable
private fun ProfileTag(
text: String,

View File

@@ -274,14 +274,14 @@ fun HistorySection(
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "历史搜索",
text = stringResource(R.string.recent_search),
color = AppColors.text,
fontSize = 16.sp,
fontWeight = FontWeight.W600
)
Spacer(modifier = Modifier.weight(1f))
Text(
text = "清空",
text = stringResource(R.string.clear),
color = AppColors.secondaryText,
fontSize = 14.sp,
modifier = Modifier.noRippleClickable { onClear() }

View File

@@ -18,6 +18,7 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Divider
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.ModalBottomSheet
@@ -33,7 +34,6 @@ import android.graphics.BitmapFactory
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
@@ -112,7 +112,7 @@ fun DraftBoxBottomSheet(
contentAlignment = Alignment.Center
) {
Text(
text = "暂无草稿",
text = stringResource(R.string.no_drafts),
fontSize = 16.sp,
color = AppColors.secondaryText
)
@@ -122,7 +122,7 @@ fun DraftBoxBottomSheet(
modifier = Modifier
.fillMaxWidth()
.weight(1f),
verticalArrangement = Arrangement.spacedBy(12.dp)
verticalArrangement = Arrangement.spacedBy(0.dp)
) {
itemsIndexed(drafts) { index, draft ->
DraftItem(
@@ -141,12 +141,22 @@ fun DraftBoxBottomSheet(
AppColors = AppColors,
context = context
)
// 在草稿项之间添加分割线(最后一个不添加)
if (index < drafts.size - 1) {
Spacer(modifier = Modifier.height(12.dp))
Divider(
color = AppColors.secondaryText.copy(alpha = 0.2f),
thickness = 0.5.dp,
modifier = Modifier.padding(horizontal = 16.dp)
)
Spacer(modifier = Modifier.height(12.dp))
}
}
}
// 底部提示
Text(
text = "仅保存最近5个草稿",
text = stringResource(R.string.only_save_the_last_5_drafts),
fontSize = 12.sp,
color = AppColors.secondaryText,
modifier = Modifier
@@ -172,7 +182,7 @@ private fun DraftItem(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(12.dp))
.background(Color.White)
.background(AppColors.secondaryBackground)
.padding(12.dp)
) {
Column {
@@ -206,7 +216,8 @@ private fun DraftItem(
DraftImageThumbnail(
imageItem = imageItem,
context = context,
modifier = Modifier.size(55.dp)
modifier = Modifier.size(55.dp),
AppColors = AppColors
)
}
@@ -216,7 +227,7 @@ private fun DraftItem(
modifier = Modifier
.size(55.dp)
.clip(RoundedCornerShape(12.dp))
.background(Color(0xFFFAF9FB)),
.background(AppColors.inputBackground),
contentAlignment = Alignment.Center
) {
Text(
@@ -250,7 +261,7 @@ private fun DraftItem(
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.rider_pro_moment_apply),
painter = painterResource(id = R.mipmap.icons_infor_edit),
contentDescription = "edit",
modifier = Modifier.size(16.dp),
tint = AppColors.text
@@ -297,12 +308,13 @@ private fun DraftItem(
private fun DraftImageThumbnail(
imageItem: DraftImageItem,
context: android.content.Context,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
AppColors: AppThemeData
) {
Box(
modifier = modifier
.clip(RoundedCornerShape(12.dp))
.background(Color(0xFFFAF9FB))
) {
val file = File(context.cacheDir, imageItem.filename)
if (file.exists()) {
@@ -338,7 +350,7 @@ private fun DraftImageThumbnail(
painter = painterResource(id = R.drawable.rider_pro_new_post_add_pic),
contentDescription = "image",
modifier = Modifier.size(24.dp),
tint = Color.Gray
tint = AppColors.secondaryText
)
}
}

View File

@@ -221,7 +221,7 @@ fun NewPostScreen() {
e.printStackTrace()
Toast.makeText(
context,
"文案优化失败:${e.message ?: "请稍后重试"}",
"${e.message ?: "请稍后重试"}",
Toast.LENGTH_SHORT
).show()
} finally {
@@ -345,16 +345,18 @@ fun NewPostScreen() {
// 底部背景图
if (isRequesting) {
Image(
painter = painterResource(id = R.mipmap.component),
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.height(400.dp)
.align(Alignment.BottomStart)
.offset(y = (-40).dp),
contentScale = ContentScale.FillBounds
)
if (!AppState.darkMode) {
Image(
painter = painterResource(id = R.mipmap.component),
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.height(400.dp)
.align(Alignment.BottomStart)
.offset(y = (-40).dp),
contentScale = ContentScale.FillBounds
)
}
// 加载动画显示在背景图上方按钮下方80dp区域
Box(

View File

@@ -106,6 +106,11 @@ data class Draft(
val createdAt: Long = System.currentTimeMillis()
)
object NewPostViewModel : ViewModel() {
private data class DraftSnapshot(
val textContent: String,
val images: List<DraftImageItem>
)
var momentService: MomentService = MomentServiceImpl()
var textContent by mutableStateOf("")
var aiTextContent by mutableStateOf("")
@@ -117,6 +122,7 @@ object NewPostViewModel : ViewModel() {
var currentPhotoUri: Uri? = null
var draft: Draft? = null
private var draftSaved = false // 标记草稿是否已保存,避免重复保存
private var lastLoadedDraftSnapshot: DraftSnapshot? = null
// watch textContent change and save draft
// fun saveDraft() {
// draft = Draft(textContent, imageList.map {
@@ -131,6 +137,7 @@ object NewPostViewModel : ViewModel() {
imageList = listOf()
relPostId = null
draftSaved = false // 重置保存标志
lastLoadedDraftSnapshot = null
}
fun asNewPostWithImageUris(imageUris: List<String>) {
@@ -213,14 +220,25 @@ object NewPostViewModel : ViewModel() {
if (draftSaved) {
return
}
val currentSnapshot = DraftSnapshot(
textContent = textContent,
images = imageList.map { DraftImageItem.fromImageItem(it) }
)
if (lastLoadedDraftSnapshot == currentSnapshot) {
draftSaved = true
return
}
val draftStore = DraftStore(context)
val draft = Draft(
textContent = textContent,
imageList = imageList.map { DraftImageItem.fromImageItem(it) }
textContent = currentSnapshot.textContent,
imageList = currentSnapshot.images
)
draftStore.saveDraft(draft)
draftSaved = true // 标记已保存
lastLoadedDraftSnapshot = currentSnapshot
}
/**
@@ -230,6 +248,10 @@ object NewPostViewModel : ViewModel() {
textContent = draft.textContent
aiTextContent = ""
draftSaved = false // 加载草稿后重置保存标志,允许重新保存
lastLoadedDraftSnapshot = DraftSnapshot(
textContent = draft.textContent,
images = draft.imageList
)
// 从草稿的图片URI恢复图片列表
imageList = withContext(Dispatchers.IO) {

View File

@@ -210,7 +210,16 @@
<string name="text_error_password_too_long">パスワードは%1$d文字を超えることはできません</string>
<string name="block">ブロック</string>
<string name="read_full_article">全文を読む</string>
<string name="news_no_comments">まだ誰もノックしてないよ</string>
<string name="drafts">ドラフトボックス</string>
<string name="no_drafts">草稿はしばらくありません</string>
<string name="only_save_the_last_5_drafts">最後の5つのドラフトのみ保存</string>
<string name="memory_paid">支払い済み:</string>
<string name="memory_used">使用済み:</string>
<string name="upper_limit">利用可能上限:</string>
<string name="no_memory">記憶がありません</string>
<string name="add_memory">上部のボタンをクリックしてグループ記憶を追加してください</string>
<string name="recent_search">けんさくりれき</string>
<!-- Create Bottom Sheet -->
<string name="create_title">作成</string>
@@ -274,6 +283,7 @@
<string name="group_chat_info_memory_description">AIは記憶に基づいてグループチャットであなたをより理解します</string>
<string name="group_chat_info_add_memory">メモリを追加</string>
<string name="group_chat_info_memory_manage">メモリ管理</string>
<string name="group_chat_info_memory_manage2">メモリ管理</string>
<string name="group_chat_info_group_settings">グループ設定</string>
<string name="group_chat_info_group_visibility">グループの可視性</string>
<string name="group_chat_info_locked">ロック中</string>

View File

@@ -70,7 +70,11 @@
<string name="new_password_tip1">请输入新密码</string>
<string name="confirm_new_password">确认新密码</string>
<string name="confirm_new_password_tip1">请确认新密码</string>
<string name="memory_paid">已付费:</string>
<string name="memory_used">已使用:</string>
<string name="upper_limit">可用上限:</string>
<string name="no_memory">暂无记忆</string>
<string name="add_memory">点击上方按钮添加群记忆</string>
<string name="cancel">取消</string>
<string name="bio">个性签名</string>
@@ -213,7 +217,11 @@
<string name="chatting_now">人正在热聊…</string>
<string name="block">拉黑</string>
<string name="read_full_article">查看全文</string>
<string name="news_no_comments">还没有人敲门</string>
<string name="drafts">草稿箱</string>
<string name="no_drafts">暂无草稿</string>
<string name="only_save_the_last_5_drafts">仅保存最近5个草稿</string>
<string name="recent_search">历史搜索</string>
<!-- Create Bottom Sheet -->
<string name="create_title">创建</string>
@@ -277,6 +285,7 @@
<string name="group_chat_info_memory_description">AI 会根据记忆在群聊里更懂你</string>
<string name="group_chat_info_add_memory">添加记忆</string>
<string name="group_chat_info_memory_manage">记忆管理</string>
<string name="group_chat_info_memory_manage2">记忆管理</string>
<string name="group_chat_info_group_settings">群资料设置</string>
<string name="group_chat_info_group_visibility">群可见性</string>
<string name="group_chat_info_locked">待解锁</string>
@@ -367,21 +376,6 @@
<string name="complete_tasks_desc">完成任务可获得奖励</string>
<string name="recharge_pai_coin">充值派币</string>
<string name="recharge_pai_coin_desc">多种套餐可选,立即充值</string>
<!-- Transaction History Reasons -->
<string name="earn_register">新用户注册奖励</string>
<string name="earn_daily">每日签到奖励</string>
<string name="earn_task">任务完成奖励</string>
<string name="earn_invite">邀请好友奖励</string>
<string name="earn_recharge">充值获得</string>
<string name="spend_group_create">创建群聊</string>
<string name="spend_group_expand">扩容群聊</string>
<string name="spend_agent_private">Agent 私密模式</string>
<string name="spend_agent_memory">Agent 记忆添加</string>
<string name="spend_room_memory">房间记忆添加</string>
<string name="spend_chat_background">自定义聊天背景</string>
<string name="spend_schedule_event">定时事件解锁</string>
<string name="create_group_chat_failed">创建群聊失败: %1$s</string>
<string name="create_group_chat_confirm_title">创建群聊确认</string>
<string name="create_group_chat_required_cost">需要消耗:</string>
@@ -401,6 +395,20 @@
<string name="explore">去探索</string>
<string name="reply_to_user">回复@%1$s</string>
<string name="error_select_at_least_one_image">请至少选择一张图片</string>
<!-- Transaction History Reasons -->
<string name="earn_register">新用户注册奖励</string>
<string name="earn_daily">每日签到奖励</string>
<string name="earn_task">任务完成奖励</string>
<string name="earn_invite">好友邀请奖励</string>
<string name="earn_recharge">充值</string>
<string name="spend_group_create">群聊创建</string>
<string name="spend_group_expand">群聊扩展</string>
<string name="spend_agent_private">智能体私密模式</string>
<string name="spend_agent_memory">智能体记忆添加</string>
<string name="spend_room_memory">房间记忆添加</string>
<string name="spend_chat_background">自定义聊天背景</string>
<string name="spend_schedule_event">日程事件解锁</string>
<string name="awaiting_traveler">等一位旅人~</string>
<string name="no_one_pinged_yet">还没有人来打扰你</string>
<string name="cosmos_awaits">小宇宙等你探索。</string>

View File

@@ -209,7 +209,16 @@
<string name="text_error_password_too_long">Password cannot exceed %1$d characters</string>
<string name="block">Block</string>
<string name="read_full_article">Read full article</string>
<string name="news_no_comments">No ones knocked yet</string>
<string name="drafts">drafts</string>
<string name="no_drafts">No draft</string>
<string name="only_save_the_last_5_drafts">Only save the last 5 drafts</string>
<string name="memory_paid">Paid:</string>
<string name="memory_used">Used:</string>
<string name="upper_limit">Available Limit:</string>
<string name="no_memory">No memory yet</string>
<string name="add_memory">Click the button above to add group memory</string>
<string name="recent_search">Recent Search</string>
<!-- Create Bottom Sheet -->
<string name="create_title">Create</string>
@@ -273,6 +282,7 @@
<string name="group_chat_info_memory_description">AI will understand you better in group chat based on memory</string>
<string name="group_chat_info_add_memory">Add Memory</string>
<string name="group_chat_info_memory_manage">Memory Management</string>
<string name="group_chat_info_memory_manage2">Memory</string>
<string name="group_chat_info_group_settings">Group Settings</string>
<string name="group_chat_info_group_visibility">Group Visibility</string>
<string name="group_chat_info_locked">Locked</string>
@@ -361,21 +371,6 @@
<string name="complete_tasks_desc">Complete tasks to earn rewards</string>
<string name="recharge_pai_coin">Recharge Pai Coin</string>
<string name="recharge_pai_coin_desc">Multiple packages available, recharge now</string>
<!-- Transaction History Reasons -->
<string name="earn_register">New User Registration Reward</string>
<string name="earn_daily">Daily Check-in Reward</string>
<string name="earn_task">Task Completion Reward</string>
<string name="earn_invite">Invite Friends Reward</string>
<string name="earn_recharge">Recharge</string>
<string name="spend_group_create">Create Group Chat</string>
<string name="spend_group_expand">Expand Group Chat</string>
<string name="spend_agent_private">Agent Private Mode</string>
<string name="spend_agent_memory">Agent Memory Added</string>
<string name="spend_room_memory">Room Memory Added</string>
<string name="spend_chat_background">Custom Chat Background</string>
<string name="spend_schedule_event">Scheduled Event Unlocked</string>
<string name="create_group_chat_failed">Failed to create group chat: %1$s</string>
<string name="create_group_chat_confirm_title">Create Group Chat</string>
<string name="create_group_chat_required_cost">Required consumption:</string>
@@ -395,6 +390,20 @@
<string name="explore">Explore</string>
<string name="reply_to_user">Reply @%1$s</string>
<string name="error_select_at_least_one_image">Please select at least one image</string>
<!-- Transaction History Reasons -->
<string name="earn_register">New User Registration Reward</string>
<string name="earn_daily">Daily Check-in Reward</string>
<string name="earn_task">Task Completion Reward</string>
<string name="earn_invite">Friend Invitation Reward</string>
<string name="earn_recharge">Recharge</string>
<string name="spend_group_create">Group Chat Creation</string>
<string name="spend_group_expand">Group Chat Expansion</string>
<string name="spend_agent_private">Agent Private Mode</string>
<string name="spend_agent_memory">Agent Memory Addition</string>
<string name="spend_room_memory">Room Memory Addition</string>
<string name="spend_chat_background">Custom Chat Background</string>
<string name="spend_schedule_event">Schedule Event Unlock</string>
<string name="awaiting_traveler">Awaiting a traveler</string>
<string name="no_one_pinged_yet">No one has pinged you yet</string>
<string name="cosmos_awaits">Your cosmos awaits.</string>