refactor: 优化前端功能屏幕

- 优化ConversationListScreen对话列表页面
- 优化CreateMemoryScreen创建回忆页面
- 优化MyMemoirScreen我的回忆录页面
- 优化ProfileScreen个人资料页面
- 优化ExportDataScreen导出数据页面
- 优化AboutScreen关于页面
This commit is contained in:
iammm0
2026-01-23 14:02:50 +08:00
parent 26247c3427
commit 2592143789
6 changed files with 459 additions and 227 deletions

View File

@@ -160,7 +160,7 @@ fun AboutScreen(
// 版权信息
Text(
text = "© 2024 Life Echo. All rights reserved.",
text = "© 2026 Life Echo. All rights reserved.",
fontSize = 14.sp,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(top = 16.dp)

View File

@@ -1,22 +1,26 @@
package com.huaga.life_echo.ui.screens
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.huaga.life_echo.data.database.Conversation
import com.huaga.life_echo.network.models.ConversationListItemDto
import com.huaga.life_echo.ui.components.common.EmptyStateView
import com.huaga.life_echo.ui.components.common.LoadingIndicator
@@ -24,6 +28,7 @@ import com.huaga.life_echo.ui.components.conversation.ConversationListHeader
import com.huaga.life_echo.ui.components.conversation.ConversationListItem
import com.huaga.life_echo.ui.viewmodel.ConversationListViewModel
import com.huaga.life_echo.ui.viewmodel.ViewModelFactory
import kotlinx.coroutines.launch
@Composable
fun ConversationListScreen(
@@ -41,11 +46,26 @@ fun ConversationListScreen(
viewModel.refreshConversations()
}
val scope = rememberCoroutineScope()
// 处理新建对话
val handleCreateConversation: () -> Unit = {
scope.launch {
val result = viewModel.createConversation()
result.fold(
onSuccess = { conversationId ->
onConversationClick(conversationId)
},
onFailure = { exception ->
// 错误处理可以在这里添加
}
)
}
}
Column(
modifier = Modifier.fillMaxSize()
) {
// 使用新的头部组件
ConversationListHeader()
// 对话列表区域
Column(
@@ -53,6 +73,7 @@ fun ConversationListScreen(
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
) {
ConversationListHeader(onCreateConversation = handleCreateConversation)
Text(
text = "我的对话",
modifier = Modifier.padding(16.dp, 16.dp, 16.dp, 8.dp),
@@ -66,12 +87,20 @@ fun ConversationListScreen(
LoadingIndicator()
}
error != null -> {
// 即使有错误,也显示默认对话
DefaultConversationItem(onClick = { onConversationClick("demo") })
// 显示错误信息
EmptyStateView(
title = "加载失败",
message = error ?: "未知错误",
modifier = Modifier.fillMaxSize()
)
}
conversations.isEmpty() -> {
// 空状态 - 显示默认对话
DefaultConversationItem(onClick = { onConversationClick("demo") })
// 空状态 - 提示用户创建新对话
EmptyStateView(
title = "还没有对话",
message = "点击上方「新建对话」按钮开始您的回忆录之旅",
modifier = Modifier.fillMaxSize()
)
}
else -> {
LazyColumn(
@@ -92,7 +121,12 @@ fun ConversationListScreen(
)
ConversationListItem(
conversation = dto,
onClick = { onConversationClick(conversation.id) }
onClick = { onConversationClick(conversation.id) },
onDelete = {
scope.launch {
viewModel.deleteConversation(conversation.id)
}
}
)
}
}
@@ -102,19 +136,3 @@ fun ConversationListScreen(
}
}
@Composable
private fun DefaultConversationItem(onClick: () -> Unit) {
val defaultDto = ConversationListItemDto(
id = "demo",
title = "回忆录助手",
avatarUrl = null,
latestMessagePreview = "您想从哪里开始呢?可以聊聊童年...",
latestMessageTime = System.currentTimeMillis(),
unreadCount = 0,
isDefaultAssistant = true
)
ConversationListItem(
conversation = defaultDto,
onClick = onClick
)
}

View File

@@ -19,6 +19,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import com.huaga.life_echo.data.database.Message
import com.huaga.life_echo.network.models.MessageDto
import com.huaga.life_echo.ui.components.chat.*
import com.huaga.life_echo.ui.components.debug.WebSocketDebugPanel
import com.huaga.life_echo.ui.theme.LightPurple
import com.huaga.life_echo.ui.viewmodel.CreateMemoryViewModel
import com.huaga.life_echo.ui.viewmodel.ViewModelFactory
@@ -39,21 +40,45 @@ fun CreateMemoryScreen(
val agentResponse by viewModel.agentResponse.collectAsState()
val connectionStatus by viewModel.connectionStatus.collectAsState()
val userMessages by viewModel.userMessages.collectAsState()
val historyMessages by viewModel.historyMessages.collectAsState()
val isStreaming by viewModel.isStreaming.collectAsState()
val streamingText by viewModel.streamingText.collectAsState()
val isTyping by viewModel.isTyping.collectAsState()
// 调试信息
val wsIsConnected by viewModel.wsIsConnected.collectAsState()
val lastMessageType by viewModel.lastMessageType.collectAsState()
val lastMessageTime by viewModel.lastMessageTime.collectAsState()
val errorMessages by viewModel.errorMessages.collectAsState()
val messageCount by viewModel.messageCount.collectAsState()
val conversationIdState by viewModel.conversationId.collectAsState()
// 初始化对话
LaunchedEffect(conversationId) {
if (conversationId != "new") {
viewModel.initializeConversation(conversationId)
} else {
// 如果是新建对话,启动新对话
viewModel.startConversation()
}
}
// 输入框状态
var inputText by remember { mutableStateOf("") }
val keyboardController = LocalSoftwareKeyboardController.current
// 构建消息列表
val messages = remember(userMessages, agentResponse) {
// 构建消息列表(包含历史消息和当前消息)
val messages = remember(historyMessages, userMessages, agentResponse) {
buildList {
// 添加用户消息
// 添加历史消息
addAll(historyMessages)
// 添加当前会话的用户消息(排除已存在的)
val existingUserMessageIds = historyMessages.filter { it.senderType == "user" }.map { it.content }.toSet()
userMessages.forEachIndexed { index, text ->
if (!existingUserMessageIds.contains(text)) {
add(MessageDto(
id = "user_$index",
id = "user_${historyMessages.size + index}",
conversationId = conversationId,
content = text,
senderType = "user",
@@ -61,10 +86,12 @@ fun CreateMemoryScreen(
messageType = "text"
))
}
// 添加AI回复
if (agentResponse.isNotEmpty()) {
}
// 添加AI回复如果不在历史消息中
if (agentResponse.isNotEmpty() && !historyMessages.any { it.content == agentResponse && it.senderType == "assistant" }) {
add(MessageDto(
id = "ai_response",
id = "ai_response_${historyMessages.size + userMessages.size}",
conversationId = conversationId,
content = agentResponse,
senderType = "assistant",
@@ -72,7 +99,7 @@ fun CreateMemoryScreen(
messageType = "text"
))
}
}
}.sortedBy { it.timestamp } // 按时间排序
}
Column(
@@ -85,6 +112,22 @@ fun CreateMemoryScreen(
onBackClick = { navController?.popBackStack() }
)
// WebSocket调试面板开发测试用
WebSocketDebugPanel(
connectionStatus = connectionStatus,
conversationId = conversationIdState,
isConnected = wsIsConnected,
isStreaming = isStreaming,
isTyping = isTyping,
lastMessageType = lastMessageType,
lastMessageTime = lastMessageTime,
errorMessages = errorMessages,
messageCount = messageCount,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp)
)
// 使用新的MessageList组件包含所有消息、流式内容和输入指示器
MessageList(
messages = messages,

View File

@@ -149,42 +149,40 @@ fun ExportDataScreen(
Spacer(modifier = Modifier.weight(1f))
// 导出按钮
// 导出按钮 - 显示开发中提示
var showDevDialog by remember { mutableStateOf(false) }
Button(
onClick = {
isExporting = true
// TODO: 执行导出操作
// 模拟导出完成
scope.launch {
delay(2000)
isExporting = false
exportCompleted = true
}
showDevDialog = true
},
modifier = Modifier.fillMaxWidth(),
enabled = !isExporting && !exportCompleted,
colors = ButtonDefaults.buttonColors(
containerColor = LightPurple
)
) {
if (isExporting) {
CircularProgressIndicator(
modifier = Modifier.size(20.dp),
color = Color.White
)
Spacer(modifier = Modifier.width(8.dp))
Text("导出中...", color = Color.White)
} else if (exportCompleted) {
Icon(
imageVector = Icons.Default.CheckCircle,
contentDescription = "完成",
tint = Color.White
)
Spacer(modifier = Modifier.width(8.dp))
Text("导出完成", color = Color.White)
} else {
Text("开始导出", color = Color.White)
}
// 开发中提示对话框
if (showDevDialog) {
AlertDialog(
onDismissRequest = { showDevDialog = false },
title = { Text("功能开发中") },
text = {
Text(
text = "导出所有数据功能正在开发中,敬请期待!",
modifier = Modifier.wrapContentHeight()
)
},
confirmButton = {
TextButton(
onClick = { showDevDialog = false }
) {
Text("确定", color = LightPurple)
}
}
)
}
}
}

View File

@@ -1,5 +1,7 @@
package com.huaga.life_echo.ui.screens
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.animation.*
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
@@ -18,21 +20,33 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.compose.foundation.lazy.rememberLazyListState
import kotlinx.coroutines.launch
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
import com.huaga.life_echo.data.database.Chapter
import com.huaga.life_echo.network.models.ChapterContentDto
import com.huaga.life_echo.network.models.ChapterDto
import com.huaga.life_echo.ui.components.memoir.*
import com.huaga.life_echo.ui.components.common.EmptyStateView
import com.huaga.life_echo.ui.theme.LightPurple
import com.huaga.life_echo.ui.viewmodel.MyMemoirViewModel
import com.huaga.life_echo.ui.viewmodel.ViewModelFactory
import com.huaga.life_echo.ui.viewmodel.ConversationListViewModel
import com.huaga.life_echo.ui.icons.AppIcons
import com.huaga.life_echo.network.models.ConversationListItemDto
@OptIn(ExperimentalMaterial3Api::class)
@RequiresApi(Build.VERSION_CODES.O)
@Composable
fun MyMemoirScreen(
navController: androidx.navigation.NavHostController? = null,
viewModel: MyMemoirViewModel = viewModel(
factory = ViewModelFactory(LocalContext.current)
),
conversationListViewModel: ConversationListViewModel = viewModel(
factory = ViewModelFactory(LocalContext.current)
)
) {
val chapters by viewModel.chapters.collectAsState(initial = emptyList())
@@ -40,7 +54,53 @@ fun MyMemoirScreen(
val isLoading by viewModel.isLoading.collectAsState()
val bookInfo by viewModel.bookInfo.collectAsState()
val showFullTextReading by viewModel.showFullTextReading.collectAsState()
var selectedTab by remember { mutableStateOf(0) }
// 整理对话相关状态
var showOrganizeDialog by remember { mutableStateOf(false) }
var showOrganizeSuccessDialog by remember { mutableStateOf(false) }
val conversations by conversationListViewModel.conversations.collectAsState(initial = emptyList())
val conversationsLoading by conversationListViewModel.isLoading.collectAsState()
val isOrganizing by viewModel.isOrganizing.collectAsState()
val organizingProgress by viewModel.organizingProgress.collectAsState()
val organizingStatus by viewModel.organizingStatus.collectAsState()
// 下拉刷新状态
var isRefreshing by remember { mutableStateOf(false) }
val refreshScope = rememberCoroutineScope()
// 下拉刷新处理
fun handleRefresh() {
refreshScope.launch {
isRefreshing = true
viewModel.refreshChapters()
viewModel.loadBookInfo()
// 等待刷新完成
kotlinx.coroutines.delay(500)
isRefreshing = false
}
}
// 加载对话列表转换为ConversationListItemDto格式
val conversationDtos = remember(conversations) {
conversations.map { conv ->
ConversationListItemDto(
id = conv.id,
title = conv.title ?: "回忆录助手",
avatarUrl = conv.avatarUrl,
latestMessagePreview = conv.latestMessagePreview,
latestMessageTime = conv.latestMessageTime ?: conv.startedAt,
unreadCount = 0,
isDefaultAssistant = conv.title == null
)
}
}
// 加载对话列表
LaunchedEffect(showOrganizeDialog) {
if (showOrganizeDialog) {
conversationListViewModel.refreshConversations()
}
}
// 加载书籍信息
LaunchedEffect(Unit) {
@@ -104,30 +164,17 @@ fun MyMemoirScreen(
)
} else {
Column(modifier = Modifier.fillMaxSize()) {
// 顶部标签页
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp)
) {
TabButton(
text = "目录",
selected = selectedTab == 0,
onClick = { selectedTab = 0 },
modifier = Modifier.padding(end = 24.dp)
)
TabButton(
text = "正在阅读",
selected = selectedTab == 1,
onClick = { selectedTab = 1 }
)
}
if (selectedChapter == null) {
// 目录视图
// 目录视图(带下拉刷新)
PullToRefreshBox(
isRefreshing = isRefreshing,
onRefresh = { handleRefresh() },
modifier = Modifier.fillMaxSize()
) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 16.dp)
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 16.dp),
state = rememberLazyListState()
) {
// 书籍信息卡片
item {
@@ -160,29 +207,135 @@ fun MyMemoirScreen(
}
}
// 「阅读全文」浮动按钮区域
// 操作按钮区域
item {
Row(
Column(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 16.dp),
horizontalArrangement = Arrangement.Center
.padding(vertical = 16.dp)
) {
FloatingActionButton(
onClick = { viewModel.toggleFullTextReading() },
containerColor = LightPurple
) {
Icon(
imageVector = AppIcons.Reading,
contentDescription = "阅读全文",
tint = Color.White
// 整理进度条(如果正在整理)
if (isOrganizing) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f)
)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
text = organizingStatus.ifEmpty { "正在整理对话..." },
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.padding(bottom = 8.dp)
)
LinearProgressIndicator(
progress = organizingProgress,
modifier = Modifier.fillMaxWidth(),
color = LightPurple,
trackColor = MaterialTheme.colorScheme.surfaceVariant
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = "${(organizingProgress * 100).toInt()}%",
fontSize = 12.sp,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.align(Alignment.End)
)
Spacer(modifier = Modifier.width(8.dp))
Text("阅读全文", color = Color.White)
}
}
}
// 操作按钮
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
// 整理对话按钮(改进样式)
Button(
onClick = { showOrganizeDialog = true },
modifier = Modifier.weight(1f),
enabled = !isOrganizing,
colors = ButtonDefaults.buttonColors(
containerColor = LightPurple
),
shape = RoundedCornerShape(12.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Icon(
imageVector = AppIcons.Edit,
contentDescription = null,
tint = Color.White,
modifier = Modifier.size(20.dp)
)
Spacer(modifier = Modifier.width(8.dp))
Text(
"整理对话",
color = Color.White,
fontSize = 14.sp
)
}
}
// 「阅读全文」按钮 - 只在有章节时显示
if (chapterDtos.isNotEmpty()) {
Button(
onClick = { viewModel.toggleFullTextReading() },
modifier = Modifier.weight(1f),
colors = ButtonDefaults.buttonColors(
containerColor = LightPurple
),
shape = RoundedCornerShape(12.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Icon(
imageVector = AppIcons.Reading,
contentDescription = null,
tint = Color.White,
modifier = Modifier.size(20.dp)
)
Spacer(modifier = Modifier.width(8.dp))
Text(
"阅读全文",
color = Color.White,
fontSize = 14.sp
)
}
}
}
}
}
}
// 如果没有章节,显示空状态
if (chapterDtos.isEmpty()) {
item {
EmptyStateView(
title = "还没有章节",
message = "开始对话让AI帮您整理回忆录章节",
icon = "📖",
modifier = Modifier
.fillMaxWidth()
.padding(top = 48.dp)
)
}
} else {
// 章节列表
items(chapterDtos.sortedBy { it.order_index }, key = { it.id }) { chapterDto ->
ChapterCard(
@@ -196,24 +349,6 @@ fun MyMemoirScreen(
)
Spacer(modifier = Modifier.height(12.dp))
}
// 如果没有章节,显示示例
if (chapterDtos.isEmpty()) {
item {
// 显示示例章节
val now = java.time.Instant.now().toString()
listOf(
ChapterDto("demo1", "童年与家庭", "", 1, "completed", "childhood", emptyList(), now, false, emptyList()),
ChapterDto("demo2", "上学的日子", "", 2, "partial", "education", emptyList(), now, false, emptyList()),
ChapterDto("demo3", "工作与事业", "", 3, "pending", "career", emptyList(), now, true, emptyList()),
ChapterDto("demo4", "爱情与婚姻", "", 4, "pending", "family", emptyList(), now, true, emptyList())
).forEach { chapterDto ->
ChapterCard(
chapter = chapterDto,
onClick = { }
)
Spacer(modifier = Modifier.height(12.dp))
}
}
}
}
@@ -261,30 +396,48 @@ fun MyMemoirScreen(
}
}
}
// 整理对话对话框
if (showOrganizeDialog) {
OrganizeConversationDialog(
conversations = conversationDtos,
isLoading = conversationsLoading,
onDismiss = { showOrganizeDialog = false },
onSelectConversation = { conversationId ->
viewModel.organizeConversation(
conversationId = conversationId,
onSuccess = {
showOrganizeSuccessDialog = true
},
onError = { errorMsg ->
// 错误处理可以在这里添加
}
)
}
)
}
@Composable
fun TabButton(
text: String,
selected: Boolean,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
Column(modifier = modifier.clickable { onClick() }) {
// 整理成功对话框
if (showOrganizeSuccessDialog) {
AlertDialog(
onDismissRequest = { showOrganizeSuccessDialog = false },
title = { Text("整理成功") },
text = {
Text(
text = text,
fontSize = 16.sp,
fontWeight = if (selected) FontWeight.Bold else FontWeight.Normal,
color = if (selected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
text = "对话内容正在整理中,请稍后刷新查看章节。",
modifier = Modifier.wrapContentHeight()
)
if (selected) {
Spacer(modifier = Modifier.height(4.dp))
Box(
modifier = Modifier
.height(2.dp)
.fillMaxWidth()
.background(LightPurple)
},
confirmButton = {
TextButton(
onClick = {
showOrganizeSuccessDialog = false
viewModel.refreshChapters()
}
) {
Text("确定", color = LightPurple)
}
}
)
}
}

View File

@@ -58,6 +58,9 @@ import com.huaga.life_echo.ui.viewmodel.PaymentViewModel
import com.huaga.life_echo.ui.viewmodel.ProfileViewModel
import com.huaga.life_echo.ui.viewmodel.ViewModelFactory
import androidx.compose.ui.platform.LocalContext
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import java.io.File
@Composable
fun ProfileScreen(
@@ -73,11 +76,30 @@ fun ProfileScreen(
var speechRate by remember { mutableStateOf(AppSettings.speechRate) }
var showSpeechRateDialog by remember { mutableStateOf(false) }
var showLogoutDialog by remember { mutableStateOf(false) }
var showUpgradePlanDialog by remember { mutableStateOf(false) }
val isLoggedIn by authViewModel.isLoggedIn.collectAsState()
val currentUser by authViewModel.currentUser.collectAsState()
val userProfile by profileViewModel.userProfile.collectAsState()
val currentPlan by paymentViewModel.currentPlan.collectAsState()
val isLoading by authViewModel.isLoading.collectAsState()
// 图片选择器
val imagePickerLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetContent()
) { uri ->
uri?.let {
// 将URI转换为File并上传
val inputStream = context.contentResolver.openInputStream(uri)
val tempFile = File(context.cacheDir, "temp_avatar.jpg")
inputStream?.use { input ->
tempFile.outputStream().use { output ->
input.copyTo(output)
}
}
authViewModel.uploadAvatar(tempFile)
}
}
// 初始化TokenManager
LaunchedEffect(Unit) {
@@ -97,42 +119,22 @@ fun ProfileScreen(
AppSettings.speechRate = speechRate
}
// 语速选择对话框
// 语速选择对话框 - 显示开发中提示
if (showSpeechRateDialog) {
AlertDialog(
onDismissRequest = { showSpeechRateDialog = false },
title = { Text("选择语速") },
title = { Text("提示") },
text = {
Column(
Text(
text = "语音模块正在开发中,敬请期待!",
modifier = Modifier.wrapContentHeight()
) {
AppSettings.SpeechRate.entries.forEach { rate ->
Row(
modifier = Modifier
.fillMaxWidth()
.clickable {
speechRate = rate
showSpeechRateDialog = false
}
.padding(vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = speechRate == rate,
onClick = {
speechRate = rate
showSpeechRateDialog = false
}
)
Spacer(modifier = Modifier.width(8.dp))
Text(rate.label)
}
}
}
},
confirmButton = {
TextButton(onClick = { showSpeechRateDialog = false }) {
Text("取消")
TextButton(
onClick = { showSpeechRateDialog = false }
) {
Text("确定", color = LightPurple)
}
}
)
@@ -153,14 +155,7 @@ fun ProfileScreen(
horizontalAlignment = Alignment.CenterHorizontally
) {
if (isLoggedIn && currentUser != null) {
// 已登录:显示用户信息
// 使用新的UserAvatar组件
com.huaga.life_echo.ui.components.profile.UserAvatar(
avatarUrl = userProfile?.avatarUrl ?: currentUser!!.avatar_url,
modifier = Modifier.size(80.dp)
)
Spacer(modifier = Modifier.height(16.dp))
// 已登录:显示用户信息(暂时不显示头像)
Text(
text = userProfile?.nickname ?: currentUser!!.nickname,
@@ -169,7 +164,26 @@ fun ProfileScreen(
color = MaterialTheme.colorScheme.onSurface
)
Spacer(modifier = Modifier.height(8.dp))
// 显示邮箱
if (!currentUser!!.email.isNullOrBlank()) {
Text(
text = currentUser!!.email ?: "",
fontSize = 14.sp,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Spacer(modifier = Modifier.height(4.dp))
}
// 显示手机号
Text(
text = currentUser!!.phone,
fontSize = 14.sp,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Spacer(modifier = Modifier.height(8.dp))
// 使用新的PlanStatusBadge组件
com.huaga.life_echo.ui.components.profile.PlanStatusBadge(
@@ -270,9 +284,9 @@ fun ProfileScreen(
SettingItem(
icon = AppIcons.Upgrade,
title = "升级/管理套餐",
subtitle = "解锁完整导出与更多功能",
subtitle = "功能开发中",
onClick = {
navController?.navigate(com.huaga.life_echo.navigation.Screen.UpgradePlan.route)
showUpgradePlanDialog = true
}
)
HorizontalDivider(modifier = Modifier.padding(horizontal = 16.dp))
@@ -329,30 +343,15 @@ fun ProfileScreen(
SettingItem(
icon = AppIcons.AccessTime,
title = "语速",
subtitle = speechRate.label,
subtitle = "正在开发语音模块",
onClick = {
// 显示语速选择对话框
// 显示提示对话框
showSpeechRateDialog = true
}
)
HorizontalDivider(modifier = Modifier.padding(horizontal = 16.dp))
SettingItem(
icon = AppIcons.FormatSize,
title = "大字模式",
trailing = {
Switch(
checked = largeFontMode,
onCheckedChange = { largeFontMode = it },
colors = SwitchDefaults.colors(
checkedThumbColor = Color.White,
checkedTrackColor = LightPurple,
uncheckedThumbColor = Color.White,
uncheckedTrackColor = Color(0xFFE0E0E0)
)
)
},
onClick = { largeFontMode = !largeFontMode }
)
// 大字模式暂时不开放
// HorizontalDivider(modifier = Modifier.padding(horizontal = 16.dp))
// SettingItem(...)
HorizontalDivider(modifier = Modifier.padding(horizontal = 16.dp))
SettingItem(
icon = AppIcons.Brightness2,
@@ -397,6 +396,27 @@ fun ProfileScreen(
}
}
// 升级套餐提示对话框
if (showUpgradePlanDialog) {
AlertDialog(
onDismissRequest = { showUpgradePlanDialog = false },
title = { Text("功能开发中") },
text = {
Text(
text = "升级/管理套餐功能正在开发中,敬请期待!",
modifier = Modifier.wrapContentHeight()
)
},
confirmButton = {
TextButton(
onClick = { showUpgradePlanDialog = false }
) {
Text("确定", color = LightPurple)
}
}
)
}
// 登出确认对话框
if (showLogoutDialog) {
AlertDialog(