feat(v1.8.0): IMPL_03 Sync Settings - Trigger Visual Separation

- Restructure settings into two clear sections: Triggers & Performance
- Add sync_section_triggers and sync_section_network_performance strings (DE + EN)
- Group all 5 triggers together (Instant: onSave/onResume, Background: WiFi/Periodic/Boot)
- Move WiFi-Only + Parallel Downloads to separate "Network & Performance" section
- Place Manual Sync info card after triggers, before Performance section

Improves UX by logically grouping related settings. Triggers are now
in one cohesive block, separated from network/performance options.
Easier to find and understand sync configuration.
This commit is contained in:
inventory69
2026-02-10 14:30:56 +01:00
parent 68584461b3
commit eaac5a0775
3 changed files with 59 additions and 67 deletions

View File

@@ -32,9 +32,11 @@ import dev.dettmer.simplenotes.ui.settings.components.SettingsSectionHeader
import dev.dettmer.simplenotes.ui.settings.components.SettingsSwitch
/**
* Sync settings screen - Configurable Sync Triggers
* v1.5.0: Jetpack Compose Settings Redesign
* v1.6.0: Individual toggle for each sync trigger (onSave, onResume, WiFi-Connect, Periodic, Boot)
* Sync settings screen — Restructured for v1.8.0
*
* Two clear sections:
* 1. Sync Triggers (all 5 triggers grouped logically)
* 2. Network & Performance (WiFi-only + Parallel Downloads)
*/
@Composable
fun SyncSettingsScreen(
@@ -50,13 +52,9 @@ fun SyncSettingsScreen(
val triggerBoot by viewModel.triggerBoot.collectAsState()
val syncInterval by viewModel.syncInterval.collectAsState()
// 🆕 v1.8.0: Parallel Downloads
val maxParallelDownloads by viewModel.maxParallelDownloads.collectAsState()
// 🆕 v1.7.0: WiFi-only sync
val wifiOnlySync by viewModel.wifiOnlySync.collectAsState()
// Check if server is configured
val isServerConfigured = viewModel.isServerConfigured()
SettingsScaffold(
@@ -71,7 +69,7 @@ fun SyncSettingsScreen(
) {
Spacer(modifier = Modifier.height(8.dp))
// 🌟 v1.6.0: Offline Mode Warning if server not configured
// ── Offline Mode Warning ──
if (!isServerConfigured) {
SettingsInfoCard(
text = stringResource(R.string.sync_offline_mode_message),
@@ -89,37 +87,14 @@ fun SyncSettingsScreen(
}
// ═══════════════════════════════════════════════════════════════
// 🆕 v1.7.0: NETZWERK-EINSCHRÄNKUNG Section (Global für alle Trigger)
// SECTION 1: SYNC TRIGGERS
// ═══════════════════════════════════════════════════════════════
SettingsSectionHeader(text = stringResource(R.string.sync_section_network))
// WiFi-Only Sync Toggle - Gilt für ALLE Trigger außer WiFi-Connect
SettingsSwitch(
title = stringResource(R.string.sync_wifi_only_title),
subtitle = stringResource(R.string.sync_wifi_only_subtitle),
checked = wifiOnlySync,
onCheckedChange = { viewModel.setWifiOnlySync(it) },
icon = Icons.Default.Wifi,
enabled = isServerConfigured
)
// Info-Hinweis dass WiFi-Connect davon ausgenommen ist
if (wifiOnlySync && isServerConfigured) {
SettingsInfoCard(
text = stringResource(R.string.sync_wifi_only_hint)
)
}
SettingsDivider()
// ═══════════════════════════════════════════════════════════════
// SOFORT-SYNC Section
// ═══════════════════════════════════════════════════════════════
SettingsSectionHeader(text = stringResource(R.string.sync_section_triggers))
// ── Sofort-Sync ──
SettingsSectionHeader(text = stringResource(R.string.sync_section_instant))
// onSave Trigger
SettingsSwitch(
title = stringResource(R.string.sync_trigger_on_save_title),
subtitle = stringResource(R.string.sync_trigger_on_save_subtitle),
@@ -129,7 +104,6 @@ fun SyncSettingsScreen(
enabled = isServerConfigured
)
// onResume Trigger
SettingsSwitch(
title = stringResource(R.string.sync_trigger_on_resume_title),
subtitle = stringResource(R.string.sync_trigger_on_resume_subtitle),
@@ -139,15 +113,11 @@ fun SyncSettingsScreen(
enabled = isServerConfigured
)
SettingsDivider()
// ═══════════════════════════════════════════════════════════════
// HINTERGRUND-SYNC Section
// ═══════════════════════════════════════════════════════════════
Spacer(modifier = Modifier.height(4.dp))
// ── Hintergrund-Sync ──
SettingsSectionHeader(text = stringResource(R.string.sync_section_background))
// WiFi-Connect Trigger
SettingsSwitch(
title = stringResource(R.string.sync_trigger_wifi_connect_title),
subtitle = stringResource(R.string.sync_trigger_wifi_connect_subtitle),
@@ -157,7 +127,6 @@ fun SyncSettingsScreen(
enabled = isServerConfigured
)
// Periodic Trigger
SettingsSwitch(
title = stringResource(R.string.sync_trigger_periodic_title),
subtitle = stringResource(R.string.sync_trigger_periodic_subtitle),
@@ -167,7 +136,7 @@ fun SyncSettingsScreen(
enabled = isServerConfigured
)
// Periodic Interval Selection (only visible if periodic trigger is enabled)
// Interval-Auswahl (nur sichtbar wenn Periodic aktiv)
if (triggerPeriodic && isServerConfigured) {
Spacer(modifier = Modifier.height(8.dp))
@@ -198,15 +167,6 @@ fun SyncSettingsScreen(
Spacer(modifier = Modifier.height(8.dp))
}
SettingsDivider()
// ═══════════════════════════════════════════════════════════════
// ADVANCED Section (Boot Sync)
// ═══════════════════════════════════════════════════════════════
SettingsSectionHeader(text = stringResource(R.string.sync_section_advanced))
// Boot Trigger
SettingsSwitch(
title = stringResource(R.string.sync_trigger_boot_title),
subtitle = stringResource(R.string.sync_trigger_boot_subtitle),
@@ -218,7 +178,44 @@ fun SyncSettingsScreen(
Spacer(modifier = Modifier.height(8.dp))
// 🆕 v1.8.0: Max Parallel Downloads
// ── Info Card ──
val manualHintText = if (isServerConfigured) {
stringResource(R.string.sync_manual_hint)
} else {
stringResource(R.string.sync_manual_hint_disabled)
}
SettingsInfoCard(
text = manualHintText
)
SettingsDivider()
// ═══════════════════════════════════════════════════════════════
// SECTION 2: NETZWERK & PERFORMANCE
// ═══════════════════════════════════════════════════════════════
SettingsSectionHeader(text = stringResource(R.string.sync_section_network_performance))
// WiFi-Only Toggle
SettingsSwitch(
title = stringResource(R.string.sync_wifi_only_title),
subtitle = stringResource(R.string.sync_wifi_only_subtitle),
checked = wifiOnlySync,
onCheckedChange = { viewModel.setWifiOnlySync(it) },
icon = Icons.Default.Wifi,
enabled = isServerConfigured
)
if (wifiOnlySync && isServerConfigured) {
SettingsInfoCard(
text = stringResource(R.string.sync_wifi_only_hint)
)
}
Spacer(modifier = Modifier.height(8.dp))
// Parallel Downloads
val parallelOptions = listOf(
RadioOption(
value = 1,
@@ -254,19 +251,6 @@ fun SyncSettingsScreen(
onValueSelected = { viewModel.setMaxParallelDownloads(it) }
)
SettingsDivider()
// Manual Sync Info
val manualHintText = if (isServerConfigured) {
stringResource(R.string.sync_manual_hint)
} else {
stringResource(R.string.sync_manual_hint_disabled)
}
SettingsInfoCard(
text = manualHintText
)
Spacer(modifier = Modifier.height(16.dp))
}
}

View File

@@ -291,6 +291,10 @@
<string name="sync_section_background">📡 Hintergrund-Sync</string>
<string name="sync_section_advanced">⚙️ Erweitert</string>
<!-- 🆕 v1.8.0: Sync Settings Restructure -->
<string name="sync_section_triggers">Sync-Auslöser</string>
<string name="sync_section_network_performance">Netzwerk &amp; Performance</string>
<string name="sync_wifi_only_hint">💡 Der WiFi-Connect Trigger ist davon nicht betroffen \u2013 er synchronisiert immer wenn WiFi verbunden wird.</string>
<string name="sync_wifi_only_error">Sync funktioniert nur wenn WLAN verbunden ist</string>

View File

@@ -291,6 +291,10 @@
<string name="sync_section_background">📡 Background Sync</string>
<string name="sync_section_advanced">⚙️ Advanced</string>
<!-- 🆕 v1.8.0: Sync Settings Restructure -->
<string name="sync_section_triggers">Sync Triggers</string>
<string name="sync_section_network_performance">Network &amp; Performance</string>
<string name="sync_wifi_only_hint">💡 WiFi-Connect Trigger is not affected by this setting \u2013 it always syncs when WiFi is connected.</string>
<string name="sync_wifi_only_error">Sync only works when WiFi is connected</string>