ui: reorder & rename settings sections

Bark → E-mail → SMS-fallback → Icons → Update → Maintenance

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-09 16:34:23 +08:00
parent fa50e56c97
commit 6b65dfbbe2
@@ -172,44 +172,71 @@ fun SettingsScreen(onOpenLog: () -> Unit) {
} }
item { item {
SectionCard("应用图标", subtitle = "导出 App 图标后,Bark 通知可按包名显示图标") { SectionCard("电邮转发", subtitle = "SMTPS 直发邮件(推荐端口 465);与 Bark 并行,互不依赖") {
OutlinedTextField( com.a2i.forwarder.ui.SwitchRow(
value = iconPrefix, title = "启用电邮转发",
onValueChange = { app.appScope.launch { app.settings.setIconPrefix(it) } }, subtitle = if (emailEnabled) "同时转发通知到邮箱" else "当前关闭",
label = { Text("图标 URL 前缀") }, checked = emailEnabled,
supportingText = { Text("转发时 icon = 前缀 + 包名 + .png;留空则不显示图标") }, ) { v -> app.appScope.launch { app.settings.setEmailForwarding(v) } }
modifier = Modifier.fillMaxWidth(),
singleLine = true, if (emailEnabled) {
) Spacer(Modifier.size(8.dp))
Text( Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
"导出目录:${treeUri?.let { DocumentFile.fromTreeUri(context, it)?.name } ?: "未选择"}", OutlinedTextField(
style = MaterialTheme.typography.bodySmall, value = smtpHostInput, onValueChange = { smtpHostInput = it },
color = MaterialTheme.colorScheme.onSurfaceVariant, label = { Text("SMTP 主机") },
modifier = Modifier.padding(top = 8.dp), supportingText = { Text("如 smtp.qq.com") },
) modifier = Modifier.weight(1.5f), singleLine = true,
Row( )
modifier = Modifier.fillMaxWidth().padding(top = 10.dp), OutlinedTextField(
horizontalArrangement = Arrangement.spacedBy(8.dp), value = smtpPortInput, onValueChange = { smtpPortInput = it.filter { c -> c.isDigit() } },
) { label = { Text("端口") },
OutlinedButton(onClick = { treeLauncher.launch(null) }, modifier = Modifier.weight(1f)) { Text("选择目录") } supportingText = { Text("465") },
modifier = Modifier.weight(1f), singleLine = true,
)
}
Spacer(Modifier.size(4.dp))
OutlinedTextField(
value = smtpUserInput, onValueChange = { smtpUserInput = it },
label = { Text("账号") },
supportingText = { Text("SMTP 登录账号(通常即邮箱地址)") },
modifier = Modifier.fillMaxWidth(), singleLine = true,
)
Spacer(Modifier.size(4.dp))
OutlinedTextField(
value = smtpPasswordInput, onValueChange = { smtpPasswordInput = it },
label = { Text("授权码 / 密码") },
supportingText = { Text("QQ/163/Gmail 需用授权码,非邮箱密码;QQ邮箱需开启SMTPS服务") },
modifier = Modifier.fillMaxWidth(), singleLine = true,
)
Spacer(Modifier.size(4.dp))
OutlinedTextField(
value = smtpFromInput, onValueChange = { smtpFromInput = it },
label = { Text("发件人地址") },
supportingText = { Text("通常与账号相同") },
modifier = Modifier.fillMaxWidth(), singleLine = true,
)
Spacer(Modifier.size(4.dp))
OutlinedTextField(
value = emailToInput, onValueChange = { emailToInput = it },
label = { Text("收件人地址") },
supportingText = { Text("转发到的目标邮箱") },
modifier = Modifier.fillMaxWidth(), singleLine = true,
)
Spacer(Modifier.size(8.dp))
Button( Button(
onClick = { onClick = {
val u = treeUri ?: return@Button
app.appScope.launch { app.appScope.launch {
exporting = true app.settings.setSmtpHost(smtpHostInput.trim())
val r = IconExporter(context).exportAll(u) app.settings.setSmtpPort(smtpPortInput.trim().toIntOrNull() ?: 587)
exporting = false app.settings.setSmtpUser(smtpUserInput.trim())
exportResult = "${r.total} 个,成功 ${r.ok},失败 ${r.fail}" app.settings.setSmtpPassword(smtpPasswordInput.trim())
app.settings.setSmtpFrom(smtpFromInput.trim())
app.settings.setEmailTo(emailToInput.trim())
} }
}, },
enabled = treeUri != null && !exporting, modifier = Modifier.fillMaxWidth(),
modifier = Modifier.weight(1f), ) { Text("保存电邮设置") }
) {
if (exporting) CircularProgressIndicator(Modifier.size(18.dp), strokeWidth = 2.dp) else Text("导出图标")
}
}
exportResult?.let {
Text(it, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.primary, modifier = Modifier.padding(top = 8.dp))
} }
} }
} }
@@ -284,77 +311,50 @@ fun SettingsScreen(onOpenLog: () -> Unit) {
} }
item { item {
SectionCard("电邮转发", subtitle = "SMTPS 直发邮件(推荐端口 465);与 Bark 并行,互不依赖") { SectionCard("应用图标", subtitle = "导出 App 图标后,Bark 通知可按包名显示图标") {
com.a2i.forwarder.ui.SwitchRow( OutlinedTextField(
title = "启用电邮转发", value = iconPrefix,
subtitle = if (emailEnabled) "同时转发通知到邮箱" else "当前关闭", onValueChange = { app.appScope.launch { app.settings.setIconPrefix(it) } },
checked = emailEnabled, label = { Text("图标 URL 前缀") },
) { v -> app.appScope.launch { app.settings.setEmailForwarding(v) } } supportingText = { Text("转发时 icon = 前缀 + 包名 + .png;留空则不显示图标") },
modifier = Modifier.fillMaxWidth(),
if (emailEnabled) { singleLine = true,
Spacer(Modifier.size(8.dp)) )
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) { Text(
OutlinedTextField( "导出目录:${treeUri?.let { DocumentFile.fromTreeUri(context, it)?.name } ?: "未选择"}",
value = smtpHostInput, onValueChange = { smtpHostInput = it }, style = MaterialTheme.typography.bodySmall,
label = { Text("SMTP 主机") }, color = MaterialTheme.colorScheme.onSurfaceVariant,
supportingText = { Text("如 smtp.qq.com") }, modifier = Modifier.padding(top = 8.dp),
modifier = Modifier.weight(1.5f), singleLine = true, )
) Row(
OutlinedTextField( modifier = Modifier.fillMaxWidth().padding(top = 10.dp),
value = smtpPortInput, onValueChange = { smtpPortInput = it.filter { c -> c.isDigit() } }, horizontalArrangement = Arrangement.spacedBy(8.dp),
label = { Text("端口") }, ) {
supportingText = { Text("465") }, OutlinedButton(onClick = { treeLauncher.launch(null) }, modifier = Modifier.weight(1f)) { Text("选择目录") }
modifier = Modifier.weight(1f), singleLine = true,
)
}
Spacer(Modifier.size(4.dp))
OutlinedTextField(
value = smtpUserInput, onValueChange = { smtpUserInput = it },
label = { Text("账号") },
supportingText = { Text("SMTP 登录账号(通常即邮箱地址)") },
modifier = Modifier.fillMaxWidth(), singleLine = true,
)
Spacer(Modifier.size(4.dp))
OutlinedTextField(
value = smtpPasswordInput, onValueChange = { smtpPasswordInput = it },
label = { Text("授权码 / 密码") },
supportingText = { Text("QQ/163/Gmail 需用授权码,非邮箱密码;QQ邮箱需开启SMTPS服务") },
modifier = Modifier.fillMaxWidth(), singleLine = true,
)
Spacer(Modifier.size(4.dp))
OutlinedTextField(
value = smtpFromInput, onValueChange = { smtpFromInput = it },
label = { Text("发件人地址") },
supportingText = { Text("通常与账号相同") },
modifier = Modifier.fillMaxWidth(), singleLine = true,
)
Spacer(Modifier.size(4.dp))
OutlinedTextField(
value = emailToInput, onValueChange = { emailToInput = it },
label = { Text("收件人地址") },
supportingText = { Text("转发到的目标邮箱") },
modifier = Modifier.fillMaxWidth(), singleLine = true,
)
Spacer(Modifier.size(8.dp))
Button( Button(
onClick = { onClick = {
val u = treeUri ?: return@Button
app.appScope.launch { app.appScope.launch {
app.settings.setSmtpHost(smtpHostInput.trim()) exporting = true
app.settings.setSmtpPort(smtpPortInput.trim().toIntOrNull() ?: 587) val r = IconExporter(context).exportAll(u)
app.settings.setSmtpUser(smtpUserInput.trim()) exporting = false
app.settings.setSmtpPassword(smtpPasswordInput.trim()) exportResult = "${r.total} 个,成功 ${r.ok},失败 ${r.fail}"
app.settings.setSmtpFrom(smtpFromInput.trim())
app.settings.setEmailTo(emailToInput.trim())
} }
}, },
modifier = Modifier.fillMaxWidth(), enabled = treeUri != null && !exporting,
) { Text("保存电邮设置") } modifier = Modifier.weight(1f),
) {
if (exporting) CircularProgressIndicator(Modifier.size(18.dp), strokeWidth = 2.dp) else Text("导出图标")
}
}
exportResult?.let {
Text(it, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.primary, modifier = Modifier.padding(top = 8.dp))
} }
} }
} }
item { item {
SectionCard("关于与更新", subtitle = "版本检查(数据来自 GitHub Releases") { SectionCard("更新", subtitle = "版本检查(数据来自 Gitea Releases") {
com.a2i.forwarder.ui.SwitchRow( com.a2i.forwarder.ui.SwitchRow(
title = "自动检查更新", title = "自动检查更新",
subtitle = "启动时检查,且距上次满 24 小时再次检查", subtitle = "启动时检查,且距上次满 24 小时再次检查",