style(ui): 列表项加卡片容器;登出移到设置页底部;按钮改矢量图标

新增 PreferenceCard(BasicComponent 本身无背景/圆角);抽屉去掉登出、新建与删除改图标按钮;设置页返回改 ChevronBackward、底部新增登出图标。
This commit is contained in:
AskaEth committed 2026-09-08 23:13:00 +08:00
1 parent df2a26701c
commit cf291b58ab
4 files changed
+117 -57

No files matched your search

@@ -36,7 +36,11 @@ fun ChatHomeScreen(
BackHandler(enabled = drawerOpen) { drawerOpen = false }
if (showSettings) {
SettingsScreen(container = container, onBack = { showSettings = false })
SettingsScreen(
container = container,
onBack = { showSettings = false },
onLogout = onLogout,
)
} else {
MiuixDrawer(
open = drawerOpen,
@@ -63,7 +67,6 @@ fun ChatHomeScreen(
drawerOpen = false
showSettings = true
},
onLogout = onLogout,
)
},
)
@@ -0,0 +1,33 @@
package top.yeij.cyrene.ui.common
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp
import top.yukonga.miuix.kmp.theme.MiuixTheme
/**
* Miuix 的 `BasicComponent` / Preference 系列本身**没有背景与圆角**(只是可点击的 Column),
* 需要外面包一层卡片容器才能得到 MD3 的「小圆角卡片」外观。
*
* 页面底色用 `surface`、卡片用 `surfaceContainer`:浅色下 #F7F7F7 对 #FFFFFF,
* 深色下 #000000 对 #242424,卡片因此能凸显出来。
*/
@Composable
fun PreferenceCard(
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
Box(
modifier = modifier
.fillMaxWidth()
.clip(RoundedCornerShape(16.dp))
.background(MiuixTheme.colorScheme.surfaceContainer),
) {
content()
}
}
@@ -23,12 +23,18 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import top.yeij.cyrene.ui.common.PreferenceCard
import top.yukonga.miuix.kmp.basic.BasicComponent
import top.yukonga.miuix.kmp.basic.Icon
import top.yukonga.miuix.kmp.basic.IconButton
import top.yukonga.miuix.kmp.basic.Text
import top.yukonga.miuix.kmp.basic.TextButton
import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.extended.Add
import top.yukonga.miuix.kmp.icon.extended.Delete
import top.yukonga.miuix.kmp.theme.MiuixTheme
/** 侧边栏内容:会话列表 + IoT/设置占位 + 登出。列表项统一用 Miuix 的 MD3 圆角卡片。 */
/** 侧边栏内容:会话列表 + IoT/设置入口。列表项为 MD3 小圆角卡片。 */
@Composable
fun ColumnScope.SessionDrawerContent(
state: SessionsUiState,
@@ -37,7 +43,6 @@ fun ColumnScope.SessionDrawerContent(
onDelete: (SessionItem) -> Unit,
onOpenIot: () -> Unit,
onOpenSettings: () -> Unit,
onLogout: () -> Unit,
) {
var pendingDelete by remember { mutableStateOf<SessionItem?>(null) }
@@ -53,11 +58,13 @@ fun ColumnScope.SessionDrawerContent(
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 20.dp, end = 12.dp, bottom = 4.dp),
.padding(start = 20.dp, end = 8.dp, bottom = 4.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text("会话", style = MiuixTheme.textStyles.subtitle, modifier = Modifier.weight(1f))
TextButton("新建", onClick = onCreate)
IconButton(onClick = onCreate) {
Icon(imageVector = MiuixIcons.Add, contentDescription = "新建会话")
}
}
LazyColumn(
@@ -91,11 +98,9 @@ fun ColumnScope.SessionDrawerContent(
}
Spacer(Modifier.height(12.dp))
DrawerAction("IoT(规划中)", onOpenIot)
PreferenceCard { BasicComponent(title = "IoT(规划中)", onClick = onOpenIot) }
Spacer(Modifier.height(8.dp))
DrawerAction("App 设置", onOpenSettings)
Spacer(Modifier.height(8.dp))
DrawerAction("登出", onLogout)
PreferenceCard { BasicComponent(title = "App 设置", onClick = onOpenSettings) }
Spacer(Modifier.height(16.dp))
pendingDelete?.let { target ->
@@ -119,6 +124,7 @@ private fun SessionRow(
onClick: () -> Unit,
onDelete: () -> Unit,
) {
PreferenceCard {
BasicComponent(
title = session.title,
onClick = onClick,
@@ -128,26 +134,21 @@ private fun SessionRow(
text = "✓",
style = MiuixTheme.textStyles.main,
color = MiuixTheme.colorScheme.primary,
modifier = Modifier.padding(horizontal = 6.dp),
modifier = Modifier.padding(horizontal = 4.dp),
)
}
if (!session.isMain) {
Text(
text = "删除",
style = MiuixTheme.textStyles.footnote1,
color = MiuixTheme.colorScheme.error,
modifier = Modifier
.clickable(onClick = onDelete)
.padding(horizontal = 8.dp, vertical = 4.dp),
IconButton(onClick = onDelete) {
Icon(
imageVector = MiuixIcons.Delete,
contentDescription = "删除会话",
tint = MiuixTheme.colorScheme.error,
)
}
}
},
)
}
@Composable
private fun DrawerAction(label: String, onClick: () -> Unit) {
BasicComponent(title = label, onClick = onClick)
}
}
@Composable
@@ -1,5 +1,6 @@
package top.yeij.cyrene.ui.settings
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
@@ -21,11 +22,16 @@ import top.yeij.cyrene.BuildConfig
import top.yeij.cyrene.app.AppContainer
import top.yeij.cyrene.core.prefs.AppPrefs
import top.yeij.cyrene.core.prefs.ThemeMode
import top.yeij.cyrene.ui.common.PreferenceCard
import top.yukonga.miuix.kmp.basic.BasicComponent
import top.yukonga.miuix.kmp.basic.Icon
import top.yukonga.miuix.kmp.basic.IconButton
import top.yukonga.miuix.kmp.basic.Scaffold
import top.yukonga.miuix.kmp.basic.SmallTopAppBar
import top.yukonga.miuix.kmp.basic.Text
import top.yukonga.miuix.kmp.basic.TextButton
import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.extended.Back
import top.yukonga.miuix.kmp.icon.extended.ChevronBackward
import top.yukonga.miuix.kmp.preference.SwitchPreference
import top.yukonga.miuix.kmp.theme.MiuixTheme
@@ -33,6 +39,7 @@ import top.yukonga.miuix.kmp.theme.MiuixTheme
fun SettingsScreen(
container: AppContainer,
onBack: () -> Unit,
onLogout: () -> Unit = {},
) {
val prefs by container.appSettings.data.collectAsState(initial = AppPrefs())
val scope = rememberCoroutineScope()
@@ -42,7 +49,11 @@ fun SettingsScreen(
topBar = {
SmallTopAppBar(
title = "App 设置",
navigationIcon = { TextButton("返回", onClick = onBack) },
navigationIcon = {
IconButton(onClick = onBack) {
Icon(imageVector = MiuixIcons.ChevronBackward, contentDescription = "返回")
}
},
)
},
) { padding ->
@@ -54,44 +65,77 @@ fun SettingsScreen(
) {
SectionTitle("外观")
ThemeMode.entries.forEach { mode ->
ThemeOption(
label = mode.label(),
selected = prefs.themeMode == mode,
PreferenceCard {
BasicComponent(
title = mode.label(),
onClick = { scope.launch { settings.setThemeMode(mode) } },
endActions = {
if (prefs.themeMode == mode) {
Text(
text = "✓",
style = MiuixTheme.textStyles.main,
color = MiuixTheme.colorScheme.primary,
)
}
},
)
}
Spacer(Modifier.height(8.dp))
}
SectionTitle("聊天")
PreferenceCard {
SwitchPreference(
title = "显示旁白",
summary = "以灰斜体小字显示 <action> / <narration>",
checked = prefs.showNarration,
onCheckedChange = { scope.launch { settings.setShowNarration(it) } },
)
}
Spacer(Modifier.height(8.dp))
PreferenceCard {
SwitchPreference(
title = "思维链默认展开",
summary = "流式期间展开思维链,结束后自动折叠",
checked = prefs.thinkingExpanded,
onCheckedChange = { scope.launch { settings.setThinkingExpanded(it) } },
)
}
SectionTitle("关于")
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp, vertical = 14.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text("版本", style = MiuixTheme.textStyles.main, modifier = Modifier.weight(1f))
PreferenceCard {
BasicComponent(
title = "版本",
summary = null,
endActions = {
Text(
text = "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})",
style = MiuixTheme.textStyles.footnote1,
color = MiuixTheme.colorScheme.onSurfaceVariantSummary,
)
},
)
}
Spacer(Modifier.height(24.dp))
Spacer(Modifier.height(32.dp))
PreferenceCard {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
) {
IconButton(onClick = onLogout) {
Icon(
imageVector = MiuixIcons.Back,
contentDescription = "登出",
tint = MiuixTheme.colorScheme.error,
)
}
}
}
Spacer(Modifier.height(32.dp))
}
}
}
@@ -106,27 +150,6 @@ private fun SectionTitle(text: String) {
)
}
@Composable
private fun ThemeOption(
label: String,
selected: Boolean,
onClick: () -> Unit,
) {
BasicComponent(
title = label,
onClick = onClick,
endActions = {
if (selected) {
Text(
text = "✓",
style = MiuixTheme.textStyles.main,
color = MiuixTheme.colorScheme.primary,
)
}
},
)
}
private fun ThemeMode.label(): String = when (this) {
ThemeMode.System -> "跟随系统"
ThemeMode.Light -> "浅色"