diff --git a/docs/v1.6.0_OFFLINE_DELETE_RESTRICTION.md b/docs/v1.6.0_OFFLINE_DELETE_RESTRICTION.md deleted file mode 100644 index 174d760..0000000 --- a/docs/v1.6.0_OFFLINE_DELETE_RESTRICTION.md +++ /dev/null @@ -1,315 +0,0 @@ -# v1.6.0 Feature: Server-LΓΆsch-EinschrΓ€nkung im Offline-Modus - -## πŸ“‹ Übersicht - -**Problem:** Im Offline-Modus kann der Benutzer immer noch "Überall lΓΆschen (auch Server)" auswΓ€hlen, was zu Netzwerkverkehr fΓΌhrt (auch wenn die Anfrage fehlschlΓ€gt). - -**Ziel:** Die "Überall lΓΆschen"-Option im Offline-Modus subtil aber intuitiv deaktivieren, um echte Offline-Nutzung zu gewΓ€hrleisten. - ---- - -## πŸ” Analyse der betroffenen Komponenten - -### 1. DeleteConfirmationDialog -**Datei:** [DeleteConfirmationDialog.kt](../android/app/src/main/java/dev/dettmer/simplenotes/ui/main/components/DeleteConfirmationDialog.kt) - -**Aktueller Zustand:** -- Zeigt zwei Optionen: "Überall lΓΆschen" und "Nur lokal lΓΆschen" -- Keine BerΓΌcksichtigung des Offline-Modus -- Verwendet in: `MainScreen.kt` (Batch-Delete) und `NoteEditorScreen.kt` (Einzelne Notiz) - -**Γ„nderungen:** -- Neuer Parameter: `isOfflineMode: Boolean = false` -- "Überall lΓΆschen" Button: `enabled = !isOfflineMode` -- Subtile visuelle Kennzeichnung wenn deaktiviert - -### 2. Verwendungsstellen - -| Datei | Verwendung | ViewModel-Zugriff | -|-------|------------|-------------------| -| `MainScreen.kt` | Batch-LΓΆschung | `MainViewModel.isOfflineMode` βœ… bereits vorhanden | -| `NoteEditorScreen.kt` | Einzelne Notiz | `NoteEditorViewModel` ❌ benΓΆtigt Erweiterung | - -### 3. NoteEditorViewModel -**Datei:** [NoteEditorViewModel.kt](../android/app/src/main/java/dev/dettmer/simplenotes/ui/editor/NoteEditorViewModel.kt) - -**Aktueller Zustand:** -- PrΓΌft Offline-Status nur fΓΌr `triggerOnSaveSync()` inline via `prefs.getString(KEY_SERVER_URL, null)` -- Kein reaktiver State fΓΌr Offline-Modus - -**Γ„nderungen:** -- Neuer StateFlow: `isOfflineMode: StateFlow` - ---- - -## πŸ“ Technische Design-Entscheidungen - -### UI/UX Design fΓΌr deaktivierte Option - -#### Option A: Grayed-out mit Tooltip-Hinweis βœ… **EMPFOHLEN** -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Notiz lΓΆschen? β”‚ -β”‚ β”‚ -β”‚ Wie mΓΆchtest du diese Notiz lΓΆschen? β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ -β”‚ β”‚ Überall lΓΆschen (auch Server) β”‚β”‚ ← Grau, nicht anklickbar -β”‚ β”‚ πŸ“΄ Nicht verfΓΌgbar im Offline-Modus β”‚β”‚ ← Subtiler Hinweis -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ -β”‚ β”‚ βœ“ Nur lokal lΓΆschen β”‚β”‚ ← Normal, anklickbar -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ -β”‚ β”‚ Abbrechen β”‚β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -**Vorteile:** -- Konsistent mit bestehendem v1.6.0 Pattern (BackupSettingsScreen, MarkdownSettingsScreen) -- Benutzer sieht sofort warum Option nicht verfΓΌgbar -- Keine Verwirrung - klare Ursache angegeben - -#### Option B: Button komplett ausblenden ❌ -**Nachteile:** -- Verwirrend fΓΌr Benutzer die den Button sonst sehen -- Inkonsistent mit v1.6.0 Design-Pattern - -#### Option C: Button mit Toast-Feedback ❌ -**Nachteile:** -- Schlechte UX - warum klickbar wenn nicht mΓΆglich? -- Frustierend fΓΌr Benutzer - ---- - -## πŸ“ Implementierungs-Plan - -### Phase 1: DeleteConfirmationDialog erweitern - -**Schritt 1.1:** Neuer Parameter und String-Ressourcen - -```kotlin -// DeleteConfirmationDialog.kt -@Composable -fun DeleteConfirmationDialog( - noteCount: Int = 1, - isOfflineMode: Boolean = false, // 🌟 v1.6.0: NEU - onDismiss: () -> Unit, - onDeleteLocal: () -> Unit, - onDeleteEverywhere: () -> Unit -) -``` - -**Neue Strings:** -```xml - -Not available in offline mode - - -Nicht verfΓΌgbar im Offline-Modus -``` - -**Schritt 1.2:** UI-Anpassung fΓΌr deaktivierten Button - -```kotlin -// Delete everywhere (server + local) - primary action -// 🌟 v1.6.0: Disabled in offline mode -Column { - TextButton( - onClick = onDeleteEverywhere, - modifier = Modifier.fillMaxWidth(), - enabled = !isOfflineMode, // 🌟 NEU - colors = ButtonDefaults.textButtonColors( - contentColor = MaterialTheme.colorScheme.error, - disabledContentColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f) - ) - ) { - Text(stringResource(R.string.delete_everywhere)) - } - - // 🌟 v1.6.0: Show hint when offline - if (isOfflineMode) { - Text( - text = stringResource(R.string.delete_everywhere_offline_hint), - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.tertiary, - modifier = Modifier.padding(start = 16.dp, end = 16.dp, bottom = 8.dp) - ) - } -} -``` - -### Phase 2: MainScreen anpassen (Batch-LΓΆschung) - -**Datei:** `MainScreen.kt` - -**Aktuelle Verwendung (Zeile ~218):** -```kotlin -DeleteConfirmationDialog( - noteCount = selectedNotes.size, - onDismiss = { showBatchDeleteDialog = false }, - onDeleteLocal = { ... }, - onDeleteEverywhere = { ... } -) -``` - -**Γ„nderung:** -```kotlin -DeleteConfirmationDialog( - noteCount = selectedNotes.size, - isOfflineMode = isOfflineMode, // 🌟 v1.6.0: NEU - bereits als State vorhanden - onDismiss = { showBatchDeleteDialog = false }, - onDeleteLocal = { ... }, - onDeleteEverywhere = { ... } -) -``` - -### Phase 3: NoteEditorScreen + NoteEditorViewModel anpassen - -**Schritt 3.1:** NoteEditorViewModel erweitern - -```kotlin -// NoteEditorViewModel.kt - -// 🌟 v1.6.0: Offline Mode State -private val _isOfflineMode = MutableStateFlow( - prefs.getBoolean(Constants.KEY_OFFLINE_MODE, true) -) -val isOfflineMode: StateFlow = _isOfflineMode.asStateFlow() -``` - -**Schritt 3.2:** NoteEditorScreen anpassen - -```kotlin -// NoteEditorScreen.kt - -// State abrufen -val isOfflineMode by viewModel.isOfflineMode.collectAsState() // 🌟 NEU - -// Dialog anpassen -if (showDeleteDialog) { - DeleteConfirmationDialog( - noteCount = 1, - isOfflineMode = isOfflineMode, // 🌟 v1.6.0: NEU - onDismiss = { showDeleteDialog = false }, - onDeleteLocal = { ... }, - onDeleteEverywhere = { ... } - ) -} -``` - ---- - -## πŸ”§ Detaillierte Γ„nderungs-Matrix - -| Datei | Γ„nderungstyp | Beschreibung | -|-------|--------------|--------------| -| `strings.xml` | String hinzufΓΌgen | `delete_everywhere_offline_hint` (EN) | -| `strings.xml` (de) | String hinzufΓΌgen | `delete_everywhere_offline_hint` (DE) | -| `DeleteConfirmationDialog.kt` | Parameter + UI | `isOfflineMode` Parameter, grayed-out Button + Hint | -| `MainScreen.kt` | Parameter ΓΌbergeben | `isOfflineMode = isOfflineMode` an Dialog | -| `NoteEditorViewModel.kt` | StateFlow hinzufΓΌgen | `isOfflineMode: StateFlow` | -| `NoteEditorScreen.kt` | State abrufen + ΓΌbergeben | collectAsState + an Dialog ΓΌbergeben | - ---- - -## βœ… Akzeptanzkriterien - -1. **Offline-Modus aktiv:** - - [ ] "Überall lΓΆschen" Button ist grau/deaktiviert - - [ ] Subtiler Hinweis-Text erscheint unter dem Button - - [ ] Button ist nicht anklickbar - - [ ] "Nur lokal lΓΆschen" funktioniert normal - - [ ] Kein Netzwerkverkehr bei LΓΆsch-Aktionen - -2. **Online-Modus (Offline-Modus deaktiviert):** - - [ ] Beide Buttons funktionieren normal - - [ ] Kein Hinweis-Text - - [ ] Verhalten unverΓ€ndert - -3. **Konsistenz:** - - [ ] UI-Pattern konsistent mit anderen v1.6.0 Offline-EinschrΓ€nkungen - - [ ] Farbgebung nutzt `MaterialTheme.colorScheme.tertiary` fΓΌr Hints - -4. **Stellen:** - - [ ] MainScreen (Batch-LΓΆschung mit Multi-Select) - - [ ] NoteEditorScreen (Einzelne Notiz lΓΆschen) - ---- - -## πŸ“Š GeschΓ€tzter Aufwand - -| Phase | Aufwand | Dateien | -|-------|---------|---------| -| Phase 1: Dialog | ~30 Min | 3 Dateien | -| Phase 2: MainScreen | ~10 Min | 1 Datei | -| Phase 3: NoteEditor | ~20 Min | 2 Dateien | -| **Gesamt** | **~1 Stunde** | **6 Dateien** | - ---- - -## πŸ§ͺ Test-Szenarien - -### Szenario 1: Einzelne Notiz lΓΆschen (Editor) -1. Offline-Modus aktivieren -2. Bestehende Notiz ΓΆffnen -3. LΓΆschen-Button klicken -4. **Erwartung:** "Überall lΓΆschen" grau, Hint sichtbar -5. "Nur lokal lΓΆschen" funktioniert - -### Szenario 2: Batch-LΓΆschung (Main Screen) -1. Offline-Modus aktivieren -2. Mehrere Notizen auswΓ€hlen (Long-Press + Tap) -3. Papierkorb-Icon klicken -4. **Erwartung:** "Überall lΓΆschen" grau, Hint sichtbar -5. "Nur lokal lΓΆschen" funktioniert - -### Szenario 3: Wechsel zwischen Modi -1. Im Offline-Modus Dialog ΓΆffnen β†’ Button deaktiviert -2. Abbrechen, in Einstellungen Offline-Modus deaktivieren -3. ZurΓΌck, Dialog erneut ΓΆffnen β†’ Button aktiviert - ---- - -## πŸ“Œ Implementierungs-Reihenfolge - -``` -1. β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ String-Ressourcen hinzufΓΌgen β”‚ ← Start hier - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β–Ό -2. β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ DeleteConfirmationDialog.kt β”‚ ← Kern-Γ„nderung - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β–Ό -3. β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ MainScreen.kt β”‚ ← Einfach (State vorhanden) - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β–Ό -4. β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ NoteEditorViewModel.kt β”‚ ← StateFlow hinzufΓΌgen - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β–Ό -5. β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ NoteEditorScreen.kt β”‚ ← State abrufen + ΓΌbergeben - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - ---- - -## πŸ”— AbhΓ€ngigkeiten - -- Keine externen AbhΓ€ngigkeiten -- Nutzt bestehende v1.6.0 Offline-Mode Infrastruktur -- Konsistent mit Design-Pattern aus `MarkdownSettingsScreen.kt` und `BackupSettingsScreen.kt` - ---- - -## πŸ“ Hinweise - -- Der `isOfflineMode` State in `MainViewModel` wird bereits reaktiv via `StateFlow` verwaltet -- `refreshOfflineModeState()` wird in `ComposeMainActivity.onResume()` aufgerufen -- Das gleiche Pattern wird in `NoteEditorViewModel` repliziert (einmalige Initialisierung ausreichend, da Editor-Lebenszyklus kurz ist) diff --git a/fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png b/fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png index be24039..098f9e2 100644 Binary files a/fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png and b/fastlane/metadata/android/de-DE/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/de-DE/images/phoneScreenshots/5.png b/fastlane/metadata/android/de-DE/images/phoneScreenshots/5.png index e639635..607d151 100644 Binary files a/fastlane/metadata/android/de-DE/images/phoneScreenshots/5.png and b/fastlane/metadata/android/de-DE/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/de-DE/images/phoneScreenshots/6.png b/fastlane/metadata/android/de-DE/images/phoneScreenshots/6.png deleted file mode 100644 index 098f9e2..0000000 Binary files a/fastlane/metadata/android/de-DE/images/phoneScreenshots/6.png and /dev/null differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png index be24039..098f9e2 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png index e639635..607d151 100644 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png and b/fastlane/metadata/android/en-US/images/phoneScreenshots/5.png differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png deleted file mode 100644 index 098f9e2..0000000 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/6.png and /dev/null differ