From 0c6b730115b146d6fec39ba83ce8f22b90a32501 Mon Sep 17 00:00:00 2001 From: Song <168455@qq.com> Date: Thu, 9 Jul 2026 16:34:23 +0800 Subject: [PATCH] ui: reorder & rename settings sections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bark → E-mail → SMS-fallback → Icons → Update → Maintenance Co-Authored-By: Claude Opus 4.8 (1M context) --- .../forwarder/ui/screens/SettingsScreen.kt | 188 +++++++++--------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/app/src/main/java/com/a2i/forwarder/ui/screens/SettingsScreen.kt b/app/src/main/java/com/a2i/forwarder/ui/screens/SettingsScreen.kt index b6856c6..9ae5047 100644 --- a/app/src/main/java/com/a2i/forwarder/ui/screens/SettingsScreen.kt +++ b/app/src/main/java/com/a2i/forwarder/ui/screens/SettingsScreen.kt @@ -172,44 +172,71 @@ fun SettingsScreen(onOpenLog: () -> Unit) { } item { - SectionCard("应用图标", subtitle = "导出 App 图标后,Bark 通知可按包名显示图标") { - OutlinedTextField( - value = iconPrefix, - onValueChange = { app.appScope.launch { app.settings.setIconPrefix(it) } }, - label = { Text("图标 URL 前缀") }, - supportingText = { Text("转发时 icon = 前缀 + 包名 + .png;留空则不显示图标") }, - modifier = Modifier.fillMaxWidth(), - singleLine = true, - ) - Text( - "导出目录:${treeUri?.let { DocumentFile.fromTreeUri(context, it)?.name } ?: "未选择"}", - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.onSurfaceVariant, - modifier = Modifier.padding(top = 8.dp), - ) - Row( - modifier = Modifier.fillMaxWidth().padding(top = 10.dp), - horizontalArrangement = Arrangement.spacedBy(8.dp), - ) { - OutlinedButton(onClick = { treeLauncher.launch(null) }, modifier = Modifier.weight(1f)) { Text("选择目录") } + 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( + value = smtpHostInput, onValueChange = { smtpHostInput = it }, + label = { Text("SMTP 主机") }, + supportingText = { Text("如 smtp.qq.com") }, + modifier = Modifier.weight(1.5f), singleLine = true, + ) + OutlinedTextField( + value = smtpPortInput, onValueChange = { smtpPortInput = it.filter { c -> c.isDigit() } }, + label = { 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( onClick = { - val u = treeUri ?: return@Button app.appScope.launch { - exporting = true - val r = IconExporter(context).exportAll(u) - exporting = false - exportResult = "共 ${r.total} 个,成功 ${r.ok},失败 ${r.fail}" + app.settings.setSmtpHost(smtpHostInput.trim()) + app.settings.setSmtpPort(smtpPortInput.trim().toIntOrNull() ?: 587) + app.settings.setSmtpUser(smtpUserInput.trim()) + app.settings.setSmtpPassword(smtpPasswordInput.trim()) + app.settings.setSmtpFrom(smtpFromInput.trim()) + app.settings.setEmailTo(emailToInput.trim()) } }, - enabled = treeUri != null && !exporting, - 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)) + modifier = Modifier.fillMaxWidth(), + ) { Text("保存电邮设置") } } } } @@ -284,77 +311,50 @@ fun SettingsScreen(onOpenLog: () -> Unit) { } item { - 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( - value = smtpHostInput, onValueChange = { smtpHostInput = it }, - label = { Text("SMTP 主机") }, - supportingText = { Text("如 smtp.qq.com") }, - modifier = Modifier.weight(1.5f), singleLine = true, - ) - OutlinedTextField( - value = smtpPortInput, onValueChange = { smtpPortInput = it.filter { c -> c.isDigit() } }, - label = { 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)) + SectionCard("应用图标", subtitle = "导出 App 图标后,Bark 通知可按包名显示图标") { + OutlinedTextField( + value = iconPrefix, + onValueChange = { app.appScope.launch { app.settings.setIconPrefix(it) } }, + label = { Text("图标 URL 前缀") }, + supportingText = { Text("转发时 icon = 前缀 + 包名 + .png;留空则不显示图标") }, + modifier = Modifier.fillMaxWidth(), + singleLine = true, + ) + Text( + "导出目录:${treeUri?.let { DocumentFile.fromTreeUri(context, it)?.name } ?: "未选择"}", + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(top = 8.dp), + ) + Row( + modifier = Modifier.fillMaxWidth().padding(top = 10.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + OutlinedButton(onClick = { treeLauncher.launch(null) }, modifier = Modifier.weight(1f)) { Text("选择目录") } Button( onClick = { + val u = treeUri ?: return@Button app.appScope.launch { - app.settings.setSmtpHost(smtpHostInput.trim()) - app.settings.setSmtpPort(smtpPortInput.trim().toIntOrNull() ?: 587) - app.settings.setSmtpUser(smtpUserInput.trim()) - app.settings.setSmtpPassword(smtpPasswordInput.trim()) - app.settings.setSmtpFrom(smtpFromInput.trim()) - app.settings.setEmailTo(emailToInput.trim()) + exporting = true + val r = IconExporter(context).exportAll(u) + exporting = false + exportResult = "共 ${r.total} 个,成功 ${r.ok},失败 ${r.fail}" } }, - modifier = Modifier.fillMaxWidth(), - ) { Text("保存电邮设置") } + enabled = treeUri != null && !exporting, + 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 { - SectionCard("关于与更新", subtitle = "版本检查(数据来自 GitHub Releases)") { + SectionCard("更新", subtitle = "版本检查(数据来自 Gitea Releases)") { com.a2i.forwarder.ui.SwitchRow( title = "自动检查更新", subtitle = "启动时检查,且距上次满 24 小时再次检查",