merge: W8 — 设置页「版本」行可点进「关于」页(含作者署名)
This commit is contained in:
commit
f24877d53b
4 files changed
+138
-2
No files matched your search
@@ -15,6 +15,7 @@ import top.yeij.cyrene.ui.admin.AdminHomeScreen
|
||||
import top.yeij.cyrene.ui.common.MiuixDrawer
|
||||
import top.yeij.cyrene.ui.sessions.SessionDrawerContent
|
||||
import top.yeij.cyrene.ui.sessions.SessionsViewModel
|
||||
import top.yeij.cyrene.ui.settings.AboutScreen
|
||||
import top.yeij.cyrene.ui.settings.SettingsScreen
|
||||
|
||||
/**
|
||||
@@ -33,9 +34,13 @@ fun ChatHomeScreen(
|
||||
var drawerOpen by remember { mutableStateOf(false) }
|
||||
var showSettings by remember { mutableStateOf(false) }
|
||||
var showAdmin by remember { mutableStateOf(false) }
|
||||
var showAbout by remember { mutableStateOf(false) }
|
||||
|
||||
BackHandler(enabled = showAdmin) { showAdmin = false }
|
||||
BackHandler(enabled = showSettings) { showSettings = false }
|
||||
// 「关于」嵌在设置页里,所以两个条件必须**互斥**:在关于页时设置页的处理器关掉,
|
||||
// 返回才只退一层(关于 → 设置),不会一步跳回聊天。
|
||||
BackHandler(enabled = showAbout) { showAbout = false }
|
||||
BackHandler(enabled = showSettings && !showAbout) { showSettings = false }
|
||||
BackHandler(enabled = drawerOpen) { drawerOpen = false }
|
||||
|
||||
when {
|
||||
@@ -44,10 +49,13 @@ fun ChatHomeScreen(
|
||||
onBack = { showAdmin = false },
|
||||
)
|
||||
|
||||
showAbout -> AboutScreen(onBack = { showAbout = false })
|
||||
|
||||
showSettings -> SettingsScreen(
|
||||
container = container,
|
||||
onBack = { showSettings = false },
|
||||
onLogout = onLogout,
|
||||
onOpenAbout = { showAbout = true },
|
||||
)
|
||||
|
||||
else -> MiuixDrawer(
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package top.yeij.cyrene.ui.settings
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import top.yeij.cyrene.BuildConfig
|
||||
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.icon.MiuixIcons
|
||||
import top.yukonga.miuix.kmp.icon.extended.ChevronBackward
|
||||
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
||||
|
||||
/**
|
||||
* 「关于」页:只有名称、版本、简介、作者这四项。
|
||||
*
|
||||
* 这四项分别来自本端常量与 `BuildConfig`(由 `app/build.gradle.kts` 生成),**不写死版本号**;
|
||||
* 页面里刻意不放任何链接 / 邮箱 / 版权年份——没有人提供过这些信息,编不得。
|
||||
*
|
||||
* 与设置页同为聊天之上的独立层级:自己带 `Scaffold`,返回落到设置页(层级见 `ChatHomeScreen`)。
|
||||
*/
|
||||
@Composable
|
||||
fun AboutScreen(onBack: () -> Unit) {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
SmallTopAppBar(
|
||||
title = "关于",
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onBack) {
|
||||
Icon(imageVector = MiuixIcons.ChevronBackward, contentDescription = "返回")
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
) { padding ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Spacer(Modifier.height(40.dp))
|
||||
Text("Cyrene", style = MiuixTheme.textStyles.title1)
|
||||
Spacer(Modifier.height(4.dp))
|
||||
Text(
|
||||
text = "Cyrene v2 后端的 Android 客户端",
|
||||
style = MiuixTheme.textStyles.footnote1,
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary,
|
||||
modifier = Modifier.padding(horizontal = 24.dp),
|
||||
)
|
||||
|
||||
Spacer(Modifier.height(32.dp))
|
||||
AboutRow(title = "版本", value = versionText(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE))
|
||||
Spacer(Modifier.height(8.dp))
|
||||
AboutRow(title = "作者", value = "AskaEth")
|
||||
Spacer(Modifier.height(32.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AboutRow(title: String, value: String) {
|
||||
PreferenceCard {
|
||||
BasicComponent(
|
||||
title = title,
|
||||
endActions = {
|
||||
Text(
|
||||
text = value,
|
||||
style = MiuixTheme.textStyles.footnote1,
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 版本号的显示文本(纯函数):设置页的「版本」行与关于页共用同一份输出,格式不会各写各的。
|
||||
*
|
||||
* 值一律来自 `BuildConfig`(AGP 按 `build.gradle.kts` 的 `versionName` / `versionCode` 生成),
|
||||
* 两处都不写死版本号,发版只需改构建文件。
|
||||
*/
|
||||
internal fun versionText(versionName: String, versionCode: Int): String = "$versionName ($versionCode)"
|
||||
@@ -33,6 +33,7 @@ import top.yukonga.miuix.kmp.basic.Text
|
||||
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.icon.extended.ChevronForward
|
||||
import top.yukonga.miuix.kmp.preference.SwitchPreference
|
||||
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
||||
|
||||
@@ -41,6 +42,7 @@ fun SettingsScreen(
|
||||
container: AppContainer,
|
||||
onBack: () -> Unit,
|
||||
onLogout: () -> Unit = {},
|
||||
onOpenAbout: () -> Unit = {},
|
||||
) {
|
||||
val prefs by container.appSettings.data.collectAsState(initial = AppPrefs())
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -129,12 +131,19 @@ fun SettingsScreen(
|
||||
BasicComponent(
|
||||
title = "版本",
|
||||
summary = null,
|
||||
onClick = onOpenAbout,
|
||||
endActions = {
|
||||
Text(
|
||||
text = "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})",
|
||||
text = versionText(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE),
|
||||
style = MiuixTheme.textStyles.footnote1,
|
||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary,
|
||||
)
|
||||
Icon(
|
||||
imageVector = MiuixIcons.ChevronForward,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.padding(start = 6.dp),
|
||||
tint = MiuixTheme.colorScheme.onSurfaceVariantSummary,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package top.yeij.cyrene.ui.settings
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* 版本文本的格式(纯函数):设置页的「版本」行与关于页共用同一份输出。
|
||||
*
|
||||
* 这里钉的是**格式**,不是某个具体版本号——值来自 `BuildConfig`,发版只改构建文件。
|
||||
*/
|
||||
class VersionTextTest {
|
||||
|
||||
@Test
|
||||
fun `version name is followed by the code in parentheses`() {
|
||||
assertEquals("0.1.0 (1)", versionText("0.1.0", 1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `both inputs are rendered verbatim, so the label tracks the build config`() {
|
||||
assertEquals("2.3.4 (567)", versionText("2.3.4", 567))
|
||||
assertEquals("1.0.0-beta (42)", versionText("1.0.0-beta", 42))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user