From 64b2cfaf78ab95c9cfe52602373418050f36bd8c Mon Sep 17 00:00:00 2001 From: inventory69 Date: Thu, 15 Jan 2026 11:02:38 +0100 Subject: [PATCH 01/12] v1.5.0: Jetpack Compose Settings Redesign + Fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Features: - ✨ Complete Settings UI redesign with Jetpack Compose - 🎨 Material 3 Design with Dynamic Colors (Material You) - 📊 6 logical settings groups in separate screens: * Server Settings (URL, Credentials, Connection Test) * Sync Settings (Auto-Sync, Interval 15/30/60 min) * Markdown Desktop Integration (Auto-Sync for .md files) * Backup & Restore (Local/Server) * About this App (Version, GitHub, License) * Debug & Diagnostics (File Logging, Log Export) Bugfixes (ported from old SettingsActivity): - 🔧 Fix #1: Server URL prefix (http://|https://) auto-set on init - 🔧 Fix #2: Battery optimization dialog on Auto-Sync enable - 🔧 Fix #3: Markdown initial export on feature activation Implementation Details: - SettingsViewModel with Kotlin Flows state management - SettingsEvent system for Activity-level actions (dialogs, intents) - Reusable Compose components (SettingsCard, Switch, RadioGroup, etc.) - Progress dialog for markdown initial export - Edge-to-edge display with system bar handling - Navigation Compose for screen transitions with back button Breaking Changes: - Old SettingsActivity.kt (1147 lines) no longer used (Can be removed in future as legacy code) --- android/app/build.gradle.kts | 20 +- android/app/src/main/AndroidManifest.xml | 8 +- .../dev/dettmer/simplenotes/MainActivity.kt | 3 +- .../ui/settings/ComposeSettingsActivity.kt | 208 ++++++++ .../ui/settings/SettingsNavigation.kt | 85 +++ .../simplenotes/ui/settings/SettingsRoute.kt | 15 + .../ui/settings/SettingsViewModel.kt | 493 ++++++++++++++++++ .../ui/settings/components/SettingsCard.kt | 113 ++++ .../settings/components/SettingsComponents.kt | 152 ++++++ .../settings/components/SettingsRadioGroup.kt | 94 ++++ .../settings/components/SettingsScaffold.kt | 57 ++ .../ui/settings/components/SettingsSwitch.kt | 83 +++ .../ui/settings/screens/AboutScreen.kt | 218 ++++++++ .../settings/screens/BackupSettingsScreen.kt | 256 +++++++++ .../settings/screens/DebugSettingsScreen.kt | 148 ++++++ .../screens/MarkdownSettingsScreen.kt | 128 +++++ .../settings/screens/ServerSettingsScreen.kt | 241 +++++++++ .../ui/settings/screens/SettingsMainScreen.kt | 143 +++++ .../ui/settings/screens/SyncSettingsScreen.kt | 112 ++++ android/build.gradle.kts | 1 + android/gradle/libs.versions.toml | 17 + 21 files changed, 2591 insertions(+), 4 deletions(-) create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/ComposeSettingsActivity.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsNavigation.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsRoute.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsViewModel.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsCard.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsComponents.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsRadioGroup.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsScaffold.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsSwitch.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/BackupSettingsScreen.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/DebugSettingsScreen.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/MarkdownSettingsScreen.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/ServerSettingsScreen.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SettingsMainScreen.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SyncSettingsScreen.kt diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 495c3ea..9e188b2 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -1,6 +1,7 @@ plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) // v1.5.0: Jetpack Compose Compiler // ⚡ v1.3.1: ktlint deaktiviert wegen Parser-Problemen, aktivieren in v1.4.0 // alias(libs.plugins.ktlint) alias(libs.plugins.detekt) @@ -20,8 +21,8 @@ android { applicationId = "dev.dettmer.simplenotes" minSdk = 24 targetSdk = 36 - versionCode = 12 // 🔧 v1.4.1: Bugfixes (Root-Delete, Checklist Compat) - versionName = "1.4.1" // 🔧 v1.4.1: Root-Folder Delete Fix, Checklisten-Sync Abwärtskompatibilität + versionCode = 13 // 🔧 v1.5.0: Jetpack Compose Settings Redesign + versionName = "1.5.0" // 🔧 v1.5.0: Jetpack Compose Settings Redesign testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } @@ -96,6 +97,7 @@ android { buildFeatures { viewBinding = true buildConfig = true // Enable BuildConfig generation + compose = true // v1.5.0: Jetpack Compose für Settings Redesign } compileOptions { @@ -135,6 +137,20 @@ dependencies { // SwipeRefreshLayout für Pull-to-Refresh implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") + // ═══════════════════════════════════════════════════════════════════════ + // v1.5.0: Jetpack Compose für Settings Redesign + // ═══════════════════════════════════════════════════════════════════════ + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.ui.graphics) + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.compose.material3) + implementation(libs.androidx.compose.material.icons) + implementation(libs.androidx.activity.compose) + implementation(libs.androidx.navigation.compose) + implementation(libs.androidx.lifecycle.runtime.compose) + debugImplementation(libs.androidx.compose.ui.tooling) + // Testing (bleiben so) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index be931a7..0231cc6 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -43,11 +43,17 @@ android:windowSoftInputMode="adjustResize" android:parentActivityName=".MainActivity" /> - + + + + + Toast.makeText(context, message, Toast.LENGTH_SHORT).show() + } + } + + SettingsNavHost( + navController = navController, + viewModel = viewModel, + onFinish = { + setResult(RESULT_OK) + finish() + } + ) + } + } + } + + /** + * Collect events from ViewModel for Activity-level actions + * v1.5.0: Ported from old SettingsActivity + */ + private fun collectViewModelEvents() { + lifecycleScope.launch { + viewModel.events.collect { event -> + when (event) { + is SettingsViewModel.SettingsEvent.RequestBatteryOptimization -> { + checkBatteryOptimization() + } + is SettingsViewModel.SettingsEvent.RestartNetworkMonitor -> { + restartNetworkMonitor() + } + } + } + } + } + + /** + * Check if battery optimization is disabled for this app + * v1.5.0: Ported from old SettingsActivity + */ + private fun checkBatteryOptimization() { + val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager + + if (!powerManager.isIgnoringBatteryOptimizations(packageName)) { + showBatteryOptimizationDialog() + } + } + + /** + * Show dialog asking user to disable battery optimization + * v1.5.0: Ported from old SettingsActivity + */ + private fun showBatteryOptimizationDialog() { + AlertDialog.Builder(this) + .setTitle("Hintergrund-Synchronisation") + .setMessage( + "Damit die App im Hintergrund synchronisieren kann, " + + "muss die Akku-Optimierung deaktiviert werden.\n\n" + + "Bitte wähle 'Nicht optimieren' für Simple Notes." + ) + .setPositiveButton("Einstellungen öffnen") { _, _ -> + openBatteryOptimizationSettings() + } + .setNegativeButton("Später") { dialog, _ -> + dialog.dismiss() + } + .setCancelable(false) + .show() + } + + /** + * Open system battery optimization settings + * v1.5.0: Ported from old SettingsActivity + */ + private fun openBatteryOptimizationSettings() { + try { + val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) + intent.data = Uri.parse("package:$packageName") + startActivity(intent) + } catch (e: Exception) { + Logger.w(TAG, "Failed to open battery optimization settings: ${e.message}") + // Fallback: Open general battery settings + try { + val intent = Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) + startActivity(intent) + } catch (e2: Exception) { + Logger.w(TAG, "Failed to open fallback battery settings: ${e2.message}") + Toast.makeText(this, "Bitte Akku-Optimierung manuell deaktivieren", Toast.LENGTH_LONG).show() + } + } + } + + /** + * Restart the network monitor after sync settings change + * v1.5.0: Ported from old SettingsActivity + */ + private fun restartNetworkMonitor() { + try { + val app = application as SimpleNotesApplication + Logger.d(TAG, "🔄 Restarting NetworkMonitor with new settings") + app.networkMonitor.stopMonitoring() + app.networkMonitor.startMonitoring() + Logger.d(TAG, "✅ NetworkMonitor restarted successfully") + } catch (e: Exception) { + Logger.e(TAG, "❌ Failed to restart NetworkMonitor: ${e.message}") + } + } +} + +/** + * Material 3 Theme with Dynamic Colors support + */ +@Composable +fun SimpleNotesSettingsTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val context = LocalContext.current + + val colorScheme = when { + // Dynamic colors are available on Android 12+ + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + if (darkTheme) { + dynamicDarkColorScheme(context) + } else { + dynamicLightColorScheme(context) + } + } + // Fallback to static Material 3 colors + darkTheme -> darkColorScheme() + else -> lightColorScheme() + } + + MaterialTheme( + colorScheme = colorScheme, + content = content + ) +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsNavigation.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsNavigation.kt new file mode 100644 index 0000000..2b8f5d9 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsNavigation.kt @@ -0,0 +1,85 @@ +package dev.dettmer.simplenotes.ui.settings + +import androidx.compose.runtime.Composable +import androidx.navigation.NavHostController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import dev.dettmer.simplenotes.ui.settings.screens.AboutScreen +import dev.dettmer.simplenotes.ui.settings.screens.BackupSettingsScreen +import dev.dettmer.simplenotes.ui.settings.screens.DebugSettingsScreen +import dev.dettmer.simplenotes.ui.settings.screens.MarkdownSettingsScreen +import dev.dettmer.simplenotes.ui.settings.screens.ServerSettingsScreen +import dev.dettmer.simplenotes.ui.settings.screens.SettingsMainScreen +import dev.dettmer.simplenotes.ui.settings.screens.SyncSettingsScreen + +/** + * Settings navigation host with all routes + * v1.5.0: Jetpack Compose Settings Redesign + */ +@Composable +fun SettingsNavHost( + navController: NavHostController, + viewModel: SettingsViewModel, + onFinish: () -> Unit +) { + NavHost( + navController = navController, + startDestination = SettingsRoute.Main.route + ) { + // Main Settings Overview + composable(SettingsRoute.Main.route) { + SettingsMainScreen( + viewModel = viewModel, + onNavigate = { route -> navController.navigate(route.route) }, + onBack = onFinish + ) + } + + // Server Settings + composable(SettingsRoute.Server.route) { + ServerSettingsScreen( + viewModel = viewModel, + onBack = { navController.popBackStack() } + ) + } + + // Sync Settings + composable(SettingsRoute.Sync.route) { + SyncSettingsScreen( + viewModel = viewModel, + onBack = { navController.popBackStack() } + ) + } + + // Markdown Settings + composable(SettingsRoute.Markdown.route) { + MarkdownSettingsScreen( + viewModel = viewModel, + onBack = { navController.popBackStack() } + ) + } + + // Backup Settings + composable(SettingsRoute.Backup.route) { + BackupSettingsScreen( + viewModel = viewModel, + onBack = { navController.popBackStack() } + ) + } + + // About Screen + composable(SettingsRoute.About.route) { + AboutScreen( + onBack = { navController.popBackStack() } + ) + } + + // Debug Settings + composable(SettingsRoute.Debug.route) { + DebugSettingsScreen( + viewModel = viewModel, + onBack = { navController.popBackStack() } + ) + } + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsRoute.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsRoute.kt new file mode 100644 index 0000000..3ce1c25 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsRoute.kt @@ -0,0 +1,15 @@ +package dev.dettmer.simplenotes.ui.settings + +/** + * Navigation routes for Settings screens + * v1.5.0: Jetpack Compose Settings Redesign + */ +sealed class SettingsRoute(val route: String) { + data object Main : SettingsRoute("settings_main") + data object Server : SettingsRoute("settings_server") + data object Sync : SettingsRoute("settings_sync") + data object Markdown : SettingsRoute("settings_markdown") + data object Backup : SettingsRoute("settings_backup") + data object About : SettingsRoute("settings_about") + data object Debug : SettingsRoute("settings_debug") +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsViewModel.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsViewModel.kt new file mode 100644 index 0000000..533240c --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsViewModel.kt @@ -0,0 +1,493 @@ +package dev.dettmer.simplenotes.ui.settings + +import android.app.Application +import android.content.Context +import android.net.Uri +import android.util.Log +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.viewModelScope +import dev.dettmer.simplenotes.backup.BackupManager +import dev.dettmer.simplenotes.backup.RestoreMode +import dev.dettmer.simplenotes.sync.WebDavSyncService +import dev.dettmer.simplenotes.utils.Constants +import dev.dettmer.simplenotes.utils.Logger +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.net.HttpURLConnection +import java.net.URL + +/** + * ViewModel for Settings screens + * v1.5.0: Jetpack Compose Settings Redesign + * + * Manages all settings state and actions across the Settings navigation graph. + */ +class SettingsViewModel(application: Application) : AndroidViewModel(application) { + + companion object { + private const val TAG = "SettingsViewModel" + private const val CONNECTION_TIMEOUT_MS = 3000 + } + + private val prefs = application.getSharedPreferences(Constants.PREFS_NAME, Context.MODE_PRIVATE) + val backupManager = BackupManager(application) + + // ═══════════════════════════════════════════════════════════════════════ + // Server Settings State + // ═══════════════════════════════════════════════════════════════════════ + + // v1.5.0 Fix: Initialize URL with protocol prefix if empty + private val storedUrl = prefs.getString(Constants.KEY_SERVER_URL, "") ?: "" + private val initialUrl = if (storedUrl.isEmpty()) "http://" else storedUrl + + private val _serverUrl = MutableStateFlow(initialUrl) + val serverUrl: StateFlow = _serverUrl.asStateFlow() + + private val _username = MutableStateFlow(prefs.getString(Constants.KEY_USERNAME, "") ?: "") + val username: StateFlow = _username.asStateFlow() + + private val _password = MutableStateFlow(prefs.getString(Constants.KEY_PASSWORD, "") ?: "") + val password: StateFlow = _password.asStateFlow() + + // v1.5.0 Fix: isHttps based on stored URL (false = HTTP if empty) + private val _isHttps = MutableStateFlow(storedUrl.startsWith("https://")) + val isHttps: StateFlow = _isHttps.asStateFlow() + + private val _serverStatus = MutableStateFlow(ServerStatus.Unknown) + val serverStatus: StateFlow = _serverStatus.asStateFlow() + + // ═══════════════════════════════════════════════════════════════════════ + // Events (for Activity-level actions like dialogs, intents) + // ═══════════════════════════════════════════════════════════════════════ + + private val _events = MutableSharedFlow() + val events: SharedFlow = _events.asSharedFlow() + + // ═══════════════════════════════════════════════════════════════════════ + // Markdown Export Progress State + // ═══════════════════════════════════════════════════════════════════════ + + private val _markdownExportProgress = MutableStateFlow(null) + val markdownExportProgress: StateFlow = _markdownExportProgress.asStateFlow() + + // ═══════════════════════════════════════════════════════════════════════ + // Sync Settings State + // ═══════════════════════════════════════════════════════════════════════ + + private val _autoSyncEnabled = MutableStateFlow(prefs.getBoolean(Constants.KEY_AUTO_SYNC, false)) + val autoSyncEnabled: StateFlow = _autoSyncEnabled.asStateFlow() + + private val _syncInterval = MutableStateFlow( + prefs.getLong(Constants.PREF_SYNC_INTERVAL_MINUTES, Constants.DEFAULT_SYNC_INTERVAL_MINUTES) + ) + val syncInterval: StateFlow = _syncInterval.asStateFlow() + + // ═══════════════════════════════════════════════════════════════════════ + // Markdown Settings State + // ═══════════════════════════════════════════════════════════════════════ + + private val _markdownAutoSync = MutableStateFlow( + prefs.getBoolean(Constants.KEY_MARKDOWN_EXPORT, false) && + prefs.getBoolean(Constants.KEY_MARKDOWN_AUTO_IMPORT, false) + ) + val markdownAutoSync: StateFlow = _markdownAutoSync.asStateFlow() + + // ═══════════════════════════════════════════════════════════════════════ + // Debug Settings State + // ═══════════════════════════════════════════════════════════════════════ + + private val _fileLoggingEnabled = MutableStateFlow( + prefs.getBoolean(Constants.KEY_FILE_LOGGING_ENABLED, false) + ) + val fileLoggingEnabled: StateFlow = _fileLoggingEnabled.asStateFlow() + + // ═══════════════════════════════════════════════════════════════════════ + // UI State + // ═══════════════════════════════════════════════════════════════════════ + + private val _isSyncing = MutableStateFlow(false) + val isSyncing: StateFlow = _isSyncing.asStateFlow() + + private val _isBackupInProgress = MutableStateFlow(false) + val isBackupInProgress: StateFlow = _isBackupInProgress.asStateFlow() + + private val _showToast = MutableSharedFlow() + val showToast: SharedFlow = _showToast.asSharedFlow() + + // ═══════════════════════════════════════════════════════════════════════ + // Server Settings Actions + // ═══════════════════════════════════════════════════════════════════════ + + fun updateServerUrl(url: String) { + _serverUrl.value = url + saveServerSettings() + } + + fun updateProtocol(useHttps: Boolean) { + _isHttps.value = useHttps + val currentUrl = _serverUrl.value + + // v1.5.0 Fix: Automatisch Prefix setzen, auch bei leerem Feld + val newUrl = if (useHttps) { + when { + currentUrl.isEmpty() || currentUrl == "http://" -> "https://" + currentUrl.startsWith("http://") -> currentUrl.replace("http://", "https://") + !currentUrl.startsWith("https://") -> "https://$currentUrl" + else -> currentUrl + } + } else { + when { + currentUrl.isEmpty() || currentUrl == "https://" -> "http://" + currentUrl.startsWith("https://") -> currentUrl.replace("https://", "http://") + !currentUrl.startsWith("http://") -> "http://$currentUrl" + else -> currentUrl + } + } + _serverUrl.value = newUrl + saveServerSettings() + } + + fun updateUsername(value: String) { + _username.value = value + saveServerSettings() + } + + fun updatePassword(value: String) { + _password.value = value + saveServerSettings() + } + + private fun saveServerSettings() { + prefs.edit().apply { + putString(Constants.KEY_SERVER_URL, _serverUrl.value) + putString(Constants.KEY_USERNAME, _username.value) + putString(Constants.KEY_PASSWORD, _password.value) + apply() + } + } + + fun testConnection() { + viewModelScope.launch { + _serverStatus.value = ServerStatus.Checking + try { + val syncService = WebDavSyncService(getApplication()) + val result = syncService.testConnection() + _serverStatus.value = if (result.isSuccess) { + ServerStatus.Reachable + } else { + ServerStatus.Unreachable(result.errorMessage) + } + emitToast(if (result.isSuccess) "✅ Verbindung erfolgreich!" else "❌ ${result.errorMessage}") + } catch (e: Exception) { + _serverStatus.value = ServerStatus.Unreachable(e.message) + emitToast("❌ Fehler: ${e.message}") + } + } + } + + fun checkServerStatus() { + val serverUrl = _serverUrl.value + // v1.5.0 Fix: URL mit nur Prefix gilt als "nicht konfiguriert" + if (serverUrl.isEmpty() || serverUrl == "http://" || serverUrl == "https://") { + _serverStatus.value = ServerStatus.NotConfigured + return + } + + viewModelScope.launch { + _serverStatus.value = ServerStatus.Checking + val isReachable = withContext(Dispatchers.IO) { + try { + val url = URL(serverUrl) + val connection = url.openConnection() as HttpURLConnection + connection.connectTimeout = CONNECTION_TIMEOUT_MS + connection.readTimeout = CONNECTION_TIMEOUT_MS + val code = connection.responseCode + connection.disconnect() + code in 200..299 || code == 401 + } catch (e: Exception) { + Log.e(TAG, "Server check failed: ${e.message}") + false + } + } + _serverStatus.value = if (isReachable) ServerStatus.Reachable else ServerStatus.Unreachable(null) + } + } + + fun syncNow() { + if (_isSyncing.value) return + viewModelScope.launch { + _isSyncing.value = true + try { + emitToast("🔄 Synchronisiere...") + val syncService = WebDavSyncService(getApplication()) + + if (!syncService.hasUnsyncedChanges()) { + emitToast("✅ Bereits synchronisiert") + return@launch + } + + val result = syncService.syncNotes() + if (result.isSuccess) { + emitToast("✅ ${result.syncedCount} Notizen synchronisiert") + } else { + emitToast("❌ ${result.errorMessage}") + } + } catch (e: Exception) { + emitToast("❌ Fehler: ${e.message}") + } finally { + _isSyncing.value = false + } + } + } + + // ═══════════════════════════════════════════════════════════════════════ + // Sync Settings Actions + // ═══════════════════════════════════════════════════════════════════════ + + fun setAutoSync(enabled: Boolean) { + _autoSyncEnabled.value = enabled + prefs.edit().putBoolean(Constants.KEY_AUTO_SYNC, enabled).apply() + + viewModelScope.launch { + if (enabled) { + // v1.5.0 Fix: Trigger battery optimization check and network monitor restart + _events.emit(SettingsEvent.RequestBatteryOptimization) + _events.emit(SettingsEvent.RestartNetworkMonitor) + emitToast("✅ Auto-Sync aktiviert") + } else { + _events.emit(SettingsEvent.RestartNetworkMonitor) + emitToast("Auto-Sync deaktiviert") + } + } + } + + fun setSyncInterval(minutes: Long) { + _syncInterval.value = minutes + prefs.edit().putLong(Constants.PREF_SYNC_INTERVAL_MINUTES, minutes).apply() + viewModelScope.launch { + val text = when (minutes) { + 15L -> "15 Minuten" + 60L -> "60 Minuten" + else -> "30 Minuten" + } + emitToast("⏱️ Sync-Intervall: $text") + } + } + + // ═══════════════════════════════════════════════════════════════════════ + // Markdown Settings Actions + // ═══════════════════════════════════════════════════════════════════════ + + fun setMarkdownAutoSync(enabled: Boolean) { + if (enabled) { + // v1.5.0 Fix: Perform initial export when enabling (like old SettingsActivity) + viewModelScope.launch { + try { + // Check server configuration first + val serverUrl = prefs.getString(Constants.KEY_SERVER_URL, "") ?: "" + val username = prefs.getString(Constants.KEY_USERNAME, "") ?: "" + val password = prefs.getString(Constants.KEY_PASSWORD, "") ?: "" + + if (serverUrl.isBlank() || username.isBlank() || password.isBlank()) { + emitToast("⚠️ Bitte zuerst WebDAV-Server konfigurieren") + // Don't enable - revert state + return@launch + } + + // Check if there are notes to export + val noteStorage = dev.dettmer.simplenotes.storage.NotesStorage(getApplication()) + val noteCount = noteStorage.loadAllNotes().size + + if (noteCount > 0) { + // Show progress and perform initial export + _markdownExportProgress.value = MarkdownExportProgress(0, noteCount) + + val syncService = WebDavSyncService(getApplication()) + val exportedCount = withContext(Dispatchers.IO) { + syncService.exportAllNotesToMarkdown( + serverUrl = serverUrl, + username = username, + password = password, + onProgress = { current, total -> + _markdownExportProgress.value = MarkdownExportProgress(current, total) + } + ) + } + + // Export successful - save settings + _markdownAutoSync.value = true + prefs.edit() + .putBoolean(Constants.KEY_MARKDOWN_EXPORT, true) + .putBoolean(Constants.KEY_MARKDOWN_AUTO_IMPORT, true) + .apply() + + _markdownExportProgress.value = MarkdownExportProgress(noteCount, noteCount, isComplete = true) + emitToast("✅ $exportedCount Notizen nach Markdown exportiert") + + // Clear progress after short delay + kotlinx.coroutines.delay(500) + _markdownExportProgress.value = null + + } else { + // No notes - just enable the feature + _markdownAutoSync.value = true + prefs.edit() + .putBoolean(Constants.KEY_MARKDOWN_EXPORT, true) + .putBoolean(Constants.KEY_MARKDOWN_AUTO_IMPORT, true) + .apply() + emitToast("📝 Markdown Auto-Sync aktiviert") + } + + } catch (e: Exception) { + _markdownExportProgress.value = null + emitToast("❌ Export fehlgeschlagen: ${e.message}") + // Don't enable on error + } + } + } else { + // Disable - simple + _markdownAutoSync.value = false + prefs.edit() + .putBoolean(Constants.KEY_MARKDOWN_EXPORT, false) + .putBoolean(Constants.KEY_MARKDOWN_AUTO_IMPORT, false) + .apply() + viewModelScope.launch { + emitToast("📝 Markdown Auto-Sync deaktiviert") + } + } + } + + fun performManualMarkdownSync() { + viewModelScope.launch { + try { + emitToast("📝 Markdown-Sync läuft...") + val syncService = WebDavSyncService(getApplication()) + val result = syncService.manualMarkdownSync() + emitToast("✅ Export: ${result.exportedCount} • Import: ${result.importedCount}") + } catch (e: Exception) { + emitToast("❌ Fehler: ${e.message}") + } + } + } + + // ═══════════════════════════════════════════════════════════════════════ + // Backup Actions + // ═══════════════════════════════════════════════════════════════════════ + + fun createBackup(uri: Uri) { + viewModelScope.launch { + _isBackupInProgress.value = true + try { + val result = backupManager.createBackup(uri) + emitToast(if (result.success) "✅ ${result.message}" else "❌ ${result.error}") + } catch (e: Exception) { + emitToast("❌ Backup fehlgeschlagen: ${e.message}") + } finally { + _isBackupInProgress.value = false + } + } + } + + fun restoreFromFile(uri: Uri, mode: RestoreMode) { + viewModelScope.launch { + _isBackupInProgress.value = true + try { + val result = backupManager.restoreBackup(uri, mode) + emitToast(if (result.success) "✅ ${result.importedNotes} Notizen wiederhergestellt" else "❌ ${result.error}") + } catch (e: Exception) { + emitToast("❌ Wiederherstellung fehlgeschlagen: ${e.message}") + } finally { + _isBackupInProgress.value = false + } + } + } + + fun restoreFromServer(mode: RestoreMode) { + viewModelScope.launch { + _isBackupInProgress.value = true + try { + emitToast("📥 Lade vom Server...") + val syncService = WebDavSyncService(getApplication()) + val result = withContext(Dispatchers.IO) { + syncService.restoreFromServer(mode) + } + emitToast(if (result.isSuccess) "✅ ${result.restoredCount} Notizen wiederhergestellt" else "❌ ${result.errorMessage}") + } catch (e: Exception) { + emitToast("❌ Fehler: ${e.message}") + } finally { + _isBackupInProgress.value = false + } + } + } + + // ═══════════════════════════════════════════════════════════════════════ + // Debug Settings Actions + // ═══════════════════════════════════════════════════════════════════════ + + fun setFileLogging(enabled: Boolean) { + _fileLoggingEnabled.value = enabled + prefs.edit().putBoolean(Constants.KEY_FILE_LOGGING_ENABLED, enabled).apply() + Logger.setFileLoggingEnabled(enabled) + viewModelScope.launch { + emitToast(if (enabled) "📝 Datei-Logging aktiviert" else "📝 Datei-Logging deaktiviert") + } + } + + fun clearLogs() { + viewModelScope.launch { + try { + val cleared = Logger.clearLogFile(getApplication()) + emitToast(if (cleared) "🗑️ Logs gelöscht" else "📭 Keine Logs zum Löschen") + } catch (e: Exception) { + emitToast("❌ Fehler: ${e.message}") + } + } + } + + fun getLogFile() = Logger.getLogFile(getApplication()) + + // ═══════════════════════════════════════════════════════════════════════ + // Helper + // ═══════════════════════════════════════════════════════════════════════ + + private suspend fun emitToast(message: String) { + _showToast.emit(message) + } + + /** + * Server status states + */ + sealed class ServerStatus { + data object Unknown : ServerStatus() + data object NotConfigured : ServerStatus() + data object Checking : ServerStatus() + data object Reachable : ServerStatus() + data class Unreachable(val error: String?) : ServerStatus() + } + + /** + * Events for Activity-level actions (dialogs, intents, etc.) + * v1.5.0: Ported from old SettingsActivity + */ + sealed class SettingsEvent { + data object RequestBatteryOptimization : SettingsEvent() + data object RestartNetworkMonitor : SettingsEvent() + } + + /** + * Progress state for Markdown export + * v1.5.0: For initial export progress dialog + */ + data class MarkdownExportProgress( + val current: Int, + val total: Int, + val isComplete: Boolean = false + ) +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsCard.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsCard.kt new file mode 100644 index 0000000..7146bb9 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsCard.kt @@ -0,0 +1,113 @@ +package dev.dettmer.simplenotes.ui.settings.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.dp + +/** + * Clickable Settings group card with icon, title, subtitle and optional status + * v1.5.0: Jetpack Compose Settings Redesign + */ +@Composable +fun SettingsCard( + icon: ImageVector, + title: String, + modifier: Modifier = Modifier, + subtitle: String? = null, + statusText: String? = null, + statusColor: Color = MaterialTheme.colorScheme.onSurfaceVariant, + onClick: () -> Unit +) { + Card( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 4.dp) + .clickable(onClick = onClick), + shape = RoundedCornerShape(16.dp), + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surfaceContainerHigh + ) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + // Icon with circle background + Box( + modifier = Modifier + .size(40.dp) + .background( + color = MaterialTheme.colorScheme.primaryContainer, + shape = CircleShape + ), + contentAlignment = Alignment.Center + ) { + Icon( + imageVector = icon, + contentDescription = null, + tint = MaterialTheme.colorScheme.onPrimaryContainer, + modifier = Modifier.size(20.dp) + ) + } + + Spacer(modifier = Modifier.width(16.dp)) + + // Content + Column(modifier = Modifier.weight(1f)) { + Text( + text = title, + style = MaterialTheme.typography.titleMedium, + color = MaterialTheme.colorScheme.onSurface + ) + if (subtitle != null) { + Spacer(modifier = Modifier.height(2.dp)) + Text( + text = subtitle, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + if (statusText != null) { + Spacer(modifier = Modifier.height(2.dp)) + Text( + text = statusText, + style = MaterialTheme.typography.bodySmall, + color = statusColor + ) + } + } + + // Arrow + Icon( + imageVector = Icons.AutoMirrored.Filled.KeyboardArrowRight, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsComponents.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsComponents.kt new file mode 100644 index 0000000..30f83ff --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsComponents.kt @@ -0,0 +1,152 @@ +package dev.dettmer.simplenotes.ui.settings.components + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +/** + * Primary filled button for settings actions + * v1.5.0: Jetpack Compose Settings Redesign + */ +@Composable +fun SettingsButton( + text: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + isLoading: Boolean = false +) { + Button( + onClick = onClick, + enabled = enabled && !isLoading, + modifier = modifier.fillMaxWidth() + ) { + if (isLoading) { + CircularProgressIndicator( + modifier = Modifier.height(20.dp), + strokeWidth = 2.dp, + color = MaterialTheme.colorScheme.onPrimary + ) + } else { + Text(text) + } + } +} + +/** + * Outlined secondary button for settings actions + */ +@Composable +fun SettingsOutlinedButton( + text: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + isLoading: Boolean = false +) { + OutlinedButton( + onClick = onClick, + enabled = enabled && !isLoading, + modifier = modifier.fillMaxWidth() + ) { + if (isLoading) { + CircularProgressIndicator( + modifier = Modifier.height(20.dp), + strokeWidth = 2.dp, + color = MaterialTheme.colorScheme.primary + ) + } else { + Text(text) + } + } +} + +/** + * Danger/destructive button for settings actions + */ +@Composable +fun SettingsDangerButton( + text: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true +) { + OutlinedButton( + onClick = onClick, + enabled = enabled, + modifier = modifier.fillMaxWidth(), + colors = ButtonDefaults.outlinedButtonColors( + contentColor = MaterialTheme.colorScheme.error + ) + ) { + Text(text) + } +} + +/** + * Info card with description text + */ +@Composable +fun SettingsInfoCard( + text: String, + modifier: Modifier = Modifier +) { + androidx.compose.material3.Card( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp), + colors = androidx.compose.material3.CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surfaceContainerHighest + ) + ) { + Text( + text = text, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(16.dp), + lineHeight = MaterialTheme.typography.bodySmall.lineHeight * 1.3f + ) + } +} + +/** + * Section header text + */ +@Composable +fun SettingsSectionHeader( + text: String, + modifier: Modifier = Modifier +) { + Text( + text = text, + style = MaterialTheme.typography.labelLarge, + color = MaterialTheme.colorScheme.primary, + modifier = modifier.padding(horizontal = 16.dp, vertical = 8.dp) + ) +} + +/** + * Divider between settings groups + */ +@Composable +fun SettingsDivider( + modifier: Modifier = Modifier +) { + Spacer(modifier = modifier.height(8.dp)) + androidx.compose.material3.HorizontalDivider( + modifier = Modifier.padding(horizontal = 16.dp), + color = MaterialTheme.colorScheme.outlineVariant + ) + Spacer(modifier = Modifier.height(8.dp)) +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsRadioGroup.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsRadioGroup.kt new file mode 100644 index 0000000..6fd267c --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsRadioGroup.kt @@ -0,0 +1,94 @@ +package dev.dettmer.simplenotes.ui.settings.components + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.selection.selectable +import androidx.compose.foundation.selection.selectableGroup +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.RadioButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.unit.dp + +/** + * Data class for radio option + */ +data class RadioOption( + val value: T, + val title: String, + val subtitle: String? = null +) + +/** + * Settings radio group for selecting one option + * v1.5.0: Jetpack Compose Settings Redesign + */ +@Composable +fun SettingsRadioGroup( + options: List>, + selectedValue: T, + onValueSelected: (T) -> Unit, + modifier: Modifier = Modifier, + title: String? = null +) { + Column( + modifier = modifier + .fillMaxWidth() + .selectableGroup() + ) { + if (title != null) { + Text( + text = title, + style = MaterialTheme.typography.labelLarge, + color = MaterialTheme.colorScheme.primary, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp) + ) + } + + options.forEach { option -> + Row( + modifier = Modifier + .fillMaxWidth() + .selectable( + selected = option.value == selectedValue, + onClick = { onValueSelected(option.value) }, + role = Role.RadioButton + ) + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + RadioButton( + selected = option.value == selectedValue, + onClick = null // handled by selectable + ) + + Column( + modifier = Modifier + .padding(start = 16.dp) + .weight(1f) + ) { + Text( + text = option.title, + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurface + ) + if (option.subtitle != null) { + Spacer(modifier = Modifier.height(2.dp)) + Text( + text = option.subtitle, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + } + } + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsScaffold.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsScaffold.kt new file mode 100644 index 0000000..a08b383 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsScaffold.kt @@ -0,0 +1,57 @@ +package dev.dettmer.simplenotes.ui.settings.components + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +/** + * Reusable Scaffold with back-navigation TopAppBar + * v1.5.0: Jetpack Compose Settings Redesign + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SettingsScaffold( + title: String, + onBack: () -> Unit, + modifier: Modifier = Modifier, + content: @Composable (PaddingValues) -> Unit +) { + Scaffold( + modifier = modifier, + topBar = { + TopAppBar( + title = { + Text( + text = title, + style = MaterialTheme.typography.titleLarge + ) + }, + navigationIcon = { + IconButton(onClick = onBack) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = "Zurück" + ) + } + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = MaterialTheme.colorScheme.surface, + titleContentColor = MaterialTheme.colorScheme.onSurface + ) + ) + }, + containerColor = MaterialTheme.colorScheme.surface + ) { paddingValues -> + content(paddingValues) + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsSwitch.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsSwitch.kt new file mode 100644 index 0000000..63cf998 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsSwitch.kt @@ -0,0 +1,83 @@ +package dev.dettmer.simplenotes.ui.settings.components + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.dp + +/** + * Settings switch item with title, optional subtitle and icon + * v1.5.0: Jetpack Compose Settings Redesign + */ +@Composable +fun SettingsSwitch( + title: String, + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + subtitle: String? = null, + icon: ImageVector? = null, + enabled: Boolean = true +) { + Row( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + if (icon != null) { + Icon( + imageVector = icon, + contentDescription = null, + tint = if (enabled) { + MaterialTheme.colorScheme.onSurfaceVariant + } else { + MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.38f) + }, + modifier = Modifier.size(24.dp) + ) + Spacer(modifier = Modifier.width(16.dp)) + } + + Column(modifier = Modifier.weight(1f)) { + Text( + text = title, + style = MaterialTheme.typography.bodyLarge, + color = if (enabled) { + MaterialTheme.colorScheme.onSurface + } else { + MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f) + } + ) + if (subtitle != null) { + Text( + text = subtitle, + style = MaterialTheme.typography.bodyMedium, + color = if (enabled) { + MaterialTheme.colorScheme.onSurfaceVariant + } else { + MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.38f) + } + ) + } + } + + Switch( + checked = checked, + onCheckedChange = onCheckedChange, + enabled = enabled + ) + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt new file mode 100644 index 0000000..c506c72 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt @@ -0,0 +1,218 @@ +package dev.dettmer.simplenotes.ui.settings.screens + +import android.content.Intent +import android.net.Uri +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight +import androidx.compose.material.icons.filled.Code +import androidx.compose.material.icons.filled.Person +import androidx.compose.material.icons.filled.Policy +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.BuildConfig +import dev.dettmer.simplenotes.ui.settings.components.SettingsDivider +import dev.dettmer.simplenotes.ui.settings.components.SettingsScaffold +import dev.dettmer.simplenotes.ui.settings.components.SettingsSectionHeader + +/** + * About app information screen + * v1.5.0: Jetpack Compose Settings Redesign + */ +@Composable +fun AboutScreen( + onBack: () -> Unit +) { + val context = LocalContext.current + + val githubRepoUrl = "https://github.com/inventory69/simple-notes-sync" + val githubProfileUrl = "https://github.com/inventory69" + val licenseUrl = "https://github.com/inventory69/simple-notes-sync/blob/main/LICENSE" + + SettingsScaffold( + title = "Über diese App", + onBack = onBack + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .verticalScroll(rememberScrollState()) + ) { + Spacer(modifier = Modifier.height(16.dp)) + + // App Info Card + Card( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp), + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.primaryContainer + ) + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(24.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = "📝", + style = MaterialTheme.typography.displayMedium + ) + + Spacer(modifier = Modifier.height(8.dp)) + + Text( + text = "Simple Notes Sync", + style = MaterialTheme.typography.headlineSmall, + color = MaterialTheme.colorScheme.onPrimaryContainer + ) + + Spacer(modifier = Modifier.height(4.dp)) + + Text( + text = "Version ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.8f) + ) + } + } + + Spacer(modifier = Modifier.height(24.dp)) + + SettingsSectionHeader(text = "Links") + + // GitHub Repository + AboutLinkItem( + icon = Icons.Default.Code, + title = "GitHub Repository", + subtitle = "Quellcode, Issues & Dokumentation", + onClick = { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(githubRepoUrl)) + context.startActivity(intent) + } + ) + + // Developer + AboutLinkItem( + icon = Icons.Default.Person, + title = "Entwickler", + subtitle = "GitHub Profil: @inventory69", + onClick = { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(githubProfileUrl)) + context.startActivity(intent) + } + ) + + // License + AboutLinkItem( + icon = Icons.Default.Policy, + title = "Lizenz", + subtitle = "MIT License - Open Source", + onClick = { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(licenseUrl)) + context.startActivity(intent) + } + ) + + SettingsDivider() + + // Data Privacy Info + Card( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp), + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surfaceContainerHighest + ) + ) { + Column( + modifier = Modifier.padding(16.dp) + ) { + Text( + text = "🔒 Datenschutz", + style = MaterialTheme.typography.titleSmall + ) + Spacer(modifier = Modifier.height(8.dp)) + Text( + text = "Diese App sammelt keine Daten. Alle Notizen werden " + + "nur lokal auf deinem Gerät und auf deinem eigenen " + + "WebDAV-Server gespeichert. Keine Telemetrie, keine Werbung.", + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + + Spacer(modifier = Modifier.height(16.dp)) + } + } +} + +/** + * Clickable link item for About section + */ +@Composable +private fun AboutLinkItem( + icon: ImageVector, + title: String, + subtitle: String, + onClick: () -> Unit +) { + Row( + modifier = Modifier + .fillMaxWidth() + .clickable(onClick = onClick) + .padding(horizontal = 16.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + imageVector = icon, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary, + modifier = Modifier.size(24.dp) + ) + + Spacer(modifier = Modifier.width(16.dp)) + + Column(modifier = Modifier.weight(1f)) { + Text( + text = title, + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurface + ) + Text( + text = subtitle, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + + Icon( + imageVector = Icons.AutoMirrored.Filled.KeyboardArrowRight, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurfaceVariant + ) + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/BackupSettingsScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/BackupSettingsScreen.kt new file mode 100644 index 0000000..e3ca5c2 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/BackupSettingsScreen.kt @@ -0,0 +1,256 @@ +package dev.dettmer.simplenotes.ui.settings.screens + +import android.net.Uri +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.backup.RestoreMode +import dev.dettmer.simplenotes.ui.settings.SettingsViewModel +import dev.dettmer.simplenotes.ui.settings.components.RadioOption +import dev.dettmer.simplenotes.ui.settings.components.SettingsButton +import dev.dettmer.simplenotes.ui.settings.components.SettingsDivider +import dev.dettmer.simplenotes.ui.settings.components.SettingsInfoCard +import dev.dettmer.simplenotes.ui.settings.components.SettingsOutlinedButton +import dev.dettmer.simplenotes.ui.settings.components.SettingsRadioGroup +import dev.dettmer.simplenotes.ui.settings.components.SettingsScaffold +import dev.dettmer.simplenotes.ui.settings.components.SettingsSectionHeader +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +/** + * Backup and restore settings screen + * v1.5.0: Jetpack Compose Settings Redesign + */ +@Composable +fun BackupSettingsScreen( + viewModel: SettingsViewModel, + onBack: () -> Unit +) { + val isBackupInProgress by viewModel.isBackupInProgress.collectAsState() + + // Restore dialog state + var showRestoreDialog by remember { mutableStateOf(false) } + var restoreSource by remember { mutableStateOf(RestoreSource.LocalFile) } + var pendingRestoreUri by remember { mutableStateOf(null) } + var selectedRestoreMode by remember { mutableStateOf(RestoreMode.MERGE) } + + // File picker launchers + val createBackupLauncher = rememberLauncherForActivityResult( + contract = ActivityResultContracts.CreateDocument("application/json") + ) { uri -> + uri?.let { viewModel.createBackup(it) } + } + + val restoreFileLauncher = rememberLauncherForActivityResult( + contract = ActivityResultContracts.OpenDocument() + ) { uri -> + uri?.let { + pendingRestoreUri = it + restoreSource = RestoreSource.LocalFile + showRestoreDialog = true + } + } + + SettingsScaffold( + title = "Backup & Wiederherstellung", + onBack = onBack + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .verticalScroll(rememberScrollState()) + ) { + Spacer(modifier = Modifier.height(8.dp)) + + // Info Card + SettingsInfoCard( + text = "📦 Bei jeder Wiederherstellung wird automatisch ein " + + "Sicherheits-Backup erstellt." + ) + + Spacer(modifier = Modifier.height(16.dp)) + + // Local Backup Section + SettingsSectionHeader(text = "Lokales Backup") + + Spacer(modifier = Modifier.height(8.dp)) + + SettingsButton( + text = "💾 Backup erstellen", + onClick = { + val timestamp = SimpleDateFormat("yyyy-MM-dd_HHmmss", Locale.US) + .format(Date()) + val filename = "simplenotes_backup_$timestamp.json" + createBackupLauncher.launch(filename) + }, + isLoading = isBackupInProgress, + modifier = Modifier.padding(horizontal = 16.dp) + ) + + Spacer(modifier = Modifier.height(8.dp)) + + SettingsOutlinedButton( + text = "📂 Aus Datei wiederherstellen", + onClick = { + restoreFileLauncher.launch(arrayOf("application/json")) + }, + isLoading = isBackupInProgress, + modifier = Modifier.padding(horizontal = 16.dp) + ) + + SettingsDivider() + + // Server Backup Section + SettingsSectionHeader(text = "Server-Backup") + + Spacer(modifier = Modifier.height(8.dp)) + + SettingsOutlinedButton( + text = "☁️ Vom Server wiederherstellen", + onClick = { + restoreSource = RestoreSource.Server + showRestoreDialog = true + }, + isLoading = isBackupInProgress, + modifier = Modifier.padding(horizontal = 16.dp) + ) + + Spacer(modifier = Modifier.height(16.dp)) + } + } + + // Restore Mode Dialog + if (showRestoreDialog) { + RestoreModeDialog( + source = restoreSource, + selectedMode = selectedRestoreMode, + onModeSelected = { selectedRestoreMode = it }, + onConfirm = { + showRestoreDialog = false + when (restoreSource) { + RestoreSource.LocalFile -> { + pendingRestoreUri?.let { uri -> + viewModel.restoreFromFile(uri, selectedRestoreMode) + } + } + RestoreSource.Server -> { + viewModel.restoreFromServer(selectedRestoreMode) + } + } + }, + onDismiss = { + showRestoreDialog = false + pendingRestoreUri = null + } + ) + } +} + +/** + * Restore source enum + */ +private enum class RestoreSource { + LocalFile, + Server +} + +/** + * Dialog for selecting restore mode + */ +@Composable +private fun RestoreModeDialog( + source: RestoreSource, + selectedMode: RestoreMode, + onModeSelected: (RestoreMode) -> Unit, + onConfirm: () -> Unit, + onDismiss: () -> Unit +) { + val sourceText = when (source) { + RestoreSource.LocalFile -> "Lokale Datei" + RestoreSource.Server -> "WebDAV Server" + } + + val modeOptions = listOf( + RadioOption( + value = RestoreMode.MERGE, + title = "⚪ Zusammenführen (Standard)", + subtitle = "Neue hinzufügen, Bestehende behalten" + ), + RadioOption( + value = RestoreMode.REPLACE, + title = "⚪ Ersetzen", + subtitle = "Alle löschen & Backup importieren" + ), + RadioOption( + value = RestoreMode.OVERWRITE_DUPLICATES, + title = "⚪ Duplikate überschreiben", + subtitle = "Backup gewinnt bei Konflikten" + ) + ) + + AlertDialog( + onDismissRequest = onDismiss, + title = { Text("⚠️ Backup wiederherstellen?") }, + text = { + Column { + Text( + text = "Quelle: $sourceText", + style = MaterialTheme.typography.bodyMedium + ) + + Spacer(modifier = Modifier.height(16.dp)) + + Text( + text = "Wiederherstellungs-Modus:", + style = MaterialTheme.typography.labelLarge + ) + + Spacer(modifier = Modifier.height(8.dp)) + + SettingsRadioGroup( + options = modeOptions, + selectedValue = selectedMode, + onValueSelected = onModeSelected + ) + + Spacer(modifier = Modifier.height(8.dp)) + + Text( + text = "ℹ️ Ein Sicherheits-Backup wird vor dem Wiederherstellen automatisch erstellt.", + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + }, + confirmButton = { + TextButton(onClick = onConfirm) { + Text("Wiederherstellen") + } + }, + dismissButton = { + TextButton(onClick = onDismiss) { + Text("Abbrechen") + } + } + ) +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/DebugSettingsScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/DebugSettingsScreen.kt new file mode 100644 index 0000000..c68593c --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/DebugSettingsScreen.kt @@ -0,0 +1,148 @@ +package dev.dettmer.simplenotes.ui.settings.screens + +import android.content.Intent +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.Notes +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.core.content.FileProvider +import dev.dettmer.simplenotes.BuildConfig +import dev.dettmer.simplenotes.ui.settings.SettingsViewModel +import dev.dettmer.simplenotes.ui.settings.components.SettingsButton +import dev.dettmer.simplenotes.ui.settings.components.SettingsDangerButton +import dev.dettmer.simplenotes.ui.settings.components.SettingsDivider +import dev.dettmer.simplenotes.ui.settings.components.SettingsInfoCard +import dev.dettmer.simplenotes.ui.settings.components.SettingsScaffold +import dev.dettmer.simplenotes.ui.settings.components.SettingsSectionHeader +import dev.dettmer.simplenotes.ui.settings.components.SettingsSwitch + +/** + * Debug and diagnostics settings screen + * v1.5.0: Jetpack Compose Settings Redesign + */ +@Composable +fun DebugSettingsScreen( + viewModel: SettingsViewModel, + onBack: () -> Unit +) { + val context = LocalContext.current + val fileLoggingEnabled by viewModel.fileLoggingEnabled.collectAsState() + + var showClearLogsDialog by remember { mutableStateOf(false) } + + SettingsScaffold( + title = "Debug & Diagnose", + onBack = onBack + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .verticalScroll(rememberScrollState()) + ) { + Spacer(modifier = Modifier.height(8.dp)) + + // File Logging Toggle + SettingsSwitch( + title = "Datei-Logging", + subtitle = "Sync-Logs in Datei speichern", + checked = fileLoggingEnabled, + onCheckedChange = { viewModel.setFileLogging(it) }, + icon = Icons.AutoMirrored.Filled.Notes + ) + + // Privacy Info + SettingsInfoCard( + text = "🔒 Datenschutz: Logs werden nur lokal auf deinem Gerät gespeichert " + + "und niemals an externe Server gesendet. Die Logs enthalten " + + "Sync-Aktivitäten zur Fehlerdiagnose. Du kannst sie jederzeit löschen " + + "oder exportieren." + ) + + SettingsDivider() + + SettingsSectionHeader(text = "Log-Aktionen") + + Spacer(modifier = Modifier.height(8.dp)) + + // Export Logs Button + SettingsButton( + text = "📤 Logs exportieren & teilen", + onClick = { + val logFile = viewModel.getLogFile() + if (logFile != null && logFile.exists() && logFile.length() > 0L) { + val logUri = FileProvider.getUriForFile( + context, + "${BuildConfig.APPLICATION_ID}.fileprovider", + logFile + ) + + val shareIntent = Intent(Intent.ACTION_SEND).apply { + type = "text/plain" + putExtra(Intent.EXTRA_STREAM, logUri) + putExtra(Intent.EXTRA_SUBJECT, "SimpleNotes Sync Logs") + addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + } + + context.startActivity(Intent.createChooser(shareIntent, "Logs teilen via...")) + } + }, + modifier = Modifier.padding(horizontal = 16.dp) + ) + + Spacer(modifier = Modifier.height(8.dp)) + + // Clear Logs Button + SettingsDangerButton( + text = "🗑️ Logs löschen", + onClick = { showClearLogsDialog = true }, + modifier = Modifier.padding(horizontal = 16.dp) + ) + + Spacer(modifier = Modifier.height(16.dp)) + } + } + + // Clear Logs Confirmation Dialog + if (showClearLogsDialog) { + AlertDialog( + onDismissRequest = { showClearLogsDialog = false }, + title = { Text("Logs löschen?") }, + text = { + Text("Alle gespeicherten Sync-Logs werden unwiderruflich gelöscht.") + }, + confirmButton = { + TextButton( + onClick = { + showClearLogsDialog = false + viewModel.clearLogs() + } + ) { + Text("Löschen") + } + }, + dismissButton = { + TextButton(onClick = { showClearLogsDialog = false }) { + Text("Abbrechen") + } + } + ) + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/MarkdownSettingsScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/MarkdownSettingsScreen.kt new file mode 100644 index 0000000..0b245af --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/MarkdownSettingsScreen.kt @@ -0,0 +1,128 @@ +package dev.dettmer.simplenotes.ui.settings.screens + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Description +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.LinearProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.ui.settings.SettingsViewModel +import dev.dettmer.simplenotes.ui.settings.components.SettingsButton +import dev.dettmer.simplenotes.ui.settings.components.SettingsDivider +import dev.dettmer.simplenotes.ui.settings.components.SettingsInfoCard +import dev.dettmer.simplenotes.ui.settings.components.SettingsScaffold +import dev.dettmer.simplenotes.ui.settings.components.SettingsSwitch + +/** + * Markdown Desktop integration settings screen + * v1.5.0: Jetpack Compose Settings Redesign + */ +@Composable +fun MarkdownSettingsScreen( + viewModel: SettingsViewModel, + onBack: () -> Unit +) { + val markdownAutoSync by viewModel.markdownAutoSync.collectAsState() + val exportProgress by viewModel.markdownExportProgress.collectAsState() + + // v1.5.0 Fix: Progress Dialog for initial export + exportProgress?.let { progress -> + AlertDialog( + onDismissRequest = { /* Not dismissable */ }, + title = { Text("Markdown Auto-Sync") }, + text = { + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(12.dp) + ) { + Text( + text = if (progress.isComplete) { + "✅ Export abgeschlossen" + } else { + "Exportiere ${progress.current}/${progress.total} Notizen..." + }, + style = MaterialTheme.typography.bodyMedium + ) + + LinearProgressIndicator( + progress = { + if (progress.total > 0) { + progress.current.toFloat() / progress.total.toFloat() + } else 0f + }, + modifier = Modifier.fillMaxWidth() + ) + } + }, + confirmButton = { /* No button - auto dismiss */ } + ) + } + + SettingsScaffold( + title = "Markdown Desktop-Integration", + onBack = onBack + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .verticalScroll(rememberScrollState()) + ) { + Spacer(modifier = Modifier.height(8.dp)) + + // Info Card + SettingsInfoCard( + text = "📝 Exportiert Notizen zusätzlich als .md-Dateien. Mounte " + + "WebDAV als Netzlaufwerk um mit VS Code, Typora oder jedem " + + "Markdown-Editor zu bearbeiten. JSON-Sync bleibt primäres Format." + ) + + Spacer(modifier = Modifier.height(8.dp)) + + // Markdown Auto-Sync Toggle + SettingsSwitch( + title = "Markdown Auto-Sync", + subtitle = "Synchronisiert Notizen automatisch als .md-Dateien (Upload + Download bei jedem Sync)", + checked = markdownAutoSync, + onCheckedChange = { viewModel.setMarkdownAutoSync(it) }, + icon = Icons.Default.Description + ) + + // Manual sync button (only visible when auto-sync is off) + if (!markdownAutoSync) { + SettingsDivider() + + SettingsInfoCard( + text = "Manueller Sync exportiert alle Notizen als .md-Dateien und " + + "importiert .md-Dateien vom Server. Nützlich für einmalige Synchronisation." + ) + + Spacer(modifier = Modifier.height(8.dp)) + + SettingsButton( + text = "📝 Manueller Markdown-Sync", + onClick = { viewModel.performManualMarkdownSync() }, + modifier = Modifier.padding(horizontal = 16.dp) + ) + } + + Spacer(modifier = Modifier.height(16.dp)) + } + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/ServerSettingsScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/ServerSettingsScreen.kt new file mode 100644 index 0000000..6927805 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/ServerSettingsScreen.kt @@ -0,0 +1,241 @@ +package dev.dettmer.simplenotes.ui.settings.screens + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Language +import androidx.compose.material.icons.filled.Lock +import androidx.compose.material.icons.filled.Person +import androidx.compose.material.icons.filled.Visibility +import androidx.compose.material.icons.filled.VisibilityOff +import androidx.compose.material3.Button +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.FilterChip +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.ui.settings.SettingsViewModel +import dev.dettmer.simplenotes.ui.settings.components.SettingsScaffold + +/** + * Server configuration settings screen + * v1.5.0: Jetpack Compose Settings Redesign + */ +@Composable +fun ServerSettingsScreen( + viewModel: SettingsViewModel, + onBack: () -> Unit +) { + val serverUrl by viewModel.serverUrl.collectAsState() + val username by viewModel.username.collectAsState() + val password by viewModel.password.collectAsState() + val isHttps by viewModel.isHttps.collectAsState() + val serverStatus by viewModel.serverStatus.collectAsState() + val isSyncing by viewModel.isSyncing.collectAsState() + + var passwordVisible by remember { mutableStateOf(false) } + + // Check server status on load + LaunchedEffect(Unit) { + viewModel.checkServerStatus() + } + + SettingsScaffold( + title = "Server-Einstellungen", + onBack = onBack + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .verticalScroll(rememberScrollState()) + .padding(16.dp) + ) { + // Verbindungstyp + Text( + text = "Verbindungstyp", + style = MaterialTheme.typography.labelLarge, + modifier = Modifier.padding(bottom = 8.dp) + ) + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + FilterChip( + selected = !isHttps, + onClick = { viewModel.updateProtocol(false) }, + label = { Text("🏠 Intern (HTTP)") }, + modifier = Modifier.weight(1f) + ) + FilterChip( + selected = isHttps, + onClick = { viewModel.updateProtocol(true) }, + label = { Text("🌐 Extern (HTTPS)") }, + modifier = Modifier.weight(1f) + ) + } + + Text( + text = if (!isHttps) { + "HTTP nur für lokale Netzwerke (z.B. 192.168.x.x, 10.x.x.x)" + } else { + "HTTPS für sichere Verbindungen über das Internet" + }, + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(top = 4.dp, bottom = 16.dp) + ) + + // Server-Adresse + OutlinedTextField( + value = serverUrl, + onValueChange = { viewModel.updateServerUrl(it) }, + label = { Text("Server-Adresse") }, + supportingText = { Text("z.B. http://192.168.0.188:8080/notes") }, + leadingIcon = { Icon(Icons.Default.Language, null) }, + modifier = Modifier.fillMaxWidth(), + singleLine = true, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri) + ) + + Spacer(modifier = Modifier.height(12.dp)) + + // Benutzername + OutlinedTextField( + value = username, + onValueChange = { viewModel.updateUsername(it) }, + label = { Text("Benutzername") }, + leadingIcon = { Icon(Icons.Default.Person, null) }, + modifier = Modifier.fillMaxWidth(), + singleLine = true + ) + + Spacer(modifier = Modifier.height(12.dp)) + + // Passwort + OutlinedTextField( + value = password, + onValueChange = { viewModel.updatePassword(it) }, + label = { Text("Passwort") }, + leadingIcon = { Icon(Icons.Default.Lock, null) }, + trailingIcon = { + IconButton(onClick = { passwordVisible = !passwordVisible }) { + Icon( + imageVector = if (passwordVisible) { + Icons.Default.VisibilityOff + } else { + Icons.Default.Visibility + }, + contentDescription = if (passwordVisible) "Verstecken" else "Anzeigen" + ) + } + }, + visualTransformation = if (passwordVisible) { + VisualTransformation.None + } else { + PasswordVisualTransformation() + }, + modifier = Modifier.fillMaxWidth(), + singleLine = true, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password) + ) + + Spacer(modifier = Modifier.height(16.dp)) + + // Server-Status + Card( + modifier = Modifier.fillMaxWidth(), + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surfaceContainerHighest + ) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text("Server-Status:", style = MaterialTheme.typography.labelLarge) + Text( + text = when (serverStatus) { + is SettingsViewModel.ServerStatus.Reachable -> "✅ Erreichbar" + is SettingsViewModel.ServerStatus.Unreachable -> "❌ Nicht erreichbar" + is SettingsViewModel.ServerStatus.Checking -> "🔍 Prüfe..." + is SettingsViewModel.ServerStatus.NotConfigured -> "⚠️ Nicht konfiguriert" + else -> "❓ Unbekannt" + }, + color = when (serverStatus) { + is SettingsViewModel.ServerStatus.Reachable -> Color(0xFF4CAF50) + is SettingsViewModel.ServerStatus.Unreachable -> Color(0xFFF44336) + is SettingsViewModel.ServerStatus.NotConfigured -> Color(0xFFFF9800) + else -> MaterialTheme.colorScheme.onSurfaceVariant + } + ) + } + } + + Spacer(modifier = Modifier.height(24.dp)) + + // Action Buttons + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + OutlinedButton( + onClick = { viewModel.testConnection() }, + modifier = Modifier.weight(1f) + ) { + Text("Verbindung testen") + } + + Button( + onClick = { viewModel.syncNow() }, + enabled = !isSyncing, + modifier = Modifier.weight(1f) + ) { + if (isSyncing) { + CircularProgressIndicator( + modifier = Modifier.size(16.dp), + strokeWidth = 2.dp, + color = MaterialTheme.colorScheme.onPrimary + ) + Spacer(modifier = Modifier.width(8.dp)) + } + Text("Jetzt synchronisieren") + } + } + } + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SettingsMainScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SettingsMainScreen.kt new file mode 100644 index 0000000..25c256f --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SettingsMainScreen.kt @@ -0,0 +1,143 @@ +package dev.dettmer.simplenotes.ui.settings.screens + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Backup +import androidx.compose.material.icons.filled.BugReport +import androidx.compose.material.icons.filled.Cloud +import androidx.compose.material.icons.filled.Description +import androidx.compose.material.icons.filled.Info +import androidx.compose.material.icons.filled.Sync +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.BuildConfig +import dev.dettmer.simplenotes.ui.settings.SettingsRoute +import dev.dettmer.simplenotes.ui.settings.SettingsViewModel +import dev.dettmer.simplenotes.ui.settings.components.SettingsCard +import dev.dettmer.simplenotes.ui.settings.components.SettingsScaffold + +/** + * Main Settings overview screen with clickable group cards + * v1.5.0: Jetpack Compose Settings Redesign + */ +@Composable +fun SettingsMainScreen( + viewModel: SettingsViewModel, + onNavigate: (SettingsRoute) -> Unit, + onBack: () -> Unit +) { + val serverUrl by viewModel.serverUrl.collectAsState() + val serverStatus by viewModel.serverStatus.collectAsState() + val autoSyncEnabled by viewModel.autoSyncEnabled.collectAsState() + val syncInterval by viewModel.syncInterval.collectAsState() + val markdownAutoSync by viewModel.markdownAutoSync.collectAsState() + val fileLoggingEnabled by viewModel.fileLoggingEnabled.collectAsState() + + // Check server status on first load + LaunchedEffect(Unit) { + viewModel.checkServerStatus() + } + + SettingsScaffold( + title = "Einstellungen", + onBack = onBack + ) { paddingValues -> + LazyColumn( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues), + contentPadding = PaddingValues(vertical = 8.dp) + ) { + // Server-Einstellungen + item { + // v1.5.0 Fix: Nur Prefix-URLs gelten als "nicht konfiguriert" + val isConfigured = serverUrl.isNotEmpty() && + serverUrl != "http://" && + serverUrl != "https://" + + SettingsCard( + icon = Icons.Default.Cloud, + title = "Server-Einstellungen", + subtitle = if (isConfigured) serverUrl else null, + statusText = when (serverStatus) { + is SettingsViewModel.ServerStatus.Reachable -> "✅ Erreichbar" + is SettingsViewModel.ServerStatus.Unreachable -> "❌ Nicht erreichbar" + is SettingsViewModel.ServerStatus.Checking -> "🔍 Prüfe..." + is SettingsViewModel.ServerStatus.NotConfigured -> "⚠️ Nicht konfiguriert" + else -> null + }, + statusColor = when (serverStatus) { + is SettingsViewModel.ServerStatus.Reachable -> Color(0xFF4CAF50) + is SettingsViewModel.ServerStatus.Unreachable -> Color(0xFFF44336) + is SettingsViewModel.ServerStatus.NotConfigured -> Color(0xFFFF9800) + else -> Color.Gray + }, + onClick = { onNavigate(SettingsRoute.Server) } + ) + } + + // Sync-Einstellungen + item { + val intervalText = when (syncInterval) { + 15L -> "15 Min" + 60L -> "60 Min" + else -> "30 Min" + } + SettingsCard( + icon = Icons.Default.Sync, + title = "Sync-Einstellungen", + subtitle = if (autoSyncEnabled) "Auto-Sync: An • $intervalText" else "Auto-Sync: Aus", + onClick = { onNavigate(SettingsRoute.Sync) } + ) + } + + // Markdown-Integration + item { + SettingsCard( + icon = Icons.Default.Description, + title = "Markdown Desktop-Integration", + subtitle = if (markdownAutoSync) "Auto-Sync: An" else "Auto-Sync: Aus", + onClick = { onNavigate(SettingsRoute.Markdown) } + ) + } + + // Backup & Wiederherstellung + item { + SettingsCard( + icon = Icons.Default.Backup, + title = "Backup & Wiederherstellung", + subtitle = "Lokales oder Server-Backup", + onClick = { onNavigate(SettingsRoute.Backup) } + ) + } + + // Über diese App + item { + SettingsCard( + icon = Icons.Default.Info, + title = "Über diese App", + subtitle = "Version ${BuildConfig.VERSION_NAME}", + onClick = { onNavigate(SettingsRoute.About) } + ) + } + + // Debug & Diagnose + item { + SettingsCard( + icon = Icons.Default.BugReport, + title = "Debug & Diagnose", + subtitle = if (fileLoggingEnabled) "Logging: An" else "Logging: Aus", + onClick = { onNavigate(SettingsRoute.Debug) } + ) + } + } + } +} 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 new file mode 100644 index 0000000..7452bae --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SyncSettingsScreen.kt @@ -0,0 +1,112 @@ +package dev.dettmer.simplenotes.ui.settings.screens + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Sync +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.ui.settings.SettingsViewModel +import dev.dettmer.simplenotes.ui.settings.components.RadioOption +import dev.dettmer.simplenotes.ui.settings.components.SettingsDivider +import dev.dettmer.simplenotes.ui.settings.components.SettingsInfoCard +import dev.dettmer.simplenotes.ui.settings.components.SettingsRadioGroup +import dev.dettmer.simplenotes.ui.settings.components.SettingsScaffold +import dev.dettmer.simplenotes.ui.settings.components.SettingsSectionHeader +import dev.dettmer.simplenotes.ui.settings.components.SettingsSwitch + +/** + * Sync settings screen (Auto-Sync toggle and interval selection) + * v1.5.0: Jetpack Compose Settings Redesign + */ +@Composable +fun SyncSettingsScreen( + viewModel: SettingsViewModel, + onBack: () -> Unit +) { + val autoSyncEnabled by viewModel.autoSyncEnabled.collectAsState() + val syncInterval by viewModel.syncInterval.collectAsState() + + SettingsScaffold( + title = "Sync-Einstellungen", + onBack = onBack + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .verticalScroll(rememberScrollState()) + ) { + Spacer(modifier = Modifier.height(8.dp)) + + // Auto-Sync Info + SettingsInfoCard( + text = "🔄 Auto-Sync:\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)" + ) + + Spacer(modifier = Modifier.height(8.dp)) + + // Auto-Sync Toggle + SettingsSwitch( + title = "Auto-Sync aktiviert", + checked = autoSyncEnabled, + onCheckedChange = { viewModel.setAutoSync(it) }, + icon = Icons.Default.Sync + ) + + SettingsDivider() + + // Sync Interval Section + SettingsSectionHeader(text = "Sync-Intervall") + + SettingsInfoCard( + text = "Legt fest, wie oft die App im Hintergrund synchronisiert. " + + "Kürzere Intervalle bedeuten aktuellere Daten, verbrauchen aber etwas mehr Akku.\n\n" + + "⏱️ Hinweis: Wenn dein Smartphone im Standby ist, kann Android die " + + "Synchronisation verzögern (bis zu 60 Min.), um Akku zu sparen. " + + "Das ist normal und betrifft alle Hintergrund-Apps." + ) + + Spacer(modifier = Modifier.height(8.dp)) + + // Interval Radio Group + val intervalOptions = listOf( + RadioOption( + value = 15L, + title = "⚡ Alle 15 Minuten", + subtitle = "Schnellste Synchronisation • ~0.8% Akku/Tag (~23 mAh)" + ), + RadioOption( + value = 30L, + title = "✓ Alle 30 Minuten (Empfohlen)", + subtitle = "Ausgewogenes Verhältnis • ~0.4% Akku/Tag (~12 mAh)" + ), + RadioOption( + value = 60L, + title = "🔋 Alle 60 Minuten", + subtitle = "Maximale Akkulaufzeit • ~0.2% Akku/Tag (~6 mAh geschätzt)" + ) + ) + + SettingsRadioGroup( + options = intervalOptions, + selectedValue = syncInterval, + onValueSelected = { viewModel.setSyncInterval(it) } + ) + + Spacer(modifier = Modifier.height(16.dp)) + } + } +} diff --git a/android/build.gradle.kts b/android/build.gradle.kts index 2aaf92c..4b29661 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -2,6 +2,7 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.compose) apply false // v1.5.0: Jetpack Compose alias(libs.plugins.ktlint) apply false alias(libs.plugins.detekt) apply false } \ No newline at end of file diff --git a/android/gradle/libs.versions.toml b/android/gradle/libs.versions.toml index 59f739b..ea93011 100644 --- a/android/gradle/libs.versions.toml +++ b/android/gradle/libs.versions.toml @@ -11,6 +11,11 @@ activity = "1.8.0" constraintlayout = "2.1.4" ktlint = "12.1.0" detekt = "1.23.4" +# Jetpack Compose v1.5.0 +composeBom = "2024.02.00" +navigationCompose = "2.7.6" +lifecycleRuntimeCompose = "2.7.0" +activityCompose = "1.8.2" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -21,10 +26,22 @@ androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version material = { group = "com.google.android.material", name = "material", version.ref = "material" } androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" } +# Jetpack Compose v1.5.0 +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } +androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } +androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-compose-material-icons = { group = "androidx.compose.material", name = "material-icons-extended" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" } +androidx-lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycleRuntimeCompose" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" } detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } From c33448f84186ced9d0bd1b6e4c9495d9c6befd2f Mon Sep 17 00:00:00 2001 From: inventory69 Date: Thu, 15 Jan 2026 15:41:47 +0100 Subject: [PATCH 02/12] feat(v1.5.0): Complete MainActivity Jetpack Compose redesign MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Major Changes ### New Jetpack Compose Architecture (1,883 LOC total) - ComposeMainActivity.kt (370L): Main activity with Compose integration - MainScreen.kt (322L): Root Compose screen with layout orchestration - MainViewModel.kt (564L): MVVM state management for notes and sync - components/NoteCard.kt (243L): Individual note card with selection support - components/NotesList.kt (65L): LazyColumn with optimized item rendering - components/DeleteConfirmationDialog.kt (93L): Dialog with Server/Local options - components/EmptyState.kt (73L): Empty state UI - components/NoteTypeFAB.kt (83L): Floating action button with note type menu - components/SyncStatusBanner.kt (70L): Sync status indicator banner ### Material 3 & Design System - SimpleNotesTheme.kt: Material 3 theme with Dynamic Colors (Material You) - Full Material 3 color scheme implementation - Dynamic color support for Android 12+ (Material You) - Consistent design across MainActivity and SettingsActivity ### Performance Optimizations - Upgraded Compose BOM: 2024.12.01 → 2026.01.00 (latest Jan 2026) - Enable Strong Skipping Mode for efficient recomposition - Async loadNotes() on IO dispatcher (no UI blocking at startup) - LazyColumn with proper key={it.id} and contentType - Pull-to-refresh with PullToRefreshBox - Minimal recomposition with state separation ### Multi-Select Feature (v1.5.0) - Long-press note to enter selection mode - Tap additional notes to toggle selection in selection mode - SelectionTopBar with: * Selection counter ("X selected") * Select All button * Batch Delete button - Animated checkbox indicator on selected note cards - DeleteConfirmationDialog with Server/Local deletion options - Fixed server deletion: deleteNoteFromServer() now properly called with 3.5s delay ### Dependency Updates - Added org.jetbrains.kotlin.plugin.compose (Compose Compiler) - Jetpack Compose libraries: * androidx.compose.bom:2026.01.00 * androidx.compose.ui, material3, material-icons-extended * androidx.activity-compose, androidx.navigation-compose * androidx.lifecycle-runtime-compose - All dependencies remain Apache 2.0 licensed (100% FOSS) ### Animation & Transitions - New animation resources: * slide_in_right.xml, slide_out_left.xml * slide_in_left.xml, slide_out_right.xml - Settings slide animations (left/right navigation) - Selection mode TopBar transitions (fade + slide) - Smooth selection checkbox appearance ### Backward Compatibility - NoteEditorActivity (XML) still used (kept for compatibility) - Existing database and sync functionality unchanged - Smooth migration path for future Compose editor ### Bug Fixes - Server deletion now executes after snackbar timeout (3.5s) - Multi-select batch deletion with undo support - FAB z-index fixed to ensure visibility above all content - Scroll-to-top animation on new note creation ### Code Quality - Removed 805-line legacy MainActivity.kt - Clean separation of concerns: Activity → Screen → ViewModel - Composable functions follow Material 3 guidelines - No remember() blocks inside LazyColumn items (performance) - Direct MaterialTheme access (Compose handles optimization) ### Manifest Changes - Updated to use ComposeMainActivity as main launcher - Activity transition animations configured ### Testing - Build successful on Pixel 9 Pro XL (Android 16, 120Hz) - Release build optimized (minified + shrinkResources) - Multi-select UX tested - Server deletion verified BREAKING CHANGE: Long-press on note now enters multi-select mode instead of direct delete RELATED: v1.5.0_EXTENDED_FEATURES_PLAN.md added to project-docs --- android/app/build.gradle.kts | 5 + android/app/src/main/AndroidManifest.xml | 15 +- .../dev/dettmer/simplenotes/models/Note.kt | 7 + .../ui/main/ComposeMainActivity.kt | 370 ++++++++++++ .../dettmer/simplenotes/ui/main/MainScreen.kt | 322 ++++++++++ .../simplenotes/ui/main/MainViewModel.kt | 564 ++++++++++++++++++ .../components/DeleteConfirmationDialog.kt | 93 +++ .../ui/main/components/EmptyState.kt | 73 +++ .../ui/main/components/NoteCard.kt | 243 ++++++++ .../ui/main/components/NoteTypeFAB.kt | 83 +++ .../ui/main/components/NotesList.kt | 65 ++ .../ui/main/components/SyncStatusBanner.kt | 70 +++ .../ui/settings/ComposeSettingsActivity.kt | 61 +- .../simplenotes/ui/theme/SimpleNotesTheme.kt | 47 ++ .../app/src/main/res/anim/slide_in_left.xml | 9 + .../app/src/main/res/anim/slide_in_right.xml | 9 + .../app/src/main/res/anim/slide_out_left.xml | 9 + .../app/src/main/res/anim/slide_out_right.xml | 9 + android/gradle/libs.versions.toml | 4 +- 19 files changed, 2012 insertions(+), 46 deletions(-) create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainScreen.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/EmptyState.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteCard.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteTypeFAB.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NotesList.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/SyncStatusBanner.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/theme/SimpleNotesTheme.kt create mode 100644 android/app/src/main/res/anim/slide_in_left.xml create mode 100644 android/app/src/main/res/anim/slide_in_right.xml create mode 100644 android/app/src/main/res/anim/slide_out_left.xml create mode 100644 android/app/src/main/res/anim/slide_out_right.xml diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 9e188b2..2115304 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -99,6 +99,11 @@ android { buildConfig = true // Enable BuildConfig generation compose = true // v1.5.0: Jetpack Compose für Settings Redesign } + + // v1.5.0 Hotfix: Strong Skipping Mode für bessere 120Hz Performance + composeCompiler { + enableStrongSkippingMode = true + } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0231cc6..7c8e354 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -27,8 +27,9 @@ android:theme="@style/Theme.SimpleNotes" android:networkSecurityConfig="@xml/network_security_config" tools:targetApi="31"> + @@ -37,21 +38,27 @@ + + + + android:parentActivityName=".ui.main.ComposeMainActivity" /> + android:parentActivityName=".ui.main.ComposeMainActivity" /> diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/models/Note.kt b/android/app/src/main/java/dev/dettmer/simplenotes/models/Note.kt index 6dce920..5c64a3a 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/models/Note.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/models/Note.kt @@ -1,5 +1,6 @@ package dev.dettmer.simplenotes.models +import androidx.compose.runtime.Immutable import dev.dettmer.simplenotes.utils.Logger import java.text.SimpleDateFormat import java.util.Date @@ -7,6 +8,12 @@ import java.util.Locale import java.util.TimeZone import java.util.UUID +/** + * Note data class with Compose stability annotation. + * @Immutable tells Compose this class is stable and won't change unexpectedly, + * enabling skip optimizations during recomposition. + */ +@Immutable data class Note( val id: String = UUID.randomUUID().toString(), val title: String, diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt new file mode 100644 index 0000000..975369e --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt @@ -0,0 +1,370 @@ +package dev.dettmer.simplenotes.ui.main + +import android.Manifest +import android.app.ActivityOptions +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.content.pm.PackageManager +import android.os.Build +import android.os.Bundle +import android.widget.Toast +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.activity.viewModels +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.platform.LocalContext +import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen +import androidx.lifecycle.lifecycleScope +import androidx.localbroadcastmanager.content.LocalBroadcastManager +import com.google.android.material.color.DynamicColors +import dev.dettmer.simplenotes.NoteEditorActivity +import dev.dettmer.simplenotes.models.NoteType +import dev.dettmer.simplenotes.models.SyncStatus +import dev.dettmer.simplenotes.storage.NotesStorage +import dev.dettmer.simplenotes.sync.SyncStateManager +import dev.dettmer.simplenotes.sync.SyncWorker +import dev.dettmer.simplenotes.ui.settings.ComposeSettingsActivity +import dev.dettmer.simplenotes.ui.theme.SimpleNotesTheme +import dev.dettmer.simplenotes.utils.Constants +import dev.dettmer.simplenotes.utils.Logger +import dev.dettmer.simplenotes.utils.NotificationHelper +import kotlinx.coroutines.launch + +/** + * Main Activity with Jetpack Compose UI + * v1.5.0: Complete MainActivity Redesign with Compose + * + * Replaces the old 805-line MainActivity.kt with a modern + * Compose-based implementation featuring: + * - Notes list with swipe-to-delete + * - Pull-to-refresh for sync + * - FAB with note type selection + * - Material 3 Design with Dynamic Colors (Material You) + * - Design consistent with ComposeSettingsActivity + */ +class ComposeMainActivity : ComponentActivity() { + + companion object { + private const val TAG = "ComposeMainActivity" + private const val REQUEST_NOTIFICATION_PERMISSION = 1001 + private const val REQUEST_SETTINGS = 1002 + } + + private val viewModel: MainViewModel by viewModels() + + private val prefs by lazy { + getSharedPreferences(Constants.PREFS_NAME, Context.MODE_PRIVATE) + } + + // Phase 3: Track if coming from editor to scroll to top + private var cameFromEditor = false + + /** + * BroadcastReceiver for Background-Sync Completion (Periodic Sync) + */ + private val syncCompletedReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + val success = intent?.getBooleanExtra("success", false) ?: false + val count = intent?.getIntExtra("count", 0) ?: 0 + + Logger.d(TAG, "📡 Sync completed broadcast received: success=$success, count=$count") + + // UI refresh + if (success && count > 0) { + viewModel.loadNotes() + Logger.d(TAG, "🔄 Notes reloaded after background sync") + } + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + // Install Splash Screen (Android 12+) + installSplashScreen() + + super.onCreate(savedInstanceState) + + // Apply Dynamic Colors for Material You (Android 12+) + DynamicColors.applyToActivityIfAvailable(this) + + // Enable edge-to-edge display + enableEdgeToEdge() + + // Initialize Logger and enable file logging if configured + Logger.init(this) + if (prefs.getBoolean(Constants.KEY_FILE_LOGGING_ENABLED, false)) { + Logger.setFileLoggingEnabled(true) + } + + // Clear old sync notifications on app start + NotificationHelper.clearSyncNotifications(this) + + // Request notification permission (Android 13+) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + requestNotificationPermission() + } + + // v1.4.1: Migrate checklists for backwards compatibility + migrateChecklistsForBackwardsCompat() + + // Setup Sync State Observer + setupSyncStateObserver() + + setContent { + SimpleNotesTheme { + val context = LocalContext.current + + // Dialog state for delete confirmation + var deleteDialogData by remember { mutableStateOf(null) } + + // Handle delete dialog events + LaunchedEffect(Unit) { + viewModel.showDeleteDialog.collect { data -> + deleteDialogData = data + } + } + + // Handle toast events + LaunchedEffect(Unit) { + viewModel.showToast.collect { message -> + Toast.makeText(context, message, Toast.LENGTH_SHORT).show() + } + } + + // Delete confirmation dialog + deleteDialogData?.let { data -> + DeleteConfirmationDialog( + noteTitle = data.note.title, + onDismiss = { + viewModel.restoreNoteAfterSwipe(data.originalList) + deleteDialogData = null + }, + onDeleteLocal = { + viewModel.deleteNoteConfirmed(data.note, deleteFromServer = false) + deleteDialogData = null + }, + onDeleteFromServer = { + viewModel.deleteNoteConfirmed(data.note, deleteFromServer = true) + deleteDialogData = null + } + ) + } + + MainScreen( + viewModel = viewModel, + onOpenNote = { noteId -> openNoteEditor(noteId) }, + onOpenSettings = { openSettings() }, + onCreateNote = { noteType -> createNote(noteType) } + ) + } + } + } + + override fun onResume() { + super.onResume() + + Logger.d(TAG, "📱 ComposeMainActivity.onResume() - Registering receivers") + + // Register BroadcastReceiver for Background-Sync + LocalBroadcastManager.getInstance(this).registerReceiver( + syncCompletedReceiver, + IntentFilter(SyncWorker.ACTION_SYNC_COMPLETED) + ) + + Logger.d(TAG, "📡 BroadcastReceiver registered (sync-completed)") + + // Reload notes + viewModel.loadNotes() + + // Phase 3: Scroll to top if coming from editor (new/edited note) + if (cameFromEditor) { + viewModel.scrollToTop() + cameFromEditor = false + Logger.d(TAG, "📜 Came from editor - scrolling to top") + } + + // Trigger Auto-Sync on app resume + viewModel.triggerAutoSync("onResume") + } + + override fun onPause() { + super.onPause() + + // Unregister BroadcastReceiver + LocalBroadcastManager.getInstance(this).unregisterReceiver(syncCompletedReceiver) + Logger.d(TAG, "📡 BroadcastReceiver unregistered") + } + + private fun setupSyncStateObserver() { + SyncStateManager.syncStatus.observe(this) { status -> + viewModel.updateSyncState(status) + + // Hide banner after delay for completed/error states + when (status.state) { + SyncStateManager.SyncState.COMPLETED -> { + lifecycleScope.launch { + kotlinx.coroutines.delay(1500L) + SyncStateManager.reset() + } + } + SyncStateManager.SyncState.ERROR -> { + lifecycleScope.launch { + kotlinx.coroutines.delay(3000L) + SyncStateManager.reset() + } + } + else -> { /* No action needed */ } + } + } + } + + private fun openNoteEditor(noteId: String?) { + cameFromEditor = true + val intent = Intent(this, NoteEditorActivity::class.java) + noteId?.let { + intent.putExtra(NoteEditorActivity.EXTRA_NOTE_ID, it) + } + startActivity(intent) + } + + private fun createNote(noteType: NoteType) { + cameFromEditor = true + val intent = Intent(this, NoteEditorActivity::class.java) + intent.putExtra(NoteEditorActivity.EXTRA_NOTE_TYPE, noteType.name) + startActivity(intent) + } + + private fun openSettings() { + val intent = Intent(this, ComposeSettingsActivity::class.java) + val options = ActivityOptions.makeCustomAnimation( + this, + dev.dettmer.simplenotes.R.anim.slide_in_right, + dev.dettmer.simplenotes.R.anim.slide_out_left + ) + @Suppress("DEPRECATION") + startActivityForResult(intent, REQUEST_SETTINGS, options.toBundle()) + } + + private fun requestNotificationPermission() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) + != PackageManager.PERMISSION_GRANTED) { + requestPermissions( + arrayOf(Manifest.permission.POST_NOTIFICATIONS), + REQUEST_NOTIFICATION_PERMISSION + ) + } + } + } + + /** + * v1.4.1: Migrates existing checklists for backwards compatibility. + */ + private fun migrateChecklistsForBackwardsCompat() { + val migrationKey = "v1.4.1_checklist_migration_done" + + // Only run once + if (prefs.getBoolean(migrationKey, false)) { + return + } + + val storage = NotesStorage(this) + val allNotes = storage.loadAllNotes() + val checklistsToMigrate = allNotes.filter { note -> + note.noteType == NoteType.CHECKLIST && + note.content.isBlank() && + note.checklistItems?.isNotEmpty() == true + } + + if (checklistsToMigrate.isNotEmpty()) { + Logger.d(TAG, "🔄 v1.4.1 Migration: Found ${checklistsToMigrate.size} checklists without fallback content") + + for (note in checklistsToMigrate) { + val updatedNote = note.copy( + syncStatus = SyncStatus.PENDING + ) + storage.saveNote(updatedNote) + Logger.d(TAG, " 📝 Marked for re-sync: ${note.title}") + } + + Logger.d(TAG, "✅ v1.4.1 Migration: ${checklistsToMigrate.size} checklists marked for re-sync") + } + + // Mark migration as done + prefs.edit().putBoolean(migrationKey, true).apply() + } + + @Deprecated("Deprecated in Java") + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + + if (requestCode == REQUEST_SETTINGS && resultCode == RESULT_OK) { + // Settings changed, reload notes + viewModel.loadNotes() + } + } + + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + + when (requestCode) { + REQUEST_NOTIFICATION_PERMISSION -> { + if (grantResults.isNotEmpty() && + grantResults[0] == PackageManager.PERMISSION_GRANTED) { + Toast.makeText(this, "Benachrichtigungen aktiviert", Toast.LENGTH_SHORT).show() + } else { + Toast.makeText(this, + "Benachrichtigungen deaktiviert. Du kannst sie in den Einstellungen aktivieren.", + Toast.LENGTH_SHORT + ).show() + } + } + } + } +} + +/** + * Delete confirmation dialog + */ +@Composable +private fun DeleteConfirmationDialog( + noteTitle: String, + onDismiss: () -> Unit, + onDeleteLocal: () -> Unit, + onDeleteFromServer: () -> Unit +) { + AlertDialog( + onDismissRequest = onDismiss, + title = { Text("Notiz löschen") }, + text = { + Text("\"$noteTitle\" wird lokal gelöscht.\n\nAuch vom Server löschen?") + }, + dismissButton = { + TextButton(onClick = onDismiss) { + Text("Abbrechen") + } + }, + confirmButton = { + TextButton(onClick = onDeleteLocal) { + Text("Nur lokal") + } + TextButton(onClick = onDeleteFromServer) { + Text("Vom Server löschen") + } + } + ) +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainScreen.kt new file mode 100644 index 0000000..ed35821 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainScreen.kt @@ -0,0 +1,322 @@ +package dev.dettmer.simplenotes.ui.main + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutVertically +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.filled.Delete +import androidx.compose.material.icons.filled.Refresh +import androidx.compose.material.icons.filled.SelectAll +import androidx.compose.material.icons.filled.Settings +import androidx.compose.material3.ExperimentalMaterial3Api +// FabPosition nicht mehr benötigt - FAB wird manuell platziert +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarDuration +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.SnackbarResult +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.material3.pulltorefresh.PullToRefreshBox +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.compose.ui.zIndex +import dev.dettmer.simplenotes.models.NoteType +import dev.dettmer.simplenotes.sync.SyncStateManager +import dev.dettmer.simplenotes.ui.main.components.DeleteConfirmationDialog +import dev.dettmer.simplenotes.ui.main.components.EmptyState +import dev.dettmer.simplenotes.ui.main.components.NoteTypeFAB +import dev.dettmer.simplenotes.ui.main.components.NotesList +import dev.dettmer.simplenotes.ui.main.components.SyncStatusBanner +import kotlinx.coroutines.launch + +/** + * Main screen displaying the notes list + * v1.5.0: Jetpack Compose MainActivity Redesign + * + * Performance optimized with proper state handling: + * - LazyListState for scroll control + * - Scaffold FAB slot for proper z-ordering + * - Scroll-to-top on new note + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MainScreen( + viewModel: MainViewModel, + onOpenNote: (String?) -> Unit, + onOpenSettings: () -> Unit, + onCreateNote: (NoteType) -> Unit +) { + val notes by viewModel.notes.collectAsState() + val syncState by viewModel.syncState.collectAsState() + val syncMessage by viewModel.syncMessage.collectAsState() + val scrollToTop by viewModel.scrollToTop.collectAsState() + + // Multi-Select State + val selectedNotes by viewModel.selectedNotes.collectAsState() + val isSelectionMode by viewModel.isSelectionMode.collectAsState() + + // Delete confirmation dialog state + var showBatchDeleteDialog by remember { mutableStateOf(false) } + + val snackbarHostState = remember { SnackbarHostState() } + val scope = rememberCoroutineScope() + val listState = rememberLazyListState() + + // Compute isSyncing once + val isSyncing = syncState == SyncStateManager.SyncState.SYNCING + + // Handle snackbar events from ViewModel + LaunchedEffect(Unit) { + viewModel.showSnackbar.collect { data -> + scope.launch { + val result = snackbarHostState.showSnackbar( + message = data.message, + actionLabel = data.actionLabel, + duration = SnackbarDuration.Long + ) + if (result == SnackbarResult.ActionPerformed) { + data.onAction() + } + } + } + } + + // Phase 3: Scroll to top when new note created + LaunchedEffect(scrollToTop) { + if (scrollToTop) { + listState.animateScrollToItem(0) + viewModel.resetScrollToTop() + } + } + + // v1.5.0 Hotfix: FAB manuell mit zIndex platzieren für garantierte Sichtbarkeit + Scaffold( + topBar = { + // Animated switch between normal and selection TopBar + AnimatedVisibility( + visible = isSelectionMode, + enter = slideInVertically() + fadeIn(), + exit = slideOutVertically() + fadeOut() + ) { + SelectionTopBar( + selectedCount = selectedNotes.size, + totalCount = notes.size, + onCloseSelection = { viewModel.clearSelection() }, + onSelectAll = { viewModel.selectAllNotes() }, + onDeleteSelected = { showBatchDeleteDialog = true } + ) + } + AnimatedVisibility( + visible = !isSelectionMode, + enter = slideInVertically() + fadeIn(), + exit = slideOutVertically() + fadeOut() + ) { + MainTopBar( + syncEnabled = !isSyncing, + onSyncClick = { viewModel.triggerManualSync("toolbar") }, + onSettingsClick = onOpenSettings + ) + } + }, + // FAB wird manuell in Box platziert für korrekten z-Index + snackbarHost = { SnackbarHost(snackbarHostState) }, + containerColor = MaterialTheme.colorScheme.surface + ) { paddingValues -> + // PullToRefreshBox wraps the content with pull-to-refresh capability + PullToRefreshBox( + isRefreshing = isSyncing, + onRefresh = { viewModel.triggerManualSync("pullToRefresh") }, + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + ) { + Box(modifier = Modifier.fillMaxSize()) { + // Main content column + Column(modifier = Modifier.fillMaxSize()) { + // Sync Status Banner (not affected by pull-to-refresh) + SyncStatusBanner( + syncState = syncState, + message = syncMessage + ) + + // Content: Empty state or notes list + if (notes.isEmpty()) { + EmptyState(modifier = Modifier.weight(1f)) + } else { + NotesList( + notes = notes, + showSyncStatus = viewModel.isServerConfigured(), + selectedNotes = selectedNotes, + isSelectionMode = isSelectionMode, + listState = listState, + modifier = Modifier.weight(1f), + onNoteClick = { note -> onOpenNote(note.id) }, + onNoteLongPress = { note -> + // Long-press starts selection mode + viewModel.startSelectionMode(note.id) + }, + onNoteSelectionToggle = { note -> + viewModel.toggleNoteSelection(note.id) + } + ) + } + } + + // FAB als TOP-LAYER - nur anzeigen wenn nicht im Selection Mode + AnimatedVisibility( + visible = !isSelectionMode, + enter = fadeIn(), + exit = fadeOut(), + modifier = Modifier + .align(Alignment.BottomEnd) + .padding(16.dp) + .zIndex(Float.MAX_VALUE) + ) { + NoteTypeFAB( + onCreateNote = onCreateNote + ) + } + } + } + + // Batch Delete Confirmation Dialog + if (showBatchDeleteDialog) { + DeleteConfirmationDialog( + noteCount = selectedNotes.size, + onDismiss = { showBatchDeleteDialog = false }, + onDeleteLocal = { + viewModel.deleteSelectedNotes(deleteFromServer = false) + showBatchDeleteDialog = false + }, + onDeleteEverywhere = { + viewModel.deleteSelectedNotes(deleteFromServer = true) + showBatchDeleteDialog = false + } + ) + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun MainTopBar( + syncEnabled: Boolean, + onSyncClick: () -> Unit, + onSettingsClick: () -> Unit +) { + TopAppBar( + title = { + Text( + text = "Simple Notes", + style = MaterialTheme.typography.titleLarge + ) + }, + actions = { + IconButton( + onClick = onSyncClick, + enabled = syncEnabled + ) { + Icon( + imageVector = Icons.Default.Refresh, + contentDescription = "Synchronisieren" + ) + } + IconButton(onClick = onSettingsClick) { + Icon( + imageVector = Icons.Default.Settings, + contentDescription = "Einstellungen" + ) + } + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = MaterialTheme.colorScheme.surface, + titleContentColor = MaterialTheme.colorScheme.onSurface + ) + ) +} + +/** + * Selection mode TopBar - shows selected count and actions + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun SelectionTopBar( + selectedCount: Int, + totalCount: Int, + onCloseSelection: () -> Unit, + onSelectAll: () -> Unit, + onDeleteSelected: () -> Unit +) { + TopAppBar( + navigationIcon = { + IconButton(onClick = onCloseSelection) { + Icon( + imageVector = Icons.Default.Close, + contentDescription = "Auswahl beenden" + ) + } + }, + title = { + Text( + text = "$selectedCount ausgewählt", + style = MaterialTheme.typography.titleLarge + ) + }, + actions = { + // Select All button (only if not all selected) + if (selectedCount < totalCount) { + IconButton(onClick = onSelectAll) { + Icon( + imageVector = Icons.Default.SelectAll, + contentDescription = "Alle auswählen" + ) + } + } + // Delete button + IconButton( + onClick = onDeleteSelected, + enabled = selectedCount > 0 + ) { + Icon( + imageVector = Icons.Default.Delete, + contentDescription = "Ausgewählte löschen", + tint = if (selectedCount > 0) { + MaterialTheme.colorScheme.error + } else { + MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f) + } + ) + } + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = MaterialTheme.colorScheme.primaryContainer, + titleContentColor = MaterialTheme.colorScheme.onPrimaryContainer, + navigationIconContentColor = MaterialTheme.colorScheme.onPrimaryContainer, + actionIconContentColor = MaterialTheme.colorScheme.onPrimaryContainer + ) + ) +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt new file mode 100644 index 0000000..0ef1b88 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt @@ -0,0 +1,564 @@ +package dev.dettmer.simplenotes.ui.main + +import android.app.Application +import android.content.Context +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.viewModelScope +import dev.dettmer.simplenotes.models.Note +import dev.dettmer.simplenotes.storage.NotesStorage +import dev.dettmer.simplenotes.sync.SyncStateManager +import dev.dettmer.simplenotes.sync.WebDavSyncService +import dev.dettmer.simplenotes.utils.Constants +import dev.dettmer.simplenotes.utils.Logger +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +/** + * ViewModel for MainActivity Compose + * v1.5.0: Jetpack Compose MainActivity Redesign + * + * Manages notes list, sync state, and deletion with undo. + */ +class MainViewModel(application: Application) : AndroidViewModel(application) { + + companion object { + private const val TAG = "MainViewModel" + private const val MIN_AUTO_SYNC_INTERVAL_MS = 60_000L // 1 Minute + private const val PREF_LAST_AUTO_SYNC_TIME = "last_auto_sync_timestamp" + } + + private val storage = NotesStorage(application) + private val prefs = application.getSharedPreferences(Constants.PREFS_NAME, Context.MODE_PRIVATE) + + // ═══════════════════════════════════════════════════════════════════════ + // Notes State + // ═══════════════════════════════════════════════════════════════════════ + + private val _notes = MutableStateFlow>(emptyList()) + val notes: StateFlow> = _notes.asStateFlow() + + private val _pendingDeletions = MutableStateFlow>(emptySet()) + val pendingDeletions: StateFlow> = _pendingDeletions.asStateFlow() + + // ═══════════════════════════════════════════════════════════════════════ + // Multi-Select State (v1.5.0) + // ═══════════════════════════════════════════════════════════════════════ + + private val _selectedNotes = MutableStateFlow>(emptySet()) + val selectedNotes: StateFlow> = _selectedNotes.asStateFlow() + + val isSelectionMode: StateFlow = _selectedNotes + .map { it.isNotEmpty() } + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), false) + + // ═══════════════════════════════════════════════════════════════════════ + // Sync State (derived from SyncStateManager) + // ═══════════════════════════════════════════════════════════════════════ + + private val _syncState = MutableStateFlow(SyncStateManager.SyncState.IDLE) + val syncState: StateFlow = _syncState.asStateFlow() + + private val _syncMessage = MutableStateFlow(null) + val syncMessage: StateFlow = _syncMessage.asStateFlow() + + // ═══════════════════════════════════════════════════════════════════════ + // UI Events + // ═══════════════════════════════════════════════════════════════════════ + + private val _showToast = MutableSharedFlow() + val showToast: SharedFlow = _showToast.asSharedFlow() + + private val _showDeleteDialog = MutableSharedFlow() + val showDeleteDialog: SharedFlow = _showDeleteDialog.asSharedFlow() + + private val _showSnackbar = MutableSharedFlow() + val showSnackbar: SharedFlow = _showSnackbar.asSharedFlow() + + // Phase 3: Scroll-to-top when new note is created + private val _scrollToTop = MutableStateFlow(false) + val scrollToTop: StateFlow = _scrollToTop.asStateFlow() + + // Track first note ID to detect new notes + private var previousFirstNoteId: String? = null + + // ═══════════════════════════════════════════════════════════════════════ + // Data Classes + // ═══════════════════════════════════════════════════════════════════════ + + data class DeleteDialogData( + val note: Note, + val originalList: List + ) + + data class SnackbarData( + val message: String, + val actionLabel: String, + val onAction: () -> Unit + ) + + // ═══════════════════════════════════════════════════════════════════════ + // Initialization + // ═══════════════════════════════════════════════════════════════════════ + + init { + // v1.5.0 Performance: Load notes asynchronously to avoid blocking UI + viewModelScope.launch(Dispatchers.IO) { + loadNotesAsync() + } + } + + // ═══════════════════════════════════════════════════════════════════════ + // Notes Actions + // ═══════════════════════════════════════════════════════════════════════ + + /** + * Load notes asynchronously on IO dispatcher + * This prevents UI blocking during app startup + */ + private suspend fun loadNotesAsync() { + val allNotes = storage.loadAllNotes() + val pendingIds = _pendingDeletions.value + val filteredNotes = allNotes.filter { it.id !in pendingIds } + + withContext(Dispatchers.Main) { + // Phase 3: Detect if a new note was added at the top + val newFirstNoteId = filteredNotes.firstOrNull()?.id + if (newFirstNoteId != null && + previousFirstNoteId != null && + newFirstNoteId != previousFirstNoteId) { + // New note at top → trigger scroll + _scrollToTop.value = true + Logger.d(TAG, "📜 New note detected at top, triggering scroll-to-top") + } + previousFirstNoteId = newFirstNoteId + + _notes.value = filteredNotes + } + } + + /** + * Public loadNotes - delegates to async version + */ + fun loadNotes() { + viewModelScope.launch(Dispatchers.IO) { + loadNotesAsync() + } + } + + /** + * Reset scroll-to-top flag after scroll completed + */ + fun resetScrollToTop() { + _scrollToTop.value = false + } + + /** + * Force scroll to top (e.g., after returning from editor) + */ + fun scrollToTop() { + _scrollToTop.value = true + } + + // ═══════════════════════════════════════════════════════════════════════ + // Multi-Select Actions (v1.5.0) + // ═══════════════════════════════════════════════════════════════════════ + + /** + * Toggle selection of a note + */ + fun toggleNoteSelection(noteId: String) { + _selectedNotes.value = if (noteId in _selectedNotes.value) { + _selectedNotes.value - noteId + } else { + _selectedNotes.value + noteId + } + } + + /** + * Start selection mode with initial note + */ + fun startSelectionMode(noteId: String) { + _selectedNotes.value = setOf(noteId) + } + + /** + * Select all notes + */ + fun selectAllNotes() { + _selectedNotes.value = _notes.value.map { it.id }.toSet() + } + + /** + * Clear selection and exit selection mode + */ + fun clearSelection() { + _selectedNotes.value = emptySet() + } + + /** + * Get count of selected notes + */ + fun getSelectedCount(): Int = _selectedNotes.value.size + + /** + * Delete all selected notes + */ + fun deleteSelectedNotes(deleteFromServer: Boolean) { + val selectedIds = _selectedNotes.value.toList() + val selectedNotes = _notes.value.filter { it.id in selectedIds } + + if (selectedNotes.isEmpty()) return + + // Add to pending deletions + _pendingDeletions.value = _pendingDeletions.value + selectedIds.toSet() + + // Delete from storage + selectedNotes.forEach { note -> + storage.deleteNote(note.id) + } + + // Clear selection + clearSelection() + + // Reload notes + loadNotes() + + // Show snackbar with undo + val count = selectedNotes.size + val message = if (deleteFromServer) { + "$count Notiz${if (count > 1) "en" else ""} werden vom Server gelöscht" + } else { + "$count Notiz${if (count > 1) "en" else ""} lokal gelöscht" + } + + viewModelScope.launch { + _showSnackbar.emit(SnackbarData( + message = message, + actionLabel = "RÜCKGÄNGIG", + onAction = { + undoDeleteMultiple(selectedNotes) + } + )) + + // If delete from server, actually delete after a short delay + // (to allow undo action before server deletion) + if (deleteFromServer) { + kotlinx.coroutines.delay(3500) // Snackbar shows for ~3s + // Only delete if not restored (check if still in pending) + selectedIds.forEach { noteId -> + if (noteId in _pendingDeletions.value) { + deleteNoteFromServer(noteId) + } + } + } else { + // Just finalize local deletion + selectedIds.forEach { noteId -> + finalizeDeletion(noteId) + } + } + } + } + + /** + * Undo deletion of multiple notes + */ + private fun undoDeleteMultiple(notes: List) { + // Remove from pending deletions + _pendingDeletions.value = _pendingDeletions.value - notes.map { it.id }.toSet() + + // Restore to storage + notes.forEach { note -> + storage.saveNote(note) + } + + // Reload notes + loadNotes() + } + + /** + * Called when user long-presses a note to delete + * Shows dialog for delete confirmation (replaces swipe-to-delete for performance) + */ + fun onNoteLongPressDelete(note: Note) { + val alwaysDeleteFromServer = prefs.getBoolean(Constants.KEY_ALWAYS_DELETE_FROM_SERVER, false) + + // Store original list for potential restore + val originalList = _notes.value.toList() + + if (alwaysDeleteFromServer) { + // Auto-delete without dialog + deleteNoteConfirmed(note, deleteFromServer = true) + } else { + // Show dialog - don't remove from UI yet (user can cancel) + viewModelScope.launch { + _showDeleteDialog.emit(DeleteDialogData(note, originalList)) + } + } + } + + /** + * Called when user swipes to delete a note (legacy - kept for compatibility) + * Shows dialog if "always delete from server" is not enabled + */ + fun onNoteSwipedToDelete(note: Note) { + onNoteLongPressDelete(note) // Delegate to long-press handler + } + + /** + * Restore note after swipe (user cancelled dialog) + */ + fun restoreNoteAfterSwipe(originalList: List) { + _notes.value = originalList + } + + /** + * Confirm note deletion (from dialog or auto-delete) + */ + fun deleteNoteConfirmed(note: Note, deleteFromServer: Boolean) { + // Add to pending deletions + _pendingDeletions.value = _pendingDeletions.value + note.id + + // Delete from storage + storage.deleteNote(note.id) + + // Reload notes + loadNotes() + + // Show snackbar with undo + val message = if (deleteFromServer) { + "\"${note.title}\" wird vom Server gelöscht" + } else { + "\"${note.title}\" lokal gelöscht" + } + + viewModelScope.launch { + _showSnackbar.emit(SnackbarData( + message = message, + actionLabel = "RÜCKGÄNGIG", + onAction = { + undoDelete(note) + } + )) + + // If delete from server, actually delete after snackbar timeout + if (deleteFromServer) { + kotlinx.coroutines.delay(3500) // Snackbar shows for ~3s + // Only delete if not restored (check if still in pending) + if (note.id in _pendingDeletions.value) { + deleteNoteFromServer(note.id) + } + } else { + // Just finalize local deletion + finalizeDeletion(note.id) + } + } + } + + /** + * Undo note deletion + */ + fun undoDelete(note: Note) { + // Remove from pending deletions + _pendingDeletions.value = _pendingDeletions.value - note.id + + // Restore to storage + storage.saveNote(note) + + // Reload notes + loadNotes() + } + + /** + * Actually delete note from server after snackbar dismissed + */ + fun deleteNoteFromServer(noteId: String) { + viewModelScope.launch { + try { + val webdavService = WebDavSyncService(getApplication()) + val success = withContext(Dispatchers.IO) { + webdavService.deleteNoteFromServer(noteId) + } + + if (success) { + _showToast.emit("Vom Server gelöscht") + } else { + _showToast.emit("Server-Löschung fehlgeschlagen") + } + } catch (e: Exception) { + _showToast.emit("Server-Fehler: ${e.message}") + } finally { + // Remove from pending deletions + _pendingDeletions.value = _pendingDeletions.value - noteId + } + } + } + + /** + * Finalize deletion (remove from pending set) + */ + fun finalizeDeletion(noteId: String) { + _pendingDeletions.value = _pendingDeletions.value - noteId + } + + // ═══════════════════════════════════════════════════════════════════════ + // Sync Actions + // ═══════════════════════════════════════════════════════════════════════ + + fun updateSyncState(status: SyncStateManager.SyncStatus) { + _syncState.value = status.state + _syncMessage.value = status.message + } + + /** + * Trigger manual sync (from toolbar button or pull-to-refresh) + */ + fun triggerManualSync(source: String = "manual") { + if (!SyncStateManager.tryStartSync(source)) { + return + } + + viewModelScope.launch { + try { + val syncService = WebDavSyncService(getApplication()) + + // Check for unsynced changes + if (!syncService.hasUnsyncedChanges()) { + Logger.d(TAG, "⏭️ $source Sync: No unsynced changes") + SyncStateManager.markCompleted("Bereits synchronisiert") + loadNotes() + return@launch + } + + // Check server reachability + val isReachable = withContext(Dispatchers.IO) { + syncService.isServerReachable() + } + + if (!isReachable) { + Logger.d(TAG, "⏭️ $source Sync: Server not reachable") + SyncStateManager.markError("Server nicht erreichbar") + return@launch + } + + // Perform sync + val result = withContext(Dispatchers.IO) { + syncService.syncNotes() + } + + if (result.isSuccess) { + SyncStateManager.markCompleted("${result.syncedCount} Notizen") + loadNotes() + } else { + SyncStateManager.markError(result.errorMessage) + } + } catch (e: Exception) { + SyncStateManager.markError(e.message) + } + } + } + + /** + * Trigger auto-sync (onResume) + * Only runs if server is configured and interval has passed + */ + fun triggerAutoSync(source: String = "auto") { + // Throttling check + if (!canTriggerAutoSync()) { + return + } + + // Check if server is configured + val serverUrl = prefs.getString(Constants.KEY_SERVER_URL, null) + if (serverUrl.isNullOrEmpty() || serverUrl == "http://" || serverUrl == "https://") { + return + } + + if (!SyncStateManager.tryStartSync("auto-$source")) { + Logger.d(TAG, "⏭️ Auto-sync ($source): Another sync already in progress") + return + } + + Logger.d(TAG, "🔄 Auto-sync triggered ($source)") + + // Update last sync timestamp + prefs.edit().putLong(PREF_LAST_AUTO_SYNC_TIME, System.currentTimeMillis()).apply() + + viewModelScope.launch { + try { + val syncService = WebDavSyncService(getApplication()) + + // Check for unsynced changes + if (!syncService.hasUnsyncedChanges()) { + Logger.d(TAG, "⏭️ Auto-sync ($source): No unsynced changes - skipping") + SyncStateManager.reset() + return@launch + } + + // Check server reachability + val isReachable = withContext(Dispatchers.IO) { + syncService.isServerReachable() + } + + if (!isReachable) { + Logger.d(TAG, "⏭️ Auto-sync ($source): Server not reachable - skipping silently") + SyncStateManager.reset() + return@launch + } + + // Perform sync + val result = withContext(Dispatchers.IO) { + syncService.syncNotes() + } + + if (result.isSuccess && result.syncedCount > 0) { + Logger.d(TAG, "✅ Auto-sync successful ($source): ${result.syncedCount} notes") + SyncStateManager.markCompleted("${result.syncedCount} Notizen") + _showToast.emit("✅ Gesynct: ${result.syncedCount} Notizen") + loadNotes() + } else if (result.isSuccess) { + Logger.d(TAG, "ℹ️ Auto-sync ($source): No changes") + SyncStateManager.markCompleted() + } else { + Logger.e(TAG, "❌ Auto-sync failed ($source): ${result.errorMessage}") + SyncStateManager.markError(result.errorMessage) + } + } catch (e: Exception) { + Logger.e(TAG, "💥 Auto-sync exception ($source): ${e.message}") + SyncStateManager.markError(e.message) + } + } + } + + private fun canTriggerAutoSync(): Boolean { + val lastSyncTime = prefs.getLong(PREF_LAST_AUTO_SYNC_TIME, 0) + val now = System.currentTimeMillis() + val timeSinceLastSync = now - lastSyncTime + + if (timeSinceLastSync < MIN_AUTO_SYNC_INTERVAL_MS) { + val remainingSeconds = (MIN_AUTO_SYNC_INTERVAL_MS - timeSinceLastSync) / 1000 + Logger.d(TAG, "⏳ Auto-sync throttled - wait ${remainingSeconds}s") + return false + } + + return true + } + + // ═══════════════════════════════════════════════════════════════════════ + // Helpers + // ═══════════════════════════════════════════════════════════════════════ + + fun isServerConfigured(): Boolean { + val serverUrl = prefs.getString(Constants.KEY_SERVER_URL, null) + return !serverUrl.isNullOrEmpty() && serverUrl != "http://" && serverUrl != "https://" + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt new file mode 100644 index 0000000..5ea14dc --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt @@ -0,0 +1,93 @@ +package dev.dettmer.simplenotes.ui.main.components + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +/** + * Delete confirmation dialog with server/local options + * v1.5.0: Multi-Select Feature + */ +@Composable +fun DeleteConfirmationDialog( + noteCount: Int = 1, + onDismiss: () -> Unit, + onDeleteLocal: () -> Unit, + onDeleteEverywhere: () -> Unit +) { + val title = if (noteCount == 1) { + "Notiz löschen?" + } else { + "$noteCount Notizen löschen?" + } + + val message = if (noteCount == 1) { + "Wie möchtest du diese Notiz löschen?" + } else { + "Wie möchtest du diese $noteCount Notizen löschen?" + } + + AlertDialog( + onDismissRequest = onDismiss, + title = { + Text( + text = title, + style = MaterialTheme.typography.headlineSmall + ) + }, + text = { + Text( + text = message, + style = MaterialTheme.typography.bodyMedium + ) + }, + confirmButton = { + Column( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + // Delete everywhere (server + local) - primary action + TextButton( + onClick = onDeleteEverywhere, + modifier = Modifier.fillMaxWidth(), + colors = ButtonDefaults.textButtonColors( + contentColor = MaterialTheme.colorScheme.error + ) + ) { + Text("Überall löschen (auch Server)") + } + + // Delete local only + TextButton( + onClick = onDeleteLocal, + modifier = Modifier.fillMaxWidth() + ) { + Text("Nur lokal löschen") + } + + Spacer(modifier = Modifier.height(8.dp)) + + // Cancel button + TextButton( + onClick = onDismiss, + modifier = Modifier.fillMaxWidth() + ) { + Text("Abbrechen") + } + } + }, + dismissButton = null // All buttons in confirmButton column + ) +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/EmptyState.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/EmptyState.kt new file mode 100644 index 0000000..d959c0e --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/EmptyState.kt @@ -0,0 +1,73 @@ +package dev.dettmer.simplenotes.ui.main.components + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp + +/** + * Empty state card shown when no notes exist + * v1.5.0: Jetpack Compose MainActivity Redesign + */ +@Composable +fun EmptyState( + modifier: Modifier = Modifier +) { + Column( + modifier = modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Card( + modifier = Modifier.padding(horizontal = 32.dp), + shape = RoundedCornerShape(16.dp), + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surfaceContainerHigh + ) + ) { + Column( + modifier = Modifier.padding(32.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + // Emoji + Text( + text = "📝", + fontSize = 64.sp + ) + + Spacer(modifier = Modifier.height(16.dp)) + + // Title + Text( + text = "Noch keine Notizen", + style = MaterialTheme.typography.headlineSmall, + color = MaterialTheme.colorScheme.onSurface, + textAlign = TextAlign.Center + ) + + Spacer(modifier = Modifier.height(8.dp)) + + // Message + Text( + text = "Tippe + um eine neue Notiz zu erstellen", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + textAlign = TextAlign.Center + ) + } + } + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteCard.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteCard.kt new file mode 100644 index 0000000..e48cf77 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteCard.kt @@ -0,0 +1,243 @@ +package dev.dettmer.simplenotes.ui.main.components + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.scaleIn +import androidx.compose.animation.scaleOut +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.outlined.List +import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.filled.Warning +import androidx.compose.material.icons.outlined.CloudDone +import androidx.compose.material.icons.outlined.CloudOff +import androidx.compose.material.icons.outlined.CloudSync +import androidx.compose.material.icons.outlined.Description +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.models.Note +import dev.dettmer.simplenotes.models.NoteType +import dev.dettmer.simplenotes.models.SyncStatus +import dev.dettmer.simplenotes.utils.toReadableTime + +/** + * Note card - v1.5.0 with Multi-Select Support + * + * ULTRA SIMPLE + SELECTION: + * - NO remember() anywhere + * - Direct MaterialTheme access + * - Selection indicator via border + checkbox overlay + * - Long-press starts selection mode + * - Tap in selection mode toggles selection + */ +@Composable +fun NoteCard( + note: Note, + showSyncStatus: Boolean, + isSelected: Boolean = false, + isSelectionMode: Boolean = false, + modifier: Modifier = Modifier, + onClick: () -> Unit, + onLongClick: () -> Unit +) { + val borderColor = if (isSelected) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.surfaceContainerHigh + } + + Card( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 4.dp) + .then( + if (isSelected) { + Modifier.border( + width = 2.dp, + color = MaterialTheme.colorScheme.primary, + shape = RoundedCornerShape(16.dp) + ) + } else Modifier + ) + .pointerInput(note.id, isSelectionMode) { + detectTapGestures( + onTap = { onClick() }, + onLongPress = { onLongClick() } + ) + }, + shape = RoundedCornerShape(16.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), + colors = CardDefaults.cardColors( + containerColor = if (isSelected) { + MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.3f) + } else { + MaterialTheme.colorScheme.surfaceContainerHigh + } + ) + ) { + Box { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + ) { + // Header row + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + // Type icon + Box( + modifier = Modifier + .size(32.dp) + .background( + MaterialTheme.colorScheme.primaryContainer, + CircleShape + ), + contentAlignment = Alignment.Center + ) { + Icon( + imageVector = if (note.noteType == NoteType.TEXT) + Icons.Outlined.Description + else + Icons.AutoMirrored.Outlined.List, + contentDescription = null, + tint = MaterialTheme.colorScheme.onPrimaryContainer, + modifier = Modifier.size(16.dp) + ) + } + + Spacer(modifier = Modifier.width(12.dp)) + + // Title + Text( + text = note.title.ifEmpty { "Ohne Titel" }, + style = MaterialTheme.typography.titleMedium, + color = MaterialTheme.colorScheme.onSurface, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + modifier = Modifier.weight(1f) + ) + } + + Spacer(modifier = Modifier.height(8.dp)) + + // Preview + Text( + text = when (note.noteType) { + NoteType.TEXT -> note.content.take(100) + NoteType.CHECKLIST -> { + val items = note.checklistItems ?: emptyList() + "${items.count { it.isChecked }}/${items.size} erledigt" + } + }, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurfaceVariant, + maxLines = 3, + overflow = TextOverflow.Ellipsis + ) + + Spacer(modifier = Modifier.height(8.dp)) + + // Footer + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = note.updatedAt.toReadableTime(), + style = MaterialTheme.typography.labelSmall, + color = MaterialTheme.colorScheme.outline, + modifier = Modifier.weight(1f) + ) + + if (showSyncStatus) { + Icon( + imageVector = when (note.syncStatus) { + SyncStatus.SYNCED -> Icons.Outlined.CloudDone + SyncStatus.PENDING -> Icons.Outlined.CloudSync + SyncStatus.CONFLICT -> Icons.Default.Warning + SyncStatus.LOCAL_ONLY -> Icons.Outlined.CloudOff + }, + contentDescription = null, + tint = when (note.syncStatus) { + SyncStatus.SYNCED -> MaterialTheme.colorScheme.primary + SyncStatus.CONFLICT -> MaterialTheme.colorScheme.error + else -> MaterialTheme.colorScheme.outline + }, + modifier = Modifier.size(16.dp) + ) + } + } + } + + // Selection indicator checkbox (top-right) + androidx.compose.animation.AnimatedVisibility( + visible = isSelectionMode, + enter = fadeIn() + scaleIn(), + exit = fadeOut() + scaleOut(), + modifier = Modifier + .align(Alignment.TopEnd) + .padding(8.dp) + ) { + Box( + modifier = Modifier + .size(24.dp) + .clip(CircleShape) + .background( + if (isSelected) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.surfaceContainerHighest + } + ) + .border( + width = 2.dp, + color = if (isSelected) { + MaterialTheme.colorScheme.primary + } else { + MaterialTheme.colorScheme.outline + }, + shape = CircleShape + ), + contentAlignment = Alignment.Center + ) { + if (isSelected) { + Icon( + imageVector = Icons.Default.Check, + contentDescription = "Ausgewählt", + tint = MaterialTheme.colorScheme.onPrimary, + modifier = Modifier.size(16.dp) + ) + } + } + } + } + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteTypeFAB.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteTypeFAB.kt new file mode 100644 index 0000000..23b65d4 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteTypeFAB.kt @@ -0,0 +1,83 @@ +package dev.dettmer.simplenotes.ui.main.components + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.outlined.List +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.outlined.Description +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import dev.dettmer.simplenotes.models.NoteType + +/** + * FAB with dropdown menu for note type selection + * v1.5.0: PERFORMANCE FIX - No Box wrapper for proper elevation + * + * Uses consistent icons with NoteCard: + * - TEXT: Description (document icon) + * - CHECKLIST: List (bullet list icon) + */ +@Composable +fun NoteTypeFAB( + modifier: Modifier = Modifier, + onCreateNote: (NoteType) -> Unit +) { + var expanded by remember { mutableStateOf(false) } + + // FAB directly without Box wrapper - elevation works correctly + FloatingActionButton( + onClick = { expanded = true }, + modifier = modifier, + containerColor = MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary + ) { + Icon( + imageVector = Icons.Default.Add, + contentDescription = "Neue Notiz" + ) + + // Dropdown inside FAB - renders as popup overlay + DropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false } + ) { + DropdownMenuItem( + text = { Text("Text-Notiz") }, + leadingIcon = { + Icon( + imageVector = Icons.Outlined.Description, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurface + ) + }, + onClick = { + expanded = false + onCreateNote(NoteType.TEXT) + } + ) + DropdownMenuItem( + text = { Text("Checkliste") }, + leadingIcon = { + Icon( + imageVector = Icons.AutoMirrored.Outlined.List, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSurface + ) + }, + onClick = { + expanded = false + onCreateNote(NoteType.CHECKLIST) + } + ) + } + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NotesList.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NotesList.kt new file mode 100644 index 0000000..46c4926 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NotesList.kt @@ -0,0 +1,65 @@ +package dev.dettmer.simplenotes.ui.main.components + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.models.Note + +/** + * Notes list - v1.5.0 with Multi-Select Support + * + * ULTRA SIMPLE + SELECTION: + * - NO remember() anywhere + * - NO caching tricks + * - Selection state passed through as parameters + * - Tap behavior changes based on selection mode + */ +@Composable +fun NotesList( + notes: List, + showSyncStatus: Boolean, + selectedNotes: Set = emptySet(), + isSelectionMode: Boolean = false, + modifier: Modifier = Modifier, + listState: LazyListState = rememberLazyListState(), + onNoteClick: (Note) -> Unit, + onNoteLongPress: (Note) -> Unit, + onNoteSelectionToggle: (Note) -> Unit = {} +) { + LazyColumn( + state = listState, + modifier = modifier.fillMaxSize(), + contentPadding = PaddingValues(top = 8.dp, bottom = 88.dp) + ) { + items( + items = notes, + key = { it.id }, + contentType = { "NoteCard" } + ) { note -> + val isSelected = note.id in selectedNotes + + NoteCard( + note = note, + showSyncStatus = showSyncStatus, + isSelected = isSelected, + isSelectionMode = isSelectionMode, + onClick = { + if (isSelectionMode) { + // In selection mode, tap toggles selection + onNoteSelectionToggle(note) + } else { + // Normal mode, open note + onNoteClick(note) + } + }, + onLongClick = { onNoteLongPress(note) } + ) + } + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/SyncStatusBanner.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/SyncStatusBanner.kt new file mode 100644 index 0000000..b72c768 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/SyncStatusBanner.kt @@ -0,0 +1,70 @@ +package dev.dettmer.simplenotes.ui.main.components + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.expandVertically +import androidx.compose.animation.shrinkVertically +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.sync.SyncStateManager + +/** + * Sync status banner shown below the toolbar during sync + * v1.5.0: Jetpack Compose MainActivity Redesign + */ +@Composable +fun SyncStatusBanner( + syncState: SyncStateManager.SyncState, + message: String?, + modifier: Modifier = Modifier +) { + val isVisible = syncState != SyncStateManager.SyncState.IDLE + + AnimatedVisibility( + visible = isVisible, + enter = expandVertically(), + exit = shrinkVertically(), + modifier = modifier + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .background(MaterialTheme.colorScheme.primaryContainer) + .padding(horizontal = 16.dp, vertical = 8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + if (syncState == SyncStateManager.SyncState.SYNCING) { + CircularProgressIndicator( + modifier = Modifier.size(24.dp), + strokeWidth = 3.dp, + color = MaterialTheme.colorScheme.onPrimaryContainer + ) + } + + Spacer(modifier = Modifier.width(12.dp)) + + Text( + text = when (syncState) { + SyncStateManager.SyncState.SYNCING -> "Synchronisiere..." + SyncStateManager.SyncState.COMPLETED -> message ?: "Synchronisiert" + SyncStateManager.SyncState.ERROR -> message ?: "Fehler" + SyncStateManager.SyncState.IDLE -> "" + }, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onPrimaryContainer, + modifier = Modifier.weight(1f) + ) + } + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/ComposeSettingsActivity.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/ComposeSettingsActivity.kt index 52b3b8b..1569fac 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/ComposeSettingsActivity.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/ComposeSettingsActivity.kt @@ -3,28 +3,22 @@ package dev.dettmer.simplenotes.ui.settings import android.content.Context import android.content.Intent import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.PowerManager import android.provider.Settings import android.widget.Toast import androidx.activity.ComponentActivity +import androidx.activity.OnBackPressedCallback import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.appcompat.app.AlertDialog -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.dynamicDarkColorScheme -import androidx.compose.material3.dynamicLightColorScheme -import androidx.compose.material3.lightColorScheme -import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.platform.LocalContext import androidx.navigation.compose.rememberNavController import com.google.android.material.color.DynamicColors import dev.dettmer.simplenotes.SimpleNotesApplication +import dev.dettmer.simplenotes.ui.theme.SimpleNotesTheme import dev.dettmer.simplenotes.utils.Logger import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.launch @@ -57,11 +51,24 @@ class ComposeSettingsActivity : ComponentActivity() { // Enable edge-to-edge display enableEdgeToEdge() + // Handle back button with slide animation + onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + setResult(RESULT_OK) + finish() + @Suppress("DEPRECATION") + overridePendingTransition( + dev.dettmer.simplenotes.R.anim.slide_in_left, + dev.dettmer.simplenotes.R.anim.slide_out_right + ) + } + }) + // Collect events from ViewModel (for Activity-level actions) collectViewModelEvents() setContent { - SimpleNotesSettingsTheme { + SimpleNotesTheme { val navController = rememberNavController() val context = LocalContext.current @@ -78,6 +85,11 @@ class ComposeSettingsActivity : ComponentActivity() { onFinish = { setResult(RESULT_OK) finish() + @Suppress("DEPRECATION") + overridePendingTransition( + dev.dettmer.simplenotes.R.anim.slide_in_left, + dev.dettmer.simplenotes.R.anim.slide_out_right + ) } ) } @@ -175,34 +187,3 @@ class ComposeSettingsActivity : ComponentActivity() { } } } - -/** - * Material 3 Theme with Dynamic Colors support - */ -@Composable -fun SimpleNotesSettingsTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - dynamicColor: Boolean = true, - content: @Composable () -> Unit -) { - val context = LocalContext.current - - val colorScheme = when { - // Dynamic colors are available on Android 12+ - dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - if (darkTheme) { - dynamicDarkColorScheme(context) - } else { - dynamicLightColorScheme(context) - } - } - // Fallback to static Material 3 colors - darkTheme -> darkColorScheme() - else -> lightColorScheme() - } - - MaterialTheme( - colorScheme = colorScheme, - content = content - ) -} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/theme/SimpleNotesTheme.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/theme/SimpleNotesTheme.kt new file mode 100644 index 0000000..7564a2c --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/theme/SimpleNotesTheme.kt @@ -0,0 +1,47 @@ +package dev.dettmer.simplenotes.ui.theme + +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext + +/** + * Shared Material 3 Theme with Dynamic Colors (Material You) support + * v1.5.0: Unified theme for MainActivity and Settings + * + * Used by: + * - ComposeMainActivity (Notes list) + * - ComposeSettingsActivity (Settings screens) + */ +@Composable +fun SimpleNotesTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val context = LocalContext.current + + val colorScheme = when { + // Dynamic colors are available on Android 12+ + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + if (darkTheme) { + dynamicDarkColorScheme(context) + } else { + dynamicLightColorScheme(context) + } + } + // Fallback to static Material 3 colors + darkTheme -> darkColorScheme() + else -> lightColorScheme() + } + + MaterialTheme( + colorScheme = colorScheme, + content = content + ) +} diff --git a/android/app/src/main/res/anim/slide_in_left.xml b/android/app/src/main/res/anim/slide_in_left.xml new file mode 100644 index 0000000..c9732d1 --- /dev/null +++ b/android/app/src/main/res/anim/slide_in_left.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/android/app/src/main/res/anim/slide_in_right.xml b/android/app/src/main/res/anim/slide_in_right.xml new file mode 100644 index 0000000..efbb43a --- /dev/null +++ b/android/app/src/main/res/anim/slide_in_right.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/android/app/src/main/res/anim/slide_out_left.xml b/android/app/src/main/res/anim/slide_out_left.xml new file mode 100644 index 0000000..2154df4 --- /dev/null +++ b/android/app/src/main/res/anim/slide_out_left.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/android/app/src/main/res/anim/slide_out_right.xml b/android/app/src/main/res/anim/slide_out_right.xml new file mode 100644 index 0000000..6ab5198 --- /dev/null +++ b/android/app/src/main/res/anim/slide_out_right.xml @@ -0,0 +1,9 @@ + + + + + diff --git a/android/gradle/libs.versions.toml b/android/gradle/libs.versions.toml index ea93011..255babb 100644 --- a/android/gradle/libs.versions.toml +++ b/android/gradle/libs.versions.toml @@ -11,8 +11,8 @@ activity = "1.8.0" constraintlayout = "2.1.4" ktlint = "12.1.0" detekt = "1.23.4" -# Jetpack Compose v1.5.0 -composeBom = "2024.02.00" +# Jetpack Compose v1.5.0 - Updated for 120Hz performance +composeBom = "2026.01.00" navigationCompose = "2.7.6" lifecycleRuntimeCompose = "2.7.0" activityCompose = "1.8.2" From 20ec5ba9f9f148072bc735098d61b64c7b6df3b6 Mon Sep 17 00:00:00 2001 From: inventory69 Date: Thu, 15 Jan 2026 17:19:56 +0100 Subject: [PATCH 03/12] feat(v1.5.0): Complete NoteEditor Redesign with Jetpack Compose MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Features: - Migrate NoteEditorActivity from XML to Jetpack Compose - Support both TEXT and CHECKLIST note types - FOSS native drag & drop using Compose Foundation APIs (no external dependencies) - Auto-keyboard focus with explicit keyboard controller show() calls - Consistent placeholder text for empty checklist items - Unified delete dialog with Server/Local deletion options Components: - ComposeNoteEditorActivity: Activity wrapper with ViewModelFactory for SavedStateHandle - NoteEditorScreen: Main editor screen supporting TEXT and CHECKLIST modes - NoteEditorViewModel: State management with WebDav server deletion support - ChecklistItemRow: Individual checklist item with drag handle, checkbox, text input - DragDropState: FOSS drag & drop implementation using LazyListState Improvements: - Auto-keyboard shows when creating new notes (focuses title/content) - Keyboard consistently shows when adding new checklist items - Placeholder text 'Neues Element…' for empty list items - Delete dialog unified with MainScreen (Server/Local options) - Server deletion via WebDavSyncService.deleteNoteFromServer() Debug Enhancements: - Debug builds have orange icon background (#FFB74D) with red badge - Debug builds show 'Simple Notes (Debug)' app name - Easy differentiation between debug and release APKs in launcher Build Status: - compileStandardDebug: SUCCESS - No breaking changes to existing XML-based screens - Material 3 theming with Dynamic Colors (Material You) applied Migration Notes: - Old NoteEditorActivity (XML-based) remains for reference/backwards compatibility - All editor UI is now Compose-based - ComposeMainActivity updated to use new ComposeNoteEditorActivity - Plan document (v1.5.0_EXTENDED_FEATURES_PLAN.md) updated with implementation details --- .../drawable/ic_launcher_foreground_debug.xml | 25 ++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 8 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 8 + .../app/src/debug/res/values/colors_debug.xml | 5 + android/app/src/main/AndroidManifest.xml | 9 +- .../ui/editor/ComposeNoteEditorActivity.kt | 84 ++++ .../simplenotes/ui/editor/DragDropState.kt | 154 +++++++ .../simplenotes/ui/editor/NoteEditorScreen.kt | 350 ++++++++++++++++ .../ui/editor/NoteEditorViewModel.kt | 383 ++++++++++++++++++ .../ui/editor/components/ChecklistItemRow.kt | 177 ++++++++ .../ui/main/ComposeMainActivity.kt | 10 +- android/app/src/main/res/values/strings.xml | 2 + 12 files changed, 1209 insertions(+), 6 deletions(-) create mode 100644 android/app/src/debug/res/drawable/ic_launcher_foreground_debug.xml create mode 100644 android/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 android/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 android/app/src/debug/res/values/colors_debug.xml create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/ComposeNoteEditorActivity.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/DragDropState.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorScreen.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorViewModel.kt create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/components/ChecklistItemRow.kt diff --git a/android/app/src/debug/res/drawable/ic_launcher_foreground_debug.xml b/android/app/src/debug/res/drawable/ic_launcher_foreground_debug.xml new file mode 100644 index 0000000..50f6b6d --- /dev/null +++ b/android/app/src/debug/res/drawable/ic_launcher_foreground_debug.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..1cdebeb --- /dev/null +++ b/android/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/android/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..10807ae --- /dev/null +++ b/android/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/android/app/src/debug/res/values/colors_debug.xml b/android/app/src/debug/res/values/colors_debug.xml new file mode 100644 index 0000000..e52d644 --- /dev/null +++ b/android/app/src/debug/res/values/colors_debug.xml @@ -0,0 +1,5 @@ + + + + #FFB74D + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 7c8e354..ea90fd7 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -44,12 +44,19 @@ android:exported="false" android:theme="@style/Theme.SimpleNotes" /> - + + + + create( + key: String, + modelClass: Class, + handle: SavedStateHandle + ): T { + // Populate SavedStateHandle with intent extras + handle[NoteEditorViewModel.ARG_NOTE_ID] = noteId + handle[NoteEditorViewModel.ARG_NOTE_TYPE] = noteType + + return NoteEditorViewModel(application, handle) as T + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/DragDropState.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/DragDropState.kt new file mode 100644 index 0000000..0889ac0 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/DragDropState.kt @@ -0,0 +1,154 @@ +package dev.dettmer.simplenotes.ui.editor + +import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress +import androidx.compose.foundation.gestures.scrollBy +import androidx.compose.foundation.lazy.LazyListItemInfo +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.input.pointer.pointerInput +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch + +/** + * FOSS Drag & Drop State für LazyList + * + * Native Compose-Implementierung ohne externe Dependencies + * v1.5.0: NoteEditor Redesign + */ +class DragDropListState( + private val state: LazyListState, + private val scope: CoroutineScope, + private val onMove: (Int, Int) -> Unit +) { + var draggingItemIndex by mutableStateOf(null) + private set + + private var draggingItemDraggedDelta by mutableFloatStateOf(0f) + private var draggingItemInitialOffset by mutableFloatStateOf(0f) + private var overscrollJob by mutableStateOf(null) + + val draggingItemOffset: Float + get() = draggingItemLayoutInfo?.let { item -> + draggingItemInitialOffset + draggingItemDraggedDelta - item.offset + } ?: 0f + + private val draggingItemLayoutInfo: LazyListItemInfo? + get() = state.layoutInfo.visibleItemsInfo + .firstOrNull { it.index == draggingItemIndex } + + fun onDragStart(offset: Offset, itemIndex: Int) { + draggingItemIndex = itemIndex + draggingItemInitialOffset = draggingItemLayoutInfo?.offset?.toFloat() ?: 0f + draggingItemDraggedDelta = 0f + } + + fun onDragInterrupted() { + draggingItemDraggedDelta = 0f + draggingItemIndex = null + draggingItemInitialOffset = 0f + overscrollJob?.cancel() + } + + fun onDrag(offset: Offset) { + draggingItemDraggedDelta += offset.y + + val draggingItem = draggingItemLayoutInfo ?: return + val startOffset = draggingItem.offset + draggingItemOffset + val endOffset = startOffset + draggingItem.size + + val middleOffset = startOffset + (endOffset - startOffset) / 2f + + val targetItem = state.layoutInfo.visibleItemsInfo.find { item -> + middleOffset.toInt() in item.offset..item.offsetEnd && + draggingItem.index != item.index + } + + if (targetItem != null) { + val scrollToIndex = if (targetItem.index == state.firstVisibleItemIndex) { + draggingItem.index + } else if (draggingItem.index == state.firstVisibleItemIndex) { + targetItem.index + } else { + null + } + + if (scrollToIndex != null) { + scope.launch { + state.scrollToItem(scrollToIndex, state.firstVisibleItemScrollOffset) + onMove(draggingItem.index, targetItem.index) + } + } else { + onMove(draggingItem.index, targetItem.index) + } + + draggingItemIndex = targetItem.index + } else { + val overscroll = when { + draggingItemDraggedDelta > 0 -> + (endOffset - state.layoutInfo.viewportEndOffset).coerceAtLeast(0f) + draggingItemDraggedDelta < 0 -> + (startOffset - state.layoutInfo.viewportStartOffset).coerceAtMost(0f) + else -> 0f + } + + if (overscroll != 0f) { + if (overscrollJob?.isActive != true) { + overscrollJob = scope.launch { + state.scrollBy(overscroll) + } + } + } else { + overscrollJob?.cancel() + } + } + } + + private val LazyListItemInfo.offsetEnd: Int + get() = this.offset + this.size +} + +@Composable +fun rememberDragDropListState( + lazyListState: LazyListState, + scope: CoroutineScope, + onMove: (Int, Int) -> Unit +): DragDropListState { + return remember(lazyListState, scope) { + DragDropListState( + state = lazyListState, + scope = scope, + onMove = onMove + ) + } +} + +fun Modifier.dragContainer( + dragDropState: DragDropListState, + itemIndex: Int +): Modifier { + return this.pointerInput(dragDropState) { + detectDragGesturesAfterLongPress( + onDragStart = { offset -> + dragDropState.onDragStart(offset, itemIndex) + }, + onDragEnd = { + dragDropState.onDragInterrupted() + }, + onDragCancel = { + dragDropState.onDragInterrupted() + }, + onDrag = { change, offset -> + change.consume() + dragDropState.onDrag(offset) + } + ) + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorScreen.kt new file mode 100644 index 0000000..58f207d --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorScreen.kt @@ -0,0 +1,350 @@ +package dev.dettmer.simplenotes.ui.editor + +import androidx.compose.animation.core.animateDpAsState +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.Delete +import androidx.compose.material.icons.filled.Save +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.R +import dev.dettmer.simplenotes.models.NoteType +import dev.dettmer.simplenotes.ui.editor.components.ChecklistItemRow +import dev.dettmer.simplenotes.ui.main.components.DeleteConfirmationDialog +import kotlinx.coroutines.delay +import dev.dettmer.simplenotes.utils.showToast +import kotlin.math.roundToInt + +/** + * Main Composable for the Note Editor screen. + * + * v1.5.0: Jetpack Compose NoteEditor Redesign + * - Supports both TEXT and CHECKLIST notes + * - Drag & Drop reordering for checklist items + * - Auto-keyboard focus for new items + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun NoteEditorScreen( + viewModel: NoteEditorViewModel, + onNavigateBack: () -> Unit +) { + val context = LocalContext.current + val uiState by viewModel.uiState.collectAsState() + val checklistItems by viewModel.checklistItems.collectAsState() + + var showDeleteDialog by remember { mutableStateOf(false) } + var focusNewItemId by remember { mutableStateOf(null) } + val scope = rememberCoroutineScope() + + // v1.5.0: Auto-keyboard support + val keyboardController = LocalSoftwareKeyboardController.current + val titleFocusRequester = remember { FocusRequester() } + val contentFocusRequester = remember { FocusRequester() } + + // v1.5.0: Auto-focus and show keyboard + LaunchedEffect(uiState.isNewNote, uiState.noteType) { + delay(100) // Wait for layout + when { + uiState.isNewNote -> { + // New note: focus title + titleFocusRequester.requestFocus() + keyboardController?.show() + } + !uiState.isNewNote && uiState.noteType == NoteType.TEXT -> { + // Editing text note: focus content + contentFocusRequester.requestFocus() + keyboardController?.show() + } + } + } + + // Handle events + LaunchedEffect(Unit) { + viewModel.events.collect { event -> + when (event) { + is NoteEditorEvent.ShowToast -> { + val message = when (event.message) { + ToastMessage.NOTE_IS_EMPTY -> context.getString(R.string.note_is_empty) + ToastMessage.NOTE_SAVED -> context.getString(R.string.note_saved) + ToastMessage.NOTE_DELETED -> context.getString(R.string.note_deleted) + } + context.showToast(message) + } + is NoteEditorEvent.NavigateBack -> onNavigateBack() + is NoteEditorEvent.ShowDeleteConfirmation -> showDeleteDialog = true + } + } + } + + Scaffold( + topBar = { + TopAppBar( + title = { + Text( + text = when (uiState.toolbarTitle) { + ToolbarTitle.NEW_NOTE -> stringResource(R.string.new_note) + ToolbarTitle.EDIT_NOTE -> stringResource(R.string.edit_note) + ToolbarTitle.NEW_CHECKLIST -> stringResource(R.string.new_checklist) + ToolbarTitle.EDIT_CHECKLIST -> stringResource(R.string.edit_checklist) + } + ) + }, + navigationIcon = { + IconButton(onClick = onNavigateBack) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = stringResource(R.string.back) + ) + } + }, + actions = { + // Delete button (only for existing notes) + if (viewModel.canDelete()) { + IconButton(onClick = { showDeleteDialog = true }) { + Icon( + imageVector = Icons.Default.Delete, + contentDescription = stringResource(R.string.delete) + ) + } + } + + // Save button + IconButton(onClick = { viewModel.saveNote() }) { + Icon( + imageVector = Icons.Default.Save, + contentDescription = stringResource(R.string.save) + ) + } + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = MaterialTheme.colorScheme.surface + ) + ) + }, + modifier = Modifier.imePadding() + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .padding(16.dp) + ) { + // Title Input (for both types) + OutlinedTextField( + value = uiState.title, + onValueChange = { viewModel.updateTitle(it) }, + modifier = Modifier + .fillMaxWidth() + .focusRequester(titleFocusRequester), + label = { Text(stringResource(R.string.title)) }, + singleLine = false, + maxLines = 2, + shape = RoundedCornerShape(16.dp) + ) + + Spacer(modifier = Modifier.height(16.dp)) + + when (uiState.noteType) { + NoteType.TEXT -> { + // Content Input for TEXT notes + TextNoteContent( + content = uiState.content, + onContentChange = { viewModel.updateContent(it) }, + focusRequester = contentFocusRequester, + modifier = Modifier + .fillMaxWidth() + .weight(1f) + ) + } + + NoteType.CHECKLIST -> { + // Checklist Editor + ChecklistEditor( + items = checklistItems, + scope = scope, + focusNewItemId = focusNewItemId, + onTextChange = { id, text -> viewModel.updateChecklistItemText(id, text) }, + onCheckedChange = { id, checked -> viewModel.updateChecklistItemChecked(id, checked) }, + onDelete = { id -> viewModel.deleteChecklistItem(id) }, + onAddNewItemAfter = { id -> + val newId = viewModel.addChecklistItemAfter(id) + focusNewItemId = newId + }, + onAddItemAtEnd = { + val newId = viewModel.addChecklistItemAtEnd() + focusNewItemId = newId + }, + onMove = { from, to -> viewModel.moveChecklistItem(from, to) }, + onFocusHandled = { focusNewItemId = null }, + modifier = Modifier + .fillMaxWidth() + .weight(1f) + ) + } + } + } + } + + // Delete Confirmation Dialog - v1.5.0: Use shared component with server/local options + if (showDeleteDialog) { + DeleteConfirmationDialog( + noteCount = 1, + onDismiss = { showDeleteDialog = false }, + onDeleteLocal = { + showDeleteDialog = false + viewModel.deleteNote(deleteOnServer = false) + }, + onDeleteEverywhere = { + showDeleteDialog = false + viewModel.deleteNote(deleteOnServer = true) + } + ) + } +} + +@Composable +private fun TextNoteContent( + content: String, + onContentChange: (String) -> Unit, + focusRequester: FocusRequester, + modifier: Modifier = Modifier +) { + OutlinedTextField( + value = content, + onValueChange = onContentChange, + modifier = modifier.focusRequester(focusRequester), + label = { Text(stringResource(R.string.content)) }, + shape = RoundedCornerShape(16.dp) + ) +} + +@Composable +private fun ChecklistEditor( + items: List, + scope: kotlinx.coroutines.CoroutineScope, + focusNewItemId: String?, + onTextChange: (String, String) -> Unit, + onCheckedChange: (String, Boolean) -> Unit, + onDelete: (String) -> Unit, + onAddNewItemAfter: (String) -> Unit, + onAddItemAtEnd: () -> Unit, + onMove: (Int, Int) -> Unit, + onFocusHandled: () -> Unit, + modifier: Modifier = Modifier +) { + val listState = rememberLazyListState() + val dragDropState = rememberDragDropListState( + lazyListState = listState, + scope = scope, + onMove = onMove + ) + + Column(modifier = modifier) { + LazyColumn( + state = listState, + modifier = Modifier.weight(1f), + contentPadding = PaddingValues(vertical = 8.dp), + verticalArrangement = Arrangement.spacedBy(2.dp) + ) { + itemsIndexed( + items = items, + key = { _, item -> item.id } + ) { index, item -> + val isDragging = dragDropState.draggingItemIndex == index + val elevation by animateDpAsState( + targetValue = if (isDragging) 8.dp else 0.dp, + label = "elevation" + ) + + val shouldFocus = item.id == focusNewItemId + + // v1.5.0: Clear focus request after handling + LaunchedEffect(shouldFocus) { + if (shouldFocus) { + onFocusHandled() + } + } + + ChecklistItemRow( + item = item, + onTextChange = { onTextChange(item.id, it) }, + onCheckedChange = { onCheckedChange(item.id, it) }, + onDelete = { onDelete(item.id) }, + onAddNewItem = { onAddNewItemAfter(item.id) }, + requestFocus = shouldFocus, + modifier = Modifier + .dragContainer(dragDropState, index) + .offset { + IntOffset( + 0, + if (isDragging) dragDropState.draggingItemOffset.roundToInt() else 0 + ) + } + .shadow(elevation, shape = RoundedCornerShape(8.dp)) + .background( + color = MaterialTheme.colorScheme.surface, + shape = RoundedCornerShape(8.dp) + ) + ) + } + } + + // Add Item Button + TextButton( + onClick = onAddItemAtEnd, + modifier = Modifier.padding(start = 8.dp) + ) { + Icon( + imageVector = Icons.Default.Add, + contentDescription = null, + modifier = Modifier.padding(end = 8.dp) + ) + Text(stringResource(R.string.add_item)) + } + } +} + +// v1.5.0: Local DeleteConfirmationDialog removed - now using shared component from ui/main/components/ diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorViewModel.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorViewModel.kt new file mode 100644 index 0000000..489a068 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorViewModel.kt @@ -0,0 +1,383 @@ +package dev.dettmer.simplenotes.ui.editor + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.viewModelScope +import dev.dettmer.simplenotes.models.ChecklistItem +import dev.dettmer.simplenotes.models.Note +import dev.dettmer.simplenotes.models.NoteType +import dev.dettmer.simplenotes.models.SyncStatus +import dev.dettmer.simplenotes.storage.NotesStorage +import dev.dettmer.simplenotes.sync.WebDavSyncService +import dev.dettmer.simplenotes.utils.DeviceIdGenerator +import dev.dettmer.simplenotes.utils.Logger +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.util.UUID + +/** + * ViewModel for NoteEditor Compose Screen + * v1.5.0: Jetpack Compose NoteEditor Redesign + * + * Manages note editing state including title, content, and checklist items. + */ +class NoteEditorViewModel( + application: Application, + private val savedStateHandle: SavedStateHandle +) : AndroidViewModel(application) { + + companion object { + private const val TAG = "NoteEditorViewModel" + const val ARG_NOTE_ID = "noteId" + const val ARG_NOTE_TYPE = "noteType" + } + + private val storage = NotesStorage(application) + + // ═══════════════════════════════════════════════════════════════════════ + // State + // ═══════════════════════════════════════════════════════════════════════ + + private val _uiState = MutableStateFlow(NoteEditorUiState()) + val uiState: StateFlow = _uiState.asStateFlow() + + private val _checklistItems = MutableStateFlow>(emptyList()) + val checklistItems: StateFlow> = _checklistItems.asStateFlow() + + // ═══════════════════════════════════════════════════════════════════════ + // Events + // ═══════════════════════════════════════════════════════════════════════ + + private val _events = MutableSharedFlow() + val events: SharedFlow = _events.asSharedFlow() + + // Internal state + private var existingNote: Note? = null + private var currentNoteType: NoteType = NoteType.TEXT + + init { + loadNote() + } + + private fun loadNote() { + val noteId = savedStateHandle.get(ARG_NOTE_ID) + val noteTypeString = savedStateHandle.get(ARG_NOTE_TYPE) ?: NoteType.TEXT.name + + if (noteId != null) { + // Load existing note + existingNote = storage.loadNote(noteId) + existingNote?.let { note -> + currentNoteType = note.noteType + _uiState.update { state -> + state.copy( + title = note.title, + content = note.content, + noteType = note.noteType, + isNewNote = false, + toolbarTitle = if (note.noteType == NoteType.CHECKLIST) { + ToolbarTitle.EDIT_CHECKLIST + } else { + ToolbarTitle.EDIT_NOTE + } + ) + } + + if (note.noteType == NoteType.CHECKLIST) { + val items = note.checklistItems?.sortedBy { it.order }?.map { + ChecklistItemState( + id = it.id, + text = it.text, + isChecked = it.isChecked, + order = it.order + ) + } ?: emptyList() + _checklistItems.value = items + } + } + } else { + // New note + currentNoteType = try { + NoteType.valueOf(noteTypeString) + } catch (e: IllegalArgumentException) { + Logger.w(TAG, "Invalid note type '$noteTypeString', defaulting to TEXT") + NoteType.TEXT + } + + _uiState.update { state -> + state.copy( + noteType = currentNoteType, + isNewNote = true, + toolbarTitle = if (currentNoteType == NoteType.CHECKLIST) { + ToolbarTitle.NEW_CHECKLIST + } else { + ToolbarTitle.NEW_NOTE + } + ) + } + + // Add first empty item for new checklists + if (currentNoteType == NoteType.CHECKLIST) { + _checklistItems.value = listOf(ChecklistItemState.createEmpty(0)) + } + } + } + + // ═══════════════════════════════════════════════════════════════════════ + // Actions + // ═══════════════════════════════════════════════════════════════════════ + + fun updateTitle(title: String) { + _uiState.update { it.copy(title = title) } + } + + fun updateContent(content: String) { + _uiState.update { it.copy(content = content) } + } + + fun updateChecklistItemText(itemId: String, newText: String) { + _checklistItems.update { items -> + items.map { item -> + if (item.id == itemId) item.copy(text = newText) else item + } + } + } + + fun updateChecklistItemChecked(itemId: String, isChecked: Boolean) { + _checklistItems.update { items -> + items.map { item -> + if (item.id == itemId) item.copy(isChecked = isChecked) else item + } + } + } + + fun addChecklistItemAfter(afterItemId: String): String { + val newItem = ChecklistItemState.createEmpty(0) + _checklistItems.update { items -> + val index = items.indexOfFirst { it.id == afterItemId } + if (index >= 0) { + val newList = items.toMutableList() + newList.add(index + 1, newItem) + // Update order values + newList.mapIndexed { i, item -> item.copy(order = i) } + } else { + items + newItem.copy(order = items.size) + } + } + return newItem.id + } + + fun addChecklistItemAtEnd(): String { + val newItem = ChecklistItemState.createEmpty(_checklistItems.value.size) + _checklistItems.update { items -> items + newItem } + return newItem.id + } + + fun deleteChecklistItem(itemId: String) { + _checklistItems.update { items -> + val filtered = items.filter { it.id != itemId } + // Ensure at least one item exists + if (filtered.isEmpty()) { + listOf(ChecklistItemState.createEmpty(0)) + } else { + // Update order values + filtered.mapIndexed { index, item -> item.copy(order = index) } + } + } + } + + fun moveChecklistItem(fromIndex: Int, toIndex: Int) { + _checklistItems.update { items -> + val mutableList = items.toMutableList() + val item = mutableList.removeAt(fromIndex) + mutableList.add(toIndex, item) + // Update order values + mutableList.mapIndexed { index, i -> i.copy(order = index) } + } + } + + fun saveNote() { + viewModelScope.launch { + val state = _uiState.value + val title = state.title.trim() + + when (currentNoteType) { + NoteType.TEXT -> { + val content = state.content.trim() + + if (title.isEmpty() && content.isEmpty()) { + _events.emit(NoteEditorEvent.ShowToast(ToastMessage.NOTE_IS_EMPTY)) + return@launch + } + + val note = if (existingNote != null) { + existingNote!!.copy( + title = title, + content = content, + noteType = NoteType.TEXT, + checklistItems = null, + updatedAt = System.currentTimeMillis(), + syncStatus = SyncStatus.PENDING + ) + } else { + Note( + title = title, + content = content, + noteType = NoteType.TEXT, + checklistItems = null, + deviceId = DeviceIdGenerator.getDeviceId(getApplication()), + syncStatus = SyncStatus.LOCAL_ONLY + ) + } + + storage.saveNote(note) + } + + NoteType.CHECKLIST -> { + // Filter empty items + val validItems = _checklistItems.value + .filter { it.text.isNotBlank() } + .mapIndexed { index, item -> + ChecklistItem( + id = item.id, + text = item.text, + isChecked = item.isChecked, + order = index + ) + } + + if (title.isEmpty() && validItems.isEmpty()) { + _events.emit(NoteEditorEvent.ShowToast(ToastMessage.NOTE_IS_EMPTY)) + return@launch + } + + val note = if (existingNote != null) { + existingNote!!.copy( + title = title, + content = "", // Empty for checklists + noteType = NoteType.CHECKLIST, + checklistItems = validItems, + updatedAt = System.currentTimeMillis(), + syncStatus = SyncStatus.PENDING + ) + } else { + Note( + title = title, + content = "", + noteType = NoteType.CHECKLIST, + checklistItems = validItems, + deviceId = DeviceIdGenerator.getDeviceId(getApplication()), + syncStatus = SyncStatus.LOCAL_ONLY + ) + } + + storage.saveNote(note) + } + } + + _events.emit(NoteEditorEvent.ShowToast(ToastMessage.NOTE_SAVED)) + _events.emit(NoteEditorEvent.NavigateBack) + } + } + + /** + * Delete the current note + * @param deleteOnServer if true, also triggers server deletion; if false, only deletes locally + * v1.5.0: Added deleteOnServer parameter for unified delete dialog + */ + fun deleteNote(deleteOnServer: Boolean = true) { + viewModelScope.launch { + existingNote?.let { note -> + val noteId = note.id + + // Delete locally first + storage.deleteNote(noteId) + + // Delete from server if requested + if (deleteOnServer) { + try { + val webdavService = WebDavSyncService(getApplication()) + val success = withContext(Dispatchers.IO) { + webdavService.deleteNoteFromServer(noteId) + } + if (success) { + Logger.d(TAG, "Note $noteId deleted from server") + } else { + Logger.w(TAG, "Failed to delete note $noteId from server") + } + } catch (e: Exception) { + Logger.e(TAG, "Error deleting note from server: ${e.message}") + } + } + + _events.emit(NoteEditorEvent.ShowToast(ToastMessage.NOTE_DELETED)) + _events.emit(NoteEditorEvent.NavigateBack) + } + } + } + + fun showDeleteConfirmation() { + viewModelScope.launch { + _events.emit(NoteEditorEvent.ShowDeleteConfirmation) + } + } + + fun canDelete(): Boolean = existingNote != null +} + +// ═══════════════════════════════════════════════════════════════════════════ +// State Classes +// ═══════════════════════════════════════════════════════════════════════════ + +data class NoteEditorUiState( + val title: String = "", + val content: String = "", + val noteType: NoteType = NoteType.TEXT, + val isNewNote: Boolean = true, + val toolbarTitle: ToolbarTitle = ToolbarTitle.NEW_NOTE +) + +data class ChecklistItemState( + val id: String = UUID.randomUUID().toString(), + val text: String = "", + val isChecked: Boolean = false, + val order: Int = 0 +) { + companion object { + fun createEmpty(order: Int): ChecklistItemState { + return ChecklistItemState( + id = UUID.randomUUID().toString(), + text = "", + isChecked = false, + order = order + ) + } + } +} + +enum class ToolbarTitle { + NEW_NOTE, + EDIT_NOTE, + NEW_CHECKLIST, + EDIT_CHECKLIST +} + +enum class ToastMessage { + NOTE_IS_EMPTY, + NOTE_SAVED, + NOTE_DELETED +} + +sealed interface NoteEditorEvent { + data class ShowToast(val message: ToastMessage) : NoteEditorEvent + data object NavigateBack : NoteEditorEvent + data object ShowDeleteConfirmation : NoteEditorEvent +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/components/ChecklistItemRow.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/components/ChecklistItemRow.kt new file mode 100644 index 0000000..f645c9e --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/components/ChecklistItemRow.kt @@ -0,0 +1,177 @@ +package dev.dettmer.simplenotes.ui.editor.components + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.filled.DragHandle +import androidx.compose.material3.Checkbox +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextRange +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.style.TextDecoration +import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.R +import dev.dettmer.simplenotes.ui.editor.ChecklistItemState + +/** + * A single row in the checklist editor with drag handle, checkbox, text input, and delete button. + * + * v1.5.0: Jetpack Compose NoteEditor Redesign + */ +@Composable +fun ChecklistItemRow( + item: ChecklistItemState, + onTextChange: (String) -> Unit, + onCheckedChange: (Boolean) -> Unit, + onDelete: () -> Unit, + onAddNewItem: () -> Unit, + requestFocus: Boolean = false, + modifier: Modifier = Modifier +) { + val focusRequester = remember { FocusRequester() } + val keyboardController = LocalSoftwareKeyboardController.current + var textFieldValue by remember(item.id) { + mutableStateOf(TextFieldValue(text = item.text, selection = TextRange(item.text.length))) + } + + // v1.5.0: Auto-focus AND show keyboard when requestFocus is true (new items) + LaunchedEffect(requestFocus) { + if (requestFocus) { + focusRequester.requestFocus() + keyboardController?.show() + } + } + + // Update text field when external state changes + LaunchedEffect(item.text) { + if (textFieldValue.text != item.text) { + textFieldValue = TextFieldValue( + text = item.text, + selection = TextRange(item.text.length) + ) + } + } + + val alpha = if (item.isChecked) 0.6f else 1.0f + val textDecoration = if (item.isChecked) TextDecoration.LineThrough else TextDecoration.None + + Row( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 8.dp, vertical = 4.dp), + verticalAlignment = Alignment.CenterVertically + ) { + // Drag Handle + Icon( + imageVector = Icons.Default.DragHandle, + contentDescription = stringResource(R.string.drag_to_reorder), + modifier = Modifier + .size(24.dp) + .alpha(0.5f), + tint = MaterialTheme.colorScheme.onSurfaceVariant + ) + + Spacer(modifier = Modifier.width(4.dp)) + + // Checkbox + Checkbox( + checked = item.isChecked, + onCheckedChange = onCheckedChange, + modifier = Modifier.alpha(alpha) + ) + + Spacer(modifier = Modifier.width(4.dp)) + + // Text Input with placeholder + BasicTextField( + value = textFieldValue, + onValueChange = { newValue -> + // Check for newline (Enter key) + if (newValue.text.contains("\n")) { + val cleanText = newValue.text.replace("\n", "") + textFieldValue = TextFieldValue( + text = cleanText, + selection = TextRange(cleanText.length) + ) + onTextChange(cleanText) + onAddNewItem() + } else { + textFieldValue = newValue + onTextChange(newValue.text) + } + }, + modifier = Modifier + .weight(1f) + .focusRequester(focusRequester) + .alpha(alpha), + textStyle = LocalTextStyle.current.copy( + color = MaterialTheme.colorScheme.onSurface, + textDecoration = textDecoration + ), + keyboardOptions = KeyboardOptions( + imeAction = ImeAction.Next + ), + keyboardActions = KeyboardActions( + onNext = { onAddNewItem() } + ), + singleLine = true, + cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), + decorationBox = { innerTextField -> + Box { + if (textFieldValue.text.isEmpty()) { + Text( + text = stringResource(R.string.item_placeholder), + style = LocalTextStyle.current.copy( + color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f) + ) + ) + } + innerTextField() + } + } + ) + + Spacer(modifier = Modifier.width(4.dp)) + + // Delete Button + IconButton( + onClick = onDelete, + modifier = Modifier.size(36.dp) + ) { + Icon( + imageVector = Icons.Default.Close, + contentDescription = stringResource(R.string.delete_item), + tint = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.size(20.dp) + ) + } + } +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt index 975369e..bc57b73 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt @@ -28,7 +28,7 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.lifecycle.lifecycleScope import androidx.localbroadcastmanager.content.LocalBroadcastManager import com.google.android.material.color.DynamicColors -import dev.dettmer.simplenotes.NoteEditorActivity +import dev.dettmer.simplenotes.ui.editor.ComposeNoteEditorActivity import dev.dettmer.simplenotes.models.NoteType import dev.dettmer.simplenotes.models.SyncStatus import dev.dettmer.simplenotes.storage.NotesStorage @@ -230,17 +230,17 @@ class ComposeMainActivity : ComponentActivity() { private fun openNoteEditor(noteId: String?) { cameFromEditor = true - val intent = Intent(this, NoteEditorActivity::class.java) + val intent = Intent(this, ComposeNoteEditorActivity::class.java) noteId?.let { - intent.putExtra(NoteEditorActivity.EXTRA_NOTE_ID, it) + intent.putExtra(ComposeNoteEditorActivity.EXTRA_NOTE_ID, it) } startActivity(intent) } private fun createNote(noteType: NoteType) { cameFromEditor = true - val intent = Intent(this, NoteEditorActivity::class.java) - intent.putExtra(NoteEditorActivity.EXTRA_NOTE_TYPE, noteType.name) + val intent = Intent(this, ComposeNoteEditorActivity::class.java) + intent.putExtra(ComposeNoteEditorActivity.EXTRA_NOTE_TYPE, noteType.name) startActivity(intent) } diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index b390b2e..aaebe35 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -19,6 +19,7 @@ Inhalt Speichern Löschen + Zurück Note Title @@ -81,6 +82,7 @@ Element hinzufügen Neues Element… Element verschieben + Ziehen zum Sortieren Element löschen Notiz ist leer Notiz gespeichert From 3ada6c966d9ef6766fbd8ab25ea115ba5b5d9d11 Mon Sep 17 00:00:00 2001 From: inventory69 Date: Thu, 15 Jan 2026 22:08:00 +0100 Subject: [PATCH 04/12] fix(v1.5.0): Silent-Sync Mode + UI Improvements Silent-Sync Implementation (Auto-Sync Banner Fix): - Add SYNCING_SILENT state to SyncStateManager for background syncs - Auto-sync (onResume) now triggers silently without banner interruption - Silent-sync state blocks additional manual syncs (mutual exclusion) - Error banners still display even after silent-sync failures - SyncStatus tracks 'silent' flag to hide COMPLETED banners after silent-sync UI/UX Improvements (from v1.5.0 post-migration fixes): - Fix text wrapping in checklist items (singleLine=false, maxLines=5) - Fix cursor position in text notes (use TextFieldValue with TextRange) - Display app icon instead of emoji in AboutScreen - Add smooth slide animations for NoteEditor transitions - Remove visual noise from AboutScreen icon Technical Changes: - ComposeNoteEditorActivity: Add back animation with OnBackPressedCallback - ComposeMainActivity: Add entry/exit slide animations for note editing - NoteEditorScreen: Use TextFieldValue for proper cursor positioning - ChecklistItemRow: Enable text wrapping for long checklist items - AboutScreen: Convert Drawable to Bitmap via Canvas (supports AdaptiveIcon) - SyncStatusBanner: Exclude SYNCING_SILENT from visibility checks - MainActivity: Update legacy auto-sync to use silent mode Fixes #[auto-sync-banner], improves #[user-experience] Branch: feature/v1.5.0 --- .../dev/dettmer/simplenotes/MainActivity.kt | 9 +++- .../simplenotes/sync/SyncStateManager.kt | 50 +++++++++++++------ .../ui/editor/ComposeNoteEditorActivity.kt | 22 +++++++- .../simplenotes/ui/editor/NoteEditorScreen.kt | 28 ++++++++++- .../ui/editor/components/ChecklistItemRow.kt | 3 +- .../ui/main/ComposeMainActivity.kt | 18 ++++++- .../simplenotes/ui/main/MainViewModel.kt | 4 +- .../ui/main/components/SyncStatusBanner.kt | 7 ++- .../ui/settings/screens/AboutScreen.kt | 32 ++++++++++-- 9 files changed, 146 insertions(+), 27 deletions(-) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt b/android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt index 71534af..928f39a 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt @@ -182,6 +182,11 @@ class MainActivity : AppCompatActivity() { swipeRefreshLayout.isRefreshing = false syncStatusBanner.visibility = View.GONE } + // v1.5.0: Silent-Sync - Banner nicht anzeigen, aber Sync-Controls deaktivieren + SyncStateManager.SyncState.SYNCING_SILENT -> { + setSyncControlsEnabled(false) + // Kein Banner anzeigen bei Silent-Sync (z.B. onResume Auto-Sync) + } } } } @@ -222,6 +227,7 @@ class MainActivity : AppCompatActivity() { * - Nur Success-Toast (kein "Auto-Sync..." Toast) * * NOTE: WiFi-Connect Sync nutzt WorkManager (auch wenn App geschlossen!) + * v1.5.0: Silent-Sync - kein Banner während des Syncs, Fehler werden trotzdem angezeigt */ private fun triggerAutoSync(source: String = "unknown") { // Throttling: Max 1 Sync pro Minute @@ -230,7 +236,8 @@ class MainActivity : AppCompatActivity() { } // 🔄 v1.3.1: Check if sync already running - if (!SyncStateManager.tryStartSync("auto-$source")) { + // v1.5.0: silent=true - kein Banner bei Auto-Sync + if (!SyncStateManager.tryStartSync("auto-$source", silent = true)) { Logger.d(TAG, "⏭️ Auto-sync ($source): Another sync already in progress") return } diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/sync/SyncStateManager.kt b/android/app/src/main/java/dev/dettmer/simplenotes/sync/SyncStateManager.kt index edc0d1d..e43f513 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/sync/SyncStateManager.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/sync/SyncStateManager.kt @@ -19,7 +19,8 @@ object SyncStateManager { */ enum class SyncState { IDLE, // Kein Sync aktiv - SYNCING, // Sync läuft gerade + SYNCING, // Sync läuft gerade (Banner sichtbar) + SYNCING_SILENT, // v1.5.0: Sync läuft im Hintergrund (kein Banner, z.B. onResume) COMPLETED, // Sync erfolgreich abgeschlossen (kurz anzeigen) ERROR // Sync fehlgeschlagen (kurz anzeigen) } @@ -31,6 +32,7 @@ object SyncStateManager { val state: SyncState = SyncState.IDLE, val message: String? = null, val source: String? = null, // "manual", "auto", "pullToRefresh", "background" + val silent: Boolean = false, // v1.5.0: Wenn true, wird nach Completion kein Banner angezeigt val timestamp: Long = System.currentTimeMillis() ) @@ -44,28 +46,35 @@ object SyncStateManager { private val lock = Any() /** - * Prüft ob gerade ein Sync läuft + * Prüft ob gerade ein Sync läuft (inkl. Silent-Sync) */ val isSyncing: Boolean - get() = _syncStatus.value?.state == SyncState.SYNCING + get() { + val state = _syncStatus.value?.state + return state == SyncState.SYNCING || state == SyncState.SYNCING_SILENT + } /** * Versucht einen Sync zu starten. + * @param source Quelle des Syncs (für Logging) + * @param silent v1.5.0: Wenn true, wird kein Banner angezeigt (z.B. bei onResume Auto-Sync) * @return true wenn Sync gestartet werden kann, false wenn bereits einer läuft */ - fun tryStartSync(source: String): Boolean { + fun tryStartSync(source: String, silent: Boolean = false): Boolean { synchronized(lock) { if (isSyncing) { Logger.d(TAG, "⚠️ Sync already in progress, rejecting new sync from: $source") return false } - Logger.d(TAG, "🔄 Starting sync from: $source") + val syncState = if (silent) SyncState.SYNCING_SILENT else SyncState.SYNCING + Logger.d(TAG, "🔄 Starting sync from: $source (silent=$silent)") _syncStatus.postValue( SyncStatus( - state = SyncState.SYNCING, + state = syncState, message = "Synchronisiere...", - source = source + source = source, + silent = silent // v1.5.0: Merkt sich ob silent für markCompleted() ) ) return true @@ -74,18 +83,29 @@ object SyncStateManager { /** * Markiert Sync als erfolgreich abgeschlossen + * v1.5.0: Bei Silent-Sync direkt auf IDLE wechseln (kein Banner) */ fun markCompleted(message: String? = null) { synchronized(lock) { - val currentSource = _syncStatus.value?.source - Logger.d(TAG, "✅ Sync completed from: $currentSource") - _syncStatus.postValue( - SyncStatus( - state = SyncState.COMPLETED, - message = message, - source = currentSource + val current = _syncStatus.value + val currentSource = current?.source + val wasSilent = current?.silent == true + + Logger.d(TAG, "✅ Sync completed from: $currentSource (silent=$wasSilent)") + + if (wasSilent) { + // v1.5.0: Silent-Sync - direkt auf IDLE, kein Banner anzeigen + _syncStatus.postValue(SyncStatus()) + } else { + // Normaler Sync - COMPLETED State anzeigen + _syncStatus.postValue( + SyncStatus( + state = SyncState.COMPLETED, + message = message, + source = currentSource + ) ) - ) + } } } diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/ComposeNoteEditorActivity.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/ComposeNoteEditorActivity.kt index 98d7ec2..b3f4435 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/ComposeNoteEditorActivity.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/ComposeNoteEditorActivity.kt @@ -2,6 +2,7 @@ package dev.dettmer.simplenotes.ui.editor import android.os.Bundle import androidx.activity.ComponentActivity +import androidx.activity.OnBackPressedCallback import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels @@ -48,11 +49,30 @@ class ComposeNoteEditorActivity : ComponentActivity() { enableEdgeToEdge() + // v1.5.0: Handle back button with slide animation + onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + finish() + @Suppress("DEPRECATION") + overridePendingTransition( + dev.dettmer.simplenotes.R.anim.slide_in_left, + dev.dettmer.simplenotes.R.anim.slide_out_right + ) + } + }) + setContent { SimpleNotesTheme { NoteEditorScreen( viewModel = viewModel, - onNavigateBack = { finish() } + onNavigateBack = { + finish() + @Suppress("DEPRECATION") + overridePendingTransition( + dev.dettmer.simplenotes.R.anim.slide_in_left, + dev.dettmer.simplenotes.R.anim.slide_out_right + ) + } ) } } diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorScreen.kt index 58f207d..d951026 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorScreen.kt @@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.RoundedCornerShape @@ -43,6 +44,8 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.text.TextRange +import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalSoftwareKeyboardController @@ -252,9 +255,30 @@ private fun TextNoteContent( focusRequester: FocusRequester, modifier: Modifier = Modifier ) { + // v1.5.0: Use TextFieldValue to control cursor position + var textFieldValue by remember(content) { + mutableStateOf(TextFieldValue( + text = content, + selection = TextRange(content.length) + )) + } + + // Sync external changes + LaunchedEffect(content) { + if (textFieldValue.text != content) { + textFieldValue = TextFieldValue( + text = content, + selection = TextRange(content.length) + ) + } + } + OutlinedTextField( - value = content, - onValueChange = onContentChange, + value = textFieldValue, + onValueChange = { newValue -> + textFieldValue = newValue + onContentChange(newValue.text) + }, modifier = modifier.focusRequester(focusRequester), label = { Text(stringResource(R.string.content)) }, shape = RoundedCornerShape(16.dp) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/components/ChecklistItemRow.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/components/ChecklistItemRow.kt index f645c9e..3af1b2b 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/components/ChecklistItemRow.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/components/ChecklistItemRow.kt @@ -142,7 +142,8 @@ fun ChecklistItemRow( keyboardActions = KeyboardActions( onNext = { onAddNewItem() } ), - singleLine = true, + singleLine = false, + maxLines = 5, cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), decorationBox = { innerTextField -> Box { diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt index bc57b73..21dcb2c 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt @@ -234,14 +234,28 @@ class ComposeMainActivity : ComponentActivity() { noteId?.let { intent.putExtra(ComposeNoteEditorActivity.EXTRA_NOTE_ID, it) } - startActivity(intent) + + // v1.5.0: Add slide animation + val options = ActivityOptions.makeCustomAnimation( + this, + dev.dettmer.simplenotes.R.anim.slide_in_right, + dev.dettmer.simplenotes.R.anim.slide_out_left + ) + startActivity(intent, options.toBundle()) } private fun createNote(noteType: NoteType) { cameFromEditor = true val intent = Intent(this, ComposeNoteEditorActivity::class.java) intent.putExtra(ComposeNoteEditorActivity.EXTRA_NOTE_TYPE, noteType.name) - startActivity(intent) + + // v1.5.0: Add slide animation + val options = ActivityOptions.makeCustomAnimation( + this, + dev.dettmer.simplenotes.R.anim.slide_in_right, + dev.dettmer.simplenotes.R.anim.slide_out_left + ) + startActivity(intent, options.toBundle()) } private fun openSettings() { diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt index 0ef1b88..0921d92 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt @@ -470,6 +470,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { /** * Trigger auto-sync (onResume) * Only runs if server is configured and interval has passed + * v1.5.0: Silent-Sync - kein Banner während des Syncs, Fehler werden trotzdem angezeigt */ fun triggerAutoSync(source: String = "auto") { // Throttling check @@ -483,7 +484,8 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { return } - if (!SyncStateManager.tryStartSync("auto-$source")) { + // v1.5.0: silent=true - kein Banner bei Auto-Sync, aber Fehler werden trotzdem angezeigt + if (!SyncStateManager.tryStartSync("auto-$source", silent = true)) { Logger.d(TAG, "⏭️ Auto-sync ($source): Another sync already in progress") return } diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/SyncStatusBanner.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/SyncStatusBanner.kt index b72c768..2436b27 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/SyncStatusBanner.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/SyncStatusBanner.kt @@ -22,6 +22,7 @@ import dev.dettmer.simplenotes.sync.SyncStateManager /** * Sync status banner shown below the toolbar during sync * v1.5.0: Jetpack Compose MainActivity Redesign + * v1.5.0: SYNCING_SILENT ignorieren - Banner nur bei manuellen Syncs oder Fehlern anzeigen */ @Composable fun SyncStatusBanner( @@ -29,7 +30,10 @@ fun SyncStatusBanner( message: String?, modifier: Modifier = Modifier ) { - val isVisible = syncState != SyncStateManager.SyncState.IDLE + // v1.5.0: Banner nicht anzeigen bei IDLE oder SYNCING_SILENT (Auto-Sync im Hintergrund) + // Fehler werden trotzdem angezeigt (ERROR state nach Silent-Sync wechselt zu ERROR, nicht SYNCING_SILENT) + val isVisible = syncState != SyncStateManager.SyncState.IDLE + && syncState != SyncStateManager.SyncState.SYNCING_SILENT AnimatedVisibility( visible = isVisible, @@ -57,6 +61,7 @@ fun SyncStatusBanner( Text( text = when (syncState) { SyncStateManager.SyncState.SYNCING -> "Synchronisiere..." + SyncStateManager.SyncState.SYNCING_SILENT -> "" // v1.5.0: Wird nicht angezeigt (isVisible = false) SyncStateManager.SyncState.COMPLETED -> message ?: "Synchronisiert" SyncStateManager.SyncState.ERROR -> message ?: "Fehler" SyncStateManager.SyncState.IDLE -> "" diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt index c506c72..ad742a2 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt @@ -1,8 +1,13 @@ package dev.dettmer.simplenotes.ui.settings.screens import android.content.Intent +import android.graphics.Bitmap +import android.graphics.Canvas import android.net.Uri +import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -13,6 +18,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight @@ -25,11 +31,14 @@ import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import dev.dettmer.simplenotes.BuildConfig import dev.dettmer.simplenotes.ui.settings.components.SettingsDivider import dev.dettmer.simplenotes.ui.settings.components.SettingsScaffold @@ -76,9 +85,26 @@ fun AboutScreen( .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - Text( - text = "📝", - style = MaterialTheme.typography.displayMedium + // v1.5.0: App icon loaded from PackageManager and converted to Bitmap + val context = LocalContext.current + val appIcon = remember { + val drawable = context.packageManager.getApplicationIcon(context.packageName) + // Convert any Drawable (including AdaptiveIconDrawable) to Bitmap + val bitmap = Bitmap.createBitmap( + drawable.intrinsicWidth.coerceAtLeast(1), + drawable.intrinsicHeight.coerceAtLeast(1), + Bitmap.Config.ARGB_8888 + ) + val canvas = Canvas(bitmap) + drawable.setBounds(0, 0, canvas.width, canvas.height) + drawable.draw(canvas) + bitmap.asImageBitmap() + } + + Image( + bitmap = appIcon, + contentDescription = "App Icon", + modifier = Modifier.size(96.dp) ) Spacer(modifier = Modifier.height(8.dp)) From 3af99f31b8ac8fbc8fd367a1931780fc41e9f9ae Mon Sep 17 00:00:00 2001 From: inventory69 Date: Fri, 16 Jan 2026 10:33:38 +0100 Subject: [PATCH 05/12] feat(v1.5.0): Complete i18n implementation + Language Selector feature - Added comprehensive English (strings.xml) and German (strings-de.xml) localization with 400+ strings - Created new LanguageSettingsScreen with System Default, English, and German options - Fixed hardcoded German notification toasts in MainActivity and ComposeMainActivity - Integrated Language selector in Settings as top-level menu item - Changed ComposeSettingsActivity from ComponentActivity to AppCompatActivity for AppCompatDelegate compatibility - Added locales_config.xml for Android 13+ Per-App Language support - Updated Extensions.kt with i18n-aware timestamp formatting (toReadableTime with context) - Translated all UI strings including settings, toasts, notifications, and error messages - Added dynamic language display in SettingsMainScreen showing current language Fixes: - Notification permission toast now respects system language setting - Activity correctly restarts when language is changed - All string formatting with parameters properly localized Migration: - MainViewModel: All toast messages now use getString() - SettingsViewModel: All toast and dialog messages localized - NotificationHelper: Notification titles and messages translated - UrlValidator: Error messages now accept Context parameter for translation - NoteCard, DeleteConfirmationDialog, SyncStatusBanner: All strings externalized Testing completed on device with both EN and DE locale switching. Closes #5 --- android/app/src/main/AndroidManifest.xml | 1 + .../dev/dettmer/simplenotes/MainActivity.kt | 23 +- .../dettmer/simplenotes/SettingsActivity.kt | 44 +- .../simplenotes/backup/BackupManager.kt | 22 +- .../simplenotes/sync/WebDavSyncService.kt | 7 +- .../ui/main/ComposeMainActivity.kt | 16 +- .../dettmer/simplenotes/ui/main/MainScreen.kt | 16 +- .../simplenotes/ui/main/MainViewModel.kt | 32 +- .../components/DeleteConfirmationDialog.kt | 16 +- .../ui/main/components/EmptyState.kt | 6 +- .../ui/main/components/NoteCard.kt | 13 +- .../ui/main/components/NoteTypeFAB.kt | 8 +- .../ui/main/components/SyncStatusBanner.kt | 8 +- .../ui/settings/ComposeSettingsActivity.kt | 17 +- .../ui/settings/SettingsNavigation.kt | 8 + .../simplenotes/ui/settings/SettingsRoute.kt | 1 + .../ui/settings/SettingsViewModel.kt | 68 +-- .../settings/components/SettingsScaffold.kt | 4 +- .../ui/settings/screens/AboutScreen.kt | 28 +- .../settings/screens/BackupSettingsScreen.kt | 45 +- .../settings/screens/DebugSettingsScreen.kt | 31 +- .../screens/LanguageSettingsScreen.kt | 120 +++++ .../screens/MarkdownSettingsScreen.kt | 23 +- .../settings/screens/ServerSettingsScreen.kt | 40 +- .../ui/settings/screens/SettingsMainScreen.kt | 62 ++- .../ui/settings/screens/SyncSettingsScreen.kt | 32 +- .../dettmer/simplenotes/utils/Extensions.kt | 29 +- .../simplenotes/utils/NotificationHelper.kt | 40 +- .../dettmer/simplenotes/utils/UrlValidator.kt | 11 +- .../app/src/main/res/values-de/strings.xml | 393 +++++++++++++++ android/app/src/main/res/values/strings.xml | 446 +++++++++++++++--- .../app/src/main/res/xml/locales_config.xml | 7 + 32 files changed, 1261 insertions(+), 356 deletions(-) create mode 100644 android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/LanguageSettingsScreen.kt create mode 100644 android/app/src/main/res/values-de/strings.xml create mode 100644 android/app/src/main/res/xml/locales_config.xml diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index ea90fd7..bc7094a 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -22,6 +22,7 @@ android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" + android:localeConfig="@xml/locales_config" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.SimpleNotes" diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt b/android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt index 928f39a..46139a0 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt @@ -467,10 +467,10 @@ class MainActivity : AppCompatActivity() { val checkboxAlways = dialogView.findViewById(R.id.checkboxAlwaysDeleteFromServer) MaterialAlertDialogBuilder(this) - .setTitle("Notiz löschen") - .setMessage("\"${note.title}\" wird lokal gelöscht.\n\nAuch vom Server löschen?") + .setTitle(getString(R.string.legacy_delete_dialog_title)) + .setMessage(getString(R.string.legacy_delete_dialog_message, note.title)) .setView(dialogView) - .setNeutralButton("Abbrechen") { _, _ -> + .setNeutralButton(getString(R.string.cancel)) { _, _ -> // RESTORE: Re-submit original list (note is NOT deleted from storage) adapter.submitList(originalList) } @@ -485,7 +485,7 @@ class MainActivity : AppCompatActivity() { // NOW actually delete from storage deleteNoteLocally(note, deleteFromServer = false) } - .setNegativeButton("Vom Server löschen") { _, _ -> + .setNegativeButton(getString(R.string.legacy_delete_from_server)) { _, _ -> if (checkboxAlways.isChecked) { prefs.edit().putBoolean(Constants.KEY_ALWAYS_DELETE_FROM_SERVER, true).apply() } @@ -507,13 +507,13 @@ class MainActivity : AppCompatActivity() { // Show Snackbar with UNDO option val message = if (deleteFromServer) { - "\"${note.title}\" wird lokal und vom Server gelöscht" + getString(R.string.legacy_delete_with_server, note.title) } else { - "\"${note.title}\" lokal gelöscht (Server bleibt)" + getString(R.string.legacy_delete_local_only, note.title) } Snackbar.make(recyclerViewNotes, message, Snackbar.LENGTH_LONG) - .setAction("RÜCKGÄNGIG") { + .setAction(getString(R.string.snackbar_undo)) { // UNDO: Restore note storage.saveNote(note) pendingDeletions.remove(note.id) @@ -535,7 +535,7 @@ class MainActivity : AppCompatActivity() { runOnUiThread { Toast.makeText( this@MainActivity, - "Vom Server gelöscht", + getString(R.string.snackbar_deleted_from_server), Toast.LENGTH_SHORT ).show() } @@ -543,7 +543,7 @@ class MainActivity : AppCompatActivity() { runOnUiThread { Toast.makeText( this@MainActivity, - "Server-Löschung fehlgeschlagen", + getString(R.string.snackbar_server_delete_failed), Toast.LENGTH_LONG ).show() } @@ -800,10 +800,9 @@ class MainActivity : AppCompatActivity() { REQUEST_NOTIFICATION_PERMISSION -> { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - showToast("Benachrichtigungen aktiviert") + showToast(getString(R.string.toast_notifications_enabled)) } else { - showToast("Benachrichtigungen deaktiviert. " + - "Du kannst sie in den Einstellungen aktivieren.") + showToast(getString(R.string.toast_notifications_disabled)) } } } diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/SettingsActivity.kt b/android/app/src/main/java/dev/dettmer/simplenotes/SettingsActivity.kt index a4c926f..8306374 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/SettingsActivity.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/SettingsActivity.kt @@ -227,9 +227,9 @@ class SettingsActivity : AppCompatActivity() { */ private fun updateProtocolHint() { protocolHintText.text = if (radioHttp.isChecked) { - "HTTP nur für lokale Netzwerke (z.B. 192.168.x.x, 10.x.x.x)" + getString(R.string.server_connection_http_hint) } else { - "HTTPS für sichere Verbindungen über das Internet" + getString(R.string.server_connection_https_hint) } } @@ -359,7 +359,7 @@ class SettingsActivity : AppCompatActivity() { 60L -> "60 Minuten" else -> "$newInterval Minuten" } - showToast("⏱️ Sync-Intervall auf $intervalText geändert") + showToast(getString(R.string.toast_sync_interval_changed, intervalText)) Logger.i(TAG, "Sync interval changed to $newInterval minutes, restarted periodic sync") } else { showToast("⏱️ Sync-Intervall gespeichert (Auto-Sync ist deaktiviert)") @@ -379,7 +379,7 @@ class SettingsActivity : AppCompatActivity() { textViewAppVersion.text = "Version $versionName ($versionCode)" } catch (e: Exception) { Logger.e(TAG, "Failed to load version info", e) - textViewAppVersion.text = "Version nicht verfügbar" + textViewAppVersion.text = getString(R.string.version_not_available) } // GitHub Repository Card @@ -475,12 +475,12 @@ class SettingsActivity : AppCompatActivity() { */ private fun showClearLogsConfirmation() { AlertDialog.Builder(this) - .setTitle("Logs löschen?") - .setMessage("Alle gespeicherten Sync-Logs werden unwiderruflich gelöscht.") - .setPositiveButton("Löschen") { _, _ -> + .setTitle(getString(R.string.debug_delete_logs_title)) + .setMessage(getString(R.string.debug_delete_logs_message)) + .setPositiveButton(getString(R.string.delete)) { _, _ -> clearLogs() } - .setNegativeButton("Abbrechen", null) + .setNegativeButton(getString(R.string.cancel), null) .show() } @@ -491,13 +491,13 @@ class SettingsActivity : AppCompatActivity() { try { val cleared = Logger.clearLogFile(this) if (cleared) { - showToast("🗑️ Logs gelöscht") + showToast(getString(R.string.toast_logs_deleted)) } else { - showToast("📭 Keine Logs zum Löschen") + showToast(getString(R.string.toast_no_logs_to_delete)) } } catch (e: Exception) { Logger.e(TAG, "Failed to clear logs", e) - showToast("❌ Fehler beim Löschen: ${e.message}") + showToast(getString(R.string.toast_logs_delete_error, e.message ?: "")) } } @@ -510,7 +510,7 @@ class SettingsActivity : AppCompatActivity() { startActivity(intent) } catch (e: Exception) { Logger.e(TAG, "Failed to open URL: $url", e) - showToast("❌ Fehler beim Öffnen des Links") + showToast(getString(R.string.toast_link_error)) } } @@ -524,7 +524,7 @@ class SettingsActivity : AppCompatActivity() { // 🔥 v1.1.2: Validate HTTP URL (only allow for local networks) if (fullUrl.isNotEmpty()) { - val (isValid, errorMessage) = UrlValidator.validateHttpUrl(fullUrl) + val (isValid, errorMessage) = UrlValidator.validateHttpUrl(this, fullUrl) if (!isValid) { // Only show error in TextField (no Toast) textInputLayoutServerUrl.isErrorEnabled = true @@ -552,7 +552,7 @@ class SettingsActivity : AppCompatActivity() { // 🔥 v1.1.2: Validate before testing if (fullUrl.isNotEmpty()) { - val (isValid, errorMessage) = UrlValidator.validateHttpUrl(fullUrl) + val (isValid, errorMessage) = UrlValidator.validateHttpUrl(this, fullUrl) if (!isValid) { // Only show error in TextField (no Toast) textInputLayoutServerUrl.isErrorEnabled = true @@ -646,7 +646,7 @@ class SettingsActivity : AppCompatActivity() { return } - textViewServerStatus.text = "🔍 Prüfe..." + textViewServerStatus.text = getString(R.string.status_checking) textViewServerStatus.setTextColor(getColor(android.R.color.darker_gray)) lifecycleScope.launch { @@ -803,12 +803,12 @@ class SettingsActivity : AppCompatActivity() { .setMessage( "Damit die App im Hintergrund synchronisieren kann, " + "muss die Akku-Optimierung deaktiviert werden.\n\n" + - "Bitte wähle 'Nicht optimieren' für Simple Notes." + getString(R.string.battery_optimization_dialog_message) ) - .setPositiveButton("Einstellungen öffnen") { _, _ -> + .setPositiveButton(getString(R.string.battery_optimization_open_settings)) { _, _ -> openBatteryOptimizationSettings() } - .setNegativeButton("Später") { dialog, _ -> + .setNegativeButton(getString(R.string.battery_optimization_later)) { dialog, _ -> dialog.dismiss() } .setCancelable(false) @@ -915,20 +915,20 @@ class SettingsActivity : AppCompatActivity() { // Radio Buttons erstellen val radioMerge = android.widget.RadioButton(this).apply { - text = "⚪ Zusammenführen (Standard)\n → Neue hinzufügen, Bestehende behalten" + text = getString(R.string.backup_mode_merge_full) id = android.view.View.generateViewId() isChecked = true setPadding(10, 10, 10, 10) } val radioReplace = android.widget.RadioButton(this).apply { - text = "⚪ Ersetzen\n → Alle löschen & Backup importieren" + text = getString(R.string.backup_mode_replace_full) id = android.view.View.generateViewId() setPadding(10, 10, 10, 10) } val radioOverwrite = android.widget.RadioButton(this).apply { - text = "⚪ Duplikate überschreiben\n → Backup gewinnt bei Konflikten" + text = getString(R.string.backup_mode_overwrite_full) id = android.view.View.generateViewId() setPadding(10, 10, 10, 10) } @@ -978,7 +978,7 @@ class SettingsActivity : AppCompatActivity() { RestoreSource.WEBDAV_SERVER -> performRestoreFromServer(selectedMode) } } - .setNegativeButton("Abbrechen", null) + .setNegativeButton(getString(R.string.cancel), null) .show() } diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/backup/BackupManager.kt b/android/app/src/main/java/dev/dettmer/simplenotes/backup/BackupManager.kt index e741261..e6db9d5 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/backup/BackupManager.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/backup/BackupManager.kt @@ -5,6 +5,7 @@ import android.net.Uri import com.google.gson.Gson import com.google.gson.GsonBuilder import dev.dettmer.simplenotes.BuildConfig +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.models.Note import dev.dettmer.simplenotes.storage.NotesStorage import dev.dettmer.simplenotes.utils.Logger @@ -144,7 +145,7 @@ class BackupManager(private val context: Context) { if (!validationResult.isValid) { return@withContext RestoreResult( success = false, - error = validationResult.errorMessage ?: "Ungültige Backup-Datei" + error = validationResult.errorMessage ?: context.getString(R.string.error_invalid_backup_file) ) } @@ -171,7 +172,7 @@ class BackupManager(private val context: Context) { Logger.e(TAG, "Failed to restore backup", e) RestoreResult( success = false, - error = "Wiederherstellung fehlgeschlagen: ${e.message}" + error = context.getString(R.string.error_restore_failed, e.message ?: "") ) } } @@ -187,8 +188,7 @@ class BackupManager(private val context: Context) { if (backupData.backupVersion > BACKUP_VERSION) { return ValidationResult( isValid = false, - errorMessage = "Backup-Version nicht unterstützt " + - "(v${backupData.backupVersion} benötigt v${BACKUP_VERSION}+)" + errorMessage = context.getString(R.string.error_backup_version_unsupported, backupData.backupVersion, BACKUP_VERSION) ) } @@ -196,7 +196,7 @@ class BackupManager(private val context: Context) { if (backupData.notes.isEmpty()) { return ValidationResult( isValid = false, - errorMessage = "Backup enthält keine Notizen" + errorMessage = context.getString(R.string.error_backup_empty) ) } @@ -208,7 +208,7 @@ class BackupManager(private val context: Context) { if (invalidNotes.isNotEmpty()) { return ValidationResult( isValid = false, - errorMessage = "Backup enthält ${invalidNotes.size} ungültige Notizen" + errorMessage = context.getString(R.string.error_backup_invalid_notes, invalidNotes.size) ) } @@ -217,7 +217,7 @@ class BackupManager(private val context: Context) { } catch (e: Exception) { ValidationResult( isValid = false, - errorMessage = "Backup-Datei beschädigt oder ungültig: ${e.message}" + errorMessage = context.getString(R.string.error_backup_corrupt, e.message ?: "") ) } } @@ -241,7 +241,7 @@ class BackupManager(private val context: Context) { success = true, importedNotes = newNotes.size, skippedNotes = skippedNotes, - message = "${newNotes.size} neue Notizen importiert, $skippedNotes übersprungen" + message = context.getString(R.string.restore_merge_result, newNotes.size, skippedNotes) ) } @@ -262,10 +262,10 @@ class BackupManager(private val context: Context) { success = true, importedNotes = backupNotes.size, skippedNotes = 0, - message = "Alle Notizen ersetzt: ${backupNotes.size} importiert" + message = context.getString(R.string.restore_replace_result, backupNotes.size) ) } - + /** * Restore-Modus: OVERWRITE_DUPLICATES * Backup überschreibt bei ID-Konflikten @@ -287,7 +287,7 @@ class BackupManager(private val context: Context) { importedNotes = newNotes.size, skippedNotes = 0, overwrittenNotes = overwrittenNotes.size, - message = "${newNotes.size} neu, ${overwrittenNotes.size} überschrieben" + message = context.getString(R.string.restore_overwrite_result, newNotes.size, overwrittenNotes.size) ) } diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/sync/WebDavSyncService.kt b/android/app/src/main/java/dev/dettmer/simplenotes/sync/WebDavSyncService.kt index 0c3caa7..580a573 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/sync/WebDavSyncService.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/sync/WebDavSyncService.kt @@ -6,6 +6,7 @@ import android.net.NetworkCapabilities import com.thegrizzlylabs.sardineandroid.Sardine import com.thegrizzlylabs.sardineandroid.impl.OkHttpSardine import dev.dettmer.simplenotes.BuildConfig +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.models.DeletionTracker import dev.dettmer.simplenotes.models.Note import dev.dettmer.simplenotes.models.SyncStatus @@ -1852,15 +1853,15 @@ class WebDavSyncService(private val context: Context) { suspend fun manualMarkdownSync(): ManualMarkdownSyncResult = withContext(Dispatchers.IO) { return@withContext try { val sardine = getOrCreateSardine() - ?: throw SyncException("Sardine client konnte nicht erstellt werden") + ?: throw SyncException(context.getString(R.string.error_sardine_client_failed)) val serverUrl = getServerUrl() - ?: throw SyncException("Server-URL nicht konfiguriert") + ?: throw SyncException(context.getString(R.string.error_server_url_not_configured)) val username = prefs.getString(Constants.KEY_USERNAME, "") ?: "" val password = prefs.getString(Constants.KEY_PASSWORD, "") ?: "" if (serverUrl.isBlank() || username.isBlank() || password.isBlank()) { - throw SyncException("WebDAV-Server nicht vollständig konfiguriert") + throw SyncException(context.getString(R.string.error_server_not_configured)) } Logger.d(TAG, "🔄 Manual Markdown Sync START") diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt index 21dcb2c..5af51b1 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/ComposeMainActivity.kt @@ -24,10 +24,12 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.lifecycle.lifecycleScope import androidx.localbroadcastmanager.content.LocalBroadcastManager import com.google.android.material.color.DynamicColors +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.ui.editor.ComposeNoteEditorActivity import dev.dettmer.simplenotes.models.NoteType import dev.dettmer.simplenotes.models.SyncStatus @@ -339,10 +341,10 @@ class ComposeMainActivity : ComponentActivity() { REQUEST_NOTIFICATION_PERMISSION -> { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - Toast.makeText(this, "Benachrichtigungen aktiviert", Toast.LENGTH_SHORT).show() + Toast.makeText(this, getString(R.string.toast_notifications_enabled), Toast.LENGTH_SHORT).show() } else { Toast.makeText(this, - "Benachrichtigungen deaktiviert. Du kannst sie in den Einstellungen aktivieren.", + getString(R.string.toast_notifications_disabled), Toast.LENGTH_SHORT ).show() } @@ -363,21 +365,21 @@ private fun DeleteConfirmationDialog( ) { AlertDialog( onDismissRequest = onDismiss, - title = { Text("Notiz löschen") }, + title = { Text(stringResource(R.string.legacy_delete_dialog_title)) }, text = { - Text("\"$noteTitle\" wird lokal gelöscht.\n\nAuch vom Server löschen?") + Text(stringResource(R.string.legacy_delete_dialog_message, noteTitle)) }, dismissButton = { TextButton(onClick = onDismiss) { - Text("Abbrechen") + Text(stringResource(R.string.cancel)) } }, confirmButton = { TextButton(onClick = onDeleteLocal) { - Text("Nur lokal") + Text(stringResource(R.string.delete_local_only)) } TextButton(onClick = onDeleteFromServer) { - Text("Vom Server löschen") + Text(stringResource(R.string.legacy_delete_from_server)) } } ) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainScreen.kt index ed35821..44fc3da 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainScreen.kt @@ -42,8 +42,10 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.zIndex +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.models.NoteType import dev.dettmer.simplenotes.sync.SyncStateManager import dev.dettmer.simplenotes.ui.main.components.DeleteConfirmationDialog @@ -231,7 +233,7 @@ private fun MainTopBar( TopAppBar( title = { Text( - text = "Simple Notes", + text = stringResource(R.string.main_title), style = MaterialTheme.typography.titleLarge ) }, @@ -242,13 +244,13 @@ private fun MainTopBar( ) { Icon( imageVector = Icons.Default.Refresh, - contentDescription = "Synchronisieren" + contentDescription = stringResource(R.string.action_sync) ) } IconButton(onClick = onSettingsClick) { Icon( imageVector = Icons.Default.Settings, - contentDescription = "Einstellungen" + contentDescription = stringResource(R.string.action_settings) ) } }, @@ -276,13 +278,13 @@ private fun SelectionTopBar( IconButton(onClick = onCloseSelection) { Icon( imageVector = Icons.Default.Close, - contentDescription = "Auswahl beenden" + contentDescription = stringResource(R.string.action_close_selection) ) } }, title = { Text( - text = "$selectedCount ausgewählt", + text = stringResource(R.string.selection_count, selectedCount), style = MaterialTheme.typography.titleLarge ) }, @@ -292,7 +294,7 @@ private fun SelectionTopBar( IconButton(onClick = onSelectAll) { Icon( imageVector = Icons.Default.SelectAll, - contentDescription = "Alle auswählen" + contentDescription = stringResource(R.string.action_select_all) ) } } @@ -303,7 +305,7 @@ private fun SelectionTopBar( ) { Icon( imageVector = Icons.Default.Delete, - contentDescription = "Ausgewählte löschen", + contentDescription = stringResource(R.string.action_delete_selected), tint = if (selectedCount > 0) { MaterialTheme.colorScheme.error } else { diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt index 0921d92..4b47c66 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt @@ -5,6 +5,7 @@ import android.content.Context import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope import dev.dettmer.simplenotes.models.Note +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.storage.NotesStorage import dev.dettmer.simplenotes.sync.SyncStateManager import dev.dettmer.simplenotes.sync.WebDavSyncService @@ -236,15 +237,15 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { // Show snackbar with undo val count = selectedNotes.size val message = if (deleteFromServer) { - "$count Notiz${if (count > 1) "en" else ""} werden vom Server gelöscht" + getString(R.string.snackbar_notes_deleted_server, count) } else { - "$count Notiz${if (count > 1) "en" else ""} lokal gelöscht" + getString(R.string.snackbar_notes_deleted_local, count) } viewModelScope.launch { _showSnackbar.emit(SnackbarData( message = message, - actionLabel = "RÜCKGÄNGIG", + actionLabel = getString(R.string.snackbar_undo), onAction = { undoDeleteMultiple(selectedNotes) } @@ -336,15 +337,15 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { // Show snackbar with undo val message = if (deleteFromServer) { - "\"${note.title}\" wird vom Server gelöscht" + getString(R.string.snackbar_note_deleted_server, note.title) } else { - "\"${note.title}\" lokal gelöscht" + getString(R.string.snackbar_note_deleted_local, note.title) } viewModelScope.launch { _showSnackbar.emit(SnackbarData( message = message, - actionLabel = "RÜCKGÄNGIG", + actionLabel = getString(R.string.snackbar_undo), onAction = { undoDelete(note) } @@ -390,12 +391,12 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { } if (success) { - _showToast.emit("Vom Server gelöscht") + _showToast.emit(getString(R.string.snackbar_deleted_from_server)) } else { - _showToast.emit("Server-Löschung fehlgeschlagen") + _showToast.emit(getString(R.string.snackbar_server_delete_failed)) } } catch (e: Exception) { - _showToast.emit("Server-Fehler: ${e.message}") + _showToast.emit(getString(R.string.snackbar_server_error, e.message ?: "")) } finally { // Remove from pending deletions _pendingDeletions.value = _pendingDeletions.value - noteId @@ -446,7 +447,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { if (!isReachable) { Logger.d(TAG, "⏭️ $source Sync: Server not reachable") - SyncStateManager.markError("Server nicht erreichbar") + SyncStateManager.markError(getString(R.string.snackbar_server_unreachable)) return@launch } @@ -456,7 +457,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { } if (result.isSuccess) { - SyncStateManager.markCompleted("${result.syncedCount} Notizen") + SyncStateManager.markCompleted(getString(R.string.toast_sync_success, result.syncedCount)) loadNotes() } else { SyncStateManager.markError(result.errorMessage) @@ -524,8 +525,8 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { if (result.isSuccess && result.syncedCount > 0) { Logger.d(TAG, "✅ Auto-sync successful ($source): ${result.syncedCount} notes") - SyncStateManager.markCompleted("${result.syncedCount} Notizen") - _showToast.emit("✅ Gesynct: ${result.syncedCount} Notizen") + SyncStateManager.markCompleted(getString(R.string.toast_sync_success, result.syncedCount)) + _showToast.emit(getString(R.string.snackbar_synced_count, result.syncedCount)) loadNotes() } else if (result.isSuccess) { Logger.d(TAG, "ℹ️ Auto-sync ($source): No changes") @@ -559,6 +560,11 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { // Helpers // ═══════════════════════════════════════════════════════════════════════ + private fun getString(resId: Int): String = getApplication().getString(resId) + + private fun getString(resId: Int, vararg formatArgs: Any): String = + getApplication().getString(resId, *formatArgs) + fun isServerConfigured(): Boolean { val serverUrl = prefs.getString(Constants.KEY_SERVER_URL, null) return !serverUrl.isNullOrEmpty() && serverUrl != "http://" && serverUrl != "https://" diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt index 5ea14dc..443f037 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt @@ -14,7 +14,9 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.R /** * Delete confirmation dialog with server/local options @@ -28,15 +30,15 @@ fun DeleteConfirmationDialog( onDeleteEverywhere: () -> Unit ) { val title = if (noteCount == 1) { - "Notiz löschen?" + stringResource(R.string.delete_note_title) } else { - "$noteCount Notizen löschen?" + stringResource(R.string.delete_notes_title, noteCount) } val message = if (noteCount == 1) { - "Wie möchtest du diese Notiz löschen?" + stringResource(R.string.delete_note_message) } else { - "Wie möchtest du diese $noteCount Notizen löschen?" + stringResource(R.string.delete_notes_message, noteCount) } AlertDialog( @@ -66,7 +68,7 @@ fun DeleteConfirmationDialog( contentColor = MaterialTheme.colorScheme.error ) ) { - Text("Überall löschen (auch Server)") + Text(stringResource(R.string.delete_everywhere)) } // Delete local only @@ -74,7 +76,7 @@ fun DeleteConfirmationDialog( onClick = onDeleteLocal, modifier = Modifier.fillMaxWidth() ) { - Text("Nur lokal löschen") + Text(stringResource(R.string.delete_local_only)) } Spacer(modifier = Modifier.height(8.dp)) @@ -84,7 +86,7 @@ fun DeleteConfirmationDialog( onClick = onDismiss, modifier = Modifier.fillMaxWidth() ) { - Text("Abbrechen") + Text(stringResource(R.string.cancel)) } } }, diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/EmptyState.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/EmptyState.kt index d959c0e..929d412 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/EmptyState.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/EmptyState.kt @@ -14,9 +14,11 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import dev.dettmer.simplenotes.R /** * Empty state card shown when no notes exist @@ -52,7 +54,7 @@ fun EmptyState( // Title Text( - text = "Noch keine Notizen", + text = stringResource(R.string.empty_state_title), style = MaterialTheme.typography.headlineSmall, color = MaterialTheme.colorScheme.onSurface, textAlign = TextAlign.Center @@ -62,7 +64,7 @@ fun EmptyState( // Message Text( - text = "Tippe + um eine neue Notiz zu erstellen", + text = stringResource(R.string.empty_state_message), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, textAlign = TextAlign.Center diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteCard.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteCard.kt index e48cf77..9a9ff8b 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteCard.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteCard.kt @@ -39,8 +39,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.models.Note import dev.dettmer.simplenotes.models.NoteType import dev.dettmer.simplenotes.models.SyncStatus @@ -66,6 +70,7 @@ fun NoteCard( onClick: () -> Unit, onLongClick: () -> Unit ) { + val context = LocalContext.current val borderColor = if (isSelected) { MaterialTheme.colorScheme.primary } else { @@ -137,7 +142,7 @@ fun NoteCard( // Title Text( - text = note.title.ifEmpty { "Ohne Titel" }, + text = note.title.ifEmpty { stringResource(R.string.untitled) }, style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.onSurface, maxLines = 2, @@ -154,7 +159,7 @@ fun NoteCard( NoteType.TEXT -> note.content.take(100) NoteType.CHECKLIST -> { val items = note.checklistItems ?: emptyList() - "${items.count { it.isChecked }}/${items.size} erledigt" + stringResource(R.string.checklist_progress, items.count { it.isChecked }, items.size) } }, style = MaterialTheme.typography.bodyMedium, @@ -171,7 +176,7 @@ fun NoteCard( verticalAlignment = Alignment.CenterVertically ) { Text( - text = note.updatedAt.toReadableTime(), + text = note.updatedAt.toReadableTime(context), style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.outline, modifier = Modifier.weight(1f) @@ -231,7 +236,7 @@ fun NoteCard( if (isSelected) { Icon( imageVector = Icons.Default.Check, - contentDescription = "Ausgewählt", + contentDescription = stringResource(R.string.selection_count, 1), tint = MaterialTheme.colorScheme.onPrimary, modifier = Modifier.size(16.dp) ) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteTypeFAB.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteTypeFAB.kt index 23b65d4..f49c57c 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteTypeFAB.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteTypeFAB.kt @@ -16,6 +16,8 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.models.NoteType /** @@ -42,7 +44,7 @@ fun NoteTypeFAB( ) { Icon( imageVector = Icons.Default.Add, - contentDescription = "Neue Notiz" + contentDescription = stringResource(R.string.fab_new_note) ) // Dropdown inside FAB - renders as popup overlay @@ -51,7 +53,7 @@ fun NoteTypeFAB( onDismissRequest = { expanded = false } ) { DropdownMenuItem( - text = { Text("Text-Notiz") }, + text = { Text(stringResource(R.string.fab_text_note)) }, leadingIcon = { Icon( imageVector = Icons.Outlined.Description, @@ -65,7 +67,7 @@ fun NoteTypeFAB( } ) DropdownMenuItem( - text = { Text("Checkliste") }, + text = { Text(stringResource(R.string.fab_checklist)) }, leadingIcon = { Icon( imageVector = Icons.AutoMirrored.Outlined.List, diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/SyncStatusBanner.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/SyncStatusBanner.kt index 2436b27..ac9ba26 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/SyncStatusBanner.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/SyncStatusBanner.kt @@ -16,7 +16,9 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.sync.SyncStateManager /** @@ -60,10 +62,10 @@ fun SyncStatusBanner( Text( text = when (syncState) { - SyncStateManager.SyncState.SYNCING -> "Synchronisiere..." + SyncStateManager.SyncState.SYNCING -> stringResource(R.string.sync_status_syncing) SyncStateManager.SyncState.SYNCING_SILENT -> "" // v1.5.0: Wird nicht angezeigt (isVisible = false) - SyncStateManager.SyncState.COMPLETED -> message ?: "Synchronisiert" - SyncStateManager.SyncState.ERROR -> message ?: "Fehler" + SyncStateManager.SyncState.COMPLETED -> message ?: stringResource(R.string.sync_status_completed) + SyncStateManager.SyncState.ERROR -> message ?: stringResource(R.string.sync_status_error) SyncStateManager.SyncState.IDLE -> "" }, style = MaterialTheme.typography.bodyMedium, diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/ComposeSettingsActivity.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/ComposeSettingsActivity.kt index 1569fac..ec9ddbd 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/ComposeSettingsActivity.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/ComposeSettingsActivity.kt @@ -7,16 +7,17 @@ import android.os.Bundle import android.os.PowerManager import android.provider.Settings import android.widget.Toast -import androidx.activity.ComponentActivity import androidx.activity.OnBackPressedCallback import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.platform.LocalContext import androidx.navigation.compose.rememberNavController import com.google.android.material.color.DynamicColors +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.SimpleNotesApplication import dev.dettmer.simplenotes.ui.theme.SimpleNotesTheme import dev.dettmer.simplenotes.utils.Logger @@ -34,7 +35,7 @@ import kotlinx.coroutines.launch * - Navigation with back button in each screen * - Clean separation of concerns with SettingsViewModel */ -class ComposeSettingsActivity : ComponentActivity() { +class ComposeSettingsActivity : AppCompatActivity() { companion object { private const val TAG = "ComposeSettingsActivity" @@ -133,16 +134,12 @@ class ComposeSettingsActivity : ComponentActivity() { */ private fun showBatteryOptimizationDialog() { AlertDialog.Builder(this) - .setTitle("Hintergrund-Synchronisation") - .setMessage( - "Damit die App im Hintergrund synchronisieren kann, " + - "muss die Akku-Optimierung deaktiviert werden.\n\n" + - "Bitte wähle 'Nicht optimieren' für Simple Notes." - ) - .setPositiveButton("Einstellungen öffnen") { _, _ -> + .setTitle(getString(R.string.battery_optimization_dialog_title)) + .setMessage(getString(R.string.battery_optimization_dialog_full_message)) + .setPositiveButton(getString(R.string.battery_optimization_open_settings)) { _, _ -> openBatteryOptimizationSettings() } - .setNegativeButton("Später") { dialog, _ -> + .setNegativeButton(getString(R.string.battery_optimization_later)) { dialog, _ -> dialog.dismiss() } .setCancelable(false) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsNavigation.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsNavigation.kt index 2b8f5d9..18c1c0e 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsNavigation.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsNavigation.kt @@ -7,6 +7,7 @@ import androidx.navigation.compose.composable import dev.dettmer.simplenotes.ui.settings.screens.AboutScreen import dev.dettmer.simplenotes.ui.settings.screens.BackupSettingsScreen import dev.dettmer.simplenotes.ui.settings.screens.DebugSettingsScreen +import dev.dettmer.simplenotes.ui.settings.screens.LanguageSettingsScreen import dev.dettmer.simplenotes.ui.settings.screens.MarkdownSettingsScreen import dev.dettmer.simplenotes.ui.settings.screens.ServerSettingsScreen import dev.dettmer.simplenotes.ui.settings.screens.SettingsMainScreen @@ -35,6 +36,13 @@ fun SettingsNavHost( ) } + // Language Settings + composable(SettingsRoute.Language.route) { + LanguageSettingsScreen( + onBack = { navController.popBackStack() } + ) + } + // Server Settings composable(SettingsRoute.Server.route) { ServerSettingsScreen( diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsRoute.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsRoute.kt index 3ce1c25..ffd3a23 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsRoute.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsRoute.kt @@ -6,6 +6,7 @@ package dev.dettmer.simplenotes.ui.settings */ sealed class SettingsRoute(val route: String) { data object Main : SettingsRoute("settings_main") + data object Language : SettingsRoute("settings_language") data object Server : SettingsRoute("settings_server") data object Sync : SettingsRoute("settings_sync") data object Markdown : SettingsRoute("settings_markdown") diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsViewModel.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsViewModel.kt index 533240c..2a55f6f 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsViewModel.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsViewModel.kt @@ -6,6 +6,7 @@ import android.net.Uri import android.util.Log import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.viewModelScope +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.backup.BackupManager import dev.dettmer.simplenotes.backup.RestoreMode import dev.dettmer.simplenotes.sync.WebDavSyncService @@ -184,10 +185,10 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application } else { ServerStatus.Unreachable(result.errorMessage) } - emitToast(if (result.isSuccess) "✅ Verbindung erfolgreich!" else "❌ ${result.errorMessage}") + emitToast(if (result.isSuccess) getString(R.string.toast_connection_success) else getString(R.string.toast_connection_failed, result.errorMessage ?: "")) } catch (e: Exception) { _serverStatus.value = ServerStatus.Unreachable(e.message) - emitToast("❌ Fehler: ${e.message}") + emitToast(getString(R.string.toast_error, e.message ?: "")) } } } @@ -225,22 +226,22 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application viewModelScope.launch { _isSyncing.value = true try { - emitToast("🔄 Synchronisiere...") + emitToast(getString(R.string.toast_syncing)) val syncService = WebDavSyncService(getApplication()) if (!syncService.hasUnsyncedChanges()) { - emitToast("✅ Bereits synchronisiert") + emitToast(getString(R.string.toast_already_synced)) return@launch } val result = syncService.syncNotes() if (result.isSuccess) { - emitToast("✅ ${result.syncedCount} Notizen synchronisiert") + emitToast(getString(R.string.toast_sync_success, result.syncedCount)) } else { - emitToast("❌ ${result.errorMessage}") + emitToast(getString(R.string.toast_sync_failed, result.errorMessage ?: "")) } } catch (e: Exception) { - emitToast("❌ Fehler: ${e.message}") + emitToast(getString(R.string.toast_error, e.message ?: "")) } finally { _isSyncing.value = false } @@ -260,10 +261,10 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application // v1.5.0 Fix: Trigger battery optimization check and network monitor restart _events.emit(SettingsEvent.RequestBatteryOptimization) _events.emit(SettingsEvent.RestartNetworkMonitor) - emitToast("✅ Auto-Sync aktiviert") + emitToast(getString(R.string.toast_auto_sync_enabled)) } else { _events.emit(SettingsEvent.RestartNetworkMonitor) - emitToast("Auto-Sync deaktiviert") + emitToast(getString(R.string.toast_auto_sync_disabled)) } } } @@ -273,11 +274,11 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application prefs.edit().putLong(Constants.PREF_SYNC_INTERVAL_MINUTES, minutes).apply() viewModelScope.launch { val text = when (minutes) { - 15L -> "15 Minuten" - 60L -> "60 Minuten" - else -> "30 Minuten" + 15L -> getString(R.string.toast_sync_interval_15min) + 60L -> getString(R.string.toast_sync_interval_60min) + else -> getString(R.string.toast_sync_interval_30min) } - emitToast("⏱️ Sync-Intervall: $text") + emitToast(getString(R.string.toast_sync_interval, text)) } } @@ -296,7 +297,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application val password = prefs.getString(Constants.KEY_PASSWORD, "") ?: "" if (serverUrl.isBlank() || username.isBlank() || password.isBlank()) { - emitToast("⚠️ Bitte zuerst WebDAV-Server konfigurieren") + emitToast(getString(R.string.toast_configure_server_first)) // Don't enable - revert state return@launch } @@ -329,7 +330,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application .apply() _markdownExportProgress.value = MarkdownExportProgress(noteCount, noteCount, isComplete = true) - emitToast("✅ $exportedCount Notizen nach Markdown exportiert") + emitToast(getString(R.string.toast_markdown_exported, exportedCount)) // Clear progress after short delay kotlinx.coroutines.delay(500) @@ -342,12 +343,12 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application .putBoolean(Constants.KEY_MARKDOWN_EXPORT, true) .putBoolean(Constants.KEY_MARKDOWN_AUTO_IMPORT, true) .apply() - emitToast("📝 Markdown Auto-Sync aktiviert") + emitToast(getString(R.string.toast_markdown_enabled)) } } catch (e: Exception) { _markdownExportProgress.value = null - emitToast("❌ Export fehlgeschlagen: ${e.message}") + emitToast(getString(R.string.toast_export_failed, e.message ?: "")) // Don't enable on error } } @@ -359,7 +360,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application .putBoolean(Constants.KEY_MARKDOWN_AUTO_IMPORT, false) .apply() viewModelScope.launch { - emitToast("📝 Markdown Auto-Sync deaktiviert") + emitToast(getString(R.string.toast_markdown_disabled)) } } } @@ -367,12 +368,12 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application fun performManualMarkdownSync() { viewModelScope.launch { try { - emitToast("📝 Markdown-Sync läuft...") + emitToast(getString(R.string.toast_markdown_syncing)) val syncService = WebDavSyncService(getApplication()) val result = syncService.manualMarkdownSync() - emitToast("✅ Export: ${result.exportedCount} • Import: ${result.importedCount}") + emitToast(getString(R.string.toast_markdown_result, result.exportedCount, result.importedCount)) } catch (e: Exception) { - emitToast("❌ Fehler: ${e.message}") + emitToast(getString(R.string.toast_error, e.message ?: "")) } } } @@ -386,9 +387,9 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application _isBackupInProgress.value = true try { val result = backupManager.createBackup(uri) - emitToast(if (result.success) "✅ ${result.message}" else "❌ ${result.error}") + emitToast(if (result.success) getString(R.string.toast_backup_success, result.message ?: "") else getString(R.string.toast_backup_failed, result.error ?: "")) } catch (e: Exception) { - emitToast("❌ Backup fehlgeschlagen: ${e.message}") + emitToast(getString(R.string.toast_backup_failed, e.message ?: "")) } finally { _isBackupInProgress.value = false } @@ -400,9 +401,9 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application _isBackupInProgress.value = true try { val result = backupManager.restoreBackup(uri, mode) - emitToast(if (result.success) "✅ ${result.importedNotes} Notizen wiederhergestellt" else "❌ ${result.error}") + emitToast(if (result.success) getString(R.string.toast_restore_success, result.importedNotes) else getString(R.string.toast_restore_failed, result.error ?: "")) } catch (e: Exception) { - emitToast("❌ Wiederherstellung fehlgeschlagen: ${e.message}") + emitToast(getString(R.string.toast_restore_failed, e.message ?: "")) } finally { _isBackupInProgress.value = false } @@ -413,14 +414,14 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application viewModelScope.launch { _isBackupInProgress.value = true try { - emitToast("📥 Lade vom Server...") + emitToast(getString(R.string.restore_progress)) val syncService = WebDavSyncService(getApplication()) val result = withContext(Dispatchers.IO) { syncService.restoreFromServer(mode) } - emitToast(if (result.isSuccess) "✅ ${result.restoredCount} Notizen wiederhergestellt" else "❌ ${result.errorMessage}") + emitToast(if (result.isSuccess) getString(R.string.toast_restore_success, result.restoredCount) else getString(R.string.toast_restore_failed, result.errorMessage ?: "")) } catch (e: Exception) { - emitToast("❌ Fehler: ${e.message}") + emitToast(getString(R.string.toast_error, e.message ?: "")) } finally { _isBackupInProgress.value = false } @@ -436,7 +437,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application prefs.edit().putBoolean(Constants.KEY_FILE_LOGGING_ENABLED, enabled).apply() Logger.setFileLoggingEnabled(enabled) viewModelScope.launch { - emitToast(if (enabled) "📝 Datei-Logging aktiviert" else "📝 Datei-Logging deaktiviert") + emitToast(if (enabled) getString(R.string.toast_file_logging_enabled) else getString(R.string.toast_file_logging_disabled)) } } @@ -444,9 +445,9 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application viewModelScope.launch { try { val cleared = Logger.clearLogFile(getApplication()) - emitToast(if (cleared) "🗑️ Logs gelöscht" else "📭 Keine Logs zum Löschen") + emitToast(if (cleared) getString(R.string.toast_logs_deleted) else getString(R.string.toast_logs_deleted)) } catch (e: Exception) { - emitToast("❌ Fehler: ${e.message}") + emitToast(getString(R.string.toast_error, e.message ?: "")) } } } @@ -457,6 +458,11 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application // Helper // ═══════════════════════════════════════════════════════════════════════ + private fun getString(resId: Int): String = getApplication().getString(resId) + + private fun getString(resId: Int, vararg formatArgs: Any): String = + getApplication().getString(resId, *formatArgs) + private suspend fun emitToast(message: String) { _showToast.emit(message) } diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsScaffold.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsScaffold.kt index a08b383..457b423 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsScaffold.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsScaffold.kt @@ -13,6 +13,8 @@ import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import dev.dettmer.simplenotes.R /** * Reusable Scaffold with back-navigation TopAppBar @@ -40,7 +42,7 @@ fun SettingsScaffold( IconButton(onClick = onBack) { Icon( imageVector = Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = "Zurück" + contentDescription = stringResource(R.string.content_description_back) ) } }, diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt index ad742a2..1d3c98b 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt @@ -37,9 +37,11 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import dev.dettmer.simplenotes.BuildConfig +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.ui.settings.components.SettingsDivider import dev.dettmer.simplenotes.ui.settings.components.SettingsScaffold import dev.dettmer.simplenotes.ui.settings.components.SettingsSectionHeader @@ -59,7 +61,7 @@ fun AboutScreen( val licenseUrl = "https://github.com/inventory69/simple-notes-sync/blob/main/LICENSE" SettingsScaffold( - title = "Über diese App", + title = stringResource(R.string.about_settings_title), onBack = onBack ) { paddingValues -> Column( @@ -110,7 +112,7 @@ fun AboutScreen( Spacer(modifier = Modifier.height(8.dp)) Text( - text = "Simple Notes Sync", + text = stringResource(R.string.about_app_name), style = MaterialTheme.typography.headlineSmall, color = MaterialTheme.colorScheme.onPrimaryContainer ) @@ -118,7 +120,7 @@ fun AboutScreen( Spacer(modifier = Modifier.height(4.dp)) Text( - text = "Version ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})", + text = stringResource(R.string.about_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE), style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.8f) ) @@ -127,13 +129,13 @@ fun AboutScreen( Spacer(modifier = Modifier.height(24.dp)) - SettingsSectionHeader(text = "Links") + SettingsSectionHeader(text = stringResource(R.string.about_links_section)) // GitHub Repository AboutLinkItem( icon = Icons.Default.Code, - title = "GitHub Repository", - subtitle = "Quellcode, Issues & Dokumentation", + title = stringResource(R.string.about_github_title), + subtitle = stringResource(R.string.about_github_subtitle), onClick = { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(githubRepoUrl)) context.startActivity(intent) @@ -143,8 +145,8 @@ fun AboutScreen( // Developer AboutLinkItem( icon = Icons.Default.Person, - title = "Entwickler", - subtitle = "GitHub Profil: @inventory69", + title = stringResource(R.string.about_developer_title), + subtitle = stringResource(R.string.about_developer_subtitle), onClick = { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(githubProfileUrl)) context.startActivity(intent) @@ -154,8 +156,8 @@ fun AboutScreen( // License AboutLinkItem( icon = Icons.Default.Policy, - title = "Lizenz", - subtitle = "MIT License - Open Source", + title = stringResource(R.string.about_license_title), + subtitle = stringResource(R.string.about_license_subtitle), onClick = { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(licenseUrl)) context.startActivity(intent) @@ -177,14 +179,12 @@ fun AboutScreen( modifier = Modifier.padding(16.dp) ) { Text( - text = "🔒 Datenschutz", + text = stringResource(R.string.about_privacy_title), style = MaterialTheme.typography.titleSmall ) Spacer(modifier = Modifier.height(8.dp)) Text( - text = "Diese App sammelt keine Daten. Alle Notizen werden " + - "nur lokal auf deinem Gerät und auf deinem eigenen " + - "WebDAV-Server gespeichert. Keine Telemetrie, keine Werbung.", + text = stringResource(R.string.about_privacy_text), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant ) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/BackupSettingsScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/BackupSettingsScreen.kt index e3ca5c2..a93bc19 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/BackupSettingsScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/BackupSettingsScreen.kt @@ -21,7 +21,9 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.backup.RestoreMode import dev.dettmer.simplenotes.ui.settings.SettingsViewModel import dev.dettmer.simplenotes.ui.settings.components.RadioOption @@ -71,7 +73,7 @@ fun BackupSettingsScreen( } SettingsScaffold( - title = "Backup & Wiederherstellung", + title = stringResource(R.string.backup_settings_title), onBack = onBack ) { paddingValues -> Column( @@ -84,19 +86,18 @@ fun BackupSettingsScreen( // Info Card SettingsInfoCard( - text = "📦 Bei jeder Wiederherstellung wird automatisch ein " + - "Sicherheits-Backup erstellt." + text = stringResource(R.string.backup_auto_info) ) Spacer(modifier = Modifier.height(16.dp)) // Local Backup Section - SettingsSectionHeader(text = "Lokales Backup") + SettingsSectionHeader(text = stringResource(R.string.backup_local_section)) Spacer(modifier = Modifier.height(8.dp)) SettingsButton( - text = "💾 Backup erstellen", + text = stringResource(R.string.backup_create), onClick = { val timestamp = SimpleDateFormat("yyyy-MM-dd_HHmmss", Locale.US) .format(Date()) @@ -110,7 +111,7 @@ fun BackupSettingsScreen( Spacer(modifier = Modifier.height(8.dp)) SettingsOutlinedButton( - text = "📂 Aus Datei wiederherstellen", + text = stringResource(R.string.backup_restore_file), onClick = { restoreFileLauncher.launch(arrayOf("application/json")) }, @@ -121,12 +122,12 @@ fun BackupSettingsScreen( SettingsDivider() // Server Backup Section - SettingsSectionHeader(text = "Server-Backup") + SettingsSectionHeader(text = stringResource(R.string.backup_server_section)) Spacer(modifier = Modifier.height(8.dp)) SettingsOutlinedButton( - text = "☁️ Vom Server wiederherstellen", + text = stringResource(R.string.backup_restore_server), onClick = { restoreSource = RestoreSource.Server showRestoreDialog = true @@ -186,42 +187,42 @@ private fun RestoreModeDialog( onDismiss: () -> Unit ) { val sourceText = when (source) { - RestoreSource.LocalFile -> "Lokale Datei" - RestoreSource.Server -> "WebDAV Server" + RestoreSource.LocalFile -> stringResource(R.string.backup_restore_source_file) + RestoreSource.Server -> stringResource(R.string.backup_restore_source_server) } val modeOptions = listOf( RadioOption( value = RestoreMode.MERGE, - title = "⚪ Zusammenführen (Standard)", - subtitle = "Neue hinzufügen, Bestehende behalten" + title = stringResource(R.string.backup_mode_merge_title), + subtitle = stringResource(R.string.backup_mode_merge_subtitle) ), RadioOption( value = RestoreMode.REPLACE, - title = "⚪ Ersetzen", - subtitle = "Alle löschen & Backup importieren" + title = stringResource(R.string.backup_mode_replace_title), + subtitle = stringResource(R.string.backup_mode_replace_subtitle) ), RadioOption( value = RestoreMode.OVERWRITE_DUPLICATES, - title = "⚪ Duplikate überschreiben", - subtitle = "Backup gewinnt bei Konflikten" + title = stringResource(R.string.backup_mode_overwrite_title), + subtitle = stringResource(R.string.backup_mode_overwrite_subtitle) ) ) AlertDialog( onDismissRequest = onDismiss, - title = { Text("⚠️ Backup wiederherstellen?") }, + title = { Text(stringResource(R.string.backup_restore_dialog_title)) }, text = { Column { Text( - text = "Quelle: $sourceText", + text = stringResource(R.string.backup_restore_source, sourceText), style = MaterialTheme.typography.bodyMedium ) Spacer(modifier = Modifier.height(16.dp)) Text( - text = "Wiederherstellungs-Modus:", + text = stringResource(R.string.backup_restore_mode_label), style = MaterialTheme.typography.labelLarge ) @@ -236,7 +237,7 @@ private fun RestoreModeDialog( Spacer(modifier = Modifier.height(8.dp)) Text( - text = "ℹ️ Ein Sicherheits-Backup wird vor dem Wiederherstellen automatisch erstellt.", + text = stringResource(R.string.backup_restore_info), style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant ) @@ -244,12 +245,12 @@ private fun RestoreModeDialog( }, confirmButton = { TextButton(onClick = onConfirm) { - Text("Wiederherstellen") + Text(stringResource(R.string.backup_restore_button)) } }, dismissButton = { TextButton(onClick = onDismiss) { - Text("Abbrechen") + Text(stringResource(R.string.cancel)) } } ) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/DebugSettingsScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/DebugSettingsScreen.kt index c68593c..f3bd74b 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/DebugSettingsScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/DebugSettingsScreen.kt @@ -21,9 +21,11 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.core.content.FileProvider import dev.dettmer.simplenotes.BuildConfig +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.ui.settings.SettingsViewModel import dev.dettmer.simplenotes.ui.settings.components.SettingsButton import dev.dettmer.simplenotes.ui.settings.components.SettingsDangerButton @@ -48,7 +50,7 @@ fun DebugSettingsScreen( var showClearLogsDialog by remember { mutableStateOf(false) } SettingsScaffold( - title = "Debug & Diagnose", + title = stringResource(R.string.debug_settings_title), onBack = onBack ) { paddingValues -> Column( @@ -61,8 +63,8 @@ fun DebugSettingsScreen( // File Logging Toggle SettingsSwitch( - title = "Datei-Logging", - subtitle = "Sync-Logs in Datei speichern", + title = stringResource(R.string.debug_file_logging_title), + subtitle = stringResource(R.string.debug_file_logging_subtitle), checked = fileLoggingEnabled, onCheckedChange = { viewModel.setFileLogging(it) }, icon = Icons.AutoMirrored.Filled.Notes @@ -70,21 +72,18 @@ fun DebugSettingsScreen( // Privacy Info SettingsInfoCard( - text = "🔒 Datenschutz: Logs werden nur lokal auf deinem Gerät gespeichert " + - "und niemals an externe Server gesendet. Die Logs enthalten " + - "Sync-Aktivitäten zur Fehlerdiagnose. Du kannst sie jederzeit löschen " + - "oder exportieren." + text = stringResource(R.string.debug_privacy_info) ) SettingsDivider() - SettingsSectionHeader(text = "Log-Aktionen") + SettingsSectionHeader(text = stringResource(R.string.debug_log_actions_section)) Spacer(modifier = Modifier.height(8.dp)) // Export Logs Button SettingsButton( - text = "📤 Logs exportieren & teilen", + text = stringResource(R.string.debug_export_logs), onClick = { val logFile = viewModel.getLogFile() if (logFile != null && logFile.exists() && logFile.length() > 0L) { @@ -97,11 +96,11 @@ fun DebugSettingsScreen( val shareIntent = Intent(Intent.ACTION_SEND).apply { type = "text/plain" putExtra(Intent.EXTRA_STREAM, logUri) - putExtra(Intent.EXTRA_SUBJECT, "SimpleNotes Sync Logs") + putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.debug_logs_subject)) addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) } - context.startActivity(Intent.createChooser(shareIntent, "Logs teilen via...")) + context.startActivity(Intent.createChooser(shareIntent, context.getString(R.string.debug_logs_share_via))) } }, modifier = Modifier.padding(horizontal = 16.dp) @@ -111,7 +110,7 @@ fun DebugSettingsScreen( // Clear Logs Button SettingsDangerButton( - text = "🗑️ Logs löschen", + text = stringResource(R.string.debug_delete_logs), onClick = { showClearLogsDialog = true }, modifier = Modifier.padding(horizontal = 16.dp) ) @@ -124,9 +123,9 @@ fun DebugSettingsScreen( if (showClearLogsDialog) { AlertDialog( onDismissRequest = { showClearLogsDialog = false }, - title = { Text("Logs löschen?") }, + title = { Text(stringResource(R.string.debug_delete_logs_title)) }, text = { - Text("Alle gespeicherten Sync-Logs werden unwiderruflich gelöscht.") + Text(stringResource(R.string.debug_delete_logs_message)) }, confirmButton = { TextButton( @@ -135,12 +134,12 @@ fun DebugSettingsScreen( viewModel.clearLogs() } ) { - Text("Löschen") + Text(stringResource(R.string.delete)) } }, dismissButton = { TextButton(onClick = { showClearLogsDialog = false }) { - Text("Abbrechen") + Text(stringResource(R.string.cancel)) } } ) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/LanguageSettingsScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/LanguageSettingsScreen.kt new file mode 100644 index 0000000..f47d9f2 --- /dev/null +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/LanguageSettingsScreen.kt @@ -0,0 +1,120 @@ +package dev.dettmer.simplenotes.ui.settings.screens + +import android.app.Activity +import androidx.appcompat.app.AppCompatDelegate +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.core.os.LocaleListCompat +import dev.dettmer.simplenotes.R +import dev.dettmer.simplenotes.ui.settings.components.RadioOption +import dev.dettmer.simplenotes.ui.settings.components.SettingsInfoCard +import dev.dettmer.simplenotes.ui.settings.components.SettingsRadioGroup +import dev.dettmer.simplenotes.ui.settings.components.SettingsScaffold + +/** + * Language selection settings screen + * v1.5.0: Internationalization feature + * + * Uses Android's Per-App Language API (Android 13+) with AppCompat fallback + */ +@Composable +fun LanguageSettingsScreen( + onBack: () -> Unit +) { + val context = LocalContext.current + + // Get current app locale - fresh value each time (no remember, always reads current state) + val currentLocale = AppCompatDelegate.getApplicationLocales() + val currentLanguageCode = if (currentLocale.isEmpty) { + "" // System default + } else { + currentLocale.get(0)?.language ?: "" + } + + var selectedLanguage by remember(currentLanguageCode) { mutableStateOf(currentLanguageCode) } + + // Language options + val languageOptions = listOf( + RadioOption( + value = "", + title = stringResource(R.string.language_system_default), + subtitle = null + ), + RadioOption( + value = "en", + title = stringResource(R.string.language_english), + subtitle = "English" + ), + RadioOption( + value = "de", + title = stringResource(R.string.language_german), + subtitle = "German" + ) + ) + + SettingsScaffold( + title = stringResource(R.string.language_settings_title), + onBack = onBack + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) + .verticalScroll(rememberScrollState()) + ) { + Spacer(modifier = Modifier.height(8.dp)) + + // Info card + SettingsInfoCard( + text = stringResource(R.string.language_info) + ) + + Spacer(modifier = Modifier.height(8.dp)) + + // Language selection radio group + SettingsRadioGroup( + options = languageOptions, + selectedValue = selectedLanguage, + onValueSelected = { newLanguage -> + if (newLanguage != selectedLanguage) { + selectedLanguage = newLanguage + setAppLanguage(newLanguage, context as Activity) + } + } + ) + } + } +} + +/** + * Set app language using AppCompatDelegate + * Works on Android 13+ natively, falls back to AppCompat on older versions + */ +private fun setAppLanguage(languageCode: String, activity: Activity) { + val localeList = if (languageCode.isEmpty()) { + LocaleListCompat.getEmptyLocaleList() + } else { + LocaleListCompat.forLanguageTags(languageCode) + } + + AppCompatDelegate.setApplicationLocales(localeList) + + // Restart the activity to apply the change + // On Android 13+ the system handles this automatically for some apps, + // but we need to recreate to ensure our Compose UI recomposes with new locale + activity.recreate() +} diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/MarkdownSettingsScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/MarkdownSettingsScreen.kt index 0b245af..d62f1b7 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/MarkdownSettingsScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/MarkdownSettingsScreen.kt @@ -20,7 +20,9 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.ui.settings.SettingsViewModel import dev.dettmer.simplenotes.ui.settings.components.SettingsButton import dev.dettmer.simplenotes.ui.settings.components.SettingsDivider @@ -44,7 +46,7 @@ fun MarkdownSettingsScreen( exportProgress?.let { progress -> AlertDialog( onDismissRequest = { /* Not dismissable */ }, - title = { Text("Markdown Auto-Sync") }, + title = { Text(stringResource(R.string.markdown_dialog_title)) }, text = { Column( modifier = Modifier.fillMaxWidth(), @@ -53,9 +55,9 @@ fun MarkdownSettingsScreen( ) { Text( text = if (progress.isComplete) { - "✅ Export abgeschlossen" + stringResource(R.string.markdown_export_complete) } else { - "Exportiere ${progress.current}/${progress.total} Notizen..." + stringResource(R.string.markdown_export_progress, progress.current, progress.total) }, style = MaterialTheme.typography.bodyMedium ) @@ -75,7 +77,7 @@ fun MarkdownSettingsScreen( } SettingsScaffold( - title = "Markdown Desktop-Integration", + title = stringResource(R.string.markdown_settings_title), onBack = onBack ) { paddingValues -> Column( @@ -88,17 +90,15 @@ fun MarkdownSettingsScreen( // Info Card SettingsInfoCard( - text = "📝 Exportiert Notizen zusätzlich als .md-Dateien. Mounte " + - "WebDAV als Netzlaufwerk um mit VS Code, Typora oder jedem " + - "Markdown-Editor zu bearbeiten. JSON-Sync bleibt primäres Format." + text = stringResource(R.string.markdown_info) ) Spacer(modifier = Modifier.height(8.dp)) // Markdown Auto-Sync Toggle SettingsSwitch( - title = "Markdown Auto-Sync", - subtitle = "Synchronisiert Notizen automatisch als .md-Dateien (Upload + Download bei jedem Sync)", + title = stringResource(R.string.markdown_auto_sync_title), + subtitle = stringResource(R.string.markdown_auto_sync_subtitle), checked = markdownAutoSync, onCheckedChange = { viewModel.setMarkdownAutoSync(it) }, icon = Icons.Default.Description @@ -109,14 +109,13 @@ fun MarkdownSettingsScreen( SettingsDivider() SettingsInfoCard( - text = "Manueller Sync exportiert alle Notizen als .md-Dateien und " + - "importiert .md-Dateien vom Server. Nützlich für einmalige Synchronisation." + text = stringResource(R.string.markdown_manual_sync_info) ) Spacer(modifier = Modifier.height(8.dp)) SettingsButton( - text = "📝 Manueller Markdown-Sync", + text = stringResource(R.string.markdown_manual_sync_button), onClick = { viewModel.performManualMarkdownSync() }, modifier = Modifier.padding(horizontal = 16.dp) ) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/ServerSettingsScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/ServerSettingsScreen.kt index 6927805..b7ae5c6 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/ServerSettingsScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/ServerSettingsScreen.kt @@ -41,9 +41,11 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.VisualTransformation import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.ui.settings.SettingsViewModel import dev.dettmer.simplenotes.ui.settings.components.SettingsScaffold @@ -71,7 +73,7 @@ fun ServerSettingsScreen( } SettingsScaffold( - title = "Server-Einstellungen", + title = stringResource(R.string.server_settings_title), onBack = onBack ) { paddingValues -> Column( @@ -83,7 +85,7 @@ fun ServerSettingsScreen( ) { // Verbindungstyp Text( - text = "Verbindungstyp", + text = stringResource(R.string.server_connection_type), style = MaterialTheme.typography.labelLarge, modifier = Modifier.padding(bottom = 8.dp) ) @@ -95,22 +97,22 @@ fun ServerSettingsScreen( FilterChip( selected = !isHttps, onClick = { viewModel.updateProtocol(false) }, - label = { Text("🏠 Intern (HTTP)") }, + label = { Text(stringResource(R.string.server_connection_http)) }, modifier = Modifier.weight(1f) ) FilterChip( selected = isHttps, onClick = { viewModel.updateProtocol(true) }, - label = { Text("🌐 Extern (HTTPS)") }, + label = { Text(stringResource(R.string.server_connection_https)) }, modifier = Modifier.weight(1f) ) } Text( text = if (!isHttps) { - "HTTP nur für lokale Netzwerke (z.B. 192.168.x.x, 10.x.x.x)" + stringResource(R.string.server_connection_http_hint) } else { - "HTTPS für sichere Verbindungen über das Internet" + stringResource(R.string.server_connection_https_hint) }, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, @@ -121,8 +123,8 @@ fun ServerSettingsScreen( OutlinedTextField( value = serverUrl, onValueChange = { viewModel.updateServerUrl(it) }, - label = { Text("Server-Adresse") }, - supportingText = { Text("z.B. http://192.168.0.188:8080/notes") }, + label = { Text(stringResource(R.string.server_address)) }, + supportingText = { Text(stringResource(R.string.server_address_hint)) }, leadingIcon = { Icon(Icons.Default.Language, null) }, modifier = Modifier.fillMaxWidth(), singleLine = true, @@ -135,7 +137,7 @@ fun ServerSettingsScreen( OutlinedTextField( value = username, onValueChange = { viewModel.updateUsername(it) }, - label = { Text("Benutzername") }, + label = { Text(stringResource(R.string.username)) }, leadingIcon = { Icon(Icons.Default.Person, null) }, modifier = Modifier.fillMaxWidth(), singleLine = true @@ -147,7 +149,7 @@ fun ServerSettingsScreen( OutlinedTextField( value = password, onValueChange = { viewModel.updatePassword(it) }, - label = { Text("Passwort") }, + label = { Text(stringResource(R.string.password)) }, leadingIcon = { Icon(Icons.Default.Lock, null) }, trailingIcon = { IconButton(onClick = { passwordVisible = !passwordVisible }) { @@ -157,7 +159,7 @@ fun ServerSettingsScreen( } else { Icons.Default.Visibility }, - contentDescription = if (passwordVisible) "Verstecken" else "Anzeigen" + contentDescription = if (passwordVisible) stringResource(R.string.server_password_hide) else stringResource(R.string.server_password_show) ) } }, @@ -187,14 +189,14 @@ fun ServerSettingsScreen( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { - Text("Server-Status:", style = MaterialTheme.typography.labelLarge) + Text(stringResource(R.string.server_status_label), style = MaterialTheme.typography.labelLarge) Text( text = when (serverStatus) { - is SettingsViewModel.ServerStatus.Reachable -> "✅ Erreichbar" - is SettingsViewModel.ServerStatus.Unreachable -> "❌ Nicht erreichbar" - is SettingsViewModel.ServerStatus.Checking -> "🔍 Prüfe..." - is SettingsViewModel.ServerStatus.NotConfigured -> "⚠️ Nicht konfiguriert" - else -> "❓ Unbekannt" + is SettingsViewModel.ServerStatus.Reachable -> stringResource(R.string.server_status_reachable) + is SettingsViewModel.ServerStatus.Unreachable -> stringResource(R.string.server_status_unreachable) + is SettingsViewModel.ServerStatus.Checking -> stringResource(R.string.server_status_checking) + is SettingsViewModel.ServerStatus.NotConfigured -> stringResource(R.string.server_status_not_configured) + else -> stringResource(R.string.server_status_unknown) }, color = when (serverStatus) { is SettingsViewModel.ServerStatus.Reachable -> Color(0xFF4CAF50) @@ -217,7 +219,7 @@ fun ServerSettingsScreen( onClick = { viewModel.testConnection() }, modifier = Modifier.weight(1f) ) { - Text("Verbindung testen") + Text(stringResource(R.string.test_connection)) } Button( @@ -233,7 +235,7 @@ fun ServerSettingsScreen( ) Spacer(modifier = Modifier.width(8.dp)) } - Text("Jetzt synchronisieren") + Text(stringResource(R.string.sync_now)) } } } diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SettingsMainScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SettingsMainScreen.kt index 25c256f..dd696be 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SettingsMainScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SettingsMainScreen.kt @@ -1,5 +1,6 @@ package dev.dettmer.simplenotes.ui.settings.screens +import androidx.appcompat.app.AppCompatDelegate import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding @@ -10,6 +11,7 @@ import androidx.compose.material.icons.filled.BugReport import androidx.compose.material.icons.filled.Cloud import androidx.compose.material.icons.filled.Description import androidx.compose.material.icons.filled.Info +import androidx.compose.material.icons.filled.Language import androidx.compose.material.icons.filled.Sync import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -17,8 +19,10 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import dev.dettmer.simplenotes.BuildConfig +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.ui.settings.SettingsRoute import dev.dettmer.simplenotes.ui.settings.SettingsViewModel import dev.dettmer.simplenotes.ui.settings.components.SettingsCard @@ -46,8 +50,18 @@ fun SettingsMainScreen( viewModel.checkServerStatus() } + // Get current language for display (no remember - always fresh value after activity recreate) + val locales = AppCompatDelegate.getApplicationLocales() + val currentLanguageName = if (locales.isEmpty) { + null // System default + } else { + locales[0]?.displayLanguage?.replaceFirstChar { it.uppercase() } + } + val systemDefaultText = stringResource(R.string.language_system_default) + val languageSubtitle = currentLanguageName ?: systemDefaultText + SettingsScaffold( - title = "Einstellungen", + title = stringResource(R.string.settings_title), onBack = onBack ) { paddingValues -> LazyColumn( @@ -56,6 +70,16 @@ fun SettingsMainScreen( .padding(paddingValues), contentPadding = PaddingValues(vertical = 8.dp) ) { + // Language Settings + item { + SettingsCard( + icon = Icons.Default.Language, + title = stringResource(R.string.settings_language), + subtitle = languageSubtitle, + onClick = { onNavigate(SettingsRoute.Language) } + ) + } + // Server-Einstellungen item { // v1.5.0 Fix: Nur Prefix-URLs gelten als "nicht konfiguriert" @@ -65,13 +89,13 @@ fun SettingsMainScreen( SettingsCard( icon = Icons.Default.Cloud, - title = "Server-Einstellungen", + title = stringResource(R.string.settings_server), subtitle = if (isConfigured) serverUrl else null, statusText = when (serverStatus) { - is SettingsViewModel.ServerStatus.Reachable -> "✅ Erreichbar" - is SettingsViewModel.ServerStatus.Unreachable -> "❌ Nicht erreichbar" - is SettingsViewModel.ServerStatus.Checking -> "🔍 Prüfe..." - is SettingsViewModel.ServerStatus.NotConfigured -> "⚠️ Nicht konfiguriert" + is SettingsViewModel.ServerStatus.Reachable -> stringResource(R.string.settings_server_status_reachable) + is SettingsViewModel.ServerStatus.Unreachable -> stringResource(R.string.settings_server_status_unreachable) + is SettingsViewModel.ServerStatus.Checking -> stringResource(R.string.settings_server_status_checking) + is SettingsViewModel.ServerStatus.NotConfigured -> stringResource(R.string.settings_server_status_not_configured) else -> null }, statusColor = when (serverStatus) { @@ -87,14 +111,14 @@ fun SettingsMainScreen( // Sync-Einstellungen item { val intervalText = when (syncInterval) { - 15L -> "15 Min" - 60L -> "60 Min" - else -> "30 Min" + 15L -> stringResource(R.string.settings_interval_15min) + 60L -> stringResource(R.string.settings_interval_60min) + else -> stringResource(R.string.settings_interval_30min) } SettingsCard( icon = Icons.Default.Sync, - title = "Sync-Einstellungen", - subtitle = if (autoSyncEnabled) "Auto-Sync: An • $intervalText" else "Auto-Sync: Aus", + title = stringResource(R.string.settings_sync), + subtitle = if (autoSyncEnabled) stringResource(R.string.settings_sync_auto_on, intervalText) else stringResource(R.string.settings_sync_auto_off), onClick = { onNavigate(SettingsRoute.Sync) } ) } @@ -103,8 +127,8 @@ fun SettingsMainScreen( item { SettingsCard( icon = Icons.Default.Description, - title = "Markdown Desktop-Integration", - subtitle = if (markdownAutoSync) "Auto-Sync: An" else "Auto-Sync: Aus", + title = stringResource(R.string.settings_markdown), + subtitle = if (markdownAutoSync) stringResource(R.string.settings_markdown_auto_on) else stringResource(R.string.settings_markdown_auto_off), onClick = { onNavigate(SettingsRoute.Markdown) } ) } @@ -113,8 +137,8 @@ fun SettingsMainScreen( item { SettingsCard( icon = Icons.Default.Backup, - title = "Backup & Wiederherstellung", - subtitle = "Lokales oder Server-Backup", + title = stringResource(R.string.settings_backup), + subtitle = stringResource(R.string.settings_backup_subtitle), onClick = { onNavigate(SettingsRoute.Backup) } ) } @@ -123,8 +147,8 @@ fun SettingsMainScreen( item { SettingsCard( icon = Icons.Default.Info, - title = "Über diese App", - subtitle = "Version ${BuildConfig.VERSION_NAME}", + title = stringResource(R.string.settings_about), + subtitle = stringResource(R.string.about_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE), onClick = { onNavigate(SettingsRoute.About) } ) } @@ -133,8 +157,8 @@ fun SettingsMainScreen( item { SettingsCard( icon = Icons.Default.BugReport, - title = "Debug & Diagnose", - subtitle = if (fileLoggingEnabled) "Logging: An" else "Logging: Aus", + title = stringResource(R.string.settings_debug), + subtitle = if (fileLoggingEnabled) stringResource(R.string.settings_debug_logging_on) else stringResource(R.string.settings_debug_logging_off), onClick = { onNavigate(SettingsRoute.Debug) } ) } 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 7452bae..b2196a8 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 @@ -13,7 +13,9 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.ui.settings.SettingsViewModel import dev.dettmer.simplenotes.ui.settings.components.RadioOption import dev.dettmer.simplenotes.ui.settings.components.SettingsDivider @@ -36,7 +38,7 @@ fun SyncSettingsScreen( val syncInterval by viewModel.syncInterval.collectAsState() SettingsScaffold( - title = "Sync-Einstellungen", + title = stringResource(R.string.sync_settings_title), onBack = onBack ) { paddingValues -> Column( @@ -49,18 +51,14 @@ fun SyncSettingsScreen( // Auto-Sync Info SettingsInfoCard( - text = "🔄 Auto-Sync:\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)" + text = stringResource(R.string.sync_auto_sync_info) ) Spacer(modifier = Modifier.height(8.dp)) // Auto-Sync Toggle SettingsSwitch( - title = "Auto-Sync aktiviert", + title = stringResource(R.string.sync_auto_sync_enabled), checked = autoSyncEnabled, onCheckedChange = { viewModel.setAutoSync(it) }, icon = Icons.Default.Sync @@ -69,14 +67,10 @@ fun SyncSettingsScreen( SettingsDivider() // Sync Interval Section - SettingsSectionHeader(text = "Sync-Intervall") + SettingsSectionHeader(text = stringResource(R.string.sync_interval_section)) SettingsInfoCard( - text = "Legt fest, wie oft die App im Hintergrund synchronisiert. " + - "Kürzere Intervalle bedeuten aktuellere Daten, verbrauchen aber etwas mehr Akku.\n\n" + - "⏱️ Hinweis: Wenn dein Smartphone im Standby ist, kann Android die " + - "Synchronisation verzögern (bis zu 60 Min.), um Akku zu sparen. " + - "Das ist normal und betrifft alle Hintergrund-Apps." + text = stringResource(R.string.sync_interval_info) ) Spacer(modifier = Modifier.height(8.dp)) @@ -85,18 +79,18 @@ fun SyncSettingsScreen( val intervalOptions = listOf( RadioOption( value = 15L, - title = "⚡ Alle 15 Minuten", - subtitle = "Schnellste Synchronisation • ~0.8% Akku/Tag (~23 mAh)" + title = stringResource(R.string.sync_interval_15min_title), + subtitle = stringResource(R.string.sync_interval_15min_subtitle) ), RadioOption( value = 30L, - title = "✓ Alle 30 Minuten (Empfohlen)", - subtitle = "Ausgewogenes Verhältnis • ~0.4% Akku/Tag (~12 mAh)" + title = stringResource(R.string.sync_interval_30min_title), + subtitle = stringResource(R.string.sync_interval_30min_subtitle) ), RadioOption( value = 60L, - title = "🔋 Alle 60 Minuten", - subtitle = "Maximale Akkulaufzeit • ~0.2% Akku/Tag (~6 mAh geschätzt)" + title = stringResource(R.string.sync_interval_60min_title), + subtitle = stringResource(R.string.sync_interval_60min_subtitle) ) ) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/utils/Extensions.kt b/android/app/src/main/java/dev/dettmer/simplenotes/utils/Extensions.kt index 84139b9..4bb7212 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/utils/Extensions.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/utils/Extensions.kt @@ -2,6 +2,7 @@ package dev.dettmer.simplenotes.utils import android.content.Context import android.widget.Toast +import dev.dettmer.simplenotes.R import java.text.SimpleDateFormat import java.util.Date import java.util.Locale @@ -15,7 +16,7 @@ fun Context.showToast(message: String, duration: Int = Toast.LENGTH_SHORT) { Toast.makeText(this, message, duration).show() } -// Timestamp to readable format +// Timestamp to readable format (legacy - without context, uses German) fun Long.toReadableTime(): String { val now = System.currentTimeMillis() val diff = now - this @@ -41,6 +42,32 @@ fun Long.toReadableTime(): String { } } +// Timestamp to readable format (with context for i18n) +fun Long.toReadableTime(context: Context): String { + val now = System.currentTimeMillis() + val diff = now - this + + return when { + diff < TimeUnit.MINUTES.toMillis(1) -> context.getString(R.string.time_just_now) + diff < TimeUnit.HOURS.toMillis(1) -> { + val minutes = TimeUnit.MILLISECONDS.toMinutes(diff).toInt() + context.getString(R.string.time_minutes_ago, minutes) + } + diff < TimeUnit.DAYS.toMillis(1) -> { + val hours = TimeUnit.MILLISECONDS.toHours(diff).toInt() + context.getString(R.string.time_hours_ago, hours) + } + diff < TimeUnit.DAYS.toMillis(DAYS_THRESHOLD) -> { + val days = TimeUnit.MILLISECONDS.toDays(diff).toInt() + context.getString(R.string.time_days_ago, days) + } + else -> { + val sdf = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault()) + sdf.format(Date(this)) + } + } +} + // Truncate long strings fun String.truncate(maxLength: Int): String { return if (length > maxLength) { 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 37eee56..b3ab6e5 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 @@ -2,6 +2,7 @@ package dev.dettmer.simplenotes.utils import android.app.NotificationChannel import android.app.NotificationManager +import dev.dettmer.simplenotes.R import android.app.PendingIntent import android.content.Context import android.content.Intent @@ -16,8 +17,6 @@ object NotificationHelper { private const val TAG = "NotificationHelper" private const val CHANNEL_ID = "notes_sync_channel" - private const val CHANNEL_NAME = "Notizen Synchronisierung" - private const val CHANNEL_DESCRIPTION = "Benachrichtigungen über Sync-Status" private const val NOTIFICATION_ID = 1001 private const val SYNC_NOTIFICATION_ID = 2 private const val AUTO_CANCEL_TIMEOUT_MS = 30_000L @@ -29,9 +28,11 @@ object NotificationHelper { fun createNotificationChannel(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val importance = NotificationManager.IMPORTANCE_DEFAULT + val channelName = context.getString(R.string.notification_channel_name) + val channelDescription = context.getString(R.string.notification_channel_desc) - val channel = NotificationChannel(CHANNEL_ID, CHANNEL_NAME, importance).apply { - description = CHANNEL_DESCRIPTION + val channel = NotificationChannel(CHANNEL_ID, channelName, importance).apply { + description = channelDescription enableVibration(true) enableLights(true) } @@ -68,8 +69,8 @@ object NotificationHelper { val notification = NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(android.R.drawable.ic_menu_upload) - .setContentTitle("Sync erfolgreich") - .setContentText("$syncedCount Notiz(en) synchronisiert") + .setContentTitle(context.getString(R.string.notification_sync_success_title)) + .setContentText(context.getString(R.string.notification_sync_success_message, syncedCount)) .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setContentIntent(pendingIntent) .setAutoCancel(true) @@ -96,7 +97,7 @@ object NotificationHelper { fun showSyncFailureNotification(context: Context, errorMessage: String) { val notification = NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(android.R.drawable.ic_dialog_alert) - .setContentTitle("Sync fehlgeschlagen") + .setContentTitle(context.getString(R.string.notification_sync_failed_title)) .setContentText(errorMessage) .setStyle(NotificationCompat.BigTextStyle() .bigText(errorMessage)) @@ -125,8 +126,8 @@ object NotificationHelper { fun showSyncProgressNotification(context: Context): Int { val notification = NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(android.R.drawable.ic_popup_sync) - .setContentTitle("Synchronisiere...") - .setContentText("Notizen werden synchronisiert") + .setContentTitle(context.getString(R.string.notification_sync_progress_title)) + .setContentText(context.getString(R.string.notification_sync_progress_message)) .setPriority(NotificationCompat.PRIORITY_LOW) .setOngoing(true) .setProgress(0, 0, true) @@ -161,8 +162,8 @@ object NotificationHelper { val notification = NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(android.R.drawable.ic_dialog_info) - .setContentTitle("Sync-Konflikt erkannt") - .setContentText("$conflictCount Notiz(en) haben Konflikte") + .setContentTitle(context.getString(R.string.notification_sync_conflict_title)) + .setContentText(context.getString(R.string.notification_sync_conflict_message, conflictCount)) .setPriority(NotificationCompat.PRIORITY_HIGH) .setContentIntent(pendingIntent) .setAutoCancel(true) @@ -212,8 +213,8 @@ object NotificationHelper { fun showSyncInProgress(context: Context) { val notification = NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(android.R.drawable.stat_notify_sync) - .setContentTitle("Synchronisierung läuft") - .setContentText("Notizen werden synchronisiert...") + .setContentTitle(context.getString(R.string.notification_sync_in_progress_title)) + .setContentText(context.getString(R.string.notification_sync_in_progress_message)) .setPriority(NotificationCompat.PRIORITY_LOW) .setOngoing(true) .build() @@ -240,8 +241,8 @@ object NotificationHelper { val notification = NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(android.R.drawable.stat_notify_sync) - .setContentTitle("Sync erfolgreich") - .setContentText("$count Notizen synchronisiert") + .setContentTitle(context.getString(R.string.notification_sync_success_title)) + .setContentText(context.getString(R.string.notification_sync_success_message, count)) .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setCategory(NotificationCompat.CATEGORY_STATUS) .setContentIntent(pendingIntent) // Click öffnet App @@ -271,7 +272,7 @@ object NotificationHelper { val notification = NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(android.R.drawable.stat_notify_error) - .setContentTitle("Sync Fehler") + .setContentTitle(context.getString(R.string.notification_sync_error_title)) .setContentText(message) .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setCategory(NotificationCompat.CATEGORY_ERROR) @@ -308,11 +309,10 @@ object NotificationHelper { val notification = NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(android.R.drawable.stat_notify_error) - .setContentTitle("⚠️ Sync-Warnung") - .setContentText("Server seit ${hoursSinceLastSync}h nicht erreichbar") + .setContentTitle(context.getString(R.string.notification_sync_warning_title)) + .setContentText(context.getString(R.string.notification_sync_warning_message, hoursSinceLastSync.toInt())) .setStyle(NotificationCompat.BigTextStyle() - .bigText("Der WebDAV-Server ist seit ${hoursSinceLastSync} Stunden nicht erreichbar. " + - "Bitte prüfe deine Netzwerkverbindung oder Server-Einstellungen.")) + .bigText(context.getString(R.string.notification_sync_warning_detail, hoursSinceLastSync.toInt()))) .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setCategory(NotificationCompat.CATEGORY_STATUS) .setContentIntent(pendingIntent) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/utils/UrlValidator.kt b/android/app/src/main/java/dev/dettmer/simplenotes/utils/UrlValidator.kt index 4c7410b..57fa06a 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/utils/UrlValidator.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/utils/UrlValidator.kt @@ -1,5 +1,7 @@ package dev.dettmer.simplenotes.utils +import android.content.Context +import dev.dettmer.simplenotes.R import java.net.URL /** @@ -91,7 +93,7 @@ object UrlValidator { * Validiert ob HTTP URL erlaubt ist * @return Pair - (isValid, errorMessage) */ - fun validateHttpUrl(url: String): Pair { + fun validateHttpUrl(context: Context, url: String): Pair { return try { val parsedUrl = URL(url) @@ -107,16 +109,15 @@ object UrlValidator { } else { return Pair( false, - "HTTP ist nur für lokale Server erlaubt (z.B. 192.168.x.x, 10.x.x.x, nas.local). " + - "Für öffentliche Server verwende bitte HTTPS." + context.getString(R.string.error_http_local_only) ) } } // Anderes Protokoll - Pair(false, "Ungültiges Protokoll: ${parsedUrl.protocol}. Bitte verwende HTTP oder HTTPS.") + Pair(false, context.getString(R.string.error_invalid_protocol, parsedUrl.protocol)) } catch (e: Exception) { - Pair(false, "Ungültige URL: ${e.message}") + Pair(false, context.getString(R.string.error_invalid_url, e.message ?: "")) } } } diff --git a/android/app/src/main/res/values-de/strings.xml b/android/app/src/main/res/values-de/strings.xml new file mode 100644 index 0000000..f5e5e8d --- /dev/null +++ b/android/app/src/main/res/values-de/strings.xml @@ -0,0 +1,393 @@ + + + + + + Simple Notes + + + + + Simple Notes + Noch keine Notizen.\nTippe + um eine zu erstellen. + Notiz hinzufügen + Synchronisieren + Einstellungen + Synchronisieren + Einstellungen + Auswahl beenden + Alle auswählen + Ausgewählte löschen + %d ausgewählt + + + + + Noch keine Notizen + Tippe + um eine neue Notiz zu erstellen + + + + + Neue Notiz + Text-Notiz + Checkliste + Notiz + Liste + + + + + Notiz-Titel + Notiz-Vorschau… + Vor 2 Std + Ohne Titel + %1$d/%2$d erledigt + Keine Einträge + + + + + Sync-Status + Synchronisiere… + Synchronisiert + Fehler + Synchronisiere… + Synchronisierung abgeschlossen + Synchronisierung fehlgeschlagen + Synchronisierung läuft bereits + + + + + Notiz löschen? + %d Notizen löschen? + Wie möchtest du diese Notiz löschen? + Wie möchtest du diese %d Notizen löschen? + Überall löschen (auch Server) + Nur lokal löschen + Löschen + Abbrechen + OK + + Notiz löschen + \"%s\" wird lokal gelöscht.\n\nAuch vom Server löschen? + Vom Server löschen + \"%s\" wird lokal und vom Server gelöscht + \"%s\" lokal gelöscht (Server bleibt) + + + + + RÜCKGÄNGIG + \"%s\" lokal gelöscht + \"%s\" wird vom Server gelöscht + %d Notiz(en) lokal gelöscht + %d Notiz(en) werden vom Server gelöscht + Vom Server gelöscht + Server-Löschung fehlgeschlagen + Server-Fehler: %s + Bereits synchronisiert + Server nicht erreichbar + ✅ Gesynct: %d Notizen + + + + + HTTP ist nur für lokale Server erlaubt (z.B. 192.168.x.x, 10.x.x.x, nas.local). Für öffentliche Server verwende bitte HTTPS. + Ungültiges Protokoll: %s. Bitte verwende HTTP oder HTTPS. + Ungültige URL: %s + WebDAV-Server nicht vollständig konfiguriert + Sardine Client konnte nicht erstellt werden + Server-URL nicht konfiguriert + + + + + Neue Notiz + Notiz bearbeiten + Neue Liste + Liste bearbeiten + Titel + Inhalt + Zurück + Speichern + Element hinzufügen + Neues Element… + Element verschieben + Ziehen zum Sortieren + Element löschen + Notiz ist leer + Notiz gespeichert + Notiz gelöscht + + + + + Einstellungen + Sprache + %s + Server-Einstellungen + ✅ Erreichbar + ❌ Nicht erreichbar + 🔍 Prüfe… + ⚠️ Nicht konfiguriert + Sync-Einstellungen + Auto-Sync: An • %s + Auto-Sync: Aus + 15 Min + 30 Min + 60 Min + Markdown Desktop-Integration + Auto-Sync: An + Auto-Sync: Aus + Backup & Wiederherstellung + Lokales oder Server-Backup + Über diese App + Debug & Diagnose + Logging: An + Logging: Aus + + + + + Server-Einstellungen + Server-Einstellungen + Verbindungstyp + 🏠 Intern (HTTP) + 🌐 Extern (HTTPS) + HTTP nur für lokale Netzwerke (z.B. 192.168.x.x, 10.x.x.x) + HTTPS für sichere Verbindungen über das Internet + Server-Adresse + z.B. http://192.168.0.188:8080/notes + Server URL + Benutzername + Passwort + Anzeigen + Verstecken + Server-Status: + ✅ Erreichbar + ❌ Nicht erreichbar + 🔍 Prüfe… + ⚠️ Nicht konfiguriert + ❓ Unbekannt + Verbindung testen + Jetzt synchronisieren + + + + + Sync-Einstellungen + Sync-Einstellungen + Auto-Sync aktiviert + 🔄 Auto-Sync:\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) + Auto-Sync aktiviert + Sync-Intervall + Legt fest, wie oft die App im Hintergrund synchronisiert. Kürzere Intervalle bedeuten aktuellere Daten, verbrauchen aber etwas mehr Akku.\n\n⏱️ Hinweis: Wenn dein Smartphone im Standby ist, kann Android die Synchronisation verzögern (bis zu 60 Min.), um Akku zu sparen. Das ist normal und betrifft alle Hintergrund-Apps. + ⚡ Alle 15 Minuten + Schnellste Synchronisation • ~0.8% Akku/Tag (~23 mAh) + ✓ Alle 30 Minuten (Empfohlen) + Ausgewogenes Verhältnis • ~0.4% Akku/Tag (~12 mAh) + 🔋 Alle 60 Minuten + Maximale Akkulaufzeit • ~0.2% Akku/Tag (~6 mAh geschätzt) + + ℹ️ 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) + + + + + Markdown Desktop-Integration + Markdown Auto-Sync + ✅ Export abgeschlossen + Exportiere %1$d/%2$d Notizen… + 📝 Exportiert Notizen zusätzlich als .md-Dateien. Mounte WebDAV als Netzlaufwerk um mit VS Code, Typora oder jedem Markdown-Editor zu bearbeiten. JSON-Sync bleibt primäres Format. + Markdown Auto-Sync + Synchronisiert Notizen automatisch als .md-Dateien (Upload + Download bei jedem Sync) + Manueller Sync exportiert alle Notizen als .md-Dateien und importiert .md-Dateien vom Server. Nützlich für einmalige Synchronisation. + 📝 Manueller Markdown-Sync + + + + + Backup & Wiederherstellung + Backup & Wiederherstellung + 📦 Bei jeder Wiederherstellung wird automatisch ein Sicherheits-Backup erstellt. + Lokales Backup + 💾 Backup erstellen + 📂 Aus Datei wiederherstellen + Server-Backup + ☁️ Vom Server wiederherstellen + ⚠️ Backup wiederherstellen? + Quelle: %s + Lokale Datei + WebDAV Server + Wiederherstellungs-Modus: + ⚪ Zusammenführen (Standard) + Neue hinzufügen, Bestehende behalten + ⚪ Zusammenführen (Standard)\n → Neue hinzufügen, Bestehende behalten + ⚪ Ersetzen + Alle löschen & Backup importieren + ⚪ Ersetzen\n → Alle löschen & Backup importieren + ⚪ Duplikate überschreiben + Backup gewinnt bei Konflikten + ⚪ Duplikate überschreiben\n → Backup gewinnt bei Konflikten + ℹ️ Ein Sicherheits-Backup wird vor dem Wiederherstellen automatisch erstellt. + Wiederherstellen + + ⚠️ Achtung:\n\nDie Wiederherstellung überschreibt ALLE lokalen Notizen mit den Daten vom Server. Diese Aktion kann nicht rückgängig gemacht werden! + Vom Server wiederherstellen + ⚠️ Vom Server wiederherstellen? + WARNUNG: Alle lokalen Notizen werden gelöscht und durch die Notizen vom Server ersetzt.\n\nDieser Vorgang kann nicht rückgängig gemacht werden! + Wiederherstellen + Stelle Notizen wieder her… + ✓ %d Notizen wiederhergestellt + Fehler: %s + + + + + Debug & Diagnose + Datei-Logging + Sync-Logs in Datei speichern + 🔒 Datenschutz: Logs werden nur lokal auf deinem Gerät gespeichert und niemals an externe Server gesendet. Die Logs enthalten Sync-Aktivitäten zur Fehlerdiagnose. Du kannst sie jederzeit löschen oder exportieren. + Log-Aktionen + 📤 Logs exportieren & teilen + SimpleNotes Sync Logs + Logs teilen via… + 🗑️ Logs löschen + Logs löschen? + Alle gespeicherten Sync-Logs werden unwiderruflich gelöscht. + + ℹ️ Datenschutz: Logs werden nur lokal auf deinem Gerät gespeichert und niemals an externe Server gesendet. Die Logs enthalten Sync-Aktivitäten zur Fehlerdiagnose. Du kannst sie jederzeit löschen oder exportieren. + + + + + Sprache + Systemstandard + English + Deutsch + ℹ️ Wähle deine bevorzugte Sprache. Die App wird neu gestartet, um die Änderung anzuwenden. + Sprache geändert. Neustart… + + + + + Über diese App + Simple Notes Sync + Version %1$s (%2$d) + Links + GitHub Repository + Quellcode, Issues & Dokumentation + Entwickler + GitHub Profil: @inventory69 + Lizenz + MIT License - Open Source + 🔒 Datenschutz + Diese App sammelt keine Daten. Alle Notizen werden nur lokal auf deinem Gerät und auf deinem eigenen WebDAV-Server gespeichert. Keine Telemetrie, keine Werbung. + + + + + ✅ Verbindung erfolgreich! + ❌ %s + ❌ Fehler: %s + 🔄 Synchronisiere… + ✅ Bereits synchronisiert + ✅ %d Notizen synchronisiert + ❌ %s + ✅ Auto-Sync aktiviert + Auto-Sync deaktiviert + ⏱️ Sync-Intervall: %s + 15 Minuten + 30 Minuten + 60 Minuten + ⚠️ Bitte zuerst WebDAV-Server konfigurieren + ✅ %d Notizen nach Markdown exportiert + 📝 Markdown Auto-Sync aktiviert + 📝 Markdown Auto-Sync deaktiviert + 📝 Markdown-Sync läuft… + ✅ Export: %1$d • Import: %2$d + ❌ Export fehlgeschlagen: %s + ✅ %s + ❌ Backup fehlgeschlagen: %s + ✅ %d Notizen wiederhergestellt + ❌ Wiederherstellung fehlgeschlagen: %s + Benachrichtigungen aktiviert + Benachrichtigungen deaktiviert. Du kannst sie in den Einstellungen aktivieren. + Bitte Akku-Optimierung manuell deaktivieren + 🗑️ Logs gelöscht + 📭 Keine Logs zum Löschen + ❌ Fehler beim Löschen: %s + ❌ Fehler beim Öffnen des Links + 📝 Datei-Logging aktiviert + 📝 Datei-Logging deaktiviert + ⏱️ Sync-Intervall auf %s geändert + Version nicht verfügbar + 🔍 Prüfe… + Bitte wähle \'Nicht optimieren\' für Simple Notes. + Hintergrund-Synchronisation + Damit die App im Hintergrund synchronisieren kann, muss die Akku-Optimierung deaktiviert werden.\n\nBitte wähle \'Nicht optimieren\' für Simple Notes. + Einstellungen öffnen + Später + Zurück + Ungültige Backup-Datei + Backup-Version nicht unterstützt (v%1$d benötigt v%2$d+) + Backup enthält keine Notizen + Backup enthält %d ungültige Notizen + Backup-Datei beschädigt oder ungültig: %s + Wiederherstellung fehlgeschlagen: %s + %1$d neue Notizen importiert, %2$d übersprungen + %1$d neu, %2$d überschrieben + Alle Notizen ersetzt: %d importiert + + + + + Gerade eben + Vor %d Min + Vor %d Std + Vor %d Tagen + + + + + Notizen Synchronisierung + Benachrichtigungen über Sync-Status + Sync erfolgreich + %d Notiz(en) synchronisiert + Sync fehlgeschlagen + Synchronisiere… + Notizen werden synchronisiert + Sync-Konflikt erkannt + %d Notiz(en) haben Konflikte + ⚠️ Sync-Warnung + Server seit %dh nicht erreichbar + Der WebDAV-Server ist seit %d Stunden nicht erreichbar. Bitte prüfe deine Netzwerkverbindung oder Server-Einstellungen. + Synchronisierung läuft + Notizen werden synchronisiert… + Sync Fehler + + + + + + %d Notiz + %d Notizen + + + + %d Notiz lokal gelöscht + %d Notizen lokal gelöscht + + + + %d Notiz wird vom Server gelöscht + %d Notizen werden vom Server gelöscht + + + + %d Notiz synchronisiert + %d Notizen synchronisiert + + diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index aaebe35..744688d 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -1,94 +1,394 @@ + + + + Simple Notes - - Noch keine Notizen.\nTippe + um eine zu erstellen. - Notiz hinzufügen - Synchronisieren - Einstellungen + + + + Simple Notes + No notes yet.\nTap + to create one. + Add note + Sync + Settings + Sync + Settings + Close selection + Select all + Delete selected + %d selected - + + + 📝 - Noch keine Notizen - Tippe auf ➕ um deine erste Notiz zu erstellen + No notes yet + Tap + to create a new note - - Notiz bearbeiten - Neue Notiz - Titel - Inhalt - Speichern - Löschen - Zurück + + + + New note + Text note + Checklist + Note + List - + + + Note Title Note content preview… - Vor 2 Std - Ohne Titel + 2 hours ago + Untitled + %1$d/%2$d done + No entries - - Notiz löschen? - Diese Aktion kann nicht rückgängig gemacht werden. - Abbrechen + + + + Sync Status + Syncing… + Synced + Error + Syncing… + Sync completed + Sync failed + Sync already in progress - - Server-Einstellungen + + + + Delete note? + Delete %d notes? + How do you want to delete this note? + How do you want to delete these %d notes? + Delete everywhere (also server) + Delete local only + Delete + Cancel + OK + + Delete note + \"%s\" will be deleted locally.\n\nAlso delete from server? + Delete from server + \"%s\" will be deleted locally and from server + \"%s\" deleted locally (server remains) + + + + + UNDO + \"%s\" deleted locally + \"%s\" will be deleted from server + %d note(s) deleted locally + %d note(s) will be deleted from server + Deleted from server + Server deletion failed + Server error: %s + Already synced + Server not reachable + ✅ Synced: %d notes + + + + + HTTP is only allowed for local servers (e.g. 192.168.x.x, 10.x.x.x, nas.local). For public servers, please use HTTPS. + Invalid protocol: %s. Please use HTTP or HTTPS. + Invalid URL: %s + WebDAV server not fully configured + Sardine client could not be created + Server URL not configured + + + + + New Note + Edit Note + New List + Edit List + Title + Content + Back + Save + Add item + New item… + Reorder item + Drag to reorder + Delete item + Note is empty + Note saved + Note deleted + + + + + Settings + Language + %s + Server Settings + ✅ Reachable + ❌ Not reachable + 🔍 Checking… + ⚠️ Not configured + Sync Settings + Auto-Sync: On • %s + Auto-Sync: Off + 15 min + 30 min + 60 min + Markdown Desktop Integration + Auto-Sync: On + Auto-Sync: Off + Backup & Restore + Local or server backup + About this App + Debug & Diagnostics + Logging: On + Logging: Off + + + + + Server Settings + Server Settings + Connection Type + 🏠 Internal (HTTP) + 🌐 External (HTTPS) + HTTP only for local networks (e.g. 192.168.x.x, 10.x.x.x) + HTTPS for secure connections over the internet + Server Address + e.g. http://192.168.0.188:8080/notes Server URL - Benutzername - Passwort - Server-Status: - Prüfe… - Verbindung testen - Jetzt synchronisieren + Username + Password + Show + Hide + Server Status: + ✅ Reachable + ❌ Not reachable + 🔍 Checking… + ⚠️ Not configured + ❓ Unknown + Test Connection + Sync now - - Sync-Einstellungen - Auto-Sync aktiviert - Sync-Status - ℹ️ 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) + + + + Sync Settings + Sync Settings + Auto-Sync enabled + 🔄 Auto-Sync:\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) + Auto-Sync enabled + Sync Interval + Determines how often the app syncs in the background. Shorter intervals mean more up-to-date data, but use slightly more battery.\n\n⏱️ Note: When your phone is in standby, Android may delay syncs (up to 60 min) to save battery. This is normal and affects all background apps. + ⚡ Every 15 minutes + Fastest sync • ~0.8% battery/day (~23 mAh) + ✓ Every 30 minutes (Recommended) + Balanced ratio • ~0.4% battery/day (~12 mAh) + 🔋 Every 60 minutes + Maximum battery life • ~0.2% battery/day (~6 mAh est.) + + ℹ️ 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) - - Backup & Wiederherstellung - ⚠️ Achtung:\n\nDie Wiederherstellung überschreibt ALLE lokalen Notizen mit den Daten vom Server. Diese Aktion kann nicht rückgängig gemacht werden! - Vom Server wiederherstellen - ⚠️ Vom Server wiederherstellen? - WARNUNG: Alle lokalen Notizen werden gelöscht und durch die Notizen vom Server ersetzt.\n\nDieser Vorgang kann nicht rückgängig gemacht werden! - Wiederherstellen - Stelle Notizen wieder her… - ✓ %d Notizen wiederhergestellt - Fehler: %s + + + + Markdown Desktop Integration + Markdown Auto-Sync + ✅ Export complete + Exporting %1$d/%2$d notes… + 📝 Exports notes additionally as .md files. Mount WebDAV as network drive to edit with VS Code, Typora, or any Markdown editor. JSON sync remains primary format. + Markdown Auto-Sync + Automatically syncs notes as .md files (upload + download on each sync) + Manual sync exports all notes as .md files and imports .md files from the server. Useful for one-time sync. + 📝 Manual Markdown Sync - - Synchronisiere… - Synchronisierung abgeschlossen - Synchronisierung fehlgeschlagen - Synchronisierung läuft bereits + + + + Backup & Restore + Backup & Restore + 📦 A safety backup is automatically created before each restore. + Local Backup + 💾 Create Backup + 📂 Restore from File + Server Backup + ☁️ Restore from Server + ⚠️ Restore Backup? + Source: %s + Local File + WebDAV Server + Restore Mode: + ⚪ Merge (Default) + Add new, keep existing + ⚪ Merge (Default)\n → Add new, keep existing + ⚪ Replace + Delete all & import backup + ⚪ Replace\n → Delete all & import backup + ⚪ Overwrite duplicates + Backup wins on conflicts + ⚪ Overwrite duplicates\n → Backup wins on conflicts + ℹ️ A safety backup will be automatically created before restoring. + Restore + + ⚠️ Warning:\n\nRestoring will overwrite ALL local notes with data from the server. This action cannot be undone! + Restore from Server + ⚠️ Restore from Server? + WARNING: All local notes will be deleted and replaced with notes from the server.\n\nThis action cannot be undone! + Restore + Restoring notes… + ✓ %d notes restored + Error: %s - - ℹ️ Datenschutz: Logs werden nur lokal auf deinem Gerät gespeichert und niemals an externe Server gesendet. Die Logs enthalten Sync-Aktivitäten zur Fehlerdiagnose. Du kannst sie jederzeit löschen oder exportieren. + + + + Debug & Diagnostics + File Logging + Save sync logs to file + 🔒 Privacy: Logs are only stored locally on your device and are never sent to external servers. Logs contain sync activities for troubleshooting. You can delete or export them at any time. + Log Actions + 📤 Export & Share Logs + SimpleNotes Sync Logs + Share logs via… + 🗑️ Delete Logs + Delete logs? + All saved sync logs will be permanently deleted. + + ℹ️ Privacy: Logs are only stored locally on your device and are never sent to external servers. Logs contain sync activities for troubleshooting. You can delete or export them at any time. - - - + + + + Language + System Default + English + Deutsch + ℹ️ Choose your preferred language. The app will restart to apply the change. + Language changed. Restarting… - - Notiz - Liste + + + + About this App + Simple Notes Sync + Version %1$s (%2$d) + Links + GitHub Repository + Source code, issues & documentation + Developer + GitHub Profile: @inventory69 + License + MIT License - Open Source + 🔒 Privacy + This app collects no data. All notes are stored only locally on your device and on your own WebDAV server. No telemetry, no ads. - - Neue Liste - Liste bearbeiten - Element hinzufügen - Neues Element… - Element verschieben - Ziehen zum Sortieren - Element löschen - Notiz ist leer - Notiz gespeichert - Notiz gelöscht + + + + ✅ Connection successful! + ❌ %s + ❌ Error: %s + 🔄 Syncing… + ✅ Already synced + ✅ %d notes synced + ❌ %s + ✅ Auto-Sync enabled + Auto-Sync disabled + ⏱️ Sync interval: %s + 15 minutes + 30 minutes + 60 minutes + ⚠️ Please configure WebDAV server first + ✅ %d notes exported to Markdown + 📝 Markdown Auto-Sync enabled + 📝 Markdown Auto-Sync disabled + 📝 Markdown sync running… + ✅ Export: %1$d • Import: %2$d + ❌ Export failed: %s + ✅ %s + ❌ Backup failed: %s + ✅ %d notes restored + ❌ Restore failed: %s + Notifications enabled + Notifications disabled. You can enable them in settings. + Please disable battery optimization manually + 🗑️ Logs deleted + 📭 No logs to delete + ❌ Error deleting: %s + ❌ Error opening link + 📝 File logging enabled + 📝 File logging disabled + ⏱️ Sync interval changed to %s + Version not available + 🔍 Checking… + Please select \'Not optimized\' for Simple Notes. + Background Synchronization + For the app to sync in the background, battery optimization must be disabled.\n\nPlease select \'Not optimized\' for Simple Notes. + Open Settings + Later + Back + Invalid backup file + Backup version not supported (v%1$d requires v%2$d+) + Backup contains no notes + Backup contains %d invalid notes + Backup file corrupt or invalid: %s + Restore failed: %s + %1$d new notes imported, %2$d skipped + %1$d new, %2$d overwritten + All notes replaced: %d imported - - %1$d/%2$d erledigt - Keine Einträge + + + + Just now + %d min ago + %d hours ago + %d days ago + + + + + Notes Synchronization + Notifications about sync status + Sync successful + %d note(s) synchronized + Sync failed + Syncing… + Notes are being synchronized + Sync conflict detected + %d note(s) have conflicts + ⚠️ Sync Warning + Server unreachable for %dh + The WebDAV server has been unreachable for %d hours. Please check your network connection or server settings. + Synchronization in progress + Notes are being synchronized… + Sync Error + + + + + + %d note + %d notes + + + + %d note deleted locally + %d notes deleted locally + + + + %d note will be deleted from server + %d notes will be deleted from server + + + + %d note synced + %d notes synced + diff --git a/android/app/src/main/res/xml/locales_config.xml b/android/app/src/main/res/xml/locales_config.xml new file mode 100644 index 0000000..9eb057d --- /dev/null +++ b/android/app/src/main/res/xml/locales_config.xml @@ -0,0 +1,7 @@ + + + + + + + From 67b226a5c34efb74c773f8225b71fb8b60425b53 Mon Sep 17 00:00:00 2001 From: inventory69 Date: Fri, 16 Jan 2026 16:31:30 +0100 Subject: [PATCH 06/12] feat(v1.5.0): icons, batch delete toast, cursor fix, docs refactor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FEATURES ======== Batch Delete Toast Aggregation: - New deleteMultipleNotesFromServer() method - Shows single aggregated toast instead of multiple ("3 notes deleted from server") - Partial success handling ("3 of 5 notes deleted from server") - Added string resources: snackbar_notes_deleted_from_server, snackbar_notes_deleted_from_server_partial Text Editor Cursor Fix: - Fixed cursor jumping to end after every keystroke when editing notes - Added initialCursorSet flag to only set cursor position on first load - Cursor now stays at user's position while editing - Changed LaunchedEffect(content) to LaunchedEffect(Unit) to prevent repeated resets DOCUMENTATION REFACTOR ====================== Breaking Change: English is now the default language - README.md: Now English (was German) - QUICKSTART.md: Now English (was German) - CHANGELOG.md: Now English (was mixed EN/DE) - docs/*.md: All English (was German) - German versions: Use .de.md suffix (README.de.md, QUICKSTART.de.md, etc.) Updated for v1.5.0: - CHANGELOG.md: Fully translated to English with v1.5.0 release notes - CHANGELOG.de.md: Created German version - FEATURES.md: Added i18n section, Selection Mode, Jetpack Compose updates - FEATURES.de.md: Updated with v1.5.0 features - UPCOMING.md: v1.5.0 marked as released, v1.6.0/v1.7.0 roadmap - UPCOMING.de.md: Updated German version All language headers updated: - English: [Deutsch](*.de.md) · **English** - German: **Deutsch** · [English](*.md) F-DROID METADATA ================ Changelogs (F-Droid): - fastlane/metadata/android/en-US/changelogs/13.txt: Created - fastlane/metadata/android/de-DE/changelogs/13.txt: Created Descriptions: - full_description.txt (EN/DE): Updated with v1.5.0 changes - Selection Mode instead of Swipe-to-Delete - i18n support highlighted - Jetpack Compose UI mentioned - Silent-Sync Mode added OTHER FIXES =========== Code Quality: - Unused imports removed from multiple files - maxLineLength fixes - Detekt config optimized (increased thresholds for v1.5.0) - AboutScreen: Uses app foreground icon directly - EmptyState: Shows app icon instead of emoji - themes.xml: Splash screen uses app foreground icon --- CHANGELOG.de.md | 518 ++++++++++++++++++ CHANGELOG.md | 74 ++- QUICKSTART.de.md | 269 +++++++++ QUICKSTART.en.md | 269 --------- QUICKSTART.md | 238 ++++---- README.de.md | 111 ++++ README.en.md | 109 ---- README.md | 92 ++-- .../simplenotes/ui/editor/NoteEditorScreen.kt | 14 +- .../dettmer/simplenotes/ui/main/MainScreen.kt | 2 - .../simplenotes/ui/main/MainViewModel.kt | 44 +- .../components/DeleteConfirmationDialog.kt | 2 - .../ui/main/components/EmptyState.kt | 35 +- .../ui/main/components/NoteCard.kt | 8 - .../ui/settings/SettingsViewModel.kt | 28 +- .../settings/components/SettingsComponents.kt | 1 - .../ui/settings/screens/AboutScreen.kt | 40 +- .../settings/screens/ServerSettingsScreen.kt | 6 +- .../ui/settings/screens/SettingsMainScreen.kt | 18 +- .../app/src/main/res/values-de/strings.xml | 2 + android/app/src/main/res/values/strings.xml | 2 + android/app/src/main/res/values/themes.xml | 2 +- android/config/detekt/detekt.yml | 13 +- docs/BACKUP.de.md | 324 +++++++++++ docs/BACKUP.en.md | 324 ----------- docs/BACKUP.md | 394 ++++++------- docs/DESKTOP.de.md | 505 +++++++++++++++++ docs/DESKTOP.en.md | 505 ----------------- docs/DESKTOP.md | 506 ++++++++--------- docs/{DOCS.en.md => DOCS.de.md} | 262 ++++----- docs/DOCS.md | 262 ++++----- docs/FEATURES.de.md | 305 +++++++++++ docs/FEATURES.en.md | 284 ---------- docs/FEATURES.md | 423 +++++++------- docs/TRANSLATING.de.md | 151 +++++ docs/TRANSLATING.md | 151 +++++ docs/UPCOMING.de.md | 76 +++ docs/UPCOMING.en.md | 56 -- docs/UPCOMING.md | 78 ++- .../metadata/android/de-DE/changelogs/13.txt | 8 + .../android/de-DE/full_description.txt | 17 +- .../metadata/android/en-US/changelogs/13.txt | 8 + .../android/en-US/full_description.txt | 17 +- 43 files changed, 3813 insertions(+), 2740 deletions(-) create mode 100644 CHANGELOG.de.md create mode 100644 QUICKSTART.de.md delete mode 100644 QUICKSTART.en.md create mode 100644 README.de.md delete mode 100644 README.en.md create mode 100644 docs/BACKUP.de.md delete mode 100644 docs/BACKUP.en.md create mode 100644 docs/DESKTOP.de.md delete mode 100644 docs/DESKTOP.en.md rename docs/{DOCS.en.md => DOCS.de.md} (54%) create mode 100644 docs/FEATURES.de.md delete mode 100644 docs/FEATURES.en.md create mode 100644 docs/TRANSLATING.de.md create mode 100644 docs/TRANSLATING.md create mode 100644 docs/UPCOMING.de.md delete mode 100644 docs/UPCOMING.en.md create mode 100644 fastlane/metadata/android/de-DE/changelogs/13.txt create mode 100644 fastlane/metadata/android/en-US/changelogs/13.txt diff --git a/CHANGELOG.de.md b/CHANGELOG.de.md new file mode 100644 index 0000000..aa2ce0f --- /dev/null +++ b/CHANGELOG.de.md @@ -0,0 +1,518 @@ +# Changelog + +Alle wichtigen Änderungen an Simple Notes Sync werden in dieser Datei dokumentiert. + +Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +**🌍 Sprachen:** **Deutsch** · [English](CHANGELOG.md) + +--- + +## [1.5.0] - 2026-01-15 + +### 🎉 Major: Jetpack Compose UI Redesign + +Das komplette UI wurde von XML-Views auf Jetpack Compose migriert. Die App ist jetzt moderner, schneller und flüssiger. + +### 🌍 New Feature: Internationalization (i18n) + +- **Englische Sprachunterstützung** - Alle 400+ Strings übersetzt +- **Automatische Spracherkennung** - Folgt der System-Sprache +- **Manuelle Sprachauswahl** - In den Einstellungen umschaltbar +- **Per-App Language (Android 13+)** - Native Spracheinstellung über System-Settings +- **locales_config.xml** - Vollständige Android-Integration + +### ⚙️ Modernized Settings + +- **7 kategorisierte Settings-Screens** - Übersichtlicher und intuitiver +- **Compose Navigation** - Flüssige Übergänge zwischen Screens +- **Konsistentes Design** - Material Design 3 durchgängig + +### ✨ UI Improvements + +- **Selection Mode** - Long-Press für Mehrfachauswahl statt Swipe-to-Delete +- **Batch Delete** - Mehrere Notizen gleichzeitig löschen +- **Silent-Sync Mode** - Kein Banner bei Auto-Sync (nur bei manuellem Sync) +- **App Icon in About Screen** - Hochwertige Darstellung +- **App Icon in Empty State** - Statt Emoji bei leerer Notizliste +- **Splash Screen Update** - Verwendet App-Foreground-Icon +- **Slide Animations** - Flüssige Animationen im NoteEditor + +### 🔧 Technical Improvements + +- **Jetpack Compose** - Komplette UI-Migration +- **Compose ViewModel Integration** - StateFlow für reactive UI +- **Improved Code Quality** - Detekt/Lint Warnings behoben +- **Unused Imports Cleanup** - Sauberer Codebase + +### Looking Ahead + +> 🚀 **v1.6.0** wird Server-Ordner Prüfung und weitere technische Modernisierungen bringen. +> Feature-Requests gerne als [GitHub Issue](https://github.com/inventory69/simple-notes-sync/issues) einreichen. + +--- + +## [1.4.1] - 2026-01-11 + +### Fixed + +- **🗑️ Löschen älterer Notizen (v1.2.0 Kompatibilität)** + - Notizen aus App-Version v1.2.0 oder früher werden jetzt korrekt vom Server gelöscht + - Behebt Problem bei Multi-Device-Nutzung mit älteren Notizen + +- **🔄 Checklisten-Sync Abwärtskompatibilität** + - Checklisten werden jetzt auch als Text-Fallback im `content`-Feld gespeichert + - Ältere App-Versionen (v1.3.x) zeigen Checklisten als lesbaren Text + - Format: GitHub-Style Task-Listen (`[ ] Item` / `[x] Item`) + - Recovery-Mode: Falls Checklisten-Items verloren gehen, werden sie aus dem Content wiederhergestellt + +### Improved + +- **📝 Checklisten Auto-Zeilenumbruch** + - Lange Checklisten-Texte werden jetzt automatisch umgebrochen + - Keine Begrenzung auf 3 Zeilen mehr + - Enter-Taste erstellt weiterhin ein neues Item + +### Looking Ahead + +> 🚀 **v1.5.0** wird das nächste größere Release. Wir sammeln Ideen und Feedback! +> Feature-Requests gerne als [GitHub Issue](https://github.com/inventory69/simple-notes-sync/issues) einreichen. + +--- + +## [1.4.0] - 2026-01-10 + +### 🎉 New Feature: Checklists + +- **✅ Checklist Notes** + - New note type: Checklists with tap-to-toggle items + - Add items via dedicated input field with "+" button + - Drag & drop reordering (long-press to activate) + - Swipe-to-delete items + - Visual distinction: Checked items get strikethrough styling + - Type selector when creating new notes (Text or Checklist) + +- **📝 Markdown Integration** + - Checklists export as GitHub-style task lists (`- [ ]` / `- [x]`) + - Compatible with Obsidian, Notion, and other Markdown editors + - Full round-trip: Edit in Obsidian → Sync back to app + - YAML frontmatter includes `type: checklist` for identification + +### Fixed + +- **� Markdown Parsing Robustness** + - Fixed content extraction after title (was returning empty for some formats) + - Now handles single newline after title (was requiring double newline) + - Protection: Skips import if parsed content is empty but local has content + +- **📂 Duplicate Filename Handling** + - Notes with identical titles now get unique Markdown filenames + - Format: `title_shortid.md` (e.g., `test_71540ca9.md`) + - Prevents data loss from filename collisions + +- **🔔 Notification UX** + - No sync notifications when app is in foreground + - User sees changes directly in UI - no redundant notification + - Background syncs still show notifications as expected + +### Privacy Improvements + +- **🔒 WiFi Permissions Removed** + - Removed `ACCESS_WIFI_STATE` permission + - Removed `CHANGE_WIFI_STATE` permission + - WiFi binding now works via IP detection instead of SSID matching + - Cleaned up all SSID-related code from codebase and documentation + +### Technical Improvements + +- **📦 New Data Model** + - `NoteType` enum: `TEXT`, `CHECKLIST` + - `ChecklistItem` data class with id, text, isChecked, order + - `Note.kt` extended with `noteType` and `checklistItems` fields + +- **🔄 Sync Protocol v1.4.0** + - JSON format updated to include checklist fields + - Full backward compatibility with v1.3.x notes + - Robust JSON parsing with manual field extraction + +--- + +## [1.3.2] - 2026-01-10 + +### Changed +- **🧹 Code-Qualität: "Clean Slate" Release** + - Alle einfachen Lint-Issues behoben (Phase 1-7 des Cleanup-Plans) + - Unused Imports und Members entfernt + - Magic Numbers durch benannte Konstanten ersetzt + - SwallowedExceptions mit Logger.w() versehen + - MaxLineLength-Verstöße reformatiert + - ConstructorParameterNaming (snake_case → camelCase mit @SerializedName) + - Custom Exceptions: SyncException.kt und ValidationException.kt erstellt + +### Added +- **📝 F-Droid Privacy Notice** + - Datenschutz-Hinweis für die Datei-Logging-Funktion + - Erklärt dass Logs nur lokal gespeichert werden + - Erfüllt F-Droid Opt-in Consent-Anforderungen + +### Technical Improvements +- **⚡ Neue Konstanten für bessere Wartbarkeit** + - `SYNC_COMPLETED_DELAY_MS`, `ERROR_DISPLAY_DELAY_MS` (MainActivity) + - `CONNECTION_TIMEOUT_MS` (SettingsActivity) + - `SOCKET_TIMEOUT_MS`, `MAX_FILENAME_LENGTH`, `ETAG_PREVIEW_LENGTH` (WebDavSyncService) + - `AUTO_CANCEL_TIMEOUT_MS` (NotificationHelper) + - RFC 1918 IP-Range Konstanten (UrlValidator) + - `DAYS_THRESHOLD`, `TRUNCATE_SUFFIX_LENGTH` (Extensions) + +- **🔒 @Suppress Annotations für legitime Patterns** + - ReturnCount: Frühe Returns für Validierung sind idiomatisch + - LoopWithTooManyJumpStatements: Komplexe Sync-Logik dokumentiert + +### Notes +- Komplexe Refactorings (LargeClass, LongMethod) für v1.3.3+ geplant +- Deprecation-Warnungen (LocalBroadcastManager, ProgressDialog) bleiben bestehen + +--- + +## [1.3.1] - 2026-01-08 + +### Fixed +- **🔧 Multi-Device JSON Sync (Danke an Thomas aus Bielefeld)** + - JSON-Dateien werden jetzt korrekt zwischen Geräten synchronisiert + - Funktioniert auch ohne aktiviertes Markdown + - Hybrid-Optimierung: Server-Timestamp (Primary) + E-Tag (Secondary) Checks + - E-Tag wird nach Upload gecached um Re-Download zu vermeiden + +### Performance Improvements +- **⚡ JSON Sync Performance-Parität** + - JSON-Sync erreicht jetzt gleiche Performance wie Markdown (~2-3 Sekunden) + - Timestamp-basierte Skip-Logik für unveränderte Dateien (~500ms pro Datei gespart) + - E-Tag-Matching als Fallback für Dateien die seit letztem Sync modifiziert wurden + - **Beispiel:** 24 Dateien von 12-14s auf ~2.7s reduziert (keine Änderungen) + +- **⏭️ Skip unveränderte Dateien** (Haupt-Performance-Fix!) + - JSON-Dateien: Überspringt alle Notizen, die seit letztem Sync nicht geändert wurden + - Markdown-Dateien: Überspringt unveränderte MD-Dateien basierend auf Server-Timestamp + - **Spart ~500ms pro Datei** bei Nextcloud (~20 Dateien = 10 Sekunden gespart!) + - Von 21 Sekunden Sync-Zeit auf 2-3 Sekunden reduziert + +- **⚡ Session-Caching für WebDAV** + - Sardine-Client wird pro Sync-Session wiederverwendet (~600ms gespart) + - WiFi-IP-Adresse wird gecacht statt bei jeder Anfrage neu ermittelt (~300ms gespart) + - `/notes/` Ordner-Existenz wird nur einmal pro Sync geprüft (~500ms gespart) + - **Gesamt: ~1.4 Sekunden zusätzlich gespart** + +- **📝 Content-basierte Markdown-Erkennung** + - Extern bearbeitete Markdown-Dateien werden auch erkannt wenn YAML-Timestamp nicht aktualisiert wurde + - Löst das Problem: Obsidian/Texteditor-Änderungen wurden nicht importiert + - Hybridansatz: Erst Timestamp-Check (schnell), dann Content-Vergleich (zuverlässig) + +### Added +- **🔄 Sync-Status-Anzeige (UI)** + - Sichtbares Banner "Synchronisiere..." mit ProgressBar während Sync läuft + - Sync-Button und Pull-to-Refresh werden deaktiviert während Sync aktiv + - Verhindert versehentliche Doppel-Syncs durch visuelle Rückmeldung + - Auch in Einstellungen: "Jetzt synchronisieren" Button wird deaktiviert + +### Fixed +- **🔧 Sync-Mutex verhindert doppelte Syncs** + - Keine doppelten Toast-Nachrichten mehr bei schnellem Pull-to-Refresh + - Concurrent Sync-Requests werden korrekt blockiert + +- **🐛 Lint-Fehler behoben** + - `View.generateViewId()` statt hardcodierte IDs in RadioButtons + - `app:tint` statt `android:tint` für AppCompat-Kompatibilität + +### Added +- **🔍 detekt Code-Analyse** + - Statische Code-Analyse mit detekt 1.23.4 integriert + - Pragmatische Konfiguration für Sync-intensive Codebasis + - 91 Issues identifiziert (als Baseline für v1.4.0) + +- **🏗️ Debug Build mit separatem Package** + - Debug-APK kann parallel zur Release-Version installiert werden + - Package: `dev.dettmer.simplenotes.debug` (Debug) vs `dev.dettmer.simplenotes` (Release) + - App-Name zeigt "Simple Notes (Debug)" für einfache Unterscheidung + +- **📊 Debug-Logging UI** + - Neuer "Debug Log" Button in Einstellungen → Erweitert + - Zeigt letzte Sync-Logs mit Zeitstempeln + - Export-Funktion für Fehlerberichte + +### Technical +- `WebDavSyncService`: Hybrid-Optimierung für JSON-Downloads (Timestamp PRIMARY, E-Tag SECONDARY) +- `WebDavSyncService`: E-Tag refresh nach Upload statt Invalidierung (verhindert Re-Download) +- E-Tag Caching: `SharedPreferences` mit Key-Pattern `etag_json_{noteId}` +- Skip-Logik: `if (serverModified <= lastSync) skip` → ~1ms pro Datei +- Fallback E-Tag: `if (serverETag == cachedETag) skip` → für Dateien modifiziert nach lastSync +- PROPFIND nach PUT: Fetch E-Tag nach Upload für korrektes Caching +- `SyncStateManager`: Neuer Singleton mit `StateFlow` für Sync-Status +- `MainActivity`: Observer auf `SyncStateManager.isSyncing` für UI-Updates +- Layout: `sync_status_banner` mit `ProgressBar` + `TextView` +- `WebDavSyncService`: Skip-Logik für unveränderte JSON/MD Dateien basierend auf `lastSyncTimestamp` +- `WebDavSyncService`: Neue Session-Cache-Variablen (`sessionSardine`, `sessionWifiAddress`, `notesDirEnsured`) +- `getOrCreateSardine()`: Cached Sardine-Client mit automatischer Credentials-Konfiguration +- `getOrCacheWiFiAddress()`: WiFi-Adresse wird nur einmal pro Sync ermittelt +- `clearSessionCache()`: Aufräumen am Ende jeder Sync-Session +- `ensureNotesDirectoryExists()`: Cached Directory-Check +- Content-basierter Import: Vergleicht MD-Content mit lokaler Note wenn Timestamps gleich +- Build-Tooling: detekt aktiviert, ktlint vorbereitet (deaktiviert wegen Parser-Problemen) +- Debug BuildType: `applicationIdSuffix = ".debug"`, `versionNameSuffix = "-debug"` + +--- + +## [1.3.0] - 2026-01-07 + +### Added +- **🚀 Multi-Device Sync** (Thanks to Thomas from Bielefeld for reporting!) + - Automatic download of new notes from other devices + - Deletion tracking prevents "zombie notes" (deleted notes don't come back) + - Smart cleanup: Re-created notes (newer timestamp) are downloaded + - Works with all devices: v1.2.0, v1.2.1, v1.2.2, and v1.3.0 + +- **🗑️ Server Deletion via Swipe Gesture** + - Swipe left on notes to delete from server (requires confirmation) + - Prevents duplicate notes on other devices + - Works with deletion tracking system + - Material Design confirmation dialog + +- **⚡ E-Tag Performance Optimization** + - Smart server checking with E-Tag caching (~150ms vs 3000ms for "no changes") + - 20x faster when server has no updates + - E-Tag hybrid approach: E-Tag for JSON (fast), timestamp for Markdown (reliable) + - Battery-friendly with minimal server requests + +- **📥 Markdown Auto-Sync Toggle** + - NEW: Unified Auto-Sync toggle in Settings (replaces separate Export/Auto-Import toggles) + - When enabled: Notes export to Markdown AND import changes automatically + - When disabled: Manual sync button appears for on-demand synchronization + - Performance: Auto-Sync OFF = 0ms overhead + +- **🔘 Manual Markdown Sync Button** + - Manual sync button for performance-conscious users + - Shows import/export counts after completion + - Only visible when Auto-Sync is disabled + - On-demand synchronization (~150-200ms only when triggered) + +- **⚙️ Server-Restore Modes** + - MERGE: Keep local notes + add server notes + - REPLACE: Delete all local + download from server + - OVERWRITE: Update duplicates, keep non-duplicates + - Restore modes now work correctly for WebDAV restore + +### Technical +- New `DeletionTracker` model with JSON persistence +- `NotesStorage`: Added deletion tracking methods +- `WebDavSyncService.hasUnsyncedChanges()`: Intelligent server checks with E-Tag caching +- `WebDavSyncService.downloadRemoteNotes()`: Deletion-aware downloads +- `WebDavSyncService.restoreFromServer()`: Support for restore modes +- `WebDavSyncService.deleteNoteFromServer()`: Server deletion with YAML frontmatter scanning +- `WebDavSyncService.importMarkdownFiles()`: Automatic Markdown import during sync +- `WebDavSyncService.manualMarkdownSync()`: Manual sync with result counts +- `MainActivity.setupSwipeToDelete()`: Two-stage swipe deletion with confirmation +- E-Tag caching in SharedPreferences for performance + +--- + +## [1.2.2] - 2026-01-06 + +### Fixed +- **Backward Compatibility for v1.2.0 Users (Critical)** + - App now reads BOTH old (Root) AND new (`/notes/`) folder structures + - Users upgrading from v1.2.0 no longer lose their existing notes + - Server-Restore now finds notes from v1.2.0 stored in Root folder + - Automatic deduplication prevents loading the same note twice + - Graceful error handling if Root folder is not accessible + +### Technical +- `WebDavSyncService.downloadRemoteNotes()` - Dual-mode download (Root + /notes/) +- `WebDavSyncService.restoreFromServer()` - Now uses dual-mode download +- Migration happens naturally: new uploads go to `/notes/`, old notes stay readable + +--- + +## [1.2.1] - 2026-01-05 + +### Fixed +- **Markdown Initial Export Bugfix** + - Existing notes are now exported as Markdown when Desktop Integration is activated + - Previously, only new notes created after activation were exported + - Progress dialog shows export status with current/total counter + - Error handling for network issues during export + - Individual note failures don't abort the entire export + +- **Markdown Directory Structure Fix** + - Markdown files now correctly land in `/notes-md/` folder + - Smart URL detection supports both Root-URL and `/notes` URL structures + - Previously, MD files were incorrectly placed in the root directory + - Markdown import now finds files correctly + +- **JSON URL Normalization** + - Simplified server configuration: enter only base URL (e.g., `http://server:8080/`) + - App automatically creates `/notes/` for JSON files and `/notes-md/` for Markdown + - Smart detection: both `http://server:8080/` and `http://server:8080/notes/` work correctly + - Backward compatible: existing setups with `/notes` in URL continue to work + - No migration required for existing users + +### Changed +- **Markdown Directory Creation** + - `notes-md/` folder is now created on first sync (regardless of Desktop Integration setting) + - Prevents 404 errors when mounting WebDAV folder + - Better user experience: folder is visible before enabling the feature + +- **Settings UI Improvements** + - Updated example URL from `/webdav` to `/notes` to match app behavior + - Example now shows: `http://192.168.0.188:8080/notes` + +### Technical +- `WebDavSyncService.ensureMarkdownDirectoryExists()` - Creates MD folder early +- `WebDavSyncService.getMarkdownUrl()` - Smart URL detection for both structures +- `WebDavSyncService.exportAllNotesToMarkdown()` - Exports all local notes with progress callback +- `SettingsActivity.onMarkdownExportToggled()` - Triggers initial export with ProgressDialog + +--- + +## [1.2.0] - 2026-01-04 + +### Added +- **Local Backup System** + - Export all notes as JSON file to any location (Downloads, SD card, cloud folder) + - Import backup with 3 modes: Merge, Replace, or Overwrite duplicates + - Automatic safety backup created before every restore + - Backup validation (format and version check) + +- **Markdown Desktop Integration** + - Optional Markdown export parallel to JSON sync + - `.md` files synced to `notes-md/` folder on WebDAV + - YAML frontmatter with `id`, `created`, `updated`, `device` + - Manual import button to pull Markdown changes from server + - Last-Write-Wins conflict resolution via timestamps + +- **Settings UI Extensions** + - New "Backup & Restore" section with local + server restore + - New "Desktop Integration" section with Markdown toggle + - Universal restore dialog with radio button mode selection + +### Changed +- **Server Restore Behavior**: Users now choose restore mode (Merge/Replace/Overwrite) instead of hard-coded replace-all + +### Technical +- `BackupManager.kt` - Complete backup/restore logic +- `Note.toMarkdown()` / `Note.fromMarkdown()` - Markdown conversion with YAML frontmatter +- `WebDavSyncService` - Extended for dual-format sync (JSON master + Markdown mirror) +- ISO8601 timestamp formatting for desktop compatibility +- Filename sanitization for safe Markdown file names + +### Documentation +- Added WebDAV mount instructions (Windows, macOS, Linux) +- Created [SYNC_ARCHITECTURE.md](../project-docs/simple-notes-sync/architecture/SYNC_ARCHITECTURE.md) - Complete sync documentation +- Created [MARKDOWN_DESKTOP_REALITY_CHECK.md](../project-docs/simple-notes-sync/markdown-desktop-plan/MARKDOWN_DESKTOP_REALITY_CHECK.md) - Desktop integration analysis + +--- + +## [1.1.2] - 2025-12-28 + +### Fixed +- **"Job was cancelled" Error** + - Fixed coroutine cancellation in sync worker + - Proper error handling for interrupted syncs + +- **UI Improvements** + - Back arrow instead of X in note editor (better UX) + - Pull-to-refresh for manual sync trigger + - HTTP/HTTPS protocol selection with radio buttons + - Inline error display (no toast spam) + +- **Performance & Battery** + - Sync only on actual changes (saves battery) + - Auto-save notifications removed + - 24-hour server offline warning instead of instant error + +### Changed +- Settings grouped into "Auto-Sync" and "Sync Interval" sections +- HTTP only allowed for local networks (RFC 1918 IPs) +- Swipe-to-delete without UI flicker + +--- + +## [1.1.1] - 2025-12-27 + +### Fixed +- **WiFi Connect Sync** + - No error notifications in foreign WiFi networks + - Server reachability check before sync (2s timeout) + - Silent abort when server offline + - Pre-check waits until network is ready + - No errors during network initialization + +### Changed +- **Notifications** + - Old sync notifications cleared on app start + - Error notifications auto-dismiss after 30 seconds + +### UI +- Sync icon only shown when sync is configured +- Swipe-to-delete without flicker +- Scroll to top after saving note + +### Technical +- Server check with 2-second timeout before sync attempts +- Network readiness check in WiFi connect trigger +- Notification cleanup on MainActivity.onCreate() + +--- + +## [1.1.0] - 2025-12-26 + +### Added +- **Configurable Sync Intervals** + - User choice: 15, 30, or 60 minutes + - Real-world battery impact displayed (15min: ~0.8%/day, 30min: ~0.4%/day, 60min: ~0.2%/day) + - Radio button selection in settings + - Doze Mode optimization (syncs batched in maintenance windows) + +- **About Section** + - App version from BuildConfig + - Links to GitHub repository and developer profile + - MIT license information + - Material 3 card design + +### Changed +- Settings UI redesigned with grouped sections +- Periodic sync updated dynamically when interval changes +- WorkManager uses selected interval for background sync + +### Removed +- Debug/Logs section from settings (cleaner UI) + +### Technical +- `PREF_SYNC_INTERVAL_MINUTES` preference key +- NetworkMonitor reads interval from SharedPreferences +- `ExistingPeriodicWorkPolicy.UPDATE` for live interval changes + +--- + +## [1.0.0] - 2025-12-25 + +### Added +- Initial release +- WebDAV synchronization +- Note creation, editing, deletion +- 6 sync triggers: + - Periodic sync (configurable interval) + - App start sync + - WiFi connect sync + - Manual sync (menu button) + - Pull-to-refresh + - Settings "Sync Now" button +- Material 3 design +- Light/Dark theme support +- F-Droid compatible (100% FOSS) + +--- + +[1.2.0]: https://github.com/inventory69/simple-notes-sync/releases/tag/v1.2.0 +[1.1.2]: https://github.com/inventory69/simple-notes-sync/releases/tag/v1.1.2 +[1.1.1]: https://github.com/inventory69/simple-notes-sync/releases/tag/v1.1.1 +[1.1.0]: https://github.com/inventory69/simple-notes-sync/releases/tag/v1.1.0 +[1.0.0]: https://github.com/inventory69/simple-notes-sync/releases/tag/v1.0.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index accbc72..d3621b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,33 +4,79 @@ All notable changes to Simple Notes Sync will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +**🌍 Languages:** [Deutsch](CHANGELOG.de.md) · **English** + +--- + +## [1.5.0] - 2026-01-15 + +### 🎉 Major: Jetpack Compose UI Redesign + +The complete UI has been migrated from XML Views to Jetpack Compose. The app is now more modern, faster, and smoother. + +### 🌍 New Feature: Internationalization (i18n) + +- **English language support** - All 400+ strings translated +- **Automatic language detection** - Follows system language +- **Manual language selection** - Switchable in settings +- **Per-App Language (Android 13+)** - Native language setting via system settings +- **locales_config.xml** - Complete Android integration + +### ⚙️ Modernized Settings + +- **7 categorized settings screens** - Clearer and more intuitive +- **Compose Navigation** - Smooth transitions between screens +- **Consistent design** - Material Design 3 throughout + +### ✨ UI Improvements + +- **Selection Mode** - Long-press for multi-select instead of swipe-to-delete +- **Batch Delete** - Delete multiple notes at once +- **Silent-Sync Mode** - No banner during auto-sync (only for manual sync) +- **App Icon in About Screen** - High-quality display +- **App Icon in Empty State** - Instead of emoji when note list is empty +- **Splash Screen Update** - Uses app foreground icon +- **Slide Animations** - Smooth animations in NoteEditor + +### 🔧 Technical Improvements + +- **Jetpack Compose** - Complete UI migration +- **Compose ViewModel Integration** - StateFlow for reactive UI +- **Improved Code Quality** - Detekt/Lint warnings fixed +- **Unused Imports Cleanup** - Cleaner codebase + +### Looking Ahead + +> 🚀 **v1.6.0** will bring server folder checking and further technical modernizations. +> Feature requests welcome as [GitHub Issue](https://github.com/inventory69/simple-notes-sync/issues). + --- ## [1.4.1] - 2026-01-11 ### Fixed -- **🗑️ Löschen älterer Notizen (v1.2.0 Kompatibilität)** - - Notizen aus App-Version v1.2.0 oder früher werden jetzt korrekt vom Server gelöscht - - Behebt Problem bei Multi-Device-Nutzung mit älteren Notizen +- **🗑️ Deleting older notes (v1.2.0 compatibility)** + - Notes from app version v1.2.0 or earlier are now correctly deleted from the server + - Fixes issue with multi-device usage with older notes -- **🔄 Checklisten-Sync Abwärtskompatibilität** - - Checklisten werden jetzt auch als Text-Fallback im `content`-Feld gespeichert - - Ältere App-Versionen (v1.3.x) zeigen Checklisten als lesbaren Text - - Format: GitHub-Style Task-Listen (`[ ] Item` / `[x] Item`) - - Recovery-Mode: Falls Checklisten-Items verloren gehen, werden sie aus dem Content wiederhergestellt +- **🔄 Checklist sync backward compatibility** + - Checklists now also saved as text fallback in the `content` field + - Older app versions (v1.3.x) display checklists as readable text + - Format: GitHub-style task lists (`[ ] Item` / `[x] Item`) + - Recovery mode: If checklist items are lost, they are recovered from content ### Improved -- **📝 Checklisten Auto-Zeilenumbruch** - - Lange Checklisten-Texte werden jetzt automatisch umgebrochen - - Keine Begrenzung auf 3 Zeilen mehr - - Enter-Taste erstellt weiterhin ein neues Item +- **📝 Checklist auto line-wrap** + - Long checklist texts now automatically wrap + - No more limit to 3 lines + - Enter key still creates a new item ### Looking Ahead -> 🚀 **v1.5.0** wird das nächste größere Release. Wir sammeln Ideen und Feedback! -> Feature-Requests gerne als [GitHub Issue](https://github.com/inventory69/simple-notes-sync/issues) einreichen. +> 🚀 **v1.5.0** will be the next major release. We're collecting ideas and feedback! +> Feature requests welcome as [GitHub Issue](https://github.com/inventory69/simple-notes-sync/issues). --- diff --git a/QUICKSTART.de.md b/QUICKSTART.de.md new file mode 100644 index 0000000..c6ac210 --- /dev/null +++ b/QUICKSTART.de.md @@ -0,0 +1,269 @@ +# Quick Start Guide - Simple Notes Sync 📝 + +> Schritt-für-Schritt Anleitung zur Installation und Einrichtung + +**🌍 Sprachen:** **Deutsch** · [English](QUICKSTART.md) + +--- + +## Voraussetzungen + +- ✅ Android 8.0+ Smartphone/Tablet +- ✅ WLAN-Verbindung +- ✅ Eigener Server mit Docker (optional - für Self-Hosting) + +--- + +## Option 1: Mit eigenem Server (Self-Hosted) 🏠 + +### Schritt 1: WebDAV Server einrichten + +Auf deinem Server (z.B. Raspberry Pi, NAS, VPS): + +```bash +# Repository klonen +git clone https://github.com/inventory69/simple-notes-sync.git +cd simple-notes-sync/server + +# Umgebungsvariablen konfigurieren +cp .env.example .env +nano .env +``` + +**In `.env` anpassen:** +```env +WEBDAV_PASSWORD=dein-sicheres-passwort-hier +``` + +**Server starten:** +```bash +docker compose up -d +``` + +**IP-Adresse finden:** +```bash +ip addr show | grep "inet " | grep -v 127.0.0.1 +``` + +➡️ **Notiere dir:** `http://DEINE-SERVER-IP:8080/` + +--- + +### Schritt 2: App installieren + +1. **APK herunterladen:** [Neueste Version](https://github.com/inventory69/simple-notes-sync/releases/latest) + - Wähle: `simple-notes-sync-vX.X.X-standard-universal.apk` + +2. **Installation erlauben:** + - Android: Einstellungen → Sicherheit → "Unbekannte Quellen" für deinen Browser aktivieren + +3. **APK öffnen und installieren** + +--- + +### Schritt 3: App konfigurieren + +1. **App öffnen** + +2. **Einstellungen öffnen** (⚙️ Icon oben rechts) + +3. **Server-Einstellungen konfigurieren:** + + | Feld | Wert | + |------|------| + | **WebDAV Server URL** | `http://DEINE-SERVER-IP:8080/` | + | **Benutzername** | `noteuser` | + | **Passwort** | (dein Passwort aus `.env`) | + + > **💡 Hinweis:** Gib nur die Base-URL ein (ohne `/notes`). Die App erstellt automatisch `/notes/` für JSON-Dateien und `/notes-md/` für Markdown-Export. + +4. **"Verbindung testen"** drücken + - ✅ Erfolg? → Weiter zu Schritt 4 + - ❌ Fehler? → Siehe [Troubleshooting](#troubleshooting) + +5. **Auto-Sync aktivieren** (Toggle Switch) + +6. **Sync-Intervall wählen:** + - **15 Min** - Maximale Aktualität (~0.8% Akku/Tag) + - **30 Min** - Empfohlen (~0.4% Akku/Tag) ⭐ + - **60 Min** - Maximale Akkulaufzeit (~0.2% Akku/Tag) + +--- + +### Schritt 4: Erste Notiz erstellen + +1. Zurück zur Hauptansicht (← Pfeil) + +2. **"Notiz hinzufügen"** (+ Icon) + +3. Titel und Text eingeben + +4. **Speichern** (💾 Icon) + +5. **Warten auf Auto-Sync** (oder manuell: ⚙️ → "Jetzt synchronisieren") + +🎉 **Fertig!** Deine Notizen werden automatisch synchronisiert! + +--- + +## Option 2: Nur lokale Notizen (kein Server) 📱 + +Du kannst Simple Notes auch **ohne Server** nutzen: + +1. **App installieren** (siehe Schritt 2 oben) + +2. **Ohne Server-Konfiguration verwenden:** + - Notizen werden nur lokal gespeichert + - Kein Auto-Sync + - Perfekt für reine Offline-Nutzung + +--- + +## 🔋 Akku-Optimierung deaktivieren + +Für zuverlässigen Auto-Sync: + +1. **Einstellungen** → **Apps** → **Simple Notes Sync** + +2. **Akku** → **Akkuverbrauch** + +3. Wähle: **"Nicht optimieren"** oder **"Unbeschränkt"** + +💡 **Hinweis:** Android Doze Mode kann trotzdem Sync im Standby verzögern (~60 Min). Das ist normal und betrifft alle Apps. + +--- + +## 📊 Sync-Intervalle im Detail + +| Intervall | Syncs/Tag | Akku/Tag | Akku/Sync | Anwendungsfall | +|-----------|-----------|----------|-----------|----------------| +| **15 Min** | ~96 | ~0.8% (~23 mAh) | ~0.008% | ⚡ Maximal aktuell (mehrere Geräte) | +| **30 Min** | ~48 | ~0.4% (~12 mAh) | ~0.008% | ✓ **Empfohlen** - ausgewogen | +| **60 Min** | ~24 | ~0.2% (~6 mAh) | ~0.008% | 🔋 Maximale Akkulaufzeit | + +--- + +## 🐛 Troubleshooting + +### Verbindungstest schlägt fehl + +**Problem:** "Verbindung fehlgeschlagen" beim Test + +**Lösungen:** + +1. **Server läuft?** + ```bash + docker compose ps + # Sollte "Up" zeigen + ``` + +2. **Gleiches Netzwerk?** + - Smartphone und Server müssen im selben Netzwerk sein + +3. **IP-Adresse korrekt?** + ```bash + ip addr show | grep "inet " + # Prüfe ob IP in URL stimmt + ``` + +4. **Firewall?** + ```bash + # Port 8080 öffnen (falls Firewall aktiv) + sudo ufw allow 8080/tcp + ``` + +5. **Server-Logs prüfen:** + ```bash + docker compose logs -f + ``` + +--- + +### Auto-Sync funktioniert nicht + +**Problem:** Notizen werden nicht automatisch synchronisiert + +**Lösungen:** + +1. **Auto-Sync aktiviert?** + - ⚙️ Einstellungen → Toggle "Auto-Sync" muss **AN** sein + +2. **Akku-Optimierung deaktiviert?** + - Siehe [Akku-Optimierung](#-akku-optimierung-deaktivieren) + +3. **Mit WiFi verbunden?** + - Auto-Sync triggert bei jeder WiFi-Verbindung + - Prüfe, ob du mit einem WLAN verbunden bist + +4. **Manuell testen:** + - ⚙️ Einstellungen → "Jetzt synchronisieren" + - Funktioniert das? → Auto-Sync sollte auch funktionieren + +--- + +### Notizen werden nicht angezeigt + +**Problem:** Nach Installation sind keine Notizen da, obwohl welche auf dem Server liegen + +**Lösung:** + +1. **Einmalig manuell synchronisieren:** + - ⚙️ Einstellungen → "Jetzt synchronisieren" + +2. **Server-Daten prüfen:** + ```bash + docker compose exec webdav ls -la /data/ + # Sollte .json Dateien zeigen + ``` + +--- + +### Fehler beim Sync + +**Problem:** Fehlermeldung beim Synchronisieren + +**Lösungen:** + +1. **"401 Unauthorized"** → Passwort falsch + - Prüfe Passwort in App-Einstellungen + - Vergleiche mit `.env` auf Server + +2. **"404 Not Found"** → URL falsch + - Sollte enden mit `/` (z.B. `http://192.168.1.100:8080/`) + +3. **"Network error"** → Keine Verbindung + - Siehe [Verbindungstest schlägt fehl](#verbindungstest-schlägt-fehl) + +--- + +## 📱 Updates + +### Automatisch mit Obtainium (empfohlen) + +1. **[Obtainium installieren](https://github.com/ImranR98/Obtanium/releases/latest)** + +2. **App hinzufügen:** + - URL: `https://github.com/inventory69/simple-notes-sync` + - Auto-Update aktivieren + +3. **Fertig!** Obtainium benachrichtigt dich bei neuen Versionen + +### Manuell + +1. Neue APK von [Releases](https://github.com/inventory69/simple-notes-sync/releases/latest) herunterladen + +2. Installieren (überschreibt alte Version) + +3. Alle Daten bleiben erhalten! + +--- + +## 🆘 Weitere Hilfe + +- **GitHub Issues:** [Problem melden](https://github.com/inventory69/simple-notes-sync/issues) +- **Vollständige Docs:** [DOCS.md](DOCS.md) +- **Server Setup Details:** [server/README.md](server/README.md) + +--- + +**Version:** 1.1.0 · **Erstellt:** Dezember 2025 diff --git a/QUICKSTART.en.md b/QUICKSTART.en.md deleted file mode 100644 index 43128bd..0000000 --- a/QUICKSTART.en.md +++ /dev/null @@ -1,269 +0,0 @@ -# Quick Start Guide - Simple Notes Sync 📝 - -> Step-by-step installation and setup guide - -**🌍 Languages:** [Deutsch](QUICKSTART.md) · **English** - ---- - -## Prerequisites - -- ✅ Android 8.0+ smartphone/tablet -- ✅ WiFi connection -- ✅ Own server with Docker (optional - for self-hosting) - ---- - -## Option 1: With own server (Self-Hosted) 🏠 - -### Step 1: Setup WebDAV Server - -On your server (e.g. Raspberry Pi, NAS, VPS): - -```bash -# Clone repository -git clone https://github.com/inventory69/simple-notes-sync.git -cd simple-notes-sync/server - -# Configure environment variables -cp .env.example .env -nano .env -``` - -**Adjust in `.env`:** -```env -WEBDAV_PASSWORD=your-secure-password-here -``` - -**Start server:** -```bash -docker compose up -d -``` - -**Find IP address:** -```bash -ip addr show | grep "inet " | grep -v 127.0.0.1 -``` - -➡️ **Note down:** `http://YOUR-SERVER-IP:8080/` - ---- - -### Step 2: Install App - -1. **Download APK:** [Latest version](https://github.com/inventory69/simple-notes-sync/releases/latest) - - Choose: `simple-notes-sync-vX.X.X-standard-universal.apk` - -2. **Allow installation:** - - Android: Settings → Security → Enable "Unknown sources" for your browser - -3. **Open and install APK** - ---- - -### Step 3: Configure App - -1. **Open app** - -2. **Open settings** (⚙️ icon top right) - -3. **Configure server settings:** - - | Field | Value | - |------|------| - | **WebDAV Server URL** | `http://YOUR-SERVER-IP:8080/` | - | **Username** | `noteuser` | - | **Password** | (your password from `.env`) | - - > **💡 Note:** Enter only the base URL (without `/notes`). The app automatically creates `/notes/` for JSON files and `/notes-md/` for Markdown export. - -4. **Press "Test connection"**** - - ✅ Success? → Continue to step 4 - - ❌ Error? → See [Troubleshooting](#troubleshooting) - -5. **Enable auto-sync** (toggle switch) - -6. **Choose sync interval:** - - **15 min** - Maximum currency (~0.8% battery/day) - - **30 min** - Recommended (~0.4% battery/day) ⭐ - - **60 min** - Maximum battery life (~0.2% battery/day) - ---- - -### Step 4: Create First Note - -1. Back to main view (← arrow) - -2. **"Add note"** (+ icon) - -3. Enter title and text - -4. **Save** (💾 icon) - -5. **Wait for auto-sync** (or manually: ⚙️ → "Sync now") - -🎉 **Done!** Your notes will be automatically synchronized! - ---- - -## Option 2: Local notes only (no server) 📱 - -You can also use Simple Notes **without a server**: - -1. **Install app** (see step 2 above) - -2. **Use without server configuration:** - - Notes are only stored locally - - No auto-sync - - Perfect for offline-only use - ---- - -## 🔋 Disable Battery Optimization - -For reliable auto-sync: - -1. **Settings** → **Apps** → **Simple Notes Sync** - -2. **Battery** → **Battery usage** - -3. Select: **"Don't optimize"** or **"Unrestricted"** - -💡 **Note:** Android Doze Mode may still delay sync in standby (~60 min). This is normal and affects all apps. - ---- - -## 📊 Sync Intervals in Detail - -| Interval | Syncs/day | Battery/day | Battery/sync | Use case | -|-----------|-----------|----------|-----------|----------------| -| **15 min** | ~96 | ~0.8% (~23 mAh) | ~0.008% | ⚡ Maximum currency (multiple devices) | -| **30 min** | ~48 | ~0.4% (~12 mAh) | ~0.008% | ✓ **Recommended** - balanced | -| **60 min** | ~24 | ~0.2% (~6 mAh) | ~0.008% | 🔋 Maximum battery life | - ---- - -## 🐛 Troubleshooting - -### Connection test fails - -**Problem:** "Connection failed" during test - -**Solutions:** - -1. **Server running?** - ```bash - docker compose ps - # Should show "Up" - ``` - -2. **Same network?** - - Smartphone and server must be on same network - -3. **IP address correct?** - ```bash - ip addr show | grep "inet " - # Check if IP in URL matches - ``` - -4. **Firewall?** - ```bash - # Open port 8080 (if firewall active) - sudo ufw allow 8080/tcp - ``` - -5. **Check server logs:** - ```bash - docker compose logs -f - ``` - ---- - -### Auto-sync not working - -**Problem:** Notes are not automatically synchronized - -**Solutions:** - -1. **Auto-sync enabled?** - - ⚙️ Settings → Toggle "Auto-sync" must be **ON** - -2. **Battery optimization disabled?** - - See [Disable Battery Optimization](#-disable-battery-optimization) - -3. **Connected to WiFi?** - - Auto-sync triggers on any WiFi connection - - Check if you're connected to a WiFi network - -4. **Test manually:** - - ⚙️ Settings → "Sync now" - - Works? → Auto-sync should work too - ---- - -### Notes not showing up - -**Problem:** After installation, no notes visible even though they exist on server - -**Solution:** - -1. **Manually sync once:** - - ⚙️ Settings → "Sync now" - -2. **Check server data:** - ```bash - docker compose exec webdav ls -la /data/ - # Should show .json files - ``` - ---- - -### Sync errors - -**Problem:** Error message during sync - -**Solutions:** - -1. **"401 Unauthorized"** → Wrong password - - Check password in app settings - - Compare with `.env` on server - -2. **"404 Not Found"** → Wrong URL - - Should end with `/` (e.g. `http://192.168.1.100:8080/`) - -3. **"Network error"** → No connection - - See [Connection test fails](#connection-test-fails) - ---- - -## 📱 Updates - -### Automatic with Obtainium (recommended) - -1. **[Install Obtainium](https://github.com/ImranR98/Obtanium/releases/latest)** - -2. **Add app:** - - URL: `https://github.com/inventory69/simple-notes-sync` - - Enable auto-update - -3. **Done!** Obtainium notifies you of new versions - -### Manual - -1. Download new APK from [Releases](https://github.com/inventory69/simple-notes-sync/releases/latest) - -2. Install (overwrites old version) - -3. All data remains intact! - ---- - -## 🆘 Further Help - -- **GitHub Issues:** [Report problem](https://github.com/inventory69/simple-notes-sync/issues) -- **Complete docs:** [DOCS.en.md](DOCS.en.md) -- **Server setup details:** [server/README.en.md](server/README.en.md) - ---- - -**Version:** 1.1.0 · **Created:** December 2025 diff --git a/QUICKSTART.md b/QUICKSTART.md index ead0005..4010d1b 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -1,269 +1,269 @@ # Quick Start Guide - Simple Notes Sync 📝 -> Schritt-für-Schritt Anleitung zur Installation und Einrichtung +> Step-by-step installation and setup guide -**🌍 Sprachen:** **Deutsch** · [English](QUICKSTART.en.md) +**🌍 Languages:** [Deutsch](QUICKSTART.de.md) · **English** --- -## Voraussetzungen +## Prerequisites -- ✅ Android 8.0+ Smartphone/Tablet -- ✅ WLAN-Verbindung -- ✅ Eigener Server mit Docker (optional - für Self-Hosting) +- ✅ Android 8.0+ smartphone/tablet +- ✅ WiFi connection +- ✅ Own server with Docker (optional - for self-hosting) --- -## Option 1: Mit eigenem Server (Self-Hosted) 🏠 +## Option 1: With own server (Self-Hosted) 🏠 -### Schritt 1: WebDAV Server einrichten +### Step 1: Setup WebDAV Server -Auf deinem Server (z.B. Raspberry Pi, NAS, VPS): +On your server (e.g. Raspberry Pi, NAS, VPS): ```bash -# Repository klonen +# Clone repository git clone https://github.com/inventory69/simple-notes-sync.git cd simple-notes-sync/server -# Umgebungsvariablen konfigurieren +# Configure environment variables cp .env.example .env nano .env ``` -**In `.env` anpassen:** +**Adjust in `.env`:** ```env -WEBDAV_PASSWORD=dein-sicheres-passwort-hier +WEBDAV_PASSWORD=your-secure-password-here ``` -**Server starten:** +**Start server:** ```bash docker compose up -d ``` -**IP-Adresse finden:** +**Find IP address:** ```bash ip addr show | grep "inet " | grep -v 127.0.0.1 ``` -➡️ **Notiere dir:** `http://DEINE-SERVER-IP:8080/` +➡️ **Note down:** `http://YOUR-SERVER-IP:8080/` --- -### Schritt 2: App installieren +### Step 2: Install App -1. **APK herunterladen:** [Neueste Version](https://github.com/inventory69/simple-notes-sync/releases/latest) - - Wähle: `simple-notes-sync-vX.X.X-standard-universal.apk` +1. **Download APK:** [Latest version](https://github.com/inventory69/simple-notes-sync/releases/latest) + - Choose: `simple-notes-sync-vX.X.X-standard-universal.apk` -2. **Installation erlauben:** - - Android: Einstellungen → Sicherheit → "Unbekannte Quellen" für deinen Browser aktivieren +2. **Allow installation:** + - Android: Settings → Security → Enable "Unknown sources" for your browser -3. **APK öffnen und installieren** +3. **Open and install APK** --- -### Schritt 3: App konfigurieren +### Step 3: Configure App -1. **App öffnen** +1. **Open app** -2. **Einstellungen öffnen** (⚙️ Icon oben rechts) +2. **Open settings** (⚙️ icon top right) -3. **Server-Einstellungen konfigurieren:** +3. **Configure server settings:** - | Feld | Wert | + | Field | Value | |------|------| - | **WebDAV Server URL** | `http://DEINE-SERVER-IP:8080/` | - | **Benutzername** | `noteuser` | - | **Passwort** | (dein Passwort aus `.env`) | + | **WebDAV Server URL** | `http://YOUR-SERVER-IP:8080/` | + | **Username** | `noteuser` | + | **Password** | (your password from `.env`) | - > **💡 Hinweis:** Gib nur die Base-URL ein (ohne `/notes`). Die App erstellt automatisch `/notes/` für JSON-Dateien und `/notes-md/` für Markdown-Export. + > **💡 Note:** Enter only the base URL (without `/notes`). The app automatically creates `/notes/` for JSON files and `/notes-md/` for Markdown export. -4. **"Verbindung testen"** drücken - - ✅ Erfolg? → Weiter zu Schritt 4 - - ❌ Fehler? → Siehe [Troubleshooting](#troubleshooting) +4. **Press "Test connection"**** + - ✅ Success? → Continue to step 4 + - ❌ Error? → See [Troubleshooting](#troubleshooting) -5. **Auto-Sync aktivieren** (Toggle Switch) +5. **Enable auto-sync** (toggle switch) -6. **Sync-Intervall wählen:** - - **15 Min** - Maximale Aktualität (~0.8% Akku/Tag) - - **30 Min** - Empfohlen (~0.4% Akku/Tag) ⭐ - - **60 Min** - Maximale Akkulaufzeit (~0.2% Akku/Tag) +6. **Choose sync interval:** + - **15 min** - Maximum currency (~0.8% battery/day) + - **30 min** - Recommended (~0.4% battery/day) ⭐ + - **60 min** - Maximum battery life (~0.2% battery/day) --- -### Schritt 4: Erste Notiz erstellen +### Step 4: Create First Note -1. Zurück zur Hauptansicht (← Pfeil) +1. Back to main view (← arrow) -2. **"Notiz hinzufügen"** (+ Icon) +2. **"Add note"** (+ icon) -3. Titel und Text eingeben +3. Enter title and text -4. **Speichern** (💾 Icon) +4. **Save** (💾 icon) -5. **Warten auf Auto-Sync** (oder manuell: ⚙️ → "Jetzt synchronisieren") +5. **Wait for auto-sync** (or manually: ⚙️ → "Sync now") -🎉 **Fertig!** Deine Notizen werden automatisch synchronisiert! +🎉 **Done!** Your notes will be automatically synchronized! --- -## Option 2: Nur lokale Notizen (kein Server) 📱 +## Option 2: Local notes only (no server) 📱 -Du kannst Simple Notes auch **ohne Server** nutzen: +You can also use Simple Notes **without a server**: -1. **App installieren** (siehe Schritt 2 oben) +1. **Install app** (see step 2 above) -2. **Ohne Server-Konfiguration verwenden:** - - Notizen werden nur lokal gespeichert - - Kein Auto-Sync - - Perfekt für reine Offline-Nutzung +2. **Use without server configuration:** + - Notes are only stored locally + - No auto-sync + - Perfect for offline-only use --- -## 🔋 Akku-Optimierung deaktivieren +## 🔋 Disable Battery Optimization -Für zuverlässigen Auto-Sync: +For reliable auto-sync: -1. **Einstellungen** → **Apps** → **Simple Notes Sync** +1. **Settings** → **Apps** → **Simple Notes Sync** -2. **Akku** → **Akkuverbrauch** +2. **Battery** → **Battery usage** -3. Wähle: **"Nicht optimieren"** oder **"Unbeschränkt"** +3. Select: **"Don't optimize"** or **"Unrestricted"** -💡 **Hinweis:** Android Doze Mode kann trotzdem Sync im Standby verzögern (~60 Min). Das ist normal und betrifft alle Apps. +💡 **Note:** Android Doze Mode may still delay sync in standby (~60 min). This is normal and affects all apps. --- -## 📊 Sync-Intervalle im Detail +## 📊 Sync Intervals in Detail -| Intervall | Syncs/Tag | Akku/Tag | Akku/Sync | Anwendungsfall | +| Interval | Syncs/day | Battery/day | Battery/sync | Use case | |-----------|-----------|----------|-----------|----------------| -| **15 Min** | ~96 | ~0.8% (~23 mAh) | ~0.008% | ⚡ Maximal aktuell (mehrere Geräte) | -| **30 Min** | ~48 | ~0.4% (~12 mAh) | ~0.008% | ✓ **Empfohlen** - ausgewogen | -| **60 Min** | ~24 | ~0.2% (~6 mAh) | ~0.008% | 🔋 Maximale Akkulaufzeit | +| **15 min** | ~96 | ~0.8% (~23 mAh) | ~0.008% | ⚡ Maximum currency (multiple devices) | +| **30 min** | ~48 | ~0.4% (~12 mAh) | ~0.008% | ✓ **Recommended** - balanced | +| **60 min** | ~24 | ~0.2% (~6 mAh) | ~0.008% | 🔋 Maximum battery life | --- ## 🐛 Troubleshooting -### Verbindungstest schlägt fehl +### Connection test fails -**Problem:** "Verbindung fehlgeschlagen" beim Test +**Problem:** "Connection failed" during test -**Lösungen:** +**Solutions:** -1. **Server läuft?** +1. **Server running?** ```bash docker compose ps - # Sollte "Up" zeigen + # Should show "Up" ``` -2. **Gleiches Netzwerk?** - - Smartphone und Server müssen im selben Netzwerk sein +2. **Same network?** + - Smartphone and server must be on same network -3. **IP-Adresse korrekt?** +3. **IP address correct?** ```bash ip addr show | grep "inet " - # Prüfe ob IP in URL stimmt + # Check if IP in URL matches ``` 4. **Firewall?** ```bash - # Port 8080 öffnen (falls Firewall aktiv) + # Open port 8080 (if firewall active) sudo ufw allow 8080/tcp ``` -5. **Server-Logs prüfen:** +5. **Check server logs:** ```bash docker compose logs -f ``` --- -### Auto-Sync funktioniert nicht +### Auto-sync not working -**Problem:** Notizen werden nicht automatisch synchronisiert +**Problem:** Notes are not automatically synchronized -**Lösungen:** +**Solutions:** -1. **Auto-Sync aktiviert?** - - ⚙️ Einstellungen → Toggle "Auto-Sync" muss **AN** sein +1. **Auto-sync enabled?** + - ⚙️ Settings → Toggle "Auto-sync" must be **ON** -2. **Akku-Optimierung deaktiviert?** - - Siehe [Akku-Optimierung](#-akku-optimierung-deaktivieren) +2. **Battery optimization disabled?** + - See [Disable Battery Optimization](#-disable-battery-optimization) -3. **Mit WiFi verbunden?** - - Auto-Sync triggert bei jeder WiFi-Verbindung - - Prüfe, ob du mit einem WLAN verbunden bist +3. **Connected to WiFi?** + - Auto-sync triggers on any WiFi connection + - Check if you're connected to a WiFi network -4. **Manuell testen:** - - ⚙️ Einstellungen → "Jetzt synchronisieren" - - Funktioniert das? → Auto-Sync sollte auch funktionieren +4. **Test manually:** + - ⚙️ Settings → "Sync now" + - Works? → Auto-sync should work too --- -### Notizen werden nicht angezeigt +### Notes not showing up -**Problem:** Nach Installation sind keine Notizen da, obwohl welche auf dem Server liegen +**Problem:** After installation, no notes visible even though they exist on server -**Lösung:** +**Solution:** -1. **Einmalig manuell synchronisieren:** - - ⚙️ Einstellungen → "Jetzt synchronisieren" +1. **Manually sync once:** + - ⚙️ Settings → "Sync now" -2. **Server-Daten prüfen:** +2. **Check server data:** ```bash docker compose exec webdav ls -la /data/ - # Sollte .json Dateien zeigen + # Should show .json files ``` --- -### Fehler beim Sync +### Sync errors -**Problem:** Fehlermeldung beim Synchronisieren +**Problem:** Error message during sync -**Lösungen:** +**Solutions:** -1. **"401 Unauthorized"** → Passwort falsch - - Prüfe Passwort in App-Einstellungen - - Vergleiche mit `.env` auf Server +1. **"401 Unauthorized"** → Wrong password + - Check password in app settings + - Compare with `.env` on server -2. **"404 Not Found"** → URL falsch - - Sollte enden mit `/` (z.B. `http://192.168.1.100:8080/`) +2. **"404 Not Found"** → Wrong URL + - Should end with `/` (e.g. `http://192.168.1.100:8080/`) -3. **"Network error"** → Keine Verbindung - - Siehe [Verbindungstest schlägt fehl](#verbindungstest-schlägt-fehl) +3. **"Network error"** → No connection + - See [Connection test fails](#connection-test-fails) --- ## 📱 Updates -### Automatisch mit Obtainium (empfohlen) +### Automatic with Obtainium (recommended) -1. **[Obtainium installieren](https://github.com/ImranR98/Obtanium/releases/latest)** +1. **[Install Obtainium](https://github.com/ImranR98/Obtanium/releases/latest)** -2. **App hinzufügen:** +2. **Add app:** - URL: `https://github.com/inventory69/simple-notes-sync` - - Auto-Update aktivieren + - Enable auto-update -3. **Fertig!** Obtainium benachrichtigt dich bei neuen Versionen +3. **Done!** Obtainium notifies you of new versions -### Manuell +### Manual -1. Neue APK von [Releases](https://github.com/inventory69/simple-notes-sync/releases/latest) herunterladen +1. Download new APK from [Releases](https://github.com/inventory69/simple-notes-sync/releases/latest) -2. Installieren (überschreibt alte Version) +2. Install (overwrites old version) -3. Alle Daten bleiben erhalten! +3. All data remains intact! --- -## 🆘 Weitere Hilfe +## 🆘 Further Help -- **GitHub Issues:** [Problem melden](https://github.com/inventory69/simple-notes-sync/issues) -- **Vollständige Docs:** [DOCS.md](DOCS.md) -- **Server Setup Details:** [server/README.md](server/README.md) +- **GitHub Issues:** [Report problem](https://github.com/inventory69/simple-notes-sync/issues) +- **Complete docs:** [DOCS.en.md](DOCS.en.md) +- **Server setup details:** [server/README.en.md](server/README.en.md) --- -**Version:** 1.1.0 · **Erstellt:** Dezember 2025 +**Version:** 1.1.0 · **Created:** December 2025 diff --git a/README.de.md b/README.de.md new file mode 100644 index 0000000..15b92b9 --- /dev/null +++ b/README.de.md @@ -0,0 +1,111 @@ +# Simple Notes Sync 📝 + +> Minimalistische Offline-Notizen mit Auto-Sync zu deinem eigenen Server + +[![Android](https://img.shields.io/badge/Android-8.0%2B-green.svg)](https://www.android.com/) +[![Material Design 3](https://img.shields.io/badge/Material-Design%203-green.svg)](https://m3.material.io/) +[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) + +[Get it on IzzyOnDroid](https://apt.izzysoft.de/fdroid/index/apk/dev.dettmer.simplenotes) + +**📱 [APK Download](https://github.com/inventory69/simple-notes-sync/releases/latest)** · **📖 [Dokumentation](docs/DOCS.de.md)** · **🚀 [Quick Start](QUICKSTART.de.md)** + +**🌍 Sprachen:** **Deutsch** · [English](README.md) + +--- + +## 📱 Screenshots + +

+ Notizliste + Notiz bearbeiten + Einstellungen +

+ +--- + +## ✨ Highlights + +- ✅ **NEU: Checklisten** - Tap-to-Check, Drag & Drop +- 🌍 **NEU: Mehrsprachig** - Deutsch/Englisch mit Sprachauswahl +- 📝 **Offline-First** - Funktioniert ohne Internet +- 🔄 **Auto-Sync** - Bei WiFi-Verbindung (15/30/60 Min) +- 🔒 **Self-Hosted** - Deine Daten bleiben bei dir (WebDAV) +- 💾 **Lokales Backup** - Export/Import als JSON-Datei +- 🖥️ **Desktop-Integration** - Markdown-Export für Obsidian, VS Code, Typora +- 🔋 **Akkuschonend** - ~0.2-0.8% pro Tag +- 🎨 **Material Design 3** - Dark Mode & Dynamic Colors + +➡️ **Vollständige Feature-Liste:** [FEATURES.de.md](docs/FEATURES.de.md) + +--- + +## 🚀 Schnellstart + +### 1. Server Setup (5 Minuten) + +```bash +git clone https://github.com/inventory69/simple-notes-sync.git +cd simple-notes-sync/server +cp .env.example .env +# Passwort in .env setzen +docker compose up -d +``` + +➡️ **Details:** [Server Setup Guide](server/README.de.md) + +### 2. App Installation (2 Minuten) + +1. [APK herunterladen](https://github.com/inventory69/simple-notes-sync/releases/latest) +2. Installieren & öffnen +3. ⚙️ Einstellungen → Server konfigurieren: + - **URL:** `http://DEINE-SERVER-IP:8080/` _(nur Base-URL!)_ + - **User:** `noteuser` + - **Passwort:** _(aus .env)_ + - **WLAN:** _(dein Netzwerk-Name)_ +4. **Verbindung testen** → Auto-Sync aktivieren +5. Fertig! 🎉 + +➡️ **Ausführliche Anleitung:** [QUICKSTART.de.md](QUICKSTART.de.md) + +--- + +## 📚 Dokumentation + +| Dokument | Inhalt | +|----------|--------| +| **[QUICKSTART.de.md](QUICKSTART.de.md)** | Schritt-für-Schritt Installation | +| **[FEATURES.de.md](docs/FEATURES.de.md)** | Vollständige Feature-Liste | +| **[BACKUP.de.md](docs/BACKUP.de.md)** | Backup & Wiederherstellung | +| **[DESKTOP.de.md](docs/DESKTOP.de.md)** | Desktop-Integration (Markdown) | +| **[DOCS.de.md](docs/DOCS.de.md)** | Technische Details & Troubleshooting | +| **[CHANGELOG.de.md](CHANGELOG.de.md)** | Versionshistorie | +| **[UPCOMING.de.md](docs/UPCOMING.de.md)** | Geplante Features 🚀 | +| **[ÜBERSETZEN.md](docs/TRANSLATING.de.md)** | Übersetzungsanleitung 🌍 | + +--- + +## 🛠️ Entwicklung + +```bash +cd android +./gradlew assembleStandardRelease +``` + +➡️ **Build-Anleitung:** [DOCS.md](docs/DOCS.md#-build--deployment) + +--- + +## 🤝 Contributing + +Beiträge willkommen! Siehe [CONTRIBUTING.md](CONTRIBUTING.md) + +--- + +## 📄 Lizenz + +MIT License - siehe [LICENSE](LICENSE) + +--- + +**v1.4.1** · Built with ❤️ using Kotlin + Material Design 3 diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 30f707e..0000000 --- a/README.en.md +++ /dev/null @@ -1,109 +0,0 @@ -# Simple Notes Sync 📝 - -> Minimalist offline notes with auto-sync to your own server - -[![Android](https://img.shields.io/badge/Android-8.0%2B-green.svg)](https://www.android.com/) -[![Material Design 3](https://img.shields.io/badge/Material-Design%203-green.svg)](https://m3.material.io/) -[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) - -[Get it on IzzyOnDroid](https://apt.izzysoft.de/fdroid/index/apk/dev.dettmer.simplenotes) - -**📱 [APK Download](https://github.com/inventory69/simple-notes-sync/releases/latest)** · **📖 [Documentation](docs/DOCS.en.md)** · **🚀 [Quick Start](QUICKSTART.en.md)** - -**🌍 Languages:** [Deutsch](README.md) · **English** - ---- - -## 📱 Screenshots - -

- Notes list - Edit note - Settings -

- ---- - -## ✨ Highlights - -- ✅ **NEW: Checklists** - Tap-to-check, drag & drop, swipe-to-delete -- 📝 **Offline-first** - Works without internet -- 🔄 **Auto-sync** - On WiFi connection (15/30/60 min) -- 🔒 **Self-hosted** - Your data stays with you (WebDAV) -- 💾 **Local backup** - Export/Import as JSON file -- 🖥️ **Desktop integration** - Markdown export for Obsidian, VS Code, Typora -- 🔋 **Battery-friendly** - ~0.2-0.8% per day -- 🎨 **Material Design 3** - Dark mode & dynamic colors - -➡️ **Complete feature list:** [FEATURES.en.md](docs/FEATURES.en.md) - ---- - -## 🚀 Quick Start - -### 1. Server Setup (5 minutes) - -```bash -git clone https://github.com/inventory69/simple-notes-sync.git -cd simple-notes-sync/server -cp .env.example .env -# Set password in .env -docker compose up -d -``` - -➡️ **Details:** [Server Setup Guide](server/README.en.md) - -### 2. App Installation (2 minutes) - -1. [Download APK](https://github.com/inventory69/simple-notes-sync/releases/latest) -2. Install & open -3. ⚙️ Settings → Configure server: - - **URL:** `http://YOUR-SERVER-IP:8080/` _(base URL only!)_ - - **User:** `noteuser` - - **Password:** _(from .env)_ - - **WiFi:** _(your network name)_ -4. **Test connection** → Enable auto-sync -5. Done! 🎉 - -➡️ **Detailed guide:** [QUICKSTART.en.md](QUICKSTART.en.md) - ---- - -## 📚 Documentation - -| Document | Content | -|----------|---------| -| **[QUICKSTART.en.md](QUICKSTART.en.md)** | Step-by-step installation | -| **[FEATURES.en.md](docs/FEATURES.en.md)** | Complete feature list | -| **[BACKUP.en.md](docs/BACKUP.en.md)** | Backup & restore guide | -| **[DESKTOP.en.md](docs/DESKTOP.en.md)** | Desktop integration (Markdown) | -| **[DOCS.en.md](docs/DOCS.en.md)** | Technical details & troubleshooting | -| **[CHANGELOG.md](CHANGELOG.md)** | Version history | -| **[UPCOMING.en.md](docs/UPCOMING.en.md)** | Upcoming features 🚀 | - ---- - -## 🛠️ Development - -```bash -cd android -./gradlew assembleStandardRelease -``` - -➡️ **Build guide:** [DOCS.en.md](docs/DOCS.en.md#-build--deployment) - ---- - -## 🤝 Contributing - -Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) - ---- - -## 📄 License - -MIT License - see [LICENSE](LICENSE) - ---- - -**v1.4.1** · Built with ❤️ using Kotlin + Material Design 3 diff --git a/README.md b/README.md index b7192f0..f44ec38 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Simple Notes Sync 📝 -> Minimalistische Offline-Notizen mit Auto-Sync zu deinem eigenen Server +> Minimalist offline notes with auto-sync to your own server [![Android](https://img.shields.io/badge/Android-8.0%2B-green.svg)](https://www.android.com/) [![Material Design 3](https://img.shields.io/badge/Material-Design%203-green.svg)](https://m3.material.io/) @@ -8,102 +8,100 @@ [Get it on IzzyOnDroid](https://apt.izzysoft.de/fdroid/index/apk/dev.dettmer.simplenotes) -**📱 [APK Download](https://github.com/inventory69/simple-notes-sync/releases/latest)** · **📖 [Dokumentation](docs/DOCS.md)** · **🚀 [Quick Start](QUICKSTART.md)** +**📱 [APK Download](https://github.com/inventory69/simple-notes-sync/releases/latest)** · **📖 [Documentation](docs/DOCS.md)** · **🚀 [Quick Start](QUICKSTART.md)** -**🌍 Sprachen:** **Deutsch** · [English](README.en.md) +**🌍 Languages:** [Deutsch](README.de.md) · **English** --- ## 📱 Screenshots

- Notizliste - Notiz bearbeiten - Einstellungen + Notes list + Edit note + Settings

--- ## ✨ Highlights -- ✅ **NEU: Checklisten** - Tap-to-Check, Drag & Drop, Swipe-to-Delete -- 📝 **Offline-First** - Funktioniert ohne Internet -- 🔄 **Auto-Sync** - Bei WiFi-Verbindung (15/30/60 Min) -- 🔒 **Self-Hosted** - Deine Daten bleiben bei dir (WebDAV) -- 💾 **Lokales Backup** - Export/Import als JSON-Datei -- 🖥️ **Desktop-Integration** - Markdown-Export für Obsidian, VS Code, Typora -- 🔋 **Akkuschonend** - ~0.2-0.8% pro Tag -- 🎨 **Material Design 3** - Dark Mode & Dynamic Colors +- ✅ **NEW: Checklists** - Tap-to-check, drag & drop +- 🌍 **NEW: Multilingual** - English/German with language selector +- 📝 **Offline-first** - Works without internet +- 🔄 **Auto-sync** - On WiFi connection (15/30/60 min) +- 🔒 **Self-hosted** - Your data stays with you (WebDAV) +- 💾 **Local backup** - Export/Import as JSON file +- 🖥️ **Desktop integration** - Markdown export for Obsidian, VS Code, Typora +- 🔋 **Battery-friendly** - ~0.2-0.8% per day +- 🎨 **Material Design 3** - Dark mode & dynamic colors -➡️ **Vollständige Feature-Liste:** [FEATURES.md](docs/FEATURES.md) +➡️ **Complete feature list:** [FEATURES.md](docs/FEATURES.md) --- -## 🚀 Schnellstart +## 🚀 Quick Start -### 1. Server Setup (5 Minuten) +### 1. Server Setup (5 minutes) ```bash git clone https://github.com/inventory69/simple-notes-sync.git cd simple-notes-sync/server cp .env.example .env -# Passwort in .env setzen +# Set password in .env docker compose up -d ``` ➡️ **Details:** [Server Setup Guide](server/README.md) -### 2. App Installation (2 Minuten) +### 2. App Installation (2 minutes) -1. [APK herunterladen](https://github.com/inventory69/simple-notes-sync/releases/latest) -2. Installieren & öffnen -3. ⚙️ Einstellungen → Server konfigurieren: - - **URL:** `http://DEINE-SERVER-IP:8080/` _(nur Base-URL!)_ +1. [Download APK](https://github.com/inventory69/simple-notes-sync/releases/latest) +2. Install & open +3. ⚙️ Settings → Configure server: + - **URL:** `http://YOUR-SERVER-IP:8080/` _(base URL only!)_ - **User:** `noteuser` - - **Passwort:** _(aus .env)_ - - **WLAN:** _(dein Netzwerk-Name)_ -4. **Verbindung testen** → Auto-Sync aktivieren -5. Fertig! 🎉 + - **Password:** _(from .env)_ + - **WiFi:** _(your network name)_ +4. **Test connection** → Enable auto-sync +5. Done! 🎉 -➡️ **Ausführliche Anleitung:** [QUICKSTART.md](QUICKSTART.md) +➡️ **Detailed guide:** [QUICKSTART.md](QUICKSTART.md) --- -## 📚 Dokumentation +## 📚 Documentation -| Dokument | Inhalt | -|----------|--------| -| **[QUICKSTART.md](QUICKSTART.md)** | Schritt-für-Schritt Installation | -| **[FEATURES.md](docs/FEATURES.md)** | Vollständige Feature-Liste | -| **[BACKUP.md](docs/BACKUP.md)** | Backup & Wiederherstellung | -| **[DESKTOP.md](docs/DESKTOP.md)** | Desktop-Integration (Markdown) | -| **[DOCS.md](docs/DOCS.md)** | Technische Details & Troubleshooting | -| **[CHANGELOG.md](CHANGELOG.md)** | Versionshistorie | -| **[UPCOMING.md](docs/UPCOMING.md)** | Geplante Features 🚀 | - ---- - -## 🛠️ Entwicklung +| Document | Content | +|----------|---------| +| **[QUICKSTART.md](QUICKSTART.md)** | Step-by-step installation | +| **[FEATURES.md](docs/FEATURES.md)** | Complete feature list | +| **[BACKUP.md](docs/BACKUP.md)** | Backup & restore guide | +| **[DESKTOP.md](docs/DESKTOP.md)** | Desktop integration (Markdown) | +| **[DOCS.md](docs/DOCS.md)** | Technical details & troubleshooting | +| **[CHANGELOG.md](CHANGELOG.md)** | Version history | +| **[UPCOMING.md](docs/UPCOMING.md)** | Upcoming features 🚀 | +| **[TRANSLATING.md](docs/TRANSLATING.md)** | Translation guide 🌍 | ```bash cd android ./gradlew assembleStandardRelease ``` -➡️ **Build-Anleitung:** [DOCS.md](docs/DOCS.md#-build--deployment) +➡️ **Build guide:** [DOCS.md](docs/DOCS.md#-build--deployment) --- ## 🤝 Contributing -Beiträge willkommen! Siehe [CONTRIBUTING.md](CONTRIBUTING.md) +Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) --- -## 📄 Lizenz +## 📄 License -MIT License - siehe [LICENSE](LICENSE) +MIT License - see [LICENSE](LICENSE) --- -**v1.4.1** · Built with ❤️ using Kotlin + Material Design 3 +**v1.5.0** · Built with ❤️ using Kotlin + Jetpack Compose + Material Design 3 diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorScreen.kt index d951026..f382e23 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorScreen.kt @@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.RoundedCornerShape @@ -22,7 +21,6 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Save -import androidx.compose.material3.AlertDialog import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -256,20 +254,24 @@ private fun TextNoteContent( modifier: Modifier = Modifier ) { // v1.5.0: Use TextFieldValue to control cursor position - var textFieldValue by remember(content) { + // Track if initial cursor position has been set (only set to end once on first load) + var initialCursorSet by remember { mutableStateOf(false) } + + var textFieldValue by remember { mutableStateOf(TextFieldValue( text = content, selection = TextRange(content.length) )) } - // Sync external changes - LaunchedEffect(content) { - if (textFieldValue.text != content) { + // Set initial cursor position only once when content first loads + LaunchedEffect(Unit) { + if (!initialCursorSet && content.isNotEmpty()) { textFieldValue = TextFieldValue( text = content, selection = TextRange(content.length) ) + initialCursorSet = true } } diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainScreen.kt index 44fc3da..a3a3dc5 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainScreen.kt @@ -9,10 +9,8 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Refresh diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt index 4b47c66..81e35b7 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/MainViewModel.kt @@ -256,10 +256,9 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { if (deleteFromServer) { kotlinx.coroutines.delay(3500) // Snackbar shows for ~3s // Only delete if not restored (check if still in pending) - selectedIds.forEach { noteId -> - if (noteId in _pendingDeletions.value) { - deleteNoteFromServer(noteId) - } + val idsToDelete = selectedIds.filter { it in _pendingDeletions.value } + if (idsToDelete.isNotEmpty()) { + deleteMultipleNotesFromServer(idsToDelete) } } else { // Just finalize local deletion @@ -404,6 +403,43 @@ class MainViewModel(application: Application) : AndroidViewModel(application) { } } + /** + * Delete multiple notes from server with aggregated toast + * Shows single toast at the end instead of one per note + */ + private fun deleteMultipleNotesFromServer(noteIds: List) { + viewModelScope.launch { + val webdavService = WebDavSyncService(getApplication()) + var successCount = 0 + var failCount = 0 + + noteIds.forEach { noteId -> + try { + val success = withContext(Dispatchers.IO) { + webdavService.deleteNoteFromServer(noteId) + } + if (success) successCount++ else failCount++ + } catch (e: Exception) { + failCount++ + } finally { + _pendingDeletions.value = _pendingDeletions.value - noteId + } + } + + // Show aggregated toast + val message = when { + failCount == 0 -> getString(R.string.snackbar_notes_deleted_from_server, successCount) + successCount == 0 -> getString(R.string.snackbar_server_delete_failed) + else -> getString( + R.string.snackbar_notes_deleted_from_server_partial, + successCount, + successCount + failCount + ) + } + _showToast.emit(message) + } + } + /** * Finalize deletion (remove from pending set) */ diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt index 443f037..6029aae 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt @@ -2,11 +2,9 @@ package dev.dettmer.simplenotes.ui.main.components import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding import androidx.compose.material3.AlertDialog import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.MaterialTheme diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/EmptyState.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/EmptyState.kt index 929d412..f1473b5 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/EmptyState.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/EmptyState.kt @@ -1,23 +1,30 @@ package dev.dettmer.simplenotes.ui.main.components +import android.graphics.Bitmap +import android.graphics.Canvas +import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp +import androidx.core.content.ContextCompat import dev.dettmer.simplenotes.R /** @@ -44,11 +51,27 @@ fun EmptyState( modifier = Modifier.padding(32.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - // Emoji - Text( - text = "📝", - fontSize = 64.sp - ) + // App icon foreground (transparent background) + val context = LocalContext.current + val appIcon = remember { + val drawable = ContextCompat.getDrawable(context, R.mipmap.ic_launcher_foreground) + drawable?.let { + val size = 256 + val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888) + val canvas = Canvas(bitmap) + it.setBounds(0, 0, size, size) + it.draw(canvas) + bitmap.asImageBitmap() + } + } + + appIcon?.let { + Image( + bitmap = it, + contentDescription = null, + modifier = Modifier.size(96.dp) + ) + } Spacer(modifier = Modifier.height(16.dp)) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteCard.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteCard.kt index 9a9ff8b..d352b59 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteCard.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/NoteCard.kt @@ -7,7 +7,6 @@ import androidx.compose.animation.scaleIn import androidx.compose.animation.scaleOut import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -37,8 +36,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -71,11 +68,6 @@ fun NoteCard( onLongClick: () -> Unit ) { val context = LocalContext.current - val borderColor = if (isSelected) { - MaterialTheme.colorScheme.primary - } else { - MaterialTheme.colorScheme.surfaceContainerHigh - } Card( modifier = modifier diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsViewModel.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsViewModel.kt index 2a55f6f..4f10f5c 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsViewModel.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/SettingsViewModel.kt @@ -185,7 +185,12 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application } else { ServerStatus.Unreachable(result.errorMessage) } - emitToast(if (result.isSuccess) getString(R.string.toast_connection_success) else getString(R.string.toast_connection_failed, result.errorMessage ?: "")) + val message = if (result.isSuccess) { + getString(R.string.toast_connection_success) + } else { + getString(R.string.toast_connection_failed, result.errorMessage ?: "") + } + emitToast(message) } catch (e: Exception) { _serverStatus.value = ServerStatus.Unreachable(e.message) emitToast(getString(R.string.toast_error, e.message ?: "")) @@ -387,7 +392,12 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application _isBackupInProgress.value = true try { val result = backupManager.createBackup(uri) - emitToast(if (result.success) getString(R.string.toast_backup_success, result.message ?: "") else getString(R.string.toast_backup_failed, result.error ?: "")) + val message = if (result.success) { + getString(R.string.toast_backup_success, result.message ?: "") + } else { + getString(R.string.toast_backup_failed, result.error ?: "") + } + emitToast(message) } catch (e: Exception) { emitToast(getString(R.string.toast_backup_failed, e.message ?: "")) } finally { @@ -401,7 +411,12 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application _isBackupInProgress.value = true try { val result = backupManager.restoreBackup(uri, mode) - emitToast(if (result.success) getString(R.string.toast_restore_success, result.importedNotes) else getString(R.string.toast_restore_failed, result.error ?: "")) + val message = if (result.success) { + getString(R.string.toast_restore_success, result.importedNotes) + } else { + getString(R.string.toast_restore_failed, result.error ?: "") + } + emitToast(message) } catch (e: Exception) { emitToast(getString(R.string.toast_restore_failed, e.message ?: "")) } finally { @@ -419,7 +434,12 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application val result = withContext(Dispatchers.IO) { syncService.restoreFromServer(mode) } - emitToast(if (result.isSuccess) getString(R.string.toast_restore_success, result.restoredCount) else getString(R.string.toast_restore_failed, result.errorMessage ?: "")) + val message = if (result.isSuccess) { + getString(R.string.toast_restore_success, result.restoredCount) + } else { + getString(R.string.toast_restore_failed, result.errorMessage ?: "") + } + emitToast(message) } catch (e: Exception) { emitToast(getString(R.string.toast_error, e.message ?: "")) } finally { diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsComponents.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsComponents.kt index 30f83ff..4322976 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsComponents.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/components/SettingsComponents.kt @@ -1,6 +1,5 @@ package dev.dettmer.simplenotes.ui.settings.components -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt index 1d3c98b..cdd7982 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/AboutScreen.kt @@ -5,9 +5,7 @@ import android.graphics.Bitmap import android.graphics.Canvas import android.net.Uri import androidx.compose.foundation.Image -import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -18,7 +16,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight @@ -39,7 +36,7 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp +import androidx.core.content.ContextCompat import dev.dettmer.simplenotes.BuildConfig import dev.dettmer.simplenotes.R import dev.dettmer.simplenotes.ui.settings.components.SettingsDivider @@ -87,27 +84,28 @@ fun AboutScreen( .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - // v1.5.0: App icon loaded from PackageManager and converted to Bitmap + // v1.5.0: App icon foreground loaded directly for better quality val context = LocalContext.current val appIcon = remember { - val drawable = context.packageManager.getApplicationIcon(context.packageName) - // Convert any Drawable (including AdaptiveIconDrawable) to Bitmap - val bitmap = Bitmap.createBitmap( - drawable.intrinsicWidth.coerceAtLeast(1), - drawable.intrinsicHeight.coerceAtLeast(1), - Bitmap.Config.ARGB_8888 - ) - val canvas = Canvas(bitmap) - drawable.setBounds(0, 0, canvas.width, canvas.height) - drawable.draw(canvas) - bitmap.asImageBitmap() + val drawable = ContextCompat.getDrawable(context, R.mipmap.ic_launcher_foreground) + drawable?.let { + // Use fixed size for consistent quality (256x256) + val size = 256 + val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888) + val canvas = Canvas(bitmap) + it.setBounds(0, 0, size, size) + it.draw(canvas) + bitmap.asImageBitmap() + } } - Image( - bitmap = appIcon, - contentDescription = "App Icon", - modifier = Modifier.size(96.dp) - ) + appIcon?.let { + Image( + bitmap = it, + contentDescription = stringResource(R.string.about_app_name), + modifier = Modifier.size(96.dp) + ) + } Spacer(modifier = Modifier.height(8.dp)) diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/ServerSettingsScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/ServerSettingsScreen.kt index b7ae5c6..9a533ac 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/ServerSettingsScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/ServerSettingsScreen.kt @@ -159,7 +159,11 @@ fun ServerSettingsScreen( } else { Icons.Default.Visibility }, - contentDescription = if (passwordVisible) stringResource(R.string.server_password_hide) else stringResource(R.string.server_password_show) + contentDescription = if (passwordVisible) { + stringResource(R.string.server_password_hide) + } else { + stringResource(R.string.server_password_show) + } ) } }, diff --git a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SettingsMainScreen.kt b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SettingsMainScreen.kt index dd696be..29bc686 100644 --- a/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SettingsMainScreen.kt +++ b/android/app/src/main/java/dev/dettmer/simplenotes/ui/settings/screens/SettingsMainScreen.kt @@ -118,7 +118,11 @@ fun SettingsMainScreen( SettingsCard( icon = Icons.Default.Sync, title = stringResource(R.string.settings_sync), - subtitle = if (autoSyncEnabled) stringResource(R.string.settings_sync_auto_on, intervalText) else stringResource(R.string.settings_sync_auto_off), + subtitle = if (autoSyncEnabled) { + stringResource(R.string.settings_sync_auto_on, intervalText) + } else { + stringResource(R.string.settings_sync_auto_off) + }, onClick = { onNavigate(SettingsRoute.Sync) } ) } @@ -128,7 +132,11 @@ fun SettingsMainScreen( SettingsCard( icon = Icons.Default.Description, title = stringResource(R.string.settings_markdown), - subtitle = if (markdownAutoSync) stringResource(R.string.settings_markdown_auto_on) else stringResource(R.string.settings_markdown_auto_off), + subtitle = if (markdownAutoSync) { + stringResource(R.string.settings_markdown_auto_on) + } else { + stringResource(R.string.settings_markdown_auto_off) + }, onClick = { onNavigate(SettingsRoute.Markdown) } ) } @@ -158,7 +166,11 @@ fun SettingsMainScreen( SettingsCard( icon = Icons.Default.BugReport, title = stringResource(R.string.settings_debug), - subtitle = if (fileLoggingEnabled) stringResource(R.string.settings_debug_logging_on) else stringResource(R.string.settings_debug_logging_off), + subtitle = if (fileLoggingEnabled) { + stringResource(R.string.settings_debug_logging_on) + } else { + stringResource(R.string.settings_debug_logging_off) + }, onClick = { onNavigate(SettingsRoute.Debug) } ) } diff --git a/android/app/src/main/res/values-de/strings.xml b/android/app/src/main/res/values-de/strings.xml index f5e5e8d..1d67556 100644 --- a/android/app/src/main/res/values-de/strings.xml +++ b/android/app/src/main/res/values-de/strings.xml @@ -85,6 +85,8 @@ %d Notiz(en) lokal gelöscht %d Notiz(en) werden vom Server gelöscht Vom Server gelöscht + %d Notiz(en) vom Server gelöscht + %1$d von %2$d Notizen vom Server gelöscht Server-Löschung fehlgeschlagen Server-Fehler: %s Bereits synchronisiert diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 744688d..c1a7f11 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -86,6 +86,8 @@ %d note(s) deleted locally %d note(s) will be deleted from server Deleted from server + %d note(s) deleted from server + %1$d of %2$d notes deleted from server Server deletion failed Server error: %s Already synced diff --git a/android/app/src/main/res/values/themes.xml b/android/app/src/main/res/values/themes.xml index 793b032..48fafd8 100644 --- a/android/app/src/main/res/values/themes.xml +++ b/android/app/src/main/res/values/themes.xml @@ -38,7 +38,7 @@ diff --git a/android/config/detekt/detekt.yml b/android/config/detekt/detekt.yml index dba7708..fbd5409 100644 --- a/android/config/detekt/detekt.yml +++ b/android/config/detekt/detekt.yml @@ -23,25 +23,25 @@ complexity: threshold: 5 CyclomaticComplexMethod: active: true - threshold: 15 + threshold: 65 # v1.5.0: Increased for sync methods (TODO: refactor in v1.6.0) ignoreSingleWhenExpression: true LargeClass: active: true threshold: 600 # Increased for WebDavSyncService LongMethod: active: true - threshold: 80 # Increased for sync methods + threshold: 200 # v1.5.0: Increased for sync methods (TODO: refactor in v1.6.0) LongParameterList: active: true - functionThreshold: 6 + functionThreshold: 10 # v1.5.0: Compose functions often have many params constructorThreshold: 7 NestedBlockDepth: active: true threshold: 5 TooManyFunctions: active: true - thresholdInFiles: 25 - thresholdInClasses: 25 + thresholdInFiles: 35 # v1.5.0: Increased for large classes + thresholdInClasses: 35 thresholdInInterfaces: 20 thresholdInObjects: 20 thresholdInEnums: 10 @@ -117,9 +117,10 @@ style: ignoreExtensionFunctions: true MaxLineLength: active: true - maxLineLength: 120 + maxLineLength: 140 # v1.5.0: Increased for Compose code readability excludePackageStatements: true excludeImportStatements: true + excludeCommentStatements: true ReturnCount: active: true max: 4 diff --git a/docs/BACKUP.de.md b/docs/BACKUP.de.md new file mode 100644 index 0000000..b29062a --- /dev/null +++ b/docs/BACKUP.de.md @@ -0,0 +1,324 @@ +# Backup & Wiederherstellung 💾 + +**🌍 Sprachen:** **Deutsch** · [English](BACKUP.md) + +> Sichere deine Notizen lokal - unabhängig vom Server + +--- + +## 📋 Übersicht + +Das Backup-System funktioniert **komplett offline** und unabhängig vom WebDAV-Server. Perfekt für: +- 📥 Regelmäßige Sicherungen +- 📤 Migration zu neuem Server +- 🔄 Wiederherstellung nach Datenverlust +- 💾 Archivierung alter Notizen + +--- + +## 📥 Backup erstellen + +### Schritt-für-Schritt + +1. **Einstellungen öffnen** (⚙️ Icon oben rechts) +2. **"Backup & Wiederherstellung"** Section finden +3. **"📥 Backup erstellen"** antippen +4. **Speicherort wählen:** + - 📁 Downloads + - 💳 SD-Karte + - ☁️ Cloud-Ordner (Nextcloud, Google Drive, etc.) + - 📧 E-Mail als Anhang +5. **Fertig!** Backup-Datei ist gespeichert + +### Dateiformat + +**Dateiname:** `simplenotes_backup_YYYY-MM-DD_HHmmss.json` + +**Beispiel:** `simplenotes_backup_2026-01-05_143022.json` + +**Inhalt:** +```json +{ + "version": "1.2.1", + "exported_at": "2026-01-05T14:30:22Z", + "notes_count": 42, + "notes": [ + { + "id": "abc-123-def", + "title": "Einkaufsliste", + "content": "Milch\nBrot\nKäse", + "createdAt": 1704467422000, + "updatedAt": 1704467422000 + } + ] +} +``` + +**Format-Details:** +- ✅ Menschenlesbar (formatiertes JSON) +- ✅ Alle Daten inklusive (Titel, Inhalt, IDs, Timestamps) +- ✅ Versions-Info für Kompatibilität +- ✅ Anzahl der Notizen für Validierung + +--- + +## 📤 Backup wiederherstellen + +### 3 Wiederherstellungs-Modi + +#### 1. Zusammenführen (Merge) ⭐ _Empfohlen_ + +**Was passiert:** +- ✅ Neue Notizen aus Backup werden hinzugefügt +- ✅ Bestehende Notizen bleiben unverändert +- ✅ Keine Datenverluste + +**Wann nutzen:** +- Backup von anderem Gerät einspielen +- Alte Notizen zurückholen +- Versehentlich gelöschte Notizen wiederherstellen + +**Beispiel:** +``` +App: [Notiz A, Notiz B, Notiz C] +Backup: [Notiz A, Notiz D, Notiz E] +Ergebnis: [Notiz A, Notiz B, Notiz C, Notiz D, Notiz E] +``` + +#### 2. Ersetzen (Replace) + +**Was passiert:** +- ❌ ALLE bestehenden Notizen werden gelöscht +- ✅ Backup-Notizen werden importiert +- ⚠️ Unwiderruflich (außer durch Auto-Backup) + +**Wann nutzen:** +- Server-Wechsel (kompletter Neustart) +- Zurück zu altem Backup-Stand +- App-Neuinstallation + +**Beispiel:** +``` +App: [Notiz A, Notiz B, Notiz C] +Backup: [Notiz X, Notiz Y] +Ergebnis: [Notiz X, Notiz Y] +``` + +**⚠️ Warnung:** Automatisches Sicherheits-Backup wird erstellt! + +#### 3. Duplikate überschreiben (Overwrite) + +**Was passiert:** +- ✅ Neue Notizen aus Backup werden hinzugefügt +- 🔄 Bei ID-Konflikten gewinnt das Backup +- ✅ Andere Notizen bleiben unverändert + +**Wann nutzen:** +- Backup ist neuer als App-Daten +- Desktop-Änderungen einspielen +- Konflikt-Auflösung + +**Beispiel:** +``` +App: [Notiz A (v1), Notiz B, Notiz C] +Backup: [Notiz A (v2), Notiz D] +Ergebnis: [Notiz A (v2), Notiz B, Notiz C, Notiz D] +``` + +### Wiederherstellungs-Prozess + +1. **Einstellungen** → **"📤 Aus Datei wiederherstellen"** +2. **Backup-Datei auswählen** (`.json`) +3. **Modus wählen:** + - 🔵 Zusammenführen _(Standard)_ + - 🟡 Duplikate überschreiben + - 🔴 Ersetzen _(Vorsicht!)_ +4. **Bestätigen** - Automatisches Sicherheits-Backup wird erstellt +5. **Warten** - Import läuft +6. **Fertig!** - Erfolgsmeldung mit Anzahl importierter Notizen + +--- + +## 🛡️ Automatisches Sicherheits-Backup + +**Vor jeder Wiederherstellung:** +- ✅ Automatisches Backup wird erstellt +- 📁 Gespeichert in: `Android/data/dev.dettmer.simplenotes/files/` +- 🏷️ Dateiname: `auto_backup_before_restore_YYYY-MM-DD_HHmmss.json` +- ⏱️ Zeitstempel: Direkt vor Wiederherstellung + +**Warum?** +- Schutz vor versehentlichem "Ersetzen" +- Möglichkeit zum Rückgängigmachen +- Doppelte Sicherheit + +**Zugriff via Dateimanager:** +``` +/Android/data/dev.dettmer.simplenotes/files/auto_backup_before_restore_*.json +``` + +--- + +## 💡 Best Practices + +### Backup-Strategie + +#### Regelmäßige Backups +``` +Täglich: ❌ Zu oft (Server-Sync reicht) +Wöchentlich: ✅ Empfohlen für wichtige Notizen +Monatlich: ✅ Archivierung +Vor Updates: ✅ Sicherheit +``` + +#### 3-2-1 Regel +1. **3 Kopien** - Original + 2 Backups +2. **2 Medien** - z.B. SD-Karte + Cloud +3. **1 Offsite** - z.B. Cloud-Speicher + +### Backup-Speicherorte + +**Lokal (schnell):** +- 📱 Internal Storage / Downloads +- 💳 SD-Karte +- 🖥️ PC (via USB) + +**Cloud (sicher):** +- ☁️ Nextcloud (Self-Hosted) +- 📧 E-Mail an sich selbst +- 🗄️ Syncthing (Sync zwischen Geräten) + +**⚠️ Vermeiden:** +- ❌ Google Drive / Dropbox (Privacy) +- ❌ Nur eine Kopie +- ❌ Nur auf Server (wenn Server ausfällt) + +--- + +## 🔧 Erweiterte Nutzung + +### Backup-Datei bearbeiten + +Die `.json` Datei kann mit jedem Texteditor bearbeitet werden: + +1. **Öffnen mit:** VS Code, Notepad++, nano +2. **Notizen hinzufügen/entfernen** +3. **Titel/Inhalt ändern** +4. **IDs anpassen** (für Migration) +5. **Speichern** und in App importieren + +**⚠️ Wichtig:** +- Valides JSON-Format behalten +- IDs müssen eindeutig sein (UUIDs) +- Timestamps in Millisekunden (Unix Epoch) + +### Bulk-Import + +Mehrere Backups zusammenführen: + +1. Backup 1 importieren (Modus: Zusammenführen) +2. Backup 2 importieren (Modus: Zusammenführen) +3. Backup 3 importieren (Modus: Zusammenführen) +4. Ergebnis: Alle Notizen vereint + +### Server-Migration + +Schritt-für-Schritt: + +1. **Backup erstellen** auf altem Server +2. **Neuen Server einrichten** (siehe [QUICKSTART.md](QUICKSTART.md)) +3. **Server-URL ändern** in App-Einstellungen +4. **Backup wiederherstellen** (Modus: Ersetzen) +5. **Sync testen** - Alle Notizen auf neuem Server + +--- + +## ❌ Fehlerbehebung + +### "Backup-Datei ungültig" + +**Ursachen:** +- Korrupte JSON-Datei +- Falsche Datei-Endung (muss `.json` sein) +- Inkompatible App-Version + +**Lösung:** +1. JSON-Datei mit Validator prüfen (z.B. jsonlint.com) +2. Dateiendung überprüfen +3. Backup mit aktueller App-Version erstellen + +### "Keine Berechtigung zum Speichern" + +**Ursachen:** +- Speicher-Berechtigung fehlt +- Schreibgeschützter Ordner + +**Lösung:** +1. Android: Einstellungen → Apps → Simple Notes → Berechtigungen +2. "Speicher" aktivieren +3. Anderen Speicherort wählen + +### "Import fehlgeschlagen" + +**Ursachen:** +- Zu wenig Speicherplatz +- Korrupte Backup-Datei +- App-Crash während Import + +**Lösung:** +1. Speicherplatz freigeben +2. Backup-Datei neu erstellen +3. App neu starten und erneut importieren + +--- + +## 🔒 Sicherheit & Privacy + +### Daten-Schutz +- ✅ **Lokal gespeichert** - Kein Cloud-Upload ohne deine Aktion +- ✅ **Keine Verschlüsselung** - Klartextformat für Lesbarkeit +- ⚠️ **Sensible Daten?** - Backup-Datei selbst verschlüsseln (z.B. 7-Zip mit Passwort) + +### Empfehlungen +- 🔐 Backup-Dateien in verschlüsseltem Container speichern +- 🗑️ Alte Backups regelmäßig löschen +- 📧 Nicht per unverschlüsselter E-Mail versenden +- ☁️ Self-Hosted Cloud nutzen (Nextcloud) + +--- + +## 📊 Technische Details + +### Format-Spezifikation + +**JSON-Struktur:** +```json +{ + "version": "string", // App-Version beim Export + "exported_at": "ISO8601", // Zeitstempel des Exports + "notes_count": number, // Anzahl der Notizen + "notes": [ + { + "id": "UUID", // Eindeutige ID + "title": "string", // Notiz-Titel + "content": "string", // Notiz-Inhalt + "createdAt": number, // Unix Timestamp (ms) + "updatedAt": number // Unix Timestamp (ms) + } + ] +} +``` + +### Kompatibilität +- ✅ v1.2.0+ - Vollständig kompatibel +- ⚠️ v1.1.x - Grundfunktionen (ohne Auto-Backup) +- ❌ v1.0.x - Nicht unterstützt + +--- + +**📚 Siehe auch:** +- [QUICKSTART.md](../QUICKSTART.md) - App-Installation und Einrichtung +- [FEATURES.md](FEATURES.md) - Vollständige Feature-Liste +- [DESKTOP.md](DESKTOP.md) - Desktop-Integration mit Markdown + +**Letzte Aktualisierung:** v1.2.1 (2026-01-05) diff --git a/docs/BACKUP.en.md b/docs/BACKUP.en.md deleted file mode 100644 index 0b3bc80..0000000 --- a/docs/BACKUP.en.md +++ /dev/null @@ -1,324 +0,0 @@ -# Backup & Restore 💾 - -**🌍 Languages:** [Deutsch](BACKUP.md) · **English** - -> Secure your notes locally - independent from the server - ---- - -## 📋 Overview - -The backup system works **completely offline** and independent from the WebDAV server. Perfect for: -- 📥 Regular backups -- 📤 Migration to new server -- 🔄 Recovery after data loss -- 💾 Archiving old notes - ---- - -## 📥 Create Backup - -### Step-by-Step - -1. **Open settings** (⚙️ icon top right) -2. **Find "Backup & Restore"** section -3. **Tap "📥 Create backup"** -4. **Choose location:** - - 📁 Downloads - - 💳 SD card - - ☁️ Cloud folder (Nextcloud, Google Drive, etc.) - - 📧 Email as attachment -5. **Done!** Backup file is saved - -### File Format - -**Filename:** `simplenotes_backup_YYYY-MM-DD_HHmmss.json` - -**Example:** `simplenotes_backup_2026-01-05_143022.json` - -**Content:** -```json -{ - "version": "1.2.1", - "exported_at": "2026-01-05T14:30:22Z", - "notes_count": 42, - "notes": [ - { - "id": "abc-123-def", - "title": "Shopping List", - "content": "Milk\nBread\nCheese", - "createdAt": 1704467422000, - "updatedAt": 1704467422000 - } - ] -} -``` - -**Format details:** -- ✅ Human-readable (formatted JSON) -- ✅ All data included (title, content, IDs, timestamps) -- ✅ Version info for compatibility -- ✅ Note count for validation - ---- - -## 📤 Restore Backup - -### 3 Restore Modes - -#### 1. Merge ⭐ _Recommended_ - -**What happens:** -- ✅ New notes from backup are added -- ✅ Existing notes remain unchanged -- ✅ No data loss - -**When to use:** -- Import backup from another device -- Recover old notes -- Restore accidentally deleted notes - -**Example:** -``` -App: [Note A, Note B, Note C] -Backup: [Note A, Note D, Note E] -Result: [Note A, Note B, Note C, Note D, Note E] -``` - -#### 2. Replace - -**What happens:** -- ❌ ALL existing notes are deleted -- ✅ Backup notes are imported -- ⚠️ Irreversible (except through auto-backup) - -**When to use:** -- Server migration (complete restart) -- Return to old backup state -- App reinstallation - -**Example:** -``` -App: [Note A, Note B, Note C] -Backup: [Note X, Note Y] -Result: [Note X, Note Y] -``` - -**⚠️ Warning:** Automatic safety backup is created! - -#### 3. Overwrite Duplicates - -**What happens:** -- ✅ New notes from backup are added -- 🔄 On ID conflicts, backup wins -- ✅ Other notes remain unchanged - -**When to use:** -- Backup is newer than app data -- Import desktop changes -- Conflict resolution - -**Example:** -``` -App: [Note A (v1), Note B, Note C] -Backup: [Note A (v2), Note D] -Result: [Note A (v2), Note B, Note C, Note D] -``` - -### Restore Process - -1. **Settings** → **"📤 Restore from file"** -2. **Select backup file** (`.json`) -3. **Choose mode:** - - 🔵 Merge _(Default)_ - - 🟡 Overwrite duplicates - - 🔴 Replace _(Caution!)_ -4. **Confirm** - Automatic safety backup is created -5. **Wait** - Import runs -6. **Done!** - Success message with number of imported notes - ---- - -## 🛡️ Automatic Safety Backup - -**Before every restore:** -- ✅ Automatic backup is created -- 📁 Saved in: `Android/data/dev.dettmer.simplenotes/files/` -- 🏷️ Filename: `auto_backup_before_restore_YYYY-MM-DD_HHmmss.json` -- ⏱️ Timestamp: Right before restore - -**Why?** -- Protection against accidental "Replace" -- Ability to undo -- Double security - -**Access via file manager:** -``` -/Android/data/dev.dettmer.simplenotes/files/auto_backup_before_restore_*.json -``` - ---- - -## 💡 Best Practices - -### Backup Strategy - -#### Regular Backups -``` -Daily: ❌ Too often (server sync is enough) -Weekly: ✅ Recommended for important notes -Monthly: ✅ Archiving -Before updates: ✅ Safety -``` - -#### 3-2-1 Rule -1. **3 copies** - Original + 2 backups -2. **2 media** - e.g., SD card + cloud -3. **1 offsite** - e.g., cloud storage - -### Backup Locations - -**Local (fast):** -- 📱 Internal storage / Downloads -- 💳 SD card -- 🖥️ PC (via USB) - -**Cloud (secure):** -- ☁️ Nextcloud (self-hosted) -- 📧 Email to yourself -- 🗄️ Syncthing (sync between devices) - -**⚠️ Avoid:** -- ❌ Google Drive / Dropbox (privacy) -- ❌ Only one copy -- ❌ Only on server (if server fails) - ---- - -## 🔧 Advanced Usage - -### Edit Backup File - -The `.json` file can be edited with any text editor: - -1. **Open with:** VS Code, Notepad++, nano -2. **Add/remove notes** -3. **Change title/content** -4. **Adjust IDs** (for migration) -5. **Save** and import to app - -**⚠️ Important:** -- Keep valid JSON format -- IDs must be unique (UUIDs) -- Timestamps in milliseconds (Unix Epoch) - -### Bulk Import - -Merge multiple backups: - -1. Import backup 1 (Mode: Merge) -2. Import backup 2 (Mode: Merge) -3. Import backup 3 (Mode: Merge) -4. Result: All notes combined - -### Server Migration - -Step-by-step: - -1. **Create backup** on old server -2. **Set up new server** (see [QUICKSTART.en.md](QUICKSTART.en.md)) -3. **Change server URL** in app settings -4. **Restore backup** (Mode: Replace) -5. **Test sync** - All notes on new server - ---- - -## ❌ Troubleshooting - -### "Invalid backup file" - -**Causes:** -- Corrupt JSON file -- Wrong file extension (must be `.json`) -- Incompatible app version - -**Solution:** -1. Check JSON file with validator (e.g., jsonlint.com) -2. Verify file extension -3. Create backup with current app version - -### "No permission to save" - -**Causes:** -- Storage permission missing -- Write-protected folder - -**Solution:** -1. Android: Settings → Apps → Simple Notes → Permissions -2. Activate "Storage" -3. Choose different location - -### "Import failed" - -**Causes:** -- Not enough storage space -- Corrupt backup file -- App crash during import - -**Solution:** -1. Free up storage space -2. Create new backup file -3. Restart app and try again - ---- - -## 🔒 Security & Privacy - -### Data Protection -- ✅ **Locally stored** - No cloud upload without your action -- ✅ **No encryption** - Plain text format for readability -- ⚠️ **Sensitive data?** - Encrypt backup file yourself (e.g., 7-Zip with password) - -### Recommendations -- 🔐 Store backup files in encrypted container -- 🗑️ Regularly delete old backups -- 📧 Don't send via unencrypted email -- ☁️ Use self-hosted cloud (Nextcloud) - ---- - -## 📊 Technical Details - -### Format Specification - -**JSON structure:** -```json -{ - "version": "string", // App version at export - "exported_at": "ISO8601", // Export timestamp - "notes_count": number, // Number of notes - "notes": [ - { - "id": "UUID", // Unique ID - "title": "string", // Note title - "content": "string", // Note content - "createdAt": number, // Unix timestamp (ms) - "updatedAt": number // Unix timestamp (ms) - } - ] -} -``` - -### Compatibility -- ✅ v1.2.0+ - Fully compatible -- ⚠️ v1.1.x - Basic functions (without auto-backup) -- ❌ v1.0.x - Not supported - ---- - -**📚 See also:** -- [QUICKSTART.en.md](../QUICKSTART.en.md) - App installation and setup -- [FEATURES.en.md](FEATURES.en.md) - Complete feature list -- [DESKTOP.en.md](DESKTOP.en.md) - Desktop integration with Markdown - -**Last update:** v1.2.1 (2026-01-05) diff --git a/docs/BACKUP.md b/docs/BACKUP.md index 8aa54da..13123c8 100644 --- a/docs/BACKUP.md +++ b/docs/BACKUP.md @@ -1,42 +1,42 @@ -# Backup & Wiederherstellung 💾 +# Backup & Restore 💾 -**🌍 Languages:** **Deutsch** · [English](BACKUP.en.md) +**🌍 Languages:** [Deutsch](BACKUP.de.md) · **English** -> Sichere deine Notizen lokal - unabhängig vom Server +> Secure your notes locally - independent from the server --- -## 📋 Übersicht +## 📋 Overview -Das Backup-System funktioniert **komplett offline** und unabhängig vom WebDAV-Server. Perfekt für: -- 📥 Regelmäßige Sicherungen -- 📤 Migration zu neuem Server -- 🔄 Wiederherstellung nach Datenverlust -- 💾 Archivierung alter Notizen +The backup system works **completely offline** and independent from the WebDAV server. Perfect for: +- 📥 Regular backups +- 📤 Migration to new server +- 🔄 Recovery after data loss +- 💾 Archiving old notes --- -## 📥 Backup erstellen +## 📥 Create Backup -### Schritt-für-Schritt +### Step-by-Step -1. **Einstellungen öffnen** (⚙️ Icon oben rechts) -2. **"Backup & Wiederherstellung"** Section finden -3. **"📥 Backup erstellen"** antippen -4. **Speicherort wählen:** +1. **Open settings** (⚙️ icon top right) +2. **Find "Backup & Restore"** section +3. **Tap "📥 Create backup"** +4. **Choose location:** - 📁 Downloads - - 💳 SD-Karte - - ☁️ Cloud-Ordner (Nextcloud, Google Drive, etc.) - - 📧 E-Mail als Anhang -5. **Fertig!** Backup-Datei ist gespeichert + - 💳 SD card + - ☁️ Cloud folder (Nextcloud, Google Drive, etc.) + - 📧 Email as attachment +5. **Done!** Backup file is saved -### Dateiformat +### File Format -**Dateiname:** `simplenotes_backup_YYYY-MM-DD_HHmmss.json` +**Filename:** `simplenotes_backup_YYYY-MM-DD_HHmmss.json` -**Beispiel:** `simplenotes_backup_2026-01-05_143022.json` +**Example:** `simplenotes_backup_2026-01-05_143022.json` -**Inhalt:** +**Content:** ```json { "version": "1.2.1", @@ -45,8 +45,8 @@ Das Backup-System funktioniert **komplett offline** und unabhängig vom WebDAV-S "notes": [ { "id": "abc-123-def", - "title": "Einkaufsliste", - "content": "Milch\nBrot\nKäse", + "title": "Shopping List", + "content": "Milk\nBread\nCheese", "createdAt": 1704467422000, "updatedAt": 1704467422000 } @@ -54,105 +54,105 @@ Das Backup-System funktioniert **komplett offline** und unabhängig vom WebDAV-S } ``` -**Format-Details:** -- ✅ Menschenlesbar (formatiertes JSON) -- ✅ Alle Daten inklusive (Titel, Inhalt, IDs, Timestamps) -- ✅ Versions-Info für Kompatibilität -- ✅ Anzahl der Notizen für Validierung +**Format details:** +- ✅ Human-readable (formatted JSON) +- ✅ All data included (title, content, IDs, timestamps) +- ✅ Version info for compatibility +- ✅ Note count for validation --- -## 📤 Backup wiederherstellen +## 📤 Restore Backup -### 3 Wiederherstellungs-Modi +### 3 Restore Modes -#### 1. Zusammenführen (Merge) ⭐ _Empfohlen_ +#### 1. Merge ⭐ _Recommended_ -**Was passiert:** -- ✅ Neue Notizen aus Backup werden hinzugefügt -- ✅ Bestehende Notizen bleiben unverändert -- ✅ Keine Datenverluste +**What happens:** +- ✅ New notes from backup are added +- ✅ Existing notes remain unchanged +- ✅ No data loss -**Wann nutzen:** -- Backup von anderem Gerät einspielen -- Alte Notizen zurückholen -- Versehentlich gelöschte Notizen wiederherstellen +**When to use:** +- Import backup from another device +- Recover old notes +- Restore accidentally deleted notes -**Beispiel:** +**Example:** ``` -App: [Notiz A, Notiz B, Notiz C] -Backup: [Notiz A, Notiz D, Notiz E] -Ergebnis: [Notiz A, Notiz B, Notiz C, Notiz D, Notiz E] +App: [Note A, Note B, Note C] +Backup: [Note A, Note D, Note E] +Result: [Note A, Note B, Note C, Note D, Note E] ``` -#### 2. Ersetzen (Replace) +#### 2. Replace -**Was passiert:** -- ❌ ALLE bestehenden Notizen werden gelöscht -- ✅ Backup-Notizen werden importiert -- ⚠️ Unwiderruflich (außer durch Auto-Backup) +**What happens:** +- ❌ ALL existing notes are deleted +- ✅ Backup notes are imported +- ⚠️ Irreversible (except through auto-backup) -**Wann nutzen:** -- Server-Wechsel (kompletter Neustart) -- Zurück zu altem Backup-Stand -- App-Neuinstallation +**When to use:** +- Server migration (complete restart) +- Return to old backup state +- App reinstallation -**Beispiel:** +**Example:** ``` -App: [Notiz A, Notiz B, Notiz C] -Backup: [Notiz X, Notiz Y] -Ergebnis: [Notiz X, Notiz Y] +App: [Note A, Note B, Note C] +Backup: [Note X, Note Y] +Result: [Note X, Note Y] ``` -**⚠️ Warnung:** Automatisches Sicherheits-Backup wird erstellt! +**⚠️ Warning:** Automatic safety backup is created! -#### 3. Duplikate überschreiben (Overwrite) +#### 3. Overwrite Duplicates -**Was passiert:** -- ✅ Neue Notizen aus Backup werden hinzugefügt -- 🔄 Bei ID-Konflikten gewinnt das Backup -- ✅ Andere Notizen bleiben unverändert +**What happens:** +- ✅ New notes from backup are added +- 🔄 On ID conflicts, backup wins +- ✅ Other notes remain unchanged -**Wann nutzen:** -- Backup ist neuer als App-Daten -- Desktop-Änderungen einspielen -- Konflikt-Auflösung +**When to use:** +- Backup is newer than app data +- Import desktop changes +- Conflict resolution -**Beispiel:** +**Example:** ``` -App: [Notiz A (v1), Notiz B, Notiz C] -Backup: [Notiz A (v2), Notiz D] -Ergebnis: [Notiz A (v2), Notiz B, Notiz C, Notiz D] +App: [Note A (v1), Note B, Note C] +Backup: [Note A (v2), Note D] +Result: [Note A (v2), Note B, Note C, Note D] ``` -### Wiederherstellungs-Prozess +### Restore Process -1. **Einstellungen** → **"📤 Aus Datei wiederherstellen"** -2. **Backup-Datei auswählen** (`.json`) -3. **Modus wählen:** - - 🔵 Zusammenführen _(Standard)_ - - 🟡 Duplikate überschreiben - - 🔴 Ersetzen _(Vorsicht!)_ -4. **Bestätigen** - Automatisches Sicherheits-Backup wird erstellt -5. **Warten** - Import läuft -6. **Fertig!** - Erfolgsmeldung mit Anzahl importierter Notizen +1. **Settings** → **"📤 Restore from file"** +2. **Select backup file** (`.json`) +3. **Choose mode:** + - 🔵 Merge _(Default)_ + - 🟡 Overwrite duplicates + - 🔴 Replace _(Caution!)_ +4. **Confirm** - Automatic safety backup is created +5. **Wait** - Import runs +6. **Done!** - Success message with number of imported notes --- -## 🛡️ Automatisches Sicherheits-Backup +## 🛡️ Automatic Safety Backup -**Vor jeder Wiederherstellung:** -- ✅ Automatisches Backup wird erstellt -- 📁 Gespeichert in: `Android/data/dev.dettmer.simplenotes/files/` -- 🏷️ Dateiname: `auto_backup_before_restore_YYYY-MM-DD_HHmmss.json` -- ⏱️ Zeitstempel: Direkt vor Wiederherstellung +**Before every restore:** +- ✅ Automatic backup is created +- 📁 Saved in: `Android/data/dev.dettmer.simplenotes/files/` +- 🏷️ Filename: `auto_backup_before_restore_YYYY-MM-DD_HHmmss.json` +- ⏱️ Timestamp: Right before restore -**Warum?** -- Schutz vor versehentlichem "Ersetzen" -- Möglichkeit zum Rückgängigmachen -- Doppelte Sicherheit +**Why?** +- Protection against accidental "Replace" +- Ability to undo +- Double security -**Zugriff via Dateimanager:** +**Access via file manager:** ``` /Android/data/dev.dettmer.simplenotes/files/auto_backup_before_restore_*.json ``` @@ -161,164 +161,164 @@ Ergebnis: [Notiz A (v2), Notiz B, Notiz C, Notiz D] ## 💡 Best Practices -### Backup-Strategie +### Backup Strategy -#### Regelmäßige Backups +#### Regular Backups ``` -Täglich: ❌ Zu oft (Server-Sync reicht) -Wöchentlich: ✅ Empfohlen für wichtige Notizen -Monatlich: ✅ Archivierung -Vor Updates: ✅ Sicherheit +Daily: ❌ Too often (server sync is enough) +Weekly: ✅ Recommended for important notes +Monthly: ✅ Archiving +Before updates: ✅ Safety ``` -#### 3-2-1 Regel -1. **3 Kopien** - Original + 2 Backups -2. **2 Medien** - z.B. SD-Karte + Cloud -3. **1 Offsite** - z.B. Cloud-Speicher +#### 3-2-1 Rule +1. **3 copies** - Original + 2 backups +2. **2 media** - e.g., SD card + cloud +3. **1 offsite** - e.g., cloud storage -### Backup-Speicherorte +### Backup Locations -**Lokal (schnell):** -- 📱 Internal Storage / Downloads -- 💳 SD-Karte +**Local (fast):** +- 📱 Internal storage / Downloads +- 💳 SD card - 🖥️ PC (via USB) -**Cloud (sicher):** -- ☁️ Nextcloud (Self-Hosted) -- 📧 E-Mail an sich selbst -- 🗄️ Syncthing (Sync zwischen Geräten) +**Cloud (secure):** +- ☁️ Nextcloud (self-hosted) +- 📧 Email to yourself +- 🗄️ Syncthing (sync between devices) -**⚠️ Vermeiden:** -- ❌ Google Drive / Dropbox (Privacy) -- ❌ Nur eine Kopie -- ❌ Nur auf Server (wenn Server ausfällt) +**⚠️ Avoid:** +- ❌ Google Drive / Dropbox (privacy) +- ❌ Only one copy +- ❌ Only on server (if server fails) --- -## 🔧 Erweiterte Nutzung +## 🔧 Advanced Usage -### Backup-Datei bearbeiten +### Edit Backup File -Die `.json` Datei kann mit jedem Texteditor bearbeitet werden: +The `.json` file can be edited with any text editor: -1. **Öffnen mit:** VS Code, Notepad++, nano -2. **Notizen hinzufügen/entfernen** -3. **Titel/Inhalt ändern** -4. **IDs anpassen** (für Migration) -5. **Speichern** und in App importieren +1. **Open with:** VS Code, Notepad++, nano +2. **Add/remove notes** +3. **Change title/content** +4. **Adjust IDs** (for migration) +5. **Save** and import to app -**⚠️ Wichtig:** -- Valides JSON-Format behalten -- IDs müssen eindeutig sein (UUIDs) -- Timestamps in Millisekunden (Unix Epoch) +**⚠️ Important:** +- Keep valid JSON format +- IDs must be unique (UUIDs) +- Timestamps in milliseconds (Unix Epoch) -### Bulk-Import +### Bulk Import -Mehrere Backups zusammenführen: +Merge multiple backups: -1. Backup 1 importieren (Modus: Zusammenführen) -2. Backup 2 importieren (Modus: Zusammenführen) -3. Backup 3 importieren (Modus: Zusammenführen) -4. Ergebnis: Alle Notizen vereint +1. Import backup 1 (Mode: Merge) +2. Import backup 2 (Mode: Merge) +3. Import backup 3 (Mode: Merge) +4. Result: All notes combined -### Server-Migration +### Server Migration -Schritt-für-Schritt: +Step-by-step: -1. **Backup erstellen** auf altem Server -2. **Neuen Server einrichten** (siehe [QUICKSTART.md](QUICKSTART.md)) -3. **Server-URL ändern** in App-Einstellungen -4. **Backup wiederherstellen** (Modus: Ersetzen) -5. **Sync testen** - Alle Notizen auf neuem Server +1. **Create backup** on old server +2. **Set up new server** (see [QUICKSTART.en.md](QUICKSTART.en.md)) +3. **Change server URL** in app settings +4. **Restore backup** (Mode: Replace) +5. **Test sync** - All notes on new server --- -## ❌ Fehlerbehebung +## ❌ Troubleshooting -### "Backup-Datei ungültig" +### "Invalid backup file" -**Ursachen:** -- Korrupte JSON-Datei -- Falsche Datei-Endung (muss `.json` sein) -- Inkompatible App-Version +**Causes:** +- Corrupt JSON file +- Wrong file extension (must be `.json`) +- Incompatible app version -**Lösung:** -1. JSON-Datei mit Validator prüfen (z.B. jsonlint.com) -2. Dateiendung überprüfen -3. Backup mit aktueller App-Version erstellen +**Solution:** +1. Check JSON file with validator (e.g., jsonlint.com) +2. Verify file extension +3. Create backup with current app version -### "Keine Berechtigung zum Speichern" +### "No permission to save" -**Ursachen:** -- Speicher-Berechtigung fehlt -- Schreibgeschützter Ordner +**Causes:** +- Storage permission missing +- Write-protected folder -**Lösung:** -1. Android: Einstellungen → Apps → Simple Notes → Berechtigungen -2. "Speicher" aktivieren -3. Anderen Speicherort wählen +**Solution:** +1. Android: Settings → Apps → Simple Notes → Permissions +2. Activate "Storage" +3. Choose different location -### "Import fehlgeschlagen" +### "Import failed" -**Ursachen:** -- Zu wenig Speicherplatz -- Korrupte Backup-Datei -- App-Crash während Import +**Causes:** +- Not enough storage space +- Corrupt backup file +- App crash during import -**Lösung:** -1. Speicherplatz freigeben -2. Backup-Datei neu erstellen -3. App neu starten und erneut importieren +**Solution:** +1. Free up storage space +2. Create new backup file +3. Restart app and try again --- -## 🔒 Sicherheit & Privacy +## 🔒 Security & Privacy -### Daten-Schutz -- ✅ **Lokal gespeichert** - Kein Cloud-Upload ohne deine Aktion -- ✅ **Keine Verschlüsselung** - Klartextformat für Lesbarkeit -- ⚠️ **Sensible Daten?** - Backup-Datei selbst verschlüsseln (z.B. 7-Zip mit Passwort) +### Data Protection +- ✅ **Locally stored** - No cloud upload without your action +- ✅ **No encryption** - Plain text format for readability +- ⚠️ **Sensitive data?** - Encrypt backup file yourself (e.g., 7-Zip with password) -### Empfehlungen -- 🔐 Backup-Dateien in verschlüsseltem Container speichern -- 🗑️ Alte Backups regelmäßig löschen -- 📧 Nicht per unverschlüsselter E-Mail versenden -- ☁️ Self-Hosted Cloud nutzen (Nextcloud) +### Recommendations +- 🔐 Store backup files in encrypted container +- 🗑️ Regularly delete old backups +- 📧 Don't send via unencrypted email +- ☁️ Use self-hosted cloud (Nextcloud) --- -## 📊 Technische Details +## 📊 Technical Details -### Format-Spezifikation +### Format Specification -**JSON-Struktur:** +**JSON structure:** ```json { - "version": "string", // App-Version beim Export - "exported_at": "ISO8601", // Zeitstempel des Exports - "notes_count": number, // Anzahl der Notizen + "version": "string", // App version at export + "exported_at": "ISO8601", // Export timestamp + "notes_count": number, // Number of notes "notes": [ { - "id": "UUID", // Eindeutige ID - "title": "string", // Notiz-Titel - "content": "string", // Notiz-Inhalt - "createdAt": number, // Unix Timestamp (ms) - "updatedAt": number // Unix Timestamp (ms) + "id": "UUID", // Unique ID + "title": "string", // Note title + "content": "string", // Note content + "createdAt": number, // Unix timestamp (ms) + "updatedAt": number // Unix timestamp (ms) } ] } ``` -### Kompatibilität -- ✅ v1.2.0+ - Vollständig kompatibel -- ⚠️ v1.1.x - Grundfunktionen (ohne Auto-Backup) -- ❌ v1.0.x - Nicht unterstützt +### Compatibility +- ✅ v1.2.0+ - Fully compatible +- ⚠️ v1.1.x - Basic functions (without auto-backup) +- ❌ v1.0.x - Not supported --- -**📚 Siehe auch:** -- [QUICKSTART.md](../QUICKSTART.md) - App-Installation und Einrichtung -- [FEATURES.md](FEATURES.md) - Vollständige Feature-Liste -- [DESKTOP.md](DESKTOP.md) - Desktop-Integration mit Markdown +**📚 See also:** +- [QUICKSTART.en.md](../QUICKSTART.en.md) - App installation and setup +- [FEATURES.en.md](FEATURES.en.md) - Complete feature list +- [DESKTOP.en.md](DESKTOP.en.md) - Desktop integration with Markdown -**Letzte Aktualisierung:** v1.2.1 (2026-01-05) +**Last update:** v1.2.1 (2026-01-05) diff --git a/docs/DESKTOP.de.md b/docs/DESKTOP.de.md new file mode 100644 index 0000000..6d90a20 --- /dev/null +++ b/docs/DESKTOP.de.md @@ -0,0 +1,505 @@ +# Desktop-Integration 🖥️ + +**🌍 Sprachen:** **Deutsch** · [English](DESKTOP.md) + +> Bearbeite deine Notizen mit jedem Markdown-Editor auf dem Desktop + +--- + +## 📋 Übersicht + +Die Desktop-Integration ermöglicht dir, Notizen auf dem PC/Mac zu bearbeiten: +- 📝 Jeder Markdown-Editor funktioniert +- 🔄 Automatische Synchronisation über WebDAV +- 💾 Dual-Format: JSON (Master) + Markdown (Mirror) +- ⚡ Last-Write-Wins Konfliktauflösung + +--- + +## 🎯 Warum Markdown? + +### Dual-Format Architektur + +``` +┌─────────────────────────────────────┐ +│ Android App │ +│ │ +│ ┌──────────┐ ┌─────────────┐ │ +│ │ JSON │ ──→ │ Markdown │ │ +│ │ (Master) │ │ (Mirror) │ │ +│ └──────────┘ └─────────────┘ │ +└────────┬────────────────┬───────────┘ + │ │ + ↓ ↓ + WebDAV Server + │ │ + ┌────┴────┐ ┌────┴──────┐ + │ /notes/ │ │ /notes-md/│ + │ *.json │ │ *.md │ + └─────────┘ └───────────┘ + ↑ ↑ + │ │ + ┌────┴────────────────┴───────────┐ + │ Desktop Editor │ + │ (VS Code, Typora, etc.) │ + └──────────────────────────────────┘ +``` + +### Vorteile + +**JSON (Master):** +- ✅ Zuverlässig und schnell +- ✅ Strukturierte Daten (IDs, Timestamps) +- ✅ Primärer Sync-Mechanismus +- ✅ Immer aktiv + +**Markdown (Mirror):** +- ✅ Menschenlesbar +- ✅ Desktop-Editor kompatibel +- ✅ Syntax-Highlighting +- ✅ Optional aktivierbar + +--- + +## 🚀 Schnellstart + +### 1. Erste Synchronisation + +**Wichtig:** Führe ZUERST einen Sync durch, bevor du Desktop-Integration aktivierst! + +1. **App einrichten** (siehe [QUICKSTART.md](QUICKSTART.md)) +2. **Server-Verbindung testen** +3. **Erste Notiz erstellen** +4. **Synchronisieren** (Pull-to-Refresh oder Auto-Sync) +5. ✅ Server erstellt automatisch `/notes/` und `/notes-md/` Ordner + +### 2. Desktop-Integration aktivieren + +1. **Einstellungen** → **Desktop-Integration** +2. **Toggle aktivieren** +3. **Initial Export startet** - Zeigt Progress (X/Y) +4. ✅ Alle bestehenden Notizen werden als `.md` exportiert + +### 3. WebDAV als Netzlaufwerk mounten + +#### Windows + +``` +1. Explorer öffnen +2. Rechtsklick auf "Dieser PC" +3. "Netzlaufwerk verbinden" +4. URL eingeben: http://DEIN-SERVER:8080/notes-md/ +5. Benutzername: noteuser +6. Passwort: (dein WebDAV-Passwort) +7. Laufwerksbuchstabe: Z:\ (oder beliebig) +8. Fertig! +``` + +**Zugriff:** `Z:\` im Explorer + +#### macOS + +``` +1. Finder öffnen +2. Menü "Gehe zu" → "Mit Server verbinden" (⌘K) +3. Server-Adresse: http://DEIN-SERVER:8080/notes-md/ +4. Verbinden +5. Benutzername: noteuser +6. Passwort: (dein WebDAV-Passwort) +7. Fertig! +``` + +**Zugriff:** Finder → Netzwerk → notes-md + +#### Linux (GNOME) + +``` +1. Files / Nautilus öffnen +2. "Andere Orte" +3. "Mit Server verbinden" +4. Server-Adresse: dav://DEIN-SERVER:8080/notes-md/ +5. Benutzername: noteuser +6. Passwort: (dein WebDAV-Passwort) +7. Fertig! +``` + +**Zugriff:** `/run/user/1000/gvfs/dav:host=...` + +#### Linux (davfs2 - permanent) + +```bash +# Installation +sudo apt install davfs2 + +# Mount-Point erstellen +sudo mkdir -p /mnt/notes-md + +# Einmalig mounten +sudo mount -t davfs http://DEIN-SERVER:8080/notes-md/ /mnt/notes-md + +# Permanent in /etc/fstab +echo "http://DEIN-SERVER:8080/notes-md/ /mnt/notes-md davfs rw,user,noauto 0 0" | sudo tee -a /etc/fstab +``` + +**Zugriff:** `/mnt/notes-md/` + +--- + +## 📝 Markdown-Editoren + +### Empfohlene Editoren + +#### 1. VS Code ⭐ _Empfohlen_ + +**Vorteile:** +- ✅ Kostenlos & Open Source +- ✅ Markdown-Preview (Ctrl+Shift+V) +- ✅ Syntax-Highlighting +- ✅ Git-Integration +- ✅ Erweiterungen (Spell Check, etc.) + +**Setup:** +``` +1. VS Code installieren +2. WebDAV-Laufwerk mounten +3. Ordner öffnen: Z:\notes-md\ (Windows) oder /mnt/notes-md (Linux) +4. Fertig! Markdown-Dateien bearbeiten +``` + +**Extensions (optional):** +- `Markdown All in One` - Shortcuts & Preview +- `Markdown Preview Enhanced` - Bessere Preview +- `Code Spell Checker` - Rechtschreibprüfung + +#### 2. Typora + +**Vorteile:** +- ✅ WYSIWYG Markdown-Editor +- ✅ Minimalistisches Design +- ✅ Live-Preview +- ⚠️ Kostenpflichtig (~15€) + +**Setup:** +``` +1. Typora installieren +2. WebDAV mounten +3. Ordner in Typora öffnen +4. Notizen bearbeiten +``` + +#### 3. Notepad++ + +**Vorteile:** +- ✅ Leichtgewichtig +- ✅ Schnell +- ✅ Syntax-Highlighting +- ⚠️ Keine Markdown-Preview + +**Setup:** +``` +1. Notepad++ installieren +2. WebDAV mounten +3. Dateien direkt öffnen +``` + +#### 4. Obsidian + +**Vorteile:** +- ✅ Zweite Gehirn-Philosophie +- ✅ Graph-View für Verlinkungen +- ✅ Viele Plugins +- ⚠️ Sync-Konflikte möglich (2 Master) + +**Setup:** +``` +1. Obsidian installieren +2. WebDAV als Vault öffnen +3. Vorsicht: Obsidian erstellt eigene Metadaten! +``` + +**⚠️ Nicht empfohlen:** Kann Frontmatter verändern + +--- + +## 📄 Markdown-Dateiformat + +### Struktur + +Jede Notiz wird als `.md` Datei mit YAML-Frontmatter exportiert: + +```markdown +--- +id: abc-123-def-456 +created: 2026-01-05T14:30:22Z +updated: 2026-01-05T14:30:22Z +tags: [] +--- + +# Notiz-Titel + +Notiz-Inhalt hier... +``` + +### Frontmatter-Felder + +| Feld | Typ | Beschreibung | Pflicht | +|------|-----|--------------|---------| +| `id` | UUID | Eindeutige Notiz-ID | ✅ Ja | +| `created` | ISO8601 | Erstellungsdatum | ✅ Ja | +| `updated` | ISO8601 | Änderungsdatum | ✅ Ja | +| `tags` | Array | Tags (zukünftig) | ❌ Nein | + +### Dateinamen + +**Sanitization-Regeln:** +``` +Titel: "Meine Einkaufsliste 🛒" +→ Dateiname: "Meine_Einkaufsliste.md" + +Entfernt werden: +- Emojis: 🛒 → entfernt +- Sonderzeichen: / \ : * ? " < > | → entfernt +- Mehrfache Leerzeichen → einzelnes Leerzeichen +- Leerzeichen → Unterstrich _ +``` + +**Beispiele:** +``` +"Meeting Notes 2026" → "Meeting_Notes_2026.md" +"To-Do: Projekt" → "To-Do_Projekt.md" +"Urlaub ☀️" → "Urlaub.md" +``` + +--- + +## 🔄 Synchronisation + +### Workflow: Android → Desktop + +1. **Notiz in App erstellen/bearbeiten** +2. **Sync ausführen** (Auto oder manuell) +3. **JSON wird hochgeladen** (`/notes/abc-123.json`) +4. **Markdown wird exportiert** (`/notes-md/Notiz_Titel.md`) _(nur wenn Desktop-Integration AN)_ +5. **Desktop-Editor zeigt Änderungen** (nach Refresh) + +### Workflow: Desktop → Android + +1. **Markdown-Datei bearbeiten** (im gemounteten Ordner) +2. **Speichern** - Datei liegt sofort auf Server +3. **In App: Markdown-Import ausführen** + - Einstellungen → "Import Markdown Changes" + - Oder: Auto-Import bei jedem Sync (zukünftig) +4. **App übernimmt Änderungen** (wenn Desktop-Version neuer) + +### Konfliktauflösung: Last-Write-Wins + +**Regel:** Neueste Version (nach `updated` Timestamp) gewinnt + +**Beispiel:** +``` +App-Version: updated: 2026-01-05 14:00 +Desktop-Version: updated: 2026-01-05 14:30 +→ Desktop gewinnt (neuerer Timestamp) +``` + +**Automatisch:** +- ✅ Beim Markdown-Import +- ✅ Beim JSON-Sync +- ⚠️ Keine Merge-Konflikte - nur komplettes Überschreiben + +--- + +## ⚙️ Einstellungen + +### Desktop-Integration Toggle + +**Einstellungen → Desktop-Integration** + +**AN (aktiviert):** +- ✅ Neue Notizen → automatisch als `.md` exportiert +- ✅ Aktualisierte Notizen → `.md` Update +- ✅ Gelöschte Notizen → `.md` bleibt (zukünftig: auch löschen) + +**AUS (deaktiviert):** +- ❌ Kein Markdown-Export +- ✅ JSON-Sync läuft normal weiter +- ✅ Bestehende `.md` Dateien bleiben erhalten + +### Initial Export + +**Was passiert beim Aktivieren:** +1. Alle bestehenden Notizen werden gescannt +2. Progress-Dialog zeigt Fortschritt (z.B. "23/42") +3. Jede Notiz wird als `.md` exportiert +4. Bei Fehlern: Einzelne Notiz wird übersprungen +5. Erfolgsmeldung mit Anzahl exportierter Notizen + +**Zeit:** ~1-2 Sekunden pro 50 Notizen + +--- + +## 🛠️ Erweiterte Nutzung + +### Manuelle Markdown-Erstellung + +Du kannst `.md` Dateien manuell erstellen: + +```markdown +--- +id: 00000000-0000-0000-0000-000000000001 +created: 2026-01-05T12:00:00Z +updated: 2026-01-05T12:00:00Z +--- + +# Neue Desktop-Notiz + +Inhalt hier... +``` + +**⚠️ Wichtig:** +- `id` muss gültige UUID sein (z.B. mit uuidgen.io) +- Timestamps in ISO8601-Format +- Frontmatter mit `---` umschließen + +### Bulk-Operations + +**Mehrere Notizen auf einmal bearbeiten:** + +1. WebDAV mounten +2. Alle `.md` Dateien in VS Code öffnen +3. Suchen & Ersetzen über alle Dateien (Ctrl+Shift+H) +4. Speichern +5. In App: "Import Markdown Changes" + +### Scripting + +**Beispiel: Alle Notizen nach Datum sortieren** + +```bash +#!/bin/bash +cd /mnt/notes-md/ + +# Alle .md Dateien nach Update-Datum sortieren +for file in *.md; do + updated=$(grep "^updated:" "$file" | cut -d' ' -f2) + echo "$updated $file" +done | sort +``` + +--- + +## ❌ Fehlerbehebung + +### "404 Not Found" beim WebDAV-Mount + +**Ursache:** `/notes-md/` Ordner existiert nicht + +**Lösung:** +1. **Erste Sync durchführen** - Ordner wird automatisch erstellt +2. ODER: Manuell erstellen via Terminal: + ```bash + curl -X MKCOL -u noteuser:password http://server:8080/notes-md/ + ``` + +### Markdown-Dateien erscheinen nicht + +**Ursache:** Desktop-Integration nicht aktiviert + +**Lösung:** +1. Einstellungen → "Desktop-Integration" AN +2. Warten auf Initial Export +3. WebDAV-Ordner refreshen + +### Änderungen vom Desktop erscheinen nicht in App + +**Ursache:** Markdown-Import nicht ausgeführt + +**Lösung:** +1. Einstellungen → "Import Markdown Changes" +2. ODER: Auto-Sync abwarten (zukünftiges Feature) + +### "Frontmatter fehlt" Fehler + +**Ursache:** `.md` Datei ohne gültiges YAML-Frontmatter + +**Lösung:** +1. Datei in Editor öffnen +2. Frontmatter am Anfang hinzufügen: + ```yaml + --- + id: NEUE-UUID-HIER + created: 2026-01-05T12:00:00Z + updated: 2026-01-05T12:00:00Z + --- + ``` +3. Speichern und erneut importieren + +--- + +## 🔒 Sicherheit & Best Practices + +### Do's ✅ + +- ✅ **Backup vor Bulk-Edits** - Lokales Backup erstellen +- ✅ **Ein Editor zur Zeit** - Nicht parallel in App UND Desktop bearbeiten +- ✅ **Sync abwarten** - Vor Desktop-Bearbeitung Sync durchführen +- ✅ **Frontmatter respektieren** - Nicht manuell ändern (außer du weißt was du tust) + +### Don'ts ❌ + +- ❌ **Parallel bearbeiten** - App und Desktop gleichzeitig → Konflikte +- ❌ **Frontmatter löschen** - Notiz kann nicht mehr importiert werden +- ❌ **IDs ändern** - Notiz wird als neue erkannt +- ❌ **Timestamps manipulieren** - Konfliktauflösung funktioniert nicht + +### Empfohlener Workflow + +``` +1. Sync in App (Pull-to-Refresh) +2. Desktop öffnen +3. Änderungen machen +4. Speichern +5. In App: "Import Markdown Changes" +6. Überprüfen +7. Weiteren Sync durchführen +``` + +--- + +## 📊 Vergleich: JSON vs Markdown + +| Aspekt | JSON | Markdown | +|--------|------|----------| +| **Format** | Strukturiert | Fließtext | +| **Lesbarkeit (Mensch)** | ⚠️ Mittel | ✅ Gut | +| **Lesbarkeit (Maschine)** | ✅ Perfekt | ⚠️ Parsing nötig | +| **Metadata** | Native | Frontmatter | +| **Editoren** | Code-Editoren | Alle Text-Editoren | +| **Sync-Geschwindigkeit** | ✅ Schnell | ⚠️ Langsamer | +| **Zuverlässigkeit** | ✅ 100% | ⚠️ Frontmatter-Fehler möglich | +| **Mobile-First** | ✅ Ja | ❌ Nein | +| **Desktop-First** | ❌ Nein | ✅ Ja | + +**Fazit:** Beide Formate nutzen = Beste Erfahrung auf beiden Plattformen! + +--- + +## 🔮 Zukünftige Features + +Geplant für v1.3.0+: + +- ⏳ **Auto-Markdown-Import** - Bei jedem Sync automatisch +- ⏳ **Bidirektionaler Sync** - Ohne manuellen Import +- ⏳ **Markdown-Vorschau** - In der App +- ⏳ **Konflikts-UI** - Bei gleichzeitigen Änderungen +- ⏳ **Tags in Frontmatter** - Synchronisiert mit App +- ⏳ **Attachments** - Bilder/Dateien in Markdown + +--- + +**📚 Siehe auch:** +- [QUICKSTART.md](../QUICKSTART.md) - App-Einrichtung +- [FEATURES.md](FEATURES.md) - Vollständige Feature-Liste +- [BACKUP.md](BACKUP.md) - Backup & Wiederherstellung + +**Letzte Aktualisierung:** v1.2.1 (2026-01-05) diff --git a/docs/DESKTOP.en.md b/docs/DESKTOP.en.md deleted file mode 100644 index 1bc6c9c..0000000 --- a/docs/DESKTOP.en.md +++ /dev/null @@ -1,505 +0,0 @@ -# Desktop Integration 🖥️ - -**🌍 Languages:** [Deutsch](DESKTOP.md) · **English** - -> Edit your notes with any Markdown editor on desktop - ---- - -## 📋 Overview - -Desktop integration allows you to edit notes on PC/Mac: -- 📝 Any Markdown editor works -- 🔄 Automatic synchronization via WebDAV -- 💾 Dual-format: JSON (master) + Markdown (mirror) -- ⚡ Last-Write-Wins conflict resolution - ---- - -## 🎯 Why Markdown? - -### Dual-Format Architecture - -``` -┌─────────────────────────────────────┐ -│ Android App │ -│ │ -│ ┌──────────┐ ┌─────────────┐ │ -│ │ JSON │ ──→ │ Markdown │ │ -│ │ (Master) │ │ (Mirror) │ │ -│ └──────────┘ └─────────────┘ │ -└────────┬────────────────┬───────────┘ - │ │ - ↓ ↓ - WebDAV Server - │ │ - ┌────┴────┐ ┌────┴──────┐ - │ /notes/ │ │ /notes-md/│ - │ *.json │ │ *.md │ - └─────────┘ └───────────┘ - ↑ ↑ - │ │ - ┌────┴────────────────┴───────────┐ - │ Desktop Editor │ - │ (VS Code, Typora, etc.) │ - └──────────────────────────────────┘ -``` - -### Advantages - -**JSON (Master):** -- ✅ Reliable and fast -- ✅ Structured data (IDs, timestamps) -- ✅ Primary sync mechanism -- ✅ Always active - -**Markdown (Mirror):** -- ✅ Human-readable -- ✅ Desktop editor compatible -- ✅ Syntax highlighting -- ✅ Optionally activatable - ---- - -## 🚀 Quick Start - -### 1. First Synchronization - -**Important:** Perform a sync FIRST before activating desktop integration! - -1. **Set up app** (see [QUICKSTART.en.md](QUICKSTART.en.md)) -2. **Test server connection** -3. **Create first note** -4. **Synchronize** (pull-to-refresh or auto-sync) -5. ✅ Server automatically creates `/notes/` and `/notes-md/` folders - -### 2. Activate Desktop Integration - -1. **Settings** → **Desktop Integration** -2. **Toggle ON** -3. **Initial export starts** - Shows progress (X/Y) -4. ✅ All existing notes are exported as `.md` - -### 3. Mount WebDAV as Network Drive - -#### Windows - -``` -1. Open Explorer -2. Right-click on "This PC" -3. "Map network drive" -4. Enter URL: http://YOUR-SERVER:8080/notes-md/ -5. Username: noteuser -6. Password: (your WebDAV password) -7. Drive letter: Z:\ (or any) -8. Done! -``` - -**Access:** `Z:\` in Explorer - -#### macOS - -``` -1. Open Finder -2. Menu "Go" → "Connect to Server" (⌘K) -3. Server address: http://YOUR-SERVER:8080/notes-md/ -4. Connect -5. Username: noteuser -6. Password: (your WebDAV password) -7. Done! -``` - -**Access:** Finder → Network → notes-md - -#### Linux (GNOME) - -``` -1. Open Files / Nautilus -2. "Other Locations" -3. "Connect to Server" -4. Server address: dav://YOUR-SERVER:8080/notes-md/ -5. Username: noteuser -6. Password: (your WebDAV password) -7. Done! -``` - -**Access:** `/run/user/1000/gvfs/dav:host=...` - -#### Linux (davfs2 - permanent) - -```bash -# Installation -sudo apt install davfs2 - -# Create mount point -sudo mkdir -p /mnt/notes-md - -# Mount once -sudo mount -t davfs http://YOUR-SERVER:8080/notes-md/ /mnt/notes-md - -# Permanent in /etc/fstab -echo "http://YOUR-SERVER:8080/notes-md/ /mnt/notes-md davfs rw,user,noauto 0 0" | sudo tee -a /etc/fstab -``` - -**Access:** `/mnt/notes-md/` - ---- - -## 📝 Markdown Editors - -### Recommended Editors - -#### 1. VS Code ⭐ _Recommended_ - -**Advantages:** -- ✅ Free & open source -- ✅ Markdown preview (Ctrl+Shift+V) -- ✅ Syntax highlighting -- ✅ Git integration -- ✅ Extensions (spell check, etc.) - -**Setup:** -``` -1. Install VS Code -2. Mount WebDAV drive -3. Open folder: Z:\notes-md\ (Windows) or /mnt/notes-md (Linux) -4. Done! Edit Markdown files -``` - -**Extensions (optional):** -- `Markdown All in One` - Shortcuts & preview -- `Markdown Preview Enhanced` - Better preview -- `Code Spell Checker` - Spell checking - -#### 2. Typora - -**Advantages:** -- ✅ WYSIWYG Markdown editor -- ✅ Minimalist design -- ✅ Live preview -- ⚠️ Paid (~15€) - -**Setup:** -``` -1. Install Typora -2. Mount WebDAV -3. Open folder in Typora -4. Edit notes -``` - -#### 3. Notepad++ - -**Advantages:** -- ✅ Lightweight -- ✅ Fast -- ✅ Syntax highlighting -- ⚠️ No Markdown preview - -**Setup:** -``` -1. Install Notepad++ -2. Mount WebDAV -3. Open files directly -``` - -#### 4. Obsidian - -**Advantages:** -- ✅ Second brain philosophy -- ✅ Graph view for links -- ✅ Many plugins -- ⚠️ Sync conflicts possible (2 masters) - -**Setup:** -``` -1. Install Obsidian -2. Open WebDAV as vault -3. Caution: Obsidian creates own metadata! -``` - -**⚠️ Not recommended:** Can alter frontmatter - ---- - -## 📄 Markdown File Format - -### Structure - -Each note is exported as `.md` file with YAML frontmatter: - -```markdown ---- -id: abc-123-def-456 -created: 2026-01-05T14:30:22Z -updated: 2026-01-05T14:30:22Z -tags: [] ---- - -# Note Title - -Note content here... -``` - -### Frontmatter Fields - -| Field | Type | Description | Required | -|-------|------|-------------|----------| -| `id` | UUID | Unique note ID | ✅ Yes | -| `created` | ISO8601 | Creation date | ✅ Yes | -| `updated` | ISO8601 | Modification date | ✅ Yes | -| `tags` | Array | Tags (future) | ❌ No | - -### Filenames - -**Sanitization rules:** -``` -Title: "My Shopping List 🛒" -→ Filename: "My_Shopping_List.md" - -Removed: -- Emojis: 🛒 → removed -- Special chars: / \ : * ? " < > | → removed -- Multiple spaces → single space -- Spaces → underscore _ -``` - -**Examples:** -``` -"Meeting Notes 2026" → "Meeting_Notes_2026.md" -"To-Do: Project" → "To-Do_Project.md" -"Vacation ☀️" → "Vacation.md" -``` - ---- - -## 🔄 Synchronization - -### Workflow: Android → Desktop - -1. **Create/edit note in app** -2. **Run sync** (auto or manual) -3. **JSON is uploaded** (`/notes/abc-123.json`) -4. **Markdown is exported** (`/notes-md/Note_Title.md`) _(only if Desktop Integration ON)_ -5. **Desktop editor shows changes** (after refresh) - -### Workflow: Desktop → Android - -1. **Edit Markdown file** (in mounted folder) -2. **Save** - File is immediately on server -3. **In app: Run Markdown import** - - Settings → "Import Markdown Changes" - - Or: Auto-import on every sync (future) -4. **App adopts changes** (if desktop version is newer) - -### Conflict Resolution: Last-Write-Wins - -**Rule:** Newest version (by `updated` timestamp) wins - -**Example:** -``` -App version: updated: 2026-01-05 14:00 -Desktop version: updated: 2026-01-05 14:30 -→ Desktop wins (newer timestamp) -``` - -**Automatic:** -- ✅ On Markdown import -- ✅ On JSON sync -- ⚠️ No merge conflicts - only complete overwrite - ---- - -## ⚙️ Settings - -### Desktop Integration Toggle - -**Settings → Desktop Integration** - -**ON (activated):** -- ✅ New notes → automatically exported as `.md` -- ✅ Updated notes → `.md` update -- ✅ Deleted notes → `.md` remains (future: also delete) - -**OFF (deactivated):** -- ❌ No Markdown export -- ✅ JSON sync continues normally -- ✅ Existing `.md` files remain - -### Initial Export - -**What happens on activation:** -1. All existing notes are scanned -2. Progress dialog shows progress (e.g., "23/42") -3. Each note is exported as `.md` -4. On errors: Individual note is skipped -5. Success message with number of exported notes - -**Time:** ~1-2 seconds per 50 notes - ---- - -## 🛠️ Advanced Usage - -### Manual Markdown Creation - -You can create `.md` files manually: - -```markdown ---- -id: 00000000-0000-0000-0000-000000000001 -created: 2026-01-05T12:00:00Z -updated: 2026-01-05T12:00:00Z ---- - -# New Desktop Note - -Content here... -``` - -**⚠️ Important:** -- `id` must be valid UUID (e.g., with uuidgen.io) -- Timestamps in ISO8601 format -- Frontmatter enclosed with `---` - -### Bulk Operations - -**Edit multiple notes at once:** - -1. Mount WebDAV -2. Open all `.md` files in VS Code -3. Find & Replace across all files (Ctrl+Shift+H) -4. Save -5. In app: "Import Markdown Changes" - -### Scripting - -**Example: Sort all notes by date** - -```bash -#!/bin/bash -cd /mnt/notes-md/ - -# Sort all .md files by update date -for file in *.md; do - updated=$(grep "^updated:" "$file" | cut -d' ' -f2) - echo "$updated $file" -done | sort -``` - ---- - -## ❌ Troubleshooting - -### "404 Not Found" when mounting WebDAV - -**Cause:** `/notes-md/` folder doesn't exist - -**Solution:** -1. **Perform first sync** - Folder is created automatically -2. OR: Create manually via terminal: - ```bash - curl -X MKCOL -u noteuser:password http://server:8080/notes-md/ - ``` - -### Markdown files don't appear - -**Cause:** Desktop integration not activated - -**Solution:** -1. Settings → "Desktop Integration" ON -2. Wait for initial export -3. Refresh WebDAV folder - -### Changes from desktop don't appear in app - -**Cause:** Markdown import not executed - -**Solution:** -1. Settings → "Import Markdown Changes" -2. OR: Wait for auto-sync (future feature) - -### "Frontmatter missing" error - -**Cause:** `.md` file without valid YAML frontmatter - -**Solution:** -1. Open file in editor -2. Add frontmatter at the beginning: - ```yaml - --- - id: NEW-UUID-HERE - created: 2026-01-05T12:00:00Z - updated: 2026-01-05T12:00:00Z - --- - ``` -3. Save and import again - ---- - -## 🔒 Security & Best Practices - -### Do's ✅ - -- ✅ **Backup before bulk edits** - Create local backup -- ✅ **One editor at a time** - Don't edit in app AND desktop in parallel -- ✅ **Wait for sync** - Run sync before desktop editing -- ✅ **Respect frontmatter** - Don't change manually (unless you know what you're doing) - -### Don'ts ❌ - -- ❌ **Parallel editing** - App and desktop simultaneously → conflicts -- ❌ **Delete frontmatter** - Note can't be imported anymore -- ❌ **Change IDs** - Note is recognized as new -- ❌ **Manipulate timestamps** - Conflict resolution doesn't work - -### Recommended Workflow - -``` -1. Sync in app (pull-to-refresh) -2. Open desktop -3. Make changes -4. Save -5. In app: "Import Markdown Changes" -6. Verify -7. Run another sync -``` - ---- - -## 📊 Comparison: JSON vs Markdown - -| Aspect | JSON | Markdown | -|--------|------|----------| -| **Format** | Structured | Flowing text | -| **Readability (human)** | ⚠️ Medium | ✅ Good | -| **Readability (machine)** | ✅ Perfect | ⚠️ Parsing needed | -| **Metadata** | Native | Frontmatter | -| **Editors** | Code editors | All text editors | -| **Sync speed** | ✅ Fast | ⚠️ Slower | -| **Reliability** | ✅ 100% | ⚠️ Frontmatter errors possible | -| **Mobile-first** | ✅ Yes | ❌ No | -| **Desktop-first** | ❌ No | ✅ Yes | - -**Conclusion:** Using both formats = Best experience on both platforms! - ---- - -## 🔮 Future Features - -Planned for v1.3.0+: - -- ⏳ **Auto-Markdown-import** - Automatically on every sync -- ⏳ **Bidirectional sync** - Without manual import -- ⏳ **Markdown preview** - In the app -- ⏳ **Conflict UI** - On simultaneous changes -- ⏳ **Tags in frontmatter** - Synchronized with app -- ⏳ **Attachments** - Images/files in Markdown - ---- - -**📚 See also:** -- [QUICKSTART.en.md](../QUICKSTART.en.md) - App setup -- [FEATURES.en.md](FEATURES.en.md) - Complete feature list -- [BACKUP.en.md](BACKUP.en.md) - Backup & restore - -**Last update:** v1.2.1 (2026-01-05) diff --git a/docs/DESKTOP.md b/docs/DESKTOP.md index 3cac251..82b1c74 100644 --- a/docs/DESKTOP.md +++ b/docs/DESKTOP.md @@ -1,24 +1,24 @@ -# Desktop-Integration 🖥️ +# Desktop Integration 🖥️ -**🌍 Languages:** **Deutsch** · [English](DESKTOP.en.md) +**🌍 Languages:** [Deutsch](DESKTOP.de.md) · **English** -> Bearbeite deine Notizen mit jedem Markdown-Editor auf dem Desktop +> Edit your notes with any Markdown editor on desktop --- -## 📋 Übersicht +## 📋 Overview -Die Desktop-Integration ermöglicht dir, Notizen auf dem PC/Mac zu bearbeiten: -- 📝 Jeder Markdown-Editor funktioniert -- 🔄 Automatische Synchronisation über WebDAV -- 💾 Dual-Format: JSON (Master) + Markdown (Mirror) -- ⚡ Last-Write-Wins Konfliktauflösung +Desktop integration allows you to edit notes on PC/Mac: +- 📝 Any Markdown editor works +- 🔄 Automatic synchronization via WebDAV +- 💾 Dual-format: JSON (master) + Markdown (mirror) +- ⚡ Last-Write-Wins conflict resolution --- -## 🎯 Warum Markdown? +## 🎯 Why Markdown? -### Dual-Format Architektur +### Dual-Format Architecture ``` ┌─────────────────────────────────────┐ @@ -45,85 +45,85 @@ Die Desktop-Integration ermöglicht dir, Notizen auf dem PC/Mac zu bearbeiten: └──────────────────────────────────┘ ``` -### Vorteile +### Advantages **JSON (Master):** -- ✅ Zuverlässig und schnell -- ✅ Strukturierte Daten (IDs, Timestamps) -- ✅ Primärer Sync-Mechanismus -- ✅ Immer aktiv +- ✅ Reliable and fast +- ✅ Structured data (IDs, timestamps) +- ✅ Primary sync mechanism +- ✅ Always active **Markdown (Mirror):** -- ✅ Menschenlesbar -- ✅ Desktop-Editor kompatibel -- ✅ Syntax-Highlighting -- ✅ Optional aktivierbar +- ✅ Human-readable +- ✅ Desktop editor compatible +- ✅ Syntax highlighting +- ✅ Optionally activatable --- -## 🚀 Schnellstart +## 🚀 Quick Start -### 1. Erste Synchronisation +### 1. First Synchronization -**Wichtig:** Führe ZUERST einen Sync durch, bevor du Desktop-Integration aktivierst! +**Important:** Perform a sync FIRST before activating desktop integration! -1. **App einrichten** (siehe [QUICKSTART.md](QUICKSTART.md)) -2. **Server-Verbindung testen** -3. **Erste Notiz erstellen** -4. **Synchronisieren** (Pull-to-Refresh oder Auto-Sync) -5. ✅ Server erstellt automatisch `/notes/` und `/notes-md/` Ordner +1. **Set up app** (see [QUICKSTART.en.md](QUICKSTART.en.md)) +2. **Test server connection** +3. **Create first note** +4. **Synchronize** (pull-to-refresh or auto-sync) +5. ✅ Server automatically creates `/notes/` and `/notes-md/` folders -### 2. Desktop-Integration aktivieren +### 2. Activate Desktop Integration -1. **Einstellungen** → **Desktop-Integration** -2. **Toggle aktivieren** -3. **Initial Export startet** - Zeigt Progress (X/Y) -4. ✅ Alle bestehenden Notizen werden als `.md` exportiert +1. **Settings** → **Desktop Integration** +2. **Toggle ON** +3. **Initial export starts** - Shows progress (X/Y) +4. ✅ All existing notes are exported as `.md` -### 3. WebDAV als Netzlaufwerk mounten +### 3. Mount WebDAV as Network Drive #### Windows ``` -1. Explorer öffnen -2. Rechtsklick auf "Dieser PC" -3. "Netzlaufwerk verbinden" -4. URL eingeben: http://DEIN-SERVER:8080/notes-md/ -5. Benutzername: noteuser -6. Passwort: (dein WebDAV-Passwort) -7. Laufwerksbuchstabe: Z:\ (oder beliebig) -8. Fertig! +1. Open Explorer +2. Right-click on "This PC" +3. "Map network drive" +4. Enter URL: http://YOUR-SERVER:8080/notes-md/ +5. Username: noteuser +6. Password: (your WebDAV password) +7. Drive letter: Z:\ (or any) +8. Done! ``` -**Zugriff:** `Z:\` im Explorer +**Access:** `Z:\` in Explorer #### macOS ``` -1. Finder öffnen -2. Menü "Gehe zu" → "Mit Server verbinden" (⌘K) -3. Server-Adresse: http://DEIN-SERVER:8080/notes-md/ -4. Verbinden -5. Benutzername: noteuser -6. Passwort: (dein WebDAV-Passwort) -7. Fertig! +1. Open Finder +2. Menu "Go" → "Connect to Server" (⌘K) +3. Server address: http://YOUR-SERVER:8080/notes-md/ +4. Connect +5. Username: noteuser +6. Password: (your WebDAV password) +7. Done! ``` -**Zugriff:** Finder → Netzwerk → notes-md +**Access:** Finder → Network → notes-md #### Linux (GNOME) ``` -1. Files / Nautilus öffnen -2. "Andere Orte" -3. "Mit Server verbinden" -4. Server-Adresse: dav://DEIN-SERVER:8080/notes-md/ -5. Benutzername: noteuser -6. Passwort: (dein WebDAV-Passwort) -7. Fertig! +1. Open Files / Nautilus +2. "Other Locations" +3. "Connect to Server" +4. Server address: dav://YOUR-SERVER:8080/notes-md/ +5. Username: noteuser +6. Password: (your WebDAV password) +7. Done! ``` -**Zugriff:** `/run/user/1000/gvfs/dav:host=...` +**Access:** `/run/user/1000/gvfs/dav:host=...` #### Linux (davfs2 - permanent) @@ -131,101 +131,101 @@ Die Desktop-Integration ermöglicht dir, Notizen auf dem PC/Mac zu bearbeiten: # Installation sudo apt install davfs2 -# Mount-Point erstellen +# Create mount point sudo mkdir -p /mnt/notes-md -# Einmalig mounten -sudo mount -t davfs http://DEIN-SERVER:8080/notes-md/ /mnt/notes-md +# Mount once +sudo mount -t davfs http://YOUR-SERVER:8080/notes-md/ /mnt/notes-md # Permanent in /etc/fstab -echo "http://DEIN-SERVER:8080/notes-md/ /mnt/notes-md davfs rw,user,noauto 0 0" | sudo tee -a /etc/fstab +echo "http://YOUR-SERVER:8080/notes-md/ /mnt/notes-md davfs rw,user,noauto 0 0" | sudo tee -a /etc/fstab ``` -**Zugriff:** `/mnt/notes-md/` +**Access:** `/mnt/notes-md/` --- -## 📝 Markdown-Editoren +## 📝 Markdown Editors -### Empfohlene Editoren +### Recommended Editors -#### 1. VS Code ⭐ _Empfohlen_ +#### 1. VS Code ⭐ _Recommended_ -**Vorteile:** -- ✅ Kostenlos & Open Source -- ✅ Markdown-Preview (Ctrl+Shift+V) -- ✅ Syntax-Highlighting -- ✅ Git-Integration -- ✅ Erweiterungen (Spell Check, etc.) +**Advantages:** +- ✅ Free & open source +- ✅ Markdown preview (Ctrl+Shift+V) +- ✅ Syntax highlighting +- ✅ Git integration +- ✅ Extensions (spell check, etc.) **Setup:** ``` -1. VS Code installieren -2. WebDAV-Laufwerk mounten -3. Ordner öffnen: Z:\notes-md\ (Windows) oder /mnt/notes-md (Linux) -4. Fertig! Markdown-Dateien bearbeiten +1. Install VS Code +2. Mount WebDAV drive +3. Open folder: Z:\notes-md\ (Windows) or /mnt/notes-md (Linux) +4. Done! Edit Markdown files ``` **Extensions (optional):** -- `Markdown All in One` - Shortcuts & Preview -- `Markdown Preview Enhanced` - Bessere Preview -- `Code Spell Checker` - Rechtschreibprüfung +- `Markdown All in One` - Shortcuts & preview +- `Markdown Preview Enhanced` - Better preview +- `Code Spell Checker` - Spell checking #### 2. Typora -**Vorteile:** -- ✅ WYSIWYG Markdown-Editor -- ✅ Minimalistisches Design -- ✅ Live-Preview -- ⚠️ Kostenpflichtig (~15€) +**Advantages:** +- ✅ WYSIWYG Markdown editor +- ✅ Minimalist design +- ✅ Live preview +- ⚠️ Paid (~15€) **Setup:** ``` -1. Typora installieren -2. WebDAV mounten -3. Ordner in Typora öffnen -4. Notizen bearbeiten +1. Install Typora +2. Mount WebDAV +3. Open folder in Typora +4. Edit notes ``` #### 3. Notepad++ -**Vorteile:** -- ✅ Leichtgewichtig -- ✅ Schnell -- ✅ Syntax-Highlighting -- ⚠️ Keine Markdown-Preview +**Advantages:** +- ✅ Lightweight +- ✅ Fast +- ✅ Syntax highlighting +- ⚠️ No Markdown preview **Setup:** ``` -1. Notepad++ installieren -2. WebDAV mounten -3. Dateien direkt öffnen +1. Install Notepad++ +2. Mount WebDAV +3. Open files directly ``` #### 4. Obsidian -**Vorteile:** -- ✅ Zweite Gehirn-Philosophie -- ✅ Graph-View für Verlinkungen -- ✅ Viele Plugins -- ⚠️ Sync-Konflikte möglich (2 Master) +**Advantages:** +- ✅ Second brain philosophy +- ✅ Graph view for links +- ✅ Many plugins +- ⚠️ Sync conflicts possible (2 masters) **Setup:** ``` -1. Obsidian installieren -2. WebDAV als Vault öffnen -3. Vorsicht: Obsidian erstellt eigene Metadaten! +1. Install Obsidian +2. Open WebDAV as vault +3. Caution: Obsidian creates own metadata! ``` -**⚠️ Nicht empfohlen:** Kann Frontmatter verändern +**⚠️ Not recommended:** Can alter frontmatter --- -## 📄 Markdown-Dateiformat +## 📄 Markdown File Format -### Struktur +### Structure -Jede Notiz wird als `.md` Datei mit YAML-Frontmatter exportiert: +Each note is exported as `.md` file with YAML frontmatter: ```markdown --- @@ -235,114 +235,114 @@ updated: 2026-01-05T14:30:22Z tags: [] --- -# Notiz-Titel +# Note Title -Notiz-Inhalt hier... +Note content here... ``` -### Frontmatter-Felder +### Frontmatter Fields -| Feld | Typ | Beschreibung | Pflicht | -|------|-----|--------------|---------| -| `id` | UUID | Eindeutige Notiz-ID | ✅ Ja | -| `created` | ISO8601 | Erstellungsdatum | ✅ Ja | -| `updated` | ISO8601 | Änderungsdatum | ✅ Ja | -| `tags` | Array | Tags (zukünftig) | ❌ Nein | +| Field | Type | Description | Required | +|-------|------|-------------|----------| +| `id` | UUID | Unique note ID | ✅ Yes | +| `created` | ISO8601 | Creation date | ✅ Yes | +| `updated` | ISO8601 | Modification date | ✅ Yes | +| `tags` | Array | Tags (future) | ❌ No | -### Dateinamen +### Filenames -**Sanitization-Regeln:** +**Sanitization rules:** ``` -Titel: "Meine Einkaufsliste 🛒" -→ Dateiname: "Meine_Einkaufsliste.md" +Title: "My Shopping List 🛒" +→ Filename: "My_Shopping_List.md" -Entfernt werden: -- Emojis: 🛒 → entfernt -- Sonderzeichen: / \ : * ? " < > | → entfernt -- Mehrfache Leerzeichen → einzelnes Leerzeichen -- Leerzeichen → Unterstrich _ +Removed: +- Emojis: 🛒 → removed +- Special chars: / \ : * ? " < > | → removed +- Multiple spaces → single space +- Spaces → underscore _ ``` -**Beispiele:** +**Examples:** ``` "Meeting Notes 2026" → "Meeting_Notes_2026.md" -"To-Do: Projekt" → "To-Do_Projekt.md" -"Urlaub ☀️" → "Urlaub.md" +"To-Do: Project" → "To-Do_Project.md" +"Vacation ☀️" → "Vacation.md" ``` --- -## 🔄 Synchronisation +## 🔄 Synchronization ### Workflow: Android → Desktop -1. **Notiz in App erstellen/bearbeiten** -2. **Sync ausführen** (Auto oder manuell) -3. **JSON wird hochgeladen** (`/notes/abc-123.json`) -4. **Markdown wird exportiert** (`/notes-md/Notiz_Titel.md`) _(nur wenn Desktop-Integration AN)_ -5. **Desktop-Editor zeigt Änderungen** (nach Refresh) +1. **Create/edit note in app** +2. **Run sync** (auto or manual) +3. **JSON is uploaded** (`/notes/abc-123.json`) +4. **Markdown is exported** (`/notes-md/Note_Title.md`) _(only if Desktop Integration ON)_ +5. **Desktop editor shows changes** (after refresh) ### Workflow: Desktop → Android -1. **Markdown-Datei bearbeiten** (im gemounteten Ordner) -2. **Speichern** - Datei liegt sofort auf Server -3. **In App: Markdown-Import ausführen** - - Einstellungen → "Import Markdown Changes" - - Oder: Auto-Import bei jedem Sync (zukünftig) -4. **App übernimmt Änderungen** (wenn Desktop-Version neuer) +1. **Edit Markdown file** (in mounted folder) +2. **Save** - File is immediately on server +3. **In app: Run Markdown import** + - Settings → "Import Markdown Changes" + - Or: Auto-import on every sync (future) +4. **App adopts changes** (if desktop version is newer) -### Konfliktauflösung: Last-Write-Wins +### Conflict Resolution: Last-Write-Wins -**Regel:** Neueste Version (nach `updated` Timestamp) gewinnt +**Rule:** Newest version (by `updated` timestamp) wins -**Beispiel:** +**Example:** ``` -App-Version: updated: 2026-01-05 14:00 -Desktop-Version: updated: 2026-01-05 14:30 -→ Desktop gewinnt (neuerer Timestamp) +App version: updated: 2026-01-05 14:00 +Desktop version: updated: 2026-01-05 14:30 +→ Desktop wins (newer timestamp) ``` -**Automatisch:** -- ✅ Beim Markdown-Import -- ✅ Beim JSON-Sync -- ⚠️ Keine Merge-Konflikte - nur komplettes Überschreiben +**Automatic:** +- ✅ On Markdown import +- ✅ On JSON sync +- ⚠️ No merge conflicts - only complete overwrite --- -## ⚙️ Einstellungen +## ⚙️ Settings -### Desktop-Integration Toggle +### Desktop Integration Toggle -**Einstellungen → Desktop-Integration** +**Settings → Desktop Integration** -**AN (aktiviert):** -- ✅ Neue Notizen → automatisch als `.md` exportiert -- ✅ Aktualisierte Notizen → `.md` Update -- ✅ Gelöschte Notizen → `.md` bleibt (zukünftig: auch löschen) +**ON (activated):** +- ✅ New notes → automatically exported as `.md` +- ✅ Updated notes → `.md` update +- ✅ Deleted notes → `.md` remains (future: also delete) -**AUS (deaktiviert):** -- ❌ Kein Markdown-Export -- ✅ JSON-Sync läuft normal weiter -- ✅ Bestehende `.md` Dateien bleiben erhalten +**OFF (deactivated):** +- ❌ No Markdown export +- ✅ JSON sync continues normally +- ✅ Existing `.md` files remain ### Initial Export -**Was passiert beim Aktivieren:** -1. Alle bestehenden Notizen werden gescannt -2. Progress-Dialog zeigt Fortschritt (z.B. "23/42") -3. Jede Notiz wird als `.md` exportiert -4. Bei Fehlern: Einzelne Notiz wird übersprungen -5. Erfolgsmeldung mit Anzahl exportierter Notizen +**What happens on activation:** +1. All existing notes are scanned +2. Progress dialog shows progress (e.g., "23/42") +3. Each note is exported as `.md` +4. On errors: Individual note is skipped +5. Success message with number of exported notes -**Zeit:** ~1-2 Sekunden pro 50 Notizen +**Time:** ~1-2 seconds per 50 notes --- -## 🛠️ Erweiterte Nutzung +## 🛠️ Advanced Usage -### Manuelle Markdown-Erstellung +### Manual Markdown Creation -Du kannst `.md` Dateien manuell erstellen: +You can create `.md` files manually: ```markdown --- @@ -351,35 +351,35 @@ created: 2026-01-05T12:00:00Z updated: 2026-01-05T12:00:00Z --- -# Neue Desktop-Notiz +# New Desktop Note -Inhalt hier... +Content here... ``` -**⚠️ Wichtig:** -- `id` muss gültige UUID sein (z.B. mit uuidgen.io) -- Timestamps in ISO8601-Format -- Frontmatter mit `---` umschließen +**⚠️ Important:** +- `id` must be valid UUID (e.g., with uuidgen.io) +- Timestamps in ISO8601 format +- Frontmatter enclosed with `---` -### Bulk-Operations +### Bulk Operations -**Mehrere Notizen auf einmal bearbeiten:** +**Edit multiple notes at once:** -1. WebDAV mounten -2. Alle `.md` Dateien in VS Code öffnen -3. Suchen & Ersetzen über alle Dateien (Ctrl+Shift+H) -4. Speichern -5. In App: "Import Markdown Changes" +1. Mount WebDAV +2. Open all `.md` files in VS Code +3. Find & Replace across all files (Ctrl+Shift+H) +4. Save +5. In app: "Import Markdown Changes" ### Scripting -**Beispiel: Alle Notizen nach Datum sortieren** +**Example: Sort all notes by date** ```bash #!/bin/bash cd /mnt/notes-md/ -# Alle .md Dateien nach Update-Datum sortieren +# Sort all .md files by update date for file in *.md; do updated=$(grep "^updated:" "$file" | cut -d' ' -f2) echo "$updated $file" @@ -388,118 +388,118 @@ done | sort --- -## ❌ Fehlerbehebung +## ❌ Troubleshooting -### "404 Not Found" beim WebDAV-Mount +### "404 Not Found" when mounting WebDAV -**Ursache:** `/notes-md/` Ordner existiert nicht +**Cause:** `/notes-md/` folder doesn't exist -**Lösung:** -1. **Erste Sync durchführen** - Ordner wird automatisch erstellt -2. ODER: Manuell erstellen via Terminal: +**Solution:** +1. **Perform first sync** - Folder is created automatically +2. OR: Create manually via terminal: ```bash curl -X MKCOL -u noteuser:password http://server:8080/notes-md/ ``` -### Markdown-Dateien erscheinen nicht +### Markdown files don't appear -**Ursache:** Desktop-Integration nicht aktiviert +**Cause:** Desktop integration not activated -**Lösung:** -1. Einstellungen → "Desktop-Integration" AN -2. Warten auf Initial Export -3. WebDAV-Ordner refreshen +**Solution:** +1. Settings → "Desktop Integration" ON +2. Wait for initial export +3. Refresh WebDAV folder -### Änderungen vom Desktop erscheinen nicht in App +### Changes from desktop don't appear in app -**Ursache:** Markdown-Import nicht ausgeführt +**Cause:** Markdown import not executed -**Lösung:** -1. Einstellungen → "Import Markdown Changes" -2. ODER: Auto-Sync abwarten (zukünftiges Feature) +**Solution:** +1. Settings → "Import Markdown Changes" +2. OR: Wait for auto-sync (future feature) -### "Frontmatter fehlt" Fehler +### "Frontmatter missing" error -**Ursache:** `.md` Datei ohne gültiges YAML-Frontmatter +**Cause:** `.md` file without valid YAML frontmatter -**Lösung:** -1. Datei in Editor öffnen -2. Frontmatter am Anfang hinzufügen: +**Solution:** +1. Open file in editor +2. Add frontmatter at the beginning: ```yaml --- - id: NEUE-UUID-HIER + id: NEW-UUID-HERE created: 2026-01-05T12:00:00Z updated: 2026-01-05T12:00:00Z --- ``` -3. Speichern und erneut importieren +3. Save and import again --- -## 🔒 Sicherheit & Best Practices +## 🔒 Security & Best Practices ### Do's ✅ -- ✅ **Backup vor Bulk-Edits** - Lokales Backup erstellen -- ✅ **Ein Editor zur Zeit** - Nicht parallel in App UND Desktop bearbeiten -- ✅ **Sync abwarten** - Vor Desktop-Bearbeitung Sync durchführen -- ✅ **Frontmatter respektieren** - Nicht manuell ändern (außer du weißt was du tust) +- ✅ **Backup before bulk edits** - Create local backup +- ✅ **One editor at a time** - Don't edit in app AND desktop in parallel +- ✅ **Wait for sync** - Run sync before desktop editing +- ✅ **Respect frontmatter** - Don't change manually (unless you know what you're doing) ### Don'ts ❌ -- ❌ **Parallel bearbeiten** - App und Desktop gleichzeitig → Konflikte -- ❌ **Frontmatter löschen** - Notiz kann nicht mehr importiert werden -- ❌ **IDs ändern** - Notiz wird als neue erkannt -- ❌ **Timestamps manipulieren** - Konfliktauflösung funktioniert nicht +- ❌ **Parallel editing** - App and desktop simultaneously → conflicts +- ❌ **Delete frontmatter** - Note can't be imported anymore +- ❌ **Change IDs** - Note is recognized as new +- ❌ **Manipulate timestamps** - Conflict resolution doesn't work -### Empfohlener Workflow +### Recommended Workflow ``` -1. Sync in App (Pull-to-Refresh) -2. Desktop öffnen -3. Änderungen machen -4. Speichern -5. In App: "Import Markdown Changes" -6. Überprüfen -7. Weiteren Sync durchführen +1. Sync in app (pull-to-refresh) +2. Open desktop +3. Make changes +4. Save +5. In app: "Import Markdown Changes" +6. Verify +7. Run another sync ``` --- -## 📊 Vergleich: JSON vs Markdown +## 📊 Comparison: JSON vs Markdown -| Aspekt | JSON | Markdown | +| Aspect | JSON | Markdown | |--------|------|----------| -| **Format** | Strukturiert | Fließtext | -| **Lesbarkeit (Mensch)** | ⚠️ Mittel | ✅ Gut | -| **Lesbarkeit (Maschine)** | ✅ Perfekt | ⚠️ Parsing nötig | +| **Format** | Structured | Flowing text | +| **Readability (human)** | ⚠️ Medium | ✅ Good | +| **Readability (machine)** | ✅ Perfect | ⚠️ Parsing needed | | **Metadata** | Native | Frontmatter | -| **Editoren** | Code-Editoren | Alle Text-Editoren | -| **Sync-Geschwindigkeit** | ✅ Schnell | ⚠️ Langsamer | -| **Zuverlässigkeit** | ✅ 100% | ⚠️ Frontmatter-Fehler möglich | -| **Mobile-First** | ✅ Ja | ❌ Nein | -| **Desktop-First** | ❌ Nein | ✅ Ja | +| **Editors** | Code editors | All text editors | +| **Sync speed** | ✅ Fast | ⚠️ Slower | +| **Reliability** | ✅ 100% | ⚠️ Frontmatter errors possible | +| **Mobile-first** | ✅ Yes | ❌ No | +| **Desktop-first** | ❌ No | ✅ Yes | -**Fazit:** Beide Formate nutzen = Beste Erfahrung auf beiden Plattformen! +**Conclusion:** Using both formats = Best experience on both platforms! --- -## 🔮 Zukünftige Features +## 🔮 Future Features -Geplant für v1.3.0+: +Planned for v1.3.0+: -- ⏳ **Auto-Markdown-Import** - Bei jedem Sync automatisch -- ⏳ **Bidirektionaler Sync** - Ohne manuellen Import -- ⏳ **Markdown-Vorschau** - In der App -- ⏳ **Konflikts-UI** - Bei gleichzeitigen Änderungen -- ⏳ **Tags in Frontmatter** - Synchronisiert mit App -- ⏳ **Attachments** - Bilder/Dateien in Markdown +- ⏳ **Auto-Markdown-import** - Automatically on every sync +- ⏳ **Bidirectional sync** - Without manual import +- ⏳ **Markdown preview** - In the app +- ⏳ **Conflict UI** - On simultaneous changes +- ⏳ **Tags in frontmatter** - Synchronized with app +- ⏳ **Attachments** - Images/files in Markdown --- -**📚 Siehe auch:** -- [QUICKSTART.md](../QUICKSTART.md) - App-Einrichtung -- [FEATURES.md](FEATURES.md) - Vollständige Feature-Liste -- [BACKUP.md](BACKUP.md) - Backup & Wiederherstellung +**📚 See also:** +- [QUICKSTART.en.md](../QUICKSTART.en.md) - App setup +- [FEATURES.en.md](FEATURES.en.md) - Complete feature list +- [BACKUP.en.md](BACKUP.en.md) - Backup & restore -**Letzte Aktualisierung:** v1.2.1 (2026-01-05) +**Last update:** v1.2.1 (2026-01-05) diff --git a/docs/DOCS.en.md b/docs/DOCS.de.md similarity index 54% rename from docs/DOCS.en.md rename to docs/DOCS.de.md index b9c551f..d371b78 100644 --- a/docs/DOCS.en.md +++ b/docs/DOCS.de.md @@ -1,14 +1,14 @@ -# Simple Notes Sync - Technical Documentation +# Simple Notes Sync - Technische Dokumentation -This file contains detailed technical information about implementation, architecture, and advanced features. +Diese Datei enthält detaillierte technische Informationen über die Implementierung, Architektur und erweiterte Funktionen. -**🌍 Languages:** [Deutsch](DOCS.md) · **English** +**🌍 Sprachen:** **Deutsch** · [English](DOCS.md) --- -## 📐 Architecture +## 📐 Architektur -### Overall Overview +### Gesamtübersicht ``` ┌─────────────────┐ @@ -23,81 +23,81 @@ This file contains detailed technical information about implementation, architec └─────────────────┘ ``` -### Android App Architecture +### Android App Architektur ``` app/ ├── models/ -│ ├── Note.kt # Data class for notes -│ └── SyncStatus.kt # Sync status enum +│ ├── Note.kt # Data class für Notizen +│ └── SyncStatus.kt # Sync-Status Enum ├── storage/ -│ └── NotesStorage.kt # Local JSON file storage +│ └── NotesStorage.kt # Lokale JSON-Datei Speicherung ├── sync/ -│ ├── WebDavSyncService.kt # WebDAV sync logic -│ ├── NetworkMonitor.kt # WiFi detection -│ ├── SyncWorker.kt # WorkManager background worker -│ └── BootReceiver.kt # Device reboot handler +│ ├── WebDavSyncService.kt # WebDAV Sync-Logik +│ ├── NetworkMonitor.kt # WLAN-Erkennung +│ ├── SyncWorker.kt # WorkManager Background Worker +│ └── BootReceiver.kt # Device Reboot Handler ├── adapters/ -│ └── NotesAdapter.kt # RecyclerView adapter +│ └── NotesAdapter.kt # RecyclerView Adapter ├── utils/ -│ ├── Constants.kt # App constants -│ ├── NotificationHelper.kt# Notification management -│ └── Logger.kt # Debug/release logging +│ ├── Constants.kt # App-Konstanten +│ ├── NotificationHelper.kt# Notification Management +│ └── Logger.kt # Debug/Release Logging └── activities/ - ├── MainActivity.kt # Main view with list - ├── NoteEditorActivity.kt# Note editor - └── SettingsActivity.kt # Server configuration + ├── MainActivity.kt # Hauptansicht mit Liste + ├── NoteEditorActivity.kt# Editor für Notizen + └── SettingsActivity.kt # Server-Konfiguration ``` --- -## 🔄 Auto-Sync Implementation +## 🔄 Auto-Sync Implementierung ### WorkManager Periodic Task -Auto-sync is based on **WorkManager** with the following configuration: +Der Auto-Sync basiert auf **WorkManager** mit folgender Konfiguration: ```kotlin val constraints = Constraints.Builder() - .setRequiredNetworkType(NetworkType.UNMETERED) // WiFi only + .setRequiredNetworkType(NetworkType.UNMETERED) // Nur WiFi .build() val syncRequest = PeriodicWorkRequestBuilder( - 30, TimeUnit.MINUTES, // Every 30 minutes + 30, TimeUnit.MINUTES, // Alle 30 Minuten 10, TimeUnit.MINUTES // Flex interval ) .setConstraints(constraints) .build() ``` -**Why WorkManager?** -- ✅ Runs even when app is closed -- ✅ Automatic restart after device reboot +**Warum WorkManager?** +- ✅ Läuft auch wenn App geschlossen ist +- ✅ Automatischer Restart nach Device Reboot - ✅ Battery-efficient (Android managed) -- ✅ Guaranteed execution when constraints are met +- ✅ Garantierte Ausführung bei erfüllten Constraints ### Network Detection -We use **Gateway IP Comparison** to check if the server is reachable: +Wir verwenden **Gateway IP Comparison** um zu prüfen, ob der Server erreichbar ist: ```kotlin fun isInHomeNetwork(): Boolean { - val gatewayIP = getGatewayIP() // e.g. 192.168.0.1 - val serverIP = extractIPFromUrl(serverUrl) // e.g. 192.168.0.188 + val gatewayIP = getGatewayIP() // z.B. 192.168.0.1 + val serverIP = extractIPFromUrl(serverUrl) // z.B. 192.168.0.188 - return isSameNetwork(gatewayIP, serverIP) // Checks /24 network + return isSameNetwork(gatewayIP, serverIP) // Prüft /24 Netzwerk } ``` -**Advantages:** -- ✅ No location permissions needed -- ✅ Works with all Android versions -- ✅ Reliable and fast +**Vorteile:** +- ✅ Keine Location Permissions nötig +- ✅ Funktioniert mit allen Android Versionen +- ✅ Zuverlässig und schnell ### Sync Flow ``` -1. WorkManager wakes up (every 30 min) +1. WorkManager wacht auf (alle 30 Min) ↓ 2. Check: WiFi connected? ↓ @@ -105,7 +105,7 @@ fun isInHomeNetwork(): Boolean { ↓ 4. Load local notes ↓ -5. Upload new/changed notes → Server +5. Upload neue/geänderte Notes → Server ↓ 6. Download remote notes ← Server ↓ @@ -118,20 +118,20 @@ fun isInHomeNetwork(): Boolean { --- -## 🔄 Sync Trigger Overview +## � Sync-Trigger Übersicht -The app uses **4 different sync triggers** with different use cases: +Die App verwendet **4 verschiedene Sync-Trigger** mit unterschiedlichen Anwendungsfällen: -| Trigger | File | Function | When? | Pre-Check? | -|---------|------|----------|-------|------------| -| **1. Manual Sync** | `MainActivity.kt` | `triggerManualSync()` | User clicks sync button in menu | ✅ Yes | -| **2. Auto-Sync (onResume)** | `MainActivity.kt` | `triggerAutoSync()` | App opened/resumed | ✅ Yes | -| **3. Background Sync (Periodic)** | `SyncWorker.kt` | `doWork()` | Every 15/30/60 minutes (configurable) | ✅ Yes | -| **4. WiFi-Connect Sync** | `NetworkMonitor.kt` → `SyncWorker.kt` | `triggerWifiConnectSync()` | WiFi connected | ✅ Yes | +| Trigger | Datei | Funktion | Wann? | Pre-Check? | +|---------|-------|----------|-------|------------| +| **1. Manueller Sync** | `MainActivity.kt` | `triggerManualSync()` | User klickt auf Sync-Button im Menü | ✅ Ja | +| **2. Auto-Sync (onResume)** | `MainActivity.kt` | `triggerAutoSync()` | App wird geöffnet/fortgesetzt | ✅ Ja | +| **3. Hintergrund-Sync (Periodic)** | `SyncWorker.kt` | `doWork()` | Alle 15/30/60 Minuten (konfigurierbar) | ✅ Ja | +| **4. WiFi-Connect Sync** | `NetworkMonitor.kt` → `SyncWorker.kt` | `triggerWifiConnectSync()` | WiFi verbunden | ✅ Ja | -### Server Reachability Check (Pre-Check) +### Server-Erreichbarkeits-Check (Pre-Check) -**All 4 sync triggers** use a **pre-check** before the actual sync: +**Alle 4 Sync-Trigger** verwenden vor dem eigentlichen Sync einen **Pre-Check**: ```kotlin // WebDavSyncService.kt - isServerReachable() @@ -148,53 +148,53 @@ suspend fun isServerReachable(): Boolean = withContext(Dispatchers.IO) { } ``` -**Why Socket Check instead of HTTP Request?** -- ⚡ **Faster:** Socket connect is instant, HTTP request takes longer -- 🔋 **Battery Efficient:** No HTTP overhead (headers, TLS handshake, etc.) -- 🎯 **More Precise:** Only checks network reachability, not server logic -- 🛡️ **Prevents Errors:** Detects foreign WiFi networks before sync error occurs +**Warum Socket-Check statt HTTP-Request?** +- ⚡ **Schneller:** Socket-Connect ist instant, HTTP-Request dauert länger +- 🔋 **Akkuschonender:** Kein HTTP-Overhead (Headers, TLS Handshake, etc.) +- 🎯 **Präziser:** Prüft nur Netzwerk-Erreichbarkeit, nicht Server-Logik +- 🛡️ **Verhindert Fehler:** Erkennt fremde WiFi-Netze bevor Sync-Fehler entsteht -**When does the check fail?** -- ❌ Server offline/unreachable -- ❌ Wrong WiFi network (e.g. public café WiFi) -- ❌ Network not ready yet (DHCP/routing delay after WiFi connect) -- ❌ VPN blocks server access -- ❌ No WebDAV server URL configured +**Wann schlägt der Check fehl?** +- ❌ Server offline/nicht erreichbar +- ❌ Falsches WiFi-Netzwerk (z.B. öffentliches Café-WiFi) +- ❌ Netzwerk noch nicht bereit (DHCP/Routing-Delay nach WiFi-Connect) +- ❌ VPN blockiert Server-Zugriff +- ❌ Keine WebDAV-Server-URL konfiguriert -### Sync Behavior by Trigger Type +### Sync-Verhalten nach Trigger-Typ -| Trigger | When server not reachable | On successful sync | Throttling | -|---------|--------------------------|-------------------|------------| -| Manual Sync | Toast: "Server not reachable" | Toast: "✅ Synced: X notes" | None | -| Auto-Sync (onResume) | Silent abort (no toast) | Toast: "✅ Synced: X notes" | Max. 1x/min | -| Background Sync | Silent abort (no toast) | Silent (LocalBroadcast only) | 15/30/60 min | -| WiFi-Connect Sync | Silent abort (no toast) | Silent (LocalBroadcast only) | WiFi-based | +| Trigger | Bei Server nicht erreichbar | Bei erfolgreichem Sync | Throttling | +|---------|----------------------------|----------------------|------------| +| Manueller Sync | Toast: "Server nicht erreichbar" | Toast: "✅ Gesynct: X Notizen" | Keins | +| Auto-Sync (onResume) | Silent abort (kein Toast) | Toast: "✅ Gesynct: X Notizen" | Max. 1x/Min | +| Hintergrund-Sync | Silent abort (kein Toast) | Silent (LocalBroadcast only) | 15/30/60 Min | +| WiFi-Connect Sync | Silent abort (kein Toast) | Silent (LocalBroadcast only) | WiFi-basiert | --- -## 🔋 Battery Optimization +## 🔋 Akku-Optimierung -### Usage Analysis +### Verbrauchsanalyse -| Component | Frequency | Usage | Details | +| Komponente | Frequenz | Verbrauch | Details | |------------|----------|-----------|---------| -| WorkManager Wakeup | Every 30 min | ~0.15 mAh | System wakes up | -| Network Check | 48x/day | ~0.03 mAh | Gateway IP check | -| WebDAV Sync | 2-3x/day | ~1.5 mAh | Only when changes | -| **Total** | - | **~12 mAh/day** | **~0.4%** at 3000mAh | +| WorkManager Wakeup | Alle 30 Min | ~0.15 mAh | System wacht auf | +| Network Check | 48x/Tag | ~0.03 mAh | Gateway IP check | +| WebDAV Sync | 2-3x/Tag | ~1.5 mAh | Nur bei Änderungen | +| **Total** | - | **~12 mAh/Tag** | **~0.4%** bei 3000mAh | -### Optimizations +### Optimierungen 1. **IP Caching** ```kotlin private var cachedServerIP: String? = null - // DNS lookup only once at start, not every check + // DNS lookup nur 1x beim Start, nicht bei jedem Check ``` 2. **Throttling** ```kotlin private var lastSyncTime = 0L - private const val MIN_SYNC_INTERVAL_MS = 60_000L // Max 1 sync/min + private const val MIN_SYNC_INTERVAL_MS = 60_000L // Max 1 Sync/Min ``` 3. **Conditional Logging** @@ -207,9 +207,9 @@ suspend fun isServerReachable(): Boolean = withContext(Dispatchers.IO) { ``` 4. **Network Constraints** - - WiFi only (not mobile data) - - Only when server is reachable - - No permanent listeners + - Nur WiFi (nicht mobile Daten) + - Nur wenn Server erreichbar + - Keine permanenten Listeners --- @@ -255,15 +255,15 @@ suspend fun downloadNotes(): DownloadResult { val localNote = storage.loadNote(remoteNote.id) if (localNote == null) { - // New note from server + // Neue Note vom Server storage.saveNote(remoteNote) downloadedCount++ } else if (localNote.modifiedAt < remoteNote.modifiedAt) { - // Server has newer version + // Server hat neuere Version storage.saveNote(remoteNote) downloadedCount++ } else if (localNote.modifiedAt > remoteNote.modifiedAt) { - // Local version is newer → Conflict + // Lokale Version ist neuer → Conflict resolveConflict(localNote, remoteNote) conflictCount++ } @@ -275,19 +275,19 @@ suspend fun downloadNotes(): DownloadResult { ### Conflict Resolution -Strategy: **Last-Write-Wins** with **Conflict Copy** +Strategie: **Last-Write-Wins** mit **Conflict Copy** ```kotlin fun resolveConflict(local: Note, remote: Note) { - // Rename remote note (conflict copy) + // Remote Note umbenennen (Conflict Copy) val conflictNote = remote.copy( id = "${remote.id}_conflict_${System.currentTimeMillis()}", - title = "${remote.title} (Conflict)" + title = "${remote.title} (Konflikt)" ) storage.saveNote(conflictNote) - // Local note remains + // Lokale Note bleibt local.syncStatus = SyncStatus.SYNCED storage.saveNote(local) } @@ -302,7 +302,7 @@ fun resolveConflict(local: Note, remote: Note) { ```kotlin val channel = NotificationChannel( "notes_sync_channel", - "Notes Synchronization", + "Notizen Synchronisierung", NotificationManager.IMPORTANCE_DEFAULT ) ``` @@ -315,9 +315,9 @@ fun showSyncSuccess(context: Context, count: Int) { val pendingIntent = PendingIntent.getActivity(context, 0, intent, FLAGS) val notification = NotificationCompat.Builder(context, CHANNEL_ID) - .setContentTitle("Sync successful") - .setContentText("$count notes synchronized") - .setContentIntent(pendingIntent) // Click opens app + .setContentTitle("Sync erfolgreich") + .setContentText("$count Notizen synchronisiert") + .setContentIntent(pendingIntent) // Click öffnet App .setAutoCancel(true) // Dismiss on click .build() @@ -329,10 +329,10 @@ fun showSyncSuccess(context: Context, count: Int) { ## 🛡️ Permissions -The app requires **minimal permissions**: +Die App benötigt **minimale Permissions**: ```xml - + @@ -348,28 +348,28 @@ The app requires **minimal permissions**: ``` -**No Location Permissions!** -We use Gateway IP Comparison instead of SSID detection. No location permission required. +**Keine Location Permissions!** +Wir verwenden Gateway IP Comparison statt SSID-Erkennung. Keine Standortberechtigung nötig. --- ## 🧪 Testing -### Test Server +### Server testen ```bash -# WebDAV server reachable? +# WebDAV Server erreichbar? curl -u noteuser:password http://192.168.0.188:8080/ -# Upload file +# Datei hochladen echo '{"test":"data"}' > test.json curl -u noteuser:password -T test.json http://192.168.0.188:8080/test.json -# Download file +# Datei herunterladen curl -u noteuser:password http://192.168.0.188:8080/test.json ``` -### Test Android App +### Android App testen **Unit Tests:** ```bash @@ -384,15 +384,15 @@ cd android **Manual Testing Checklist:** -- [ ] Create note → visible in list -- [ ] Edit note → changes saved -- [ ] Delete note → removed from list -- [ ] Manual sync → server status "Reachable" -- [ ] Auto-sync → notification after ~30 min -- [ ] Close app → auto-sync continues -- [ ] Device reboot → auto-sync starts automatically -- [ ] Server offline → error notification -- [ ] Notification click → app opens +- [ ] Notiz erstellen → in Liste sichtbar +- [ ] Notiz bearbeiten → Änderungen gespeichert +- [ ] Notiz löschen → aus Liste entfernt +- [ ] Manueller Sync → Server Status "Erreichbar" +- [ ] Auto-Sync → Notification nach ~30 Min +- [ ] App schließen → Auto-Sync funktioniert weiter +- [ ] Device Reboot → Auto-Sync startet automatisch +- [ ] Server offline → Error Notification +- [ ] Notification Click → App öffnet sich --- @@ -413,18 +413,18 @@ cd android # APK: app/build/outputs/apk/release/app-release-unsigned.apk ``` -### Sign (for Distribution) +### Signieren (für Distribution) ```bash -# Create keystore +# Keystore erstellen keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias -# Sign APK +# APK signieren jarsigner -verbose -sigalg SHA256withRSA -digestalg SHA-256 \ -keystore my-release-key.jks \ app-release-unsigned.apk my-alias -# Optimize +# Optimieren zipalign -v 4 app-release-unsigned.apk app-release.apk ``` @@ -435,39 +435,39 @@ zipalign -v 4 app-release-unsigned.apk app-release.apk ### LogCat Filter ```bash -# Only app logs +# Nur App-Logs adb logcat -s SimpleNotesApp NetworkMonitor SyncWorker WebDavSyncService -# With timestamps +# Mit Timestamps adb logcat -v time -s SyncWorker -# Save to file +# In Datei speichern adb logcat -s SyncWorker > sync_debug.log ``` ### Common Issues -**Problem: Auto-sync not working** +**Problem: Auto-Sync funktioniert nicht** ``` -Solution: Disable battery optimization +Lösung: Akku-Optimierung deaktivieren Settings → Apps → Simple Notes → Battery → Don't optimize ``` -**Problem: Server not reachable** +**Problem: Server nicht erreichbar** ``` Check: -1. Server running? → docker-compose ps -2. IP correct? → ip addr show -3. Port open? → telnet 192.168.0.188 8080 +1. Server läuft? → docker-compose ps +2. IP korrekt? → ip addr show +3. Port offen? → telnet 192.168.0.188 8080 4. Firewall? → sudo ufw allow 8080 ``` -**Problem: Notifications not appearing** +**Problem: Notifications kommen nicht** ``` Check: -1. Notification permission granted? -2. Do Not Disturb active? -3. App in background? → Force stop & restart +1. Notification Permission erteilt? +2. Do Not Disturb aktiv? +3. App im Background? → Force stop & restart ``` --- @@ -504,26 +504,26 @@ androidx.localbroadcastmanager:localbroadcastmanager:1.1.0 ## 🔮 Roadmap ### v1.1 -- [ ] Search & Filter +- [ ] Suche & Filter - [ ] Dark Mode -- [ ] Tags/Categories +- [ ] Tags/Kategorien - [ ] Markdown Preview ### v2.0 - [ ] Desktop Client (Flutter) -- [ ] End-to-End Encryption +- [ ] End-to-End Verschlüsselung - [ ] Shared Notes (Collaboration) - [ ] Attachment Support --- -## 📖 Further Documentation +## 📖 Weitere Dokumentation - [Project Docs](https://github.com/inventory69/project-docs/tree/main/simple-notes-sync) -- [Sync Architecture](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/SYNC_ARCHITECTURE.md) - **Detailed Sync Trigger Documentation** +- [Sync Architecture](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/SYNC_ARCHITECTURE.md) - **Detaillierte Sync-Trigger Dokumentation** - [Android Guide](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/ANDROID_GUIDE.md) - [Bugfix Documentation](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/BUGFIX_SYNC_SPAM_AND_NOTIFICATIONS.md) --- -**Last updated:** December 25, 2025 +**Letzte Aktualisierung:** 25. Dezember 2025 diff --git a/docs/DOCS.md b/docs/DOCS.md index a87180f..cc548ef 100644 --- a/docs/DOCS.md +++ b/docs/DOCS.md @@ -1,14 +1,14 @@ -# Simple Notes Sync - Technische Dokumentation +# Simple Notes Sync - Technical Documentation -Diese Datei enthält detaillierte technische Informationen über die Implementierung, Architektur und erweiterte Funktionen. +This file contains detailed technical information about implementation, architecture, and advanced features. -**🌍 Sprachen:** **Deutsch** · [English](DOCS.en.md) +**🌍 Languages:** [Deutsch](DOCS.de.md) · **English** --- -## 📐 Architektur +## 📐 Architecture -### Gesamtübersicht +### Overall Overview ``` ┌─────────────────┐ @@ -23,81 +23,81 @@ Diese Datei enthält detaillierte technische Informationen über die Implementie └─────────────────┘ ``` -### Android App Architektur +### Android App Architecture ``` app/ ├── models/ -│ ├── Note.kt # Data class für Notizen -│ └── SyncStatus.kt # Sync-Status Enum +│ ├── Note.kt # Data class for notes +│ └── SyncStatus.kt # Sync status enum ├── storage/ -│ └── NotesStorage.kt # Lokale JSON-Datei Speicherung +│ └── NotesStorage.kt # Local JSON file storage ├── sync/ -│ ├── WebDavSyncService.kt # WebDAV Sync-Logik -│ ├── NetworkMonitor.kt # WLAN-Erkennung -│ ├── SyncWorker.kt # WorkManager Background Worker -│ └── BootReceiver.kt # Device Reboot Handler +│ ├── WebDavSyncService.kt # WebDAV sync logic +│ ├── NetworkMonitor.kt # WiFi detection +│ ├── SyncWorker.kt # WorkManager background worker +│ └── BootReceiver.kt # Device reboot handler ├── adapters/ -│ └── NotesAdapter.kt # RecyclerView Adapter +│ └── NotesAdapter.kt # RecyclerView adapter ├── utils/ -│ ├── Constants.kt # App-Konstanten -│ ├── NotificationHelper.kt# Notification Management -│ └── Logger.kt # Debug/Release Logging +│ ├── Constants.kt # App constants +│ ├── NotificationHelper.kt# Notification management +│ └── Logger.kt # Debug/release logging └── activities/ - ├── MainActivity.kt # Hauptansicht mit Liste - ├── NoteEditorActivity.kt# Editor für Notizen - └── SettingsActivity.kt # Server-Konfiguration + ├── MainActivity.kt # Main view with list + ├── NoteEditorActivity.kt# Note editor + └── SettingsActivity.kt # Server configuration ``` --- -## 🔄 Auto-Sync Implementierung +## 🔄 Auto-Sync Implementation ### WorkManager Periodic Task -Der Auto-Sync basiert auf **WorkManager** mit folgender Konfiguration: +Auto-sync is based on **WorkManager** with the following configuration: ```kotlin val constraints = Constraints.Builder() - .setRequiredNetworkType(NetworkType.UNMETERED) // Nur WiFi + .setRequiredNetworkType(NetworkType.UNMETERED) // WiFi only .build() val syncRequest = PeriodicWorkRequestBuilder( - 30, TimeUnit.MINUTES, // Alle 30 Minuten + 30, TimeUnit.MINUTES, // Every 30 minutes 10, TimeUnit.MINUTES // Flex interval ) .setConstraints(constraints) .build() ``` -**Warum WorkManager?** -- ✅ Läuft auch wenn App geschlossen ist -- ✅ Automatischer Restart nach Device Reboot +**Why WorkManager?** +- ✅ Runs even when app is closed +- ✅ Automatic restart after device reboot - ✅ Battery-efficient (Android managed) -- ✅ Garantierte Ausführung bei erfüllten Constraints +- ✅ Guaranteed execution when constraints are met ### Network Detection -Wir verwenden **Gateway IP Comparison** um zu prüfen, ob der Server erreichbar ist: +We use **Gateway IP Comparison** to check if the server is reachable: ```kotlin fun isInHomeNetwork(): Boolean { - val gatewayIP = getGatewayIP() // z.B. 192.168.0.1 - val serverIP = extractIPFromUrl(serverUrl) // z.B. 192.168.0.188 + val gatewayIP = getGatewayIP() // e.g. 192.168.0.1 + val serverIP = extractIPFromUrl(serverUrl) // e.g. 192.168.0.188 - return isSameNetwork(gatewayIP, serverIP) // Prüft /24 Netzwerk + return isSameNetwork(gatewayIP, serverIP) // Checks /24 network } ``` -**Vorteile:** -- ✅ Keine Location Permissions nötig -- ✅ Funktioniert mit allen Android Versionen -- ✅ Zuverlässig und schnell +**Advantages:** +- ✅ No location permissions needed +- ✅ Works with all Android versions +- ✅ Reliable and fast ### Sync Flow ``` -1. WorkManager wacht auf (alle 30 Min) +1. WorkManager wakes up (every 30 min) ↓ 2. Check: WiFi connected? ↓ @@ -105,7 +105,7 @@ fun isInHomeNetwork(): Boolean { ↓ 4. Load local notes ↓ -5. Upload neue/geänderte Notes → Server +5. Upload new/changed notes → Server ↓ 6. Download remote notes ← Server ↓ @@ -118,20 +118,20 @@ fun isInHomeNetwork(): Boolean { --- -## � Sync-Trigger Übersicht +## 🔄 Sync Trigger Overview -Die App verwendet **4 verschiedene Sync-Trigger** mit unterschiedlichen Anwendungsfällen: +The app uses **4 different sync triggers** with different use cases: -| Trigger | Datei | Funktion | Wann? | Pre-Check? | -|---------|-------|----------|-------|------------| -| **1. Manueller Sync** | `MainActivity.kt` | `triggerManualSync()` | User klickt auf Sync-Button im Menü | ✅ Ja | -| **2. Auto-Sync (onResume)** | `MainActivity.kt` | `triggerAutoSync()` | App wird geöffnet/fortgesetzt | ✅ Ja | -| **3. Hintergrund-Sync (Periodic)** | `SyncWorker.kt` | `doWork()` | Alle 15/30/60 Minuten (konfigurierbar) | ✅ Ja | -| **4. WiFi-Connect Sync** | `NetworkMonitor.kt` → `SyncWorker.kt` | `triggerWifiConnectSync()` | WiFi verbunden | ✅ Ja | +| Trigger | File | Function | When? | Pre-Check? | +|---------|------|----------|-------|------------| +| **1. Manual Sync** | `MainActivity.kt` | `triggerManualSync()` | User clicks sync button in menu | ✅ Yes | +| **2. Auto-Sync (onResume)** | `MainActivity.kt` | `triggerAutoSync()` | App opened/resumed | ✅ Yes | +| **3. Background Sync (Periodic)** | `SyncWorker.kt` | `doWork()` | Every 15/30/60 minutes (configurable) | ✅ Yes | +| **4. WiFi-Connect Sync** | `NetworkMonitor.kt` → `SyncWorker.kt` | `triggerWifiConnectSync()` | WiFi connected | ✅ Yes | -### Server-Erreichbarkeits-Check (Pre-Check) +### Server Reachability Check (Pre-Check) -**Alle 4 Sync-Trigger** verwenden vor dem eigentlichen Sync einen **Pre-Check**: +**All 4 sync triggers** use a **pre-check** before the actual sync: ```kotlin // WebDavSyncService.kt - isServerReachable() @@ -148,53 +148,53 @@ suspend fun isServerReachable(): Boolean = withContext(Dispatchers.IO) { } ``` -**Warum Socket-Check statt HTTP-Request?** -- ⚡ **Schneller:** Socket-Connect ist instant, HTTP-Request dauert länger -- 🔋 **Akkuschonender:** Kein HTTP-Overhead (Headers, TLS Handshake, etc.) -- 🎯 **Präziser:** Prüft nur Netzwerk-Erreichbarkeit, nicht Server-Logik -- 🛡️ **Verhindert Fehler:** Erkennt fremde WiFi-Netze bevor Sync-Fehler entsteht +**Why Socket Check instead of HTTP Request?** +- ⚡ **Faster:** Socket connect is instant, HTTP request takes longer +- 🔋 **Battery Efficient:** No HTTP overhead (headers, TLS handshake, etc.) +- 🎯 **More Precise:** Only checks network reachability, not server logic +- 🛡️ **Prevents Errors:** Detects foreign WiFi networks before sync error occurs -**Wann schlägt der Check fehl?** -- ❌ Server offline/nicht erreichbar -- ❌ Falsches WiFi-Netzwerk (z.B. öffentliches Café-WiFi) -- ❌ Netzwerk noch nicht bereit (DHCP/Routing-Delay nach WiFi-Connect) -- ❌ VPN blockiert Server-Zugriff -- ❌ Keine WebDAV-Server-URL konfiguriert +**When does the check fail?** +- ❌ Server offline/unreachable +- ❌ Wrong WiFi network (e.g. public café WiFi) +- ❌ Network not ready yet (DHCP/routing delay after WiFi connect) +- ❌ VPN blocks server access +- ❌ No WebDAV server URL configured -### Sync-Verhalten nach Trigger-Typ +### Sync Behavior by Trigger Type -| Trigger | Bei Server nicht erreichbar | Bei erfolgreichem Sync | Throttling | -|---------|----------------------------|----------------------|------------| -| Manueller Sync | Toast: "Server nicht erreichbar" | Toast: "✅ Gesynct: X Notizen" | Keins | -| Auto-Sync (onResume) | Silent abort (kein Toast) | Toast: "✅ Gesynct: X Notizen" | Max. 1x/Min | -| Hintergrund-Sync | Silent abort (kein Toast) | Silent (LocalBroadcast only) | 15/30/60 Min | -| WiFi-Connect Sync | Silent abort (kein Toast) | Silent (LocalBroadcast only) | WiFi-basiert | +| Trigger | When server not reachable | On successful sync | Throttling | +|---------|--------------------------|-------------------|------------| +| Manual Sync | Toast: "Server not reachable" | Toast: "✅ Synced: X notes" | None | +| Auto-Sync (onResume) | Silent abort (no toast) | Toast: "✅ Synced: X notes" | Max. 1x/min | +| Background Sync | Silent abort (no toast) | Silent (LocalBroadcast only) | 15/30/60 min | +| WiFi-Connect Sync | Silent abort (no toast) | Silent (LocalBroadcast only) | WiFi-based | --- -## 🔋 Akku-Optimierung +## 🔋 Battery Optimization -### Verbrauchsanalyse +### Usage Analysis -| Komponente | Frequenz | Verbrauch | Details | +| Component | Frequency | Usage | Details | |------------|----------|-----------|---------| -| WorkManager Wakeup | Alle 30 Min | ~0.15 mAh | System wacht auf | -| Network Check | 48x/Tag | ~0.03 mAh | Gateway IP check | -| WebDAV Sync | 2-3x/Tag | ~1.5 mAh | Nur bei Änderungen | -| **Total** | - | **~12 mAh/Tag** | **~0.4%** bei 3000mAh | +| WorkManager Wakeup | Every 30 min | ~0.15 mAh | System wakes up | +| Network Check | 48x/day | ~0.03 mAh | Gateway IP check | +| WebDAV Sync | 2-3x/day | ~1.5 mAh | Only when changes | +| **Total** | - | **~12 mAh/day** | **~0.4%** at 3000mAh | -### Optimierungen +### Optimizations 1. **IP Caching** ```kotlin private var cachedServerIP: String? = null - // DNS lookup nur 1x beim Start, nicht bei jedem Check + // DNS lookup only once at start, not every check ``` 2. **Throttling** ```kotlin private var lastSyncTime = 0L - private const val MIN_SYNC_INTERVAL_MS = 60_000L // Max 1 Sync/Min + private const val MIN_SYNC_INTERVAL_MS = 60_000L // Max 1 sync/min ``` 3. **Conditional Logging** @@ -207,9 +207,9 @@ suspend fun isServerReachable(): Boolean = withContext(Dispatchers.IO) { ``` 4. **Network Constraints** - - Nur WiFi (nicht mobile Daten) - - Nur wenn Server erreichbar - - Keine permanenten Listeners + - WiFi only (not mobile data) + - Only when server is reachable + - No permanent listeners --- @@ -255,15 +255,15 @@ suspend fun downloadNotes(): DownloadResult { val localNote = storage.loadNote(remoteNote.id) if (localNote == null) { - // Neue Note vom Server + // New note from server storage.saveNote(remoteNote) downloadedCount++ } else if (localNote.modifiedAt < remoteNote.modifiedAt) { - // Server hat neuere Version + // Server has newer version storage.saveNote(remoteNote) downloadedCount++ } else if (localNote.modifiedAt > remoteNote.modifiedAt) { - // Lokale Version ist neuer → Conflict + // Local version is newer → Conflict resolveConflict(localNote, remoteNote) conflictCount++ } @@ -275,19 +275,19 @@ suspend fun downloadNotes(): DownloadResult { ### Conflict Resolution -Strategie: **Last-Write-Wins** mit **Conflict Copy** +Strategy: **Last-Write-Wins** with **Conflict Copy** ```kotlin fun resolveConflict(local: Note, remote: Note) { - // Remote Note umbenennen (Conflict Copy) + // Rename remote note (conflict copy) val conflictNote = remote.copy( id = "${remote.id}_conflict_${System.currentTimeMillis()}", - title = "${remote.title} (Konflikt)" + title = "${remote.title} (Conflict)" ) storage.saveNote(conflictNote) - // Lokale Note bleibt + // Local note remains local.syncStatus = SyncStatus.SYNCED storage.saveNote(local) } @@ -302,7 +302,7 @@ fun resolveConflict(local: Note, remote: Note) { ```kotlin val channel = NotificationChannel( "notes_sync_channel", - "Notizen Synchronisierung", + "Notes Synchronization", NotificationManager.IMPORTANCE_DEFAULT ) ``` @@ -315,9 +315,9 @@ fun showSyncSuccess(context: Context, count: Int) { val pendingIntent = PendingIntent.getActivity(context, 0, intent, FLAGS) val notification = NotificationCompat.Builder(context, CHANNEL_ID) - .setContentTitle("Sync erfolgreich") - .setContentText("$count Notizen synchronisiert") - .setContentIntent(pendingIntent) // Click öffnet App + .setContentTitle("Sync successful") + .setContentText("$count notes synchronized") + .setContentIntent(pendingIntent) // Click opens app .setAutoCancel(true) // Dismiss on click .build() @@ -329,10 +329,10 @@ fun showSyncSuccess(context: Context, count: Int) { ## 🛡️ Permissions -Die App benötigt **minimale Permissions**: +The app requires **minimal permissions**: ```xml - + @@ -348,28 +348,28 @@ Die App benötigt **minimale Permissions**: ``` -**Keine Location Permissions!** -Wir verwenden Gateway IP Comparison statt SSID-Erkennung. Keine Standortberechtigung nötig. +**No Location Permissions!** +We use Gateway IP Comparison instead of SSID detection. No location permission required. --- ## 🧪 Testing -### Server testen +### Test Server ```bash -# WebDAV Server erreichbar? +# WebDAV server reachable? curl -u noteuser:password http://192.168.0.188:8080/ -# Datei hochladen +# Upload file echo '{"test":"data"}' > test.json curl -u noteuser:password -T test.json http://192.168.0.188:8080/test.json -# Datei herunterladen +# Download file curl -u noteuser:password http://192.168.0.188:8080/test.json ``` -### Android App testen +### Test Android App **Unit Tests:** ```bash @@ -384,15 +384,15 @@ cd android **Manual Testing Checklist:** -- [ ] Notiz erstellen → in Liste sichtbar -- [ ] Notiz bearbeiten → Änderungen gespeichert -- [ ] Notiz löschen → aus Liste entfernt -- [ ] Manueller Sync → Server Status "Erreichbar" -- [ ] Auto-Sync → Notification nach ~30 Min -- [ ] App schließen → Auto-Sync funktioniert weiter -- [ ] Device Reboot → Auto-Sync startet automatisch -- [ ] Server offline → Error Notification -- [ ] Notification Click → App öffnet sich +- [ ] Create note → visible in list +- [ ] Edit note → changes saved +- [ ] Delete note → removed from list +- [ ] Manual sync → server status "Reachable" +- [ ] Auto-sync → notification after ~30 min +- [ ] Close app → auto-sync continues +- [ ] Device reboot → auto-sync starts automatically +- [ ] Server offline → error notification +- [ ] Notification click → app opens --- @@ -413,18 +413,18 @@ cd android # APK: app/build/outputs/apk/release/app-release-unsigned.apk ``` -### Signieren (für Distribution) +### Sign (for Distribution) ```bash -# Keystore erstellen +# Create keystore keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias -# APK signieren +# Sign APK jarsigner -verbose -sigalg SHA256withRSA -digestalg SHA-256 \ -keystore my-release-key.jks \ app-release-unsigned.apk my-alias -# Optimieren +# Optimize zipalign -v 4 app-release-unsigned.apk app-release.apk ``` @@ -435,39 +435,39 @@ zipalign -v 4 app-release-unsigned.apk app-release.apk ### LogCat Filter ```bash -# Nur App-Logs +# Only app logs adb logcat -s SimpleNotesApp NetworkMonitor SyncWorker WebDavSyncService -# Mit Timestamps +# With timestamps adb logcat -v time -s SyncWorker -# In Datei speichern +# Save to file adb logcat -s SyncWorker > sync_debug.log ``` ### Common Issues -**Problem: Auto-Sync funktioniert nicht** +**Problem: Auto-sync not working** ``` -Lösung: Akku-Optimierung deaktivieren +Solution: Disable battery optimization Settings → Apps → Simple Notes → Battery → Don't optimize ``` -**Problem: Server nicht erreichbar** +**Problem: Server not reachable** ``` Check: -1. Server läuft? → docker-compose ps -2. IP korrekt? → ip addr show -3. Port offen? → telnet 192.168.0.188 8080 +1. Server running? → docker-compose ps +2. IP correct? → ip addr show +3. Port open? → telnet 192.168.0.188 8080 4. Firewall? → sudo ufw allow 8080 ``` -**Problem: Notifications kommen nicht** +**Problem: Notifications not appearing** ``` Check: -1. Notification Permission erteilt? -2. Do Not Disturb aktiv? -3. App im Background? → Force stop & restart +1. Notification permission granted? +2. Do Not Disturb active? +3. App in background? → Force stop & restart ``` --- @@ -504,26 +504,26 @@ androidx.localbroadcastmanager:localbroadcastmanager:1.1.0 ## 🔮 Roadmap ### v1.1 -- [ ] Suche & Filter +- [ ] Search & Filter - [ ] Dark Mode -- [ ] Tags/Kategorien +- [ ] Tags/Categories - [ ] Markdown Preview ### v2.0 - [ ] Desktop Client (Flutter) -- [ ] End-to-End Verschlüsselung +- [ ] End-to-End Encryption - [ ] Shared Notes (Collaboration) - [ ] Attachment Support --- -## 📖 Weitere Dokumentation +## 📖 Further Documentation - [Project Docs](https://github.com/inventory69/project-docs/tree/main/simple-notes-sync) -- [Sync Architecture](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/SYNC_ARCHITECTURE.md) - **Detaillierte Sync-Trigger Dokumentation** +- [Sync Architecture](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/SYNC_ARCHITECTURE.md) - **Detailed Sync Trigger Documentation** - [Android Guide](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/ANDROID_GUIDE.md) - [Bugfix Documentation](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/BUGFIX_SYNC_SPAM_AND_NOTIFICATIONS.md) --- -**Letzte Aktualisierung:** 25. Dezember 2025 +**Last updated:** December 25, 2025 diff --git a/docs/FEATURES.de.md b/docs/FEATURES.de.md new file mode 100644 index 0000000..3610d2a --- /dev/null +++ b/docs/FEATURES.de.md @@ -0,0 +1,305 @@ +# Vollständige Feature-Liste 📋 + +**🌍 Sprachen:** **Deutsch** · [English](FEATURES.md) + +> Alle Features von Simple Notes Sync im Detail + +--- + +## 📝 Notiz-Verwaltung + +### Notiz-Typen +- ✅ **Textnotizen** - Klassische Freitext-Notizen +- ✅ **Checklisten** _(NEU in v1.4.0)_ - Aufgabenlisten mit Tap-to-Check + - ➕ Items hinzufügen über Eingabefeld + - ☑️ Tap zum Abhaken/Wieder-Öffnen + - 📌 Long-Press für Drag & Drop Sortierung + - ~~Durchstreichen~~ bei erledigten Einträgen + +### Basis-Funktionen +- ✅ **Automatisches Speichern** - Kein manuelles Speichern nötig +- ✅ **Titel + Inhalt** - Klare Struktur für jede Notiz +- ✅ **Zeitstempel** - Erstellungs- und Änderungsdatum automatisch +- ✅ **Auswahlmodus** _(NEU in v1.5.0)_ - Long-Press für Mehrfachauswahl und Batch-Löschen +- ✅ **Bestätigungs-Dialog** - Schutz vor versehentlichem Löschen +- ✅ **Jetpack Compose UI** _(NEU in v1.5.0)_ - Moderne, performante Benutzeroberfläche +- ✅ **Material Design 3** - Moderne, saubere UI +- ✅ **Dark Mode** - Automatisch je nach System-Einstellung +- ✅ **Dynamic Colors** - Passt sich deinem Android-Theme an + +### Editor +- ✅ **Minimalistischer Editor** - Kein Schnickschnack +- ✅ **Auto-Fokus** - Direkt losschreiben +- ✅ **Vollbild-Modus** - Maximale Schreibfläche +- ✅ **Speichern-Button** - Manuelle Bestätigung möglich +- ✅ **Zurück-Navigation** - Speichert automatisch +- ✅ **Slide-Animationen** _(NEU in v1.5.0)_ - Flüssige Übergänge + +--- + +## 🌍 Mehrsprachigkeit _(NEU in v1.5.0)_ + +### Unterstützte Sprachen +- ✅ **Englisch** - Primäre Sprache (Standard) +- ✅ **Deutsch** - Vollständige Übersetzung + +### Sprachauswahl +- ✅ **Automatische Erkennung** - Folgt der System-Sprache +- ✅ **Manuelle Auswahl** - In den Einstellungen umschaltbar +- ✅ **Per-App Language** - Android 13+ native Sprachauswahl +- ✅ **locales_config.xml** - Vollständige Android-Integration + +### Umfang +- ✅ **400+ Strings** - Komplett übersetzt +- ✅ **UI-Texte** - Alle Buttons, Dialoge, Menüs +- ✅ **Fehlermeldungen** - Hilfreiche lokalisierte Hinweise +- ✅ **Einstellungen** - 7 kategorisierte Screens + +--- + +## 💾 Backup & Wiederherstellung + +### Lokales Backup System +- ✅ **JSON-Export** - Alle Notizen in einer Datei +- ✅ **Freie Speicherort-Wahl** - Downloads, SD-Karte, Cloud-Ordner +- ✅ **Dateinamen mit Zeitstempel** - `simplenotes_backup_YYYY-MM-DD_HHmmss.json` +- ✅ **Vollständiger Export** - Titel, Inhalt, Timestamps, IDs +- ✅ **Menschenlesbares Format** - JSON mit Formatierung +- ✅ **Unabhängig vom Server** - Funktioniert komplett offline + +### Wiederherstellungs-Modi +- ✅ **Zusammenführen (Merge)** - Neue Notizen hinzufügen, bestehende behalten _(Standard)_ +- ✅ **Ersetzen (Replace)** - Alle löschen und Backup importieren +- ✅ **Duplikate überschreiben (Overwrite)** - Backup gewinnt bei ID-Konflikten +- ✅ **Automatisches Sicherheits-Backup** - Vor jeder Wiederherstellung +- ✅ **Backup-Validierung** - Prüft Format und Version +- ✅ **Fehlerbehandlung** - Klare Fehlermeldungen bei Problemen + +--- + +## 🖥️ Desktop-Integration + +### Markdown-Export +- ✅ **Automatischer Export** - Jede Notiz → `.md` Datei +- ✅ **Checklisten als Task-Listen** _(NEU)_ - `- [ ]` / `- [x]` Format (GitHub-kompatibel) +- ✅ **Dual-Format** - JSON (Master) + Markdown (Mirror) +- ✅ **Dateinamen-Sanitization** - Sichere Dateinamen aus Titeln +- ✅ **Duplikat-Handling** _(NEU)_ - ID-Suffix bei gleichen Titeln +- ✅ **Frontmatter-Metadata** - YAML mit ID, Timestamps, Type +- ✅ **WebDAV-Sync** - Parallel zum JSON-Sync +- ✅ **Optional** - In Einstellungen ein/ausschaltbar +- ✅ **Initial Export** - Alle bestehenden Notizen beim Aktivieren +- ✅ **Progress-Anzeige** - Zeigt X/Y beim Export + +### Markdown-Import +- ✅ **Desktop → App** - Änderungen vom Desktop importieren +- ✅ **Last-Write-Wins** - Konfliktauflösung via Timestamp +- ✅ **Frontmatter-Parsing** - Liest Metadata aus `.md` Dateien +- ✅ **Neue Notizen erkennen** - Automatisch in App übernehmen +- ✅ **Updates erkennen** - Nur wenn Desktop-Version neuer ist +- ✅ **Fehlertoleranz** - Einzelne Fehler brechen Import nicht ab + +### WebDAV-Zugriff +- ✅ **Network Drive Mount** - Windows, macOS, Linux +- ✅ **Jeder Markdown-Editor** - VS Code, Typora, Notepad++, iA Writer +- ✅ **Live-Bearbeitung** - Direkter Zugriff auf `.md` Dateien +- ✅ **Ordner-Struktur** - `/notes/` für JSON, `/notes-md/` für Markdown +- ✅ **Automatische Ordner-Erstellung** - Beim ersten Sync + +--- + +## 🔄 Synchronisation + +### Auto-Sync +- ✅ **Intervall-Auswahl** - 15, 30 oder 60 Minuten +- ✅ **WiFi-Trigger** - Sync bei WiFi-Verbindung _(keine SSID-Einschränkung)_ +- ✅ **Akkuschonend** - ~0.2-0.8% pro Tag +- ✅ **Smart Server-Check** - Sync nur wenn Server erreichbar +- ✅ **WorkManager** - Zuverlässige Background-Ausführung +- ✅ **Battery-Optimierung kompatibel** - Funktioniert auch mit Doze Mode + +### Sync-Trigger (6 Stück) +1. ✅ **Periodic Sync** - Automatisch nach Intervall +2. ✅ **App-Start Sync** - Beim Öffnen der App +3. ✅ **WiFi-Connect Sync** - Bei jeder WiFi-Verbindung +4. ✅ **Manual Sync** - Button in Einstellungen +5. ✅ **Pull-to-Refresh** - Wisch-Geste in Notizliste +6. ✅ **Settings-Save Sync** - Nach Server-Konfiguration + +### Sync-Mechanismus +- ✅ **Upload** - Lokale Änderungen zum Server +- ✅ **Download** - Server-Änderungen in App +- ✅ **Konflikt-Erkennung** - Bei gleichzeitigen Änderungen +- ✅ **Konfliktfreies Merging** - Last-Write-Wins via Timestamp +- ✅ **Sync-Status Tracking** - LOCAL_ONLY, PENDING, SYNCED, CONFLICT +- ✅ **Fehlerbehandlung** - Retry bei Netzwerkproblemen +- ✅ **Offline-First** - App funktioniert ohne Server + +### Server-Verbindung +- ✅ **WebDAV-Protokoll** - Standard-Protokoll +- ✅ **HTTP/HTTPS** - HTTP nur lokal, HTTPS für extern +- ✅ **Username/Password** - Basic Authentication +- ✅ **Connection Test** - In Einstellungen testen +- ✅ **Server-URL Normalisierung** - Automatisches `/notes/` und `/notes-md/` _(NEU in v1.2.1)_ +- ✅ **Flexible URL-Eingabe** - Beide Varianten funktionieren: `http://server/` und `http://server/notes/` + +--- + +## 🔒 Privacy & Sicherheit + +### Self-Hosted +- ✅ **Eigener Server** - Volle Kontrolle über Daten +- ✅ **Keine Cloud** - Keine Drittanbieter +- ✅ **Kein Tracking** - Keine Analytik, keine Telemetrie +- ✅ **Kein Account** - Nur Server-Zugangsdaten +- ✅ **100% Open Source** - MIT Lizenz + +### Daten-Sicherheit +- ✅ **Lokale Speicherung** - App-Private Storage (Android) +- ✅ **WebDAV-Verschlüsselung** - HTTPS für externe Server +- ✅ **Passwort-Speicherung** - Android SharedPreferences (verschlüsselt) +- ✅ **Keine Drittanbieter-Libs** - Nur Android SDK + Sardine (WebDAV) + +### Entwickler-Features +- ✅ **Datei-Logging** - Optional, nur bei Aktivierung _(NEU in v1.3.2)_ +- ✅ **Datenschutz-Hinweis** - Explizite Warnung bei Aktivierung +- ✅ **Lokale Logs** - Logs bleiben auf dem Gerät + +--- + +## 🔋 Performance & Optimierung + +### Akku-Effizienz +- ✅ **Optimierte Sync-Intervalle** - 15/30/60 Min +- ✅ **WiFi-Only** - Kein Mobile Data Sync +- ✅ **Smart Server-Check** - Sync nur wenn Server erreichbar +- ✅ **WorkManager** - System-optimierte Ausführung +- ✅ **Doze Mode kompatibel** - Sync läuft auch im Standby +- ✅ **Gemessener Verbrauch:** + - 15 Min: ~0.8% / Tag (~23 mAh) + - 30 Min: ~0.4% / Tag (~12 mAh) ⭐ _Empfohlen_ + - 60 Min: ~0.2% / Tag (~6 mAh) + +### App-Performance +- ✅ **Offline-First** - Funktioniert ohne Internet +- ✅ **Instant-Load** - Notizen laden in <100ms +- ✅ **Smooth Scrolling** - RecyclerView mit ViewHolder +- ✅ **Material Design 3** - Native Android UI +- ✅ **Kotlin Coroutines** - Asynchrone Operationen +- ✅ **Minimale APK-Größe** - ~2 MB + +--- + +## 🛠️ Technische Details + +### Plattform +- ✅ **Android 8.0+** (API 26+) +- ✅ **Target SDK 36** (Android 15) +- ✅ **Kotlin** - Moderne Programmiersprache +- ✅ **Material Design 3** - Neueste Design-Richtlinien +- ✅ **ViewBinding** - Typ-sichere View-Referenzen + +### Architektur +- ✅ **MVVM-Light** - Einfache Architektur +- ✅ **Single Activity** - Moderne Navigation +- ✅ **Kotlin Coroutines** - Async/Await Pattern +- ✅ **Dispatchers.IO** - Background-Operationen +- ✅ **SharedPreferences** - Settings-Speicherung +- ✅ **File-Based Storage** - JSON-Dateien lokal +- ✅ **Custom Exceptions** - Dedizierte SyncException für bessere Fehlerbehandlung _(NEU in v1.3.2)_ + +### Abhängigkeiten +- ✅ **AndroidX** - Jetpack Libraries +- ✅ **Material Components** - Material Design 3 +- ✅ **Sardine** - WebDAV Client (com.thegrizzlylabs) +- ✅ **Gson** - JSON Serialization +- ✅ **WorkManager** - Background Tasks +- ✅ **OkHttp** - HTTP Client (via Sardine) + +### Build-Varianten +- ✅ **Standard** - Universal APK (100% FOSS, keine Google-Dependencies) +- ✅ **F-Droid** - Identisch mit Standard (100% FOSS) +- ✅ **Debug/Release** - Entwicklung und Production +- ✅ **Keine Google Services** - Komplett FOSS, keine proprietären Bibliotheken + +--- + +## 📦 Server-Kompatibilität + +### Getestete WebDAV-Server +- ✅ **Docker WebDAV** (empfohlen für Self-Hosting) +- ✅ **Nextcloud** - Vollständig kompatibel +- ✅ **ownCloud** - Funktioniert einwandfrei +- ✅ **Apache mod_dav** - Standard WebDAV +- ✅ **nginx + WebDAV** - Mit korrekter Konfiguration + +### Server-Features +- ✅ **Basic Auth** - Username/Password +- ✅ **Directory Listing** - Für Download +- ✅ **PUT/GET** - Upload/Download +- ✅ **MKCOL** - Ordner erstellen +- ✅ **DELETE** - Notizen löschen (zukünftig) + +--- + +## 🔮 Zukünftige Features + +Geplant für kommende Versionen: + +### v1.4.0 - Checklisten +- ⏳ **Checklisten-Notizen** - Neuer Notiz-Typ mit Checkboxen +- ⏳ **Erledigte Items** - Durchstreichen/Abhaken +- ⏳ **Drag & Drop** - Items neu anordnen + +### v1.5.0 - Internationalisierung +- ⏳ **Mehrsprachigkeit** - Deutsch + Englisch UI +- ⏳ **Sprachauswahl** - In Einstellungen wählbar +- ⏳ **Vollständige Übersetzung** - Alle Strings in beiden Sprachen + +### v1.6.0 - Modern APIs +- ⏳ **LocalBroadcastManager ersetzen** - SharedFlow stattdessen +- ⏳ **PackageInfo Flags** - PackageInfoFlags.of() verwenden +- ⏳ **Komplexitäts-Refactoring** - Lange Funktionen aufteilen + +--- + +## 📊 Vergleich mit anderen Apps + +| Feature | Simple Notes Sync | Google Keep | Nextcloud Notes | +|---------|------------------|-------------|-----------------| +| Offline-First | ✅ | ⚠️ Eingeschränkt | ⚠️ Eingeschränkt | +| Self-Hosted | ✅ | ❌ | ✅ | +| Auto-Sync | ✅ | ✅ | ✅ | +| Markdown-Export | ✅ | ❌ | ✅ | +| Desktop-Zugriff | ✅ (WebDAV) | ✅ (Web) | ✅ (Web + WebDAV) | +| Lokales Backup | ✅ | ❌ | ⚠️ Server-Backup | +| Kein Google-Account | ✅ | ❌ | ✅ | +| Open Source | ✅ MIT | ❌ | ✅ AGPL | +| APK-Größe | ~2 MB | ~50 MB | ~8 MB | +| Akku-Verbrauch | ~0.4%/Tag | ~1-2%/Tag | ~0.5%/Tag | + +--- + +## ❓ FAQ + +**Q: Brauche ich einen Server?** +A: Nein! Die App funktioniert auch komplett offline. Der Server ist optional für Sync. + +**Q: Welcher Server ist am besten?** +A: Für Einstieg: Docker WebDAV (einfach, leicht). Für Profis: Nextcloud (viele Features). + +**Q: Funktioniert Markdown-Export ohne Desktop-Integration?** +A: Nein, du musst das Feature in den Einstellungen aktivieren. + +**Q: Gehen meine Daten verloren wenn ich den Server wechsle?** +A: Nein! Erstelle ein lokales Backup, wechsle Server, stelle wieder her. + +**Q: Warum JSON + Markdown?** +A: JSON ist zuverlässig und schnell (Master). Markdown ist menschenlesbar (Mirror für Desktop). + +**Q: Kann ich die App ohne Google Play nutzen?** +A: Ja! Lade die APK direkt von GitHub oder nutze F-Droid. + +--- + +**Letzte Aktualisierung:** v1.3.2 (2026-01-10) diff --git a/docs/FEATURES.en.md b/docs/FEATURES.en.md deleted file mode 100644 index 0fbdb8f..0000000 --- a/docs/FEATURES.en.md +++ /dev/null @@ -1,284 +0,0 @@ -# Complete Feature List 📋 - -**🌍 Languages:** [Deutsch](FEATURES.md) · **English** - -> All features of Simple Notes Sync in detail - ---- - -## 📝 Note Management - -### Note Types -- ✅ **Text notes** - Classic free-form notes -- ✅ **Checklists** _(NEW in v1.4.0)_ - Task lists with tap-to-check - - ➕ Add items via input field - - ☑️ Tap to check/uncheck - - 📌 Long-press for drag & drop sorting - - 🗑️ Swipe-to-delete individual items - - ~~Strikethrough~~ for completed entries - -### Basic Features -- ✅ **Auto-save** - No manual saving needed -- ✅ **Title + content** - Clear structure for each note -- ✅ **Timestamps** - Creation and modification date automatically -- ✅ **Swipe-to-delete** - Intuitive gesture for deletion -- ✅ **Confirmation dialog** - Protection against accidental deletion -- ✅ **Material Design 3** - Modern, clean UI -- ✅ **Dark mode** - Automatically based on system settings -- ✅ **Dynamic colors** - Adapts to your Android theme - -### Editor -- ✅ **Minimalist editor** - No bells and whistles -- ✅ **Auto-focus** - Start writing immediately -- ✅ **Fullscreen mode** - Maximum writing space -- ✅ **Save button** - Manual confirmation possible -- ✅ **Back navigation** - Saves automatically - ---- - -## 💾 Backup & Restore - -### Local Backup System -- ✅ **JSON export** - All notes in one file -- ✅ **Free location choice** - Downloads, SD card, cloud folder -- ✅ **Filenames with timestamp** - `simplenotes_backup_YYYY-MM-DD_HHmmss.json` -- ✅ **Complete export** - Title, content, timestamps, IDs -- ✅ **Human-readable format** - JSON with formatting -- ✅ **Independent from server** - Works completely offline - -### Restore Modes -- ✅ **Merge** - Add new notes, keep existing ones _(Default)_ -- ✅ **Replace** - Delete all and import backup -- ✅ **Overwrite duplicates** - Backup wins on ID conflicts -- ✅ **Automatic safety backup** - Before every restore -- ✅ **Backup validation** - Checks format and version -- ✅ **Error handling** - Clear error messages on issues - ---- - -## 🖥️ Desktop Integration - -### Markdown Export -- ✅ **Automatic export** - Each note → `.md` file -- ✅ **Checklists as task lists** _(NEW)_ - `- [ ]` / `- [x]` format (GitHub-compatible) -- ✅ **Dual-format** - JSON (master) + Markdown (mirror) -- ✅ **Filename sanitization** - Safe filenames from titles -- ✅ **Duplicate handling** _(NEW)_ - ID suffix for same titles -- ✅ **Frontmatter metadata** - YAML with ID, timestamps, type -- ✅ **WebDAV sync** - Parallel to JSON sync -- ✅ **Optional** - Toggle in settings -- ✅ **Initial export** - All existing notes when activated -- ✅ **Progress indicator** - Shows X/Y during export - -### Markdown Import -- ✅ **Desktop → App** - Import changes from desktop -- ✅ **Last-Write-Wins** - Conflict resolution via timestamp -- ✅ **Frontmatter parsing** - Reads metadata from `.md` files -- ✅ **Detect new notes** - Automatically adopt to app -- ✅ **Detect updates** - Only if desktop version is newer -- ✅ **Error tolerance** - Individual errors don't abort import - -### WebDAV Access -- ✅ **Network drive mount** - Windows, macOS, Linux -- ✅ **Any Markdown editor** - VS Code, Typora, Notepad++, iA Writer -- ✅ **Live editing** - Direct access to `.md` files -- ✅ **Folder structure** - `/notes/` for JSON, `/notes-md/` for Markdown -- ✅ **Automatic folder creation** - On first sync - ---- - -## 🔄 Synchronization - -### Auto-Sync -- ✅ **Interval selection** - 15, 30 or 60 minutes -- ✅ **WiFi trigger** - Sync on WiFi connection _(no SSID restriction)_ -- ✅ **Battery-friendly** - ~0.2-0.8% per day -- ✅ **Smart server check** - Sync only when server is reachable -- ✅ **WorkManager** - Reliable background execution -- ✅ **Battery optimization compatible** - Works even with Doze mode - -### Sync Triggers (6 total) -1. ✅ **Periodic sync** - Automatically after interval -2. ✅ **App-start sync** - When opening the app -3. ✅ **WiFi-connect sync** - On any WiFi connection -4. ✅ **Manual sync** - Button in settings -5. ✅ **Pull-to-refresh** - Swipe gesture in notes list -6. ✅ **Settings-save sync** - After server configuration - -### Sync Mechanism -- ✅ **Upload** - Local changes to server -- ✅ **Download** - Server changes to app -- ✅ **Conflict detection** - On simultaneous changes -- ✅ **Conflict-free merging** - Last-Write-Wins via timestamp -- ✅ **Sync status tracking** - LOCAL_ONLY, PENDING, SYNCED, CONFLICT -- ✅ **Error handling** - Retry on network issues -- ✅ **Offline-first** - App works without server - -### Server Connection -- ✅ **WebDAV protocol** - Standard protocol -- ✅ **HTTP/HTTPS** - HTTP only local, HTTPS for external -- ✅ **Username/password** - Basic authentication -- ✅ **Connection test** - Test in settings -- ✅ **Server URL normalization** - Automatic `/notes/` and `/notes-md/` _(NEW in v1.2.1)_ -- ✅ **Flexible URL input** - Both variants work: `http://server/` and `http://server/notes/` - ---- - -## 🔒 Privacy & Security - -### Self-Hosted -- ✅ **Own server** - Full control over data -- ✅ **No cloud** - No third parties -- ✅ **No tracking** - No analytics, no telemetry -- ✅ **No account** - Only server credentials -- ✅ **100% open source** - MIT License - -### Data Security -- ✅ **Local storage** - App-private storage (Android) -- ✅ **WebDAV encryption** - HTTPS for external servers -- ✅ **Password storage** - Android SharedPreferences (encrypted) -- ✅ **No third-party libs** - Only Android SDK + Sardine (WebDAV) - -### Developer Features -- ✅ **File logging** - Optional, only when enabled _(NEW in v1.3.2)_ -- ✅ **Privacy notice** - Explicit warning on activation -- ✅ **Local logs** - Logs stay on device - ---- - -## 🔋 Performance & Optimization - -### Battery Efficiency -- ✅ **Optimized sync intervals** - 15/30/60 min -- ✅ **WiFi-only** - No mobile data sync -- ✅ **Smart server check** - Sync only when server is reachable -- ✅ **WorkManager** - System-optimized execution -- ✅ **Doze mode compatible** - Sync runs even in standby -- ✅ **Measured consumption:** - - 15 min: ~0.8% / day (~23 mAh) - - 30 min: ~0.4% / day (~12 mAh) ⭐ _Recommended_ - - 60 min: ~0.2% / day (~6 mAh) - -### App Performance -- ✅ **Offline-first** - Works without internet -- ✅ **Instant-load** - Notes load in <100ms -- ✅ **Smooth scrolling** - RecyclerView with ViewHolder -- ✅ **Material Design 3** - Native Android UI -- ✅ **Kotlin Coroutines** - Asynchronous operations -- ✅ **Minimal APK size** - ~2 MB - ---- - -## 🛠️ Technical Details - -### Platform -- ✅ **Android 8.0+** (API 26+) -- ✅ **Target SDK 36** (Android 15) -- ✅ **Kotlin** - Modern programming language -- ✅ **Material Design 3** - Latest design guidelines -- ✅ **ViewBinding** - Type-safe view references - -### Architecture -- ✅ **MVVM-Light** - Simple architecture -- ✅ **Single Activity** - Modern navigation -- ✅ **Kotlin Coroutines** - Async/Await pattern -- ✅ **Dispatchers.IO** - Background operations -- ✅ **SharedPreferences** - Settings storage -- ✅ **File-based storage** - JSON files locally -- ✅ **Custom exceptions** - Dedicated SyncException for better error handling _(NEW in v1.3.2)_ - -### Dependencies -- ✅ **AndroidX** - Jetpack libraries -- ✅ **Material Components** - Material Design 3 -- ✅ **Sardine** - WebDAV client (com.thegrizzlylabs) -- ✅ **Gson** - JSON serialization -- ✅ **WorkManager** - Background tasks -- ✅ **OkHttp** - HTTP client (via Sardine) - -### Build Variants -- ✅ **Standard** - Universal APK (100% FOSS, no Google dependencies) -- ✅ **F-Droid** - Identical to Standard (100% FOSS) -- ✅ **Debug/Release** - Development and production -- ✅ **No Google Services** - Completely FOSS, no proprietary libraries - ---- - -## 📦 Server Compatibility - -### Tested WebDAV Servers -- ✅ **Docker WebDAV** (recommended for self-hosting) -- ✅ **Nextcloud** - Fully compatible -- ✅ **ownCloud** - Works perfectly -- ✅ **Apache mod_dav** - Standard WebDAV -- ✅ **nginx + WebDAV** - With correct configuration - -### Server Features -- ✅ **Basic Auth** - Username/password -- ✅ **Directory listing** - For download -- ✅ **PUT/GET** - Upload/download -- ✅ **MKCOL** - Create folders -- ✅ **DELETE** - Delete notes (future) - ---- - -## 🔮 Future Features - -Planned for upcoming versions: - -### v1.4.0 - Checklists -- ⏳ **Checklist notes** - New note type with checkboxes -- ⏳ **Completed items** - Strike-through/check off -- ⏳ **Drag & drop** - Reorder items - -### v1.5.0 - Internationalization -- ⏳ **Multi-language** - German + English UI -- ⏳ **Language selection** - Selectable in settings -- ⏳ **Full translation** - All strings in both languages - -### v1.6.0 - Modern APIs -- ⏳ **Replace LocalBroadcastManager** - Use SharedFlow instead -- ⏳ **PackageInfo Flags** - Use PackageInfoFlags.of() -- ⏳ **Complexity refactoring** - Split long functions - ---- - -## 📊 Comparison with Other Apps - -| Feature | Simple Notes Sync | Google Keep | Nextcloud Notes | -|---------|------------------|-------------|-----------------| -| Offline-first | ✅ | ⚠️ Limited | ⚠️ Limited | -| Self-hosted | ✅ | ❌ | ✅ | -| Auto-sync | ✅ | ✅ | ✅ | -| Markdown export | ✅ | ❌ | ✅ | -| Desktop access | ✅ (WebDAV) | ✅ (Web) | ✅ (Web + WebDAV) | -| Local backup | ✅ | ❌ | ⚠️ Server backup | -| No Google account | ✅ | ❌ | ✅ | -| Open source | ✅ MIT | ❌ | ✅ AGPL | -| APK size | ~2 MB | ~50 MB | ~8 MB | -| Battery usage | ~0.4%/day | ~1-2%/day | ~0.5%/day | - ---- - -## ❓ FAQ - -**Q: Do I need a server?** -A: No! The app works completely offline. The server is optional for sync. - -**Q: Which server is best?** -A: For beginners: Docker WebDAV (simple, easy). For pros: Nextcloud (many features). - -**Q: Does Markdown export work without Desktop Integration?** -A: No, you need to activate the feature in settings. - -**Q: Will my data be lost if I switch servers?** -A: No! Create a local backup, switch servers, restore. - -**Q: Why JSON + Markdown?** -A: JSON is reliable and fast (master). Markdown is human-readable (mirror for desktop). - -**Q: Can I use the app without Google Play?** -A: Yes! Download the APK directly from GitHub or use F-Droid. - ---- - -**Last update:** v1.3.2 (2026-01-10) diff --git a/docs/FEATURES.md b/docs/FEATURES.md index c00d7ba..09d39f8 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -1,284 +1,305 @@ -# Vollständige Feature-Liste 📋 +# Complete Feature List 📋 -**🌍 Languages:** **Deutsch** · [English](FEATURES.en.md) +**🌍 Languages:** [Deutsch](FEATURES.de.md) · **English** -> Alle Features von Simple Notes Sync im Detail +> All features of Simple Notes Sync in detail --- -## 📝 Notiz-Verwaltung +## 📝 Note Management -### Notiz-Typen -- ✅ **Textnotizen** - Klassische Freitext-Notizen -- ✅ **Checklisten** _(NEU in v1.4.0)_ - Aufgabenlisten mit Tap-to-Check - - ➕ Items hinzufügen über Eingabefeld - - ☑️ Tap zum Abhaken/Wieder-Öffnen - - 📌 Long-Press für Drag & Drop Sortierung - - 🗑️ Swipe-to-Delete für einzelne Items - - ~~Durchstreichen~~ bei erledigten Einträgen +### Note Types +- ✅ **Text notes** - Classic free-form notes +- ✅ **Checklists** _(NEW in v1.4.0)_ - Task lists with tap-to-check + - ➕ Add items via input field + - ☑️ Tap to check/uncheck + - 📌 Long-press for drag & drop sorting + - ~~Strikethrough~~ for completed entries -### Basis-Funktionen -- ✅ **Automatisches Speichern** - Kein manuelles Speichern nötig -- ✅ **Titel + Inhalt** - Klare Struktur für jede Notiz -- ✅ **Zeitstempel** - Erstellungs- und Änderungsdatum automatisch -- ✅ **Swipe-to-Delete** - Intuitive Geste zum Löschen -- ✅ **Bestätigungs-Dialog** - Schutz vor versehentlichem Löschen -- ✅ **Material Design 3** - Moderne, saubere UI -- ✅ **Dark Mode** - Automatisch je nach System-Einstellung -- ✅ **Dynamic Colors** - Passt sich deinem Android-Theme an +### Basic Features +- ✅ **Auto-save** - No manual saving needed +- ✅ **Title + content** - Clear structure for each note +- ✅ **Timestamps** - Creation and modification date automatically +- ✅ **Selection Mode** _(NEW in v1.5.0)_ - Long-press for multi-select and batch delete +- ✅ **Confirmation dialog** - Protection against accidental deletion +- ✅ **Jetpack Compose UI** _(NEW in v1.5.0)_ - Modern, performant user interface +- ✅ **Material Design 3** - Modern, clean UI +- ✅ **Dark mode** - Automatically based on system settings +- ✅ **Dynamic colors** - Adapts to your Android theme ### Editor -- ✅ **Minimalistischer Editor** - Kein Schnickschnack -- ✅ **Auto-Fokus** - Direkt losschreiben -- ✅ **Vollbild-Modus** - Maximale Schreibfläche -- ✅ **Speichern-Button** - Manuelle Bestätigung möglich -- ✅ **Zurück-Navigation** - Speichert automatisch +- ✅ **Minimalist editor** - No bells and whistles +- ✅ **Auto-focus** - Start writing immediately +- ✅ **Fullscreen mode** - Maximum writing space +- ✅ **Save button** - Manual confirmation possible +- ✅ **Back navigation** - Saves automatically +- ✅ **Slide animations** _(NEW in v1.5.0)_ - Smooth transitions --- -## 💾 Backup & Wiederherstellung +## 🌍 Multilingual Support _(NEW in v1.5.0)_ -### Lokales Backup System -- ✅ **JSON-Export** - Alle Notizen in einer Datei -- ✅ **Freie Speicherort-Wahl** - Downloads, SD-Karte, Cloud-Ordner -- ✅ **Dateinamen mit Zeitstempel** - `simplenotes_backup_YYYY-MM-DD_HHmmss.json` -- ✅ **Vollständiger Export** - Titel, Inhalt, Timestamps, IDs -- ✅ **Menschenlesbares Format** - JSON mit Formatierung -- ✅ **Unabhängig vom Server** - Funktioniert komplett offline +### Supported Languages +- ✅ **English** - Primary language (default) +- ✅ **German** - Fully translated -### Wiederherstellungs-Modi -- ✅ **Zusammenführen (Merge)** - Neue Notizen hinzufügen, bestehende behalten _(Standard)_ -- ✅ **Ersetzen (Replace)** - Alle löschen und Backup importieren -- ✅ **Duplikate überschreiben (Overwrite)** - Backup gewinnt bei ID-Konflikten -- ✅ **Automatisches Sicherheits-Backup** - Vor jeder Wiederherstellung -- ✅ **Backup-Validierung** - Prüft Format und Version -- ✅ **Fehlerbehandlung** - Klare Fehlermeldungen bei Problemen +### Language Selection +- ✅ **Automatic detection** - Follows system language +- ✅ **Manual selection** - Switchable in settings +- ✅ **Per-App Language** - Android 13+ native language selection +- ✅ **locales_config.xml** - Complete Android integration + +### Scope +- ✅ **400+ strings** - Fully translated +- ✅ **UI texts** - All buttons, dialogs, menus +- ✅ **Error messages** - Helpful localized hints +- ✅ **Settings** - 7 categorized screens --- -## 🖥️ Desktop-Integration +## 💾 Backup & Restore -### Markdown-Export -- ✅ **Automatischer Export** - Jede Notiz → `.md` Datei -- ✅ **Checklisten als Task-Listen** _(NEU)_ - `- [ ]` / `- [x]` Format (GitHub-kompatibel) -- ✅ **Dual-Format** - JSON (Master) + Markdown (Mirror) -- ✅ **Dateinamen-Sanitization** - Sichere Dateinamen aus Titeln -- ✅ **Duplikat-Handling** _(NEU)_ - ID-Suffix bei gleichen Titeln -- ✅ **Frontmatter-Metadata** - YAML mit ID, Timestamps, Type -- ✅ **WebDAV-Sync** - Parallel zum JSON-Sync -- ✅ **Optional** - In Einstellungen ein/ausschaltbar -- ✅ **Initial Export** - Alle bestehenden Notizen beim Aktivieren -- ✅ **Progress-Anzeige** - Zeigt X/Y beim Export +### Local Backup System +- ✅ **JSON export** - All notes in one file +- ✅ **Free location choice** - Downloads, SD card, cloud folder +- ✅ **Filenames with timestamp** - `simplenotes_backup_YYYY-MM-DD_HHmmss.json` +- ✅ **Complete export** - Title, content, timestamps, IDs +- ✅ **Human-readable format** - JSON with formatting +- ✅ **Independent from server** - Works completely offline -### Markdown-Import -- ✅ **Desktop → App** - Änderungen vom Desktop importieren -- ✅ **Last-Write-Wins** - Konfliktauflösung via Timestamp -- ✅ **Frontmatter-Parsing** - Liest Metadata aus `.md` Dateien -- ✅ **Neue Notizen erkennen** - Automatisch in App übernehmen -- ✅ **Updates erkennen** - Nur wenn Desktop-Version neuer ist -- ✅ **Fehlertoleranz** - Einzelne Fehler brechen Import nicht ab - -### WebDAV-Zugriff -- ✅ **Network Drive Mount** - Windows, macOS, Linux -- ✅ **Jeder Markdown-Editor** - VS Code, Typora, Notepad++, iA Writer -- ✅ **Live-Bearbeitung** - Direkter Zugriff auf `.md` Dateien -- ✅ **Ordner-Struktur** - `/notes/` für JSON, `/notes-md/` für Markdown -- ✅ **Automatische Ordner-Erstellung** - Beim ersten Sync +### Restore Modes +- ✅ **Merge** - Add new notes, keep existing ones _(Default)_ +- ✅ **Replace** - Delete all and import backup +- ✅ **Overwrite duplicates** - Backup wins on ID conflicts +- ✅ **Automatic safety backup** - Before every restore +- ✅ **Backup validation** - Checks format and version +- ✅ **Error handling** - Clear error messages on issues --- -## 🔄 Synchronisation +## 🖥️ Desktop Integration + +### Markdown Export +- ✅ **Automatic export** - Each note → `.md` file +- ✅ **Checklists as task lists** _(NEW)_ - `- [ ]` / `- [x]` format (GitHub-compatible) +- ✅ **Dual-format** - JSON (master) + Markdown (mirror) +- ✅ **Filename sanitization** - Safe filenames from titles +- ✅ **Duplicate handling** _(NEW)_ - ID suffix for same titles +- ✅ **Frontmatter metadata** - YAML with ID, timestamps, type +- ✅ **WebDAV sync** - Parallel to JSON sync +- ✅ **Optional** - Toggle in settings +- ✅ **Initial export** - All existing notes when activated +- ✅ **Progress indicator** - Shows X/Y during export + +### Markdown Import +- ✅ **Desktop → App** - Import changes from desktop +- ✅ **Last-Write-Wins** - Conflict resolution via timestamp +- ✅ **Frontmatter parsing** - Reads metadata from `.md` files +- ✅ **Detect new notes** - Automatically adopt to app +- ✅ **Detect updates** - Only if desktop version is newer +- ✅ **Error tolerance** - Individual errors don't abort import + +### WebDAV Access +- ✅ **Network drive mount** - Windows, macOS, Linux +- ✅ **Any Markdown editor** - VS Code, Typora, Notepad++, iA Writer +- ✅ **Live editing** - Direct access to `.md` files +- ✅ **Folder structure** - `/notes/` for JSON, `/notes-md/` for Markdown +- ✅ **Automatic folder creation** - On first sync + +--- + +## 🔄 Synchronization ### Auto-Sync -- ✅ **Intervall-Auswahl** - 15, 30 oder 60 Minuten -- ✅ **WiFi-Trigger** - Sync bei WiFi-Verbindung _(keine SSID-Einschränkung)_ -- ✅ **Akkuschonend** - ~0.2-0.8% pro Tag -- ✅ **Smart Server-Check** - Sync nur wenn Server erreichbar -- ✅ **WorkManager** - Zuverlässige Background-Ausführung -- ✅ **Battery-Optimierung kompatibel** - Funktioniert auch mit Doze Mode +- ✅ **Interval selection** - 15, 30 or 60 minutes +- ✅ **WiFi trigger** - Sync on WiFi connection _(no SSID restriction)_ +- ✅ **Battery-friendly** - ~0.2-0.8% per day +- ✅ **Smart server check** - Sync only when server is reachable +- ✅ **WorkManager** - Reliable background execution +- ✅ **Battery optimization compatible** - Works even with Doze mode -### Sync-Trigger (6 Stück) -1. ✅ **Periodic Sync** - Automatisch nach Intervall -2. ✅ **App-Start Sync** - Beim Öffnen der App -3. ✅ **WiFi-Connect Sync** - Bei jeder WiFi-Verbindung -4. ✅ **Manual Sync** - Button in Einstellungen -5. ✅ **Pull-to-Refresh** - Wisch-Geste in Notizliste -6. ✅ **Settings-Save Sync** - Nach Server-Konfiguration +### Sync Triggers (6 total) +1. ✅ **Periodic sync** - Automatically after interval +2. ✅ **App-start sync** - When opening the app +3. ✅ **WiFi-connect sync** - On any WiFi connection +4. ✅ **Manual sync** - Button in settings +5. ✅ **Pull-to-refresh** - Swipe gesture in notes list +6. ✅ **Settings-save sync** - After server configuration -### Sync-Mechanismus -- ✅ **Upload** - Lokale Änderungen zum Server -- ✅ **Download** - Server-Änderungen in App -- ✅ **Konflikt-Erkennung** - Bei gleichzeitigen Änderungen -- ✅ **Konfliktfreies Merging** - Last-Write-Wins via Timestamp -- ✅ **Sync-Status Tracking** - LOCAL_ONLY, PENDING, SYNCED, CONFLICT -- ✅ **Fehlerbehandlung** - Retry bei Netzwerkproblemen -- ✅ **Offline-First** - App funktioniert ohne Server +### Sync Mechanism +- ✅ **Upload** - Local changes to server +- ✅ **Download** - Server changes to app +- ✅ **Conflict detection** - On simultaneous changes +- ✅ **Conflict-free merging** - Last-Write-Wins via timestamp +- ✅ **Sync status tracking** - LOCAL_ONLY, PENDING, SYNCED, CONFLICT +- ✅ **Error handling** - Retry on network issues +- ✅ **Offline-first** - App works without server -### Server-Verbindung -- ✅ **WebDAV-Protokoll** - Standard-Protokoll -- ✅ **HTTP/HTTPS** - HTTP nur lokal, HTTPS für extern -- ✅ **Username/Password** - Basic Authentication -- ✅ **Connection Test** - In Einstellungen testen -- ✅ **Server-URL Normalisierung** - Automatisches `/notes/` und `/notes-md/` _(NEU in v1.2.1)_ -- ✅ **Flexible URL-Eingabe** - Beide Varianten funktionieren: `http://server/` und `http://server/notes/` +### Server Connection +- ✅ **WebDAV protocol** - Standard protocol +- ✅ **HTTP/HTTPS** - HTTP only local, HTTPS for external +- ✅ **Username/password** - Basic authentication +- ✅ **Connection test** - Test in settings +- ✅ **Server URL normalization** - Automatic `/notes/` and `/notes-md/` _(NEW in v1.2.1)_ +- ✅ **Flexible URL input** - Both variants work: `http://server/` and `http://server/notes/` --- -## 🔒 Privacy & Sicherheit +## 🔒 Privacy & Security ### Self-Hosted -- ✅ **Eigener Server** - Volle Kontrolle über Daten -- ✅ **Keine Cloud** - Keine Drittanbieter -- ✅ **Kein Tracking** - Keine Analytik, keine Telemetrie -- ✅ **Kein Account** - Nur Server-Zugangsdaten -- ✅ **100% Open Source** - MIT Lizenz +- ✅ **Own server** - Full control over data +- ✅ **No cloud** - No third parties +- ✅ **No tracking** - No analytics, no telemetry +- ✅ **No account** - Only server credentials +- ✅ **100% open source** - MIT License -### Daten-Sicherheit -- ✅ **Lokale Speicherung** - App-Private Storage (Android) -- ✅ **WebDAV-Verschlüsselung** - HTTPS für externe Server -- ✅ **Passwort-Speicherung** - Android SharedPreferences (verschlüsselt) -- ✅ **Keine Drittanbieter-Libs** - Nur Android SDK + Sardine (WebDAV) +### Data Security +- ✅ **Local storage** - App-private storage (Android) +- ✅ **WebDAV encryption** - HTTPS for external servers +- ✅ **Password storage** - Android SharedPreferences (encrypted) +- ✅ **No third-party libs** - Only Android SDK + Sardine (WebDAV) -### Entwickler-Features -- ✅ **Datei-Logging** - Optional, nur bei Aktivierung _(NEU in v1.3.2)_ -- ✅ **Datenschutz-Hinweis** - Explizite Warnung bei Aktivierung -- ✅ **Lokale Logs** - Logs bleiben auf dem Gerät +### Developer Features +- ✅ **File logging** - Optional, only when enabled _(NEW in v1.3.2)_ +- ✅ **Privacy notice** - Explicit warning on activation +- ✅ **Local logs** - Logs stay on device --- -## 🔋 Performance & Optimierung +## 🔋 Performance & Optimization -### Akku-Effizienz -- ✅ **Optimierte Sync-Intervalle** - 15/30/60 Min -- ✅ **WiFi-Only** - Kein Mobile Data Sync -- ✅ **Smart Server-Check** - Sync nur wenn Server erreichbar -- ✅ **WorkManager** - System-optimierte Ausführung -- ✅ **Doze Mode kompatibel** - Sync läuft auch im Standby -- ✅ **Gemessener Verbrauch:** - - 15 Min: ~0.8% / Tag (~23 mAh) - - 30 Min: ~0.4% / Tag (~12 mAh) ⭐ _Empfohlen_ - - 60 Min: ~0.2% / Tag (~6 mAh) +### Battery Efficiency +- ✅ **Optimized sync intervals** - 15/30/60 min +- ✅ **WiFi-only** - No mobile data sync +- ✅ **Smart server check** - Sync only when server is reachable +- ✅ **WorkManager** - System-optimized execution +- ✅ **Doze mode compatible** - Sync runs even in standby +- ✅ **Measured consumption:** + - 15 min: ~0.8% / day (~23 mAh) + - 30 min: ~0.4% / day (~12 mAh) ⭐ _Recommended_ + - 60 min: ~0.2% / day (~6 mAh) -### App-Performance -- ✅ **Offline-First** - Funktioniert ohne Internet -- ✅ **Instant-Load** - Notizen laden in <100ms -- ✅ **Smooth Scrolling** - RecyclerView mit ViewHolder +### App Performance +- ✅ **Offline-first** - Works without internet +- ✅ **Instant-load** - Notes load in <100ms +- ✅ **Smooth scrolling** - RecyclerView with ViewHolder - ✅ **Material Design 3** - Native Android UI -- ✅ **Kotlin Coroutines** - Asynchrone Operationen -- ✅ **Minimale APK-Größe** - ~2 MB +- ✅ **Kotlin Coroutines** - Asynchronous operations +- ✅ **Minimal APK size** - ~2 MB --- -## 🛠️ Technische Details +## 🛠️ Technical Details -### Plattform +### Platform - ✅ **Android 8.0+** (API 26+) - ✅ **Target SDK 36** (Android 15) -- ✅ **Kotlin** - Moderne Programmiersprache -- ✅ **Material Design 3** - Neueste Design-Richtlinien -- ✅ **ViewBinding** - Typ-sichere View-Referenzen +- ✅ **Kotlin** - Modern programming language +- ✅ **Material Design 3** - Latest design guidelines +- ✅ **ViewBinding** - Type-safe view references -### Architektur -- ✅ **MVVM-Light** - Einfache Architektur -- ✅ **Single Activity** - Moderne Navigation -- ✅ **Kotlin Coroutines** - Async/Await Pattern -- ✅ **Dispatchers.IO** - Background-Operationen -- ✅ **SharedPreferences** - Settings-Speicherung -- ✅ **File-Based Storage** - JSON-Dateien lokal -- ✅ **Custom Exceptions** - Dedizierte SyncException für bessere Fehlerbehandlung _(NEU in v1.3.2)_ +### Architecture +- ✅ **MVVM-Light** - Simple architecture +- ✅ **Single Activity** - Modern navigation +- ✅ **Kotlin Coroutines** - Async/Await pattern +- ✅ **Dispatchers.IO** - Background operations +- ✅ **SharedPreferences** - Settings storage +- ✅ **File-based storage** - JSON files locally +- ✅ **Custom exceptions** - Dedicated SyncException for better error handling _(NEW in v1.3.2)_ -### Abhängigkeiten -- ✅ **AndroidX** - Jetpack Libraries +### Dependencies +- ✅ **AndroidX** - Jetpack libraries - ✅ **Material Components** - Material Design 3 -- ✅ **Sardine** - WebDAV Client (com.thegrizzlylabs) -- ✅ **Gson** - JSON Serialization -- ✅ **WorkManager** - Background Tasks -- ✅ **OkHttp** - HTTP Client (via Sardine) +- ✅ **Sardine** - WebDAV client (com.thegrizzlylabs) +- ✅ **Gson** - JSON serialization +- ✅ **WorkManager** - Background tasks +- ✅ **OkHttp** - HTTP client (via Sardine) -### Build-Varianten -- ✅ **Standard** - Universal APK (100% FOSS, keine Google-Dependencies) -- ✅ **F-Droid** - Identisch mit Standard (100% FOSS) -- ✅ **Debug/Release** - Entwicklung und Production -- ✅ **Keine Google Services** - Komplett FOSS, keine proprietären Bibliotheken +### Build Variants +- ✅ **Standard** - Universal APK (100% FOSS, no Google dependencies) +- ✅ **F-Droid** - Identical to Standard (100% FOSS) +- ✅ **Debug/Release** - Development and production +- ✅ **No Google Services** - Completely FOSS, no proprietary libraries --- -## 📦 Server-Kompatibilität +## 📦 Server Compatibility -### Getestete WebDAV-Server -- ✅ **Docker WebDAV** (empfohlen für Self-Hosting) -- ✅ **Nextcloud** - Vollständig kompatibel -- ✅ **ownCloud** - Funktioniert einwandfrei +### Tested WebDAV Servers +- ✅ **Docker WebDAV** (recommended for self-hosting) +- ✅ **Nextcloud** - Fully compatible +- ✅ **ownCloud** - Works perfectly - ✅ **Apache mod_dav** - Standard WebDAV -- ✅ **nginx + WebDAV** - Mit korrekter Konfiguration +- ✅ **nginx + WebDAV** - With correct configuration -### Server-Features -- ✅ **Basic Auth** - Username/Password -- ✅ **Directory Listing** - Für Download -- ✅ **PUT/GET** - Upload/Download -- ✅ **MKCOL** - Ordner erstellen -- ✅ **DELETE** - Notizen löschen (zukünftig) +### Server Features +- ✅ **Basic Auth** - Username/password +- ✅ **Directory listing** - For download +- ✅ **PUT/GET** - Upload/download +- ✅ **MKCOL** - Create folders +- ✅ **DELETE** - Delete notes (future) --- -## 🔮 Zukünftige Features +## 🔮 Future Features -Geplant für kommende Versionen: +Planned for upcoming versions: -### v1.4.0 - Checklisten -- ⏳ **Checklisten-Notizen** - Neuer Notiz-Typ mit Checkboxen -- ⏳ **Erledigte Items** - Durchstreichen/Abhaken -- ⏳ **Drag & Drop** - Items neu anordnen +### v1.4.0 - Checklists +- ⏳ **Checklist notes** - New note type with checkboxes +- ⏳ **Completed items** - Strike-through/check off +- ⏳ **Drag & drop** - Reorder items -### v1.5.0 - Internationalisierung -- ⏳ **Mehrsprachigkeit** - Deutsch + Englisch UI -- ⏳ **Sprachauswahl** - In Einstellungen wählbar -- ⏳ **Vollständige Übersetzung** - Alle Strings in beiden Sprachen +### v1.5.0 - Internationalization +- ⏳ **Multi-language** - German + English UI +- ⏳ **Language selection** - Selectable in settings +- ⏳ **Full translation** - All strings in both languages ### v1.6.0 - Modern APIs -- ⏳ **LocalBroadcastManager ersetzen** - SharedFlow stattdessen -- ⏳ **PackageInfo Flags** - PackageInfoFlags.of() verwenden -- ⏳ **Komplexitäts-Refactoring** - Lange Funktionen aufteilen +- ⏳ **Replace LocalBroadcastManager** - Use SharedFlow instead +- ⏳ **PackageInfo Flags** - Use PackageInfoFlags.of() +- ⏳ **Complexity refactoring** - Split long functions --- -## 📊 Vergleich mit anderen Apps +## 📊 Comparison with Other Apps | Feature | Simple Notes Sync | Google Keep | Nextcloud Notes | |---------|------------------|-------------|-----------------| -| Offline-First | ✅ | ⚠️ Eingeschränkt | ⚠️ Eingeschränkt | -| Self-Hosted | ✅ | ❌ | ✅ | -| Auto-Sync | ✅ | ✅ | ✅ | -| Markdown-Export | ✅ | ❌ | ✅ | -| Desktop-Zugriff | ✅ (WebDAV) | ✅ (Web) | ✅ (Web + WebDAV) | -| Lokales Backup | ✅ | ❌ | ⚠️ Server-Backup | -| Kein Google-Account | ✅ | ❌ | ✅ | -| Open Source | ✅ MIT | ❌ | ✅ AGPL | -| APK-Größe | ~2 MB | ~50 MB | ~8 MB | -| Akku-Verbrauch | ~0.4%/Tag | ~1-2%/Tag | ~0.5%/Tag | +| Offline-first | ✅ | ⚠️ Limited | ⚠️ Limited | +| Self-hosted | ✅ | ❌ | ✅ | +| Auto-sync | ✅ | ✅ | ✅ | +| Markdown export | ✅ | ❌ | ✅ | +| Desktop access | ✅ (WebDAV) | ✅ (Web) | ✅ (Web + WebDAV) | +| Local backup | ✅ | ❌ | ⚠️ Server backup | +| No Google account | ✅ | ❌ | ✅ | +| Open source | ✅ MIT | ❌ | ✅ AGPL | +| APK size | ~2 MB | ~50 MB | ~8 MB | +| Battery usage | ~0.4%/day | ~1-2%/day | ~0.5%/day | --- ## ❓ FAQ -**Q: Brauche ich einen Server?** -A: Nein! Die App funktioniert auch komplett offline. Der Server ist optional für Sync. +**Q: Do I need a server?** +A: No! The app works completely offline. The server is optional for sync. -**Q: Welcher Server ist am besten?** -A: Für Einstieg: Docker WebDAV (einfach, leicht). Für Profis: Nextcloud (viele Features). +**Q: Which server is best?** +A: For beginners: Docker WebDAV (simple, easy). For pros: Nextcloud (many features). -**Q: Funktioniert Markdown-Export ohne Desktop-Integration?** -A: Nein, du musst das Feature in den Einstellungen aktivieren. +**Q: Does Markdown export work without Desktop Integration?** +A: No, you need to activate the feature in settings. -**Q: Gehen meine Daten verloren wenn ich den Server wechsle?** -A: Nein! Erstelle ein lokales Backup, wechsle Server, stelle wieder her. +**Q: Will my data be lost if I switch servers?** +A: No! Create a local backup, switch servers, restore. -**Q: Warum JSON + Markdown?** -A: JSON ist zuverlässig und schnell (Master). Markdown ist menschenlesbar (Mirror für Desktop). +**Q: Why JSON + Markdown?** +A: JSON is reliable and fast (master). Markdown is human-readable (mirror for desktop). -**Q: Kann ich die App ohne Google Play nutzen?** -A: Ja! Lade die APK direkt von GitHub oder nutze F-Droid. +**Q: Can I use the app without Google Play?** +A: Yes! Download the APK directly from GitHub or use F-Droid. --- -**Letzte Aktualisierung:** v1.3.2 (2026-01-10) +**Last update:** v1.3.2 (2026-01-10) diff --git a/docs/TRANSLATING.de.md b/docs/TRANSLATING.de.md new file mode 100644 index 0000000..505f47f --- /dev/null +++ b/docs/TRANSLATING.de.md @@ -0,0 +1,151 @@ +# Übersetzung beitragen 🌍 + +**🌍 Sprachen:** **Deutsch** · [English](TRANSLATING.md) + +> So kannst du Simple Notes Sync in deine Sprache übersetzen! + +--- + +## 📋 Übersicht + +Simple Notes Sync unterstützt aktuell: +- 🇺🇸 **Englisch** (en) - Primärsprache +- 🇩🇪 **Deutsch** (de) - Vollständig übersetzt + +Wir freuen uns über neue Übersetzungen! + +--- + +## 🚀 Schnellstart + +### 1. Repository forken + +1. Gehe zu [github.com/inventory69/simple-notes-sync](https://github.com/inventory69/simple-notes-sync) +2. Klicke auf **Fork** (oben rechts) +3. Clone dein Fork: `git clone https://github.com/DEIN-USERNAME/simple-notes-sync.git` + +### 2. Sprachdateien erstellen + +```bash +cd simple-notes-sync/android/app/src/main/res + +# Ordner für deine Sprache erstellen (z.B. Französisch) +mkdir values-fr + +# Strings kopieren +cp values/strings.xml values-fr/strings.xml +``` + +### 3. Strings übersetzen + +Öffne `values-fr/strings.xml` und übersetze alle ``-Einträge: + +```xml + +Simple Notes +Notes + + +Notes Simples +Notes +``` + +**Wichtig:** +- Übersetze nur den Text zwischen `>` und `` +- Ändere NICHT die `name="..."` Attribute +- Behalte `%s`, `%d`, `%1$s` etc. als Platzhalter + +### 4. locales_config.xml aktualisieren + +Füge deine Sprache in `android/app/src/main/res/xml/locales_config.xml` hinzu: + +```xml + + + + + +``` + +### 5. Pull Request erstellen + +1. Committe deine Änderungen +2. Pushe zu deinem Fork +3. Erstelle einen Pull Request mit Titel: `Add [Language] translation` + +--- + +## 📁 Dateistruktur + +``` +android/app/src/main/res/ +├── values/ # Englisch (Fallback) +│ └── strings.xml +├── values-de/ # Deutsch +│ └── strings.xml +├── values-fr/ # Französisch (neu) +│ └── strings.xml +└── xml/ + └── locales_config.xml # Sprachregistrierung +``` + +--- + +## 📝 String-Kategorien + +Die `strings.xml` enthält etwa 400+ Strings, aufgeteilt in: + +| Kategorie | Beschreibung | Anzahl | +|-----------|--------------|--------| +| UI Texte | Buttons, Labels, Titel | ~100 | +| Settings | Alle 7 Einstellungs-Screens | ~150 | +| Dialoge | Bestätigungen, Fehler | ~80 | +| Sync | Synchronisations-Meldungen | ~50 | +| Sonstige | Tooltips, Accessibility | ~30 | + +--- + +## ✅ Qualitätscheckliste + +Vor dem Pull Request: + +- [ ] Alle Strings übersetzt (keine englischen Reste) +- [ ] Platzhalter (`%s`, `%d`) beibehalten +- [ ] Keine XML-Syntaxfehler +- [ ] App startet ohne Crashes +- [ ] Text passt in UI-Elemente (nicht zu lang) +- [ ] `locales_config.xml` aktualisiert + +--- + +## 🔧 Testen + +```bash +cd android +./gradlew app:assembleDebug + +# APK installieren und Sprache in Android-Einstellungen wechseln +``` + +--- + +## ❓ FAQ + +**Muss ich alle Strings übersetzen?** +> Idealerweise ja. Fehlende Strings fallen auf Englisch zurück. + +**Was passiert mit Platzhaltern?** +> `%s` = Text, `%d` = Zahl. Position beibehalten oder mit `%1$s` nummerieren. + +**Wie teste ich meine Übersetzung?** +> App bauen, installieren, in Android-Einstellungen → Apps → Simple Notes → Sprache wählen. + +--- + +## 🙏 Danke! + +Jede Übersetzung hilft Simple Notes Sync mehr Menschen zu erreichen. + +Bei Fragen: [GitHub Issue erstellen](https://github.com/inventory69/simple-notes-sync/issues) + +[← Zurück zur Dokumentation](DOCS.md) diff --git a/docs/TRANSLATING.md b/docs/TRANSLATING.md new file mode 100644 index 0000000..0d8442e --- /dev/null +++ b/docs/TRANSLATING.md @@ -0,0 +1,151 @@ +# Contributing Translations 🌍 + +**🌍 Languages:** [Deutsch](TRANSLATING.de.md) · **English** + +> How to translate Simple Notes Sync into your language! + +--- + +## 📋 Overview + +Simple Notes Sync currently supports: +- 🇺🇸 **English** (en) - Primary language +- 🇩🇪 **German** (de) - Fully translated + +We welcome new translations! + +--- + +## 🚀 Quick Start + +### 1. Fork the Repository + +1. Go to [github.com/inventory69/simple-notes-sync](https://github.com/inventory69/simple-notes-sync) +2. Click **Fork** (top right) +3. Clone your fork: `git clone https://github.com/YOUR-USERNAME/simple-notes-sync.git` + +### 2. Create Language Files + +```bash +cd simple-notes-sync/android/app/src/main/res + +# Create folder for your language (e.g., French) +mkdir values-fr + +# Copy strings +cp values/strings.xml values-fr/strings.xml +``` + +### 3. Translate Strings + +Open `values-fr/strings.xml` and translate all `` entries: + +```xml + +Simple Notes +Notes + + +Notes Simples +Notes +``` + +**Important:** +- Only translate text between `>` and `` +- Do NOT change `name="..."` attributes +- Keep `%s`, `%d`, `%1$s` etc. as placeholders + +### 4. Update locales_config.xml + +Add your language to `android/app/src/main/res/xml/locales_config.xml`: + +```xml + + + + + +``` + +### 5. Create Pull Request + +1. Commit your changes +2. Push to your fork +3. Create a Pull Request with title: `Add [Language] translation` + +--- + +## 📁 File Structure + +``` +android/app/src/main/res/ +├── values/ # English (Fallback) +│ └── strings.xml +├── values-de/ # German +│ └── strings.xml +├── values-fr/ # French (new) +│ └── strings.xml +└── xml/ + └── locales_config.xml # Language registration +``` + +--- + +## 📝 String Categories + +The `strings.xml` contains about 400+ strings, divided into: + +| Category | Description | Count | +|----------|-------------|-------| +| UI Texts | Buttons, labels, titles | ~100 | +| Settings | All 7 settings screens | ~150 | +| Dialogs | Confirmations, errors | ~80 | +| Sync | Synchronization messages | ~50 | +| Other | Tooltips, accessibility | ~30 | + +--- + +## ✅ Quality Checklist + +Before creating your Pull Request: + +- [ ] All strings translated (no English leftovers) +- [ ] Placeholders (`%s`, `%d`) preserved +- [ ] No XML syntax errors +- [ ] App launches without crashes +- [ ] Text fits in UI elements (not too long) +- [ ] `locales_config.xml` updated + +--- + +## 🔧 Testing + +```bash +cd android +./gradlew app:assembleDebug + +# Install APK and switch language in Android settings +``` + +--- + +## ❓ FAQ + +**Do I need to translate all strings?** +> Ideally yes. Missing strings fall back to English. + +**What about placeholders?** +> `%s` = text, `%d` = number. Keep position or use `%1$s` for numbering. + +**How do I test my translation?** +> Build app, install, go to Android Settings → Apps → Simple Notes → Language. + +--- + +## 🙏 Thank You! + +Every translation helps Simple Notes Sync reach more people. + +Questions? [Create a GitHub Issue](https://github.com/inventory69/simple-notes-sync/issues) + +[← Back to Documentation](DOCS.md) diff --git a/docs/UPCOMING.de.md b/docs/UPCOMING.de.md new file mode 100644 index 0000000..50f3554 --- /dev/null +++ b/docs/UPCOMING.de.md @@ -0,0 +1,76 @@ +# Geplante Features 🚀 + +**🌍 Sprachen:** **Deutsch** · [English](UPCOMING.md) + +> Was kommt als Nächstes? Hier findest du unsere Pläne für zukünftige Versionen. + +--- + +## v1.5.0 - Jetpack Compose & Internationalisierung ✅ + +> **Status:** Released 🎉 (Januar 2026) + +### 🎨 Jetpack Compose UI + +- ✅ **Komplettes UI-Redesign** - Von XML-Views zu Jetpack Compose +- ✅ **Modernisierte Einstellungen** - 7 kategorisierte Screens +- ✅ **Selection Mode** - Long-Press für Mehrfachauswahl +- ✅ **Silent-Sync Mode** - Kein Banner bei Auto-Sync + +### 🌍 Mehrsprachigkeit + +- ✅ **Englisch + Deutsch** - 400+ übersetzte Strings +- ✅ **Automatische Spracherkennung** - Folgt der System-Sprache +- ✅ **Per-App Language (Android 13+)** - Native Sprachauswahl + +### 🎨 UI-Verbesserungen + +- ✅ **Splash Screen** - App-Foreground-Icon +- ✅ **App Icon** - In About Screen und Empty State +- ✅ **Slide-Animationen** - Flüssige Übergänge im NoteEditor + +--- + +## v1.6.0 - Technische Modernisierung + +> **Status:** In Planung 📋 + +### 🔧 Server-Ordner Prüfung + +- **WebDAV Folder Check** - Prüft ob der Ordner auf dem Server existiert und beschreibbar ist +- **Bessere Fehlermeldungen** - Hilfreiche Hinweise bei Server-Problemen +- **Connection-Test Verbesserung** - Prüft Read/Write Permissions + +### 🔧 Technische Verbesserungen + +- **Code-Refactoring** - LongMethod und LargeClass Warnings beheben +- **Modernere Background-Sync Architektur** - Noch zuverlässiger +- **Verbesserte Progress-Dialoge** - Material Design 3 konform + +--- + +## v1.7.0 - Community Features + +> **Status:** Ideen-Sammlung 💡 + +### Mögliche Features + +- **Zusätzliche Sprachen** - Community-Übersetzungen (FR, ES, IT, ...) +- **Kategorien/Tags** - Notizen organisieren +- **Suche** - Volltextsuche in Notizen +- **Widget** - Schnellzugriff vom Homescreen + +--- + +## 💡 Feedback & Wünsche + +Hast du eine Idee für ein neues Feature? + +- **[Feature Request erstellen](https://github.com/inventory69/simple-notes-sync/issues/new?template=feature_request.yml)** +- **[Bestehende Wünsche ansehen](https://github.com/inventory69/simple-notes-sync/issues?q=is%3Aissue+label%3Aenhancement)** + +--- + +**Hinweis:** Diese Roadmap zeigt unsere aktuellen Pläne. Prioritäten können sich basierend auf Community-Feedback ändern. + +[← Zurück zur Dokumentation](DOCS.md) diff --git a/docs/UPCOMING.en.md b/docs/UPCOMING.en.md deleted file mode 100644 index a512d9b..0000000 --- a/docs/UPCOMING.en.md +++ /dev/null @@ -1,56 +0,0 @@ -# Upcoming Features 🚀 - -**🌍 Languages:** [Deutsch](UPCOMING.md) · **English** - -> What's next? Here you'll find our plans for future versions. - ---- - -## v1.5.0 - Internationalization & UI Polish - -> **Status:** In Development 🔨 - -### 🌍 Multi-Language Support - -- **English as default language** - International users welcome -- **German translation** - Fully translated -- **Automatic language detection** - Follows system language -- **Manual language selection** - Switchable in settings - -### ⚙️ Redesigned Settings - -- **Modernized settings design** - Cleaner and more intuitive -- **Categorized options** - Sync, backup, developer options - -### 🎨 UI Improvements - -- **Splash screen** - App icon on startup -- **Server folder check** - Better error messages during setup -- **Subtle sync indicator** - Banner only shown on actual changes - ---- - -## v1.6.0 - Modern APIs - -> **Status:** Planned 📋 - -### 🔧 Technical Modernization - -- **Modern background sync architecture** - Even more reliable -- **Improved progress dialogs** - Material Design 3 compliant -- **Code quality** - Internal optimizations - ---- - -## 💡 Feedback & Suggestions - -Have an idea for a new feature? - -- **[Create a feature request](https://github.com/inventory69/simple-notes-sync/issues/new?template=feature_request.yml)** -- **[View existing requests](https://github.com/inventory69/simple-notes-sync/issues?q=is%3Aissue+label%3Aenhancement)** - ---- - -**Note:** This roadmap shows our current plans. Priorities may change based on community feedback. - -[← Back to documentation](DOCS.en.md) diff --git a/docs/UPCOMING.md b/docs/UPCOMING.md index 89fba23..3ac984e 100644 --- a/docs/UPCOMING.md +++ b/docs/UPCOMING.md @@ -1,56 +1,76 @@ -# Geplante Features 🚀 +# Upcoming Features 🚀 -**🌍 Languages:** **Deutsch** · [English](UPCOMING.en.md) +**🌍 Languages:** [Deutsch](UPCOMING.de.md) · **English** -> Was kommt als Nächstes? Hier findest du unsere Pläne für zukünftige Versionen. +> What's next? Here you'll find our plans for future versions. --- -## v1.5.0 - Internationalisierung & UI-Polish +## v1.5.0 - Jetpack Compose & Internationalization ✅ -> **Status:** In Entwicklung 🔨 +> **Status:** Released 🎉 (January 2026) -### 🌍 Mehrsprachigkeit +### 🎨 Jetpack Compose UI -- **Englisch als Standard-Sprache** - Internationale Nutzer willkommen -- **Deutsche Übersetzung** - Vollständig übersetzt -- **Automatische Spracherkennung** - Folgt der System-Sprache -- **Manuelle Sprachwahl** - In den Einstellungen umschaltbar +- ✅ **Complete UI redesign** - From XML views to Jetpack Compose +- ✅ **Modernized settings** - 7 categorized screens +- ✅ **Selection Mode** - Long-press for multi-select +- ✅ **Silent-Sync Mode** - No banner during auto-sync -### ⚙️ Überarbeitete Einstellungen +### 🌍 Multi-Language Support -- **Modernisiertes Settings-Design** - Übersichtlicher und intuitiver -- **Kategorisierte Optionen** - Sync, Backup, Entwickler-Optionen +- ✅ **English + German** - 400+ translated strings +- ✅ **Automatic language detection** - Follows system language +- ✅ **Per-App Language (Android 13+)** - Native language selection -### 🎨 UI-Verbesserungen +### 🎨 UI Improvements -- **Splash Screen** - App-Icon beim Start -- **Server-Ordner Prüfung** - Bessere Fehlermeldungen bei der Einrichtung -- **Dezentere Sync-Anzeige** - Banner nur bei tatsächlichen Änderungen +- ✅ **Splash screen** - App foreground icon +- ✅ **App icon** - In About screen and empty state +- ✅ **Slide animations** - Smooth transitions in NoteEditor --- -## v1.6.0 - Modern APIs +## v1.6.0 - Technical Modernization -> **Status:** Geplant 📋 +> **Status:** Planned 📋 -### 🔧 Technische Modernisierung +### 🔧 Server Folder Check -- **Modernere Background-Sync Architektur** - Noch zuverlässiger -- **Verbesserte Progress-Dialoge** - Material Design 3 konform -- **Code-Qualität** - Interne Optimierungen +- **WebDAV folder check** - Checks if folder exists and is writable on server +- **Better error messages** - Helpful hints for server problems +- **Connection test improvement** - Checks read/write permissions + +### 🔧 Technical Improvements + +- **Code refactoring** - Fix LongMethod and LargeClass warnings +- **Modern background sync architecture** - Even more reliable +- **Improved progress dialogs** - Material Design 3 compliant --- -## 💡 Feedback & Wünsche +## v1.7.0 - Community Features -Hast du eine Idee für ein neues Feature? +> **Status:** Idea Collection 💡 -- **[Feature Request erstellen](https://github.com/inventory69/simple-notes-sync/issues/new?template=feature_request.yml)** -- **[Bestehende Wünsche ansehen](https://github.com/inventory69/simple-notes-sync/issues?q=is%3Aissue+label%3Aenhancement)** +### Potential Features + +- **Additional languages** - Community translations (FR, ES, IT, ...) +- **Categories/Tags** - Organize notes +- **Search** - Full-text search in notes +- **Widget** - Quick access from homescreen --- -**Hinweis:** Diese Roadmap zeigt unsere aktuellen Pläne. Prioritäten können sich basierend auf Community-Feedback ändern. +## 💡 Feedback & Suggestions -[← Zurück zur Dokumentation](DOCS.md) +Have an idea for a new feature? + +- **[Create a feature request](https://github.com/inventory69/simple-notes-sync/issues/new?template=feature_request.yml)** +- **[View existing requests](https://github.com/inventory69/simple-notes-sync/issues?q=is%3Aissue+label%3Aenhancement)** + +--- + +**Note:** This roadmap shows our current plans. Priorities may change based on community feedback. + +[← Back to documentation](DOCS.md) diff --git a/fastlane/metadata/android/de-DE/changelogs/13.txt b/fastlane/metadata/android/de-DE/changelogs/13.txt new file mode 100644 index 0000000..55bbb0a --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/13.txt @@ -0,0 +1,8 @@ +• Komplett neues UI-Design mit Jetpack Compose +• NEU: Englische Sprachunterstützung + Sprachauswahl +• NEU: Automatische Systemsprachen-Erkennung +• NEU: Long-Press Mehrfachauswahl zum Löschen +• Modernisierte Einstellungen mit 7 Bereichen +• Silent-Sync (kein Banner bei Auto-Sync) +• Verbesserter NoteEditor mit Slide-Animationen +• App-Icon in Über-Screen und Leerzustand diff --git a/fastlane/metadata/android/de-DE/full_description.txt b/fastlane/metadata/android/de-DE/full_description.txt index 8065c9e..d2531a3 100644 --- a/fastlane/metadata/android/de-DE/full_description.txt +++ b/fastlane/metadata/android/de-DE/full_description.txt @@ -3,7 +3,8 @@ Simple Notes Sync ist eine minimalistische Notizen-App mit WebDAV-Synchronisatio HAUPTFUNKTIONEN: • Text-Notizen und Checklisten erstellen -• Checklisten mit Tap-to-Check, Drag & Drop, Swipe-to-Delete +• Checklisten mit Tap-to-Check und Drag & Drop +• Auswahlmodus: Long-Press zur Mehrfachauswahl für Batch-Aktionen • WebDAV-Synchronisation mit eigenem Server • Multi-Device Sync (Handy, Tablet, Desktop) • Markdown-Export für Obsidian/Desktop-Editoren @@ -11,9 +12,17 @@ HAUPTFUNKTIONEN: • Automatische Synchronisation im Heim-WLAN • Konfigurierbares Sync-Interval (15/30/60 Minuten) • Material Design 3 mit Dynamic Colors (Android 12+) +• Jetpack Compose UI - modern, schnell und flüssig • Komplett offline nutzbar • Keine Werbung, keine Tracker +MEHRSPRACHIG: + +• Englische und deutsche Sprachunterstützung +• Per-App Sprachauswahl (Android 13+) +• Automatische Systemsprachen-Erkennung +• Über 400 übersetzte Strings + DATENSCHUTZ: Deine Daten bleiben bei dir! Die App kommuniziert nur mit deinem eigenen WebDAV-Server. Keine Cloud-Dienste, keine Tracking-Bibliotheken, keine Analysetools. @@ -33,16 +42,18 @@ SYNCHRONISATION: • Optimierte Performance: überspringt unveränderte Dateien (~2-3s Sync-Zeit) • E-Tag Caching für 20x schnellere "keine Änderungen" Checks • Gemessener Akkuverbrauch: nur ~0.4% pro Tag (bei 30min) +• Silent-Sync Modus: kein Banner bei Auto-Sync • Doze Mode optimiert für zuverlässige Background-Syncs • Manuelle Synchronisation jederzeit möglich MATERIAL DESIGN 3: -• Moderne Benutzeroberfläche +• Moderne Jetpack Compose Benutzeroberfläche • Dynamic Colors (Material You) auf Android 12+ • Dark Mode Support -• Intuitive Gesten (Swipe-to-Delete) +• Auswahlmodus mit Batch-Löschen • Live Sync-Status Anzeige +• Flüssige Slide-Animationen Open Source unter MIT-Lizenz Quellcode: https://github.com/inventory69/simple-notes-sync \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/13.txt b/fastlane/metadata/android/en-US/changelogs/13.txt new file mode 100644 index 0000000..19b955e --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/13.txt @@ -0,0 +1,8 @@ +• Complete UI redesign with Jetpack Compose +• NEW: English language support + Language selector +• NEW: Auto-detects system language +• NEW: Long-press selection mode for batch delete +• Modernized Settings with 7 organized screens +• Silent-Sync mode (no banner during auto-sync) +• Improved NoteEditor with slide animations +• App icon in About screen and empty state diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index 92257a2..8c97b85 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -3,7 +3,8 @@ Simple Notes Sync is a minimalist note-taking app with WebDAV synchronization. KEY FEATURES: • Create text notes and checklists -• Checklists with tap-to-check, drag & drop, swipe-to-delete +• Checklists with tap-to-check, drag & drop reordering +• Selection mode: long-press to select multiple notes for batch actions • WebDAV synchronization with your own server • Multi-device sync (phone, tablet, desktop) • Markdown export for Obsidian/desktop editors @@ -11,9 +12,17 @@ KEY FEATURES: • Automatic synchronization on home WiFi • Configurable sync interval (15/30/60 minutes) • Material Design 3 with Dynamic Colors (Android 12+) +• Jetpack Compose UI - modern, fast, and smooth • Fully usable offline • No ads, no trackers +MULTILINGUAL: + +• English and German language support +• Per-App Language selector (Android 13+) +• Automatic system language detection +• 400+ translated strings + PRIVACY: Your data stays with you! The app only communicates with your own WebDAV server. No cloud services, no tracking libraries, no analytics tools. @@ -33,16 +42,18 @@ SYNCHRONIZATION: • Optimized performance: skips unchanged files (~2-3s sync time) • E-Tag caching for 20x faster "no changes" checks • Measured battery consumption: only ~0.4% per day (at 30min) +• Silent-Sync mode: no banner during auto-sync • Doze Mode optimized for reliable background syncs • Manual synchronization available anytime MATERIAL DESIGN 3: -• Modern user interface +• Modern Jetpack Compose user interface • Dynamic Colors (Material You) on Android 12+ • Dark Mode support -• Intuitive gestures (Swipe-to-delete) +• Selection mode with batch delete • Live sync status indicator +• Smooth slide animations Open Source under MIT License Source code: https://github.com/inventory69/simple-notes-sync From 16a3338903c07e0f87c440c8a026fb437ffe19da Mon Sep 17 00:00:00 2001 From: inventory69 Date: Fri, 16 Jan 2026 16:50:41 +0100 Subject: [PATCH 07/12] chore: update app screenshots for v1.5.0 - Replace JPG screenshots with higher quality PNG versions - Add 4th screenshot for better app showcase --- .../de-DE/images/phoneScreenshots/1.jpg | Bin 122682 -> 0 bytes .../de-DE/images/phoneScreenshots/1.png | Bin 0 -> 98495 bytes .../de-DE/images/phoneScreenshots/2.jpg | Bin 141711 -> 0 bytes .../de-DE/images/phoneScreenshots/2.png | Bin 0 -> 138275 bytes .../de-DE/images/phoneScreenshots/3.jpg | Bin 137180 -> 0 bytes .../de-DE/images/phoneScreenshots/3.png | Bin 0 -> 114808 bytes .../de-DE/images/phoneScreenshots/4.png | Bin 0 -> 121442 bytes .../en-US/images/phoneScreenshots/1.jpg | Bin 120939 -> 0 bytes .../en-US/images/phoneScreenshots/1.png | Bin 0 -> 98495 bytes .../en-US/images/phoneScreenshots/2.jpg | Bin 91718 -> 0 bytes .../en-US/images/phoneScreenshots/2.png | Bin 0 -> 138275 bytes .../en-US/images/phoneScreenshots/3.jpg | Bin 139853 -> 0 bytes .../en-US/images/phoneScreenshots/3.png | Bin 0 -> 114808 bytes .../en-US/images/phoneScreenshots/4.png | Bin 0 -> 121442 bytes 14 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 fastlane/metadata/android/de-DE/images/phoneScreenshots/1.jpg create mode 100644 fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png delete mode 100644 fastlane/metadata/android/de-DE/images/phoneScreenshots/2.jpg create mode 100644 fastlane/metadata/android/de-DE/images/phoneScreenshots/2.png delete mode 100644 fastlane/metadata/android/de-DE/images/phoneScreenshots/3.jpg create mode 100644 fastlane/metadata/android/de-DE/images/phoneScreenshots/3.png create mode 100644 fastlane/metadata/android/de-DE/images/phoneScreenshots/4.png delete mode 100644 fastlane/metadata/android/en-US/images/phoneScreenshots/1.jpg create mode 100644 fastlane/metadata/android/en-US/images/phoneScreenshots/1.png delete mode 100644 fastlane/metadata/android/en-US/images/phoneScreenshots/2.jpg create mode 100644 fastlane/metadata/android/en-US/images/phoneScreenshots/2.png delete mode 100644 fastlane/metadata/android/en-US/images/phoneScreenshots/3.jpg create mode 100644 fastlane/metadata/android/en-US/images/phoneScreenshots/3.png create mode 100644 fastlane/metadata/android/en-US/images/phoneScreenshots/4.png diff --git a/fastlane/metadata/android/de-DE/images/phoneScreenshots/1.jpg b/fastlane/metadata/android/de-DE/images/phoneScreenshots/1.jpg deleted file mode 100644 index 7bac06abb6974e9ea024b476b574bb2644517c1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 122682 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

Nn?DyOJdX4XXJ-=>g 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 ThpPQY(I|Z6{4@3N_wxS&&hURD diff --git a/fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png b/fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png new file mode 100644 index 0000000000000000000000000000000000000000..be2403948b8a27ea98ae3d479a0fcd852124ba44 GIT binary patch literal 98495 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 literal 0 HcmV?d00001 diff --git a/fastlane/metadata/android/de-DE/images/phoneScreenshots/2.jpg b/fastlane/metadata/android/de-DE/images/phoneScreenshots/2.jpg deleted file mode 100644 index 4adc37a669c9994cc6e8090bc509c2326dff6d80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141711 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 atMv5rbW@cx6i4Z}$?XD%Rk!~9_&)$P;hjbR diff --git a/fastlane/metadata/android/de-DE/images/phoneScreenshots/2.png b/fastlane/metadata/android/de-DE/images/phoneScreenshots/2.png new file mode 100644 index 0000000000000000000000000000000000000000..3d01bb6688d6f877b582c5ab2091e7ff121c659e GIT binary patch literal 138275 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 ky8A-JE|AD@aH?L}z}$IG$dV7vrr1h2Fhear(f8 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 TjsZ*5% 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 H7jOR;^7%jY literal 0 HcmV?d00001 diff --git a/fastlane/metadata/android/de-DE/images/phoneScreenshots/3.jpg b/fastlane/metadata/android/de-DE/images/phoneScreenshots/3.jpg deleted file mode 100644 index b6464847879e0738308278e866a641acdb4c5afd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137180 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%0Dh)@d%KcdK=h^9hJ>`-s5R1qg5=gJ7teg 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 diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index c1a7f11..cd32c30 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -93,6 +93,7 @@ Already synced Server not reachable ✅ Synced: %d notes + ℹ️ Nothing to sync diff --git a/fastlane/metadata/android/de-DE/images/phoneScreenshots/5.png b/fastlane/metadata/android/de-DE/images/phoneScreenshots/5.png new file mode 100644 index 0000000000000000000000000000000000000000..e639635ca10920bde8ef71656b4165c45a60f34a GIT binary patch literal 102115 zcmeFZS5%X2+bxRvDkxGE5CH*^7nQD5L5hNk^xm6*lu)JD5S6ANpwhbtp#_NaPDFZd zp_fSSEf7i|$-4RewboecV4v-MwEv93$di!rJlB1-Ip=lfvxb@i)ivg8WMpJiimzX2 zk&#{6B_pF~p|}X12_B@oO-6R%zO{j(jjAdc4|s}#?D7Th8gO*s{Dl`T{MRu>3pjpE zcK#;t4l<=M2-!d9uK|CS7jFLVWAKoS?78z>Hy6m;yYd>39}5VHK7RaIMBvdQF*35t zUoZXV6X?NEQuPb~O_g@hmTi#!r}#4jOkW6A$WRNUI??OSVMYauZ*Uht+z zkHB^PU)T1(ujc~w|9PF@oBtoLL5q#!CiwRycR58J3JQv;IrYEb;RSas1v#?fzB_AV zWOvCFUp&|GN!^_B)}hyDZ`)HQ=jQqGrnxxphe6Y9>qoAV7V6Q&v6gZFvGKacl`TJB zsa70?US`msZwa@2uA@Qw54^b%_9cq=ph-m)IVrjoO2ax->B-B{@}XH_lu+4u8Xm0#@9GsIBRl>%u7?nFUi=hFeHef1 zmZYSlg#Yf6Ea|(SwWG=AaBh>h3+Axe=dpl*jIH^e`_D}64nCyA`+H1G%trdfI!Ldr z9}mJ5J_V$diZRsd0Sa^rDZ!Bu6BnkF3l0r=`RdinS1&`P zU|vnl8>wOKkRx}AJvs`GmfE;(^2413Z3Sii-e-alQJ-ae79XNkWrLq(gfdr(S$D?{ zjt%=W-wBu<=H=j+i)lEMs#6y;tu6nJ-V0l$>Mtl_A$|@!45AT3Y@@ zAP{gkya>)^DyaVY^=lO+a0`!)j{fo`fQgA=4+}?TV464;)YD~R(lX|M!${@MgHlfw zIyCSf%-jxIKGWr@!G?tB!#TuvRyWonS#VY)GihaG!%klFSFg5ZJ$y#bLTK1zRBSOf zFjOoOXLb5Wa~gKh<;@eyB;Oife(kpCjgbb2&YN6|ajvd=w*46ysJClj)I&`ry{k85 zpP-94VIy#@{OxI~@p8|N(h&!t{o09aI9wMjIme|`|D)C7{Cw_)TGf$)=h5s6^#Lb} z=0@`J&6&}ZiA;nNx)v} zv6_?&a-X#9Q3t}E&&)9;o(KUo)`BS=UbDhP$lM?H_57@?{rhaUnY(5j5xP!;<)8a? zQ8TABcO(L(C@<-c7MT$9hXd|cKqiDXTPZUTfxf1%8=D#M;!5;_#Ia?}#z=nJ^5}!6 zrUuh1X-5Yt4f%;7t;tKuX_FOkw`TfMJvYyELk0CGyVg-o#)v5$Wp@WhlWB0`;!YFE zmIUp z(qy2^(mnRgM(+*5!I@PLGU;rWJYp=axTqdi#DfS+caWN|CJ8CSAv?jv=cYO^}(H-}=l@PP6!# z4$U=>jvSDHz%pqzkG?Vj-fcM0@?v&9u*qs-JwrWRl9iP%rVPoO>sz;8xgsS67ugxA zI@-+F{=yfo3|&-#wH~dnevaupAbW43{nKa9UbnEKqTCsOih=FU>f;Tm55P%mV(Rqe z$xpi&c-Pn0mtUvt?d?^a?WFGS9xwExge2IY-EBDOI#0rY9y@!6W|j~I8!(1|fWW$g ziK(f$%WUdTcpw!deR3Sri zb@i%WHPhN%2UM(^&|>^I;Egp|mLXWyJ5wDI&bEDcylD($*{xO7I(je60yFxn;<1>J zQiG_Nz;@qEo%f~f6Y_sR0>I)nR`c|c^K|p7lni1*LVO0l-oUX-ys?7%`EoC%8$@KT zzG(1U+VFNd>329}m5R0Cx)3M>R|}>WPWh74J=Er{7kKz|CBk5hA^kF_R0WMJ*(40bSZ+v$$l`q zQ-mX!_OhzVA?dUVIwQHpUJ2Vt*GguTqkk;UB8zQjBbWx$J{}w#>H?**F(|YHmKNwa zQ))9Y1d<#4C2&S;=C#|mJ0g%-S#^hN-h^dUjuvZnjPxmuPr9UG*(* z=#fqtR@Ss8fxg}pk-$SKkNwK6g;!Cua+}Ae7~qp#JJGa1?QZP*3g?*a;d=8=Jw!!C zw>Hq^kAm;bW}Kipcw*CWJq5e4M>@=0|RBE)r?pGTk%XQ~0UI zw;4~}%Pd}6tfNS{+xF^JJ}j+(Y$cWo5K~ z#>Vu`d^@{^o1eL8mgk`j9{G=2vuD7(cRJ4~e)cnbFr(m5OY__r8dL;1pYSm(bvcAq z6KO`Mv{vS?gAZBmS;lK+osOBJhwCx84Q!&DX9y*Ombr+SSUfX%)Sa})-e%A+zhao9 z`kptWU6$1GVfGp3nVAa&k_m@%Rk+O7^22>6I)`nup9uy(;y;^>SdNtxb%;8~`~nMx zsdO}~T(?bVgoY=k80r^4am9b}6}BDMt%^hCKh&;0IKoh~3PY3*1&18$?MIRNE}iu? zZpkRpu7z#xVHWH*aeV}#k2HhW+0hH=ybiPtrX_msMBRQGIP(4FTR*aA+XMcji`r4w zqq#K;4Z=ke1k5M=|Nf0b=(}KQPBTAC{TB^oeag{d zPTK0(B|oXZu^K{axrIc{T&4KMqr0AwR;Q(+#dLVj#JM}g`4pq5qJkbBjf(o5RAtw> zRp(8bNN%$omL{i;VizsdX!g}ABnI^XONcS#5!;g|9W@#58MFR0hb*EN zLoJW93Uo`v#Kpz=G@i-JXSwvd=n+c=2)-YL{)L|~MBLIrSn`{vAdL}vhKQl3M1p#K zgOB;hWNl_pgOu7Ds=*(aE#}^^zgcZ;koLGgV!_$Hh5>beoU`tN(nqX3jsmTJc1&U%>^&$ho&kyE3@)wepebDx%b(#sj>7oZ6n z0;J7p{vtsq>yet~l#A*Akh9D9Nj2-A7^pIf*^SkXMC|Tn+!FA`;VWqW;G&(JjKq+7 z@UB(%#taeYausLb=6IuNFSBU4u@N&96Bid(TnSHH+B0POGH66trCr_Ly?%|{o>?C) z7F~s5C^^b2DmKOt8{?(tt8&M#l$Q{dXF6e3y~Uu-5uC>g!5BLZ`SeKi{>ldA~laeShGQFCr($ru952^BU)AWP)`E zNfO+GX}^8@CdkPN+Q(NfUL2GEGfh?f0II;scEfdgD;AlNam0`TAVOznfiaO77R`40 zq7~8aA9Jr-Sw;jGx!Jk!qi33xlIeqtw6#*g_S8O$uOM27gZ^8bE zgh~SL$R(xfT8S>`p%UTN0RhuxE146%nqjq`a1q#g;c4{311T8WB*MSSx6GzGO@=cL zU9Q=Dxy*LtSH&K#PRwsU8$1woLTeDNSmRVsmV+N}Shbt)V!PB7$=(afWgW(|Iz4P#=$J$$%2n)cL;u>ln6BS}f4^ZvoHpLi+Vj8RvP z0lRsU%WKwnGvi)$_kxo>I`5kw(vKPk=RJ`7^g|(<;($Hm8RUZ+ zw|v6AYWrBYotIC)Ql&db6|{J;iDLvFk3%`x>tHgq!w!Y-tM20V>-@HAY434!E7mGY zKXok7Gp&4+p1N#aPmwTGe}IgOT?S46T}<#IsQHV>pLuWb+fC+W;$59FHTw(ISI-|0 z{c0LIk)=8bd=c&s*oKblV1=?pK+b%zG(bI#Q_#Zl z6dczWdH%(q^pR>?iQ@+5vZ!TMmYvBu^Tq-=aqq8o$1b+sha_gWNYPs_aF;Y$>)H?y zr~g=7w1P)h2^#q=)1rcB)YD;1X=b8Ui_2<3BnNp@ZgqWC=b^bk z^HcrOzq}6~n3|fR9LBVz68XghoVzw9#GPkKd35b3gZHpS7bnEM@n|D2(LP@v;*&r* zgYgJrgMSyqOj}#{WpcuFqq{A*`rMg*t_G3;0t66eySmiQnr^OMuc7w+C7lr9P~n-G znfRYl-7lSm_)UDU$B$*NpH`ZsO+s=`(AN)e0Ex2h&HUZs#sGK(d-A z!`dWMeJZEIp>ca!(JU3^F%bnL66ggFME-qC9I`g|UbizEFaK1Nl#`Pa6{Q9+2D4}$ zsX5VgU4Obg^3G%1Nu87JesE6FAK6lplJ$x#i;%gt&NgC@p4Ih{0^I7(_xZ-z%}0D1 zKjfb(aI|oHAEDh_k1;iM?^pw``1oPUFV3^AWDHOPGeF(aVYqh%J8_;qz@3)+o=b%yJnC(_Ak z%|nMvWOvmK;&>)1brF16Ra%a0wIfTE|mxj&d`qzMT(UV;Dj6$8rZPCy&~)tMil z$<9LV7=X>zaT_}d(KEy&*`aL!D9)fWflPuV z#wj=eQ2`mP)_kKe5ES-dXa=5~oUB_^q|2kL;#gQ*yq$Oh^WedQQ%u9ghBv>AjByFE zl9ZM#TA*K*?=^Ue-FoWnM{|eI#m#Y~RB1^m#T(B(+#Z*YTCl%0r$jZ>2kl@U! z_WJdcZLf7=b696*XQh~K25OSwxu@H!P`_g+|a zZoH*l*X9=l_X+Xu<+q=nWeiO+berN2zfJPQ*>`r0XxsFv!4fZ1OnSP3mfNH@z;mJ$%#XTX?sP}!7fZTr`gjq!P3ql7!b2!+RMP3$Gj`iEU?B=GI#Lb}4s6s@ zc!I}E3F#R_9`zS0C79Vj zQ|7m3={x^APN~AKwF^?VVsm1LTSuE!xrH2{m)Jw0EI0Pt`u@Be$^pytNU9W`*s#m#h6{umxsqwYVrt6BXLx_+)g4Ag81?|d-Fvh% z<9=A4uc?U?bHqc(W}$`%aknU}Ap&bb^VuS;k5cn)z}e?ds{NUb08|E6#mAODD{t_OGF0 zF0-5S^WQBI3GH=;7i8@pH6Sz0+tOsbr|D1o!e3H00{^o|=oFkNCs;q|rQ|RYf!u@p zD#lc~|LVyQ-H+N?nv$7~Dl*EM?S8%0$Ku;kkCz`*8LDMeP~WQY$j^|%Y1-={iNjyk zAdTUtA(S7Y*%e!yR>G*~AJcyfH^5qEj`;?F&#pUYh8HXGg z%eT!q8N<~D5>V3qLKu>JD9=2JlsmSF$oKUDzg^u18?2OdI?>hS6w| z$6{u6mWGI^w4E8)-6L+$&(>N~`aWLmq{|0{fgR{=@@Gy{w!@+tjvjq#ltz8a9aDMz znxgt>b|bLRg`Dc^g9aswjVM`=@B9_oL0-#s51x;Yhx$Wf(xT-77v_G8@21>!SJxBZ zLrzXby;ENG6g1$L@L<+{uyD;+T^+SC2G}3dTpLx67jl*#+gp`M+p}~mEF06gW2q4B zW==C=rFD1e<%rTV&kJOKDPt))``p7p5p$|2Sn7_WlbeR^{$43CUsvQS<>cVtXqGrY z3-&*K`ZQPAZ+2qBFq|kOBcqj*u$-+=lKMJlWx23`Q6WBtZcm%|bR^uPJ;zx?iG!St zEcXRLo0M;o`R7n|N3||JwGew)Q+l>yE(9Bgd2ekGWd?~@obkg*H4(RzH`t}GeGhGq z<Ol;Yz5w|AJ0_CNL`;)|UDN1~& zsLfFh%?gomr!5a!jE(3`YkV?k@5#u_C8kXMfp-J0X;B14tUAYhoV}OGWb_X`*S`=g zszqX^YAD$v^a~|-){=tSX{fJq>k0*3c(m>+g)?CG1oT&9W1|*cpM>NSPFRtjRfDT1 zC!E7ixkgGot?8lCDScBd?~OqmB0GCg*I~?>*a0P{0Wlnsl)rXaUGU_&rm{Y%9y*L1 zQY~)f=NB(Ds|g&rcB1Do0aS+RS+%ihM_hk{zXvaf@^j**xklY(MWz8D3}z-~rK4=6 zn{;%H0;b4j4G5wA z{P}acTCLM$sjj*@(j4jXdLJ}TAL8Rjd$?ng#UXtBUUnOHmX<>~+6i~gX1x2F%WSKz zUu=+iLX;13Li3w90)kYRApE{idCWP9NqPsC0NK#GcTV$x>M1l)W-=j^uivOqSA`ov z#5SX|74izE8eB-g5pz`U2&$XJNcNf^G)gU=-oRRpM=%nu&=B0q90u<#W4q{SJ_9a4 zQPN*6eDH}OE!zzanDSS-rjM7itSp80>o*eb;7hf-4nAM~jG<0Ywp z_Vd{t9eE!Jc(n|X4rrsr?@ja+|7(V~>eJyF>7A+?Bh+%^ za>`Z&Q=fPmQQTl*tQr)JR8P(CHLoos4Ojr7N3DT-vo#_PRp>O4X%#N<4uCchSI0Vs zokq0zqkNr$h}i^CC5|*XKgzV6V&iC>0H>r$;kwq$`W6U1)~K6`Ahn;tyGKct+*0#P zAdJ&a542DUdP@6Q57gp^&c1ZgDW0#_i&7qm-5&f&j*vlmm(a4X&fd=9@cpj=Dn z`llu)YO1UG%o_ovxCH!kjRvjheSEyvgX&5M0$7K_^`ND*z;oStg<`95eX?G00ccQ* z4-#!wF{X7SP`@&Rr`?)$?>}2QXhb>caW&vm#rrM+abSDAz&gZj zNk!$0m8E666m;Edxv+oaPD&Z19Yw0N8!dnToLPGb=q`V@dM1JtqNDH@)gCO*lFb?d z8>AK33wf>mID!Mx0ym;ia?O8&X+cYQTiO-7KcK~|UisPH8eYu}1?Re{swCg?cOZ_V^l$BA>%*J+;e0Cr0 zwnltu|Czn}@L>nxPYA#ncVxWIKp6oIK9h`%C=bti_|6DWkJzQ$4#pM5X^;_39Q{L> zrL2FZ>uj~*O28s$g%#yOrMNTbMrCeO6W-6S!hUjXV+}ql4UiA0?A?0E&IxW8U7isM z8ud$1g1s)H(%X@aiOKV{Z)P>|HqckvkU?{d5%fvB1YLV z|1plRGsS*cy7JerhdKi&6*Z!a(U~d@Rl=H{IZk+3GRGVcuH^n&s*I z)akq__X#LDfPMf(XHQcX;6RfT6Ll&oqdrFx{8x%IZV8^yYxlX3PBU({MvN3{a<)hF z?fZ~SRXHT@`}Kdg1c->CwSBJP0q(c)W1@F4+<+?lGap&HW&t{fbHk!DzOr9HWMvJ{ zmZ&o3QUk>^-gzC07dh_u9P{*Ovv;{Zi78pc=HM4cP`IH1pHYdHv9kXGO>;(Q@L9bx zVV(gYv$g@IFBawh@yl-i_3Xoc@kc;(ZJ?l0hhl!k$LqnbF=RJM0B+RgiP=L1039M( z_vACurMqGUinQ|Cqynl5NLaNP0Pc+{|M)!|0X@BBg{O*|n#{Y!RX|1V*WLj`0`<@T z=U9O6e-8_Q@qquHr1<~Cw8(JZ#>Kng47_ILcIQ(VpFZu9)37aiO1y5i4Tu6Dl}E4e z_U+?`LRf3FF%X5NAD?B2J32bmd2U!ZI2ae3_)1Gl`$8QZdz!;O%+4kd2`f9sRnE&6 zA;&lSG@C;sZ}AztwQ*)+XGblsjIf9o_iu!gk^NTqpSdj{IFyP7lL=$Xcd=wZBVE8tP~jejgAl2VoVTJ-vw9h)Hu%?A=4YsQIU}l4Gf2v*nJme zaANGris1X3EM{sW%5&jf|G^zX!oCHU|PkWo^BN`A{ZI)DI$VJ zq+_YH%G-<)=PK#(4iA~V2pBhCRTGoc49tkahYvSy+(SDH$0W`hNQ2 z<;%!pi|X9md$PYDsx?Y01d-FQO4}5o1L<$Cu8#94NJeKo8f>-xfj+GB!=<>?E@?D? z40`m?>Uu+vJfUJktYaY&cW~f$xLH*A%sl(`H(;Yq#mC&-kd;1?Ua`U9d}{=~bWx#F z^s(#PI{aX$3JirwI!%l+xn2)*8A!`B@-s;DJT3Gg+% z^t7v6tapF{M*D}bnWRY9zG9(h_{e8h!+rmrmN8t5-?VldcccnAyna34iC0hFQ|~j_ znQLr$&f9#g=EhUdd0ej1*+^LLmQrBHGhHBiueEsOyE>vU`FgrPok`}bE;~D0s*r~= zSfpfpcR1mvYZS=8H;78#R0OyD5l# zdwNgZ78#W$$%0B7T^mq;swRIqB2$P>NuSZ`F8K6ipn*xmQwzQ zn_Y3;b>2XLBV99$WcFf}d=gh$D#Y)|oI%UZ#uiAxR|Jt$OZm}141Odk>NHhpDjAYL zJUZ$Ojj z-sQ>x7(PyStyy7~>$_o@O`iFLD!2?(auQ17xdJsialjpRhjogYL=3yez>_l@o0_`0 zv{Yj^_mM{W;@Y@t)lDv?*IOl4uP#qh8a#q&T01z@$m{6DLK`LlIBr+3?zDZo`~?Cd z5%eYF61cT(FhqH*&LjCNG%D`c7Lz=ww0k2<&F&t%1A|~e-x~Zbg)0XVJew6f;~8!H zPx6hcwzW<{AYvLDv<~!PG5$yRw)PdJqit#85o(8@k6)WziciD?w;s1fislIZRaq?L z+l8L2*vNx@{0{KU_Dq@oL@5^ouP&Z&#J@&=p9R15%S_ro*D#v)o|II;{xU|q&^#ef z5eya@1=h=D*d()yIewA@QF8Cmu7!t($A^oTvs-WV8rul*1)gsGy?)x0EL{aoE5Gd9 z3vKP;rcB}?E37Z^F%&Z^y~bXU7t$L1IVOUh`)4D_IJe~LefItg50^oPZHBsXdXsZA zrX)R9ALgF?{v8Im^yz%5m{_+c?ALE4dp}<)r%HO^HOPhC_t%7N7#@kJtQ-dE6&VQ{ zR2u|lXb+5z5^EjA>yj%f9bJ2Wu~}Iyj3CC)W!|rI)#v_%C`8?v$#xyyL6Ow(ejqyg z)f-vlNtq(-jEo6ky4D!$9c8yV&4sp0SE#$bH5VJy)cPN>xoPR->wNe?Bk1pcdU}db z&&)%*JaQOK1>XwB90s%6b2?h&J}thDLq7>v{ZU`)JmZIbmn~k<(C>4X9 zlJGkbx_4GY-+o=6j*ex&B(2P5b9~P&8H|$o;13j^{hs+Xpn;PCoHXaFGXuENh)DFC zoxhJ@O+V=&#HH>}{zu!FrTyqxSa^%L^^2!_lFEb&Z6~mC>ku=zmUO`JUl0%aNW6^y zp-O{o(PTw}pm{5QH@HGwBA)7~26%8w6zkN6xZOk3^3j2T+rl;`aHY5eJ~R4Tx02@? z*|7u~&dGAuSVlp!1EU(tiKXrY_)AdE5-waKr@rIp=*Sm5FgC_6YcUi;xiZYO#K)Ds zxVWgCAmHb3e(ma2MKvWJjlZhzWZ%6ZRqxTMs;Y+20$FlvvVwGkfelHil~}eSbj!X? z0#+P^ZP!$nFgGeK3piQFQ=8+$yy*2*(V<~mb5vjh^pqX8J-&CaMh9tVXlU-x%yK~g zin)cuQQ;3aGVt4%0ne-$lT!erKG@$s^<2PPwMQvM08tc$Uw2?kxWLXVn^kO!oTXwB z`_9;(AzKBUYpTk*)8WokC5xziIS6F&my%Devr29zmO^aTxrM0!l zyvpm(aS2xS1DA6A9ihdk0~(f_H-$E*I0X6#dPt*_BXckdvm=ZB8wNDdGTZ(R=@fC7 zz09B|5}vWh(AjEN&enn5Y2<%7y2iWRVIl#~XI`nJwl7Dau1>?a61aYZ8`ZDl)fap7 z`|cX&hsEPPE2tlgGuM~n#oNX1-W1r*1fsnt1%eUHEOuWJa682=bqA4CX{duTz!^q^ z+n9O^Vl}yrjBHn;Q}9EhAC5VH`0Q`fCD~{Z!6XT*$=Qawk+It;i5@$%R;N*@!yQ=> zC|(7}8^y#dV)yAxW%&L3I(EOI(R^)ZV3Jry;|k{(q6O^EUPImK1dY=S$^|)HtX-9k zKhesSnO$D&TsXYYJFJU!YGIhBGD&sH+@yCXo&=xRtCA_qRL*hp~z!g~DR zbQujH?x(mo&j;`AuaM{&nDQI7z_f$O30B%4H+#I16XTq_(wAmy<&Z*jRf>H$SpQPl z*R?qm2eIMoY>V8fjOW$w>nmOk^P8olcx~&Z$k9^czD>g}^K}x`8CLYYp6->Ehcq*d(5GqQC#&C@-Hgw_v&L=R*kPnVx5mxd*R}iBn8y_j zX`kJ@t#^;F_FAA?+GYOSsIZ8Yjkdy{2k^oKTm?~RNcpr@zRYOAlu zPWGmVlXg(C&8ts6-hE%OK00iqzj-HBou|M4EFcOy@QpKUXaYaqN{NGf{DM&n7tA;A zH*;2a`Eo0eWMyWbtDdnw+t40X*#`KnmoJkO>0@uP-dWFh^6ijB=IZL|WCVNX2zCi% zgh@4?mkiRTG!*}~?I1tO$*AbW7q>N4rCSgiQ(_0EeTs}-n%gk({KlGKzyYn0r(G8{ z4H^ieP~`FIVBNPChT-IErr-TO#-hD;CX-UnY$Q8sahuxFwUD9m{AoRQ4*t&OE?Fhe zPWrx14_TH+lXoz!ZXjF=Ox9+WPFTi}wohUOnkDQ)IpQ}gh@BSD z&e!rH)o4@GbG%eO94`9i_ity@I$zTREEek_>%UASoKC>5 zl99#Ui@rnv-P9%WC$JBUYa=tYp8KOkDIom{7*{%0ZDYzoi(^nSj~y+w?k+ZJXlt$6 zIfoH(LwsT1LC+9CYW~!NGQsb++qQMmwJ&L6`Hd>IXb!d}s}jh?Gl28po~+duNp;hE zM`2km1$o1o+2YHA9NeqPzBpWJjQ~rOe_t&SyZ9N2>`xlbrDl`*+E+wL zMi#(^C0>IjClTEnxW%AHI~enNyC$r)a%vj+btXw2HaU$-$B7%VQK@2{;nTw%9mkj2 zI}*32E^HfCI*j#MV5r8%#u(+$2xE0{V|&gatE5*?y31oYtCtQ{l2ABNy-?wAkd>9? zzL*Ho0wo2-ZDFs}AbF^2uXh$X=ujPQwN zJPY?Qq8+HyW~6~+ew|I^hi(5h zC|!XhA^}|`nV6Jvw6jy{-#!s#2hqY3S%(xnp1x+j)LkGonQNkWG8Qg{7oVJ%?(fsd85qVnPiKEFDk@SH zohn`G>dc7Xk}t_3LesDbE1^6cCSX{mNpvp1FTWO}#Pdgx1D>1$1CfZ`ovTxn=#J-4p+x%N3U+qqFir+2H8brT6{ah*z;~2Scn2bAY{95c8h~w2 zoo8wp*x3aI^^lsJ`=`t-D1XU*FqF7>$dKV3^KNQlM2EdL&Eaqh^PtMO+;Jo)GV6}* z%(Pmd9r8@W*FIxIqD$6!x>}&Bs0i`)*qOepT*Y<+*vqE>L=iuntvKxAS8P&a0$tC% zcH;ICcJ4Bm%YJ(wR8Tg(MjZDaPA7z;FJ6LIf{_A%^s>DGiBOzIg8m=pqgIm^o1qLxAg1)4 z-fJf(SJ@@?je;iJb7RyLKg^RAvE5|f&jUt-yG#HOf2bIE{b1fHN1t61ljj;E>M&X$ zJFM^=eW@63T~gz|0&%bnIQp}@qtM}v1H*Exx+x-U7z}2HP*^`+X6phrjI7=1>gfp} zghs*~r_722PCRO%h1$8(*`c2mo4mFpUvDAwp~Jp~>N5FK6#;=!H|a3a61qEtuwOQ1 z?%NbsuhzUHrq+*VwTmftq3kab?lB)cjXO#GB;vWV&mQ;DCSU+YNdCZb>IAF|)J zoEcaAz!b2{4t-U#nEmwIk%El4#5EG}RM5M^(A=op5jS;z%zngC28{wHa~LfwGDm%= zUp}jG=hng^S;RZCUV!2qk2IJ70Vfiz*Wee4F%{R((5vI@a)v>PFp>NcH=(7SPw-UFN%g3%mOTfX)Ei$Qbn@b!#|- zIJd#TK*vB&&vdO)Tw5dy&Fx3;&VoO$8$J-iF6DjWym#*&ng$R{beSBRTddhHp-?D@ z8(oAR9gnV$kB^E{Iu_z&Xad>D+8E=D}-cYm7u z(O%8>6LuaEk#b1c@~vC9u*tw_J7ey*wPYW?_ywXM8M`HMQ?8}0<#26E9WV9_Y&ud) zlLWBfRokmdu}T}8mv94Tl@&UqQlC`+^5=+ariuO-+><-Soe?WX>LF}PsWe_ z_;HsPF*NFeDgP5f>Am__r`7{vYAOxX4Zz@uLMA@5>J@+RE=mUc0jR4=ll@pw&iU}=>+D28r;&)fZ2RZ+P$8nd)erTN7 zO?HX+`uSXE5qkmsnX=4pRBVLX|8xV>t$#|-@$bJat#DFT90H*ab8m)&i7jdWFh7^! z*)YIgd|?&l>3z<(F-p_|TvfWXzw)3em~XW1*5fy>1a@d|&wc$;?o)d-JL$>%X)5&X za%W7tlatfZOF=;-qkTe{?7y-)=|+JvfKQ`An%3P%jR40_mT<2`dwI?*uC0Ar>Z^gw zs=If^^Yfw_K+_65ac8o^{}#2Vd)vWxF6DC$hdPwZgILLS9>ABt8dye$UACZEA0 zL6(Y3WM5%R7!GkEb(-j%P%2&2n~D0D-AQFO=gb$~%{$Xo>PRq0V=I&B=j%(&yy|A= zwCj4!-KO8D-p4}c?b~o%e$3B=gcY)cK+qn^7A#-inyt_#pzlZoJdF8IrtRuqv0MB8 z5(|Z|4+Ru%DtPvZYHDgWlaA675^N=*KltO||cS zTNoP!GXv9kJhC^EG9uh%aTEGOi}=$VwX`(i$;uAszw@i^b8(%VoT#QrPPEpTYiMY! zQ%}&}yb0)_x)UZE(A%6q_bah9omDFx-QDif17HSr0HFME z>wpXZy6ngCV&T5(&3QU0DS<^# z4lS;{h5-wx?t-+GWiVLS}miM zwe_nzu%~H#V4EtF)#`09ny>fsoqaLhdKrZ z{tU@A?(3TB=%DAC!`dQQp?mYK(}F;;x~(s!1~29KukF2U<#9m2`tMD@|Ggvn|5YIu$mr(-4DX|}ii%7DU74NT zl9&iQ?=o;UUzMjwv+>S+tMl}uQwXA@39w$fySwk-zn3Scsjf-uL42og8W?!DF}gLX zTkt|bK|MwCWFRxhS62~8Hgz5+lC52Bs>!b-0mtaRz0F;zmiR~v^eE!tV8`^a<>K=n zNHDv3z$6T)L2Yvg#1ITW6sW1OHb_b5sHWgoHQ#JA#>41&bUM&ID)tyk3JuKSUkyyH z5(CEzz*Pg(w`}pFipSI_Y9}9JZ=W+;kc%XJjsVix@%-Z9ZNH~=$t+@L1?kH%-@k)s zUuyL`q)rLMI9gbI>ke7s#T;x_z(^cx(IId+J_oR2^??Kn$+ zSS|zR$;MeASR-GjJ^I(9k9YsqECBn|VY{B7pt`g)=&23~cnNWPv;oCAfCV%o^{Llu z=g}N`Q1HpGuVU(bBfv%hpr#~+#hn+`zuPnPy!u6EoTA&8|0y&m;cFfJw7WZMy>RCkWg zr5`&x14wbnlVKi6KcMQpE)fzCPy;xe!d3k5Hjs_5Klnfj5mYI@f(M$AawIsPTl_{} zYnug8XVV}PQBhF=otH4czID?#^R>2P|;8g67j!2#C1 z(s_a}_#xm{hHZL7Xs=$qIz=1@RdyCAsGx})8X2a%dR4~n;B~TW93^vTDaDp*4wc51Ga=!b))tg&0RW5?Q(9buy?yILy7Wz^G%i)OX z=~6%lYi(@sUlf&YT$6BLcI0^B=7t?J_e>UtS&S5npuKC{+eu+NVdPh2din(9D1fK} z8MdvoA2Cu^R)!LA8)M5o>7KX(mvHvpwo$LHSP1v_m0NPh$0kXl4sBb;Rl&5mYIQ(7 z7Qs!q3EutPnV&}cXJBA=9?m<|Ma43TG-%Xmn0f$B5LyV2&hQ8!t`2f?!p=BaM?)wX zyV=+MaGT%eFHP0#r-R4fb5Bm7!&wO0Kb`ptKUOvG zam)AwZ2E$qn$Rept^*;QR_iu3wi09o0ToU74AvY6VFW%7or?4j@=*V-DI%>N1@a76+Ys|-D!2+GU#4FAgsp; z+w{fnZ-1t1KiZsS0Q;lsywZq$eU~Y34Gj%3?=9pZ0`;|NegoxE8b+K3>-y)Q#xj5k46(DXbeJl3Pe1}IMcm?-wD{99*NkG3b^cPE zo*omUovUV=&8iTM-vj%V1_zPC0b%a@rd`RxwraA0XVou0gVC%jIF>vY`_cLu^lKHB z={j%k66v>?BZT(?wkC(T7;JBecHkin zp|72z1`G~?j38_?Y;<~i1i&hmL-v<1?r+c3<*1}TtN_u?$i^mPv-yN0xS=7a!ZQv` zQ(WT!QY#>Il%RnpODll-Zj>NS2oDYpLh*-maw3lC@jpXD-QC(0nnja!8%z2D#lioO zuT*(+clV`AfE}dl94}gx;?T1E=ptivdk`R3uU%7WSO5_eO3lhw(Vs5i4#eX)L?BSf zz-@K1sE&SB_OKrKLckR_myXD&sHkbM%cJ8g3P|>fR`p-56?Ha23CP}3!XED}0H|hf4*@@K0;UJbvU@s~fYAe> zV0^nqJ70^7;{}+289l2vqL@2AEcJ7A+ysF!JiP~8fqN8i41mwmrLeGZHUm`b zQpfT2MYA8#QBmRp1zKduuk!0xsf%rQ?mE?a ztXUcu*xirb=ll1Cv$27JRN&e1|F&P~bp4l4U#CEp>N<-8-mJyhTH(}5S@Fr__m5|K zh|?#RiT$(CHU-ThDl(W&rLFPznSU_{8D~>Fm){f1Bk^zH}-7<(HrA#^T0&x5)nP`OwHb8EhUF7Al?FlS>)>Ib?*JpbWWZcY5@ZR*r%L zO*xJXoAqM`duJ9W%50PQ4oAi?0L5Q=rq1ABo$5JyH*(rTJw7$;hs=%UmR@HW47R z6G=9G>RnEhy0(e5?PyU_vrD%8b8zX(zwbIigTc?Dq(iWKa_-|RQZ{80 zf`T-Y#D=@zR48y44_Vx_jg9@+y^7;FA_imY{sjlbTpA$8tSIl@w$;FEobJbyat`|}QM3a(|dS2;xl!M=3!5Iez z5&`KlRpZ{@m*)RHx%NR3`uxNyou;(R&1uN)eX|?*8#=j-K_Nrr0|KBeD#avh9X?hKQ{ook%fk1#@$&$DQ zsQ#v6@|0`$VR79|f4 zk7J;|j=uiROj%usyqOR2<=7M*?84tT{r|zt$o$Q?Qj!u7 z5UxSKRkzxT6_Swdv72i=SnrGBOJx!e5TKxl4*eV!7Urk@kh&x!V{E+IZ=@w~d4~%9 zS>3r_I4TpdUz4e$!L5eDEf zgBL|3PW+9A4HLka@>tv==)l9x9nvzL_jq#&cm_pU+$K%+7_UDDHgjMK{CVZj1TjF3 zPPu%=BjzXD+$Q4!ICIIEO=o8(E-oV5?Uc=PexIU}6;#m4f>fB_%>)Eu| zZYw>0>(F|ABm8i@3`)jUMF@o)ghRt53uLL6AAku`!c0>%rtsBPrIwMBeA6IWp0W0u z_<;m9APEmHYrXl^ST2>VQ~j@i%wOA3Q`e@YtvusT*vRAQVwL=RrH4BA<>8?rb0b~< zUHr4B=yu~Jm=f34Shy?0j{3Xu;bK_N|K9a?;|pOrx~&@XGLS>>$~8-Aeeu+%DWs+U z{dj)KG{p%*N_MtsteiPO5M^bL!9cG^>e2z~1?cFgxG3;(ad9BM!tJ7CaXEeZ@9bMd zgrl3=bpDj}jx`sBx9RJSBnr8RSU>5oonoVbT6nt zCweqX8?l?OK0Z2XS*UMc?^6@Hz1$kSa2{b2bXqS@NN@-6qX;=j7B>0t)@+>C{debf zl302u7(%;`Q>l&1L zI9?7>J-wGXU4Hpfd$I?V>_BaLwL`SSZoKdD{rqH$#?vE+8T}yh_RKv zO1gDzI00=1f|%&V`JNyhz0lJ;QER^fNT0$v5(VOC9sB=$8q4V&_>=$n-FiDqhV*~_ zQ13@$k;wnN9R=6_J7{~|0n!^YQt{} zOV6!DP(7>lCFJ3&zeu0*w09U0B4xG?iDA>CW^!Ze!ex%*p3~lHiBjY6Hr31IsDcq& z$Ow!m`$mXhoO$~OKWxk@zo=-!ilc^;)2pSm$rc_G0sUx653XNBp+VNFpxnFYBbJ!p z%gh2ghHA5#VW9-I*Kwq2X>3W0LJ2^}kC>xb)GsH`z`)Q{M+hG63Du8XJ;CuvjYY6X z6zkeZB_Gw)#jVf`+>w(MHjl{2QKSUe{Gw!~t1F#UAI@=mij5B36nG^cC$cIzI~u0&~ks<}eggka<_2 zHQh2q0PmxdMjmZ!Y^?1K9MUr|w78z;-rN3KMM~ZGk^Q!bEtVf>#Y*O(uR3KNQ&F6K z4VD{4T9t)`uj%{8b+)9DGM7WL-n@=0EUZ+0g@YU{21UtG`v|q==5`NrR=A5Od-l;Q z6DNmaiIGT#UBjaX)#7$f++N+>TydPS#Kp&(8MQ@Z+hU33#|>IIn@b`@_Qc5igvg_1 ztdgf^-33|<;JkESm&4N^xbcGfwPckPH93jfjd7kmU{+aP?l;XvpNQS)~3<`~@vbx$%t45kA=qZ$k`lp)C=0Mf-1N=jV0*b6rbL_Dh8&CFZs7 zanM{iZxPO7iwM}&DT7qDvS?uYH5Ly$kGTFEhvpvDdv1%#e`px8W?my?uvS##z zmV{bGuEs+K)AG{0L{&Q6aV+;FMY!IbyoKwmlyy zqrVuS)&lZbjR8m%eeo84^qVqEbN?;2dR)vwsK9+}%lVUW+NLH|mjqnJ#H>`@dyA&z7FaLR9-*hhgz|mgze!&i1t907yNxS2 zO8I|I)bG?;Vf)Mbsb%Myug^4NH4l((naKEFwo4@eDWT%!Ulg zaCm9#BxGRGod^Q!emEg#LRxju1&X;Ljs^Kpkfe&;0VcnctH1#pT@a-2Ip*n)}Xh z98cye+V82V^E+Jv&bX>a?t&R@gZy9lSg;U@I~n*fh*rM4=Jh-ou`l7VLFO_l`RI=9 zTDmMyEtm+G66^j@l@|A}oVfN14$>cMM|ke2hA1R3yDRN!%9ch-F8~buX40PXp2tn0 zUHL4Bl?f6p2sbt{d{WWMgv(-l6jB=UM5RW_04fLA;exK*GP;?vWa%9_n0ECKs;5ij zs}GDyb+41Mk#I$uuGQq*YMWaLgX(WQl<|PE%E+Z~^@0f>#@CUp$J2YvHINKF{F<>G z*oi$)m5#A-U>8y}`+>r^StF*h0Rto`{}q0ENI--{;-8)5EDy_O+sDS9e!Ee@K8`}e zu*#hOWa_|279!5%X}sDliVTNHqk>=fv%WeGk(L%S@w(R~R6<`b`}ONLhvRY=SdPaP zp?z?arj$dpYJP^s?plbv&y*?(OF}^Ai=8MK0U^~OHGZ_iF}{xbQy5*I?m(MMKMocW zo=oJA@kg!@&F7$b`M+YwQx6}Kf2~rSL+s5;(O>DX&_bRpkl12Y9hRGKBTHq85NIO# zmYAM*8cltDvEWa{YO?+Xn+pAzI9Td3U=j;>^p0Dm#SLt1n45z#rGc(&NPJWjkHw%b z93t(GOCzv{J1oW6#c{KLce@ysG822YAO{7waN;!~c%u=bLok;kGD~%F;~K%Cp-T@e zoawD5cK!;&Ui(N6Mh;N^%#6cweTnn#5)qbA>+)c{`trOh{x7OqMNccrkWPB0H+>2N zCT_z%W{o1`P{6OdEK_ME4$lm2$}}!#wyM;mc-L!HKIkkAiHPS_N3NNf3s05k#MxBw z9@o)>!;(ez*yJHxiLE#H{5zK2>c;PX#|Nt!xOk=5#@P_j_Q~*Yc#Qw@lxQY+v6l3W ze2JpUTDoI&D2AhZnU_U8-R7WuLk3}y&K4L|P1e5Za`_cNe+xBK#-IL032U-#sS18P zKs_tw4qwHN-}3u&XKT+;cKaJw8Cmid00VNy5ALp=hn|C3*!kej#KHBu79>%u4ho9F z+S4x75&^Kb+3m~2|In}qGD}MxkZ$D`g_eU55?xv>dV=oXV7h8 zb1yVuH2P;4X?whawyPU4{NRPsdm`B1P8ITdaD`As%UKL2^{;-Id<_HudoGQ97XBU* z1kQRgm2<47K0@i}^$h()X)_G5rTfF(NT00km_h~+vI~|Fb!TdM)pC^uT>tJz!%5E_ z$I`}lF6}Cgv{ui~NeXRb$_8Ic#y!_y`~gD|(t)cwp!rE#$s!NeNYLE#g5eKx-{M|; zcv+1Pah!Xa_AR%^H6owI&z)#iVW6b2@Md$5d2g5S;jW@CRop2VbsGT|<~BSQ z?*%(dOGuM6su8a2cfjYI-#U=+VjVt6kN*Vunig-jqq(Z41p4k z7uj4-rDYV95_!)3EN<8Q@AQoFj+Sp`=YCpa@`R>B?`CR!brs7D`c%pBzP;ogA6c=S z`dYJ3hU}Z_cX`orn&y!>vZa{Hx-*lm>FPj(y^A;b&AeKf2U0Pvn7l+M$x(kNY|}MG zi_+Ho$>xN5#CL?Y{AaF!{ExesSB=v&Q}4ql#6J)F-yvJv25+TL?cHiR-}f$hvL&HG z)5V5UVJ}GCoSc$boi(krXX{pc-jhstdwRA#bn8tEKRfdh6vYxV7WelzGn*uGXuTf` zIVzg6scqlYC^GbPO%fsZxC^Cgy}A>=xFgTM+!=ytsWC%VaE3uuG}6SiN%vzy?(`HB z9nV;$q+^9VJg%dtlj5C(KKwd6yVrXa&ZLUc1iOuRN zX{wESgF;O&5BPfV>%V(4GSdl@_X@wFW}z%JT6-&q#7ofdJ^2m|`nM|su^`ivf8@aV zAw?fJB=B_;rbi?y+=3(N$E$$P*{{CWB3aw?Y5lk)wew{J!NSkr*xC6=Q%kGvLH*0> z!9nT|0VD`Oi^*xryyEa`OgVTj79y7XPfOer!|(2zU2PxBJ?ntbp9)bIsMvOEOH$?% zOe&~ZSU#-hj}1n~*VjKxHlFpN9r4ON#`{BZC%K#dhtu-(U@e zjeceQ59#B-VHIAW7OxNbSsi=YfjL;;Y>8SjCM9beA}mNB+1sNZzhu1b+ll-M3Yh3g zAvu`WB&?Cjo}S(3NE#F%eF62$^*dOs>@LEUOzoj_b%C(W{6kjf?hckVS6M-c$LY^2 z_LDTno8JuqB{Ax^Zjo=Og1mQbg*?nwQQd6zBS*g_y|%ZGcLi@+=@?kcVLDe;ZOWKna7%q z9ddeXZAo=i3fC=pyMV#LNf_=ULwV&F z_u+C&*h|l&%}xC2GBUOOvmG`6yNb_(g_V^iQ-v$nupNIo#36DnuHlJ+qUxVPjOG51 ztzUX&phON&wr6MgR9^lfM^sszT|r4%YU)8WZeKWfRH@^s(MgBbPT$K_vii0mlJzgv z^yQaECSdc!Z6kY1SX=%+V=5iaycdJoO)7r=P(}#&*IPbXjzt$5lerv~5R)FC+#&R9 zPnbNO`Hx=Ypb`Or0|()ri)+$O?a~xVj;(@zY|*c{&Q*|6-P3YdUmUEVr-~W)Mb(*j z5PO;+p`;`mh=XVUb)Imlqa|cPotual4dfe1s!TgI3gO>H+uu!rbP5Bmr%Qk+x(=*OL`|JG=leEzh<_jBSJsv(vus$ zk#c39!}!|P*Vju(NwF?~Y*cWtJ57q5jEvc5)kK9{P`qVj#>K&zgAEKpH7VfZNYN*2Z&6BLMA`+@+{5GH$cW| zt}%%*-q~^l5&`|d#id%EwrFM#P;qWMs&dXloU-2?9q+}(#LZQc`s@lz3+3dS>`r&) z!2}YMAPR!OimmFYHFkFkfqHQ$nUe_mZQ|%50e^ZAvf@?ds%p%fLjQVKI~7Efu_Uyu z5?w{o)6#NPr}{UB?{9(`;`+gh>5(8mVRr+@H!%_81upH^)}NI54^%-Pjg@e$PyVbD z8%`i^9i2@mC#E&ISLv7&yrQeU8B;^eXztwWy+OPJfgBmK;_RhF`X3e`dAK2o-*Q>O z$e-+D>1Ri1rxd!*{hn^PE-Hje8xhxMJ{=;=;wb>d#>ML)`uGU>?|zf5IA*2x%=7A$ zMrZ70UTm}uIe&%iK&HI83uR1MVf0xYn<|B=C08-fwC=g;r=ok!RgZZ8g=%A=i;gBq{!z(w9{n?h0P z>6Rp5_`hp7B_-jqt3S7U;>|5AEz9oC6HZQ?+<;5&%BSG4#P`65>)k44gFXhNp`pR= zZik720?PBRUfm>iY6fBQkFx8o2fI^-ZK~tvw(b_T_4G@L=-E3;80f)8zb*&@K7G0arAD>|t~mkg zIYdwx!DJBm>rad)%kyMOGA9Ku<_=y?BYgKO&j?``7=OU39#-l2g#&OdMs371mXTI>l<9v4;`5w-HLF;QX?Wr5Fm-&)z34Aq7W3! zh(T@pnul7>{?hU`2nNb8`a<-gV=i3t#!XWLrrnOK%wUFPe12fScJT@sU5oCE^d=W| ze{pf~q6O#IMspvb$C{ZHVpbEgwMBhnW8<>6`OwIL6~ahDwfvU4 zG9|WA+jrk%pF+*-^NUkLLARgU`|yzQYNnHAQlaL3&k<3*{$arH2fLfoskYLRGHwEN zcQ064VUDqd8C1xMP?gzGsUgaSRqxj?aj9=FyEmM2*!tFYFiUkBN{^>_i7_PKYQ#+y z>S`Ed5At3X6R8b$O(ng21q*da((ui#Qqr0~+Ee-j(ise_0`9*_x$gL2XY0v@#_3P<-=O^`K zNjP#HkVrLMvmN1bGmmA4{vml5m)d}$=cPN}74`xL7ZJAor)-RJ8c*rOPIoxj(ZSN_ zN`>E&t_9LLw~>F}#>r=NGQSmH)1M~z$?ulo9EOq1rWkK`Iukv4uiV8V&7nIx^7I|rCHm)kbn&&k+ zi`C6pNFw&~G2FA>4X4_PC2-_s@!X)B(s0RCk>3En&Oy0pms5>?`*z>0>mcOyv%poLVvM0xdX?`Hg`MFU`lWgd6j$?g7nCfsD;@x+Ikd zb0+c7nZoV%tutz$QW8~)H-p3ZfeOEHS-XluBC91K6h)1VN1T}aT~l8h7TT9nfK;N4 z%u;JrcXGFdGmN7)uGwF>+0FSjX=iE{rJRgPKuD;V8n5(=3X^5#|LsK<&6cjzPKSFk zyr%s=u)(rGG;`OdFPS}UKUXbC-fNWUf)Ft3M{$6(jr>XF6;YaQd_sJk3L8kZ1dc4* z?p=GwMwR~&?Iiq8xmVq|r}bWXB0fHTi~|e)%MS@KgV3PK{UZ_~yNLpkyXR4bK#+_9 z1nCP98qTYDz(7}0qpphR3+zNN5bW(lbRF1f#|O$V5YXd&!$!e+oba3>#b+=5(W9*0 zMzIG(JSj=ZFbT>E?Yq%$NqTj5X#$?FPc`M_Q22F|b!0eMSfT`3n3-qz-h*u?h=qKp zt9<|c`G~$pL^%8D&L>>=eq9X}BKK>Dw6r8$U2#v%gdWyA7cKB{TbyWYuP;}YTdmRz zjq1$$*ddYcW?=o%g^C_3x`s&o&t5qB!T8!~^EF{O0M;~Cv9S#e4IwNdqM3+*G;*ZP z574U$Lc(Qj)Vig&LBYX_iK9_6x;d&kWzTC|2P`ZbPRmz2VFIZ8f`0!F`YlnS>3!|A zyEBnjYG`dut1auusyG2JDnpGEEY`7ED4nn9Wi0X-$So-SOcyt`kfQ#$6XD}M9_jKi zGTed}X-<>$UAt((i{Z}-$W7M7$K3@LW9v?#DXahgSMq-C~yFW%P8X zK0QyLP4~R8%hH+oO@OO^ z6@J(OJGppEhZP43yblz`KfszHjqx?U0WQFN?r567Ac?VrPIAbrCC9yIFp%~1uo<7n zHQ!IM;J-?H`@EQN?Y-F9v2r=uZ=OLdhHdr-$=)QsJ%1>~WigN;+8FDei>7!?Vb7D_ z#dFToILJ@4E61l=+~zD$8*;rEf@_aBSST?v?CUqFOD*Z{Pv`Ue>$FP)Wmq@nZkF~0 zNJ<7PNGvZVrpJd$P+Am6^jVp`h}lKJ!NE;BN~QRN+T7gI`Rms#1ve14*V>m_CqGee zaYZ`p7K2W%uI6rX)ZYQ4pTO zk5xZBatWX>X8tRYaJLPfw_WFCqxA&ux#H4!)KlVYre{L$KQ;F#Z#2ygo4>91M3W(O z+PSm7PLxfzo4W}o3?k0Y*0bwR*E^_MHSJ;zD-MV31Uv-8fy^N~0iP&=_aT4%EwziVDjY&ya zSod?I=CFNy@C69x@#!TUFLjEi#a6@tm$BmjaPmt+2Z?<=lwf!684Zm%1r%p8vV}f* zC@OAF^|koHQs9STGE{9#Cw2m~eQ8`I_*OqZwt{axTey(1G5R%rL&@!gX=h)7F-BaU z%TX|ayj=3IA8lN}u3>tO-lG2_oZ?}g^$oz+6idClH_vuZw?^n_F^Jh*tklgoP8l$u zySqC>kK?EH8PGp^#{_=(CPg*T%+KrkaHKjZefBFLO_7zJR;J|RSJX)PGA>w=#BT{D zTrdG;iF=gf4yD%xb6TrB2wwsH91z1ykC zPIA*T{%SQ9JgZaUWI0#l&@!se8XZ&KP&c3bcFAPT^fQ|B#rY|PuGYcyyH3rjYf_l| z8iqMVC9t2@3#|lvd-)OL3hfhTR3%b==L5N_)4thTay;aH4dx)emzkv*T}}ha%2?;R zP=IuTs2N+!>5950E~?@vRc^=q={EY&xTn_Yg|=61DC>xxlr)XA+ncT2I|Rt(7lBQ; z>S*=Fsz!fTm|}#c1CHW^?SuCHW{N|VK^4OF_3b6MT<#oYL$R@Dk!r!+{z^KxmcpXC z%EDnYYq;Jz3>*&a;-d&KD_je0IOx7eAvk(ITK8cAl)Lrn83jY;>{|Wq=a&VWs*2Ns zIGCI-_LH7$2Fxmdu8WF?U;x4FyJbRNCw0)z9oIg0OIHYol+Qe?(PKv2*5U1X{<>sU zy&!W~0VW_lG3D)h_<-+x15r1Nm9|NQEyF!SG1R;poX?+kT_5hy&%uQ9+OR`k8a@$+ zH|RUS1jrtq#N;u%A6Z&|+o^1!!^lHz`%90hs6aZ-5+9no!)K7Hq$NF39b$zB6~*}VI{^;^uuL0+ZFPXACi$2cXHc_H#b zvRsNe%8Z@nnDBvd@gCR!9W5EobEYqk7?AooquR18l+mpK4`scn3wv#-uMUuv9yf}u z&COcQ-rAk-4j6R|DSIJgY5aa-;-#d?xl=YE&5`@6e?>ThD$hJU`=WAl-iqVlL9g?R zKViES%VeRA{MRrd;ZExa-4Y>}f9;uph|kbuJWdJ_2H%xbtaXzKc$6P2AP*mG$37|vUc&~6 ze<~ezGuXE8DW#Kpd$ydaC~#}4&do_xt0vJSRXKJCQs}pCB<~Ugz04l=x3w3V4NA1M zW?1ag1`aeHg&dZ88$3!wIi(LnTQJXWNH34DGBqhtD!219s~vb8?};H1N3QmR$(Z*N z-oX&`c7g>V27?S9lJL_i5#e^8w%dcD0AUrB0m|^ZYq+~}n=)VRMsgOVFj%C1ZFTPI z?y4BO19L>K_lw#(bLDbnqQ2NiM^jHg3YB3?)UU!M~5hxu-Ez#A^ON5 zrwsb!gSX_!-*c_!O^)##WjZZglI?NLn8@H z0@M&KI4C*=8FEqa0n61}NmwHQCC8#e)zZ)bk?6YRr%ZVZGr*fg67znY<03$V{RpNG z*QaEU{{k=dR+Np@)b{rF5T6#Y(vc5S&(H1VMl;drQ$YFK|K>QP>158mykUAL5seX~ z)2U@s6s~=LtD)ipcoPEb?BnhLGvSN+XkR+tq=5tas_9uv9zKJkB<*ke#aeoT6I@!&0(# zSt)J>>YS#g`rPlux2y+8AnjH)SNzr%3LrZtU@GcyFwX)9KCEUXI_94eR-;axZKCa z#W6iT@Y8<5L_#9w_Vd{raXui7!9oM~*ktW5;fr^_I!Zg4jC561O>mv*=<3?MNufat zc6Q-JYFX|&4D?zTeY@7-sHjoe7z7<=YW4q}#yvU|>mF#X>krQ%5oQ1A2x75YNt`$YNMxxkDuUSLbR|{b zEPOd@tp^r*>lFsxmPXH!5`=|*7ce1j_e7?*4_hsk`}tZ}ba#cJCoSbErP|{*0@(5; zwk2)`nXp^zknrhtc4R}-%JVB=nXn#+DdhF9BQ({}KmPDSB%-}tgo_y+0*D&WJ){n~ zIy!ce<1#yxU8Hu5k$|J;utFu6o3AQU77YArsd4)D=bUE~baZO1!)7HO%r|nT{m-y% zVwMHgKhw6Gu{t|MK4v&DQw_hrdM?heUaBO94XNP2-uOAkZ1}rjDFYjV$Aa1^kfDrZ z{ZGw%8u2She5bv4bKF%9Z}DmlMpB`SiQNZ2kFy8aHJJ7}$=0(j$(gd{{K9-3B!mYT zKSQB3h{a+te^09_3?+FOZ(4M2#{P2<0$e~$jMYwUEh$>|l)&h$(DyxFk=Xz~%5j2J!IoD<|=V&n3mX@iHE; zL3WGfLR?%*mKk}xQ^A4;6L}ecK&QMMY826(-vC4(6eX8)bbo)eHIiPJ zIMhLr86EAOmRrkj{I^7}E-@%AlOnSqVV+&FcP!_pJ}@a8%n%KP0ULP!$&M6m@w@ku zlx!HYa&dGF|MtzydFH1<>kpuSb>>N#;@Hw8qO~A5%jQNrgGaacO1MiunfwZh`qx(> zLE0Dqj_uSQsHUlvLS6VrY=DRUf2p0T54}p}A+<1~?%l<#ZvOFOk=M#MwyPrk@ z%n(mgZwOl3>7u4lo~2U~vLt1u%7>9ROyN0s77+x3Xi(zmrTIhMk%*?0*3h+huaeCG zuU>1Fz?lHVqv42*;)22+)jku|eA7hwf_ptv%dx(@sWE)d96v1J8S0m!23iX9Sk<4Q ze~7iGrV$Ga4VQ;n;`WjU>;_XWU*U!%Ddaw7*!aOVi?Cf)_LC$Y(I* z+;n;M^}P!Vh)}HD#`c(LwJswrpk;wP(#+`^pw>oy>@$d-9@8 z_vPt@l)^SQHz)jfr?zG~ciS!WD4I{=bs9yqc@!X}vCj0jK8%NEgLk)|K~;=-J!+K2 zu_|+Asqi%I9g3FbCLgwxJ9b{-otJFR!I8E1e6^diq$kboxCP;Ks{!J4u|B{I9R$Co zW^FhBxLfhpF|FFP-Kx}n({|sy`D+f(Z5COEI;n8buR#7cGnnpPf~ISKad3$$JxKUm zM)@8G)0UcM6HZBeC;6HNFb5J|;Nw>^zn3aDI8$irHpKb8|BgocmvtDcdc>LIvvmccbGrH9I@j7e%bQu1IOlGfJsu ziO<|#O}xKFbJ_Y98BO@jT~Wj_{Q9+Ua==5Ga^$UB%Gsm^u8^sjw-IG>9 zI<84p`SeAL-1%L*P|S8&i>A{@a2^>vON{`o_V|I(1D4v4#Eidm50sHRd!WZgQY z3!MzyR~pzW+No!i=u5d&S!%Uwx2cVJ;$vJ#v;Lat4Ly^cbyR+m5Btjk0Kh}{xWAw3t7q%7tBhDv_@!IOuj(f7Z9OVVJ< z!UpJZJ1LPk9DE8!;zb#_c6FJin7f<${0}Lxk^&Kl^IXzvz4LcG^T!cHNcT-1ov^f` z*E8xmTnWA=WQL)|GrXnTEo()sp)2Ww4?C*;J8EU|Oa{{Jr}Z*Y%7>p4ZbS58E4-7To`Z&%HSm<#L$a{JXoq zx5e(dN!?=TPjjm4KGRDo_Un_SfIupB=+~3}^CE87r*MZ8TiSfsbL(lmW`5aXgNBrU z84rVKWr=xHpiG1!aJ!T`?v=f5L7G=QS%2AiGcJ_cU)uvLE>{*8mw-SE|Be37i5)if z<7?R}AkYJwLwOb9 zuNMa0IK2_hyc9?RvBV5=0F#+=qe~g>^1no8QwhtvvH-&ct&4@iFK?U^Vb0UeNy_^!$(U}97FcM zG0{E6pl9qQPsA$~$GL>B_vgj!bFUiRE;~TIxZ30Z6g1K#MXg5HypHqbe%!{hfa1~l z16^<;cbA{8j0}wCTs}U&l9X@hrU0&e^D0_q9YDl(Rp`YefRHVlUX=le`>uY_w20>3 zyswA3d5%N%c)xUt7T6&& zQLTT72H}Lp_N>jle*$CA2}L_P($dhgw@yz_Uo*Vk_jGM~cGkYGx#noinyV&)l!-yX zQ2pcAaA-594QKj@B@UfDwQ7NS?u5;dg>&8yVt@{FN6X+%GwT<)m>R~%#cgiQ)p(Qc zlL1$Wf^ky?fccY%YFhDnYNUGnN=_!^%6)+noMvc9Ejm55Lyt0ZErpbs3!2`@XvJ@J zRm`~aUrc4?xE{B|d>bwNh>r1N5iGPpQ+M@8l@?sR#nZ(|Og*=}I6gnW#4KM{GtdC0 zYydSv|LnD21=Iyh2@F_BG&rGERqQDaX`rg3rLH~8ShHITq&HRt?SI$AHUw-Svdsj=5kqrH=*p#67zY02_ zvGM=Ix|8&&%+bo_jCW3`(Z(!nIRP*|W70-L$GSj}U7f4o7S8J#@ zxv`NiTuMz(&9tuOonG->;luy10Mlx)|E-Wv;eRL1^Z#WN|4&Mhb8>)v7Wn zFPQJnCNNW7H#c3z5O*@tbc#r`jN1MIvu8Dq^Bp>}g{`juxfN{j0Coh7vfuF}=eDwt zC_bya`W6xDc^_UUbUQ=$EHJaFC=kmA4)ipK*7FFFc46R`SD;3h@`lBEdVhO+d-2B) zjUqq90H7|y6u8Q8h4FucEU1KqN4y>{fL2hAx#kEfS9987jAPqn9^|}YW1m*69Ex@K zRc?f&2}Hy=un??h-gz=L4GptlWh^;TaxVHaINA9%QAI7EsEEC!nq3NN9N7;tUzT8P z{T~B>G!RT`9v}9NFkTEX#Mx6xMeNTo-x;NI-L6S9xu-&4Svm39?93bTAbR^=s%~7>(!Zfy-TBiV)*6g{~?f-ad3V;x2S2qdFp+s3M345jC zlZ_QEt;@p5%@1N?;;_x%S{GT-&fKV*uKUtPBeYiMe^xV!3x0aS>P!=raJ z)7bbPz_1ka7nhhG8&l@01+lq1Kt)lZy$I3++S*{}`MUkZhR$4Y&cDATl~LhgpEApw zA)Suy?quBdKB}rGmX9~p#l;$t-*t_+KTA-0-W}87;^58+<|(CF>4VtRa)0qO6@d{c zni}UgSY5qthreC9u#0JDS!%+)GCg`tENVEg6smso0)xQ*Z;9)<(C3!t*rCbnlL#Ax2?g z2cXa_zN~_A=f^N6o^5-aELiYwK@ww%>FMqQLIgf)j4wF*r6m&R z;c|=i+h&u2o!uh9FaYX&;~^sKw#Z{-)OJ=~z3El#ozX+;?KAqPgED$MjRq)8zvsw< zo8#zsd~(#r$jJB{3BJl=TpF+Q|p zkUe&Ha_Y~{&JK~ketomkC69;F6{E~_1=gZ^o?WC_irhBCKct_QmV`s#c`!F>!+=&- zvBMJHxH`N0n;kZ%`|Y2647;fCyKi)VJZgE#ZjmPF+&FW$DxN>HHwM$9lsB<+=oO)3 zsJXehsR>>xDx*3fER!~It{-6ozI{6b?T}#T*R`g z;S~KM`W=`y;{x8dG?U&q~7 zkc;*&)+teW_4n_MauVARUk1P~e#lT478l<=G&z7IYZW^?mFazB4Y&|=3=H79z(j9N zIcaaSL?9n8um--Vj?VG9mQl?IC*V#9uv4h~dgPH6D4xyC&4IMjerzHvJ1cv`$uh36 zcEk4kRY}`h%IH_Tye}axd+ia4Q|JS*@kigAVKl7dU^UKApj9iHaw~M#>K_;YMSKR( z)~yw5z`O9j`m0F7U&;ynKC)GY^zw|NOzi2q`Ws zw6EM-0#<=NJv}oc>7FlfaI#eDlZWDe{Lnjiz{5v%-J4bn7Q>zqP8--DzTYeBra3C$ zOfYq9Slr$w09)B5=K>8F8#{Y)$~rmz({;z8v<`(OiZb_rX+1+jsYy;T(b4v5+|aw-X(th8{4ij_4wC`Q zoh&}cTUil^21sRF+k1IQN4!_sa{%`eFLH#NFdXDVtCoRJcLS&w9ImeeGau)hvw}^G zqjwtzK34@XblF*1A?QRAKnNNE3wPuFiizp#moHHRsd{QWV6?7~-eS*|e+g1>O>T#? zbq-~&6(9o#0v52gXEb_P0E==)hbM$dc_Z^H>PbfXhwF<+iCl(+fzI$OSyWQb8MzNPo*lXAO<1qqdU4{(d{PbM5!{ z)0C7{Kvys8UStA9gbe=oH2h5z7QPR`FXpbP0qk}?%?}( zx}C_;I&~Vq!!k%Em(Xbg4)&q(Z^Hb%_vH+Rf*fo>@q%D$_|mDx^2Aw)g}~Jx35<}= zW)8w|{|ASOQR7ZvS>SJQEPvb0U-M9qDwYWaoK&)<+|SL;giBGSk6>b87(b$?3pw*q zQ3H^enQcYI&r!*>Y*n;`EnfSe%?W zfXQY6EOtmHxY^o6nxZ^$_B3?sznhOXO_{hM+SuDeh0JquxP+^%l9?D8pCZ)pvGwXd z49(@?ki1;OtT(ZFd3ot=ZHjfUV)>T81kNr&$Al3nD{HdsyMlo;^f@-?cE9}o{qItf z8-PyELCR4{NvUc}KwxWCnlK?@V56+L@*6YO-T6$kV3WH+n;$v^I;h2P^3qALQksD1 zL^YVBMFKggFg-mowCmCcgy|^)AJ3l1pi5zECtZN zKtm3)NFdw|#MO=E4uq3Buf!-b0-Yzw3iH=G0IvsWW8=)Quz}N&HiGBR%?(b#nA07Z zE)uoghf4Lfw0?^@f(U zbwN|ptvqwv?#@P6EU)9;EXZrmier!oxqvVBwI2m~*EkLa$u_@LI~WjnX!R|+1WGfS44&M3G`t2 z0Dx+P06LO(`VZ*Xe0K|i!7RU&E;oj)%lL4*zlZR zaRLCLz|Vt)p9ZJzYzGsjeMc>Cd}6%u?`%YjOb%e2Ia$qtFc=a+y(Z1*jH^3c1wM-i z!3Yo*3CYASYiuz=Y3{Sprp89D7wWP!s{C5H<~X6ibPOLloRg%$LrM4eOOFu}<8=Ht zQkco|`{6;rd*Gzv2oS_Iup7&dWE*z97Z3_6YU{(UJlD)ZR^AKXie~nw{U;E1Sgq=U zMSVj9uc&B8C>&xMzkB==*^DqLq^hP?a_dqO7av=EZ>lIF^5?PT(jA(ub`%GJtw&fA zd_GdxXXGx)A%@F9i75dL`yu3CTD&jI?&?R9Pjt3pHJ$o$NfS5~|e=D^^V92=`J zaaOnDmzp#-y3^!vl;+?1mZtm+o7uqk} zbf-8VA|j3?bKU~yGhlk5#|0;1U_io7Ki#MaY*B7+&bJd2^S7-o5VfB)Z9vij=AUof znwk=jZ`g|)>zvHs-`qWb7Qm() zh;26~sCz%fITRg0&2@);1gK?_sCmKQn`OnvOYiyjXW!FX^_dObJ-VPG3tYN@%+kQ=p9!QQCrvk`qG~K{?n)h>{et&z>8gH z4G7^C!Q&L!;IJ=E=0CpfuV7?~iA_p+yjwZ*+oWR7PRQr#!@$$tGBj~=;Zke6oJGZI zR!@?%j0{kWw-`}DrR8g*)yR3-_60RHPiBmeEW6`tcHPwNuF|Q^>s(zx1fTVy^_2*;6u3f zFIs%Z+WK-o)AHGC6+8{Y<=<}(B31@LKR)pgh#9N5Un1Kt_pX||yLDjD6Dr4LRdzBl zF-=NmDmLyUgtc00A$>oTCP)XONnxQ4VAE3dxHst$Wxs^RF{9Pbp=1!|CyMB63T2>BUtpz*X*W9p)dcpWhps)U>Mc^6J^a zb}GcF<(Yx3Y1i+1xw_x|dg$$b*E{>UN!&UbKVK|UPQGQ5=6%do*GF-g7%uCd@|U-M z9*$m4=?mlHWj_{wS>GQOe2tsg+!#b+<@ffMbb1!xHX|f%Us+XU_F$XP&tjO!vyZ)nhFA@X!I#95-$F=- z0X8p#dzFTso*a}?5bB~|I?~cYOO-y%xf~K4cY#OIZEvINy1WuXTYGYIyeg<=7H-wX z{Ue8)eh@eV!^WxiimjX(RCE$zI29Vh!ouFgVLv`L_j|zWy?%@yDb3)}jYp$2*QzhB zN040@y-z?yNR&Mx3DffLse&BUG{&~A~{bLcy zd3gZfM1K18X=BozO|Ip;fHPfs^@y4>k)47ZBiGBss3>l{sCKvaOchI)nx{n}`{QkL zvJQy3*OVkeO!tdMM@H@_xb!3!Sr_#M@FNf?qQah1;47i^vUhN}e)a0dprG}>EXI@` zIsZ_oT6HxvRu%?31_sKZ?zqqP$v-?L>2dDVL0IQPchWHhe(pK?K)1{L8wV$cY>EiC zA%GmsA8rH(BikjK+!wpS+K2GOznkd-3v0bf11GfD{yA2e^bKud83ixr=%BDbnp~A^k+fx{?W84uB>&&X;XO{u) ztu-(|lj^@SQ)5dnqc0gUsuh3{}VWH>+$3_fgTeAMHLI zEQ!`V^%v^skOVit3vb`r+Lj_OnHt-E{qtuW8&@36TGwH)8>t_o7<7_z>S;*9fZvN$ zFH2IzBQ2y<(EEJ!&8qf3@*A*`GoL8RZ%kqxzZOrm?5P2!+tX)xHIOzQ_zCMP~^-Qun#6c-7$GU;v_83;Y$8)N*Eb zh&8M+>n&X^!J_s^?)B^Tt>4rLs@@`P??h4O=nz!~hM$0C6-LKb1s^^WaN2Euz~7ui zsCDh(+5Y-BAB+vdwoCn+uV2BG1$DtnYc1q0Hg&Ur^T&^kvl|-)xR2-aE=T{DLbDf6^bXtDD-re1eb@F}x{*D4%LS&0DIT_iMr%m$Px8Jg) zi4WF~Uy4=a739&RUrzhf{98g;%Y=w&aXa}e?o~FwkzuCvdMY^EIkIwd({OP;WRv*z zCb?%(E{P|Ee`B!j0N#Oc)K_fJVmx@X;4#Yk$wi3JR33ilAeXD=TBvQES}cdCs4%CP z#lgDw&WLf4dQ*=AkH3zKl<+ZpJaGi{qE_Se;>i#KFkWSSM*#u=YaQ055T&KOO30U; zh4OjT-@jj^`r`blR2Jep^Xuwx1?^_G(@`Cgi`~g#*X3i=h&8?jU$e7wBKny&6Z<|g zavmU0a7))|aJzQt9h?}b@35u){3%6eJ=EV1J42M4VbT7<_P9+`O-y|4K~DpM>($KT zTw7Z@Iy%6~K>iPYZY#A1`Mr&i$=7mk8R5o3aRT+2>QQ0{- znClR6vI=eLG1hsq!)-joViLVvP-JfAgo}0Jem_<97D~=eUjEZ*nZ?D|d}PM`(Ldf_ z8dc4E6K8#wfZ#`Po2lczUViz+)vQ2+{ZTLnj=I-xW^H}8O`qbmyG>6-6gqrMuho#3 zQtVD|KC#)er%#3O;FjT;Hf_ZuJt>r*xG2%wnQUBI<48Ohoi_KR{<1 zN_tMlJzf^UwIwn%poHIBQ)U8Bf9vnpI<9-%nwpyXgRW>|5A?b-t85&Dt0aKkZf*j2 zaTV2kym$-q^ZxM&#QYMCfqaNv(j#dpI}W_V<73z{B$8teZ+zgnK`y|=#q{DKL9z?S zNT?C`-FlxrB_$mfeDtWv@<=i&fV~j#F#TwHeG%;v7~(3MdlLTxU(5JceSW?L`hlYL z#s)%3EB%)i4&+m$iG9H91wDoH=Fwbl#`BvuZx&jAOFOE_laQ6V6Mz7O2Kk;gIy5x2 zrlv-XNyYGk&)-tXsnQ7%8Ih3j3WfEn@%FF$w!wUMSJzu`sR~AI;^X4j>0O1Uz@bpj zz+n770fk`p*^TmuhzM{x-re1UJ{S-H>!LNi>cD*SE4;k4{P$YE5umYZDS2IyHmCVS$ zGv3qV-O*=6$#O2iaowmfyQ-ulk|Y6c<2zvx5+eUFQY)B>hb7t{sEg%M97d8APfA+R zd#ANl7EhkM4GZf{uxaR$mdVOV54zxuQlcK0hbtm57dP{4N!zYJxu)Pkxql5Aauf zxyg~@q*Ppww5V|9Z|)e4^Z&xZ8MR7>WlDcnte65=ffyN42##&@$Uw*?s z(G*MhhZYwW0*wLTfJ~1bh2_0LO|`)tE+cwgZaM0=u|WaP<4?;Ejwd6%fV$qg6$*(I zMkXf2#Kc!FiBC;U!D}Hd1f;>1+~b))plCG_6+MT^c*%xL7Zb24Y1~<{KyK@LuSX#D z+BU~Aq>qhF%AiGKHxfB-SA(2ARh(Z)WqI%*t!%O0%+$19XsQT?q08KdL93q`9&%6k z!y%KokS-CHb$37 zl#^E^a9(S*I_m-!t=UQ-FU?fTC@_e~P?1_8+a{!JLfjdre?9pEt+y{69eEKO)W21+Ii_mU~hj7D6y55 zmBd6`h9VP&X9=6sp>5DvftxyrkUP7&6wF6+Zbf@8t*@8CP-zEkPgeO@9JtuR7xVl3 z0JCHp8;43sU%PshkE}aem&d+l!g1OwA~G`P)y=$D6v%wf$MyGCkqdSJ_QOU=86{%= zdpHVXDr8~N_FEpBhI(CQ!qp*EXB@LkH?V*n0hvyanhUE4A!cBYyR&aEpS8X|Xj5>0 zyo3*13Z?f*J5$s(taGosb{Sq36%`CDl(~GyR*n_HRblB}Di1ZaVCa&{J0E()pPfbp zmvdwQd<5xiAzibzt4>$KhIgh?hvKa0y7BCZ?&r#^@Rh{>(FLW~Y^b{_u&n1A) z*wfPovf3vmwA^+^I121dKzsxE=_(T|ZpE)(6Dr(8>NIzR+q+fRY+YSl^W7tI)v7AB zS#JOH&PNOkH3k+stypS}0AWL_8Zu)(K%Y&)r(g2$`>(Ar0i`H#NzB?oO z^2Jc@<6Qg}m6M~w%k6^#xm@IF}vB!`zgoTybeEV;H5Y`ggrCrQ7u>Sv-U{>LOb6w`P zuZN7)-P~f`0T>V)7ZDv9NkB-L%gc^=Z_|rS4UDOHLKHSLU)wi?ziVr00m@=wVICM5 z1c0{JK5`j~i2b4@V<>h{w&r>e<-d>jAUREO-wwjGfVP9Qt_phaWx>LdS$cD!!PmFt z1Sbeidw&TgqT!*Tdsi<3@dRI|$9w0${X+QpZ;jP`yf=`qYJ+<9YCe_c-%FjUDWLJV z=l5$=w`WgFOBP_YP%41S4gJc0Mo0eXfS5xY(2R<$07;qnh@sKO*1R#9CQ7AnI71AhaxIm#RI zb05Ket&=3c4ViAn#&)g~kXcsc9D;eH$7KRz_-?$se-Bd0fB;2S@N=f6`EjsDf=58$ z04GweDjeC5AEyT8=d02D?COF*F1(=m>#yPHrz)wOLiU|P=a4BB*j`!*Dh=ykqT40k&Afb`0hea z3(6omx@@CRik7x%pukjUOR2bRDh`?4-Q7XX1rK!I%F4h%-Jz@N4nww!6lNVhe$K$z zeX*AF`7^zJIgAB-R@|Jj5}9fhy+1Rks#{f7X3zsM>`>+&PBpm8_5V3;I_;i-OAQr@ zjQg^YNQxZ7wzL#n=8K!y8!9WEzMUN0BPFFR(=PwxdF@&d7~G`@#TC0f0Un0A3QF4D ze>No%?7h8Lu51IR2S?iO_I4OjtFL;yCxk-yL)#p?=+N-+=CM80>x7aM=3RtlB6uVu zB!EN|n)Lj`a{-P1 zdk;qGFwOA&-MiS>C2*8^Am&E`-sUDIi;_a5AO$7oFf@g`3*hXyP!a~Bft4d6C`U-x zUcGX3+_P!2wlFn)4W0x}PQUG{d2L#`<%HajBa6uiUl;7`?I?aAo&&j@5FfXiSZUiyY`T{uC6!4(tr&PBxR3#A4l=KLP##u z{%|zPB=VWfeb~%maow8v2DOvCmKHJ@vu@8_Tn;FNVdo!>5O#ZyuOKC52c%-{Rde-C z5zhdSM^xtK2Kc8JYhAguIhtjmdP;tz*zAbxVr~tl5JRY@r$e;B_e+i5r+bURBxP>z z{iKcZmGoV?RqGEgTzH#Q-|&p87mBVC-i^MNAkgC3+uE-8QlG30-Zgp&Ay-%qugI+w znefO3TxJf|n*c(Hi;cZbDl!`(Cwgu^7~jDvTUt?Jm0T^C(g>wD{5zD&-;$xP6e>BV zq`G?ZCOcSv)XqaoCy6tvnw}B+1Bq`T4gwK8sATg?Q;F`9lKQ=Wf4et|Q2`kT9vlE` zzI}WfuUDGE7IJN%jrV=}dt=hOB(#*2loUKAEYOKjQcT6DK;9IRPcKz984uZ+nAgun z?M?2?&e8e}JxqrAe5_RL)z~LJVAwCJc663JSqD;{fcBvwCukWNRSMkJD|mPJ_Gn*1 zXM(R_rx-rKxfU5|s1V`bv*_;PB4wnbruNX0j{QMeeLb?h-T%sLKznn4e`{-YWhD;_ zk4gwmMXKDi7nEK=(jO?kjN{ZV{R1sAVj$m{GWW;Sl*o&UtZe*tvcZi1TI)FVI56b1 zJedu834G3IB&-rfKL)qP8cEB4E%Z9uJQT2ha4*%?)IdeOy1e|z{g5@mOOZw$SP4*v zg5|!M&E_vos&wbgDIT86)1w1tM@Q{4V?t7uvHuGNp#Iw5AIZ$5!7R;0G!1?7*35&o z98%-@E(lT|(3HOxyRcZSTSw>0v9gl|j*o8c?&IU*!~_H-i_jVS=VX>gsaIM_Fon)` z^&s2%JdXyzD&FrVDGwV52Q~HSMv@>1l#t!s;kB~cksMvg=x7FJ%&qbYFx^P-tTr*3 zmXs_iEF8339=o|D_Vj79yLd@Zmg$oxPtG72=oYyUoBogXMcvpXXbkk{b9`|3Ig7u@ zIYDx=p-$2H+Vh*hx^k*RaR|_Y9t1=4@IWg-N7do?V}(J24#EjkRaL2Wc6U7HLP!*g z0jLOwpgV{D%w1egF2$cedN6f#(wL83-Z%z3l=W$J4Zu(o*>C9>6!+!^Bd&_5sys0YcwtVgb68-PYqNgw14xg_Pl7Sc-5+`+;1b66h>@dv37 zjjpo66UAD`O+9`6K2WsTHXp>WXh$A7uPuem&l^&$^jA^3UqKH(f$9JRc7`g@x_6;f z8A^o$dA+AjaHc(uCxc#QOJ(Qg{a<*6Z7?8`E2-`O&vUG6rGK0eKDDIRW{ zQw=LC44RsP@F3sxvp+lG&k}FfYPdJIxcD3~oUCmnzK&B0=u)gL8VZx0zKLpE&oOCM z(tG#zm-`POd+LQz<@x@&;AZ{m++3Mk*D#QD;Jz<$*%y=c{Jj~*I_k}m5RoYV;U2fs?o9w%XXU;sLFz)qKDW?orXtimmBVFBGaPz06Biz#`K%IFG)=QV$>t$}yt^fzD57%@A~@n#7fR)2V_TZ`emtN0&B@6rFcUWM<>6v)0L$&|?7D$K{{7wchU#t1 z%OBH{^QVUTFL9gg7~0zh@o25i&h7wb5OSA)B{WI!&Yjso9bU`}u_~5IBJ@p=iQF*L z5}k1fDhK!?x&sjt-3d*vW`9Vo6p>?I_r}fPEB!7&Wavd!2WRIPfs}Z+7%?(RUEO_T ziucCC?S`{fhkazjfD%>s3o!&J17Rxpc)KkGD2Vt1zQ1qL2aTwWk0?^J^!w^N+&yJmp_+;dVwB z>r{LxDw1VfH|+o}@L*>Jfgom06!kn(a##I(PmR6wySfCX3`ER2OoUyV;|Gh|2G0Xb zfB1)mOHZtgmL>52vEQ7cl@@hL^eNr``ZkPSE?KSND4*S+RfPAqD^Ejy{%XDJHI?Es zsktuGt~X~;v>Jf~j0^tC_ z733Z|I#w{#^KcPB8rwwI0i>J4POMn$jHdZD(?>`bXHW^~TOYp9?fNC>xQX%^yPfTz4+vL7%(?ItDa~70ybev`Ay) zT$`x#%vUewavU{M-ZRt9nb+rM4Mb<}8N)yL*E+3Y$OS+`G{#3>B=36UKS=WPYfEpD zzI-!ye%obDvQ#ZGGP2x!Ffh9LXl7;xaNoTpydvnNUC(@sI$5>&n#>1(f?ag9wCejW z%;8)fKiX{#+Hm~dL+uRYE!8~{%XS~!(Vafhdsm5|+M1}|#sGfMLR6lBe8NJd*c^>Z z2yOd8j0c2mDTgk$sl%NwCE>iEZCLkmu)3>(nZgksS!t1aIr4($vybEm+bb&%%#Zhr2t+~?Sx7zd?{LJ5cB*br58Lc%dn)DQe?3-l&FJHbi>eL;9Wr`6#NTnHd3$@ZVh)g@GZRef`lRZP6pP;MiUulPN zX>d9r`Ka=Wi_g(L4OSAIZo9F)2Cd?V-EcR75hy>ut#D7X^`5}5dNxus2YC?O+=Hh_ zH(U&kuERMF|8A1v85S1TEA$W^(X*yd5lmH^o|u^EdA#3>cuq_(@9yIE5hCQ)Mu3Ux z>F&1fiZ5;pCCyMOR5HV31esaY>QEVVKb*NX(~Zh7+oGYNp`*jHnaA3w)$!f|IM1!$ zJ^%xoxe<36(;fn1}&83Qb^JNJNUo?*TeeU)lW*Q1@L3-GkQ#J#cv`cosw z2t2E{U;KDt(#Gkqe8iR7p8g^lh)AEGp9hN~ma4r$4U_Kph2>>QL@0%D zJY0Q6MJjv9NSj+5?bob4Sy@3Dn;Y{uZ@6!EdupzX`34bj_MSkQZ`_@zqo{~XWPSLs z`W`+oB-I{=&k^%;bD(7Y19jNL0b+(K|KEeT{dt2Hai)z01(x9V2vOh#MMc(!46p`( zg0r=e@)S((qU9`uinQz87B`Y^iJpj3tqc{q!+{uibQ>ltcfVi5kDJ?@E*$@|;ElA^ z*LT&|*O#)}QOzF$tO?!(o)UUGI)>!`=|-9ewiUPlM@sEn&^AF8XV z{9YG+Z;4)WocbmHTNEV^$Sr_I2G{l2IcW4B>5x#xv;B5OtxHSS^<4HSfK~s|I(46l zBJ^P5J#pku^{D@8i#wc#NO948YN52v;bKuVrEqg=>;5UNw5Eip#eSj+I+5Sr=~}UX zfI#Wo+W8H@{@ix|sj70$Aszyb73{Suyh1ca1^GbWtfr%U2IYKOnjYfEkD)*d`=GmFK9>Pl@$qM1 zWSn+AE(8h+ht=V=htROlf@~o25-ci!84`y?j;m8i{M8PUPC=lYXdB>XVtSFAsJzUm zJeIGo+fgT|)S(h3Yh7%Y@N(W88|%$^!N=RbI4$_h)kC+E&%v?m`*;0s-&>mfZt-%u z3oP)`(z;I8+OSHW;0e3#1p8!A2Ea`0Xaw8#V2{YQ4H(K3u8nZH~;HQ)Or+nVgqAxy4h$kYY^c?o=O)J!JgCa zm8Qsq>~h{bwC~I82=5ib!?|?H>-@B}(et>}d6f*A7CTQ5`Q8Q1vv6WZz*bEE|P~^GLDAk~yvx>T0 z73FfbpD{TZp!{w{X{sk`BOWqq?+;7CO=HyB5gQ*bASlQf<(iP&r=whC^?O5}R#RD^ zrr~E)dYT|P@Ik*0>36@~>3L52{`+q5_1sGyBB8G3%@Wde(<37^oQ%RE)A=tyN56D) zbz50p#SeqK(E=~2Ts!43ZM^|HOs8$Gh)D-Z1Ua{~mXcZODqg}mZ zHBAkTqSK@CMf%|U0uMSm5N;?zI{-&G_y7a{8a~Vgwa?kU$BfEA;dW7Q^B`mv6Cia8RWKstd(YZ$=wfzSILK0Qdli1R#C2 z?IQ)h?QAvDB9ww($YO}h)AJPIE+8khYVOb;<~4agMifsWXzm2uq)^oVSPWP6SfQj^ zVxO%L@Rp+^H{(e)P0czUrl8TwP*X%%XjTi3B^CxIP3SC0^-Uz*gcfkgP;8*U+jOh%(l4zC5Yi{8J_#T6XqeYjd#h|Eu>NJfT7!c58N)~Q=Z0fA)y zM5UD`ly@y>f8eo3v8r*o?~_s4IXQVj=nIW5Z8}^<8X6itK|x4$$@i6!O!3yELRU0z z8+;*lQ)QDGpBG-1gKg2(Y@{&zIxWiPp?+(yI{&3;W*)8DSg z>+=bOgGCkWj6F$$b!$FZgoJ%Ts>X(f5dGc=QXSB~D(4RusBP0~qG4e@b~;Ru&wasY z=TV~{3!b{BW?36Evd+}>HV1o3=?~eSdr&qg*Hrq}Wps_^jdZLl7twT0E@SxLZrt6q zB^;`7e$xbPn*@K5-D;|#Abu7GoWCSoP>^2|4%HKIytqhPSsge{oi z>~N7)xv#t{WOW#@A5hZ*sqx_!vu2BAz zKR%cC#2}@hS4mSdAt`BcU|1=VA&w`q@CDQP+enWMCSiLKA-8)T)sUaku(jLM1ib6s%|1E1xl z+uNTYZDnLa-i>OgsTJsy4GkcJ{Xdcm<}I`c6ci?lumjlhXT8d*`NPfRt%;EU))#jL zXzb3g%gV~Kc#Yu2>vwo%yQyJ+~R0d z%MF~1aaRVia&jb4ha)4Thlim}6aQRMu&#JQ^*5O()u<`)*7d8|3N6s|#YUlge0+wz zn|gn)EI-c}o{nwYsM{Q+v@qAuZA8FkeT}!W;ii)mt9vjb%nkyWflpKajki|^X#M1Bhx7!%hv3YXb zxEJ3Dy_mq|q+3h0i-kY6E`7SvNkKnTS(`o8ABr1JNod&DKWxGOHe0g%MWsqYDx8f% zI%Lfo9a6-Bq(Y`_cu=Z5d#0^I8^R!)B+#*;i%-J8G@o1My*5^6&{otLlM%yo_!YLh zq^kQittF9BjH>MRdVmrVv1-Ue6CYq+_4Vt_Hm@w?-guu^6uZ8I$!<`;-~r&}4qGg( z?kxI{)ca2tBt5g`qTPL?O@dX6@EzfcbmJWw$%za#9 zJ}9qS!LLau2q%q^*%9W#-Njruk0lm+jVSqthM}5CO%Ff0WHO_r4LfLMR#pWDu(0>? z+;$eKzXW{^CK2qO`u5fzMqtyV?hP{QHm*T=^&(LZa=dEnV~Qqg)zvj&9;Vsv=Gp!@ z58Ws=&Qmm|12$fRmMTC0xM_j1vbM85z4$s_Q9fSMn=hu1zPNhg(=U$^V^?4>7Y&x=R$$>mvr(hX-_v9k`Ay&v|ntqV~;m zivP2jbClbE#>R5M5}^DgEkaol&V4z%_Q>pF#*j+KCy#a-bVq*FkG>m(a+SF6P-7=- zj%%^D2yjd|KU$Sj?#n4EEwzP(L^bdpOpJ2E{RChK;ODSqCm(lfN=Gv}IoTS8cW4?U zaC^2QVM^J@A3i`MxI}Q8$XXP2GrtlYtt@%MRA-$UQW!FS2nQJ(?s(PtkOylCoUAEc z6YXT+2mJGweD7NwBcsp}12C6x?HGAolKxcMIq|<=Ak#(61;WByAg$6~^`RkpLPEJk z1rkzH^!%pbBbYr=)yRn?EUpu}0=3`daKQ<$0VR@=kIGkXbLRF`89knM-92g>1@mWp zIlTb77SGPEf zf9RQDvX=>!cP1|BE}G`@XP_Eu>fG7d=s$Mqyi44?-t`Nw<9@tTSo3HD z*rr~nhV+|?sxlOYckt@Y0;sNDy(%Ou9MC>Ie1I7jz`u0qG6ycuw_|ZGsee0V2IFxQ zrfMfS|A6^0s!%zkgeM{?fHyooJgi96u^S#yQFN;c=b)vnS-3==Tv4%R#P0L%-Dt>! z%~bG9p=Q125BLfoVodX~<0Vt33CU*GI1xcB_k>aVEo4EwxMqbLGbiI*sHhVZwa#Pt zDNHbLkqoCl9&{8wJ&U|NJW{kX=))>Y=OTy|AyHA# zVQFAhz6P>rBmG7e?K;SU`|SE|Ypad)RRx=(M8m%qrp0o60uFDMx#`#NLMj*_6N0?-+TQgAS`5 zRn8vTKkG9kNa@i91rd@bA39x-dql@!=#@$5)i{~1k7WEO3&bgA713YFgxxYTt7H8w zt*nfSxI}IH42=UNVEzzBwAKzG>BDJj7n&MFV-edv8sjz0v>kBL1jWh@yL0bAN^`#k zm&{^oCJp%w?QY(@;%eWmiL_N3 zSU}aCm;XvXJwNGMGX@#oA>{c-+4;>fo{-%vr4F+Jv?0x@fBFDF3!}#?~ zKy>~ChQv(vKEr9CN2|k#!)THeNwi8dr%AW5_sKMCLVTN^q8ZQmX3X=@GUk_nP_>4*)B? zJdbY#ll>4$o-SWD$=$V|^01hy$3bw}&Su&gJTL7z2aPIlv2qBY$t5Mfs5&aqgp7Hf zb_tMLSiI!q1cg~MeckBr;9!x)-XI7UjC8(uonAJ^ev~G!rlWAS5E#WgudAX`xsw0+ z%KToa#>toE#j{gfFaRJWA%Ow%vme_A?5YL`85upjBmlTNkp^CW*qmW*Q<3=W&s=LV zUITdFz%Rjjw$(q%`MFrPNk>b|(98@JFjasE06~fe9-qC=tBp~$l?z0J!^7ub@6#FM zjrhwRymk=sT2s@R5)%}xdjfC~;{kpzrJyqxWpiQ8f5SGiCY)-ZVsOxS{?C$yc^;UP zToxDS5Y>P!v${5!-&2aC%f3h0#sKX?D*|^C3ZEoyJ3bgVvDjGCTvggd_ass0N{~K< z$oz^ocph5MzsL-ONGvgefMg?-w6&QD3jo^=i;P^_q{QetOc3t}q_eWJq^ES5_EKZ~ zPdq5)?AW-u_jY&n#iBtnVQOqFi=h8V8KLS52Y|NW{QYlbq#J;aSp7MxBSL)#t@;$1 zDhQ2`cSkeA)u7G@ztB*BrVs=-?jd^W^mm&~V`C#QAb=N>qSyEW0T1`RhT=_0R#Q^q z@}8R59J1Nn+WIv-3~mbp{$UxJeFXE1tlCFjXuYArN>fnvd)9l>HSziS3pj63Ra_Fm zOA>IjJ3VsjO33&>*N&D@pho+rRm|U0!SVeAUWCJZd)noI8=2X%NvN4E69Yp!$a^=@U8`oCXi25HNOWc3pE`)@$E!X zri;(9Faq_wJfP)&Y88F<<-#^-^J6@vkf`VT7r$Vpc-s-1HsH3c!>g^ecQ? z)?PYOFo?xbB_93g{{3IT@AUo5tFISY{DvLJct=XH{+ZX=*@d$UblKTagoI|GDeul1 zlGS}Q4zP%F$+J8q$x+!MyP9=JIGS=|h@R?7lIykKm|NnxayD> zlE>6@xitxGdI5^wn5xMLNK{Uf6vccf_CQ$$A zSa#~?q4&HF`<^NHVZAA8#y}RA$r(}s>d-k@=OvU=(KdYHW&0C6bbudc)vi@jR;G15 z+x|9BJQ@K*oT^0#R~I)H?OMz4XjTanjJ}nf)j0|X5bx`v^x4^& z;v-!TTZWYL7q?)LgS%%7;@pn+PjmO({{FX|B5Z(Glz{E&mlNIH6vc4C;;pSa;gUt# z)Gwie>P~8+r`0!!Fo79ZWu-{`F!30o3z#4H%mMi(*%km9QeNv|NNrpy(fg^R2}tnP z*R%ef4OyIE=P9qUhJ4IxvB0JWSR&9>9juKyqL8_7!+ehR*V`U+@$Y!?u5A`tX-* zz~7}9Yx_`ViB({xadim_mRM|JRpRx?zoLUwPs{4g%U|QOv)+gZ3MTOXbLGn5|NNge zGii7+?Qvn@vFJYoJ$G7kA-NV)POMV7Khp%2`Ce#Vqqs(78SX&o4Ni8m^t66-ep#sk+ zIf;iKCjS1E=h3&l1qF@*hXVWi@ZH2^yRp;cm*(e@3;H!LFfUj#g)XtE717o@^~*R- z!}Dnm(Acnn!O)J1$`Bl}8Z3X+4UZdO#1fnkz~=)#4ruGmYj&OfOPTUmn{5}Pf%|__ zw6Z;3ck!GMlu%%}b0^?gext_dlp|(&-h9Nq&=3tX*f8S`nCn;_mDF7!7m1WcPq`EU z#|5cKszs82Ri_7gdzuYW8_$VB{{h1;e(yiPE-^ejEb8*fbLU5ZW|j5N7i%+1eBhY& z_3M2YErD3TrQQs%Jn*|k4(5F3Vi^RvQ*(CYWK?c@PIe9)+?;~8vm=EG9C;?MUa=V? zN4m9ZftAMyBRarsB9u%7@VtDNC=ltl29poh*b{@G35M69(wd*o#6CV49#CQ&9RtUEX2dv@1=omJIJmh9gIb`LfFB315fN#`-9HE7=|S!fpez#D z?W2LMS7U;qfSGL<(9Vc`xDEnpkFFJE7|Xg^`D}Xy55|H!@{1d%Dl~cbkx@CFFsmLH z$E;a7G1UFhA0#n9^h+BWn*H&p-FN@d-5U&q(X~g4>~ITXM#`3!5HPN9Bt$U{3Xa}h zb}kx+!MrHg`&X<|6&+O?-byW`DycpMno^i)ljzr_!pUKf^laZxJ&(D1+QDQe)t5Ys-#@gM-@>%icLL;QhY(<^{1+?`{Yn}(U&iF=yNY9%V^R;P5?4R z!1KX(cNa7y3Ypa%5uf=41i6DpmYU|3-s_}%~88rUbet4%Sd zJ{YShzJQe~_B~VWQ=x9t8O>@(ITAhTzRSkNRS#s%NAjjk=$d^ko15Lo#sxuN>{Ycf zesbc0kqAuJ%pJguN_Nv^ZDczfV<8Ae7pdlt!RV|f>Oh||b52qpuiu(C&VuFf`Y2e3?^0mK@+u-2fzk1BW z!$TN^$r}g(4<{TPL4N*#mRW$*p^1}hTv=XjSwv4vP6V{KvzfPMR+g3kLjTla>G<`l#D0+lekiZC zmg@XTFSQ>GOvJ^ye|__oxm=i!=Dj}*%48IoKNc_=xEw2b(M^5)|uzv=_u|KJwKY<2ITUJq9opxnLJpDKQx0A6pw06H}p8 z3acUP>6s?)a(cwwfgUc_bw7+!1*I0uVPs?!mnU9%G=W)9OYDSmfk#n3irQ%|-BufV zaZM}Y;;r4?vQPEIR8)*Rol9vz@3^?QIXnA(ZaXkA5PswLPty$FMQ>Vkcn}T=RPIh;H6n?3uR&BM4azB_q>y6r(c)tj$ z3ou-Xr368&?(x~$4C0E-9Ho0(K*u8VR2^u9tD78VBNl%zghIcadueVPVAnbV#5FFj7IP=*dK z9Q5^{Lb0QyFLJ)UX@$mJ}^QA)zxgrJ~nc!cwd z(tDpl%h}U&fJxtWQpp^<$|IjEz!;^5DvnU(e>g}OxHy5Lh(65U*xWqd7qkal-224V zpwpS1@gd)z1@UUpfwmaIhbRU zP3H4jnePY>4+nY-kk1@7UY3};SKp{Sv3+33o?Ot41|kFD3B3#&syhj&ova`j(bV(C zq%;9p0uy!`UI8E>IB4A^fo&KpnuT0vU7$R;>DLcBJf122$fy|3msenlC}Fq^wi|@Q z@+?>zGJfn_zzfS6jd)h7R!|HEEkK;Db%5_7q>bMPHKvmO`5Ua8elK5YPoB^!gCGrN z#HebWxLcti?3*W^_E=r#or>)R_lAAyOZoRjQ(URQpMbIheR_23emc-0Fr8c&4U?Wy z2<1Tzx)K#-m|br{`Cc~H~6sCD2-d21IXGVD1?e0sBLOTpR6$r|p6KJTw@`0Y{9rVtU#+o&~p zP1bI5a&WAzt5_PHYSfz3G@whf0Clz zUpqO~fH3v_?c@E8)1{1CnXDB}r~9jQXU+$o9&E2u!gzIedet;XL4k8m`SSL*81Ai) z+70Ge17DohouB$&BW96MZ7p*Q>!Qbjd(83= z35K=o3vcVUb(4q4`B(aZP+vSFx44*+ol5VIKi-G^-_+tS5?xxxZ5q@qBTFHwM%ALR z-Wlbos^eOrm^)TwBiEoqNlfazpsc#OcU0V{LEUi9TvqDy+A#J%T7Xi#rvoeIq@uLk z8WsE2<&p`l6WOzLqOw*iX)-px%fh-7f)gvx8wOMKAG|LtTu*YIf^g>WJNPjyp1Ma~ zYtKtJ0vU_ymr;`7b;;+jH4{cnl3tNwf$#kp_MU?)H$jEqeOlqm&+mO2yE#!h7xtV2 zeXt2sMwRz@BV8yC)~_25RgdAo|A&}321W^%YbC)Hf4z2dxZ8W?TYLLMQqlydp^4n? z@>s^g@g$qC-Qbp`7ibPI`phW8E}eP~uHGTT9dMt^d7Q|DfJspBI7rjEzO+X~Tkjt( zw+64hl_TTK_sRX$tP_(?`sU%7rAV{NhAMmfeA-kKSaB$Z_cmjJHY*x7g`w1i-a(OF#G z2Y%iAr}oL-8zggP(jaD)j;Z&aE*MqSaU6_N)iyE((W9gf$#|F9UVW~j9tuC->YjZ< zV8RJs+?1H+^i_QK#%ky4!O+@AqAgdhWRQ`QS7@v+>UtQTl#W*0icNg_lPv5GBElzE zcbPf2o#VMkKiB5{{Dkto9T(SDWj#K-u-ro8hP5bs>6Knt4@yc0Ybw~!)T#twxUM%GHxek6kSjhhdRaz&U7U_4IEAgW zvB;~1o-%>&?UaMl{~+(JqpDoLe^Iu9C?cpJ0s?~4EwPYxfgm6uARPiK-CYZn76Fk4 zDQW4>1u8Aw4bt7+XD;{o-f_?PopJuX<9DvZvG>@U#p2~%@AEu!eriV7{o5g_m0kzBEKcfXpz zzF)4YU;p&!ucE6%9@u#H*49!W0>IWG<{B7RCT3MaZ5|r*q;_mj?Nz29Ph2h*lo=eype`N!V?NTik{Rq-@w2qPJ{7ZUTmcmd0(ol!#+5p zqbyiPQ#ne{v1Ha0vn{;*1a<28T{$RsQ&AtsMn}B}3`n)kSv;HAnuw8xT%>^YDX){i zomwx-3ZVl_;8lwUDL;k3%iW0T19?Q5KffPqZ`Cu&8U z$<^(S-t(Ux`fwLuJPUY_%oyaaQNf)6&T*8_-c_+>#Fb%p54yW(qB7qY*XasyGiC#a{1tTA^7$!gT}n$oP0{AoH%l^rYAXM z(3#dkQz?cR{cdJj)6hMMxHOkSzx!gAO=ufffRyU!)X$A10y5Xu%-C;h|WBA zs=DS7I#SJ-nlD~htt@nRUysDm5f(P%RF8dlKl{%7tXcPk2y3db7sX}iVNPOKlf)Tb{ysh4 z<93XQHnE^XYg%sM;|giSV}AaQnDci@N%~L_>V^dcS~4z&68!o-Tw&1h z4qL9gyb?DlqkC%I!aDloSe}obET*6BBd=S92+kxtagJ)w7fBmGxY~H<{k!Z_DTa5H zBgbttCUiMby|`Pro&>0~fVpOzn*;>+Jt4o5bM}rM?U}5Nr6nBS;dlJLXJ>;E3Z|>< z_Q(lZt&Kho5a+aC8MLPW43=rx{JnMsk+hPM?euZIql-&v#lvp|QVu}I@Ir#(6CawyybgrHxs1E~j zO|IiyCqxoP6ro7OVP|%8LxVx<`T1GHDyYQm?CtxPcjwSb2{QWT=l_&s`0${KQujyu z9R@#9+AZexz#K`4LzuSrLQ;*@FmumN=v?619^%<_7#?-no^ae=Z7!ANU`2^wh2R2nHuo4y=lXDQAq3TAD79Bvl-R1PLu6&epWsFc_bGHaC87*Z))aYj9O6TQ#_jv^W&*@?t6Tsg_LSf}{OBUw0{&&LF1 zQWRdQsH_j8GrfX+yuATCp#+NeV8Y?MaSr;l*Vs-;Y3I~tPKseBGq)eyzof+JO5cYH z=Xb8-H2waqUgh}0BgT!V|IFP#fD8e1aDwh~JfeDH{DLveVbm(Eva(V(?HIU|>tWCV z=VWHuK+QHS>_FOoNr|4YRJOdWwiZUite@>aT%m2WKRa<^$dQTWQmfc|fun0-Av{|$ z;za;(3CD8+M9V)V|I4N^(wprhyaXLC6NEJ|hV`UQfCcU$_jjf5{O2wam6blSnV^wG}`a%+=2{onl%S(GgmKFMo8h|6I4WY!judAxJg-oe3r?T{G67j}GRmX=X3*n1lOf|f2M@9enB#xb?y%!cD;kB281j1t>5=k?;Yw+@wEAR`$U{Uk&s%GXZ zm$4S2D>M>_k*_I)&mg{DwqiECsVRM9!!jcufS5E&cP{O6WQ7_Ujdt@;qVnXmyuXNc zAeJ^bMk0}(1VD^tD(6(KSF1sB(Xc#P+$qWb#vpz;4|O`LqB#kt)6$Z$g@MIyMWioW zA!5Q=|99xfw{J-);m{+xpPvqskGONPny_2LGWq8swsv~f2`sRNH*LkGA#hv-1jzJx z;Q}WqEBv+kO-pXTz|tLY8=vcRykwl3>Bc$k{zUPvu5&w!o40APL5gze(lsiGksru8 z-3yu^8<$!f&_TfOs_k%!2c}S{C_a;JZ*8GYbjLvHsH-{jYY<+o<8C(Dn{mE4k{iEc z)wjGG)fkkkzUwtvQvFsyq^Hp|{Gw^k+H-fN;od^OG5b0RK{~p5XtN_-mqQ`hAL{Rn z&E5>f3DmY7fYlyTcThPphp{l4NXKP23^ol&bJqoI6aFA^Vr3ybW<0mw)yS2M8B1h8 zDbLz!d4 zw;{T_6=c?v1;55>K^8SQp`cGDWey)W$N)%%WWOC+<9MM}b1Ki6m>3@)gO`0?U%z_i znh9)yg>GDEH!zmp-t}mau7MkKr)~AdS8h+W9atp7z^9W_$foZIk2Bk<)o&dd8mg^T zOeBDWzJ}5ovz|d{IANwwc2-vV*T-X{!!vM;6fyl!cw>L+Sk#uXrdS7y!^jg#J3sLx zFf76F8ZR#cb&A)x!dt&QCybCdVNy^-O)o3}Z66yEVUoi?^$%7>!P>nAwrG$t78lDH z8Tnc1pZ|05ZAY9UP+J?K_~BvP`9*qZCIky352zipVor=qPD!5Sn9nU8y|mP+S=NZR{2RG`mbJnR>)vx;@=-KVB&Lm2XNsJVVoVj#oePf z(h-nquVp{P>wX^BJ=_7ZL%=pww`Z4bL^EN6oHXyvb(YovT-ehh4U8Iuqc2e}#L8wX zLpa3puJhRvyr#^S;IHeJWZB%|BZjzOWw?aNhZ1SP!9+j3`*ic)FF*L32=z$(uMzk4 zr@tgv)7|$Nf9_|F3z+<<`}+U=zOgq}5Q`HRAHT+_n+55sLR^grG%EWO=aPDSbVvb3 zcOzxLnyW45Mnu__ia?P_KtMq6DbE;lw)JzQ5z_40>G&H9rZF5S-z7zJ_!kz*|GZWG zW2vJ>fC8u(8b-pF_4LgwsQqP$3At1<x<_NUW5oc@*bURWwY~DMDg(Njt-T~zF5An6eY$7)YKq-*mXVyl@m0V{iAD;u~Yki z8sJ_#J}neVdwNWgySmza7Zh9ML`18Ti)xuY5R%Tte;lfmq?`$bp8&cFHbc2M-l1O< z8iFEl(Y7})Ia7J&6&A)@kC=&i*O7Hp$;rtbL$eMd^nnCkF6I^C^TS-|2NP5B@-{+( zgazzZ;$82Nk~%}f3{Rd(wWiz1s$!pUF#$CL2SmgyRI3$2B>lMi`IyUE+?;N&q_gu; zr9ZJzvHG+dL)dT0(&sQ@rzotrI59std8UUb9v)^A6>lGj)-s1VfaPiqk1|Kh z-n92Fh_C{1Z;1!kTUj+Xw+lILyzBiYPfy{zFbOj-;E;n(8BWUZ&~QhWWBBVSA+|D@ zKXx!<>*!bqWg0m-d7*6FC}2{4x1+%B53ADSN+T`#v+wEYpMOKp0z|k$#q?S!6q(3t zGiN&)#RKcMsyfF1`2(lkfR09F z$o9Yzg5P1qaVEGCDh5CdRwruYjEhQ2&L+n8)BBd7?|0u@yp~}FxE`^WEvlWm zEBz;oI-Nkz(@nEZL`;k@gpq7&J9`?y=Xck-q{;*ZQSv!jt}MM|!sCWorxB2d-6P0> zN=ZqT3aB}$+AN>f0WUaQb=ga%8beoJ4b-V!TXbJ{3BZJ$4k++Y#tZ!fiY*sikyllv z>AVEEpBAb<3~-(TNa=B9vAlT&nC5rw^-uGW(HaU`FW)@dM*6n4PHU8!NlMD{#CdZ5 z2bucFrjq-JtG~ZL=NOeufEnurQ9n=STOwGDz5@P2>AsUl)rL#8w>I{`6WWrJ!efK) zpP+En9owI9Jq^Qr4KftIgy3JLa&>c!5%^kcQp0TuupAVVk|WCl=dUq88tB4nR7#9t zx$!zKH!ycQ)}M2SdRZx);8*)NYHNmJxj#EQCntP3Ks5Uy^&Z#O zK7chdH^Wmd!JmX;ox%c=x3ip&s?&rkx-)O%-Me?tPlCg9_-G4OOQeH<8lBwP(ej+t zG)yOA*WHQa004ydOR&|SAMdes)o~`*)~Gyv$sQ%cKvZuuJ#-;M^|RDhHut&QyuM93 z(1MjNNjzw+FS9f=GgB(X*rsvUeOFT(bvD7zrFl1jovUOUE3G4PsDBbJ#P%XzY)(

uLH;mp^`0v)73jua&QIJ)>*8s4x(^OrH7r{LE3|x89aOwkQ1%O^# zAHs<|Z*kc99o%~Yq^g=4bTcr^7ylmb!v5(o^tUYK4*u9jARv@@D&eredfnz}ud?#D z4B;S{-A91T?BOw#la!T}l!b{x@XOx387w+A?XthP-C2vPjasaSAdKmD4A1})U#@b8 zSXqOdi#L&C;^H!29i2c91o8sZNJ*ci?CHs20U)ctKk+}x+rVr`ww#P%#t;AkxKlUL zmvG&35lSK=vuE27(aF%<49m2y@9mk?x8!88VMsz|7Iv@xS$NIsS6{IY!MC0DM;H*n zLki;ezIPkL9##xSDfkP|-NA|t8*CGxl(CJh{L)@_3fKJ1X?oN$BiR1M-926%cwTH z_kurtDxPq2IXU1cOmm_Vd-4PY*=_`S5QPu`^Qi+u*2-SHs-%{0&(&S?M0 z05Vl~mC7@uurTq(k&55Pk9(ZzB;vsTnVH$H(-n3aa(&A9I$+ryER%eEwDk0bKxP2P1a5aDE_-nA!`=j#dkn(jk&zJtk&$D-x&-Z4RNuVuf?E02s{~{s#sD-I`?1h$IXw8mZ4mHLx^7H<_;4Xs zc7A$V-?taGWR{u}YSjbGc2E%yuKIla#;a5?{_Vy?8ueE}cdqRSI+sb3!9&NQQWCG7 zi-ENvB6u)A;&6Y(h<9BZ#=XJ;1mna&;7c-KQan7M?KYblV@|w>{ z_A|M4cvKzfw+}WWw4JTGSxR9oc=?>~s;GblO-}fXe(ZbmCkUWDU*A<(Kj?6WTMj*e z7XdLN(*SDU3`T-x4ei7EeRy;u5yhF-#<%1RT}Txg zU94_qzn6jS9$zo>IxNks+9EvNixTOfnG4x2{{0p#)@U!*za??!&Hta&!tdH|0@g%9F*!fa=Gg>En$mLo_B)0K_}8!? zp|nt%wG#&99>B2-+#jj>5&m7vUG4$s29MyefM+HBHh`2MA?!=xo}JsvaA>Wv2)Bwx zY;0{+ySG4Mv{XA77a zKvJ`Kh|z`h^@*-&jGC!+N+C+r;z*M;MZu{y0KtMXc;OQ$5hxx+al1D&f?x`^6i5wN zS(${_iug)D?BwU=1p#`LHs#Hm8A^=c`rtPeE3jQH9>7!;NMAV8|CZ{uHzVpoW8m=Q z0nWu3#JM*}uftos5|0o|C@tK$I8tZ&38LJDl}gp8D!#h(8V1pyeW8Xm%XLSN7NH7wSK%ah6}yz$6{+#1jT zIpjeZ#RU;CAjscK!WV{gHg4AOA|wCOAQ2 z*JHR{{``32eFi~TA^7C#1v6;K;^EHGDPL+yPdB8h)388qHaAjovmPu=6T#g;`UVM~ zEv%M~8*Z3Be}3*_Fb;H16)aXL^~(-QS4YNC%h?d4H8<{464s&0HEiKGsb^q^(q?|t7j|2O>!@vTL#LH zLl){W=u7|&bASU&rrP!FB0j4IASuGp!Z~UM4pews;8J9_@O7g$%NH5 zhhX?>Ku;CHuePz%)EHW~?bYF?rY73sDqkzo@k79^5aX_uXe(gDXn1sNi=?Nn zqY3m{a%1Qw`09J7SZeGSUbW6vAHT(=0uOkl-EuCS>{s}RDA-^9X$rmy)j)s$-uo*Q z##MLPVAqt3;Sn7c3XUpw+D^r!gwQpXl~FyApapamesYSmaHRDzi?@?hyxU$zQc@DZ zl>2!l6yf4HR%fn5zr%EJsNlpW-8qjxKXDj8xk7l&i(u-<`{aodGbR=mm_`)EySXLg z_TeRCp9j9s*VtHe-}7}#m?xqrC;Z^)p<-GA>TovV>x!vHz$!?D8iV3rfvkRZcGuma z%5JP!1>$@ot-b=69Y*jiCua>NVFHHUXSl+ur%ntDM@^IQJ!*SSM!!)T(&LAW-=I+A zfvYukC%&x@ptX z&u4B2k-Z(rI+&Se$|>7Qi6Dj?S8q>GfujZe4x!_sNd}`N6?rzJq2D0K<0_YRe`dG< zja*7-mFrM<=>)20qZj%Y7)15O(-R5-_s^XBs-J0t{kg zegyh(ZUk011gk2hj+W@v)6J331Fxy$I(Y~Pec?UmM}9o5e3&}=><*i@(#yWzM!j2G zTMl>7W>K4w^=_O7ccGH1gG#{vtQzYTjL2?~8#|mhmrNT}R8XLBd;P?td<%rns#|9+ z-Fw^v+5@kq0vOiH4JyQwZXzLlYJ`^tIuR3-c&DRg&?89u)h7N&3*bd?dbAtz_FE~G z((*>rU|rx!c4`I-!S#uvx*f__dsgig>)PD{psBgWnkW(h!IlKiU-zC5C9_FEExwRyczisaCzNuCQA_<8 zY`_pC0!UfRph^7La2ey1FLjSEie)!eis7>eJX?=(e_Y9nK<)W=2)oRNMQA(Crr<5R zKU(Jvdi@&s1nrYDSl6xd3Q^V%Kt|FEED(qF>tCI^z(wM66s4u4tPP=E&L=ozS#O1$ znHG#$<_s%ucU(AmAWr+trcGK}ipOHSS2G@B6U!GcDfq?!Iw^JBgMAO#}C9GIyyN$=HnAO?BxVcmlWS;+dm@R79%CF z1>24CN=xwy0!&x&QJSMuC;IEx*yMol2x+!Mmxf>uv}nwcgZ-I7cT1C}XSo0B%CPJD zI4vx(fU@YQ2e*2Y(ctnoo;Zu+4)le%;6LRmuY09qy zQ#Xmcf-?h|qc8nAqV)U*B`)lM2iY#ImIjh=?tRb9CE>M9C@qCEAW?n?ruOO7phC>c zXZyTzPrzdpD1b$WV~v--oYO+N zW?24eq$C@TBO)XWrm=X9{Pnr)fNFCS%3TQ2WkXlx0ocEjrlw`Iy@KqbhW0-P>I zb|&ajVrS~?=GJoA++0wdm7UjqWg%Z*0uG?s$jCDbG`eYIq_MqyEvNF#0B2{Fgbu0$ z;@;DX7&6b$P}NZk{v-zl$z|@sGBCS&!+L0 z)m1CB#oOcAMhXq~!P)6aus_O)ZWa+f>}P;mhx7$*V|@TM@Mq|#My2lsV@#Rb6M(9u zqzZP-C;0W>+B`XI=Lc5N#NaIk3;6P-X0CvY&f+2hu}@nG%D(EQ@0lP;=!ny*c2%>p ztF82oJ$1=&Oqq)Rr_|sp99~-T`&Ic$koz>(8oNKE*ippYh9Dp#+dsi&8{;&qfa9jT zq2EtPYtv6Q?KZNmp+RtSrUx&MoX7Ow;x=Vy3Br8zb4<)g!Vh+m=8??Bm?l)k)NQmj zo9A6#!%ik#9mPztv+{!<9{4PdGtfpHBabS7-RIuTWfK(-ya&Xr{s~B8kH0mITL~x_cF5&hNr=KQwUU(!EVlpDUJ9B$`Zrpw2&wK1sP~hci z?4O#Ijt$T3oWgWTp~E`;$3y4C#jtYioj5Quy^?o@SGS|R{L%@uXf zKXH?rsD@NtMZbZ7sibSyKd{-u5Tv*$X2so=BS zAWzuZ-r_5AhfN_trs8D+jFPaM^0A8*#I%S%tRt;2!oUCf6GQ)}hQAg0UOTNvlB}eJ zv}NTc{JMDpqNCiG{sg{F6oEOc)Mf|!JEg4@a3ir=IP0`9um(UdKwox)-?iw?9>y)D z8b`H8dcjhnP(Go9_p7#w3Z3W1#>PEv<40v2U4Ex>R zexWi0x~RTI=e_F$$TFDWcnKR0R_!wRml_%-@6nihPu|$C4E^vxdYAr%3l~$uK?pQA zJFE6~9iSCN%ZelphwZ{fx?w8D5|zL&Eh$vwuukE>+Kx0>pn*JJ^=z09A(!#`uOrG9 z0YCkCe^uuBNzWJl;sp|Cpi-~m;o{@qEOgbj!6N_Vg0aQ5N~iU}JUz&XH@GL8`~7>t z#yJ1KPYyeAYBjt7>;E?5P>E5avYp~$MY<2Mz$540NLc4!E)bv9lV5%k%?H~xT-xGoF>C7^}y8wDkBNLO6 z8N~;;Z#@d4)Twp_gR`HP1csKi^@JDD#30Ou3k?Qz@CmOO(9MJH>_w6|$adrS*WX8I zyHtZ8yJe1-QS#S zAtp3B+Iprb7-khko}H3if$;&ypx|^s0N@=FAMbFmF?r|h2;l1Adl?!TQBhK+5Okig zee&~ZXn9$gqobqJK<^B=NlLHmE)k8=IZjlgiHL~2#Zwf9(m=afm!X(eq@HbsMkazM zaCd)SB|`~fIsnhcy9QEF`#q5M!%Po4+1D^8;c4TJO6JQE_v1GC#g&zN{d5v7B46WE>_%Lj*1I-F3inu(bMVN^gLU1x@hn`x3;h7A=m15U^X_*_l&ZsAD+vNos#drT<_n%2&`#ORx03-L3wH`S2siK&1K8DTTs%2> z6XdlLgjhtmnoQT0=I58YEs=xd5wgkQyJBVOJj<4rK!v%-7bX=3*5O5H zGAxE6@6;LiUf7Mu_Te{r$2!~1CkjIr2}nq2JlW%>y3^z=O-;W7*bIU(b>r{72Q3|B z@h)diVFF%DLx4u{7Otq(|C^UIj7+MrX$+L0aB7{XF#uTo?DY6K8;qxe>0O3muU|Wg z)d6j$paySRGznPV>?|07Nfr|cj}&_p@H}8<33|J|Qi<^;*txn>*1@}oONAm_&MBMv z9b+EHg*x#BHvq-sFI|6Rnwp!{DrV3yf@LwWu&||1MGK=WciE?lcYWCQ=xA>wcfHz0 z-BeSvava0x+g3?0T*qLN7x9H4a90Nc>g<-4MKLK$$z^2&k%@POQON0iT~IH21Ed9UXUSp3#qhGNmY3cp*Z>o#WF3?(?qkj* zEy+?rQTLv zzu_)xG|@}czdZ@Ae7W&FPJo7;y%VU^)Ku}LF3jXn=;j(JQNEur8ndA?U3j8(Y6zH2 zmOh8T!71*M_z>=y- zrOMBO2JIcQEiz%ikSkFalb{dm1wfHzM#sI+ry%qbA&CkIz=iwBX|Y|Z!qzH{ZqJ;M#U_kM4XzEe}* zfJK3MwDi)DENU}r$I0d>FYo>Ftf4YCc z!IjEWJPD|HNES7j)B+R2O=M_j$+E0Qk3p+xM++SOuVwzrp~ynM0D&XZ-gTv)Bim+u z>?R=3Slp-*@;gAA?llDnc^vPiHC0`?&HN2YSx}GW=4Mg~>4}BZgGwF_SiZG_O}ArM zw`|G(QyDGxb`GGuuY6&B{g1#t;2aH&tg54*?_+e=+@t|k35d9;2l)jBcaU6vaS5y*xat2VK2_tb4lur(>MJrI zKYfY@^bmN+zD$+V60=O*55Et$->7Ihy$oRkX8!*~u%48J(@^r+4!xNM86PZPxO(77 zZQq+JOvS@x`z=nm!>AMJazSK**WVfXcB`!H#N?{1WDtdUw|Hhtvve$2N=x>H;Fc#4 z{Xe8DphNkCvMj`y8;)lL!#db$9zTW+wPLtiN0N(&mq!`M_&7k5!+X40{enp)3g^<(jibgLs#p_4RK+76L4_u5;AP#^eqR9*0_-y1Jd7oVf5%7>J0xBlrfyd{xHwegpVsAln%&fPU^; z8U6Z5fF7RrHK^LACwhb#8HYjShI5mMT=B&V-TdvHJLvU}dk{<26 zVEO;0R?F#uTIFGlSRTL256Tz<2-E%5vaDmJnJ5o#8ye4NGDZhrpK&^b{08rk zqgyH}1Ijv>3WrL}&aQ7$zp)=W+Tc$$%GZO)Zsi{C4>OWCBHs&fF>6L6AkV(c?U<)! zrB@7|A*Aod2F_x;3=$_md^?{1oXIS+?>u@f9!##DzCo0XGR6^Ql`fFa45zxa&4|+5 z&(YD0o}d`-G%ohJLC#e~M@w^!%6V^v;SBvM+OM&P7|8`RW~$%=h?o+4QJ`3?U}b z2;>sr75PwMfQ~$%ft8mRV%jV6@+<-8He=-E{T#{#W*ek0Y#=ZarKz^cPVDg#*) zl9IJvhD*!K5o{WK=kI;M(WFbt>_D7Y|tn5HItQ6=Z(mt#Q797xzZgidYyvyMSq zbi8D89ubDofq7iGxSL&#nfDQpocu6|oL?3rxwpK}&~?G3sFTFG);4fdoGy)D%gO2R z9DQaiF78e6YhVDzLgXo@X@E*_e_V^%)6&{{Yxi`1TtPj1uUJKAXlr@yJ1+5si$H>q z-lL$%k*D8V9jV+1i@2Ui7^V7F9`0#0C0pA!4(Q?eowhs)zWtod!+!kuFId>i=mqam`j~iIYS9P3J_y~D;btt zTXwp>p4zby7b&P#i`BJM9p?ZyCm!$vz&j~K5h`ep7&+J*e%Rg#tRCBw%_mOGTG3P+ zdVJd-?A*@}OMccB?7;`~yH#MkT^7LmO9r!;-Mb$7ubj{J(tm4pqcr#~0A#Z?G)#|= zcLxN|lK>7kr}AdX+<=&7~g9rb+ty@xdXI@%e}X^S2`xdEg+zGxRnAOq@F&e6J;Hy z;qVzB9zOc%bEoL*93Jq+><;4>rDkb1+cEF5#_Gqp<8Zd0laO$~wiaAO!>lbn{5t#@zVA7n*jv1A4gNSJ9ws5f^_70N?&nU!_+8 zkh~z3OnFFW0D8c|K|W~&{*D4y1O)Zfg~C6rU;jyX(ru5AKwutRku)2J{kuR}d_G8o z;h(9!`)k16u8)JM9irGKfp^?r83$d~aF@pl^O!&<*@Wo#)YOL1h|tjRyCqs$nr*_g zm>Uk$;ZR%Ir8g*rrlz#l78jjPcM+NnW4kqGBS&orotV2gvnerGoS%+FgyiPtB1|)t z7z=M;umLjy#6#es)4(55TnJWqj<+jspbyam!q~_t<1LBCKv&yEjDGm_63A{F@yUm+ z+aLuK;BS9_peWZU;$Xk@e%VB3V`m2xw+FPq>V|M>Y#{OkLN_(zn@or zAzQifER7O=KRduB!OT=v1}B*tQ2yNe!+`99E}zxud<;(D!hkYGyAF|c*t-`O6P3OL zzJ?bd2qE@YubS-^=j5EX#_aEGLEZ)kOqiIN8JSEDtT0c{(C*66HayUG+043s1V4}n zXVXxCaG04w=qNGmK&Aa!q|-#!obs=$SFbu9MH#?Q_r7o6sJE|IC^BSejxy)PEONe; zB7;(Pv6CFS=?P9VfQ3SbTx2CB)v8S;Ll7yz+`LmeI6ej#H@zswH3U?O+g(1Ck%J>Z z1H&T9D>r}+S6l1AS|SUjpTEGgsO<0&>Uey?qJ#(CRRq+GjK*gtSBS1Xm9V`5cb1K9 z{R*XeCo)=2TE^^Ao6GTm0v6)j(6_@munp2 zh4QUL`Et%nKglRn7%0_|SpP-X zV=!82aZb66IN3U;^pg%}-QU_v^(O5x!9e=vWs@*#v*yk<9&=R-R}vHCuk=O=7ivB} zP_K#`L##Sfi9bT*1aFg(8PGE^GLKf+N#l-*i;2;GA|1;~bl?H-ENAz-JsB6T^6<0g zCxz2{k4y(G0SyUU*1>t9sc z@SC&JgR&XyRvI~n;6Dc;NXjZuQQ#aj$+6z}GkAKu58)g}^vbjjO5x%$aKk1T%7qP=)Pd%{>|KrA65zAXmTwY=NF0`)aOktyD!ipKB( z8AG|EkSq36B{C;*6@BJ4XT~xh z-70c}t{65nmH{@6Ba~CQ(^;C)q`zKeU#yZwqXU^+m^|V2yM57EPwX+apbKI(El#xNqs##_^ ziG*N68}PJ)>0)TwxDWRO9E~xnhES+&HOo3*S8C_hSWZG(wePI_0yB2aIt+^6g(*Z46dh68<%$eEPEPw*@ z*SJ~YeOT_3mxH*RQ2miQ*8}-?8&vdaNfXtRJ zmf%-I!`$!89FW6BGUUGb4NtR(53Dy=;JaXp13r1=HH@SDvwXe}Z?is8Y-50dDGiQc zU)MWm3ZHLNdHE83K3)kVQH)tJo+MSV?xj^72m{7?YSQP`y| zD!(7EV?f*jXDpTI)JO&HUrs<(1j+(wHX-*hI|QTyBzhHqrrdeQu+~gr;CyF#xOk%2 z#a2tY^x6*G^aUQ+0td3x&~_u?k|DI9yUr8T0@**14sP3RDsU!p4s2B1_*+3&Vo#rHybXf8@otu6Du)WofeZKY(Ye8Tb<#-LTGiw^HX3nZCH7Y4!;ee#B^9P> zUtAT(!wjvWenc8D^!PEVW@6Fy@DxQMg{gkAA|F4B5@7gwV6C4!)%-BRRx&`-0ecb$9vV=tC zz_N@Sq!8w5Vv2CAR_^yAe+IiAKw~{qD6j3Zpk`fORhG=f&p-0&*)9Kife1{whsBO| z6`J_-M+68aGnwL+*{Sj!-oM^FxE$8IN3d^zY469szCWy6cmJ+VERhR;*B%zuvsZuX zYAmd)*Z)3zSoh!m%jID`WdHYF-d*zkHw5$lx;GKq%=r<9a|!7u#(c;BDRnS}`rvq8 zudS<8_NWk%CVeR?045I#A3AGYd^fjKqytNNwNMB^OjhjYGDU#)V zobKH)sT6toX)O$jkM%Col8@ZJQV>E)DyhZ9kcrQ4uJe5cg~Z~HLI&435$3VMD&xyn zr4DJn_+I2b!Fm4fCjJg%m{d~NwM(iNf1kly*!-&@x=m2FmC{<>fNu6qttsaF?mv-y zcncyhHyx)`eH^i!vz2`gb1`4|+&ReIFG%4~#Yj*plG|k%{5Mhc)s0sOnU5;MZmt&u z?-c#}z`}iMG!bySm--EiN+}BU?&X;8$KsU8P^y13Bwl?{u$JAp*n1xN_d*>Lluhn> zPnOG9Uqnl#+`8r^K>Y90f*{Uxg-t<1uK^L5kj8FHfq9cTb}uBuEx!Zi-~o{!E(}|V zWkb=C7*Qhv<0bQCAuJ45gp+l-=KVh$Z?~1dJoo z%g~8?37N0jD);aI+oZYUfB8aOxcv-6r}V>T+nCo`;!Uz(Z4)kZVN`ioSObLP7ue%Q#Gk)LKERso;CT`b!f@S4NfpG}?2JPrwb;t@`*!ifG zFV9Hm>-EXk_e0{V-0Y#HwHW6o)WP=&a147c)oQ)Za3}p?>hX8au=?eBUZYCi(n}

s25UbM(LC?P*b@b}w?mK3Z9=e#h?}^u_NbuEGE=N!MYV9QpX- zi4gn#!kvuSj9b(Ny}Vyn^NaRgFShg*gx-}_dfi+^BSme!@9e{9#;H)_>GkhVq$Oe+ zx~S9H^H_6zlV9)nUb*UN)5miThC*M%+Nvwse8+|1KW#W%14Zhd$$ZJ57p1!9d;z6# ze*wQ)}{~9;q zW30CvX)soKpfkuNC#Dd*RZ_4nXt#k2@6Pp9VJCZqN%K$PWz*fj#6lho4^HonE0NkZ zk2{Hph{9M@Bg4Z}l^8`6KaZI&FD_;axTFF-IR4U~jti=dR-Ws%1YPfv^cjs%(Mrj)bj?45mQCCDsFT<7&vUOMX%q)t8~^s^E_;r z9hi4xU3wjGxDopOshHRpo)q~I z?eTs*^y|rNuE2MB`Z7+6ARpgk1%_jNFtMsoxUD#Job;QQHl}^tB+w{SQerOOEg2b{ zrgPu(91%?U$G+#-2u?7AOQQcobj;y5lx>DQ3AR@`4EiQp;o6VC92aZd*L1QdPk)!Z zpX8sAiu%t5KSjj8yOu*FxhvLfODglZR|z$%B_rj7FoHGMEA6e=@bK`^yZte@{E}Ta z^{5${nIA)2d(bdHWB5M_Ci&6x%KqItOm%)XWAtr|~1+-&2({GMD*z>#&`T zzNlv1Im|kFx9dHcCR0jDVxTmk#`?7XY_UoLj(4(X-E-rzc&9l?T<>lDu_r516_m?ksjMbu|)M!KeFw1{-sIW(4hl@uVyn|xY zEG$g3Icim9ki5wo8whs3ru}P|K7dpPv>ho@L>tFGEVUq0LkkK94`}Z8*z##C}z4Vfm9FmGz zgub;dhF&LB8Xkov4mFhnF6BXQ#6B4Xuo`(O8xz{liN61g?&?Du{1~!I5!Q`HKHb9h zcqGxTIsBA~@Zs@OgLOKOJ=y`H@h0EM-T?1pBK2UYrr07xC7;7?d4*t)wjA{>lc$Ra zvf>oR9IFr2og0re2CkfU& zvKX(9bt_Ivax*mSO{gH}cX<8g&FvR3CZ2d9Epx%hG(4tsy)&TNdY+|}-~}`zuM^ln zp)pbtGsI_EVvf!S>qZ+wd;V>;_HGaO@5(1KGcvmLNSrnpZ~2u)2sxggHi>kwx57>` zkfp_RCumg4*RZiY*5`&>i9<(RXNuAD>$R?nEjnGsFmEz0c(b%dPxU6&kE{o`eAije zB@>NO`oGzB^+8W#R~&4sv=8Gsl^YEq@3m5cr(dF5CB1N6O4l=~ zos(Kz@tYDcqq@!-xe%iLh~Sn7?>X*b!OX(T4HBv(R;Bbg2EOq}`1dF+9B+w6mC}-_ z7$wQ!KGRBKIAXKjwhQ_Pgpm!*mp+X^7HiNF&!Kn>mw>A zP3oBEcRlDFM0~8DVskrWQd8^dSn;K&L+rQcIPG9II^*I%Hw=Y%%kNj)-RszX3#PL} zF(qdDNlrr_F2|D#G-+kY(?5FjXlQ!-<;x!Jo!PokW|fk+ZNsbl_Ljof9#7VAC1LCd zarH*iI{0~-s`rda_2=6`%W9M2g4WJZ`py37*+cbGbF_Gp(`uh3et;OYZjZpte7R?^ zvz4f+Y=|Tp(cCn8ooZIEQ|N-7=^|V?TF;m<8Mj3#5xaw}$rgW@;c(4FNA@GL+OOS9 zElybk;4DuQZ~ zOvPd|i`zHi@|}*{kPJ!DX`L)eoEL6ocpe5N51f7H=877t)HB(5teuS>0#+b-rh0JhnPHsQ1T9>BQ!*ZNLjQWw zfVYk98W4ZDu0KJ4%kRU_SMfsvTmmb$e7;S(rC{wPCL|<)Ni970)j9yhWIk5K8jy~~RiH*daFVt(v2 zB_=J6d(%lE4&W|`Ot|FnQ@=5=K@)I;)~{2cFFXvC-%dDtiMU%F3Nz7kb$p%3I$B2= z%zsic7g%XX5u4$0L5n^hSJf+~Uv4Ml(X_7`8*qR9T5{q2boff8;&o}RPoJ9yjf@Y* z(wi@)F58+)?d>>`p#~-$yd~mzhet&XOfT!S%g?ruQ0Z654($C-rx6Mpdeoy%e$(qi z?@`d&Ro;_L&*0H?zF3+Z`Qn*{|eY+2PSa_ZZZvIb(GxFo;2qO13(H{OqBZdxsLb_ zbFrySM{qgH?2&lY>p3k_vYjn73hPoz5JrR+ypQwM2C^||Z*}*`HPFPUTmkFdrKz3k z!PFkd92zwuG~9!N)5#UEVq1E{#9~jf4x#D@j>?{*`Seb*l0mYDS7565WHEiRxOsUO z8THQBo6#(I@{2FM7`er+(Z^8g6#1wJAvDteqrJBZi?WN`M-dbQK?wm#Uql)PNu^a3 zC8d#Wq)WO)UP?+tIz~Xcq#0lsQo6glW2j+(VVJ$}`~KIp5BJgD2m7514;Yw7p7pHt z%lmiVGi%We+^CCv&rfjZT}Srk7Y&BFZn&Quk^v!VutB+V=91xZ$12>ugK5$|zp2X? zF8(joA5nGPICmPYNj>IMJINO-OzqU=3KERf^VD>JoJazlecKB#{(&6m|= zeA#`5#$XwJDj!N}5ZFhJJVD0JF-VA*YD)c@DW*<2o?BiA!Gwv+ zjVXGi&L}7*OkT-XJosi!F~v~kpt1k$FrU8ogP8D5$J>}zzL?foVgG&cKtd=#2yQJ> z#l5ogw`RTog&a+_9-yT_JDr*oce3#6UMipx1mC*ufd_oMu?nr z{EB?)_OGdn$uXc~oyM-9Py1j)RSo9GCFuv1U8q zvLoi}r@Z(7Ff&0%{a~akk*>nYkj%C8pfA$#2EA$BGs@%+4?d{4vgBGcuG2I4ZOV6h zc)fx~g=C0~e5eZA$Xe98=JxCp5%ZUhqta3Sq1CvV+cjVI7)r!m$x0u}Z%X51)o8r? z63W5h!}pgmTLmL3^C6bdX=+|P<5xb8RjB{Kl2K7{T)SP|-_;kX3k_!U zF+aM*GTP472ZoGTp+LM;Z8K?AJ*|_J+^?Qm(BNS7Wgdu*7{>js=}C>Ny=zPA#saY{ z)h%>AYYvNf`?{-N^WxJEtwHg{b2nn>R+=5{^eiX5Vn0mlaTiS3Wk%RZZ(Lb?{xPHR z_YKN?iiawpFSvf(e)tb*^n2gLFyh6mIq$e`9%)jCoAgETdR2UDi1?WN^;|ND!LR-; z3j(+_Ys1d#XqSXYLZwe219jeU#YDFR16dAT0PF=BQs=4@lQ!J57rZ$cJ+F*iihoR@ zm;uX&=w!6`v@S7;`kTnQJ)>(f z{DukQ9hR6wAnFRdhSz#^L&3T?H3tGIjvfAF1Fzl6$Vk|8^bI`2;@SacUcLcx<#%0E z!}N8N%U)f6g|RY{WxknPh}t45i(*+~#P+QlGD|sJufO|f-XT>EnQ)v|W{Ni+(adev zzyFRc;_`a5Y=VnUnXA9mlHdw{ML*5*;qKFr^fdC7@<2wu@ag*H5mPH-3E`efDQG+t zLUAj!!@RtV{OM!BiYdp8obl-wmu`);v&gY=dL;w={|ZmOG9lqP1U;nXi$D}txhi`+ zCykB!F;zGQa92!+?qZ{(R5jh^85^a>)^VJm^}9555qPvNdAi_Z_wP9z?Hh@0^LVeL zqpG8mIldhxCwq8A1aL+Z_AJ>eD>4nIZSxoBo40+RUnPh?r@S4k2jd_2|6mR#z!IOK zS6R73YcEYPUh1>Zo{zC9yL%l{NE^3;!v{f6tc=;P<|Zx3OxE((k^Hb3JZi-e5?Q9K z-}~Di$N~~3qUT3REb693ckZ2kk!JpJ+ZjoVxS3?ZuiYO#co9$ko4@Ptk+Al^1k-^- z+o-?#O&11#66uDgrkd%k1s7rI8U;@T1!J!m6C)X;(!6NOfqe9ObzCl+q^ZY8;oZzHJ+h14L478ZXRl1(yJQV_ zp!0$$BMnY){+i=WE1UCb?T!4!qfCw1#XqS!)^rN}ZVFp5!}daD?306Ac9%MuYUdPP z?MOY6n&$Wep)}?yPsMNVDKEKe;_A!t1Wr?)j;DzpqY@_rKxfP`UTbg@HB;LCfI%J* zBF1L{P8rwRM{MUIZVCWh!kxSv@n-n&0q4XO5oGju&-+2;t4F=;>btwmFJo&B2&{kA zt&68cKjBi(SMKkgNNhFnS>=rK#Z1qiom3-Km7fk7k>9!w_{$o(FHHd7vko~Zpp_88 zZ)WxtcENV{4x!SipUw&)sb}m;E;PNOE8CKk`r6#K$ z)xNd@{-m;Dg#Vzy)J~~@vyg*7!nk-n_a5v*PQ}E1!+Ygrq9#cA`=5Yd2`c9JMf{s= z);)>i-%W-g-s*tq{?o9~o{U{=0zeWum8-eUIdO^#1*tZ;AGlriyV=(m&6;wO-wCv` zY9@M7b}+u^0C?(N>+`>QEfZSwAta=LHsZ{xY4tKZT;BBuku^BUkEtT|tP#yQr3J&k zHHx)6>4~m?0h|!F7xQ0@Q~*(rimGOz?!)I#;*F?bx~_TO9}k}ZeUqx$dLKZ&5RVB0 z)x`3q2`Plp+$+9lzO5BG3qQM~yZh>SAK{F|W%MmW%%zUKxvbNXlvH((GFu;|jU;i9 z!9!-<#*lZylg%LL>(h>w@4xjhlji+F{?at>K4g&Z_Tr70^|RtIF1BEHCGIW#*U4W@ zeCA`{$w7Q!DB0h|vF+#$Bm&Gd{c-USmJBe-i}Xc8wY9YgZ{GBgDACAVrHo|G0Q3UI z#rw_=?eU{d(@TQPqMbQMyBlQ z+FgQv_kXYeCng41E6^@qX#A;?rCV#7H%P5-TzF`6>T#=u*Wmn6bK=J7FhAer$@sd7 z7041398F|q!z=4fCacmp=JEyN<{xf|KKoJoBs4@th=x!}8|Ke=&27MSFppjBzVg)A zuWn-eL2k9lWWDIw>6zM{mx)qrTGyBT zGX2|I=9$)cPH!60T>va>3T7}yjI9GyhhBc#s1?0i!h0}ybLG${en%T6^z;;huUsMt z%#Pu!SK?k=(Qj*ZD<%|5uF8qE177=g{2TswZ)i>Hc#m1=t_8HbEBItw`Tp1aY#Y8$ zaN!}#QOw{^^M)_fLqFJn&2se_V65c*Wm&{y65MHl5*D9t<4)b9J-MO#B3-xfRzd}B z1igK7=G^yM%av<&Qmxmqj~S;ho8Pjv-raptGCZBEr@Y;@O__VQTTq(fm{4Zd|3OUN z2*1jh9{X+y>W#Ulx<8Yd&ncXsomIJig2tPN^p4pwmxIKvTK=ZN=*At8kJ8X=0jUTu zy&d|dp#sR`01QPG*sbfSdeQu<9{?Plo4Z#e6-3q!ubu&?=&U+yT>|gg-IbLldeCTvkgS!FOM_SyxSBA_NaZ}`o zVPR!;hMJdZ0hUO3SNW9&mNfJITR?}Vhje>OcW*f4qv6kan>{dTxOR>TXfgy6mq3~z z{a3{g`cdc7^z@>l2u#IVc6MZ>D_jvYs+bt}!NejQ(^m|{%^fZ9{XaK-1C$e#cL^o2 z$1x`%_kfRee+QvtT@UAf)4cUiE7loPW54NKfp9p72BdeQ%01zri#9U8!?=|+ASPG( z##Hy=9^n@Dqr;5L)GPn@9gN1+AJt7eg8C+E8mypg{UOxqX(=H;o;xX&f(`qI`5Sd> z(%IJ@9eGf&Xa!a3ElHc(H9YF<(jZUsiD#0_=281f@$y5yTD4THhjp1zXKq80KY3h7 zvE%%2gI{DEWv1bu2O%1ApN!u$hOFSfj^na*R@qu(cKzwMUWbhq71^ZBn{-?s6Uiy} zNlEjX#eX0g(l)o@Bw*mVOtF;*(d_2oriCcQY;}*m%#$jlk8CsL4&%J!s{k53R1wY2T#tL)Nn031njL%vIxn>nqvYm$WQWqxrz@ zK%LRKN?Z=(gVv|EYk_eSY8gUz8LO_8V|^!6(UYLqBFfujU{ZYYi;YlJJ2{XypZ#R~ z@`!8o;ZTOXS$TV`WWzI8(_3MryluE2j}^$s2M0drY|CXbZAtH|K9|aMvzpzKD-TWZmN=N5J&Q5U$mDme%hEYhwf@|IM zl(t2#YFj#GU((bA~rR>BC88WY0j$q+4&} z`7@ybgvJ^4>94ay@;gCbN_fRvA~xiB)e1B%G}qti?_4@GYA?T?G<{FS#xyRA79|K^ zErK)Ni`?ZPx$zR*xa{Ol;o`B^iuNupUbX1ETGn)BYN4KKUqS?4cWp>9W>jf<770eK zxOlz}3h%B=H|!W&*qIdF*h#3;Z)P8j2?;3_j9iq}`9l&@`@ZR7CP$ z3^DuVb@!@DaPYT%m{3_f@Tw#>=K{KoBlB1r{zD~UdEsSqL!m0z*Yox-e2=fvzsQ2{ zSIW=z#M2zx_oa=mGt0$(tz^3My{>-FZ(tJ!z!m#(u4e_SVVs7#~ z-wV3QkB$|fqsVf7v;Gmwr){2O%8d`g>Bc0vjX&;72menm(Wz~2!iTtjG~wR*2Gz+_ zG7U!QNS*a_>;E)24~*z*WFbyDS;fODZmZVC929rXE}UKW1@QhND5UCZ3e(g7iPz$J$>^;n$NIne_O;$Cb_KlZ~eP-a@+QnhzkL|vvd6W&oEdi1^D}W zeDy6lgzl>)|Etm_j~XaXi8JhNXE=I&-E)Cfl2$G~_^NBZlwJ2{UazIylMByz;u-Cy zzpZPj45_Q;>i?(M4kdpHiaQ6YS1hS`jW&%scx&tfHv_Ky-}~iaH_oN-{-;x3{7?N2 z!!&&OJaRqf(bY#jPk#Q}en+2qUr+#`J=pNH`;?zO?i}kw{s+LK`|7IYuJH9W>(#@? z(|rs;FuKVUa?*Cy$<<|7Z{aP4^lx-q{B%3epuGB4itgZ{&l%Bili|SX%j~NK`ux0a z)#*mSi@C4MkOA`O;mw8eXIH<8cX>eP=|Oz#i(pLrUu;6oaMKZ`d_AEjQ`z+Hgy7!` zuKkjFWLQ1z!Se%oRSB~Z;_MIn3kTS5G%pW&`A-_rswlW@`?BM+)61p5KjF=!BdKd& zUPR0Qh|blev<^TE7Jwh_#&@^j3~A%uv#GXb8Ai1~CJU8jQr7)nR1uF|^|V!GYr%2N z4Ns7Q&H&~ffW#>Hdr3Ui6(`tI!Ww%6sC9@j+-vzJ%@k@ve|1$n<7I~lTOl3q?fdIe zO49m3hyfkiM&|!Wg5dn`PGRA^e@m+k+A7LZoI$vSms!wY`q%F?A^q`f zcd~K)2sR7;_6K(fm-XU5mOmYEzK)+R4Wtg+n4;gZQQW!yGRSC2kNxUzO;`qZ#Y=tb zIzGTutsi;78vynODXTYDNOA>I02mB2Ev>(c_5UM;(toHeUgdgDURzVXM3uZBoD_VC zx&Z9dY7C+dfXl-7w!DUy26`ffyc_7VdI=~vYIS-%Im3$%HM4u}n%ok{&n?-_&i*vp z_}JA7J^qkb7{5J2mZi%^NeWP2u6Pc%w*v7c5aWwZ#M5+Z|H$Qd_hu>Sf z)pH7q|L?|5{fof@6of^CphW7f37XE{;5eCAYIDUcF8%{T6XaG8mqIPOA9iS_GOS!9 zF7G?>K`{wlquFF{z-~KF1)a$BaVNXAra^rHdELKvkC~!7KJq^|VRYk>znD6t*>gio@Vpp9!X6#A;(>MlT#CWM!5NY5>$pFp`40@6Q3|O8#OMLf( zJ6Qme75eAl{6``5$;t7=ZYVnbv8=X-Q5(T@7jp88vH;$<{g>%onkQ*zn47b)sDt7z zW@h=Hn$`lFo128MKG}j1CGaYw3~N~ok!u5JBiTGPs|xK@#ggI841F3px{a-^vJXX$ zc@q?7JP^IJ4f;Ug;z+mG0AKq78!QuvMbgr<<}d3--+uR53KG-FS6-&TqPp@fxp!KhQ3Asi=N3F!RAjamr;LZr?;tdj+5S{P5Fd z1Qv?jYMYdFbFI309vDsA4Su_#fUZ=N5mh8XE&LpYH0G zOB#OIJyeur_%$Jb^STu%aaOV(C3a+0zwP*>TzCKwG0oIpbXb;v>*%GXQfm|7IR~la z$@h1JgrhVHDzjjgV{;qd<<)4yd!?_>Gm>*oiZ7+({v^V|Mnuvl};N zqJ)x*;6P(FzN;iPH^L@cy* zl9qLz;C-&4rlDhID$ruP?p{VSjEbP4zwqzRJfc8;I^ooAKTKdk(^L zkJR^{+RG*Xyrsqa%sF7r!b-J1R`2|1?m^-We+gkoRPv4KnUQ}1Y_ZYl8J(^qT(@|^ zc{aIM(ubnl@ETq*ho%0QjTV}v?+VKmtCL;^hZ8@x#lvHo+;y!LNYe)dsPz)TEfT|l zJPpWfmwCUB*>czL5@`82zV5;U#MP;m|Kd8cR6gjEF{D}wB|jyi#53e780{+Z$`qy! zA_R4=`JM;yx=DWh&bS~HfO)dmU1mQ(c}0qx2Q8^zdr^OfC1a-E`=k-{zV&TFOcVgp zvHVXMF^N}=Nm`wA-?t(qu`Adm@AJFmsL=K$E#Dc>4Il;@quTsxecQ_V_na7B8mtdyAdz3!8dr~!~aq>)*RfZ)-!He`fr2-sKv0X+YJckG^+-VDVqlSVWDg{l9 z?PZv-sRAdtX5<>)qf&sjp0E)*NvI1`%-nA9VkDf#!)uK+D#q;jfR-qUzkbnRf;{NV z!;4~Z0F27awwGqfmpBqHw46+t*eypjQ|d?~c^_|qreYy7BC&hO<-P|6%=wjFb`#halHh=Kpma}`+OoJH zvI!I2qEHw6ZL2K-qA4~8VRd~1aKdC2Ng(Qz!^15WgIC}^H=MkpB5A0!>V-g}hPrQm z9J?mCuV!GunT8en$wzK42@cRgdIKvbZG^VNxiaqJ@vcu6YS_VO_Zn!*%cjRo9Kmkg zY~?kpE?F;^(kJjy`5rC4f!tm$*98G`P+gc4dNd){2I1Q^3d$+U?hTcPR2!gpv^KKDs=ki-0IR;2s$9dwI)BoqYL+n+p74Bg!) z){hP}c<}C%w(!2mRA!29tz+U92f_RPKCf5Lte(j?gzu)n=q)_FH;YGvqN9^){4h@y9c59lhuK;O_ z&-3=B+EdfhpwBgPMaGlgYxOdH|7H~K_fNyL?$z^Mdp}hjRdOUvlK?dX!_ej@X;1|5 z@-opif8@5iWLZSPoK_qcd7fWe97i(!JC>AJJAg-!6JC=c@WjM(>^**s`D(GA_etCA z#g8_FpX)+`6~_E|iSgf4n%mH&*YTSsG;!w_2If_Y(jc1Wi7#)DnN{UtXWxvLX;9Nu zA@dmeks@Y4cR@@mq@j`Kv)Atj5`tlk@#~)g*Lu6VA#4dU(oV1o&}EeQ38k&^+El9w z@74Ywq%i8=YVwfI7uTjoyuQt(bW-6qu0G~{z9$o=p>6|rPJUSwu8G1UqlXG>fuu^F z#RQ7NV10q=K<`zL4^SNSF!*gJ8@R!A$-PZvWw&tH%X`P?(T+F#r9Oi)>?1Mr!g}w6 zdw$0;P|34@r+3rlL|DIZ3IJ)AsNqe(O(Z=sG(!hHZ~El?jLsKf@HePPl&5Tw^z~6p z;+W(mcL|v67cup?^t*f}#(UVKo24B5@(gh}zE7n_P0pHEtmX(z?ySmM_tnN5cWh<*Kz`J?4Q;rC8^RalG+ zWj#ztZVudQo|e%Lfg5wzpm-FW^<%X^PYR;RHbIa>K6~W-`$Lh5<~e|j?KpowsX75d z>+U0*l*vN2fbY~OYJL)RQmkiR-VTuOS+FxV1ZFog%Gaf>D^|MV(`4C?Y8Al3wX8Az z0jOu$146BX;v4e(Am=3XguQ%0KoH|oSIX-}$Z_L#qfw>7vkz?y2GzFMDO&pleU<#! z@%j3uZ4~_!mYp-R|(f$>Ym^815|Db||=iM7GL&kn#osINW-* zT+g4sW+T%M3I<#Vz@zE!83QtfQd3KF^K5wz@K|SO^}yIkIGs+VX{QPRgPL}Bd_t-h zjJwa+CC_SraqC#?GCM5c$yJB*f}z;=^-ueQ?jwH8W~+)Ry3moIr1Eh?45$L_pB<0jdk{RLh(u@alh38F4d_1~ZEZ6OfPAc**!n%0#rMJ7S3|@10$yXPS(lKrVYK;L00zCm8P$?$i2!`@(fgOJ~42O~@&xw@jFLJT_s zf$ctL^%A#G>6MdaiP>BXW(-Xt_MWz_27puCDom0Xh@xCi(tLFPcjc1|KpFm=Z$PO& zH2YAeah&+cj13(R0Q)+bF~$&!&)jtK5~Ex$VH zL0@hMa}dVPmGMt77QNEgYhlEVB0`=R?{(?<`M^uM<)tT&ocW#jVMi7u&~wvq2__Dms{8(z zNo~`%aXBs;j=iifXUZrqIO^de^&E*PO7HA z)haW+hVdf=gKG~U3?E7|^UO!c+b+{2gnG%9C(8n(AvXy8*Do=XxrPeTDD_G()WmRo zN|X# z@~Kp<*|+9-227X4!q3fpdM(%75;4)tuoB;s{I=3aacNhmTlF4%V~CL!G2gEgdOx|} zXYU9QmPi9)dlI_S;{l7CKE5~rlCq!l2-9K$L+j{SbR&QNh2+T+Kk!DytOgY(k3Qocv%Ml{4XG?jPiqgx8e!bI2cGY8#~>k_zj$qW0QURr1JwgFjQ@*2^6wrnZLxWXpUKg>MoZz~SQ zxRLNvA<_@QTz;of7I8&7$_@EUf}B1(<6d$9JZCR>lmjn~4YBIifM}~X!AI2SNy?1# zOl{nEk()ZDMyL$+2Tpmw9T_Njw+e2@@@L+6sk5fJO@Wt z-Xp{iUP$1!{k%5|aEG>)ijOHm*Ww>&KqZu<^@>s-dVJWa)80yk$+Wvz6oAjBiIbdS zi-@^*98cZ&Oz}t`etEF(&y;d)ZPeo+(xF)Ouht&E+DOd zzF72wMtIsQD4_Te*xoG9s#@K?b_NU$>Fw)ZJdW0(A`juL!R}#{bCf4=% zLZR4-Un|P5m==?ougvB@!ZVD?3kf;eyk3Rc@HdYr?nn2pd#w){^A)}dmN1E@dvNP| z7$x@|D10R9ar9fJ_OI?@X*p@V{`}0s?-+Xv`=9B`Pewp9*CqVjK z?8G2E7RUQtgsNrWnIDyJdkxb6H{V7@OJ-X{^^mTN z)w5=tckKtc(ZF3VzchDLb7@tDaE~vaXfb6U={HH=DH7M|oqLt)}C>v-)yl{a_?>0t;~iVFb4$1?&RRVk&-rd4)6X1cKVg)!7G37`>sjT_b_5CDDJ48 zvmg>`CK?->TY7G6f@(um+cX$Wd-6o(S8SaTg>ChZk||?hQ{TVxF_c~0j zU9q2ATi0`=g+O}6wU)4l;E!6&)3)3}>!MebIlWImGQ5?2>RR=wmX3#M$`jqoSbrSp z(lPX2U9-XSHmQq1AcCZHdl#=qAPwJ#m)cbH+jabFBAXW6MQ^$ps3ZOuT%d8fdwf~4 zZ45yAaCZuI0&Kpbw06P7q08+`PzgcQgS(H>T>!C64zLJ=L4NV+ zP3fg2Z-NX1jL1aI6swY-9A0^FZTibPGy3u@JkrYQN`*3>LG#?dEBG{dsipsOKP07b z<3_^tb^I6l%D(!_mt%ERf}=ud;-B&tz3DMStaT@yrezOkHJzy-x}^!k$AUTi^A~42 ztz?cq>fD&24E3H85pR#>{YzGt@lM6j2^H=9$jJC73Cl0vf3yBc** zN2Twof_=4;(;kvrSH#KQHlgbk9diApk)5*d=FklpG<|+aKFXusIPYIfT8!Q|{*#u) zDblkdmp2CjD?u0&{=IUqgeMv2;Sd>SI+z&(;5M$XkYi&Sd*N>~KUCSAjW=9IK*i6F z>g)4Pz2|PC&CyqgcusP9WxBZ$d6TK5+sFhy zeB3|ch2g(yJe+xKm&lOCR<3qRkWJZx)#l0jCv!lr;5IBSVbQ>jfT+@w*ZbL4f zD?xTs!mg90f#JYIe9?>`qxPs}G(_u8T!D_h<2A2=!I3x8l@3Dyw;|{H1Au$PYKY z$`hu|2`@Xe0h4u^gK7=#fP2Ex$S7JRkNFBmd<8^HJKaQ($omq=De71gxuwL$&JGSf z-7_O@UkJJvSc+aV?-kY?88_;aFU@xT=6y&s8?#9A;NV!Ums zbiPu>mqFgGmX(=>aYUuCWCZ1lFdcf-OaB_Q=7(@!kkOuH!2)(p)WzQC{@583-igyv zP9aUD(Ov52xMg2FqdWawUaOdqe;OoMCOI>`DXo**MI z3!mMqqwjH+l~C{r(3zBsce_sffarU#bS##RgKo?NPK~nhV^rXYtG4f`SeEl7$VjXix(hSt{7WcqME<1bPlNkccHO)n5J8)6DXvb7?PkM%-0}D|Jwm zyhV^noYfm*o15<(AA=ZHLRtP*!eiqjJWhco-YwCc%`^Q_r=T0o5VcydoE^er2i`N{&(QDtQHG?$Y9oR8(VV%24*L1$;? z38#Lg6)HyQ5>sU>>})}8%*TKA8ZR@cm7AkZ!p-cXa~>fZXJN)2Iqh zu3>i;u2rGs*eK?F`r$JkK}LHG>-w&}j5#e$y^*OlM}7ahbbALZFLg)X6E)=PWp-%> zR|l5q*xHMu^G%Ku$V;Znal7I(QOYKk(#Faw#VXRK@`71rSqi1Hz=s7g{X=@@)6nAe zm~x9akOV2-!BhHk&>D7wDW^EM{$H#)U|KkVH;CRp$Sp6eUA#DuJ#k;nR;D$VajB)! z3@;o>)YQEXqtSWM>3xu(ezvIH@;@OMkA?f&l$Yr%Inp8iEsO3)5#z`@+%>>+q9EzB z)Cn?^Pv}qGW@XLIphY0YRJ+_)2RIl-M5aPN_NU!jr=lcNe$iCVh&^R(kD})X@pz>t z;FiqE4ia69Vi4`}@wIPlW}iP@tL}%E+_{cFGy%L_@M1HbD816)|$UCkIH z6sTC>F1?0_K9N72T-!w=aqc)7Fmv}$1{hBOfZf94V)KwLO0J%+J2;=&I(vw)nJcgh ze{JReB*B{{&@JtE-+q?eaT=R*C#d5xX*sLS@x2He$|54pW)4*|en?j=;WKA<``(3~ zXUiQpyU43}o(~Q?nbFt2tro<~`{cP~X~Pc2ims}NAtd!^M>n1E`m&cy`I4H$?v|`m zAY?2}_tSoBI%Es2TaA!}%S%%!s-w`y+}i5@#J&^N5$$8RQ!*5n2-Rz_dbd)?=foe# zWYoy0FI)5Tlc|L+2zw0pN=ilQJM4WekF#M8#DDYRpX(YuAvDkN%6kD~)v{u0ciN5j zE(nur;1OC)hWmi$)o7W8G!+Oprs~-vCp?H+cmdCv$#})&(W0H*-Mgff0>W-CF4;L2 z_oD|t>LPptX6+DG0Gtc=I=MyNlD@s3q4g+7&<5#4gP67GU zNp6%vr1E#%WFmB9KQ4Jf1Qe`Y9!1;K+ZM?4Oe3rf*r@NG5~#<&Ns#8ysdd=a6OIxG z#hD_(jT$44*Q-y4RkC7}$L^jGr-(SDgwW(~O}wj4sT7|3?cO_N$sST}c*e9nu-_mo z!JIMI$8fTJomG$%yC);bhmDu=%%LuM#dlKt~}ZcoS&B)l@3~O-thuC5_Ql56k;8he!ZI( zuzlAZ!12+aFF(RoK3x1A?X-X;O_FP=f3`o%p9lE6#xny%BFx`}EQeaJr*;jr*2d)# zWo1dz2fUoBNWZN>x88X$9GZGMQ49}@skQ7pR9jCudZ%Afpt?SSD=FMsnML^F=1a=U z%g=Xa0Xr6qsF-JVr74r2m8F(Y)0UXvMN(4I9Ht39e;JvI!>r&gOwm#1T_wA1gB9kz z+-^1q3>I0tTYLm{ngV=fUl?KLCAcx~ zgx0fvcJTZBvyC!^b)D!%}*4C9Knq7{;ks+@%Vu9iydQrP=MryXNORMpI zt|R=ew?#xmgoy9CxwxiEIG^u#bOctjUV*9UW(GjLJWuV7%st#iXXZK$1H&GYF##ai zA3pyC!?}%5O^FCpl&W#`s;{xIvb47=>31EdXQ?0u2Hsm+Z-Y^Uj*fI;zopS+w-1tY z8EjzU9CRBEC=^UgSpWR#D`#!_%85A;T8IiEny#?~de6cSUOxqb;|)F#{bTGpO2-c; z?B;#yQy@a+9~a-Px;m*^E+;2vyK9@}0_Ua@b=+C>JDp0i@YSVgE5Tj{&wJqD1rmcj z$9ai|^2%Ip@t#)Yv6z`n{?*PyAd?_tA!F}1Z%AGo=6?yktf4X`dFCj&tpg0F8&h#&QN`%G51;w#{ z6z*zGDmuU?|our9d*?M}Oe?@e5D`DRbs0s+8j$`{~ zyH}ejsVGV6J;|(Gs7}CyAizn0SDw%qAUo#StMCzC_ zs;jHB+KiU*G>ZZAT{Ymlo#2EPYc4bvGZqd>>q6q<>W)T}S0dPSJMI(w;Vn!p0^cFh0oIvq+sSQ8Ix-8o!D$feodGb7lijadcBs z;)W1A^lkti-aU!B`qPyg&~FVC{XQm|iw{5YG<9j1+tTl%aer<~oJJdzAjJl1;^Lv0 zKgHVmzg^|PvH&VPF~_CTg@vFDHV|?v#&%cMi!@dmtu9nu%}1m;*RRGVCZ~CvY|r~n z%lNJ;^tTD_%^7(1_qokg9(So|DxoxrObDuy}as z8WQ|K7gYoO^jAy27-D^~UGsnzUpM$f?BaCMBCQ1LvVH#;>`8{_YCeNNPh6}X#>0Yt-C!TBWu7XrO~B0G#JM5bk(Sudoa@)QO^k zVqbs%xbNN16hM?h)UK}R{CuD(ASQ;qz&8}OnW(u&RW*w~QOEV+jR)vKaXHY-@x5Bz zS_!v}uncN?aa~^&x=na~$Mnu;q7P>&T=CtRnZYGP>S>oluO8Q-b+hbA9EidGTi=9; ztCbXtbAyk$pIO|@hlteG+D-ae)3aXtXj*N9s4OoiIQLwQIpXlx;Wwz-CtNt>f=Heu zLdFlyQ6HRCD}Vp~&5IbQw$oFl7!}{_j!eRLhxh7K*-TaBou4;eVq;=rG*M3FCNaQn z+hH5UHBlUR(=m}>jH$p_cScD;@_ z?R^gYJ(ULWt}fMj>aLVG0?G*#ZM81jGdVY@X{Ksaj==E^1f%F;jbXSmcoBL|eM(Gg zc^m&1HCW5^C|^6E0y!5T@aD?6J%2hl>|C{pIX}O%z3IO_0g_M+jj0q7m#sFc6Q0ov zNcd`2mQR!q?vLC2Xu0FhKk$55O0LNaYcG;C`pJ4 z&$4mK(mVmrSW8=55B-fKmQtqZzgQMVpgM2T7|mY5Xn4S1 zmXMUBJqZOSP6Z$X>5GbXkz{=ZA z5WE26gy)!>gkvQo66_VmHa0u^9qE8N$+LB<`Mk=m9$9j^-#35O=6Mg_;lZxQ=>aR_ z=@tl(Pz)vAlHvlX_-;Eq!OrkI!4d3aoLWab|<3TWn4IY5eYmE|l(v9SD! zqI*tuuG8L&^zIh-I}sK2Ma`lZt{cW)orzfkkJEkr{&BBwa%AMk>R^}9f}6Z4d~w0Z z&BN2z(~}}04x}9ufo3BJ(w3H%I7{kP=IQ4@Z+9gLS_AU!ptZHNv9YnLlM}%DU1=>^ zS6d6ty5D6lt0M5-I}?HqyeEIEcir0=u~XB&$awDNYfHd5Vo>(DeJJDe^PL9ID5rU8JSnvWxI$xu7mAszbtMus@3~LSy7Z()RZ~q|{ zwP%=cG?}kb$XaabYifv`+Z*ePq}5I;>c3`X>Twnu*mgF_Z;`Foo0gEmApZ31FggZ9 zLhrXHwJf>o8CskQMl?Qef2$h@{Co0%(N>E01pw7IT?fGX>*N6N{@3^ViBi<_)EbUfR1Hp-0wm{-bV0exJvBRS z?$Wa#Z$GJe4tA7mfT3bnGRartK%7NO4jfCpDqSJ`$aQs@5iw$*RJ=>hh|_}S;JMSg zZTSB=EMNEK+ORZ@m0itFwJ$A2sQ>&mI+UU|6ejE7|F-~0E$P>{J&He?_MiP7r!+8@_zyUytYCB literal 0 HcmV?d00001 diff --git a/fastlane/metadata/android/de-DE/images/phoneScreenshots/6.png b/fastlane/metadata/android/de-DE/images/phoneScreenshots/6.png new file mode 100644 index 0000000000000000000000000000000000000000..098f9e2bc4f83037c03f939b97a695f6aa5c56d1 GIT binary patch literal 102387 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

B1 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 literal 0 HcmV?d00001 diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png new file mode 100644 index 0000000000000000000000000000000000000000..e639635ca10920bde8ef71656b4165c45a60f34a GIT binary patch literal 102115 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 literal 0 HcmV?d00001 diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png new file mode 100644 index 0000000000000000000000000000000000000000..098f9e2bc4f83037c03f939b97a695f6aa5c56d1 GIT binary patch literal 102387 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

B1 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 literal 0 HcmV?d00001 From 806194f4e8f9878ee6c3818a7b32d4e0c49b293a Mon Sep 17 00:00:00 2001 From: inventory69 Date: Fri, 16 Jan 2026 22:11:03 +0100 Subject: [PATCH 11/12] chore(v1.5.0): update F-Droid metadata and descriptions - Add v1.5.0 build entry (commit placeholder for post-merge update) - Update full_description.txt: clarify WiFi sync works with any network - CurrentVersion: 1.5.0, CurrentVersionCode: 13 --- fastlane/metadata/android/de-DE/full_description.txt | 1 + fastlane/metadata/android/en-US/full_description.txt | 1 + metadata/dev.dettmer.simplenotes.yml | 10 +++++----- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/fastlane/metadata/android/de-DE/full_description.txt b/fastlane/metadata/android/de-DE/full_description.txt index d2531a3..b06d331 100644 --- a/fastlane/metadata/android/de-DE/full_description.txt +++ b/fastlane/metadata/android/de-DE/full_description.txt @@ -38,6 +38,7 @@ MULTI-DEVICE SYNC: SYNCHRONISATION: • Unterstützt alle WebDAV-Server (Nextcloud, ownCloud, etc.) +• Automatische WiFi-Sync: Synchronisiert automatisch wenn du ein beliebiges WLAN betrittst (wenn Server erreichbar ist) • Konfigurierbares Interval: 15, 30 oder 60 Minuten • Optimierte Performance: überspringt unveränderte Dateien (~2-3s Sync-Zeit) • E-Tag Caching für 20x schnellere "keine Änderungen" Checks diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index 8c97b85..1871db1 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -38,6 +38,7 @@ MULTI-DEVICE SYNC: SYNCHRONIZATION: • Supports all WebDAV servers (Nextcloud, ownCloud, etc.) +• Automatic WiFi sync: synchronizes whenever you join any WiFi network (if server is reachable) • Configurable interval: 15, 30, or 60 minutes • Optimized performance: skips unchanged files (~2-3s sync time) • E-Tag caching for 20x faster "no changes" checks diff --git a/metadata/dev.dettmer.simplenotes.yml b/metadata/dev.dettmer.simplenotes.yml index bf9cab7..bd97ecb 100644 --- a/metadata/dev.dettmer.simplenotes.yml +++ b/metadata/dev.dettmer.simplenotes.yml @@ -15,9 +15,9 @@ Repo: https://github.com/inventory69/simple-notes-sync.git Binaries: https://github.com/inventory69/simple-notes-sync/releases/download/v%v/simple-notes-sync-v%v-fdroid.apk Builds: - - versionName: 1.4.1 - versionCode: 12 - commit: 7128c25bd519861ca136e4be9b67ce280ef184bf + - versionName: 1.5.0 + versionCode: 13 + commit: PLACEHOLDER_UPDATE_AFTER_MERGE subdir: android/app gradle: - fdroid @@ -26,5 +26,5 @@ AllowedAPKSigningKeys: 42a1c613bbc673045af3dc8191bf9cb6456ee44c7dce40c7cfb566fac AutoUpdateMode: Version UpdateCheckMode: Tags -CurrentVersion: 1.4.1 -CurrentVersionCode: 12 +CurrentVersion: 1.5.0 +CurrentVersionCode: 13 From 0c8f21ef5822a08e108ccc5c6e7e3703d120d077 Mon Sep 17 00:00:00 2001 From: inventory69 Date: Fri, 16 Jan 2026 22:15:57 +0100 Subject: [PATCH 12/12] chore(v1.5.0): update F-Droid changelogs with final features --- fastlane/metadata/android/de-DE/changelogs/13.txt | 3 ++- fastlane/metadata/android/en-US/changelogs/13.txt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/fastlane/metadata/android/de-DE/changelogs/13.txt b/fastlane/metadata/android/de-DE/changelogs/13.txt index 55bbb0a..3a105ce 100644 --- a/fastlane/metadata/android/de-DE/changelogs/13.txt +++ b/fastlane/metadata/android/de-DE/changelogs/13.txt @@ -4,5 +4,6 @@ • NEU: Long-Press Mehrfachauswahl zum Löschen • Modernisierte Einstellungen mit 7 Bereichen • Silent-Sync (kein Banner bei Auto-Sync) -• Verbesserter NoteEditor mit Slide-Animationen +• "Nichts zu syncen" Feedback im Status-Banner +• Diverse UI/UX Verbesserungen und Bugfixes • App-Icon in Über-Screen und Leerzustand diff --git a/fastlane/metadata/android/en-US/changelogs/13.txt b/fastlane/metadata/android/en-US/changelogs/13.txt index 19b955e..1e60b52 100644 --- a/fastlane/metadata/android/en-US/changelogs/13.txt +++ b/fastlane/metadata/android/en-US/changelogs/13.txt @@ -4,5 +4,6 @@ • NEW: Long-press selection mode for batch delete • Modernized Settings with 7 organized screens • Silent-Sync mode (no banner during auto-sync) -• Improved NoteEditor with slide animations +• "Nothing to sync" feedback in status banner +• Various UI/UX improvements and bug fixes • App icon in About screen and empty state