diff --git a/app/src/main/kotlin/org/libremail/ui/settings/SettingsScreen.kt b/app/src/main/kotlin/org/libremail/ui/settings/SettingsScreen.kt
index da70170..9a7cdd8 100644
--- a/app/src/main/kotlin/org/libremail/ui/settings/SettingsScreen.kt
+++ b/app/src/main/kotlin/org/libremail/ui/settings/SettingsScreen.kt
@@ -132,41 +132,6 @@ fun SettingsScreen(
ClickRow(title = stringResource(R.string.settings_add_account), onClick = onAddAccount)
HorizontalDivider()
- SectionHeader(stringResource(R.string.settings_notifications))
- SwitchRow(
- title = stringResource(R.string.settings_new_mail),
- checked = settings.newMailNotifications,
- onCheckedChange = viewModel::setNewMailNotifications,
- subtitle = stringResource(R.string.settings_new_mail_summary),
- )
- HorizontalDivider()
-
- SectionHeader(stringResource(R.string.settings_contacts))
- ContactAutocompleteRow(
- state = contactsState,
- onClick = {
- when (contactsState) {
- // Already on: send to system settings, the only place to turn it back off.
- ContactPermissionState.GRANTED ->
- runCatching { context.startActivity(viewModel.contactsSettingsIntent()) }
- // Re-requestable in-app: explain first (#128), then launch the system dialog.
- ContactPermissionState.DENIED -> showContactsRationale = true
- // Permanently denied: an in-app request is a no-op, so deep-link to settings.
- ContactPermissionState.BLOCKED -> showContactsBlocked = true
- }
- },
- )
- HorizontalDivider()
-
- SectionHeader(stringResource(R.string.settings_appearance))
- SwitchRow(
- title = stringResource(R.string.settings_dynamic_color),
- checked = settings.dynamicColor,
- onCheckedChange = viewModel::setDynamicColor,
- subtitle = stringResource(R.string.settings_dynamic_color_summary),
- )
- HorizontalDivider()
-
SectionHeader(stringResource(R.string.settings_downloading))
RadioRow(
title = stringResource(R.string.fetch_always),
@@ -188,11 +153,35 @@ fun SettingsScreen(
)
HorizontalDivider()
- SectionHeader(stringResource(R.string.settings_diagnostics))
- ClickRow(
- title = stringResource(R.string.settings_report_problem),
- subtitle = stringResource(R.string.settings_report_problem_summary),
- onClick = onReportProblem,
+ SectionHeader(stringResource(R.string.settings_contacts))
+ ContactAutocompleteRow(
+ state = contactsState,
+ onClick = {
+ when (contactsState) {
+ // Already on: send to system settings, the only place to turn it back off.
+ ContactPermissionState.GRANTED ->
+ runCatching { context.startActivity(viewModel.contactsSettingsIntent()) }
+ // Re-requestable in-app: explain first (#128), then launch the system dialog.
+ ContactPermissionState.DENIED -> showContactsRationale = true
+ // Permanently denied: an in-app request is a no-op, so deep-link to settings.
+ ContactPermissionState.BLOCKED -> showContactsBlocked = true
+ }
+ },
+ )
+ HorizontalDivider()
+
+ SectionHeader(stringResource(R.string.settings_appearance))
+ Text(
+ text = stringResource(R.string.settings_appearance_summary),
+ style = MaterialTheme.typography.bodySmall,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ modifier = Modifier.padding(horizontal = 16.dp),
+ )
+ SwitchRow(
+ title = stringResource(R.string.settings_dynamic_color),
+ checked = settings.dynamicColor,
+ onCheckedChange = viewModel::setDynamicColor,
+ subtitle = stringResource(R.string.settings_dynamic_color_summary),
)
HorizontalDivider()
@@ -205,6 +194,15 @@ fun SettingsScreen(
)
HorizontalDivider()
+ SectionHeader(stringResource(R.string.settings_notifications))
+ SwitchRow(
+ title = stringResource(R.string.settings_new_mail),
+ checked = settings.newMailNotifications,
+ onCheckedChange = viewModel::setNewMailNotifications,
+ subtitle = stringResource(R.string.settings_new_mail_summary),
+ )
+ HorizontalDivider()
+
// Global device-only retention default (issue #13); accounts may override it.
RetentionSection(
count = settings.retentionCount,
@@ -215,6 +213,15 @@ fun SettingsScreen(
)
HorizontalDivider()
+ // Standalone trailing action, no section header — matches AccountSettingsScreen's
+ // "Remove account" row; self-explanatory as the last item in the list (#158).
+ ClickRow(
+ title = stringResource(R.string.settings_report_problem),
+ subtitle = stringResource(R.string.settings_report_problem_summary),
+ onClick = onReportProblem,
+ )
+ HorizontalDivider()
+
AdvancedHeader(expanded = advancedExpanded, onToggle = viewModel::toggleAdvanced)
AnimatedVisibility(visible = advancedExpanded) {
Column {
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5f85910..976335b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -224,13 +224,13 @@
Always on-demand
Sync only message headers; download a message\'s content when you open it.
Notifications
- New-mail notifications
+ New mail notifications
Show a notification when new mail arrives
No accounts yet
Remove account
- Backup
+ Settings Backup
Include settings in Android Backup
Let Android back up your LibreMail preferences (Google Auto Backup) so they restore when you set up a new device. Your mail, accounts, passwords, and encryption keys are never backed up — only app settings. Off by default; uses Google infrastructure.
@@ -278,6 +278,7 @@
Sound & vibration
Manage sound, vibration, and importance in Android settings
Appearance
+ Match device theme\nMaterial You theming (Android 12+)
Use wallpaper colors
Material You dynamic theming (Android 12+)
Add account
@@ -319,7 +320,6 @@
Open settings
- Diagnostics
Report a problem
Capture diagnostics you can review and optionally send
Problem reports