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 d9308552a0
commit 0c6b730115
@@ -172,44 +172,71 @@ fun SettingsScreen(onOpenLog: () -> Unit) {
} }
item { item {
SectionCard("应用图标", subtitle = "导出 App 图标后,Bark 通知可按包名显示图标") { SectionCard("电邮转发", subtitle = "SMTPS 直发邮件(推荐端口 465);与 Bark 并行,互不依赖") {
com.a2i.forwarder.ui.SwitchRow(
title = "启用电邮转发",
subtitle = if (emailEnabled) "同时转发通知到邮箱" else "当前关闭",
checked = emailEnabled,
) { v -> app.appScope.launch { app.settings.setEmailForwarding(v) } }
if (emailEnabled) {
Spacer(Modifier.size(8.dp))
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
OutlinedTextField( OutlinedTextField(
value = iconPrefix, value = smtpHostInput, onValueChange = { smtpHostInput = it },
onValueChange = { app.appScope.launch { app.settings.setIconPrefix(it) } }, label = { Text("SMTP 主机") },
label = { Text("图标 URL 前缀") }, supportingText = { Text("如 smtp.qq.com") },
supportingText = { Text("转发时 icon = 前缀 + 包名 + .png;留空则不显示图标") }, modifier = Modifier.weight(1.5f), singleLine = true,
modifier = Modifier.fillMaxWidth(),
singleLine = true,
) )
Text( OutlinedTextField(
"导出目录:${treeUri?.let { DocumentFile.fromTreeUri(context, it)?.name } ?: "未选择"}", value = smtpPortInput, onValueChange = { smtpPortInput = it.filter { c -> c.isDigit() } },
style = MaterialTheme.typography.bodySmall, label = { Text("端口") },
color = MaterialTheme.colorScheme.onSurfaceVariant, supportingText = { Text("465") },
modifier = Modifier.padding(top = 8.dp), modifier = Modifier.weight(1f), singleLine = true,
) )
Row( }
modifier = Modifier.fillMaxWidth().padding(top = 10.dp), Spacer(Modifier.size(4.dp))
horizontalArrangement = Arrangement.spacedBy(8.dp), OutlinedTextField(
) { value = smtpUserInput, onValueChange = { smtpUserInput = it },
OutlinedButton(onClick = { treeLauncher.launch(null) }, modifier = Modifier.weight(1f)) { Text("选择目录") } 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(
title = "启用电邮转发",
subtitle = if (emailEnabled) "同时转发通知到邮箱" else "当前关闭",
checked = emailEnabled,
) { v -> app.appScope.launch { app.settings.setEmailForwarding(v) } }
if (emailEnabled) {
Spacer(Modifier.size(8.dp))
Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp)) {
OutlinedTextField( OutlinedTextField(
value = smtpHostInput, onValueChange = { smtpHostInput = it }, value = iconPrefix,
label = { Text("SMTP 主机") }, onValueChange = { app.appScope.launch { app.settings.setIconPrefix(it) } },
supportingText = { Text("如 smtp.qq.com") }, label = { Text("图标 URL 前缀") },
modifier = Modifier.weight(1.5f), singleLine = true, supportingText = { Text("转发时 icon = 前缀 + 包名 + .png;留空则不显示图标") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
) )
OutlinedTextField( Text(
value = smtpPortInput, onValueChange = { smtpPortInput = it.filter { c -> c.isDigit() } }, "导出目录:${treeUri?.let { DocumentFile.fromTreeUri(context, it)?.name } ?: "未选择"}",
label = { Text("端口") }, style = MaterialTheme.typography.bodySmall,
supportingText = { Text("465") }, color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.weight(1f), singleLine = true, modifier = Modifier.padding(top = 8.dp),
) )
} Row(
Spacer(Modifier.size(4.dp)) modifier = Modifier.fillMaxWidth().padding(top = 10.dp),
OutlinedTextField( horizontalArrangement = Arrangement.spacedBy(8.dp),
value = smtpUserInput, onValueChange = { smtpUserInput = it }, ) {
label = { Text("账号") }, OutlinedButton(onClick = { treeLauncher.launch(null) }, modifier = Modifier.weight(1f)) { 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 小时再次检查",