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.common.MiuixDrawer
|
||||||
import top.yeij.cyrene.ui.sessions.SessionDrawerContent
|
import top.yeij.cyrene.ui.sessions.SessionDrawerContent
|
||||||
import top.yeij.cyrene.ui.sessions.SessionsViewModel
|
import top.yeij.cyrene.ui.sessions.SessionsViewModel
|
||||||
|
import top.yeij.cyrene.ui.settings.AboutScreen
|
||||||
import top.yeij.cyrene.ui.settings.SettingsScreen
|
import top.yeij.cyrene.ui.settings.SettingsScreen
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,9 +34,13 @@ fun ChatHomeScreen(
|
|||||||
var drawerOpen by remember { mutableStateOf(false) }
|
var drawerOpen by remember { mutableStateOf(false) }
|
||||||
var showSettings by remember { mutableStateOf(false) }
|
var showSettings by remember { mutableStateOf(false) }
|
||||||
var showAdmin by remember { mutableStateOf(false) }
|
var showAdmin by remember { mutableStateOf(false) }
|
||||||
|
var showAbout by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
BackHandler(enabled = showAdmin) { showAdmin = 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 }
|
BackHandler(enabled = drawerOpen) { drawerOpen = false }
|
||||||
|
|
||||||
when {
|
when {
|
||||||
@@ -44,10 +49,13 @@ fun ChatHomeScreen(
|
|||||||
onBack = { showAdmin = false },
|
onBack = { showAdmin = false },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
showAbout -> AboutScreen(onBack = { showAbout = false })
|
||||||
|
|
||||||
showSettings -> SettingsScreen(
|
showSettings -> SettingsScreen(
|
||||||
container = container,
|
container = container,
|
||||||
onBack = { showSettings = false },
|
onBack = { showSettings = false },
|
||||||
onLogout = onLogout,
|
onLogout = onLogout,
|
||||||
|
onOpenAbout = { showAbout = true },
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> MiuixDrawer(
|
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.MiuixIcons
|
||||||
import top.yukonga.miuix.kmp.icon.extended.Back
|
import top.yukonga.miuix.kmp.icon.extended.Back
|
||||||
import top.yukonga.miuix.kmp.icon.extended.ChevronBackward
|
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.preference.SwitchPreference
|
||||||
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
import top.yukonga.miuix.kmp.theme.MiuixTheme
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@ fun SettingsScreen(
|
|||||||
container: AppContainer,
|
container: AppContainer,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
onLogout: () -> Unit = {},
|
onLogout: () -> Unit = {},
|
||||||
|
onOpenAbout: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val prefs by container.appSettings.data.collectAsState(initial = AppPrefs())
|
val prefs by container.appSettings.data.collectAsState(initial = AppPrefs())
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
@@ -129,12 +131,19 @@ fun SettingsScreen(
|
|||||||
BasicComponent(
|
BasicComponent(
|
||||||
title = "版本",
|
title = "版本",
|
||||||
summary = null,
|
summary = null,
|
||||||
|
onClick = onOpenAbout,
|
||||||
endActions = {
|
endActions = {
|
||||||
Text(
|
Text(
|
||||||
text = "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})",
|
text = versionText(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE),
|
||||||
style = MiuixTheme.textStyles.footnote1,
|
style = MiuixTheme.textStyles.footnote1,
|
||||||
color = MiuixTheme.colorScheme.onSurfaceVariantSummary,
|
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