From ebab347d4b3b095dec7844ea60bb6789d6ee84fd Mon Sep 17 00:00:00 2001 From: inventory69 Date: Mon, 26 Jan 2026 23:21:13 +0100 Subject: [PATCH] fix: Notification opens ComposeMainActivity, WiFi-Only toggle in own section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: 1. Notification click now opens ComposeMainActivity instead of legacy MainActivity 2. WiFi-Only toggle moved to its own 'Network Restriction' section at top of sync settings 3. Added hint explaining WiFi-Connect trigger is not affected by WiFi-Only setting UI Changes: - New section header: 'Network Restriction' / 'Netzwerk-Einschränkung' - WiFi-Only toggle now clearly separated from sync triggers - Info card shows when WiFi-Only is enabled explaining the exception --- .../simplenotes/sync/NetworkMonitor.kt | 71 ++++++++++++++----- .../ui/settings/screens/SyncSettingsScreen.kt | 35 ++++++--- .../simplenotes/utils/NotificationHelper.kt | 12 ++-- .../app/src/main/res/values-de/strings.xml | 5 +- android/app/src/main/res/values/strings.xml | 5 +- 5 files changed, 93 insertions(+), 35 deletions(-) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/sync/NetworkMonitor.kt b/android/app/src/main/java/dev/dettmer/simplenotes/sync/NetworkMonitor.kt index f20bfbe..0858d6e 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/sync/NetworkMonitor.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/sync/NetworkMonitor.kt @@ -68,15 +68,20 @@ class NetworkMonitor(private val context: Context) { lastConnectedNetworkId = currentNetworkId - // Auto-Sync check - val autoSyncEnabled = prefs.getBoolean(Constants.KEY_AUTO_SYNC, false) - Logger.d(TAG, " Auto-Sync enabled: $autoSyncEnabled") + // WiFi-Connect Trigger prüfen - NICHT KEY_AUTO_SYNC! + // Der Callback ist registriert WEIL KEY_SYNC_TRIGGER_WIFI_CONNECT = true + // Aber defensive Prüfung für den Fall, dass Settings sich geändert haben + val wifiConnectEnabled = prefs.getBoolean( + Constants.KEY_SYNC_TRIGGER_WIFI_CONNECT, + Constants.DEFAULT_TRIGGER_WIFI_CONNECT + ) + Logger.d(TAG, " WiFi-Connect trigger enabled: $wifiConnectEnabled") - if (autoSyncEnabled) { - Logger.d(TAG, " ✅ Triggering WorkManager...") + if (wifiConnectEnabled) { + Logger.d(TAG, " ✅ Triggering WiFi-Connect sync...") triggerWifiConnectSync() } else { - Logger.d(TAG, " ❌ Auto-sync disabled - not triggering") + Logger.d(TAG, " ⏭️ WiFi-Connect trigger disabled in settings") } } else { Logger.d(TAG, " ⚠️ Same WiFi network as before - ignoring (no network change)") @@ -140,23 +145,55 @@ class NetworkMonitor(private val context: Context) { /** * Startet WorkManager mit Network Constraints + NetworkCallback + * + * 🆕 v1.7.0: Überarbeitete Logik - WiFi-Connect Trigger funktioniert UNABHÄNGIG von KEY_AUTO_SYNC + * - KEY_AUTO_SYNC + KEY_SYNC_TRIGGER_PERIODIC → Periodic Sync + * - KEY_SYNC_TRIGGER_WIFI_CONNECT → WiFi-Connect Trigger (unabhängig!) */ fun startMonitoring() { - val autoSyncEnabled = prefs.getBoolean(Constants.KEY_AUTO_SYNC, false) + Logger.d(TAG, "🚀 NetworkMonitor.startMonitoring() called") - if (!autoSyncEnabled) { - Logger.d(TAG, "Auto-sync disabled - stopping all monitoring") - stopMonitoring() - return + val autoSyncEnabled = prefs.getBoolean(Constants.KEY_AUTO_SYNC, false) + val periodicEnabled = prefs.getBoolean(Constants.KEY_SYNC_TRIGGER_PERIODIC, Constants.DEFAULT_TRIGGER_PERIODIC) + val wifiConnectEnabled = prefs.getBoolean(Constants.KEY_SYNC_TRIGGER_WIFI_CONNECT, Constants.DEFAULT_TRIGGER_WIFI_CONNECT) + + Logger.d(TAG, " Settings: autoSync=$autoSyncEnabled, periodic=$periodicEnabled, wifiConnect=$wifiConnectEnabled") + + // 1. Periodic Sync (nur wenn KEY_AUTO_SYNC UND KEY_SYNC_TRIGGER_PERIODIC aktiv) + if (autoSyncEnabled && periodicEnabled) { + Logger.d(TAG, "📅 Starting periodic sync...") + startPeriodicSync() + } else { + WorkManager.getInstance(context).cancelUniqueWork(AUTO_SYNC_WORK_NAME) + Logger.d(TAG, "⏭️ Periodic sync disabled (autoSync=$autoSyncEnabled, periodic=$periodicEnabled)") } - Logger.d(TAG, "🚀 Starting NetworkMonitor (WorkManager + WiFi Callback)") + // 2. WiFi-Connect Trigger (🆕 UNABHÄNGIG von KEY_AUTO_SYNC!) + if (wifiConnectEnabled) { + Logger.d(TAG, "📶 Starting WiFi monitoring...") + startWifiMonitoring() + } else { + stopWifiMonitoring() + Logger.d(TAG, "⏭️ WiFi-Connect trigger disabled") + } - // 1. WorkManager für periodic sync - startPeriodicSync() - - // 2. NetworkCallback für WiFi-Connect Detection - startWifiMonitoring() + // 3. Logging für Debug + if (!autoSyncEnabled && !wifiConnectEnabled) { + Logger.d(TAG, "🛑 No background triggers active") + } + } + + /** + * 🆕 v1.7.0: Stoppt nur WiFi-Monitoring, nicht den gesamten NetworkMonitor + */ + private fun stopWifiMonitoring() { + try { + connectivityManager.unregisterNetworkCallback(networkCallback) + Logger.d(TAG, "🛑 WiFi NetworkCallback unregistered") + } catch (e: Exception) { + // Already unregistered - das ist OK + Logger.d(TAG, " WiFi callback already unregistered") + } } /** diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SyncSettingsScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SyncSettingsScreen.kt index 2991cb5..d734edf 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SyncSettingsScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SyncSettingsScreen.kt @@ -85,6 +85,31 @@ fun SyncSettingsScreen( Spacer(modifier = Modifier.height(8.dp)) } + // ═══════════════════════════════════════════════════════════════ + // 🆕 v1.7.0: NETZWERK-EINSCHRÄNKUNG Section (Global für alle Trigger) + // ═══════════════════════════════════════════════════════════════ + + 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 // ═══════════════════════════════════════════════════════════════ @@ -111,16 +136,6 @@ fun SyncSettingsScreen( enabled = isServerConfigured ) - // 🆕 v1.7.0: WiFi-Only Sync 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 - ) - SettingsDivider() // ═══════════════════════════════════════════════════════════════ diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/utils/NotificationHelper.kt b/android/app/src/main/java/dev/dettmer/simplenotes/utils/NotificationHelper.kt index b3ab6e5..62d2eda 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/utils/NotificationHelper.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/utils/NotificationHelper.kt @@ -11,7 +11,7 @@ import android.os.Handler import android.os.Looper import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat -import dev.dettmer.simplenotes.MainActivity +import dev.dettmer.simplenotes.ui.main.ComposeMainActivity object NotificationHelper { @@ -58,7 +58,7 @@ object NotificationHelper { * Zeigt Erfolgs-Notification nach Sync */ fun showSyncSuccessNotification(context: Context, syncedCount: Int) { - val intent = Intent(context, MainActivity::class.java).apply { + val intent = Intent(context, ComposeMainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } @@ -154,7 +154,7 @@ object NotificationHelper { * Zeigt Notification bei erkanntem Konflikt */ fun showConflictNotification(context: Context, conflictCount: Int) { - val intent = Intent(context, MainActivity::class.java) + val intent = Intent(context, ComposeMainActivity::class.java) val pendingIntent = PendingIntent.getActivity( context, 0, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT @@ -229,7 +229,7 @@ object NotificationHelper { */ fun showSyncSuccess(context: Context, count: Int) { // PendingIntent für App-Öffnung - val intent = Intent(context, MainActivity::class.java).apply { + val intent = Intent(context, ComposeMainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP } val pendingIntent = PendingIntent.getActivity( @@ -260,7 +260,7 @@ object NotificationHelper { */ fun showSyncError(context: Context, message: String) { // PendingIntent für App-Öffnung - val intent = Intent(context, MainActivity::class.java).apply { + val intent = Intent(context, ComposeMainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP } val pendingIntent = PendingIntent.getActivity( @@ -297,7 +297,7 @@ object NotificationHelper { */ fun showSyncWarning(context: Context, hoursSinceLastSync: Long) { // PendingIntent für App-Öffnung - val intent = Intent(context, MainActivity::class.java).apply { + val intent = Intent(context, ComposeMainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP } val pendingIntent = PendingIntent.getActivity( diff --git a/android/app/src/main/res/values-de/strings.xml b/android/app/src/main/res/values-de/strings.xml index 6dce156..81a188d 100644 --- a/android/app/src/main/res/values-de/strings.xml +++ b/android/app/src/main/res/values-de/strings.xml @@ -206,10 +206,13 @@ ℹ️ Auto-Sync:\n\n• Prüft alle 30 Min ob Server erreichbar\n• Funktioniert bei jeder WiFi-Verbindung\n• Läuft auch im Hintergrund\n• Minimaler Akkuverbrauch (~0.4%%/Tag) + 📶 Netzwerk-Einschränkung 📲 Sofort-Sync 📡 Hintergrund-Sync ⚙️ Erweitert + 💡 Der WiFi-Connect Trigger ist davon nicht betroffen \u2013 er synchronisiert immer wenn WiFi verbunden wird. + Nach dem Speichern Sync sofort nach jeder Änderung @@ -228,7 +231,7 @@ Sync nur im WLAN Sync wird nur durchgeführt wenn WLAN verbunden ist. Spart mobiles Datenvolumen und verhindert lange Wartezeit. - Sync nur im WLAN möglich + Sync nur im WLAN möglich Manueller Sync (Toolbar/Pull-to-Refresh) ist ebenfalls verfügbar. Sync ist im Offline-Modus nicht verfügbar. diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index e94abb8..414911d 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -206,10 +206,13 @@ ℹ️ Auto-Sync:\n\n• Checks every 30 min if server is reachable\n• Works on any WiFi connection\n• Runs in background\n• Minimal battery usage (~0.4%%/day) + 📶 Network Restriction 📲 Instant Sync 📡 Background Sync ⚙️ Advanced + 💡 WiFi-Connect Trigger is not affected by this setting \u2013 it always syncs when WiFi is connected. + After Saving Sync immediately after each change @@ -228,7 +231,7 @@ WiFi-only sync Sync only when connected to WiFi. Saves mobile data and prevents long wait times. - Sync only works when connected to WiFi + Sync only works when connected to WiFi Manual sync (toolbar/pull-to-refresh) is also available. Sync is not available in offline mode.