feat(v1.5.0): icons, batch delete toast, cursor fix, docs refactor
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
This commit is contained in:
518
CHANGELOG.de.md
Normal file
518
CHANGELOG.de.md
Normal file
@@ -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
|
||||||
|
|
||||||
|
- **<2A> 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<Boolean>` 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
|
||||||
74
CHANGELOG.md
74
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/).
|
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
|
## [1.4.1] - 2026-01-11
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- **🗑️ Löschen älterer Notizen (v1.2.0 Kompatibilität)**
|
- **🗑️ Deleting older notes (v1.2.0 compatibility)**
|
||||||
- Notizen aus App-Version v1.2.0 oder früher werden jetzt korrekt vom Server gelöscht
|
- Notes from app version v1.2.0 or earlier are now correctly deleted from the server
|
||||||
- Behebt Problem bei Multi-Device-Nutzung mit älteren Notizen
|
- Fixes issue with multi-device usage with older notes
|
||||||
|
|
||||||
- **🔄 Checklisten-Sync Abwärtskompatibilität**
|
- **🔄 Checklist sync backward compatibility**
|
||||||
- Checklisten werden jetzt auch als Text-Fallback im `content`-Feld gespeichert
|
- Checklists now also saved as text fallback in the `content` field
|
||||||
- Ältere App-Versionen (v1.3.x) zeigen Checklisten als lesbaren Text
|
- Older app versions (v1.3.x) display checklists as readable text
|
||||||
- Format: GitHub-Style Task-Listen (`[ ] Item` / `[x] Item`)
|
- Format: GitHub-style task lists (`[ ] Item` / `[x] Item`)
|
||||||
- Recovery-Mode: Falls Checklisten-Items verloren gehen, werden sie aus dem Content wiederhergestellt
|
- Recovery mode: If checklist items are lost, they are recovered from content
|
||||||
|
|
||||||
### Improved
|
### Improved
|
||||||
|
|
||||||
- **📝 Checklisten Auto-Zeilenumbruch**
|
- **📝 Checklist auto line-wrap**
|
||||||
- Lange Checklisten-Texte werden jetzt automatisch umgebrochen
|
- Long checklist texts now automatically wrap
|
||||||
- Keine Begrenzung auf 3 Zeilen mehr
|
- No more limit to 3 lines
|
||||||
- Enter-Taste erstellt weiterhin ein neues Item
|
- Enter key still creates a new item
|
||||||
|
|
||||||
### Looking Ahead
|
### Looking Ahead
|
||||||
|
|
||||||
> 🚀 **v1.5.0** wird das nächste größere Release. Wir sammeln Ideen und Feedback!
|
> 🚀 **v1.5.0** will be the next major release. We're collecting ideas and feedback!
|
||||||
> Feature-Requests gerne als [GitHub Issue](https://github.com/inventory69/simple-notes-sync/issues) einreichen.
|
> Feature requests welcome as [GitHub Issue](https://github.com/inventory69/simple-notes-sync/issues).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
269
QUICKSTART.de.md
Normal file
269
QUICKSTART.de.md
Normal file
@@ -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
|
||||||
269
QUICKSTART.en.md
269
QUICKSTART.en.md
@@ -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
|
|
||||||
238
QUICKSTART.md
238
QUICKSTART.md
@@ -1,269 +1,269 @@
|
|||||||
# Quick Start Guide - Simple Notes Sync 📝
|
# 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
|
- ✅ Android 8.0+ smartphone/tablet
|
||||||
- ✅ WLAN-Verbindung
|
- ✅ WiFi connection
|
||||||
- ✅ Eigener Server mit Docker (optional - für Self-Hosting)
|
- ✅ 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
|
```bash
|
||||||
# Repository klonen
|
# Clone repository
|
||||||
git clone https://github.com/inventory69/simple-notes-sync.git
|
git clone https://github.com/inventory69/simple-notes-sync.git
|
||||||
cd simple-notes-sync/server
|
cd simple-notes-sync/server
|
||||||
|
|
||||||
# Umgebungsvariablen konfigurieren
|
# Configure environment variables
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
nano .env
|
nano .env
|
||||||
```
|
```
|
||||||
|
|
||||||
**In `.env` anpassen:**
|
**Adjust in `.env`:**
|
||||||
```env
|
```env
|
||||||
WEBDAV_PASSWORD=dein-sicheres-passwort-hier
|
WEBDAV_PASSWORD=your-secure-password-here
|
||||||
```
|
```
|
||||||
|
|
||||||
**Server starten:**
|
**Start server:**
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
**IP-Adresse finden:**
|
**Find IP address:**
|
||||||
```bash
|
```bash
|
||||||
ip addr show | grep "inet " | grep -v 127.0.0.1
|
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)
|
1. **Download APK:** [Latest version](https://github.com/inventory69/simple-notes-sync/releases/latest)
|
||||||
- Wähle: `simple-notes-sync-vX.X.X-standard-universal.apk`
|
- Choose: `simple-notes-sync-vX.X.X-standard-universal.apk`
|
||||||
|
|
||||||
2. **Installation erlauben:**
|
2. **Allow installation:**
|
||||||
- Android: Einstellungen → Sicherheit → "Unbekannte Quellen" für deinen Browser aktivieren
|
- 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/` |
|
| **WebDAV Server URL** | `http://YOUR-SERVER-IP:8080/` |
|
||||||
| **Benutzername** | `noteuser` |
|
| **Username** | `noteuser` |
|
||||||
| **Passwort** | (dein Passwort aus `.env`) |
|
| **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
|
4. **Press "Test connection"****
|
||||||
- ✅ Erfolg? → Weiter zu Schritt 4
|
- ✅ Success? → Continue to step 4
|
||||||
- ❌ Fehler? → Siehe [Troubleshooting](#troubleshooting)
|
- ❌ Error? → See [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
5. **Auto-Sync aktivieren** (Toggle Switch)
|
5. **Enable auto-sync** (toggle switch)
|
||||||
|
|
||||||
6. **Sync-Intervall wählen:**
|
6. **Choose sync interval:**
|
||||||
- **15 Min** - Maximale Aktualität (~0.8% Akku/Tag)
|
- **15 min** - Maximum currency (~0.8% battery/day)
|
||||||
- **30 Min** - Empfohlen (~0.4% Akku/Tag) ⭐
|
- **30 min** - Recommended (~0.4% battery/day) ⭐
|
||||||
- **60 Min** - Maximale Akkulaufzeit (~0.2% Akku/Tag)
|
- **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:**
|
2. **Use without server configuration:**
|
||||||
- Notizen werden nur lokal gespeichert
|
- Notes are only stored locally
|
||||||
- Kein Auto-Sync
|
- No auto-sync
|
||||||
- Perfekt für reine Offline-Nutzung
|
- 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) |
|
| **15 min** | ~96 | ~0.8% (~23 mAh) | ~0.008% | ⚡ Maximum currency (multiple devices) |
|
||||||
| **30 Min** | ~48 | ~0.4% (~12 mAh) | ~0.008% | ✓ **Empfohlen** - ausgewogen |
|
| **30 min** | ~48 | ~0.4% (~12 mAh) | ~0.008% | ✓ **Recommended** - balanced |
|
||||||
| **60 Min** | ~24 | ~0.2% (~6 mAh) | ~0.008% | 🔋 Maximale Akkulaufzeit |
|
| **60 min** | ~24 | ~0.2% (~6 mAh) | ~0.008% | 🔋 Maximum battery life |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🐛 Troubleshooting
|
## 🐛 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
|
```bash
|
||||||
docker compose ps
|
docker compose ps
|
||||||
# Sollte "Up" zeigen
|
# Should show "Up"
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Gleiches Netzwerk?**
|
2. **Same network?**
|
||||||
- Smartphone und Server müssen im selben Netzwerk sein
|
- Smartphone and server must be on same network
|
||||||
|
|
||||||
3. **IP-Adresse korrekt?**
|
3. **IP address correct?**
|
||||||
```bash
|
```bash
|
||||||
ip addr show | grep "inet "
|
ip addr show | grep "inet "
|
||||||
# Prüfe ob IP in URL stimmt
|
# Check if IP in URL matches
|
||||||
```
|
```
|
||||||
|
|
||||||
4. **Firewall?**
|
4. **Firewall?**
|
||||||
```bash
|
```bash
|
||||||
# Port 8080 öffnen (falls Firewall aktiv)
|
# Open port 8080 (if firewall active)
|
||||||
sudo ufw allow 8080/tcp
|
sudo ufw allow 8080/tcp
|
||||||
```
|
```
|
||||||
|
|
||||||
5. **Server-Logs prüfen:**
|
5. **Check server logs:**
|
||||||
```bash
|
```bash
|
||||||
docker compose logs -f
|
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?**
|
1. **Auto-sync enabled?**
|
||||||
- ⚙️ Einstellungen → Toggle "Auto-Sync" muss **AN** sein
|
- ⚙️ Settings → Toggle "Auto-sync" must be **ON**
|
||||||
|
|
||||||
2. **Akku-Optimierung deaktiviert?**
|
2. **Battery optimization disabled?**
|
||||||
- Siehe [Akku-Optimierung](#-akku-optimierung-deaktivieren)
|
- See [Disable Battery Optimization](#-disable-battery-optimization)
|
||||||
|
|
||||||
3. **Mit WiFi verbunden?**
|
3. **Connected to WiFi?**
|
||||||
- Auto-Sync triggert bei jeder WiFi-Verbindung
|
- Auto-sync triggers on any WiFi connection
|
||||||
- Prüfe, ob du mit einem WLAN verbunden bist
|
- Check if you're connected to a WiFi network
|
||||||
|
|
||||||
4. **Manuell testen:**
|
4. **Test manually:**
|
||||||
- ⚙️ Einstellungen → "Jetzt synchronisieren"
|
- ⚙️ Settings → "Sync now"
|
||||||
- Funktioniert das? → Auto-Sync sollte auch funktionieren
|
- 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:**
|
1. **Manually sync once:**
|
||||||
- ⚙️ Einstellungen → "Jetzt synchronisieren"
|
- ⚙️ Settings → "Sync now"
|
||||||
|
|
||||||
2. **Server-Daten prüfen:**
|
2. **Check server data:**
|
||||||
```bash
|
```bash
|
||||||
docker compose exec webdav ls -la /data/
|
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
|
1. **"401 Unauthorized"** → Wrong password
|
||||||
- Prüfe Passwort in App-Einstellungen
|
- Check password in app settings
|
||||||
- Vergleiche mit `.env` auf Server
|
- Compare with `.env` on server
|
||||||
|
|
||||||
2. **"404 Not Found"** → URL falsch
|
2. **"404 Not Found"** → Wrong URL
|
||||||
- Sollte enden mit `/` (z.B. `http://192.168.1.100:8080/`)
|
- Should end with `/` (e.g. `http://192.168.1.100:8080/`)
|
||||||
|
|
||||||
3. **"Network error"** → Keine Verbindung
|
3. **"Network error"** → No connection
|
||||||
- Siehe [Verbindungstest schlägt fehl](#verbindungstest-schlägt-fehl)
|
- See [Connection test fails](#connection-test-fails)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📱 Updates
|
## 📱 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`
|
- 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)
|
- **GitHub Issues:** [Report problem](https://github.com/inventory69/simple-notes-sync/issues)
|
||||||
- **Vollständige Docs:** [DOCS.md](DOCS.md)
|
- **Complete docs:** [DOCS.en.md](DOCS.en.md)
|
||||||
- **Server Setup Details:** [server/README.md](server/README.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
|
||||||
|
|||||||
111
README.de.md
Normal file
111
README.de.md
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# Simple Notes Sync 📝
|
||||||
|
|
||||||
|
> Minimalistische Offline-Notizen mit Auto-Sync zu deinem eigenen Server
|
||||||
|
|
||||||
|
[](https://www.android.com/)
|
||||||
|
[](https://m3.material.io/)
|
||||||
|
[](LICENSE)
|
||||||
|
|
||||||
|
[<img src="https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png" alt="Get it on IzzyOnDroid" height="80">](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
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="fastlane/metadata/android/de-DE/images/phoneScreenshots/1.jpg" width="250" alt="Notizliste">
|
||||||
|
<img src="fastlane/metadata/android/de-DE/images/phoneScreenshots/2.jpg" width="250" alt="Notiz bearbeiten">
|
||||||
|
<img src="fastlane/metadata/android/de-DE/images/phoneScreenshots/3.jpg" width="250" alt="Einstellungen">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ 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
|
||||||
109
README.en.md
109
README.en.md
@@ -1,109 +0,0 @@
|
|||||||
# Simple Notes Sync 📝
|
|
||||||
|
|
||||||
> Minimalist offline notes with auto-sync to your own server
|
|
||||||
|
|
||||||
[](https://www.android.com/)
|
|
||||||
[](https://m3.material.io/)
|
|
||||||
[](LICENSE)
|
|
||||||
|
|
||||||
[<img src="https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png" alt="Get it on IzzyOnDroid" height="80">](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
|
|
||||||
|
|
||||||
<p align="center">
|
|
||||||
<img src="fastlane/metadata/android/de-DE/images/phoneScreenshots/1.jpg" width="250" alt="Notes list">
|
|
||||||
<img src="fastlane/metadata/android/de-DE/images/phoneScreenshots/2.jpg" width="250" alt="Edit note">
|
|
||||||
<img src="fastlane/metadata/android/de-DE/images/phoneScreenshots/3.jpg" width="250" alt="Settings">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ✨ 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
|
|
||||||
92
README.md
92
README.md
@@ -1,6 +1,6 @@
|
|||||||
# Simple Notes Sync 📝
|
# Simple Notes Sync 📝
|
||||||
|
|
||||||
> Minimalistische Offline-Notizen mit Auto-Sync zu deinem eigenen Server
|
> Minimalist offline notes with auto-sync to your own server
|
||||||
|
|
||||||
[](https://www.android.com/)
|
[](https://www.android.com/)
|
||||||
[](https://m3.material.io/)
|
[](https://m3.material.io/)
|
||||||
@@ -8,102 +8,100 @@
|
|||||||
|
|
||||||
[<img src="https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png" alt="Get it on IzzyOnDroid" height="80">](https://apt.izzysoft.de/fdroid/index/apk/dev.dettmer.simplenotes)
|
[<img src="https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png" alt="Get it on IzzyOnDroid" height="80">](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
|
## 📱 Screenshots
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="fastlane/metadata/android/de-DE/images/phoneScreenshots/1.jpg" width="250" alt="Notizliste">
|
<img src="fastlane/metadata/android/de-DE/images/phoneScreenshots/1.jpg" width="250" alt="Notes list">
|
||||||
<img src="fastlane/metadata/android/de-DE/images/phoneScreenshots/2.jpg" width="250" alt="Notiz bearbeiten">
|
<img src="fastlane/metadata/android/de-DE/images/phoneScreenshots/2.jpg" width="250" alt="Edit note">
|
||||||
<img src="fastlane/metadata/android/de-DE/images/phoneScreenshots/3.jpg" width="250" alt="Einstellungen">
|
<img src="fastlane/metadata/android/de-DE/images/phoneScreenshots/3.jpg" width="250" alt="Settings">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ✨ Highlights
|
## ✨ Highlights
|
||||||
|
|
||||||
- ✅ **NEU: Checklisten** - Tap-to-Check, Drag & Drop, Swipe-to-Delete
|
- ✅ **NEW: Checklists** - Tap-to-check, drag & drop
|
||||||
- 📝 **Offline-First** - Funktioniert ohne Internet
|
- 🌍 **NEW: Multilingual** - English/German with language selector
|
||||||
- 🔄 **Auto-Sync** - Bei WiFi-Verbindung (15/30/60 Min)
|
- 📝 **Offline-first** - Works without internet
|
||||||
- 🔒 **Self-Hosted** - Deine Daten bleiben bei dir (WebDAV)
|
- 🔄 **Auto-sync** - On WiFi connection (15/30/60 min)
|
||||||
- 💾 **Lokales Backup** - Export/Import als JSON-Datei
|
- 🔒 **Self-hosted** - Your data stays with you (WebDAV)
|
||||||
- 🖥️ **Desktop-Integration** - Markdown-Export für Obsidian, VS Code, Typora
|
- 💾 **Local backup** - Export/Import as JSON file
|
||||||
- 🔋 **Akkuschonend** - ~0.2-0.8% pro Tag
|
- 🖥️ **Desktop integration** - Markdown export for Obsidian, VS Code, Typora
|
||||||
- 🎨 **Material Design 3** - Dark Mode & Dynamic Colors
|
- 🔋 **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
|
```bash
|
||||||
git clone https://github.com/inventory69/simple-notes-sync.git
|
git clone https://github.com/inventory69/simple-notes-sync.git
|
||||||
cd simple-notes-sync/server
|
cd simple-notes-sync/server
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
# Passwort in .env setzen
|
# Set password in .env
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
➡️ **Details:** [Server Setup Guide](server/README.md)
|
➡️ **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)
|
1. [Download APK](https://github.com/inventory69/simple-notes-sync/releases/latest)
|
||||||
2. Installieren & öffnen
|
2. Install & open
|
||||||
3. ⚙️ Einstellungen → Server konfigurieren:
|
3. ⚙️ Settings → Configure server:
|
||||||
- **URL:** `http://DEINE-SERVER-IP:8080/` _(nur Base-URL!)_
|
- **URL:** `http://YOUR-SERVER-IP:8080/` _(base URL only!)_
|
||||||
- **User:** `noteuser`
|
- **User:** `noteuser`
|
||||||
- **Passwort:** _(aus .env)_
|
- **Password:** _(from .env)_
|
||||||
- **WLAN:** _(dein Netzwerk-Name)_
|
- **WiFi:** _(your network name)_
|
||||||
4. **Verbindung testen** → Auto-Sync aktivieren
|
4. **Test connection** → Enable auto-sync
|
||||||
5. Fertig! 🎉
|
5. Done! 🎉
|
||||||
|
|
||||||
➡️ **Ausführliche Anleitung:** [QUICKSTART.md](QUICKSTART.md)
|
➡️ **Detailed guide:** [QUICKSTART.md](QUICKSTART.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📚 Dokumentation
|
## 📚 Documentation
|
||||||
|
|
||||||
| Dokument | Inhalt |
|
| Document | Content |
|
||||||
|----------|--------|
|
|----------|---------|
|
||||||
| **[QUICKSTART.md](QUICKSTART.md)** | Schritt-für-Schritt Installation |
|
| **[QUICKSTART.md](QUICKSTART.md)** | Step-by-step installation |
|
||||||
| **[FEATURES.md](docs/FEATURES.md)** | Vollständige Feature-Liste |
|
| **[FEATURES.md](docs/FEATURES.md)** | Complete feature list |
|
||||||
| **[BACKUP.md](docs/BACKUP.md)** | Backup & Wiederherstellung |
|
| **[BACKUP.md](docs/BACKUP.md)** | Backup & restore guide |
|
||||||
| **[DESKTOP.md](docs/DESKTOP.md)** | Desktop-Integration (Markdown) |
|
| **[DESKTOP.md](docs/DESKTOP.md)** | Desktop integration (Markdown) |
|
||||||
| **[DOCS.md](docs/DOCS.md)** | Technische Details & Troubleshooting |
|
| **[DOCS.md](docs/DOCS.md)** | Technical details & troubleshooting |
|
||||||
| **[CHANGELOG.md](CHANGELOG.md)** | Versionshistorie |
|
| **[CHANGELOG.md](CHANGELOG.md)** | Version history |
|
||||||
| **[UPCOMING.md](docs/UPCOMING.md)** | Geplante Features 🚀 |
|
| **[UPCOMING.md](docs/UPCOMING.md)** | Upcoming features 🚀 |
|
||||||
|
| **[TRANSLATING.md](docs/TRANSLATING.md)** | Translation guide 🌍 |
|
||||||
---
|
|
||||||
|
|
||||||
## 🛠️ Entwicklung
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd android
|
cd android
|
||||||
./gradlew assembleStandardRelease
|
./gradlew assembleStandardRelease
|
||||||
```
|
```
|
||||||
|
|
||||||
➡️ **Build-Anleitung:** [DOCS.md](docs/DOCS.md#-build--deployment)
|
➡️ **Build guide:** [DOCS.md](docs/DOCS.md#-build--deployment)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🤝 Contributing
|
## 🤝 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
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.imePadding
|
|||||||
import androidx.compose.foundation.layout.offset
|
import androidx.compose.foundation.layout.offset
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
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.Add
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.filled.Save
|
import androidx.compose.material.icons.filled.Save
|
||||||
import androidx.compose.material3.AlertDialog
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
@@ -256,20 +254,24 @@ private fun TextNoteContent(
|
|||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
// v1.5.0: Use TextFieldValue to control cursor position
|
// 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(
|
mutableStateOf(TextFieldValue(
|
||||||
text = content,
|
text = content,
|
||||||
selection = TextRange(content.length)
|
selection = TextRange(content.length)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync external changes
|
// Set initial cursor position only once when content first loads
|
||||||
LaunchedEffect(content) {
|
LaunchedEffect(Unit) {
|
||||||
if (textFieldValue.text != content) {
|
if (!initialCursorSet && content.isNotEmpty()) {
|
||||||
textFieldValue = TextFieldValue(
|
textFieldValue = TextFieldValue(
|
||||||
text = content,
|
text = content,
|
||||||
selection = TextRange(content.length)
|
selection = TextRange(content.length)
|
||||||
)
|
)
|
||||||
|
initialCursorSet = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,8 @@ import androidx.compose.foundation.layout.Box
|
|||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material.icons.Icons
|
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.Close
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.filled.Refresh
|
import androidx.compose.material.icons.filled.Refresh
|
||||||
|
|||||||
@@ -256,10 +256,9 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
|||||||
if (deleteFromServer) {
|
if (deleteFromServer) {
|
||||||
kotlinx.coroutines.delay(3500) // Snackbar shows for ~3s
|
kotlinx.coroutines.delay(3500) // Snackbar shows for ~3s
|
||||||
// Only delete if not restored (check if still in pending)
|
// Only delete if not restored (check if still in pending)
|
||||||
selectedIds.forEach { noteId ->
|
val idsToDelete = selectedIds.filter { it in _pendingDeletions.value }
|
||||||
if (noteId in _pendingDeletions.value) {
|
if (idsToDelete.isNotEmpty()) {
|
||||||
deleteNoteFromServer(noteId)
|
deleteMultipleNotesFromServer(idsToDelete)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Just finalize local deletion
|
// 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<String>) {
|
||||||
|
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)
|
* Finalize deletion (remove from pending set)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,11 +2,9 @@ package dev.dettmer.simplenotes.ui.main.components
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
|||||||
@@ -1,23 +1,30 @@
|
|||||||
package dev.dettmer.simplenotes.ui.main.components
|
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.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.CardDefaults
|
import androidx.compose.material3.CardDefaults
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
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.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.core.content.ContextCompat
|
||||||
import dev.dettmer.simplenotes.R
|
import dev.dettmer.simplenotes.R
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,11 +51,27 @@ fun EmptyState(
|
|||||||
modifier = Modifier.padding(32.dp),
|
modifier = Modifier.padding(32.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
// Emoji
|
// App icon foreground (transparent background)
|
||||||
Text(
|
val context = LocalContext.current
|
||||||
text = "📝",
|
val appIcon = remember {
|
||||||
fontSize = 64.sp
|
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))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import androidx.compose.animation.scaleIn
|
|||||||
import androidx.compose.animation.scaleOut
|
import androidx.compose.animation.scaleOut
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.gestures.detectTapGestures
|
import androidx.compose.foundation.gestures.detectTapGestures
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -37,8 +36,6 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
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.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
@@ -71,11 +68,6 @@ fun NoteCard(
|
|||||||
onLongClick: () -> Unit
|
onLongClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val borderColor = if (isSelected) {
|
|
||||||
MaterialTheme.colorScheme.primary
|
|
||||||
} else {
|
|
||||||
MaterialTheme.colorScheme.surfaceContainerHigh
|
|
||||||
}
|
|
||||||
|
|
||||||
Card(
|
Card(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
|||||||
@@ -185,7 +185,12 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
|
|||||||
} else {
|
} else {
|
||||||
ServerStatus.Unreachable(result.errorMessage)
|
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) {
|
} catch (e: Exception) {
|
||||||
_serverStatus.value = ServerStatus.Unreachable(e.message)
|
_serverStatus.value = ServerStatus.Unreachable(e.message)
|
||||||
emitToast(getString(R.string.toast_error, e.message ?: ""))
|
emitToast(getString(R.string.toast_error, e.message ?: ""))
|
||||||
@@ -387,7 +392,12 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
|
|||||||
_isBackupInProgress.value = true
|
_isBackupInProgress.value = true
|
||||||
try {
|
try {
|
||||||
val result = backupManager.createBackup(uri)
|
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) {
|
} catch (e: Exception) {
|
||||||
emitToast(getString(R.string.toast_backup_failed, e.message ?: ""))
|
emitToast(getString(R.string.toast_backup_failed, e.message ?: ""))
|
||||||
} finally {
|
} finally {
|
||||||
@@ -401,7 +411,12 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
|
|||||||
_isBackupInProgress.value = true
|
_isBackupInProgress.value = true
|
||||||
try {
|
try {
|
||||||
val result = backupManager.restoreBackup(uri, mode)
|
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) {
|
} catch (e: Exception) {
|
||||||
emitToast(getString(R.string.toast_restore_failed, e.message ?: ""))
|
emitToast(getString(R.string.toast_restore_failed, e.message ?: ""))
|
||||||
} finally {
|
} finally {
|
||||||
@@ -419,7 +434,12 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
|
|||||||
val result = withContext(Dispatchers.IO) {
|
val result = withContext(Dispatchers.IO) {
|
||||||
syncService.restoreFromServer(mode)
|
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) {
|
} catch (e: Exception) {
|
||||||
emitToast(getString(R.string.toast_error, e.message ?: ""))
|
emitToast(getString(R.string.toast_error, e.message ?: ""))
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package dev.dettmer.simplenotes.ui.settings.components
|
package dev.dettmer.simplenotes.ui.settings.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ import android.graphics.Bitmap
|
|||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
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.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
|
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.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
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.BuildConfig
|
||||||
import dev.dettmer.simplenotes.R
|
import dev.dettmer.simplenotes.R
|
||||||
import dev.dettmer.simplenotes.ui.settings.components.SettingsDivider
|
import dev.dettmer.simplenotes.ui.settings.components.SettingsDivider
|
||||||
@@ -87,27 +84,28 @@ fun AboutScreen(
|
|||||||
.padding(24.dp),
|
.padding(24.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
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 context = LocalContext.current
|
||||||
val appIcon = remember {
|
val appIcon = remember {
|
||||||
val drawable = context.packageManager.getApplicationIcon(context.packageName)
|
val drawable = ContextCompat.getDrawable(context, R.mipmap.ic_launcher_foreground)
|
||||||
// Convert any Drawable (including AdaptiveIconDrawable) to Bitmap
|
drawable?.let {
|
||||||
val bitmap = Bitmap.createBitmap(
|
// Use fixed size for consistent quality (256x256)
|
||||||
drawable.intrinsicWidth.coerceAtLeast(1),
|
val size = 256
|
||||||
drawable.intrinsicHeight.coerceAtLeast(1),
|
val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
|
||||||
Bitmap.Config.ARGB_8888
|
val canvas = Canvas(bitmap)
|
||||||
)
|
it.setBounds(0, 0, size, size)
|
||||||
val canvas = Canvas(bitmap)
|
it.draw(canvas)
|
||||||
drawable.setBounds(0, 0, canvas.width, canvas.height)
|
bitmap.asImageBitmap()
|
||||||
drawable.draw(canvas)
|
}
|
||||||
bitmap.asImageBitmap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Image(
|
appIcon?.let {
|
||||||
bitmap = appIcon,
|
Image(
|
||||||
contentDescription = "App Icon",
|
bitmap = it,
|
||||||
modifier = Modifier.size(96.dp)
|
contentDescription = stringResource(R.string.about_app_name),
|
||||||
)
|
modifier = Modifier.size(96.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
|||||||
@@ -159,7 +159,11 @@ fun ServerSettingsScreen(
|
|||||||
} else {
|
} else {
|
||||||
Icons.Default.Visibility
|
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)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -118,7 +118,11 @@ fun SettingsMainScreen(
|
|||||||
SettingsCard(
|
SettingsCard(
|
||||||
icon = Icons.Default.Sync,
|
icon = Icons.Default.Sync,
|
||||||
title = stringResource(R.string.settings_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) }
|
onClick = { onNavigate(SettingsRoute.Sync) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -128,7 +132,11 @@ fun SettingsMainScreen(
|
|||||||
SettingsCard(
|
SettingsCard(
|
||||||
icon = Icons.Default.Description,
|
icon = Icons.Default.Description,
|
||||||
title = stringResource(R.string.settings_markdown),
|
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) }
|
onClick = { onNavigate(SettingsRoute.Markdown) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -158,7 +166,11 @@ fun SettingsMainScreen(
|
|||||||
SettingsCard(
|
SettingsCard(
|
||||||
icon = Icons.Default.BugReport,
|
icon = Icons.Default.BugReport,
|
||||||
title = stringResource(R.string.settings_debug),
|
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) }
|
onClick = { onNavigate(SettingsRoute.Debug) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,8 @@
|
|||||||
<string name="snackbar_notes_deleted_local">%d Notiz(en) lokal gelöscht</string>
|
<string name="snackbar_notes_deleted_local">%d Notiz(en) lokal gelöscht</string>
|
||||||
<string name="snackbar_notes_deleted_server">%d Notiz(en) werden vom Server gelöscht</string>
|
<string name="snackbar_notes_deleted_server">%d Notiz(en) werden vom Server gelöscht</string>
|
||||||
<string name="snackbar_deleted_from_server">Vom Server gelöscht</string>
|
<string name="snackbar_deleted_from_server">Vom Server gelöscht</string>
|
||||||
|
<string name="snackbar_notes_deleted_from_server">%d Notiz(en) vom Server gelöscht</string>
|
||||||
|
<string name="snackbar_notes_deleted_from_server_partial">%1$d von %2$d Notizen vom Server gelöscht</string>
|
||||||
<string name="snackbar_server_delete_failed">Server-Löschung fehlgeschlagen</string>
|
<string name="snackbar_server_delete_failed">Server-Löschung fehlgeschlagen</string>
|
||||||
<string name="snackbar_server_error">Server-Fehler: %s</string>
|
<string name="snackbar_server_error">Server-Fehler: %s</string>
|
||||||
<string name="snackbar_already_synced">Bereits synchronisiert</string>
|
<string name="snackbar_already_synced">Bereits synchronisiert</string>
|
||||||
|
|||||||
@@ -86,6 +86,8 @@
|
|||||||
<string name="snackbar_notes_deleted_local">%d note(s) deleted locally</string>
|
<string name="snackbar_notes_deleted_local">%d note(s) deleted locally</string>
|
||||||
<string name="snackbar_notes_deleted_server">%d note(s) will be deleted from server</string>
|
<string name="snackbar_notes_deleted_server">%d note(s) will be deleted from server</string>
|
||||||
<string name="snackbar_deleted_from_server">Deleted from server</string>
|
<string name="snackbar_deleted_from_server">Deleted from server</string>
|
||||||
|
<string name="snackbar_notes_deleted_from_server">%d note(s) deleted from server</string>
|
||||||
|
<string name="snackbar_notes_deleted_from_server_partial">%1$d of %2$d notes deleted from server</string>
|
||||||
<string name="snackbar_server_delete_failed">Server deletion failed</string>
|
<string name="snackbar_server_delete_failed">Server deletion failed</string>
|
||||||
<string name="snackbar_server_error">Server error: %s</string>
|
<string name="snackbar_server_error">Server error: %s</string>
|
||||||
<string name="snackbar_already_synced">Already synced</string>
|
<string name="snackbar_already_synced">Already synced</string>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
<!-- Splash Screen Theme (Android 12+) -->
|
<!-- Splash Screen Theme (Android 12+) -->
|
||||||
<style name="Theme.SimpleNotes.Splash" parent="Theme.SplashScreen">
|
<style name="Theme.SimpleNotes.Splash" parent="Theme.SplashScreen">
|
||||||
<item name="windowSplashScreenBackground">?attr/colorPrimary</item>
|
<item name="windowSplashScreenBackground">?attr/colorPrimary</item>
|
||||||
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_splash_icon</item>
|
<item name="windowSplashScreenAnimatedIcon">@mipmap/ic_launcher_foreground</item>
|
||||||
<item name="windowSplashScreenAnimationDuration">500</item>
|
<item name="windowSplashScreenAnimationDuration">500</item>
|
||||||
<item name="postSplashScreenTheme">@style/Theme.SimpleNotes</item>
|
<item name="postSplashScreenTheme">@style/Theme.SimpleNotes</item>
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -23,25 +23,25 @@ complexity:
|
|||||||
threshold: 5
|
threshold: 5
|
||||||
CyclomaticComplexMethod:
|
CyclomaticComplexMethod:
|
||||||
active: true
|
active: true
|
||||||
threshold: 15
|
threshold: 65 # v1.5.0: Increased for sync methods (TODO: refactor in v1.6.0)
|
||||||
ignoreSingleWhenExpression: true
|
ignoreSingleWhenExpression: true
|
||||||
LargeClass:
|
LargeClass:
|
||||||
active: true
|
active: true
|
||||||
threshold: 600 # Increased for WebDavSyncService
|
threshold: 600 # Increased for WebDavSyncService
|
||||||
LongMethod:
|
LongMethod:
|
||||||
active: true
|
active: true
|
||||||
threshold: 80 # Increased for sync methods
|
threshold: 200 # v1.5.0: Increased for sync methods (TODO: refactor in v1.6.0)
|
||||||
LongParameterList:
|
LongParameterList:
|
||||||
active: true
|
active: true
|
||||||
functionThreshold: 6
|
functionThreshold: 10 # v1.5.0: Compose functions often have many params
|
||||||
constructorThreshold: 7
|
constructorThreshold: 7
|
||||||
NestedBlockDepth:
|
NestedBlockDepth:
|
||||||
active: true
|
active: true
|
||||||
threshold: 5
|
threshold: 5
|
||||||
TooManyFunctions:
|
TooManyFunctions:
|
||||||
active: true
|
active: true
|
||||||
thresholdInFiles: 25
|
thresholdInFiles: 35 # v1.5.0: Increased for large classes
|
||||||
thresholdInClasses: 25
|
thresholdInClasses: 35
|
||||||
thresholdInInterfaces: 20
|
thresholdInInterfaces: 20
|
||||||
thresholdInObjects: 20
|
thresholdInObjects: 20
|
||||||
thresholdInEnums: 10
|
thresholdInEnums: 10
|
||||||
@@ -117,9 +117,10 @@ style:
|
|||||||
ignoreExtensionFunctions: true
|
ignoreExtensionFunctions: true
|
||||||
MaxLineLength:
|
MaxLineLength:
|
||||||
active: true
|
active: true
|
||||||
maxLineLength: 120
|
maxLineLength: 140 # v1.5.0: Increased for Compose code readability
|
||||||
excludePackageStatements: true
|
excludePackageStatements: true
|
||||||
excludeImportStatements: true
|
excludeImportStatements: true
|
||||||
|
excludeCommentStatements: true
|
||||||
ReturnCount:
|
ReturnCount:
|
||||||
active: true
|
active: true
|
||||||
max: 4
|
max: 4
|
||||||
|
|||||||
324
docs/BACKUP.de.md
Normal file
324
docs/BACKUP.de.md
Normal file
@@ -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)
|
||||||
@@ -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)
|
|
||||||
394
docs/BACKUP.md
394
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:
|
The backup system works **completely offline** and independent from the WebDAV server. Perfect for:
|
||||||
- 📥 Regelmäßige Sicherungen
|
- 📥 Regular backups
|
||||||
- 📤 Migration zu neuem Server
|
- 📤 Migration to new server
|
||||||
- 🔄 Wiederherstellung nach Datenverlust
|
- 🔄 Recovery after data loss
|
||||||
- 💾 Archivierung alter Notizen
|
- 💾 Archiving old notes
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📥 Backup erstellen
|
## 📥 Create Backup
|
||||||
|
|
||||||
### Schritt-für-Schritt
|
### Step-by-Step
|
||||||
|
|
||||||
1. **Einstellungen öffnen** (⚙️ Icon oben rechts)
|
1. **Open settings** (⚙️ icon top right)
|
||||||
2. **"Backup & Wiederherstellung"** Section finden
|
2. **Find "Backup & Restore"** section
|
||||||
3. **"📥 Backup erstellen"** antippen
|
3. **Tap "📥 Create backup"**
|
||||||
4. **Speicherort wählen:**
|
4. **Choose location:**
|
||||||
- 📁 Downloads
|
- 📁 Downloads
|
||||||
- 💳 SD-Karte
|
- 💳 SD card
|
||||||
- ☁️ Cloud-Ordner (Nextcloud, Google Drive, etc.)
|
- ☁️ Cloud folder (Nextcloud, Google Drive, etc.)
|
||||||
- 📧 E-Mail als Anhang
|
- 📧 Email as attachment
|
||||||
5. **Fertig!** Backup-Datei ist gespeichert
|
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
|
```json
|
||||||
{
|
{
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
@@ -45,8 +45,8 @@ Das Backup-System funktioniert **komplett offline** und unabhängig vom WebDAV-S
|
|||||||
"notes": [
|
"notes": [
|
||||||
{
|
{
|
||||||
"id": "abc-123-def",
|
"id": "abc-123-def",
|
||||||
"title": "Einkaufsliste",
|
"title": "Shopping List",
|
||||||
"content": "Milch\nBrot\nKäse",
|
"content": "Milk\nBread\nCheese",
|
||||||
"createdAt": 1704467422000,
|
"createdAt": 1704467422000,
|
||||||
"updatedAt": 1704467422000
|
"updatedAt": 1704467422000
|
||||||
}
|
}
|
||||||
@@ -54,105 +54,105 @@ Das Backup-System funktioniert **komplett offline** und unabhängig vom WebDAV-S
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Format-Details:**
|
**Format details:**
|
||||||
- ✅ Menschenlesbar (formatiertes JSON)
|
- ✅ Human-readable (formatted JSON)
|
||||||
- ✅ Alle Daten inklusive (Titel, Inhalt, IDs, Timestamps)
|
- ✅ All data included (title, content, IDs, timestamps)
|
||||||
- ✅ Versions-Info für Kompatibilität
|
- ✅ Version info for compatibility
|
||||||
- ✅ Anzahl der Notizen für Validierung
|
- ✅ Note count for validation
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📤 Backup wiederherstellen
|
## 📤 Restore Backup
|
||||||
|
|
||||||
### 3 Wiederherstellungs-Modi
|
### 3 Restore Modes
|
||||||
|
|
||||||
#### 1. Zusammenführen (Merge) ⭐ _Empfohlen_
|
#### 1. Merge ⭐ _Recommended_
|
||||||
|
|
||||||
**Was passiert:**
|
**What happens:**
|
||||||
- ✅ Neue Notizen aus Backup werden hinzugefügt
|
- ✅ New notes from backup are added
|
||||||
- ✅ Bestehende Notizen bleiben unverändert
|
- ✅ Existing notes remain unchanged
|
||||||
- ✅ Keine Datenverluste
|
- ✅ No data loss
|
||||||
|
|
||||||
**Wann nutzen:**
|
**When to use:**
|
||||||
- Backup von anderem Gerät einspielen
|
- Import backup from another device
|
||||||
- Alte Notizen zurückholen
|
- Recover old notes
|
||||||
- Versehentlich gelöschte Notizen wiederherstellen
|
- Restore accidentally deleted notes
|
||||||
|
|
||||||
**Beispiel:**
|
**Example:**
|
||||||
```
|
```
|
||||||
App: [Notiz A, Notiz B, Notiz C]
|
App: [Note A, Note B, Note C]
|
||||||
Backup: [Notiz A, Notiz D, Notiz E]
|
Backup: [Note A, Note D, Note E]
|
||||||
Ergebnis: [Notiz A, Notiz B, Notiz C, Notiz D, Notiz E]
|
Result: [Note A, Note B, Note C, Note D, Note E]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 2. Ersetzen (Replace)
|
#### 2. Replace
|
||||||
|
|
||||||
**Was passiert:**
|
**What happens:**
|
||||||
- ❌ ALLE bestehenden Notizen werden gelöscht
|
- ❌ ALL existing notes are deleted
|
||||||
- ✅ Backup-Notizen werden importiert
|
- ✅ Backup notes are imported
|
||||||
- ⚠️ Unwiderruflich (außer durch Auto-Backup)
|
- ⚠️ Irreversible (except through auto-backup)
|
||||||
|
|
||||||
**Wann nutzen:**
|
**When to use:**
|
||||||
- Server-Wechsel (kompletter Neustart)
|
- Server migration (complete restart)
|
||||||
- Zurück zu altem Backup-Stand
|
- Return to old backup state
|
||||||
- App-Neuinstallation
|
- App reinstallation
|
||||||
|
|
||||||
**Beispiel:**
|
**Example:**
|
||||||
```
|
```
|
||||||
App: [Notiz A, Notiz B, Notiz C]
|
App: [Note A, Note B, Note C]
|
||||||
Backup: [Notiz X, Notiz Y]
|
Backup: [Note X, Note Y]
|
||||||
Ergebnis: [Notiz X, Notiz 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:**
|
**What happens:**
|
||||||
- ✅ Neue Notizen aus Backup werden hinzugefügt
|
- ✅ New notes from backup are added
|
||||||
- 🔄 Bei ID-Konflikten gewinnt das Backup
|
- 🔄 On ID conflicts, backup wins
|
||||||
- ✅ Andere Notizen bleiben unverändert
|
- ✅ Other notes remain unchanged
|
||||||
|
|
||||||
**Wann nutzen:**
|
**When to use:**
|
||||||
- Backup ist neuer als App-Daten
|
- Backup is newer than app data
|
||||||
- Desktop-Änderungen einspielen
|
- Import desktop changes
|
||||||
- Konflikt-Auflösung
|
- Conflict resolution
|
||||||
|
|
||||||
**Beispiel:**
|
**Example:**
|
||||||
```
|
```
|
||||||
App: [Notiz A (v1), Notiz B, Notiz C]
|
App: [Note A (v1), Note B, Note C]
|
||||||
Backup: [Notiz A (v2), Notiz D]
|
Backup: [Note A (v2), Note D]
|
||||||
Ergebnis: [Notiz A (v2), Notiz B, Notiz C, Notiz D]
|
Result: [Note A (v2), Note B, Note C, Note D]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Wiederherstellungs-Prozess
|
### Restore Process
|
||||||
|
|
||||||
1. **Einstellungen** → **"📤 Aus Datei wiederherstellen"**
|
1. **Settings** → **"📤 Restore from file"**
|
||||||
2. **Backup-Datei auswählen** (`.json`)
|
2. **Select backup file** (`.json`)
|
||||||
3. **Modus wählen:**
|
3. **Choose mode:**
|
||||||
- 🔵 Zusammenführen _(Standard)_
|
- 🔵 Merge _(Default)_
|
||||||
- 🟡 Duplikate überschreiben
|
- 🟡 Overwrite duplicates
|
||||||
- 🔴 Ersetzen _(Vorsicht!)_
|
- 🔴 Replace _(Caution!)_
|
||||||
4. **Bestätigen** - Automatisches Sicherheits-Backup wird erstellt
|
4. **Confirm** - Automatic safety backup is created
|
||||||
5. **Warten** - Import läuft
|
5. **Wait** - Import runs
|
||||||
6. **Fertig!** - Erfolgsmeldung mit Anzahl importierter Notizen
|
6. **Done!** - Success message with number of imported notes
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🛡️ Automatisches Sicherheits-Backup
|
## 🛡️ Automatic Safety Backup
|
||||||
|
|
||||||
**Vor jeder Wiederherstellung:**
|
**Before every restore:**
|
||||||
- ✅ Automatisches Backup wird erstellt
|
- ✅ Automatic backup is created
|
||||||
- 📁 Gespeichert in: `Android/data/dev.dettmer.simplenotes/files/`
|
- 📁 Saved in: `Android/data/dev.dettmer.simplenotes/files/`
|
||||||
- 🏷️ Dateiname: `auto_backup_before_restore_YYYY-MM-DD_HHmmss.json`
|
- 🏷️ Filename: `auto_backup_before_restore_YYYY-MM-DD_HHmmss.json`
|
||||||
- ⏱️ Zeitstempel: Direkt vor Wiederherstellung
|
- ⏱️ Timestamp: Right before restore
|
||||||
|
|
||||||
**Warum?**
|
**Why?**
|
||||||
- Schutz vor versehentlichem "Ersetzen"
|
- Protection against accidental "Replace"
|
||||||
- Möglichkeit zum Rückgängigmachen
|
- Ability to undo
|
||||||
- Doppelte Sicherheit
|
- Double security
|
||||||
|
|
||||||
**Zugriff via Dateimanager:**
|
**Access via file manager:**
|
||||||
```
|
```
|
||||||
/Android/data/dev.dettmer.simplenotes/files/auto_backup_before_restore_*.json
|
/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
|
## 💡 Best Practices
|
||||||
|
|
||||||
### Backup-Strategie
|
### Backup Strategy
|
||||||
|
|
||||||
#### Regelmäßige Backups
|
#### Regular Backups
|
||||||
```
|
```
|
||||||
Täglich: ❌ Zu oft (Server-Sync reicht)
|
Daily: ❌ Too often (server sync is enough)
|
||||||
Wöchentlich: ✅ Empfohlen für wichtige Notizen
|
Weekly: ✅ Recommended for important notes
|
||||||
Monatlich: ✅ Archivierung
|
Monthly: ✅ Archiving
|
||||||
Vor Updates: ✅ Sicherheit
|
Before updates: ✅ Safety
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 3-2-1 Regel
|
#### 3-2-1 Rule
|
||||||
1. **3 Kopien** - Original + 2 Backups
|
1. **3 copies** - Original + 2 backups
|
||||||
2. **2 Medien** - z.B. SD-Karte + Cloud
|
2. **2 media** - e.g., SD card + cloud
|
||||||
3. **1 Offsite** - z.B. Cloud-Speicher
|
3. **1 offsite** - e.g., cloud storage
|
||||||
|
|
||||||
### Backup-Speicherorte
|
### Backup Locations
|
||||||
|
|
||||||
**Lokal (schnell):**
|
**Local (fast):**
|
||||||
- 📱 Internal Storage / Downloads
|
- 📱 Internal storage / Downloads
|
||||||
- 💳 SD-Karte
|
- 💳 SD card
|
||||||
- 🖥️ PC (via USB)
|
- 🖥️ PC (via USB)
|
||||||
|
|
||||||
**Cloud (sicher):**
|
**Cloud (secure):**
|
||||||
- ☁️ Nextcloud (Self-Hosted)
|
- ☁️ Nextcloud (self-hosted)
|
||||||
- 📧 E-Mail an sich selbst
|
- 📧 Email to yourself
|
||||||
- 🗄️ Syncthing (Sync zwischen Geräten)
|
- 🗄️ Syncthing (sync between devices)
|
||||||
|
|
||||||
**⚠️ Vermeiden:**
|
**⚠️ Avoid:**
|
||||||
- ❌ Google Drive / Dropbox (Privacy)
|
- ❌ Google Drive / Dropbox (privacy)
|
||||||
- ❌ Nur eine Kopie
|
- ❌ Only one copy
|
||||||
- ❌ Nur auf Server (wenn Server ausfällt)
|
- ❌ 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
|
1. **Open with:** VS Code, Notepad++, nano
|
||||||
2. **Notizen hinzufügen/entfernen**
|
2. **Add/remove notes**
|
||||||
3. **Titel/Inhalt ändern**
|
3. **Change title/content**
|
||||||
4. **IDs anpassen** (für Migration)
|
4. **Adjust IDs** (for migration)
|
||||||
5. **Speichern** und in App importieren
|
5. **Save** and import to app
|
||||||
|
|
||||||
**⚠️ Wichtig:**
|
**⚠️ Important:**
|
||||||
- Valides JSON-Format behalten
|
- Keep valid JSON format
|
||||||
- IDs müssen eindeutig sein (UUIDs)
|
- IDs must be unique (UUIDs)
|
||||||
- Timestamps in Millisekunden (Unix Epoch)
|
- Timestamps in milliseconds (Unix Epoch)
|
||||||
|
|
||||||
### Bulk-Import
|
### Bulk Import
|
||||||
|
|
||||||
Mehrere Backups zusammenführen:
|
Merge multiple backups:
|
||||||
|
|
||||||
1. Backup 1 importieren (Modus: Zusammenführen)
|
1. Import backup 1 (Mode: Merge)
|
||||||
2. Backup 2 importieren (Modus: Zusammenführen)
|
2. Import backup 2 (Mode: Merge)
|
||||||
3. Backup 3 importieren (Modus: Zusammenführen)
|
3. Import backup 3 (Mode: Merge)
|
||||||
4. Ergebnis: Alle Notizen vereint
|
4. Result: All notes combined
|
||||||
|
|
||||||
### Server-Migration
|
### Server Migration
|
||||||
|
|
||||||
Schritt-für-Schritt:
|
Step-by-step:
|
||||||
|
|
||||||
1. **Backup erstellen** auf altem Server
|
1. **Create backup** on old server
|
||||||
2. **Neuen Server einrichten** (siehe [QUICKSTART.md](QUICKSTART.md))
|
2. **Set up new server** (see [QUICKSTART.en.md](QUICKSTART.en.md))
|
||||||
3. **Server-URL ändern** in App-Einstellungen
|
3. **Change server URL** in app settings
|
||||||
4. **Backup wiederherstellen** (Modus: Ersetzen)
|
4. **Restore backup** (Mode: Replace)
|
||||||
5. **Sync testen** - Alle Notizen auf neuem Server
|
5. **Test sync** - All notes on new server
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ❌ Fehlerbehebung
|
## ❌ Troubleshooting
|
||||||
|
|
||||||
### "Backup-Datei ungültig"
|
### "Invalid backup file"
|
||||||
|
|
||||||
**Ursachen:**
|
**Causes:**
|
||||||
- Korrupte JSON-Datei
|
- Corrupt JSON file
|
||||||
- Falsche Datei-Endung (muss `.json` sein)
|
- Wrong file extension (must be `.json`)
|
||||||
- Inkompatible App-Version
|
- Incompatible app version
|
||||||
|
|
||||||
**Lösung:**
|
**Solution:**
|
||||||
1. JSON-Datei mit Validator prüfen (z.B. jsonlint.com)
|
1. Check JSON file with validator (e.g., jsonlint.com)
|
||||||
2. Dateiendung überprüfen
|
2. Verify file extension
|
||||||
3. Backup mit aktueller App-Version erstellen
|
3. Create backup with current app version
|
||||||
|
|
||||||
### "Keine Berechtigung zum Speichern"
|
### "No permission to save"
|
||||||
|
|
||||||
**Ursachen:**
|
**Causes:**
|
||||||
- Speicher-Berechtigung fehlt
|
- Storage permission missing
|
||||||
- Schreibgeschützter Ordner
|
- Write-protected folder
|
||||||
|
|
||||||
**Lösung:**
|
**Solution:**
|
||||||
1. Android: Einstellungen → Apps → Simple Notes → Berechtigungen
|
1. Android: Settings → Apps → Simple Notes → Permissions
|
||||||
2. "Speicher" aktivieren
|
2. Activate "Storage"
|
||||||
3. Anderen Speicherort wählen
|
3. Choose different location
|
||||||
|
|
||||||
### "Import fehlgeschlagen"
|
### "Import failed"
|
||||||
|
|
||||||
**Ursachen:**
|
**Causes:**
|
||||||
- Zu wenig Speicherplatz
|
- Not enough storage space
|
||||||
- Korrupte Backup-Datei
|
- Corrupt backup file
|
||||||
- App-Crash während Import
|
- App crash during import
|
||||||
|
|
||||||
**Lösung:**
|
**Solution:**
|
||||||
1. Speicherplatz freigeben
|
1. Free up storage space
|
||||||
2. Backup-Datei neu erstellen
|
2. Create new backup file
|
||||||
3. App neu starten und erneut importieren
|
3. Restart app and try again
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔒 Sicherheit & Privacy
|
## 🔒 Security & Privacy
|
||||||
|
|
||||||
### Daten-Schutz
|
### Data Protection
|
||||||
- ✅ **Lokal gespeichert** - Kein Cloud-Upload ohne deine Aktion
|
- ✅ **Locally stored** - No cloud upload without your action
|
||||||
- ✅ **Keine Verschlüsselung** - Klartextformat für Lesbarkeit
|
- ✅ **No encryption** - Plain text format for readability
|
||||||
- ⚠️ **Sensible Daten?** - Backup-Datei selbst verschlüsseln (z.B. 7-Zip mit Passwort)
|
- ⚠️ **Sensitive data?** - Encrypt backup file yourself (e.g., 7-Zip with password)
|
||||||
|
|
||||||
### Empfehlungen
|
### Recommendations
|
||||||
- 🔐 Backup-Dateien in verschlüsseltem Container speichern
|
- 🔐 Store backup files in encrypted container
|
||||||
- 🗑️ Alte Backups regelmäßig löschen
|
- 🗑️ Regularly delete old backups
|
||||||
- 📧 Nicht per unverschlüsselter E-Mail versenden
|
- 📧 Don't send via unencrypted email
|
||||||
- ☁️ Self-Hosted Cloud nutzen (Nextcloud)
|
- ☁️ Use self-hosted cloud (Nextcloud)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📊 Technische Details
|
## 📊 Technical Details
|
||||||
|
|
||||||
### Format-Spezifikation
|
### Format Specification
|
||||||
|
|
||||||
**JSON-Struktur:**
|
**JSON structure:**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"version": "string", // App-Version beim Export
|
"version": "string", // App version at export
|
||||||
"exported_at": "ISO8601", // Zeitstempel des Exports
|
"exported_at": "ISO8601", // Export timestamp
|
||||||
"notes_count": number, // Anzahl der Notizen
|
"notes_count": number, // Number of notes
|
||||||
"notes": [
|
"notes": [
|
||||||
{
|
{
|
||||||
"id": "UUID", // Eindeutige ID
|
"id": "UUID", // Unique ID
|
||||||
"title": "string", // Notiz-Titel
|
"title": "string", // Note title
|
||||||
"content": "string", // Notiz-Inhalt
|
"content": "string", // Note content
|
||||||
"createdAt": number, // Unix Timestamp (ms)
|
"createdAt": number, // Unix timestamp (ms)
|
||||||
"updatedAt": number // Unix Timestamp (ms)
|
"updatedAt": number // Unix timestamp (ms)
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Kompatibilität
|
### Compatibility
|
||||||
- ✅ v1.2.0+ - Vollständig kompatibel
|
- ✅ v1.2.0+ - Fully compatible
|
||||||
- ⚠️ v1.1.x - Grundfunktionen (ohne Auto-Backup)
|
- ⚠️ v1.1.x - Basic functions (without auto-backup)
|
||||||
- ❌ v1.0.x - Nicht unterstützt
|
- ❌ v1.0.x - Not supported
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**📚 Siehe auch:**
|
**📚 See also:**
|
||||||
- [QUICKSTART.md](../QUICKSTART.md) - App-Installation und Einrichtung
|
- [QUICKSTART.en.md](../QUICKSTART.en.md) - App installation and setup
|
||||||
- [FEATURES.md](FEATURES.md) - Vollständige Feature-Liste
|
- [FEATURES.en.md](FEATURES.en.md) - Complete feature list
|
||||||
- [DESKTOP.md](DESKTOP.md) - Desktop-Integration mit Markdown
|
- [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)
|
||||||
|
|||||||
505
docs/DESKTOP.de.md
Normal file
505
docs/DESKTOP.de.md
Normal file
@@ -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)
|
||||||
@@ -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)
|
|
||||||
506
docs/DESKTOP.md
506
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:
|
Desktop integration allows you to edit notes on PC/Mac:
|
||||||
- 📝 Jeder Markdown-Editor funktioniert
|
- 📝 Any Markdown editor works
|
||||||
- 🔄 Automatische Synchronisation über WebDAV
|
- 🔄 Automatic synchronization via WebDAV
|
||||||
- 💾 Dual-Format: JSON (Master) + Markdown (Mirror)
|
- 💾 Dual-format: JSON (master) + Markdown (mirror)
|
||||||
- ⚡ Last-Write-Wins Konfliktauflösung
|
- ⚡ 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):**
|
**JSON (Master):**
|
||||||
- ✅ Zuverlässig und schnell
|
- ✅ Reliable and fast
|
||||||
- ✅ Strukturierte Daten (IDs, Timestamps)
|
- ✅ Structured data (IDs, timestamps)
|
||||||
- ✅ Primärer Sync-Mechanismus
|
- ✅ Primary sync mechanism
|
||||||
- ✅ Immer aktiv
|
- ✅ Always active
|
||||||
|
|
||||||
**Markdown (Mirror):**
|
**Markdown (Mirror):**
|
||||||
- ✅ Menschenlesbar
|
- ✅ Human-readable
|
||||||
- ✅ Desktop-Editor kompatibel
|
- ✅ Desktop editor compatible
|
||||||
- ✅ Syntax-Highlighting
|
- ✅ Syntax highlighting
|
||||||
- ✅ Optional aktivierbar
|
- ✅ 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))
|
1. **Set up app** (see [QUICKSTART.en.md](QUICKSTART.en.md))
|
||||||
2. **Server-Verbindung testen**
|
2. **Test server connection**
|
||||||
3. **Erste Notiz erstellen**
|
3. **Create first note**
|
||||||
4. **Synchronisieren** (Pull-to-Refresh oder Auto-Sync)
|
4. **Synchronize** (pull-to-refresh or auto-sync)
|
||||||
5. ✅ Server erstellt automatisch `/notes/` und `/notes-md/` Ordner
|
5. ✅ Server automatically creates `/notes/` and `/notes-md/` folders
|
||||||
|
|
||||||
### 2. Desktop-Integration aktivieren
|
### 2. Activate Desktop Integration
|
||||||
|
|
||||||
1. **Einstellungen** → **Desktop-Integration**
|
1. **Settings** → **Desktop Integration**
|
||||||
2. **Toggle aktivieren**
|
2. **Toggle ON**
|
||||||
3. **Initial Export startet** - Zeigt Progress (X/Y)
|
3. **Initial export starts** - Shows progress (X/Y)
|
||||||
4. ✅ Alle bestehenden Notizen werden als `.md` exportiert
|
4. ✅ All existing notes are exported as `.md`
|
||||||
|
|
||||||
### 3. WebDAV als Netzlaufwerk mounten
|
### 3. Mount WebDAV as Network Drive
|
||||||
|
|
||||||
#### Windows
|
#### Windows
|
||||||
|
|
||||||
```
|
```
|
||||||
1. Explorer öffnen
|
1. Open Explorer
|
||||||
2. Rechtsklick auf "Dieser PC"
|
2. Right-click on "This PC"
|
||||||
3. "Netzlaufwerk verbinden"
|
3. "Map network drive"
|
||||||
4. URL eingeben: http://DEIN-SERVER:8080/notes-md/
|
4. Enter URL: http://YOUR-SERVER:8080/notes-md/
|
||||||
5. Benutzername: noteuser
|
5. Username: noteuser
|
||||||
6. Passwort: (dein WebDAV-Passwort)
|
6. Password: (your WebDAV password)
|
||||||
7. Laufwerksbuchstabe: Z:\ (oder beliebig)
|
7. Drive letter: Z:\ (or any)
|
||||||
8. Fertig!
|
8. Done!
|
||||||
```
|
```
|
||||||
|
|
||||||
**Zugriff:** `Z:\` im Explorer
|
**Access:** `Z:\` in Explorer
|
||||||
|
|
||||||
#### macOS
|
#### macOS
|
||||||
|
|
||||||
```
|
```
|
||||||
1. Finder öffnen
|
1. Open Finder
|
||||||
2. Menü "Gehe zu" → "Mit Server verbinden" (⌘K)
|
2. Menu "Go" → "Connect to Server" (⌘K)
|
||||||
3. Server-Adresse: http://DEIN-SERVER:8080/notes-md/
|
3. Server address: http://YOUR-SERVER:8080/notes-md/
|
||||||
4. Verbinden
|
4. Connect
|
||||||
5. Benutzername: noteuser
|
5. Username: noteuser
|
||||||
6. Passwort: (dein WebDAV-Passwort)
|
6. Password: (your WebDAV password)
|
||||||
7. Fertig!
|
7. Done!
|
||||||
```
|
```
|
||||||
|
|
||||||
**Zugriff:** Finder → Netzwerk → notes-md
|
**Access:** Finder → Network → notes-md
|
||||||
|
|
||||||
#### Linux (GNOME)
|
#### Linux (GNOME)
|
||||||
|
|
||||||
```
|
```
|
||||||
1. Files / Nautilus öffnen
|
1. Open Files / Nautilus
|
||||||
2. "Andere Orte"
|
2. "Other Locations"
|
||||||
3. "Mit Server verbinden"
|
3. "Connect to Server"
|
||||||
4. Server-Adresse: dav://DEIN-SERVER:8080/notes-md/
|
4. Server address: dav://YOUR-SERVER:8080/notes-md/
|
||||||
5. Benutzername: noteuser
|
5. Username: noteuser
|
||||||
6. Passwort: (dein WebDAV-Passwort)
|
6. Password: (your WebDAV password)
|
||||||
7. Fertig!
|
7. Done!
|
||||||
```
|
```
|
||||||
|
|
||||||
**Zugriff:** `/run/user/1000/gvfs/dav:host=...`
|
**Access:** `/run/user/1000/gvfs/dav:host=...`
|
||||||
|
|
||||||
#### Linux (davfs2 - permanent)
|
#### Linux (davfs2 - permanent)
|
||||||
|
|
||||||
@@ -131,101 +131,101 @@ Die Desktop-Integration ermöglicht dir, Notizen auf dem PC/Mac zu bearbeiten:
|
|||||||
# Installation
|
# Installation
|
||||||
sudo apt install davfs2
|
sudo apt install davfs2
|
||||||
|
|
||||||
# Mount-Point erstellen
|
# Create mount point
|
||||||
sudo mkdir -p /mnt/notes-md
|
sudo mkdir -p /mnt/notes-md
|
||||||
|
|
||||||
# Einmalig mounten
|
# Mount once
|
||||||
sudo mount -t davfs http://DEIN-SERVER:8080/notes-md/ /mnt/notes-md
|
sudo mount -t davfs http://YOUR-SERVER:8080/notes-md/ /mnt/notes-md
|
||||||
|
|
||||||
# Permanent in /etc/fstab
|
# 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:**
|
**Advantages:**
|
||||||
- ✅ Kostenlos & Open Source
|
- ✅ Free & open source
|
||||||
- ✅ Markdown-Preview (Ctrl+Shift+V)
|
- ✅ Markdown preview (Ctrl+Shift+V)
|
||||||
- ✅ Syntax-Highlighting
|
- ✅ Syntax highlighting
|
||||||
- ✅ Git-Integration
|
- ✅ Git integration
|
||||||
- ✅ Erweiterungen (Spell Check, etc.)
|
- ✅ Extensions (spell check, etc.)
|
||||||
|
|
||||||
**Setup:**
|
**Setup:**
|
||||||
```
|
```
|
||||||
1. VS Code installieren
|
1. Install VS Code
|
||||||
2. WebDAV-Laufwerk mounten
|
2. Mount WebDAV drive
|
||||||
3. Ordner öffnen: Z:\notes-md\ (Windows) oder /mnt/notes-md (Linux)
|
3. Open folder: Z:\notes-md\ (Windows) or /mnt/notes-md (Linux)
|
||||||
4. Fertig! Markdown-Dateien bearbeiten
|
4. Done! Edit Markdown files
|
||||||
```
|
```
|
||||||
|
|
||||||
**Extensions (optional):**
|
**Extensions (optional):**
|
||||||
- `Markdown All in One` - Shortcuts & Preview
|
- `Markdown All in One` - Shortcuts & preview
|
||||||
- `Markdown Preview Enhanced` - Bessere Preview
|
- `Markdown Preview Enhanced` - Better preview
|
||||||
- `Code Spell Checker` - Rechtschreibprüfung
|
- `Code Spell Checker` - Spell checking
|
||||||
|
|
||||||
#### 2. Typora
|
#### 2. Typora
|
||||||
|
|
||||||
**Vorteile:**
|
**Advantages:**
|
||||||
- ✅ WYSIWYG Markdown-Editor
|
- ✅ WYSIWYG Markdown editor
|
||||||
- ✅ Minimalistisches Design
|
- ✅ Minimalist design
|
||||||
- ✅ Live-Preview
|
- ✅ Live preview
|
||||||
- ⚠️ Kostenpflichtig (~15€)
|
- ⚠️ Paid (~15€)
|
||||||
|
|
||||||
**Setup:**
|
**Setup:**
|
||||||
```
|
```
|
||||||
1. Typora installieren
|
1. Install Typora
|
||||||
2. WebDAV mounten
|
2. Mount WebDAV
|
||||||
3. Ordner in Typora öffnen
|
3. Open folder in Typora
|
||||||
4. Notizen bearbeiten
|
4. Edit notes
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 3. Notepad++
|
#### 3. Notepad++
|
||||||
|
|
||||||
**Vorteile:**
|
**Advantages:**
|
||||||
- ✅ Leichtgewichtig
|
- ✅ Lightweight
|
||||||
- ✅ Schnell
|
- ✅ Fast
|
||||||
- ✅ Syntax-Highlighting
|
- ✅ Syntax highlighting
|
||||||
- ⚠️ Keine Markdown-Preview
|
- ⚠️ No Markdown preview
|
||||||
|
|
||||||
**Setup:**
|
**Setup:**
|
||||||
```
|
```
|
||||||
1. Notepad++ installieren
|
1. Install Notepad++
|
||||||
2. WebDAV mounten
|
2. Mount WebDAV
|
||||||
3. Dateien direkt öffnen
|
3. Open files directly
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 4. Obsidian
|
#### 4. Obsidian
|
||||||
|
|
||||||
**Vorteile:**
|
**Advantages:**
|
||||||
- ✅ Zweite Gehirn-Philosophie
|
- ✅ Second brain philosophy
|
||||||
- ✅ Graph-View für Verlinkungen
|
- ✅ Graph view for links
|
||||||
- ✅ Viele Plugins
|
- ✅ Many plugins
|
||||||
- ⚠️ Sync-Konflikte möglich (2 Master)
|
- ⚠️ Sync conflicts possible (2 masters)
|
||||||
|
|
||||||
**Setup:**
|
**Setup:**
|
||||||
```
|
```
|
||||||
1. Obsidian installieren
|
1. Install Obsidian
|
||||||
2. WebDAV als Vault öffnen
|
2. Open WebDAV as vault
|
||||||
3. Vorsicht: Obsidian erstellt eigene Metadaten!
|
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
|
```markdown
|
||||||
---
|
---
|
||||||
@@ -235,114 +235,114 @@ updated: 2026-01-05T14:30:22Z
|
|||||||
tags: []
|
tags: []
|
||||||
---
|
---
|
||||||
|
|
||||||
# Notiz-Titel
|
# Note Title
|
||||||
|
|
||||||
Notiz-Inhalt hier...
|
Note content here...
|
||||||
```
|
```
|
||||||
|
|
||||||
### Frontmatter-Felder
|
### Frontmatter Fields
|
||||||
|
|
||||||
| Feld | Typ | Beschreibung | Pflicht |
|
| Field | Type | Description | Required |
|
||||||
|------|-----|--------------|---------|
|
|-------|------|-------------|----------|
|
||||||
| `id` | UUID | Eindeutige Notiz-ID | ✅ Ja |
|
| `id` | UUID | Unique note ID | ✅ Yes |
|
||||||
| `created` | ISO8601 | Erstellungsdatum | ✅ Ja |
|
| `created` | ISO8601 | Creation date | ✅ Yes |
|
||||||
| `updated` | ISO8601 | Änderungsdatum | ✅ Ja |
|
| `updated` | ISO8601 | Modification date | ✅ Yes |
|
||||||
| `tags` | Array | Tags (zukünftig) | ❌ Nein |
|
| `tags` | Array | Tags (future) | ❌ No |
|
||||||
|
|
||||||
### Dateinamen
|
### Filenames
|
||||||
|
|
||||||
**Sanitization-Regeln:**
|
**Sanitization rules:**
|
||||||
```
|
```
|
||||||
Titel: "Meine Einkaufsliste 🛒"
|
Title: "My Shopping List 🛒"
|
||||||
→ Dateiname: "Meine_Einkaufsliste.md"
|
→ Filename: "My_Shopping_List.md"
|
||||||
|
|
||||||
Entfernt werden:
|
Removed:
|
||||||
- Emojis: 🛒 → entfernt
|
- Emojis: 🛒 → removed
|
||||||
- Sonderzeichen: / \ : * ? " < > | → entfernt
|
- Special chars: / \ : * ? " < > | → removed
|
||||||
- Mehrfache Leerzeichen → einzelnes Leerzeichen
|
- Multiple spaces → single space
|
||||||
- Leerzeichen → Unterstrich _
|
- Spaces → underscore _
|
||||||
```
|
```
|
||||||
|
|
||||||
**Beispiele:**
|
**Examples:**
|
||||||
```
|
```
|
||||||
"Meeting Notes 2026" → "Meeting_Notes_2026.md"
|
"Meeting Notes 2026" → "Meeting_Notes_2026.md"
|
||||||
"To-Do: Projekt" → "To-Do_Projekt.md"
|
"To-Do: Project" → "To-Do_Project.md"
|
||||||
"Urlaub ☀️" → "Urlaub.md"
|
"Vacation ☀️" → "Vacation.md"
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔄 Synchronisation
|
## 🔄 Synchronization
|
||||||
|
|
||||||
### Workflow: Android → Desktop
|
### Workflow: Android → Desktop
|
||||||
|
|
||||||
1. **Notiz in App erstellen/bearbeiten**
|
1. **Create/edit note in app**
|
||||||
2. **Sync ausführen** (Auto oder manuell)
|
2. **Run sync** (auto or manual)
|
||||||
3. **JSON wird hochgeladen** (`/notes/abc-123.json`)
|
3. **JSON is uploaded** (`/notes/abc-123.json`)
|
||||||
4. **Markdown wird exportiert** (`/notes-md/Notiz_Titel.md`) _(nur wenn Desktop-Integration AN)_
|
4. **Markdown is exported** (`/notes-md/Note_Title.md`) _(only if Desktop Integration ON)_
|
||||||
5. **Desktop-Editor zeigt Änderungen** (nach Refresh)
|
5. **Desktop editor shows changes** (after refresh)
|
||||||
|
|
||||||
### Workflow: Desktop → Android
|
### Workflow: Desktop → Android
|
||||||
|
|
||||||
1. **Markdown-Datei bearbeiten** (im gemounteten Ordner)
|
1. **Edit Markdown file** (in mounted folder)
|
||||||
2. **Speichern** - Datei liegt sofort auf Server
|
2. **Save** - File is immediately on server
|
||||||
3. **In App: Markdown-Import ausführen**
|
3. **In app: Run Markdown import**
|
||||||
- Einstellungen → "Import Markdown Changes"
|
- Settings → "Import Markdown Changes"
|
||||||
- Oder: Auto-Import bei jedem Sync (zukünftig)
|
- Or: Auto-import on every sync (future)
|
||||||
4. **App übernimmt Änderungen** (wenn Desktop-Version neuer)
|
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
|
App version: updated: 2026-01-05 14:00
|
||||||
Desktop-Version: updated: 2026-01-05 14:30
|
Desktop version: updated: 2026-01-05 14:30
|
||||||
→ Desktop gewinnt (neuerer Timestamp)
|
→ Desktop wins (newer timestamp)
|
||||||
```
|
```
|
||||||
|
|
||||||
**Automatisch:**
|
**Automatic:**
|
||||||
- ✅ Beim Markdown-Import
|
- ✅ On Markdown import
|
||||||
- ✅ Beim JSON-Sync
|
- ✅ On JSON sync
|
||||||
- ⚠️ Keine Merge-Konflikte - nur komplettes Überschreiben
|
- ⚠️ No merge conflicts - only complete overwrite
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ⚙️ Einstellungen
|
## ⚙️ Settings
|
||||||
|
|
||||||
### Desktop-Integration Toggle
|
### Desktop Integration Toggle
|
||||||
|
|
||||||
**Einstellungen → Desktop-Integration**
|
**Settings → Desktop Integration**
|
||||||
|
|
||||||
**AN (aktiviert):**
|
**ON (activated):**
|
||||||
- ✅ Neue Notizen → automatisch als `.md` exportiert
|
- ✅ New notes → automatically exported as `.md`
|
||||||
- ✅ Aktualisierte Notizen → `.md` Update
|
- ✅ Updated notes → `.md` update
|
||||||
- ✅ Gelöschte Notizen → `.md` bleibt (zukünftig: auch löschen)
|
- ✅ Deleted notes → `.md` remains (future: also delete)
|
||||||
|
|
||||||
**AUS (deaktiviert):**
|
**OFF (deactivated):**
|
||||||
- ❌ Kein Markdown-Export
|
- ❌ No Markdown export
|
||||||
- ✅ JSON-Sync läuft normal weiter
|
- ✅ JSON sync continues normally
|
||||||
- ✅ Bestehende `.md` Dateien bleiben erhalten
|
- ✅ Existing `.md` files remain
|
||||||
|
|
||||||
### Initial Export
|
### Initial Export
|
||||||
|
|
||||||
**Was passiert beim Aktivieren:**
|
**What happens on activation:**
|
||||||
1. Alle bestehenden Notizen werden gescannt
|
1. All existing notes are scanned
|
||||||
2. Progress-Dialog zeigt Fortschritt (z.B. "23/42")
|
2. Progress dialog shows progress (e.g., "23/42")
|
||||||
3. Jede Notiz wird als `.md` exportiert
|
3. Each note is exported as `.md`
|
||||||
4. Bei Fehlern: Einzelne Notiz wird übersprungen
|
4. On errors: Individual note is skipped
|
||||||
5. Erfolgsmeldung mit Anzahl exportierter Notizen
|
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
|
```markdown
|
||||||
---
|
---
|
||||||
@@ -351,35 +351,35 @@ created: 2026-01-05T12:00:00Z
|
|||||||
updated: 2026-01-05T12:00:00Z
|
updated: 2026-01-05T12:00:00Z
|
||||||
---
|
---
|
||||||
|
|
||||||
# Neue Desktop-Notiz
|
# New Desktop Note
|
||||||
|
|
||||||
Inhalt hier...
|
Content here...
|
||||||
```
|
```
|
||||||
|
|
||||||
**⚠️ Wichtig:**
|
**⚠️ Important:**
|
||||||
- `id` muss gültige UUID sein (z.B. mit uuidgen.io)
|
- `id` must be valid UUID (e.g., with uuidgen.io)
|
||||||
- Timestamps in ISO8601-Format
|
- Timestamps in ISO8601 format
|
||||||
- Frontmatter mit `---` umschließen
|
- Frontmatter enclosed with `---`
|
||||||
|
|
||||||
### Bulk-Operations
|
### Bulk Operations
|
||||||
|
|
||||||
**Mehrere Notizen auf einmal bearbeiten:**
|
**Edit multiple notes at once:**
|
||||||
|
|
||||||
1. WebDAV mounten
|
1. Mount WebDAV
|
||||||
2. Alle `.md` Dateien in VS Code öffnen
|
2. Open all `.md` files in VS Code
|
||||||
3. Suchen & Ersetzen über alle Dateien (Ctrl+Shift+H)
|
3. Find & Replace across all files (Ctrl+Shift+H)
|
||||||
4. Speichern
|
4. Save
|
||||||
5. In App: "Import Markdown Changes"
|
5. In app: "Import Markdown Changes"
|
||||||
|
|
||||||
### Scripting
|
### Scripting
|
||||||
|
|
||||||
**Beispiel: Alle Notizen nach Datum sortieren**
|
**Example: Sort all notes by date**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
cd /mnt/notes-md/
|
cd /mnt/notes-md/
|
||||||
|
|
||||||
# Alle .md Dateien nach Update-Datum sortieren
|
# Sort all .md files by update date
|
||||||
for file in *.md; do
|
for file in *.md; do
|
||||||
updated=$(grep "^updated:" "$file" | cut -d' ' -f2)
|
updated=$(grep "^updated:" "$file" | cut -d' ' -f2)
|
||||||
echo "$updated $file"
|
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:**
|
**Solution:**
|
||||||
1. **Erste Sync durchführen** - Ordner wird automatisch erstellt
|
1. **Perform first sync** - Folder is created automatically
|
||||||
2. ODER: Manuell erstellen via Terminal:
|
2. OR: Create manually via terminal:
|
||||||
```bash
|
```bash
|
||||||
curl -X MKCOL -u noteuser:password http://server:8080/notes-md/
|
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:**
|
**Solution:**
|
||||||
1. Einstellungen → "Desktop-Integration" AN
|
1. Settings → "Desktop Integration" ON
|
||||||
2. Warten auf Initial Export
|
2. Wait for initial export
|
||||||
3. WebDAV-Ordner refreshen
|
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:**
|
**Solution:**
|
||||||
1. Einstellungen → "Import Markdown Changes"
|
1. Settings → "Import Markdown Changes"
|
||||||
2. ODER: Auto-Sync abwarten (zukünftiges Feature)
|
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:**
|
**Solution:**
|
||||||
1. Datei in Editor öffnen
|
1. Open file in editor
|
||||||
2. Frontmatter am Anfang hinzufügen:
|
2. Add frontmatter at the beginning:
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
id: NEUE-UUID-HIER
|
id: NEW-UUID-HERE
|
||||||
created: 2026-01-05T12:00:00Z
|
created: 2026-01-05T12:00:00Z
|
||||||
updated: 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 ✅
|
### Do's ✅
|
||||||
|
|
||||||
- ✅ **Backup vor Bulk-Edits** - Lokales Backup erstellen
|
- ✅ **Backup before bulk edits** - Create local backup
|
||||||
- ✅ **Ein Editor zur Zeit** - Nicht parallel in App UND Desktop bearbeiten
|
- ✅ **One editor at a time** - Don't edit in app AND desktop in parallel
|
||||||
- ✅ **Sync abwarten** - Vor Desktop-Bearbeitung Sync durchführen
|
- ✅ **Wait for sync** - Run sync before desktop editing
|
||||||
- ✅ **Frontmatter respektieren** - Nicht manuell ändern (außer du weißt was du tust)
|
- ✅ **Respect frontmatter** - Don't change manually (unless you know what you're doing)
|
||||||
|
|
||||||
### Don'ts ❌
|
### Don'ts ❌
|
||||||
|
|
||||||
- ❌ **Parallel bearbeiten** - App und Desktop gleichzeitig → Konflikte
|
- ❌ **Parallel editing** - App and desktop simultaneously → conflicts
|
||||||
- ❌ **Frontmatter löschen** - Notiz kann nicht mehr importiert werden
|
- ❌ **Delete frontmatter** - Note can't be imported anymore
|
||||||
- ❌ **IDs ändern** - Notiz wird als neue erkannt
|
- ❌ **Change IDs** - Note is recognized as new
|
||||||
- ❌ **Timestamps manipulieren** - Konfliktauflösung funktioniert nicht
|
- ❌ **Manipulate timestamps** - Conflict resolution doesn't work
|
||||||
|
|
||||||
### Empfohlener Workflow
|
### Recommended Workflow
|
||||||
|
|
||||||
```
|
```
|
||||||
1. Sync in App (Pull-to-Refresh)
|
1. Sync in app (pull-to-refresh)
|
||||||
2. Desktop öffnen
|
2. Open desktop
|
||||||
3. Änderungen machen
|
3. Make changes
|
||||||
4. Speichern
|
4. Save
|
||||||
5. In App: "Import Markdown Changes"
|
5. In app: "Import Markdown Changes"
|
||||||
6. Überprüfen
|
6. Verify
|
||||||
7. Weiteren Sync durchführen
|
7. Run another sync
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📊 Vergleich: JSON vs Markdown
|
## 📊 Comparison: JSON vs Markdown
|
||||||
|
|
||||||
| Aspekt | JSON | Markdown |
|
| Aspect | JSON | Markdown |
|
||||||
|--------|------|----------|
|
|--------|------|----------|
|
||||||
| **Format** | Strukturiert | Fließtext |
|
| **Format** | Structured | Flowing text |
|
||||||
| **Lesbarkeit (Mensch)** | ⚠️ Mittel | ✅ Gut |
|
| **Readability (human)** | ⚠️ Medium | ✅ Good |
|
||||||
| **Lesbarkeit (Maschine)** | ✅ Perfekt | ⚠️ Parsing nötig |
|
| **Readability (machine)** | ✅ Perfect | ⚠️ Parsing needed |
|
||||||
| **Metadata** | Native | Frontmatter |
|
| **Metadata** | Native | Frontmatter |
|
||||||
| **Editoren** | Code-Editoren | Alle Text-Editoren |
|
| **Editors** | Code editors | All text editors |
|
||||||
| **Sync-Geschwindigkeit** | ✅ Schnell | ⚠️ Langsamer |
|
| **Sync speed** | ✅ Fast | ⚠️ Slower |
|
||||||
| **Zuverlässigkeit** | ✅ 100% | ⚠️ Frontmatter-Fehler möglich |
|
| **Reliability** | ✅ 100% | ⚠️ Frontmatter errors possible |
|
||||||
| **Mobile-First** | ✅ Ja | ❌ Nein |
|
| **Mobile-first** | ✅ Yes | ❌ No |
|
||||||
| **Desktop-First** | ❌ Nein | ✅ Ja |
|
| **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
|
- ⏳ **Auto-Markdown-import** - Automatically on every sync
|
||||||
- ⏳ **Bidirektionaler Sync** - Ohne manuellen Import
|
- ⏳ **Bidirectional sync** - Without manual import
|
||||||
- ⏳ **Markdown-Vorschau** - In der App
|
- ⏳ **Markdown preview** - In the app
|
||||||
- ⏳ **Konflikts-UI** - Bei gleichzeitigen Änderungen
|
- ⏳ **Conflict UI** - On simultaneous changes
|
||||||
- ⏳ **Tags in Frontmatter** - Synchronisiert mit App
|
- ⏳ **Tags in frontmatter** - Synchronized with app
|
||||||
- ⏳ **Attachments** - Bilder/Dateien in Markdown
|
- ⏳ **Attachments** - Images/files in Markdown
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**📚 Siehe auch:**
|
**📚 See also:**
|
||||||
- [QUICKSTART.md](../QUICKSTART.md) - App-Einrichtung
|
- [QUICKSTART.en.md](../QUICKSTART.en.md) - App setup
|
||||||
- [FEATURES.md](FEATURES.md) - Vollständige Feature-Liste
|
- [FEATURES.en.md](FEATURES.en.md) - Complete feature list
|
||||||
- [BACKUP.md](BACKUP.md) - Backup & Wiederherstellung
|
- [BACKUP.en.md](BACKUP.en.md) - Backup & restore
|
||||||
|
|
||||||
**Letzte Aktualisierung:** v1.2.1 (2026-01-05)
|
**Last update:** v1.2.1 (2026-01-05)
|
||||||
|
|||||||
@@ -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/
|
app/
|
||||||
├── models/
|
├── models/
|
||||||
│ ├── Note.kt # Data class for notes
|
│ ├── Note.kt # Data class für Notizen
|
||||||
│ └── SyncStatus.kt # Sync status enum
|
│ └── SyncStatus.kt # Sync-Status Enum
|
||||||
├── storage/
|
├── storage/
|
||||||
│ └── NotesStorage.kt # Local JSON file storage
|
│ └── NotesStorage.kt # Lokale JSON-Datei Speicherung
|
||||||
├── sync/
|
├── sync/
|
||||||
│ ├── WebDavSyncService.kt # WebDAV sync logic
|
│ ├── WebDavSyncService.kt # WebDAV Sync-Logik
|
||||||
│ ├── NetworkMonitor.kt # WiFi detection
|
│ ├── NetworkMonitor.kt # WLAN-Erkennung
|
||||||
│ ├── SyncWorker.kt # WorkManager background worker
|
│ ├── SyncWorker.kt # WorkManager Background Worker
|
||||||
│ └── BootReceiver.kt # Device reboot handler
|
│ └── BootReceiver.kt # Device Reboot Handler
|
||||||
├── adapters/
|
├── adapters/
|
||||||
│ └── NotesAdapter.kt # RecyclerView adapter
|
│ └── NotesAdapter.kt # RecyclerView Adapter
|
||||||
├── utils/
|
├── utils/
|
||||||
│ ├── Constants.kt # App constants
|
│ ├── Constants.kt # App-Konstanten
|
||||||
│ ├── NotificationHelper.kt# Notification management
|
│ ├── NotificationHelper.kt# Notification Management
|
||||||
│ └── Logger.kt # Debug/release logging
|
│ └── Logger.kt # Debug/Release Logging
|
||||||
└── activities/
|
└── activities/
|
||||||
├── MainActivity.kt # Main view with list
|
├── MainActivity.kt # Hauptansicht mit Liste
|
||||||
├── NoteEditorActivity.kt# Note editor
|
├── NoteEditorActivity.kt# Editor für Notizen
|
||||||
└── SettingsActivity.kt # Server configuration
|
└── SettingsActivity.kt # Server-Konfiguration
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔄 Auto-Sync Implementation
|
## 🔄 Auto-Sync Implementierung
|
||||||
|
|
||||||
### WorkManager Periodic Task
|
### WorkManager Periodic Task
|
||||||
|
|
||||||
Auto-sync is based on **WorkManager** with the following configuration:
|
Der Auto-Sync basiert auf **WorkManager** mit folgender Konfiguration:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
val constraints = Constraints.Builder()
|
val constraints = Constraints.Builder()
|
||||||
.setRequiredNetworkType(NetworkType.UNMETERED) // WiFi only
|
.setRequiredNetworkType(NetworkType.UNMETERED) // Nur WiFi
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(
|
val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(
|
||||||
30, TimeUnit.MINUTES, // Every 30 minutes
|
30, TimeUnit.MINUTES, // Alle 30 Minuten
|
||||||
10, TimeUnit.MINUTES // Flex interval
|
10, TimeUnit.MINUTES // Flex interval
|
||||||
)
|
)
|
||||||
.setConstraints(constraints)
|
.setConstraints(constraints)
|
||||||
.build()
|
.build()
|
||||||
```
|
```
|
||||||
|
|
||||||
**Why WorkManager?**
|
**Warum WorkManager?**
|
||||||
- ✅ Runs even when app is closed
|
- ✅ Läuft auch wenn App geschlossen ist
|
||||||
- ✅ Automatic restart after device reboot
|
- ✅ Automatischer Restart nach Device Reboot
|
||||||
- ✅ Battery-efficient (Android managed)
|
- ✅ Battery-efficient (Android managed)
|
||||||
- ✅ Guaranteed execution when constraints are met
|
- ✅ Garantierte Ausführung bei erfüllten Constraints
|
||||||
|
|
||||||
### Network Detection
|
### 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
|
```kotlin
|
||||||
fun isInHomeNetwork(): Boolean {
|
fun isInHomeNetwork(): Boolean {
|
||||||
val gatewayIP = getGatewayIP() // e.g. 192.168.0.1
|
val gatewayIP = getGatewayIP() // z.B. 192.168.0.1
|
||||||
val serverIP = extractIPFromUrl(serverUrl) // e.g. 192.168.0.188
|
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:**
|
**Vorteile:**
|
||||||
- ✅ No location permissions needed
|
- ✅ Keine Location Permissions nötig
|
||||||
- ✅ Works with all Android versions
|
- ✅ Funktioniert mit allen Android Versionen
|
||||||
- ✅ Reliable and fast
|
- ✅ Zuverlässig und schnell
|
||||||
|
|
||||||
### Sync Flow
|
### Sync Flow
|
||||||
|
|
||||||
```
|
```
|
||||||
1. WorkManager wakes up (every 30 min)
|
1. WorkManager wacht auf (alle 30 Min)
|
||||||
↓
|
↓
|
||||||
2. Check: WiFi connected?
|
2. Check: WiFi connected?
|
||||||
↓
|
↓
|
||||||
@@ -105,7 +105,7 @@ fun isInHomeNetwork(): Boolean {
|
|||||||
↓
|
↓
|
||||||
4. Load local notes
|
4. Load local notes
|
||||||
↓
|
↓
|
||||||
5. Upload new/changed notes → Server
|
5. Upload neue/geänderte Notes → Server
|
||||||
↓
|
↓
|
||||||
6. Download remote notes ← Server
|
6. Download remote notes ← Server
|
||||||
↓
|
↓
|
||||||
@@ -118,20 +118,20 @@ fun isInHomeNetwork(): Boolean {
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔄 Sync Trigger Overview
|
## <EFBFBD> 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? |
|
| Trigger | Datei | Funktion | Wann? | Pre-Check? |
|
||||||
|---------|------|----------|-------|------------|
|
|---------|-------|----------|-------|------------|
|
||||||
| **1. Manual Sync** | `MainActivity.kt` | `triggerManualSync()` | User clicks sync button in menu | ✅ Yes |
|
| **1. Manueller Sync** | `MainActivity.kt` | `triggerManualSync()` | User klickt auf Sync-Button im Menü | ✅ Ja |
|
||||||
| **2. Auto-Sync (onResume)** | `MainActivity.kt` | `triggerAutoSync()` | App opened/resumed | ✅ Yes |
|
| **2. Auto-Sync (onResume)** | `MainActivity.kt` | `triggerAutoSync()` | App wird geöffnet/fortgesetzt | ✅ Ja |
|
||||||
| **3. Background Sync (Periodic)** | `SyncWorker.kt` | `doWork()` | Every 15/30/60 minutes (configurable) | ✅ Yes |
|
| **3. Hintergrund-Sync (Periodic)** | `SyncWorker.kt` | `doWork()` | Alle 15/30/60 Minuten (konfigurierbar) | ✅ Ja |
|
||||||
| **4. WiFi-Connect Sync** | `NetworkMonitor.kt` → `SyncWorker.kt` | `triggerWifiConnectSync()` | WiFi connected | ✅ Yes |
|
| **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
|
```kotlin
|
||||||
// WebDavSyncService.kt - isServerReachable()
|
// WebDavSyncService.kt - isServerReachable()
|
||||||
@@ -148,53 +148,53 @@ suspend fun isServerReachable(): Boolean = withContext(Dispatchers.IO) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Why Socket Check instead of HTTP Request?**
|
**Warum Socket-Check statt HTTP-Request?**
|
||||||
- ⚡ **Faster:** Socket connect is instant, HTTP request takes longer
|
- ⚡ **Schneller:** Socket-Connect ist instant, HTTP-Request dauert länger
|
||||||
- 🔋 **Battery Efficient:** No HTTP overhead (headers, TLS handshake, etc.)
|
- 🔋 **Akkuschonender:** Kein HTTP-Overhead (Headers, TLS Handshake, etc.)
|
||||||
- 🎯 **More Precise:** Only checks network reachability, not server logic
|
- 🎯 **Präziser:** Prüft nur Netzwerk-Erreichbarkeit, nicht Server-Logik
|
||||||
- 🛡️ **Prevents Errors:** Detects foreign WiFi networks before sync error occurs
|
- 🛡️ **Verhindert Fehler:** Erkennt fremde WiFi-Netze bevor Sync-Fehler entsteht
|
||||||
|
|
||||||
**When does the check fail?**
|
**Wann schlägt der Check fehl?**
|
||||||
- ❌ Server offline/unreachable
|
- ❌ Server offline/nicht erreichbar
|
||||||
- ❌ Wrong WiFi network (e.g. public café WiFi)
|
- ❌ Falsches WiFi-Netzwerk (z.B. öffentliches Café-WiFi)
|
||||||
- ❌ Network not ready yet (DHCP/routing delay after WiFi connect)
|
- ❌ Netzwerk noch nicht bereit (DHCP/Routing-Delay nach WiFi-Connect)
|
||||||
- ❌ VPN blocks server access
|
- ❌ VPN blockiert Server-Zugriff
|
||||||
- ❌ No WebDAV server URL configured
|
- ❌ Keine WebDAV-Server-URL konfiguriert
|
||||||
|
|
||||||
### Sync Behavior by Trigger Type
|
### Sync-Verhalten nach Trigger-Typ
|
||||||
|
|
||||||
| Trigger | When server not reachable | On successful sync | Throttling |
|
| Trigger | Bei Server nicht erreichbar | Bei erfolgreichem Sync | Throttling |
|
||||||
|---------|--------------------------|-------------------|------------|
|
|---------|----------------------------|----------------------|------------|
|
||||||
| Manual Sync | Toast: "Server not reachable" | Toast: "✅ Synced: X notes" | None |
|
| Manueller Sync | Toast: "Server nicht erreichbar" | Toast: "✅ Gesynct: X Notizen" | Keins |
|
||||||
| Auto-Sync (onResume) | Silent abort (no toast) | Toast: "✅ Synced: X notes" | Max. 1x/min |
|
| Auto-Sync (onResume) | Silent abort (kein Toast) | Toast: "✅ Gesynct: X Notizen" | Max. 1x/Min |
|
||||||
| Background Sync | Silent abort (no toast) | Silent (LocalBroadcast only) | 15/30/60 min |
|
| Hintergrund-Sync | Silent abort (kein Toast) | Silent (LocalBroadcast only) | 15/30/60 Min |
|
||||||
| WiFi-Connect Sync | Silent abort (no toast) | Silent (LocalBroadcast only) | WiFi-based |
|
| 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 |
|
| WorkManager Wakeup | Alle 30 Min | ~0.15 mAh | System wacht auf |
|
||||||
| Network Check | 48x/day | ~0.03 mAh | Gateway IP check |
|
| Network Check | 48x/Tag | ~0.03 mAh | Gateway IP check |
|
||||||
| WebDAV Sync | 2-3x/day | ~1.5 mAh | Only when changes |
|
| WebDAV Sync | 2-3x/Tag | ~1.5 mAh | Nur bei Änderungen |
|
||||||
| **Total** | - | **~12 mAh/day** | **~0.4%** at 3000mAh |
|
| **Total** | - | **~12 mAh/Tag** | **~0.4%** bei 3000mAh |
|
||||||
|
|
||||||
### Optimizations
|
### Optimierungen
|
||||||
|
|
||||||
1. **IP Caching**
|
1. **IP Caching**
|
||||||
```kotlin
|
```kotlin
|
||||||
private var cachedServerIP: String? = null
|
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**
|
2. **Throttling**
|
||||||
```kotlin
|
```kotlin
|
||||||
private var lastSyncTime = 0L
|
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**
|
3. **Conditional Logging**
|
||||||
@@ -207,9 +207,9 @@ suspend fun isServerReachable(): Boolean = withContext(Dispatchers.IO) {
|
|||||||
```
|
```
|
||||||
|
|
||||||
4. **Network Constraints**
|
4. **Network Constraints**
|
||||||
- WiFi only (not mobile data)
|
- Nur WiFi (nicht mobile Daten)
|
||||||
- Only when server is reachable
|
- Nur wenn Server erreichbar
|
||||||
- No permanent listeners
|
- Keine permanenten Listeners
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -255,15 +255,15 @@ suspend fun downloadNotes(): DownloadResult {
|
|||||||
val localNote = storage.loadNote(remoteNote.id)
|
val localNote = storage.loadNote(remoteNote.id)
|
||||||
|
|
||||||
if (localNote == null) {
|
if (localNote == null) {
|
||||||
// New note from server
|
// Neue Note vom Server
|
||||||
storage.saveNote(remoteNote)
|
storage.saveNote(remoteNote)
|
||||||
downloadedCount++
|
downloadedCount++
|
||||||
} else if (localNote.modifiedAt < remoteNote.modifiedAt) {
|
} else if (localNote.modifiedAt < remoteNote.modifiedAt) {
|
||||||
// Server has newer version
|
// Server hat neuere Version
|
||||||
storage.saveNote(remoteNote)
|
storage.saveNote(remoteNote)
|
||||||
downloadedCount++
|
downloadedCount++
|
||||||
} else if (localNote.modifiedAt > remoteNote.modifiedAt) {
|
} else if (localNote.modifiedAt > remoteNote.modifiedAt) {
|
||||||
// Local version is newer → Conflict
|
// Lokale Version ist neuer → Conflict
|
||||||
resolveConflict(localNote, remoteNote)
|
resolveConflict(localNote, remoteNote)
|
||||||
conflictCount++
|
conflictCount++
|
||||||
}
|
}
|
||||||
@@ -275,19 +275,19 @@ suspend fun downloadNotes(): DownloadResult {
|
|||||||
|
|
||||||
### Conflict Resolution
|
### Conflict Resolution
|
||||||
|
|
||||||
Strategy: **Last-Write-Wins** with **Conflict Copy**
|
Strategie: **Last-Write-Wins** mit **Conflict Copy**
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
fun resolveConflict(local: Note, remote: Note) {
|
fun resolveConflict(local: Note, remote: Note) {
|
||||||
// Rename remote note (conflict copy)
|
// Remote Note umbenennen (Conflict Copy)
|
||||||
val conflictNote = remote.copy(
|
val conflictNote = remote.copy(
|
||||||
id = "${remote.id}_conflict_${System.currentTimeMillis()}",
|
id = "${remote.id}_conflict_${System.currentTimeMillis()}",
|
||||||
title = "${remote.title} (Conflict)"
|
title = "${remote.title} (Konflikt)"
|
||||||
)
|
)
|
||||||
|
|
||||||
storage.saveNote(conflictNote)
|
storage.saveNote(conflictNote)
|
||||||
|
|
||||||
// Local note remains
|
// Lokale Note bleibt
|
||||||
local.syncStatus = SyncStatus.SYNCED
|
local.syncStatus = SyncStatus.SYNCED
|
||||||
storage.saveNote(local)
|
storage.saveNote(local)
|
||||||
}
|
}
|
||||||
@@ -302,7 +302,7 @@ fun resolveConflict(local: Note, remote: Note) {
|
|||||||
```kotlin
|
```kotlin
|
||||||
val channel = NotificationChannel(
|
val channel = NotificationChannel(
|
||||||
"notes_sync_channel",
|
"notes_sync_channel",
|
||||||
"Notes Synchronization",
|
"Notizen Synchronisierung",
|
||||||
NotificationManager.IMPORTANCE_DEFAULT
|
NotificationManager.IMPORTANCE_DEFAULT
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
@@ -315,9 +315,9 @@ fun showSyncSuccess(context: Context, count: Int) {
|
|||||||
val pendingIntent = PendingIntent.getActivity(context, 0, intent, FLAGS)
|
val pendingIntent = PendingIntent.getActivity(context, 0, intent, FLAGS)
|
||||||
|
|
||||||
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
|
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
|
||||||
.setContentTitle("Sync successful")
|
.setContentTitle("Sync erfolgreich")
|
||||||
.setContentText("$count notes synchronized")
|
.setContentText("$count Notizen synchronisiert")
|
||||||
.setContentIntent(pendingIntent) // Click opens app
|
.setContentIntent(pendingIntent) // Click öffnet App
|
||||||
.setAutoCancel(true) // Dismiss on click
|
.setAutoCancel(true) // Dismiss on click
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
@@ -329,10 +329,10 @@ fun showSyncSuccess(context: Context, count: Int) {
|
|||||||
|
|
||||||
## 🛡️ Permissions
|
## 🛡️ Permissions
|
||||||
|
|
||||||
The app requires **minimal permissions**:
|
Die App benötigt **minimale Permissions**:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<!-- Network -->
|
<!-- Netzwerk -->
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
@@ -348,28 +348,28 @@ The app requires **minimal permissions**:
|
|||||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||||
```
|
```
|
||||||
|
|
||||||
**No Location Permissions!**
|
**Keine Location Permissions!**
|
||||||
We use Gateway IP Comparison instead of SSID detection. No location permission required.
|
Wir verwenden Gateway IP Comparison statt SSID-Erkennung. Keine Standortberechtigung nötig.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧪 Testing
|
## 🧪 Testing
|
||||||
|
|
||||||
### Test Server
|
### Server testen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# WebDAV server reachable?
|
# WebDAV Server erreichbar?
|
||||||
curl -u noteuser:password http://192.168.0.188:8080/
|
curl -u noteuser:password http://192.168.0.188:8080/
|
||||||
|
|
||||||
# Upload file
|
# Datei hochladen
|
||||||
echo '{"test":"data"}' > test.json
|
echo '{"test":"data"}' > test.json
|
||||||
curl -u noteuser:password -T test.json http://192.168.0.188:8080/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
|
curl -u noteuser:password http://192.168.0.188:8080/test.json
|
||||||
```
|
```
|
||||||
|
|
||||||
### Test Android App
|
### Android App testen
|
||||||
|
|
||||||
**Unit Tests:**
|
**Unit Tests:**
|
||||||
```bash
|
```bash
|
||||||
@@ -384,15 +384,15 @@ cd android
|
|||||||
|
|
||||||
**Manual Testing Checklist:**
|
**Manual Testing Checklist:**
|
||||||
|
|
||||||
- [ ] Create note → visible in list
|
- [ ] Notiz erstellen → in Liste sichtbar
|
||||||
- [ ] Edit note → changes saved
|
- [ ] Notiz bearbeiten → Änderungen gespeichert
|
||||||
- [ ] Delete note → removed from list
|
- [ ] Notiz löschen → aus Liste entfernt
|
||||||
- [ ] Manual sync → server status "Reachable"
|
- [ ] Manueller Sync → Server Status "Erreichbar"
|
||||||
- [ ] Auto-sync → notification after ~30 min
|
- [ ] Auto-Sync → Notification nach ~30 Min
|
||||||
- [ ] Close app → auto-sync continues
|
- [ ] App schließen → Auto-Sync funktioniert weiter
|
||||||
- [ ] Device reboot → auto-sync starts automatically
|
- [ ] Device Reboot → Auto-Sync startet automatisch
|
||||||
- [ ] Server offline → error notification
|
- [ ] Server offline → Error Notification
|
||||||
- [ ] Notification click → app opens
|
- [ ] Notification Click → App öffnet sich
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -413,18 +413,18 @@ cd android
|
|||||||
# APK: app/build/outputs/apk/release/app-release-unsigned.apk
|
# APK: app/build/outputs/apk/release/app-release-unsigned.apk
|
||||||
```
|
```
|
||||||
|
|
||||||
### Sign (for Distribution)
|
### Signieren (für Distribution)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Create keystore
|
# Keystore erstellen
|
||||||
keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias
|
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 \
|
jarsigner -verbose -sigalg SHA256withRSA -digestalg SHA-256 \
|
||||||
-keystore my-release-key.jks \
|
-keystore my-release-key.jks \
|
||||||
app-release-unsigned.apk my-alias
|
app-release-unsigned.apk my-alias
|
||||||
|
|
||||||
# Optimize
|
# Optimieren
|
||||||
zipalign -v 4 app-release-unsigned.apk app-release.apk
|
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
|
### LogCat Filter
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Only app logs
|
# Nur App-Logs
|
||||||
adb logcat -s SimpleNotesApp NetworkMonitor SyncWorker WebDavSyncService
|
adb logcat -s SimpleNotesApp NetworkMonitor SyncWorker WebDavSyncService
|
||||||
|
|
||||||
# With timestamps
|
# Mit Timestamps
|
||||||
adb logcat -v time -s SyncWorker
|
adb logcat -v time -s SyncWorker
|
||||||
|
|
||||||
# Save to file
|
# In Datei speichern
|
||||||
adb logcat -s SyncWorker > sync_debug.log
|
adb logcat -s SyncWorker > sync_debug.log
|
||||||
```
|
```
|
||||||
|
|
||||||
### Common Issues
|
### 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
|
Settings → Apps → Simple Notes → Battery → Don't optimize
|
||||||
```
|
```
|
||||||
|
|
||||||
**Problem: Server not reachable**
|
**Problem: Server nicht erreichbar**
|
||||||
```
|
```
|
||||||
Check:
|
Check:
|
||||||
1. Server running? → docker-compose ps
|
1. Server läuft? → docker-compose ps
|
||||||
2. IP correct? → ip addr show
|
2. IP korrekt? → ip addr show
|
||||||
3. Port open? → telnet 192.168.0.188 8080
|
3. Port offen? → telnet 192.168.0.188 8080
|
||||||
4. Firewall? → sudo ufw allow 8080
|
4. Firewall? → sudo ufw allow 8080
|
||||||
```
|
```
|
||||||
|
|
||||||
**Problem: Notifications not appearing**
|
**Problem: Notifications kommen nicht**
|
||||||
```
|
```
|
||||||
Check:
|
Check:
|
||||||
1. Notification permission granted?
|
1. Notification Permission erteilt?
|
||||||
2. Do Not Disturb active?
|
2. Do Not Disturb aktiv?
|
||||||
3. App in background? → Force stop & restart
|
3. App im Background? → Force stop & restart
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -504,26 +504,26 @@ androidx.localbroadcastmanager:localbroadcastmanager:1.1.0
|
|||||||
## 🔮 Roadmap
|
## 🔮 Roadmap
|
||||||
|
|
||||||
### v1.1
|
### v1.1
|
||||||
- [ ] Search & Filter
|
- [ ] Suche & Filter
|
||||||
- [ ] Dark Mode
|
- [ ] Dark Mode
|
||||||
- [ ] Tags/Categories
|
- [ ] Tags/Kategorien
|
||||||
- [ ] Markdown Preview
|
- [ ] Markdown Preview
|
||||||
|
|
||||||
### v2.0
|
### v2.0
|
||||||
- [ ] Desktop Client (Flutter)
|
- [ ] Desktop Client (Flutter)
|
||||||
- [ ] End-to-End Encryption
|
- [ ] End-to-End Verschlüsselung
|
||||||
- [ ] Shared Notes (Collaboration)
|
- [ ] Shared Notes (Collaboration)
|
||||||
- [ ] Attachment Support
|
- [ ] Attachment Support
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📖 Further Documentation
|
## 📖 Weitere Dokumentation
|
||||||
|
|
||||||
- [Project Docs](https://github.com/inventory69/project-docs/tree/main/simple-notes-sync)
|
- [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)
|
- [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)
|
- [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
|
||||||
262
docs/DOCS.md
262
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/
|
app/
|
||||||
├── models/
|
├── models/
|
||||||
│ ├── Note.kt # Data class für Notizen
|
│ ├── Note.kt # Data class for notes
|
||||||
│ └── SyncStatus.kt # Sync-Status Enum
|
│ └── SyncStatus.kt # Sync status enum
|
||||||
├── storage/
|
├── storage/
|
||||||
│ └── NotesStorage.kt # Lokale JSON-Datei Speicherung
|
│ └── NotesStorage.kt # Local JSON file storage
|
||||||
├── sync/
|
├── sync/
|
||||||
│ ├── WebDavSyncService.kt # WebDAV Sync-Logik
|
│ ├── WebDavSyncService.kt # WebDAV sync logic
|
||||||
│ ├── NetworkMonitor.kt # WLAN-Erkennung
|
│ ├── NetworkMonitor.kt # WiFi detection
|
||||||
│ ├── SyncWorker.kt # WorkManager Background Worker
|
│ ├── SyncWorker.kt # WorkManager background worker
|
||||||
│ └── BootReceiver.kt # Device Reboot Handler
|
│ └── BootReceiver.kt # Device reboot handler
|
||||||
├── adapters/
|
├── adapters/
|
||||||
│ └── NotesAdapter.kt # RecyclerView Adapter
|
│ └── NotesAdapter.kt # RecyclerView adapter
|
||||||
├── utils/
|
├── utils/
|
||||||
│ ├── Constants.kt # App-Konstanten
|
│ ├── Constants.kt # App constants
|
||||||
│ ├── NotificationHelper.kt# Notification Management
|
│ ├── NotificationHelper.kt# Notification management
|
||||||
│ └── Logger.kt # Debug/Release Logging
|
│ └── Logger.kt # Debug/release logging
|
||||||
└── activities/
|
└── activities/
|
||||||
├── MainActivity.kt # Hauptansicht mit Liste
|
├── MainActivity.kt # Main view with list
|
||||||
├── NoteEditorActivity.kt# Editor für Notizen
|
├── NoteEditorActivity.kt# Note editor
|
||||||
└── SettingsActivity.kt # Server-Konfiguration
|
└── SettingsActivity.kt # Server configuration
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔄 Auto-Sync Implementierung
|
## 🔄 Auto-Sync Implementation
|
||||||
|
|
||||||
### WorkManager Periodic Task
|
### WorkManager Periodic Task
|
||||||
|
|
||||||
Der Auto-Sync basiert auf **WorkManager** mit folgender Konfiguration:
|
Auto-sync is based on **WorkManager** with the following configuration:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
val constraints = Constraints.Builder()
|
val constraints = Constraints.Builder()
|
||||||
.setRequiredNetworkType(NetworkType.UNMETERED) // Nur WiFi
|
.setRequiredNetworkType(NetworkType.UNMETERED) // WiFi only
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(
|
val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(
|
||||||
30, TimeUnit.MINUTES, // Alle 30 Minuten
|
30, TimeUnit.MINUTES, // Every 30 minutes
|
||||||
10, TimeUnit.MINUTES // Flex interval
|
10, TimeUnit.MINUTES // Flex interval
|
||||||
)
|
)
|
||||||
.setConstraints(constraints)
|
.setConstraints(constraints)
|
||||||
.build()
|
.build()
|
||||||
```
|
```
|
||||||
|
|
||||||
**Warum WorkManager?**
|
**Why WorkManager?**
|
||||||
- ✅ Läuft auch wenn App geschlossen ist
|
- ✅ Runs even when app is closed
|
||||||
- ✅ Automatischer Restart nach Device Reboot
|
- ✅ Automatic restart after device reboot
|
||||||
- ✅ Battery-efficient (Android managed)
|
- ✅ Battery-efficient (Android managed)
|
||||||
- ✅ Garantierte Ausführung bei erfüllten Constraints
|
- ✅ Guaranteed execution when constraints are met
|
||||||
|
|
||||||
### Network Detection
|
### 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
|
```kotlin
|
||||||
fun isInHomeNetwork(): Boolean {
|
fun isInHomeNetwork(): Boolean {
|
||||||
val gatewayIP = getGatewayIP() // z.B. 192.168.0.1
|
val gatewayIP = getGatewayIP() // e.g. 192.168.0.1
|
||||||
val serverIP = extractIPFromUrl(serverUrl) // z.B. 192.168.0.188
|
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:**
|
**Advantages:**
|
||||||
- ✅ Keine Location Permissions nötig
|
- ✅ No location permissions needed
|
||||||
- ✅ Funktioniert mit allen Android Versionen
|
- ✅ Works with all Android versions
|
||||||
- ✅ Zuverlässig und schnell
|
- ✅ Reliable and fast
|
||||||
|
|
||||||
### Sync Flow
|
### Sync Flow
|
||||||
|
|
||||||
```
|
```
|
||||||
1. WorkManager wacht auf (alle 30 Min)
|
1. WorkManager wakes up (every 30 min)
|
||||||
↓
|
↓
|
||||||
2. Check: WiFi connected?
|
2. Check: WiFi connected?
|
||||||
↓
|
↓
|
||||||
@@ -105,7 +105,7 @@ fun isInHomeNetwork(): Boolean {
|
|||||||
↓
|
↓
|
||||||
4. Load local notes
|
4. Load local notes
|
||||||
↓
|
↓
|
||||||
5. Upload neue/geänderte Notes → Server
|
5. Upload new/changed notes → Server
|
||||||
↓
|
↓
|
||||||
6. Download remote notes ← Server
|
6. Download remote notes ← Server
|
||||||
↓
|
↓
|
||||||
@@ -118,20 +118,20 @@ fun isInHomeNetwork(): Boolean {
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## <EFBFBD> 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? |
|
| Trigger | File | Function | When? | Pre-Check? |
|
||||||
|---------|-------|----------|-------|------------|
|
|---------|------|----------|-------|------------|
|
||||||
| **1. Manueller Sync** | `MainActivity.kt` | `triggerManualSync()` | User klickt auf Sync-Button im Menü | ✅ Ja |
|
| **1. Manual Sync** | `MainActivity.kt` | `triggerManualSync()` | User clicks sync button in menu | ✅ Yes |
|
||||||
| **2. Auto-Sync (onResume)** | `MainActivity.kt` | `triggerAutoSync()` | App wird geöffnet/fortgesetzt | ✅ Ja |
|
| **2. Auto-Sync (onResume)** | `MainActivity.kt` | `triggerAutoSync()` | App opened/resumed | ✅ Yes |
|
||||||
| **3. Hintergrund-Sync (Periodic)** | `SyncWorker.kt` | `doWork()` | Alle 15/30/60 Minuten (konfigurierbar) | ✅ Ja |
|
| **3. Background Sync (Periodic)** | `SyncWorker.kt` | `doWork()` | Every 15/30/60 minutes (configurable) | ✅ Yes |
|
||||||
| **4. WiFi-Connect Sync** | `NetworkMonitor.kt` → `SyncWorker.kt` | `triggerWifiConnectSync()` | WiFi verbunden | ✅ Ja |
|
| **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
|
```kotlin
|
||||||
// WebDavSyncService.kt - isServerReachable()
|
// WebDavSyncService.kt - isServerReachable()
|
||||||
@@ -148,53 +148,53 @@ suspend fun isServerReachable(): Boolean = withContext(Dispatchers.IO) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Warum Socket-Check statt HTTP-Request?**
|
**Why Socket Check instead of HTTP Request?**
|
||||||
- ⚡ **Schneller:** Socket-Connect ist instant, HTTP-Request dauert länger
|
- ⚡ **Faster:** Socket connect is instant, HTTP request takes longer
|
||||||
- 🔋 **Akkuschonender:** Kein HTTP-Overhead (Headers, TLS Handshake, etc.)
|
- 🔋 **Battery Efficient:** No HTTP overhead (headers, TLS handshake, etc.)
|
||||||
- 🎯 **Präziser:** Prüft nur Netzwerk-Erreichbarkeit, nicht Server-Logik
|
- 🎯 **More Precise:** Only checks network reachability, not server logic
|
||||||
- 🛡️ **Verhindert Fehler:** Erkennt fremde WiFi-Netze bevor Sync-Fehler entsteht
|
- 🛡️ **Prevents Errors:** Detects foreign WiFi networks before sync error occurs
|
||||||
|
|
||||||
**Wann schlägt der Check fehl?**
|
**When does the check fail?**
|
||||||
- ❌ Server offline/nicht erreichbar
|
- ❌ Server offline/unreachable
|
||||||
- ❌ Falsches WiFi-Netzwerk (z.B. öffentliches Café-WiFi)
|
- ❌ Wrong WiFi network (e.g. public café WiFi)
|
||||||
- ❌ Netzwerk noch nicht bereit (DHCP/Routing-Delay nach WiFi-Connect)
|
- ❌ Network not ready yet (DHCP/routing delay after WiFi connect)
|
||||||
- ❌ VPN blockiert Server-Zugriff
|
- ❌ VPN blocks server access
|
||||||
- ❌ Keine WebDAV-Server-URL konfiguriert
|
- ❌ No WebDAV server URL configured
|
||||||
|
|
||||||
### Sync-Verhalten nach Trigger-Typ
|
### Sync Behavior by Trigger Type
|
||||||
|
|
||||||
| Trigger | Bei Server nicht erreichbar | Bei erfolgreichem Sync | Throttling |
|
| Trigger | When server not reachable | On successful sync | Throttling |
|
||||||
|---------|----------------------------|----------------------|------------|
|
|---------|--------------------------|-------------------|------------|
|
||||||
| Manueller Sync | Toast: "Server nicht erreichbar" | Toast: "✅ Gesynct: X Notizen" | Keins |
|
| Manual Sync | Toast: "Server not reachable" | Toast: "✅ Synced: X notes" | None |
|
||||||
| Auto-Sync (onResume) | Silent abort (kein Toast) | Toast: "✅ Gesynct: X Notizen" | Max. 1x/Min |
|
| Auto-Sync (onResume) | Silent abort (no toast) | Toast: "✅ Synced: X notes" | Max. 1x/min |
|
||||||
| Hintergrund-Sync | Silent abort (kein Toast) | Silent (LocalBroadcast only) | 15/30/60 Min |
|
| Background Sync | Silent abort (no toast) | Silent (LocalBroadcast only) | 15/30/60 min |
|
||||||
| WiFi-Connect Sync | Silent abort (kein Toast) | Silent (LocalBroadcast only) | WiFi-basiert |
|
| 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 |
|
| WorkManager Wakeup | Every 30 min | ~0.15 mAh | System wakes up |
|
||||||
| Network Check | 48x/Tag | ~0.03 mAh | Gateway IP check |
|
| Network Check | 48x/day | ~0.03 mAh | Gateway IP check |
|
||||||
| WebDAV Sync | 2-3x/Tag | ~1.5 mAh | Nur bei Änderungen |
|
| WebDAV Sync | 2-3x/day | ~1.5 mAh | Only when changes |
|
||||||
| **Total** | - | **~12 mAh/Tag** | **~0.4%** bei 3000mAh |
|
| **Total** | - | **~12 mAh/day** | **~0.4%** at 3000mAh |
|
||||||
|
|
||||||
### Optimierungen
|
### Optimizations
|
||||||
|
|
||||||
1. **IP Caching**
|
1. **IP Caching**
|
||||||
```kotlin
|
```kotlin
|
||||||
private var cachedServerIP: String? = null
|
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**
|
2. **Throttling**
|
||||||
```kotlin
|
```kotlin
|
||||||
private var lastSyncTime = 0L
|
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**
|
3. **Conditional Logging**
|
||||||
@@ -207,9 +207,9 @@ suspend fun isServerReachable(): Boolean = withContext(Dispatchers.IO) {
|
|||||||
```
|
```
|
||||||
|
|
||||||
4. **Network Constraints**
|
4. **Network Constraints**
|
||||||
- Nur WiFi (nicht mobile Daten)
|
- WiFi only (not mobile data)
|
||||||
- Nur wenn Server erreichbar
|
- Only when server is reachable
|
||||||
- Keine permanenten Listeners
|
- No permanent listeners
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -255,15 +255,15 @@ suspend fun downloadNotes(): DownloadResult {
|
|||||||
val localNote = storage.loadNote(remoteNote.id)
|
val localNote = storage.loadNote(remoteNote.id)
|
||||||
|
|
||||||
if (localNote == null) {
|
if (localNote == null) {
|
||||||
// Neue Note vom Server
|
// New note from server
|
||||||
storage.saveNote(remoteNote)
|
storage.saveNote(remoteNote)
|
||||||
downloadedCount++
|
downloadedCount++
|
||||||
} else if (localNote.modifiedAt < remoteNote.modifiedAt) {
|
} else if (localNote.modifiedAt < remoteNote.modifiedAt) {
|
||||||
// Server hat neuere Version
|
// Server has newer version
|
||||||
storage.saveNote(remoteNote)
|
storage.saveNote(remoteNote)
|
||||||
downloadedCount++
|
downloadedCount++
|
||||||
} else if (localNote.modifiedAt > remoteNote.modifiedAt) {
|
} else if (localNote.modifiedAt > remoteNote.modifiedAt) {
|
||||||
// Lokale Version ist neuer → Conflict
|
// Local version is newer → Conflict
|
||||||
resolveConflict(localNote, remoteNote)
|
resolveConflict(localNote, remoteNote)
|
||||||
conflictCount++
|
conflictCount++
|
||||||
}
|
}
|
||||||
@@ -275,19 +275,19 @@ suspend fun downloadNotes(): DownloadResult {
|
|||||||
|
|
||||||
### Conflict Resolution
|
### Conflict Resolution
|
||||||
|
|
||||||
Strategie: **Last-Write-Wins** mit **Conflict Copy**
|
Strategy: **Last-Write-Wins** with **Conflict Copy**
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
fun resolveConflict(local: Note, remote: Note) {
|
fun resolveConflict(local: Note, remote: Note) {
|
||||||
// Remote Note umbenennen (Conflict Copy)
|
// Rename remote note (conflict copy)
|
||||||
val conflictNote = remote.copy(
|
val conflictNote = remote.copy(
|
||||||
id = "${remote.id}_conflict_${System.currentTimeMillis()}",
|
id = "${remote.id}_conflict_${System.currentTimeMillis()}",
|
||||||
title = "${remote.title} (Konflikt)"
|
title = "${remote.title} (Conflict)"
|
||||||
)
|
)
|
||||||
|
|
||||||
storage.saveNote(conflictNote)
|
storage.saveNote(conflictNote)
|
||||||
|
|
||||||
// Lokale Note bleibt
|
// Local note remains
|
||||||
local.syncStatus = SyncStatus.SYNCED
|
local.syncStatus = SyncStatus.SYNCED
|
||||||
storage.saveNote(local)
|
storage.saveNote(local)
|
||||||
}
|
}
|
||||||
@@ -302,7 +302,7 @@ fun resolveConflict(local: Note, remote: Note) {
|
|||||||
```kotlin
|
```kotlin
|
||||||
val channel = NotificationChannel(
|
val channel = NotificationChannel(
|
||||||
"notes_sync_channel",
|
"notes_sync_channel",
|
||||||
"Notizen Synchronisierung",
|
"Notes Synchronization",
|
||||||
NotificationManager.IMPORTANCE_DEFAULT
|
NotificationManager.IMPORTANCE_DEFAULT
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
@@ -315,9 +315,9 @@ fun showSyncSuccess(context: Context, count: Int) {
|
|||||||
val pendingIntent = PendingIntent.getActivity(context, 0, intent, FLAGS)
|
val pendingIntent = PendingIntent.getActivity(context, 0, intent, FLAGS)
|
||||||
|
|
||||||
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
|
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
|
||||||
.setContentTitle("Sync erfolgreich")
|
.setContentTitle("Sync successful")
|
||||||
.setContentText("$count Notizen synchronisiert")
|
.setContentText("$count notes synchronized")
|
||||||
.setContentIntent(pendingIntent) // Click öffnet App
|
.setContentIntent(pendingIntent) // Click opens app
|
||||||
.setAutoCancel(true) // Dismiss on click
|
.setAutoCancel(true) // Dismiss on click
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
@@ -329,10 +329,10 @@ fun showSyncSuccess(context: Context, count: Int) {
|
|||||||
|
|
||||||
## 🛡️ Permissions
|
## 🛡️ Permissions
|
||||||
|
|
||||||
Die App benötigt **minimale Permissions**:
|
The app requires **minimal permissions**:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<!-- Netzwerk -->
|
<!-- Network -->
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
@@ -348,28 +348,28 @@ Die App benötigt **minimale Permissions**:
|
|||||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||||
```
|
```
|
||||||
|
|
||||||
**Keine Location Permissions!**
|
**No Location Permissions!**
|
||||||
Wir verwenden Gateway IP Comparison statt SSID-Erkennung. Keine Standortberechtigung nötig.
|
We use Gateway IP Comparison instead of SSID detection. No location permission required.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🧪 Testing
|
## 🧪 Testing
|
||||||
|
|
||||||
### Server testen
|
### Test Server
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# WebDAV Server erreichbar?
|
# WebDAV server reachable?
|
||||||
curl -u noteuser:password http://192.168.0.188:8080/
|
curl -u noteuser:password http://192.168.0.188:8080/
|
||||||
|
|
||||||
# Datei hochladen
|
# Upload file
|
||||||
echo '{"test":"data"}' > test.json
|
echo '{"test":"data"}' > test.json
|
||||||
curl -u noteuser:password -T test.json http://192.168.0.188:8080/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
|
curl -u noteuser:password http://192.168.0.188:8080/test.json
|
||||||
```
|
```
|
||||||
|
|
||||||
### Android App testen
|
### Test Android App
|
||||||
|
|
||||||
**Unit Tests:**
|
**Unit Tests:**
|
||||||
```bash
|
```bash
|
||||||
@@ -384,15 +384,15 @@ cd android
|
|||||||
|
|
||||||
**Manual Testing Checklist:**
|
**Manual Testing Checklist:**
|
||||||
|
|
||||||
- [ ] Notiz erstellen → in Liste sichtbar
|
- [ ] Create note → visible in list
|
||||||
- [ ] Notiz bearbeiten → Änderungen gespeichert
|
- [ ] Edit note → changes saved
|
||||||
- [ ] Notiz löschen → aus Liste entfernt
|
- [ ] Delete note → removed from list
|
||||||
- [ ] Manueller Sync → Server Status "Erreichbar"
|
- [ ] Manual sync → server status "Reachable"
|
||||||
- [ ] Auto-Sync → Notification nach ~30 Min
|
- [ ] Auto-sync → notification after ~30 min
|
||||||
- [ ] App schließen → Auto-Sync funktioniert weiter
|
- [ ] Close app → auto-sync continues
|
||||||
- [ ] Device Reboot → Auto-Sync startet automatisch
|
- [ ] Device reboot → auto-sync starts automatically
|
||||||
- [ ] Server offline → Error Notification
|
- [ ] Server offline → error notification
|
||||||
- [ ] Notification Click → App öffnet sich
|
- [ ] Notification click → app opens
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -413,18 +413,18 @@ cd android
|
|||||||
# APK: app/build/outputs/apk/release/app-release-unsigned.apk
|
# APK: app/build/outputs/apk/release/app-release-unsigned.apk
|
||||||
```
|
```
|
||||||
|
|
||||||
### Signieren (für Distribution)
|
### Sign (for Distribution)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Keystore erstellen
|
# Create keystore
|
||||||
keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias
|
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 \
|
jarsigner -verbose -sigalg SHA256withRSA -digestalg SHA-256 \
|
||||||
-keystore my-release-key.jks \
|
-keystore my-release-key.jks \
|
||||||
app-release-unsigned.apk my-alias
|
app-release-unsigned.apk my-alias
|
||||||
|
|
||||||
# Optimieren
|
# Optimize
|
||||||
zipalign -v 4 app-release-unsigned.apk app-release.apk
|
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
|
### LogCat Filter
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Nur App-Logs
|
# Only app logs
|
||||||
adb logcat -s SimpleNotesApp NetworkMonitor SyncWorker WebDavSyncService
|
adb logcat -s SimpleNotesApp NetworkMonitor SyncWorker WebDavSyncService
|
||||||
|
|
||||||
# Mit Timestamps
|
# With timestamps
|
||||||
adb logcat -v time -s SyncWorker
|
adb logcat -v time -s SyncWorker
|
||||||
|
|
||||||
# In Datei speichern
|
# Save to file
|
||||||
adb logcat -s SyncWorker > sync_debug.log
|
adb logcat -s SyncWorker > sync_debug.log
|
||||||
```
|
```
|
||||||
|
|
||||||
### Common Issues
|
### 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
|
Settings → Apps → Simple Notes → Battery → Don't optimize
|
||||||
```
|
```
|
||||||
|
|
||||||
**Problem: Server nicht erreichbar**
|
**Problem: Server not reachable**
|
||||||
```
|
```
|
||||||
Check:
|
Check:
|
||||||
1. Server läuft? → docker-compose ps
|
1. Server running? → docker-compose ps
|
||||||
2. IP korrekt? → ip addr show
|
2. IP correct? → ip addr show
|
||||||
3. Port offen? → telnet 192.168.0.188 8080
|
3. Port open? → telnet 192.168.0.188 8080
|
||||||
4. Firewall? → sudo ufw allow 8080
|
4. Firewall? → sudo ufw allow 8080
|
||||||
```
|
```
|
||||||
|
|
||||||
**Problem: Notifications kommen nicht**
|
**Problem: Notifications not appearing**
|
||||||
```
|
```
|
||||||
Check:
|
Check:
|
||||||
1. Notification Permission erteilt?
|
1. Notification permission granted?
|
||||||
2. Do Not Disturb aktiv?
|
2. Do Not Disturb active?
|
||||||
3. App im Background? → Force stop & restart
|
3. App in background? → Force stop & restart
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -504,26 +504,26 @@ androidx.localbroadcastmanager:localbroadcastmanager:1.1.0
|
|||||||
## 🔮 Roadmap
|
## 🔮 Roadmap
|
||||||
|
|
||||||
### v1.1
|
### v1.1
|
||||||
- [ ] Suche & Filter
|
- [ ] Search & Filter
|
||||||
- [ ] Dark Mode
|
- [ ] Dark Mode
|
||||||
- [ ] Tags/Kategorien
|
- [ ] Tags/Categories
|
||||||
- [ ] Markdown Preview
|
- [ ] Markdown Preview
|
||||||
|
|
||||||
### v2.0
|
### v2.0
|
||||||
- [ ] Desktop Client (Flutter)
|
- [ ] Desktop Client (Flutter)
|
||||||
- [ ] End-to-End Verschlüsselung
|
- [ ] End-to-End Encryption
|
||||||
- [ ] Shared Notes (Collaboration)
|
- [ ] Shared Notes (Collaboration)
|
||||||
- [ ] Attachment Support
|
- [ ] Attachment Support
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📖 Weitere Dokumentation
|
## 📖 Further Documentation
|
||||||
|
|
||||||
- [Project Docs](https://github.com/inventory69/project-docs/tree/main/simple-notes-sync)
|
- [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)
|
- [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)
|
- [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
|
||||||
|
|||||||
305
docs/FEATURES.de.md
Normal file
305
docs/FEATURES.de.md
Normal file
@@ -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)
|
||||||
@@ -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)
|
|
||||||
423
docs/FEATURES.md
423
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
|
### Note Types
|
||||||
- ✅ **Textnotizen** - Klassische Freitext-Notizen
|
- ✅ **Text notes** - Classic free-form notes
|
||||||
- ✅ **Checklisten** _(NEU in v1.4.0)_ - Aufgabenlisten mit Tap-to-Check
|
- ✅ **Checklists** _(NEW in v1.4.0)_ - Task lists with tap-to-check
|
||||||
- ➕ Items hinzufügen über Eingabefeld
|
- ➕ Add items via input field
|
||||||
- ☑️ Tap zum Abhaken/Wieder-Öffnen
|
- ☑️ Tap to check/uncheck
|
||||||
- 📌 Long-Press für Drag & Drop Sortierung
|
- 📌 Long-press for drag & drop sorting
|
||||||
- 🗑️ Swipe-to-Delete für einzelne Items
|
- ~~Strikethrough~~ for completed entries
|
||||||
- ~~Durchstreichen~~ bei erledigten Einträgen
|
|
||||||
|
|
||||||
### Basis-Funktionen
|
### Basic Features
|
||||||
- ✅ **Automatisches Speichern** - Kein manuelles Speichern nötig
|
- ✅ **Auto-save** - No manual saving needed
|
||||||
- ✅ **Titel + Inhalt** - Klare Struktur für jede Notiz
|
- ✅ **Title + content** - Clear structure for each note
|
||||||
- ✅ **Zeitstempel** - Erstellungs- und Änderungsdatum automatisch
|
- ✅ **Timestamps** - Creation and modification date automatically
|
||||||
- ✅ **Swipe-to-Delete** - Intuitive Geste zum Löschen
|
- ✅ **Selection Mode** _(NEW in v1.5.0)_ - Long-press for multi-select and batch delete
|
||||||
- ✅ **Bestätigungs-Dialog** - Schutz vor versehentlichem Löschen
|
- ✅ **Confirmation dialog** - Protection against accidental deletion
|
||||||
- ✅ **Material Design 3** - Moderne, saubere UI
|
- ✅ **Jetpack Compose UI** _(NEW in v1.5.0)_ - Modern, performant user interface
|
||||||
- ✅ **Dark Mode** - Automatisch je nach System-Einstellung
|
- ✅ **Material Design 3** - Modern, clean UI
|
||||||
- ✅ **Dynamic Colors** - Passt sich deinem Android-Theme an
|
- ✅ **Dark mode** - Automatically based on system settings
|
||||||
|
- ✅ **Dynamic colors** - Adapts to your Android theme
|
||||||
|
|
||||||
### Editor
|
### Editor
|
||||||
- ✅ **Minimalistischer Editor** - Kein Schnickschnack
|
- ✅ **Minimalist editor** - No bells and whistles
|
||||||
- ✅ **Auto-Fokus** - Direkt losschreiben
|
- ✅ **Auto-focus** - Start writing immediately
|
||||||
- ✅ **Vollbild-Modus** - Maximale Schreibfläche
|
- ✅ **Fullscreen mode** - Maximum writing space
|
||||||
- ✅ **Speichern-Button** - Manuelle Bestätigung möglich
|
- ✅ **Save button** - Manual confirmation possible
|
||||||
- ✅ **Zurück-Navigation** - Speichert automatisch
|
- ✅ **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
|
### Supported Languages
|
||||||
- ✅ **JSON-Export** - Alle Notizen in einer Datei
|
- ✅ **English** - Primary language (default)
|
||||||
- ✅ **Freie Speicherort-Wahl** - Downloads, SD-Karte, Cloud-Ordner
|
- ✅ **German** - Fully translated
|
||||||
- ✅ **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
|
### Language Selection
|
||||||
- ✅ **Zusammenführen (Merge)** - Neue Notizen hinzufügen, bestehende behalten _(Standard)_
|
- ✅ **Automatic detection** - Follows system language
|
||||||
- ✅ **Ersetzen (Replace)** - Alle löschen und Backup importieren
|
- ✅ **Manual selection** - Switchable in settings
|
||||||
- ✅ **Duplikate überschreiben (Overwrite)** - Backup gewinnt bei ID-Konflikten
|
- ✅ **Per-App Language** - Android 13+ native language selection
|
||||||
- ✅ **Automatisches Sicherheits-Backup** - Vor jeder Wiederherstellung
|
- ✅ **locales_config.xml** - Complete Android integration
|
||||||
- ✅ **Backup-Validierung** - Prüft Format und Version
|
|
||||||
- ✅ **Fehlerbehandlung** - Klare Fehlermeldungen bei Problemen
|
### 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
|
### Local Backup System
|
||||||
- ✅ **Automatischer Export** - Jede Notiz → `.md` Datei
|
- ✅ **JSON export** - All notes in one file
|
||||||
- ✅ **Checklisten als Task-Listen** _(NEU)_ - `- [ ]` / `- [x]` Format (GitHub-kompatibel)
|
- ✅ **Free location choice** - Downloads, SD card, cloud folder
|
||||||
- ✅ **Dual-Format** - JSON (Master) + Markdown (Mirror)
|
- ✅ **Filenames with timestamp** - `simplenotes_backup_YYYY-MM-DD_HHmmss.json`
|
||||||
- ✅ **Dateinamen-Sanitization** - Sichere Dateinamen aus Titeln
|
- ✅ **Complete export** - Title, content, timestamps, IDs
|
||||||
- ✅ **Duplikat-Handling** _(NEU)_ - ID-Suffix bei gleichen Titeln
|
- ✅ **Human-readable format** - JSON with formatting
|
||||||
- ✅ **Frontmatter-Metadata** - YAML mit ID, Timestamps, Type
|
- ✅ **Independent from server** - Works completely offline
|
||||||
- ✅ **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
|
### Restore Modes
|
||||||
- ✅ **Desktop → App** - Änderungen vom Desktop importieren
|
- ✅ **Merge** - Add new notes, keep existing ones _(Default)_
|
||||||
- ✅ **Last-Write-Wins** - Konfliktauflösung via Timestamp
|
- ✅ **Replace** - Delete all and import backup
|
||||||
- ✅ **Frontmatter-Parsing** - Liest Metadata aus `.md` Dateien
|
- ✅ **Overwrite duplicates** - Backup wins on ID conflicts
|
||||||
- ✅ **Neue Notizen erkennen** - Automatisch in App übernehmen
|
- ✅ **Automatic safety backup** - Before every restore
|
||||||
- ✅ **Updates erkennen** - Nur wenn Desktop-Version neuer ist
|
- ✅ **Backup validation** - Checks format and version
|
||||||
- ✅ **Fehlertoleranz** - Einzelne Fehler brechen Import nicht ab
|
- ✅ **Error handling** - Clear error messages on issues
|
||||||
|
|
||||||
### 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
|
## 🖥️ 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
|
### Auto-Sync
|
||||||
- ✅ **Intervall-Auswahl** - 15, 30 oder 60 Minuten
|
- ✅ **Interval selection** - 15, 30 or 60 minutes
|
||||||
- ✅ **WiFi-Trigger** - Sync bei WiFi-Verbindung _(keine SSID-Einschränkung)_
|
- ✅ **WiFi trigger** - Sync on WiFi connection _(no SSID restriction)_
|
||||||
- ✅ **Akkuschonend** - ~0.2-0.8% pro Tag
|
- ✅ **Battery-friendly** - ~0.2-0.8% per day
|
||||||
- ✅ **Smart Server-Check** - Sync nur wenn Server erreichbar
|
- ✅ **Smart server check** - Sync only when server is reachable
|
||||||
- ✅ **WorkManager** - Zuverlässige Background-Ausführung
|
- ✅ **WorkManager** - Reliable background execution
|
||||||
- ✅ **Battery-Optimierung kompatibel** - Funktioniert auch mit Doze Mode
|
- ✅ **Battery optimization compatible** - Works even with Doze mode
|
||||||
|
|
||||||
### Sync-Trigger (6 Stück)
|
### Sync Triggers (6 total)
|
||||||
1. ✅ **Periodic Sync** - Automatisch nach Intervall
|
1. ✅ **Periodic sync** - Automatically after interval
|
||||||
2. ✅ **App-Start Sync** - Beim Öffnen der App
|
2. ✅ **App-start sync** - When opening the app
|
||||||
3. ✅ **WiFi-Connect Sync** - Bei jeder WiFi-Verbindung
|
3. ✅ **WiFi-connect sync** - On any WiFi connection
|
||||||
4. ✅ **Manual Sync** - Button in Einstellungen
|
4. ✅ **Manual sync** - Button in settings
|
||||||
5. ✅ **Pull-to-Refresh** - Wisch-Geste in Notizliste
|
5. ✅ **Pull-to-refresh** - Swipe gesture in notes list
|
||||||
6. ✅ **Settings-Save Sync** - Nach Server-Konfiguration
|
6. ✅ **Settings-save sync** - After server configuration
|
||||||
|
|
||||||
### Sync-Mechanismus
|
### Sync Mechanism
|
||||||
- ✅ **Upload** - Lokale Änderungen zum Server
|
- ✅ **Upload** - Local changes to server
|
||||||
- ✅ **Download** - Server-Änderungen in App
|
- ✅ **Download** - Server changes to app
|
||||||
- ✅ **Konflikt-Erkennung** - Bei gleichzeitigen Änderungen
|
- ✅ **Conflict detection** - On simultaneous changes
|
||||||
- ✅ **Konfliktfreies Merging** - Last-Write-Wins via Timestamp
|
- ✅ **Conflict-free merging** - Last-Write-Wins via timestamp
|
||||||
- ✅ **Sync-Status Tracking** - LOCAL_ONLY, PENDING, SYNCED, CONFLICT
|
- ✅ **Sync status tracking** - LOCAL_ONLY, PENDING, SYNCED, CONFLICT
|
||||||
- ✅ **Fehlerbehandlung** - Retry bei Netzwerkproblemen
|
- ✅ **Error handling** - Retry on network issues
|
||||||
- ✅ **Offline-First** - App funktioniert ohne Server
|
- ✅ **Offline-first** - App works without server
|
||||||
|
|
||||||
### Server-Verbindung
|
### Server Connection
|
||||||
- ✅ **WebDAV-Protokoll** - Standard-Protokoll
|
- ✅ **WebDAV protocol** - Standard protocol
|
||||||
- ✅ **HTTP/HTTPS** - HTTP nur lokal, HTTPS für extern
|
- ✅ **HTTP/HTTPS** - HTTP only local, HTTPS for external
|
||||||
- ✅ **Username/Password** - Basic Authentication
|
- ✅ **Username/password** - Basic authentication
|
||||||
- ✅ **Connection Test** - In Einstellungen testen
|
- ✅ **Connection test** - Test in settings
|
||||||
- ✅ **Server-URL Normalisierung** - Automatisches `/notes/` und `/notes-md/` _(NEU in v1.2.1)_
|
- ✅ **Server URL normalization** - Automatic `/notes/` and `/notes-md/` _(NEW in v1.2.1)_
|
||||||
- ✅ **Flexible URL-Eingabe** - Beide Varianten funktionieren: `http://server/` und `http://server/notes/`
|
- ✅ **Flexible URL input** - Both variants work: `http://server/` and `http://server/notes/`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔒 Privacy & Sicherheit
|
## 🔒 Privacy & Security
|
||||||
|
|
||||||
### Self-Hosted
|
### Self-Hosted
|
||||||
- ✅ **Eigener Server** - Volle Kontrolle über Daten
|
- ✅ **Own server** - Full control over data
|
||||||
- ✅ **Keine Cloud** - Keine Drittanbieter
|
- ✅ **No cloud** - No third parties
|
||||||
- ✅ **Kein Tracking** - Keine Analytik, keine Telemetrie
|
- ✅ **No tracking** - No analytics, no telemetry
|
||||||
- ✅ **Kein Account** - Nur Server-Zugangsdaten
|
- ✅ **No account** - Only server credentials
|
||||||
- ✅ **100% Open Source** - MIT Lizenz
|
- ✅ **100% open source** - MIT License
|
||||||
|
|
||||||
### Daten-Sicherheit
|
### Data Security
|
||||||
- ✅ **Lokale Speicherung** - App-Private Storage (Android)
|
- ✅ **Local storage** - App-private storage (Android)
|
||||||
- ✅ **WebDAV-Verschlüsselung** - HTTPS für externe Server
|
- ✅ **WebDAV encryption** - HTTPS for external servers
|
||||||
- ✅ **Passwort-Speicherung** - Android SharedPreferences (verschlüsselt)
|
- ✅ **Password storage** - Android SharedPreferences (encrypted)
|
||||||
- ✅ **Keine Drittanbieter-Libs** - Nur Android SDK + Sardine (WebDAV)
|
- ✅ **No third-party libs** - Only Android SDK + Sardine (WebDAV)
|
||||||
|
|
||||||
### Entwickler-Features
|
### Developer Features
|
||||||
- ✅ **Datei-Logging** - Optional, nur bei Aktivierung _(NEU in v1.3.2)_
|
- ✅ **File logging** - Optional, only when enabled _(NEW in v1.3.2)_
|
||||||
- ✅ **Datenschutz-Hinweis** - Explizite Warnung bei Aktivierung
|
- ✅ **Privacy notice** - Explicit warning on activation
|
||||||
- ✅ **Lokale Logs** - Logs bleiben auf dem Gerät
|
- ✅ **Local logs** - Logs stay on device
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔋 Performance & Optimierung
|
## 🔋 Performance & Optimization
|
||||||
|
|
||||||
### Akku-Effizienz
|
### Battery Efficiency
|
||||||
- ✅ **Optimierte Sync-Intervalle** - 15/30/60 Min
|
- ✅ **Optimized sync intervals** - 15/30/60 min
|
||||||
- ✅ **WiFi-Only** - Kein Mobile Data Sync
|
- ✅ **WiFi-only** - No mobile data sync
|
||||||
- ✅ **Smart Server-Check** - Sync nur wenn Server erreichbar
|
- ✅ **Smart server check** - Sync only when server is reachable
|
||||||
- ✅ **WorkManager** - System-optimierte Ausführung
|
- ✅ **WorkManager** - System-optimized execution
|
||||||
- ✅ **Doze Mode kompatibel** - Sync läuft auch im Standby
|
- ✅ **Doze mode compatible** - Sync runs even in standby
|
||||||
- ✅ **Gemessener Verbrauch:**
|
- ✅ **Measured consumption:**
|
||||||
- 15 Min: ~0.8% / Tag (~23 mAh)
|
- 15 min: ~0.8% / day (~23 mAh)
|
||||||
- 30 Min: ~0.4% / Tag (~12 mAh) ⭐ _Empfohlen_
|
- 30 min: ~0.4% / day (~12 mAh) ⭐ _Recommended_
|
||||||
- 60 Min: ~0.2% / Tag (~6 mAh)
|
- 60 min: ~0.2% / day (~6 mAh)
|
||||||
|
|
||||||
### App-Performance
|
### App Performance
|
||||||
- ✅ **Offline-First** - Funktioniert ohne Internet
|
- ✅ **Offline-first** - Works without internet
|
||||||
- ✅ **Instant-Load** - Notizen laden in <100ms
|
- ✅ **Instant-load** - Notes load in <100ms
|
||||||
- ✅ **Smooth Scrolling** - RecyclerView mit ViewHolder
|
- ✅ **Smooth scrolling** - RecyclerView with ViewHolder
|
||||||
- ✅ **Material Design 3** - Native Android UI
|
- ✅ **Material Design 3** - Native Android UI
|
||||||
- ✅ **Kotlin Coroutines** - Asynchrone Operationen
|
- ✅ **Kotlin Coroutines** - Asynchronous operations
|
||||||
- ✅ **Minimale APK-Größe** - ~2 MB
|
- ✅ **Minimal APK size** - ~2 MB
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🛠️ Technische Details
|
## 🛠️ Technical Details
|
||||||
|
|
||||||
### Plattform
|
### Platform
|
||||||
- ✅ **Android 8.0+** (API 26+)
|
- ✅ **Android 8.0+** (API 26+)
|
||||||
- ✅ **Target SDK 36** (Android 15)
|
- ✅ **Target SDK 36** (Android 15)
|
||||||
- ✅ **Kotlin** - Moderne Programmiersprache
|
- ✅ **Kotlin** - Modern programming language
|
||||||
- ✅ **Material Design 3** - Neueste Design-Richtlinien
|
- ✅ **Material Design 3** - Latest design guidelines
|
||||||
- ✅ **ViewBinding** - Typ-sichere View-Referenzen
|
- ✅ **ViewBinding** - Type-safe view references
|
||||||
|
|
||||||
### Architektur
|
### Architecture
|
||||||
- ✅ **MVVM-Light** - Einfache Architektur
|
- ✅ **MVVM-Light** - Simple architecture
|
||||||
- ✅ **Single Activity** - Moderne Navigation
|
- ✅ **Single Activity** - Modern navigation
|
||||||
- ✅ **Kotlin Coroutines** - Async/Await Pattern
|
- ✅ **Kotlin Coroutines** - Async/Await pattern
|
||||||
- ✅ **Dispatchers.IO** - Background-Operationen
|
- ✅ **Dispatchers.IO** - Background operations
|
||||||
- ✅ **SharedPreferences** - Settings-Speicherung
|
- ✅ **SharedPreferences** - Settings storage
|
||||||
- ✅ **File-Based Storage** - JSON-Dateien lokal
|
- ✅ **File-based storage** - JSON files locally
|
||||||
- ✅ **Custom Exceptions** - Dedizierte SyncException für bessere Fehlerbehandlung _(NEU in v1.3.2)_
|
- ✅ **Custom exceptions** - Dedicated SyncException for better error handling _(NEW in v1.3.2)_
|
||||||
|
|
||||||
### Abhängigkeiten
|
### Dependencies
|
||||||
- ✅ **AndroidX** - Jetpack Libraries
|
- ✅ **AndroidX** - Jetpack libraries
|
||||||
- ✅ **Material Components** - Material Design 3
|
- ✅ **Material Components** - Material Design 3
|
||||||
- ✅ **Sardine** - WebDAV Client (com.thegrizzlylabs)
|
- ✅ **Sardine** - WebDAV client (com.thegrizzlylabs)
|
||||||
- ✅ **Gson** - JSON Serialization
|
- ✅ **Gson** - JSON serialization
|
||||||
- ✅ **WorkManager** - Background Tasks
|
- ✅ **WorkManager** - Background tasks
|
||||||
- ✅ **OkHttp** - HTTP Client (via Sardine)
|
- ✅ **OkHttp** - HTTP client (via Sardine)
|
||||||
|
|
||||||
### Build-Varianten
|
### Build Variants
|
||||||
- ✅ **Standard** - Universal APK (100% FOSS, keine Google-Dependencies)
|
- ✅ **Standard** - Universal APK (100% FOSS, no Google dependencies)
|
||||||
- ✅ **F-Droid** - Identisch mit Standard (100% FOSS)
|
- ✅ **F-Droid** - Identical to Standard (100% FOSS)
|
||||||
- ✅ **Debug/Release** - Entwicklung und Production
|
- ✅ **Debug/Release** - Development and production
|
||||||
- ✅ **Keine Google Services** - Komplett FOSS, keine proprietären Bibliotheken
|
- ✅ **No Google Services** - Completely FOSS, no proprietary libraries
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📦 Server-Kompatibilität
|
## 📦 Server Compatibility
|
||||||
|
|
||||||
### Getestete WebDAV-Server
|
### Tested WebDAV Servers
|
||||||
- ✅ **Docker WebDAV** (empfohlen für Self-Hosting)
|
- ✅ **Docker WebDAV** (recommended for self-hosting)
|
||||||
- ✅ **Nextcloud** - Vollständig kompatibel
|
- ✅ **Nextcloud** - Fully compatible
|
||||||
- ✅ **ownCloud** - Funktioniert einwandfrei
|
- ✅ **ownCloud** - Works perfectly
|
||||||
- ✅ **Apache mod_dav** - Standard WebDAV
|
- ✅ **Apache mod_dav** - Standard WebDAV
|
||||||
- ✅ **nginx + WebDAV** - Mit korrekter Konfiguration
|
- ✅ **nginx + WebDAV** - With correct configuration
|
||||||
|
|
||||||
### Server-Features
|
### Server Features
|
||||||
- ✅ **Basic Auth** - Username/Password
|
- ✅ **Basic Auth** - Username/password
|
||||||
- ✅ **Directory Listing** - Für Download
|
- ✅ **Directory listing** - For download
|
||||||
- ✅ **PUT/GET** - Upload/Download
|
- ✅ **PUT/GET** - Upload/download
|
||||||
- ✅ **MKCOL** - Ordner erstellen
|
- ✅ **MKCOL** - Create folders
|
||||||
- ✅ **DELETE** - Notizen löschen (zukünftig)
|
- ✅ **DELETE** - Delete notes (future)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔮 Zukünftige Features
|
## 🔮 Future Features
|
||||||
|
|
||||||
Geplant für kommende Versionen:
|
Planned for upcoming versions:
|
||||||
|
|
||||||
### v1.4.0 - Checklisten
|
### v1.4.0 - Checklists
|
||||||
- ⏳ **Checklisten-Notizen** - Neuer Notiz-Typ mit Checkboxen
|
- ⏳ **Checklist notes** - New note type with checkboxes
|
||||||
- ⏳ **Erledigte Items** - Durchstreichen/Abhaken
|
- ⏳ **Completed items** - Strike-through/check off
|
||||||
- ⏳ **Drag & Drop** - Items neu anordnen
|
- ⏳ **Drag & drop** - Reorder items
|
||||||
|
|
||||||
### v1.5.0 - Internationalisierung
|
### v1.5.0 - Internationalization
|
||||||
- ⏳ **Mehrsprachigkeit** - Deutsch + Englisch UI
|
- ⏳ **Multi-language** - German + English UI
|
||||||
- ⏳ **Sprachauswahl** - In Einstellungen wählbar
|
- ⏳ **Language selection** - Selectable in settings
|
||||||
- ⏳ **Vollständige Übersetzung** - Alle Strings in beiden Sprachen
|
- ⏳ **Full translation** - All strings in both languages
|
||||||
|
|
||||||
### v1.6.0 - Modern APIs
|
### v1.6.0 - Modern APIs
|
||||||
- ⏳ **LocalBroadcastManager ersetzen** - SharedFlow stattdessen
|
- ⏳ **Replace LocalBroadcastManager** - Use SharedFlow instead
|
||||||
- ⏳ **PackageInfo Flags** - PackageInfoFlags.of() verwenden
|
- ⏳ **PackageInfo Flags** - Use PackageInfoFlags.of()
|
||||||
- ⏳ **Komplexitäts-Refactoring** - Lange Funktionen aufteilen
|
- ⏳ **Complexity refactoring** - Split long functions
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📊 Vergleich mit anderen Apps
|
## 📊 Comparison with Other Apps
|
||||||
|
|
||||||
| Feature | Simple Notes Sync | Google Keep | Nextcloud Notes |
|
| Feature | Simple Notes Sync | Google Keep | Nextcloud Notes |
|
||||||
|---------|------------------|-------------|-----------------|
|
|---------|------------------|-------------|-----------------|
|
||||||
| Offline-First | ✅ | ⚠️ Eingeschränkt | ⚠️ Eingeschränkt |
|
| Offline-first | ✅ | ⚠️ Limited | ⚠️ Limited |
|
||||||
| Self-Hosted | ✅ | ❌ | ✅ |
|
| Self-hosted | ✅ | ❌ | ✅ |
|
||||||
| Auto-Sync | ✅ | ✅ | ✅ |
|
| Auto-sync | ✅ | ✅ | ✅ |
|
||||||
| Markdown-Export | ✅ | ❌ | ✅ |
|
| Markdown export | ✅ | ❌ | ✅ |
|
||||||
| Desktop-Zugriff | ✅ (WebDAV) | ✅ (Web) | ✅ (Web + WebDAV) |
|
| Desktop access | ✅ (WebDAV) | ✅ (Web) | ✅ (Web + WebDAV) |
|
||||||
| Lokales Backup | ✅ | ❌ | ⚠️ Server-Backup |
|
| Local backup | ✅ | ❌ | ⚠️ Server backup |
|
||||||
| Kein Google-Account | ✅ | ❌ | ✅ |
|
| No Google account | ✅ | ❌ | ✅ |
|
||||||
| Open Source | ✅ MIT | ❌ | ✅ AGPL |
|
| Open source | ✅ MIT | ❌ | ✅ AGPL |
|
||||||
| APK-Größe | ~2 MB | ~50 MB | ~8 MB |
|
| APK size | ~2 MB | ~50 MB | ~8 MB |
|
||||||
| Akku-Verbrauch | ~0.4%/Tag | ~1-2%/Tag | ~0.5%/Tag |
|
| Battery usage | ~0.4%/day | ~1-2%/day | ~0.5%/day |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ❓ FAQ
|
## ❓ FAQ
|
||||||
|
|
||||||
**Q: Brauche ich einen Server?**
|
**Q: Do I need a server?**
|
||||||
A: Nein! Die App funktioniert auch komplett offline. Der Server ist optional für Sync.
|
A: No! The app works completely offline. The server is optional for sync.
|
||||||
|
|
||||||
**Q: Welcher Server ist am besten?**
|
**Q: Which server is best?**
|
||||||
A: Für Einstieg: Docker WebDAV (einfach, leicht). Für Profis: Nextcloud (viele Features).
|
A: For beginners: Docker WebDAV (simple, easy). For pros: Nextcloud (many features).
|
||||||
|
|
||||||
**Q: Funktioniert Markdown-Export ohne Desktop-Integration?**
|
**Q: Does Markdown export work without Desktop Integration?**
|
||||||
A: Nein, du musst das Feature in den Einstellungen aktivieren.
|
A: No, you need to activate the feature in settings.
|
||||||
|
|
||||||
**Q: Gehen meine Daten verloren wenn ich den Server wechsle?**
|
**Q: Will my data be lost if I switch servers?**
|
||||||
A: Nein! Erstelle ein lokales Backup, wechsle Server, stelle wieder her.
|
A: No! Create a local backup, switch servers, restore.
|
||||||
|
|
||||||
**Q: Warum JSON + Markdown?**
|
**Q: Why JSON + Markdown?**
|
||||||
A: JSON ist zuverlässig und schnell (Master). Markdown ist menschenlesbar (Mirror für Desktop).
|
A: JSON is reliable and fast (master). Markdown is human-readable (mirror for desktop).
|
||||||
|
|
||||||
**Q: Kann ich die App ohne Google Play nutzen?**
|
**Q: Can I use the app without Google Play?**
|
||||||
A: Ja! Lade die APK direkt von GitHub oder nutze F-Droid.
|
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)
|
||||||
|
|||||||
151
docs/TRANSLATING.de.md
Normal file
151
docs/TRANSLATING.de.md
Normal file
@@ -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 `<string>`-Einträge:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- Original (Englisch) -->
|
||||||
|
<string name="app_name">Simple Notes</string>
|
||||||
|
<string name="notes_title">Notes</string>
|
||||||
|
|
||||||
|
<!-- Übersetzt (Französisch) -->
|
||||||
|
<string name="app_name">Notes Simples</string>
|
||||||
|
<string name="notes_title">Notes</string>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Wichtig:**
|
||||||
|
- Übersetze nur den Text zwischen `>` und `</string>`
|
||||||
|
- Ä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
|
||||||
|
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<locale android:name="en" />
|
||||||
|
<locale android:name="de" />
|
||||||
|
<locale android:name="fr" /> <!-- NEU -->
|
||||||
|
</locale-config>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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)
|
||||||
151
docs/TRANSLATING.md
Normal file
151
docs/TRANSLATING.md
Normal file
@@ -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 `<string>` entries:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- Original (English) -->
|
||||||
|
<string name="app_name">Simple Notes</string>
|
||||||
|
<string name="notes_title">Notes</string>
|
||||||
|
|
||||||
|
<!-- Translated (French) -->
|
||||||
|
<string name="app_name">Notes Simples</string>
|
||||||
|
<string name="notes_title">Notes</string>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important:**
|
||||||
|
- Only translate text between `>` and `</string>`
|
||||||
|
- 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
|
||||||
|
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<locale android:name="en" />
|
||||||
|
<locale android:name="de" />
|
||||||
|
<locale android:name="fr" /> <!-- NEW -->
|
||||||
|
</locale-config>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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)
|
||||||
76
docs/UPCOMING.de.md
Normal file
76
docs/UPCOMING.de.md
Normal file
@@ -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)
|
||||||
@@ -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)
|
|
||||||
@@ -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
|
- ✅ **Complete UI redesign** - From XML views to Jetpack Compose
|
||||||
- **Deutsche Übersetzung** - Vollständig übersetzt
|
- ✅ **Modernized settings** - 7 categorized screens
|
||||||
- **Automatische Spracherkennung** - Folgt der System-Sprache
|
- ✅ **Selection Mode** - Long-press for multi-select
|
||||||
- **Manuelle Sprachwahl** - In den Einstellungen umschaltbar
|
- ✅ **Silent-Sync Mode** - No banner during auto-sync
|
||||||
|
|
||||||
### ⚙️ Überarbeitete Einstellungen
|
### 🌍 Multi-Language Support
|
||||||
|
|
||||||
- **Modernisiertes Settings-Design** - Übersichtlicher und intuitiver
|
- ✅ **English + German** - 400+ translated strings
|
||||||
- **Kategorisierte Optionen** - Sync, Backup, Entwickler-Optionen
|
- ✅ **Automatic language detection** - Follows system language
|
||||||
|
- ✅ **Per-App Language (Android 13+)** - Native language selection
|
||||||
|
|
||||||
### 🎨 UI-Verbesserungen
|
### 🎨 UI Improvements
|
||||||
|
|
||||||
- **Splash Screen** - App-Icon beim Start
|
- ✅ **Splash screen** - App foreground icon
|
||||||
- **Server-Ordner Prüfung** - Bessere Fehlermeldungen bei der Einrichtung
|
- ✅ **App icon** - In About screen and empty state
|
||||||
- **Dezentere Sync-Anzeige** - Banner nur bei tatsächlichen Änderungen
|
- ✅ **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
|
- **WebDAV folder check** - Checks if folder exists and is writable on server
|
||||||
- **Verbesserte Progress-Dialoge** - Material Design 3 konform
|
- **Better error messages** - Helpful hints for server problems
|
||||||
- **Code-Qualität** - Interne Optimierungen
|
- **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)**
|
### Potential Features
|
||||||
- **[Bestehende Wünsche ansehen](https://github.com/inventory69/simple-notes-sync/issues?q=is%3Aissue+label%3Aenhancement)**
|
|
||||||
|
- **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)
|
||||||
|
|||||||
8
fastlane/metadata/android/de-DE/changelogs/13.txt
Normal file
8
fastlane/metadata/android/de-DE/changelogs/13.txt
Normal file
@@ -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
|
||||||
@@ -3,7 +3,8 @@ Simple Notes Sync ist eine minimalistische Notizen-App mit WebDAV-Synchronisatio
|
|||||||
HAUPTFUNKTIONEN:
|
HAUPTFUNKTIONEN:
|
||||||
|
|
||||||
• Text-Notizen und Checklisten erstellen
|
• 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
|
• WebDAV-Synchronisation mit eigenem Server
|
||||||
• Multi-Device Sync (Handy, Tablet, Desktop)
|
• Multi-Device Sync (Handy, Tablet, Desktop)
|
||||||
• Markdown-Export für Obsidian/Desktop-Editoren
|
• Markdown-Export für Obsidian/Desktop-Editoren
|
||||||
@@ -11,9 +12,17 @@ HAUPTFUNKTIONEN:
|
|||||||
• Automatische Synchronisation im Heim-WLAN
|
• Automatische Synchronisation im Heim-WLAN
|
||||||
• Konfigurierbares Sync-Interval (15/30/60 Minuten)
|
• Konfigurierbares Sync-Interval (15/30/60 Minuten)
|
||||||
• Material Design 3 mit Dynamic Colors (Android 12+)
|
• Material Design 3 mit Dynamic Colors (Android 12+)
|
||||||
|
• Jetpack Compose UI - modern, schnell und flüssig
|
||||||
• Komplett offline nutzbar
|
• Komplett offline nutzbar
|
||||||
• Keine Werbung, keine Tracker
|
• Keine Werbung, keine Tracker
|
||||||
|
|
||||||
|
MEHRSPRACHIG:
|
||||||
|
|
||||||
|
• Englische und deutsche Sprachunterstützung
|
||||||
|
• Per-App Sprachauswahl (Android 13+)
|
||||||
|
• Automatische Systemsprachen-Erkennung
|
||||||
|
• Über 400 übersetzte Strings
|
||||||
|
|
||||||
DATENSCHUTZ:
|
DATENSCHUTZ:
|
||||||
|
|
||||||
Deine Daten bleiben bei dir! Die App kommuniziert nur mit deinem eigenen WebDAV-Server. Keine Cloud-Dienste, keine Tracking-Bibliotheken, keine Analysetools.
|
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)
|
• Optimierte Performance: überspringt unveränderte Dateien (~2-3s Sync-Zeit)
|
||||||
• E-Tag Caching für 20x schnellere "keine Änderungen" Checks
|
• E-Tag Caching für 20x schnellere "keine Änderungen" Checks
|
||||||
• Gemessener Akkuverbrauch: nur ~0.4% pro Tag (bei 30min)
|
• 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
|
• Doze Mode optimiert für zuverlässige Background-Syncs
|
||||||
• Manuelle Synchronisation jederzeit möglich
|
• Manuelle Synchronisation jederzeit möglich
|
||||||
|
|
||||||
MATERIAL DESIGN 3:
|
MATERIAL DESIGN 3:
|
||||||
|
|
||||||
• Moderne Benutzeroberfläche
|
• Moderne Jetpack Compose Benutzeroberfläche
|
||||||
• Dynamic Colors (Material You) auf Android 12+
|
• Dynamic Colors (Material You) auf Android 12+
|
||||||
• Dark Mode Support
|
• Dark Mode Support
|
||||||
• Intuitive Gesten (Swipe-to-Delete)
|
• Auswahlmodus mit Batch-Löschen
|
||||||
• Live Sync-Status Anzeige
|
• Live Sync-Status Anzeige
|
||||||
|
• Flüssige Slide-Animationen
|
||||||
|
|
||||||
Open Source unter MIT-Lizenz
|
Open Source unter MIT-Lizenz
|
||||||
Quellcode: https://github.com/inventory69/simple-notes-sync
|
Quellcode: https://github.com/inventory69/simple-notes-sync
|
||||||
8
fastlane/metadata/android/en-US/changelogs/13.txt
Normal file
8
fastlane/metadata/android/en-US/changelogs/13.txt
Normal file
@@ -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
|
||||||
@@ -3,7 +3,8 @@ Simple Notes Sync is a minimalist note-taking app with WebDAV synchronization.
|
|||||||
KEY FEATURES:
|
KEY FEATURES:
|
||||||
|
|
||||||
• Create text notes and checklists
|
• 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
|
• WebDAV synchronization with your own server
|
||||||
• Multi-device sync (phone, tablet, desktop)
|
• Multi-device sync (phone, tablet, desktop)
|
||||||
• Markdown export for Obsidian/desktop editors
|
• Markdown export for Obsidian/desktop editors
|
||||||
@@ -11,9 +12,17 @@ KEY FEATURES:
|
|||||||
• Automatic synchronization on home WiFi
|
• Automatic synchronization on home WiFi
|
||||||
• Configurable sync interval (15/30/60 minutes)
|
• Configurable sync interval (15/30/60 minutes)
|
||||||
• Material Design 3 with Dynamic Colors (Android 12+)
|
• Material Design 3 with Dynamic Colors (Android 12+)
|
||||||
|
• Jetpack Compose UI - modern, fast, and smooth
|
||||||
• Fully usable offline
|
• Fully usable offline
|
||||||
• No ads, no trackers
|
• No ads, no trackers
|
||||||
|
|
||||||
|
MULTILINGUAL:
|
||||||
|
|
||||||
|
• English and German language support
|
||||||
|
• Per-App Language selector (Android 13+)
|
||||||
|
• Automatic system language detection
|
||||||
|
• 400+ translated strings
|
||||||
|
|
||||||
PRIVACY:
|
PRIVACY:
|
||||||
|
|
||||||
Your data stays with you! The app only communicates with your own WebDAV server. No cloud services, no tracking libraries, no analytics tools.
|
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)
|
• Optimized performance: skips unchanged files (~2-3s sync time)
|
||||||
• E-Tag caching for 20x faster "no changes" checks
|
• E-Tag caching for 20x faster "no changes" checks
|
||||||
• Measured battery consumption: only ~0.4% per day (at 30min)
|
• 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
|
• Doze Mode optimized for reliable background syncs
|
||||||
• Manual synchronization available anytime
|
• Manual synchronization available anytime
|
||||||
|
|
||||||
MATERIAL DESIGN 3:
|
MATERIAL DESIGN 3:
|
||||||
|
|
||||||
• Modern user interface
|
• Modern Jetpack Compose user interface
|
||||||
• Dynamic Colors (Material You) on Android 12+
|
• Dynamic Colors (Material You) on Android 12+
|
||||||
• Dark Mode support
|
• Dark Mode support
|
||||||
• Intuitive gestures (Swipe-to-delete)
|
• Selection mode with batch delete
|
||||||
• Live sync status indicator
|
• Live sync status indicator
|
||||||
|
• Smooth slide animations
|
||||||
|
|
||||||
Open Source under MIT License
|
Open Source under MIT License
|
||||||
Source code: https://github.com/inventory69/simple-notes-sync
|
Source code: https://github.com/inventory69/simple-notes-sync
|
||||||
|
|||||||
Reference in New Issue
Block a user