From 80a46e0e493c8de71f0cc8bf379a072b842bada4 Mon Sep 17 00:00:00 2001 From: inventory69 Date: Tue, 23 Dec 2025 22:36:41 +0100 Subject: [PATCH] Update documentation for Simple Notes Sync - Revamped QUICKSTART.md for clearer installation and setup instructions, including detailed steps for server setup and app configuration. - Revised README.md to reflect new features and streamlined installation process, emphasizing offline capabilities and auto-sync functionality. - Removed outdated README.old.md to maintain a clean repository. [skip ci] --- GITHUB_ACTIONS_SETUP.md | 188 ---- IMPROVEMENT_PLAN.md | 2338 --------------------------------------- QUICKSTART.md | 465 ++++---- README.md | 131 +-- README.old.md | 335 ------ 5 files changed, 294 insertions(+), 3163 deletions(-) delete mode 100644 GITHUB_ACTIONS_SETUP.md delete mode 100644 IMPROVEMENT_PLAN.md delete mode 100644 README.old.md diff --git a/GITHUB_ACTIONS_SETUP.md b/GITHUB_ACTIONS_SETUP.md deleted file mode 100644 index d5f7a3c..0000000 --- a/GITHUB_ACTIONS_SETUP.md +++ /dev/null @@ -1,188 +0,0 @@ -# GitHub Actions Setup Guide - -This guide explains how to set up the GitHub Actions workflow for automated APK builds with proper signing. - -## Overview - -The workflow in `.github/workflows/build-production-apk.yml` automatically: -- Builds signed APKs on every push to `main` -- Generates version numbers using `YYYY.MM.DD` + build number -- Creates 3 APK variants (universal, arm64-v8a, armeabi-v7a) -- Creates GitHub releases with all APKs attached - -## Prerequisites - -- GitHub CLI (`gh`) installed -- Java 17+ installed (for keytool) -- Git repository initialized with GitHub remote - -## Step 1: Generate Signing Keystore - -⚠️ **IMPORTANT**: Store the keystore securely! Without it, you cannot publish updates to your app. - -```bash -# Navigate to project root -cd /path/to/simple-notes-sync - -# Generate keystore (replace values as needed) -keytool -genkey -v \ - -keystore android/app/simple-notes-release.jks \ - -keyalg RSA \ - -keysize 2048 \ - -validity 10000 \ - -alias simple-notes - -# You will be prompted for: -# - Keystore password (remember this!) -# - Key password (remember this!) -# - Your name, organization, etc. -``` - -**Store these securely:** -- Keystore password -- Key password -- Alias: `simple-notes` -- Keystore file: `android/app/simple-notes-release.jks` - -⚠️ **BACKUP**: Make a backup of the keystore file in a secure location (NOT in the repository). - -## Step 2: Base64 Encode Keystore - -```bash -# Create base64 encoded version -base64 android/app/simple-notes-release.jks > simple-notes-release.jks.b64 - -# Or on macOS: -base64 -i android/app/simple-notes-release.jks -o simple-notes-release.jks.b64 -``` - -## Step 3: Set GitHub Secrets - -Using GitHub CLI (recommended): - -```bash -# Set KEYSTORE_BASE64 secret -gh secret set KEYSTORE_BASE64 < simple-notes-release.jks.b64 - -# Set KEYSTORE_PASSWORD (will prompt for input) -gh secret set KEYSTORE_PASSWORD - -# Set KEY_PASSWORD (will prompt for input) -gh secret set KEY_PASSWORD - -# Set KEY_ALIAS (value: simple-notes) -printf "simple-notes" | gh secret set KEY_ALIAS -``` - -Or manually via GitHub web interface: -1. Go to repository Settings → Secrets and variables → Actions -2. Click "New repository secret" -3. Add these secrets: - - `KEYSTORE_BASE64`: Paste content of `simple-notes-release.jks.b64` - - `KEYSTORE_PASSWORD`: Your keystore password - - `KEY_PASSWORD`: Your key password - - `KEY_ALIAS`: `simple-notes` - -## Step 4: Verify Setup - -```bash -# Check secrets are set -gh secret list - -# Expected output: -# KEYSTORE_BASE64 Updated YYYY-MM-DD -# KEYSTORE_PASSWORD Updated YYYY-MM-DD -# KEY_PASSWORD Updated YYYY-MM-DD -# KEY_ALIAS Updated YYYY-MM-DD -``` - -## Step 5: Cleanup - -```bash -# Remove sensitive files (they're in .gitignore, but double-check) -rm simple-notes-release.jks.b64 -rm -f android/key.properties # Generated by workflow - -# Verify keystore is NOT tracked by git -git status | grep -i jks -# Should return nothing -``` - -## Step 6: Trigger First Build - -```bash -# Commit and push to main -git add . -git commit -m "🚀 feat: Add GitHub Actions deployment workflow" -git push origin main - -# Or manually trigger workflow -gh workflow run build-production-apk.yml -``` - -## Verification - -1. Go to GitHub repository → Actions tab -2. Check workflow run status -3. Once complete, go to Releases tab -4. Verify release was created with 3 APK variants -5. Download and test one of the APKs - -## Troubleshooting - -### Build fails with "Keystore not found" -- Check `KEYSTORE_BASE64` secret is set correctly -- Verify base64 encoding was done without line breaks - -### Build fails with "Incorrect password" -- Verify `KEYSTORE_PASSWORD` and `KEY_PASSWORD` are correct -- Re-set secrets if needed - -### APK files not found -- Check build logs for errors in assembleRelease step -- Verify APK output paths match workflow expectations - -### Updates don't work -- Ensure you're using the same keystore for all builds -- Verify `applicationId` in build.gradle.kts matches - -## Security Notes - -- ✅ Keystore is base64-encoded in GitHub secrets (secure) -- ✅ Passwords are stored in GitHub secrets (encrypted) -- ✅ `key.properties` and `.jks` files are in `.gitignore` -- ⚠️ Never commit keystore files to repository -- ⚠️ Keep backup of keystore in secure location -- ⚠️ Don't share keystore passwords - -## Versioning - -Versions follow this pattern: -- **Version Name**: `YYYY.MM.DD` (e.g., `2025.01.15`) -- **Version Code**: GitHub run number (e.g., `42`) -- **Release Tag**: `vYYYY.MM.DD-prod.BUILD` (e.g., `v2025.01.15-prod.42`) - -This ensures: -- Semantic versioning based on release date -- Incremental version codes for Play Store compatibility -- Clear distinction between builds - -## APK Variants - -The workflow generates 3 APK variants: - -1. **Universal APK** (~5 MB) - - Works on all devices - - Larger file size - - Recommended for most users - -2. **arm64-v8a APK** (~3 MB) - - For modern devices (2018+) - - Smaller, faster - - 64-bit ARM processors - -3. **armeabi-v7a APK** (~3 MB) - - For older devices - - 32-bit ARM processors - -Users can choose based on their device - Obtanium auto-updates work with all variants. diff --git a/IMPROVEMENT_PLAN.md b/IMPROVEMENT_PLAN.md deleted file mode 100644 index f5b053a..0000000 --- a/IMPROVEMENT_PLAN.md +++ /dev/null @@ -1,2338 +0,0 @@ -# 🎯 Simple Notes Sync - Verbesserungsplan - -**Erstellt am:** 21. Dezember 2025 -**Ziel:** UX-Verbesserungen, Material Design 3, Deutsche Lokalisierung, F-Droid Release - ---- - -## 📋 Übersicht der Probleme & Lösungen - ---- - -## 🆕 NEU: Server-Backup Wiederherstellung - -### ❗ Neue Anforderung: Notizen vom Server wiederherstellen - -**Problem:** -- User kann keine vollständige Wiederherstellung vom Server machen -- Wenn lokale Daten verloren gehen, keine einfache Recovery -- Nützlich bei Gerätewechsel oder nach App-Neuinstallation - -**Lösung:** - -#### UI-Komponente (Settings) -```kotlin -// SettingsActivity.kt - Button hinzufügen - - -// Click Handler -buttonRestoreFromServer.setOnClickListener { - showRestoreConfirmationDialog() -} - -private fun showRestoreConfirmationDialog() { - MaterialAlertDialogBuilder(this) - .setTitle("Vom Server wiederherstellen?") - .setMessage( - "⚠️ WARNUNG:\n\n" + - "• Alle lokalen Notizen werden gelöscht\n" + - "• Alle Notizen vom Server werden heruntergeladen\n" + - "• Diese Aktion kann nicht rückgängig gemacht werden\n\n" + - "Fortfahren?" - ) - .setIcon(R.drawable.ic_warning) - .setPositiveButton("Wiederherstellen") { _, _ -> - restoreFromServer() - } - .setNegativeButton("Abbrechen", null) - .show() -} - -private fun restoreFromServer() { - lifecycleScope.launch { - try { - // Show progress dialog - val progressDialog = MaterialAlertDialogBuilder(this@SettingsActivity) - .setTitle("Wiederherstelle...") - .setMessage("Lade Notizen vom Server...") - .setCancelable(false) - .create() - progressDialog.show() - - val syncService = WebDavSyncService(this@SettingsActivity) - val result = syncService.restoreFromServer() - - progressDialog.dismiss() - - if (result.isSuccess) { - MaterialAlertDialogBuilder(this@SettingsActivity) - .setTitle("✅ Wiederherstellung erfolgreich") - .setMessage("${result.restoredCount} Notizen vom Server wiederhergestellt") - .setPositiveButton("OK") { _, _ -> - // Trigger MainActivity refresh - val intent = Intent("dev.dettmer.simplenotes.NOTES_CHANGED") - LocalBroadcastManager.getInstance(this@SettingsActivity) - .sendBroadcast(intent) - } - .show() - } else { - showErrorDialog(result.errorMessage ?: "Unbekannter Fehler") - } - } catch (e: Exception) { - showErrorDialog(e.message ?: "Wiederherstellung fehlgeschlagen") - } - } -} -``` - -#### Backend-Logik (WebDavSyncService) -```kotlin -// WebDavSyncService.kt -data class RestoreResult( - val isSuccess: Boolean, - val restoredCount: Int = 0, - val errorMessage: String? = null -) - -suspend fun restoreFromServer(): RestoreResult = withContext(Dispatchers.IO) { - try { - val serverUrl = prefs.getString(Constants.KEY_SERVER_URL, null) - val username = prefs.getString(Constants.KEY_USERNAME, null) - val password = prefs.getString(Constants.KEY_PASSWORD, null) - - if (serverUrl.isNullOrEmpty() || username.isNullOrEmpty() || password.isNullOrEmpty()) { - return@withContext RestoreResult( - isSuccess = false, - errorMessage = "Server nicht konfiguriert" - ) - } - - // List all remote files - val sardine = Sardine() - sardine.setCredentials(username, password) - - val remoteFiles = sardine.list(serverUrl) - .filter { it.name.endsWith(".json") && !it.isDirectory } - - if (remoteFiles.isEmpty()) { - return@withContext RestoreResult( - isSuccess = false, - errorMessage = "Keine Notizen auf dem Server gefunden" - ) - } - - val restoredNotes = mutableListOf() - - // Download each note - for (file in remoteFiles) { - try { - val content = sardine.get(file.href).toString(Charsets.UTF_8) - val note = Note.fromJson(content) - restoredNotes.add(note) - } catch (e: Exception) { - Log.w(TAG, "Failed to parse ${file.name}: ${e.message}") - // Continue with other files - } - } - - if (restoredNotes.isEmpty()) { - return@withContext RestoreResult( - isSuccess = false, - errorMessage = "Keine gültigen Notizen gefunden" - ) - } - - // Clear local storage and save all notes - withContext(Dispatchers.Main) { - storage.clearAll() - restoredNotes.forEach { note -> - storage.saveNote(note.copy(syncStatus = SyncStatus.SYNCED)) - } - } - - RestoreResult( - isSuccess = true, - restoredCount = restoredNotes.size - ) - - } catch (e: Exception) { - Log.e(TAG, "Restore failed", e) - RestoreResult( - isSuccess = false, - errorMessage = e.message ?: "Verbindungsfehler" - ) - } -} -``` - -#### Storage Update -```kotlin -// NotesStorage.kt - Methode hinzufügen -fun clearAll() { - val file = File(context.filesDir, NOTES_FILE) - if (file.exists()) { - file.delete() - } - // Create empty notes list - saveAllNotes(emptyList()) -} -``` - -**Betroffene Dateien:** -- `android/app/src/main/java/dev/dettmer/simplenotes/SettingsActivity.kt` -- `android/app/src/main/java/dev/dettmer/simplenotes/sync/WebDavSyncService.kt` -- `android/app/src/main/java/dev/dettmer/simplenotes/storage/NotesStorage.kt` -- `android/app/src/main/res/layout/activity_settings.xml` -- `android/app/src/main/res/values/strings.xml` -- `android/app/src/main/res/drawable/ic_cloud_download.xml` (neu) - -**Zeitaufwand:** 2-3 Stunden - -**Strings hinzufügen:** -```xml -Vom Server wiederherstellen -Vom Server wiederherstellen? -⚠️ WARNUNG:\n\n• Alle lokalen Notizen werden gelöscht\n• Alle Notizen vom Server werden heruntergeladen\n• Diese Aktion kann nicht rückgängig gemacht werden\n\nFortfahren? -Wiederherstelle... -Lade Notizen vom Server... -✅ Wiederherstellung erfolgreich -%d Notizen vom Server wiederhergestellt -Server nicht konfiguriert -Keine Notizen auf dem Server gefunden -Keine gültigen Notizen gefunden -``` - ---- - -### 1️⃣ Server-Status Aktualisierung ⚠️ HOCH -**Problem:** -- Server-Status wird nicht sofort nach erfolgreichem Verbindungstest grün -- User muss App neu öffnen oder Focus ändern - -**Lösung:** -```kotlin -// In SettingsActivity.kt nach testConnection() -private fun testConnection() { - lifecycleScope.launch { - try { - showToast("Teste Verbindung...") - val syncService = WebDavSyncService(this@SettingsActivity) - val result = syncService.testConnection() - - if (result.isSuccess) { - showToast("Verbindung erfolgreich!") - checkServerStatus() // ✅ HIER HINZUFÜGEN - } else { - showToast("Verbindung fehlgeschlagen: ${result.errorMessage}") - checkServerStatus() // ✅ Auch bei Fehler aktualisieren - } - } catch (e: Exception) { - showToast("Fehler: ${e.message}") - checkServerStatus() // ✅ Auch bei Exception - } - } -} -``` - -**Betroffene Dateien:** -- `android/app/src/main/java/dev/dettmer/simplenotes/SettingsActivity.kt` - -**Zeitaufwand:** 15 Minuten - ---- - -### 2️⃣ Auto-Save Indikator im Editor ⚠️ HOCH -**Problem:** -- User erkennt nicht, dass automatisch gespeichert wird -- Save-Button fehlt → Verwirrung -- Keine visuelle Rückmeldung über Speicher-Status - -**Lösung A: Auto-Save mit Indikator (Empfohlen)** -```kotlin -// NoteEditorActivity.kt -private var autoSaveJob: Job? = null -private lateinit var saveStatusTextView: TextView - -private fun setupAutoSave() { - val textWatcher = object : TextWatcher { - override fun afterTextChanged(s: Editable?) { - // Cancel previous save job - autoSaveJob?.cancel() - - // Show "Speichere..." - saveStatusTextView.text = "💾 Speichere..." - saveStatusTextView.setTextColor(getColor(android.R.color.darker_gray)) - - // Debounce: Save after 2 seconds of no typing - autoSaveJob = lifecycleScope.launch { - delay(2000) - saveNoteQuietly() - - // Show "Gespeichert ✓" - saveStatusTextView.text = "✓ Gespeichert" - saveStatusTextView.setTextColor(getColor(android.R.color.holo_green_dark)) - - // Hide after 2 seconds - delay(2000) - saveStatusTextView.text = "" - } - } - // ... beforeTextChanged, onTextChanged - } - - editTextTitle.addTextChangedListener(textWatcher) - editTextContent.addTextChangedListener(textWatcher) -} - -private fun saveNoteQuietly() { - val title = editTextTitle.text?.toString()?.trim() ?: "" - val content = editTextContent.text?.toString()?.trim() ?: "" - - if (title.isEmpty() && content.isEmpty()) return - - val note = if (existingNote != null) { - existingNote!!.copy( - title = title, - content = content, - updatedAt = System.currentTimeMillis(), - syncStatus = SyncStatus.PENDING - ) - } else { - Note( - title = title, - content = content, - deviceId = DeviceIdGenerator.getDeviceId(this), - syncStatus = SyncStatus.LOCAL_ONLY - ).also { existingNote = it } - } - - storage.saveNote(note) -} -``` - -**Layout Update:** -```xml - - -``` - -**Alternative B: Save-Button behalten + Auto-Save** -- Button zeigt "Gespeichert ✓" nach Auto-Save -- Button disabled wenn keine Änderungen - -**Betroffene Dateien:** -- `android/app/src/main/java/dev/dettmer/simplenotes/NoteEditorActivity.kt` -- `android/app/src/main/res/layout/activity_editor.xml` -- `android/app/src/main/res/values/strings.xml` - -**Zeitaufwand:** 1-2 Stunden - ---- - -### 3️⃣ GitHub Releases auf Deutsch ⚠️ MITTEL -**Problem:** -- Release Notes sind auf Englisch -- Asset-Namen teilweise englisch -- Zielgruppe ist deutsch - -**Lösung:** -```yaml -# .github/workflows/build-production-apk.yml - -# Asset-Namen schon auf Deutsch ✓ - -# Release Body übersetzen: -body: | - # 📝 Produktions-Release: Simple Notes Sync v${{ env.VERSION_NAME }} - - ## 📊 Build-Informationen - - - **Version:** ${{ env.VERSION_NAME }}+${{ env.BUILD_NUMBER }} - - **Build-Datum:** ${{ env.COMMIT_DATE }} - - **Commit:** ${{ env.SHORT_SHA }} - - **Umgebung:** 🟢 **PRODUKTION** - - --- - - ## 📋 Änderungen - - ${{ env.COMMIT_MSG }} - - --- - - ## 📦 Download & Installation - - ### Welche APK sollte ich herunterladen? - - | Dein Gerät | Diese APK herunterladen | Größe | Kompatibilität | - |------------|-------------------------|-------|----------------| - | 🤷 Unsicher? | `simple-notes-sync-v${{ env.VERSION_NAME }}-universal.apk` | ~3 MB | Funktioniert auf allen Geräten | - | Modern (ab 2018) | `simple-notes-sync-v${{ env.VERSION_NAME }}-arm64-v8a.apk` | ~2 MB | Schneller, kleiner | - | Ältere Geräte | `simple-notes-sync-v${{ env.VERSION_NAME }}-armeabi-v7a.apk` | ~2 MB | Ältere ARM-Chips | - - ### 📲 Installationsschritte - 1. Lade die passende APK aus den Assets herunter - 2. Aktiviere "Aus unbekannten Quellen installieren" in den Android-Einstellungen - 3. Öffne die heruntergeladene APK-Datei - 4. Folge den Installationsanweisungen - 5. Konfiguriere die WebDAV-Einstellungen in der App - - --- - - ## ⚙️ Funktionen - - - ✅ Automatische WebDAV-Synchronisation alle 30 Minuten (~0,4% Akku/Tag) - - ✅ Intelligente Gateway-Erkennung (automatische Heimnetzwerk-Erkennung) - - ✅ Material Design 3 Benutzeroberfläche - - ✅ Privatsphäre-fokussiert (kein Tracking, keine Analytics) - - ✅ Offline-First Architektur - - --- - - ## 🔄 Aktualisierung von vorheriger Version - - Installiere diese APK einfach über die bestehende Installation - alle Daten und Einstellungen bleiben erhalten. - - --- - - ## 📱 Obtanium - Automatische Updates - - Erhalte automatische Updates mit [Obtanium](https://github.com/ImranR98/Obtanium/releases/latest). - - **Einrichtung:** - 1. Installiere Obtanium über den obigen Link - 2. Füge die App mit dieser URL hinzu: `https://github.com/inventory69/simple-notes-sync` - 3. Aktiviere automatische Updates - - --- - - ## 🆘 Support - - Bei Problemen oder Fragen bitte ein Issue auf GitHub öffnen. - - --- - - ## 🔒 Datenschutz & Sicherheit - - - Alle Daten werden über deinen eigenen WebDAV-Server synchronisiert - - Keine Analytics oder Tracking von Drittanbietern - - Keine Internet-Berechtigungen außer für WebDAV-Sync - - Alle Sync-Vorgänge verschlüsselt (HTTPS) - - Open Source - prüfe den Code selbst - - --- - - ## 🛠️ Technische Details - - - **Sprache:** Kotlin - - **UI:** Material Design 3 - - **Sync:** WorkManager + WebDAV - - **Target SDK:** Android 16 (API 36) - - **Min SDK:** Android 8.0 (API 26) -``` - -**Betroffene Dateien:** -- `.github/workflows/build-production-apk.yml` - -**Zeitaufwand:** 30 Minuten - ---- - -### 4️⃣ Material Design 3 - Vollständige Migration ⚠️ HOCH - -**Basierend auf:** `MATERIAL_DESIGN_3_MIGRATION.md` Plan - -**Problem:** -- Aktuelles Design ist Material Design 2 -- Keine Dynamic Colors (Material You) -- Veraltete Komponenten und Farb-Palette -- Keine Android 12+ Features - -**Ziel:** -- ✨ Dynamische Farben aus Wallpaper (Material You) -- 🎨 Modern Design Language -- 🔲 Größere Corner Radius (16dp) -- 📱 Material Symbols Icons -- 📝 Material 3 Typography -- 🌓 Perfekter Dark Mode -- ♿ Bessere Accessibility - ---- - -#### Phase 4.1: Theme & Dynamic Colors (15 Min) - -**themes.xml:** -```xml - - - - - - - - - - -``` - -**colors.xml (Material 3 Baseline - Grün/Natur Theme):** -```xml - - - #006C4C - #FFFFFF - #89F8C7 - #002114 - - #4D6357 - #FFFFFF - #CFE9D9 - #0A1F16 - - #3D6373 - #FFFFFF - #C1E8FB - #001F29 - - #BA1A1A - #FFFFFF - #FFDAD6 - #410002 - - #FBFDF9 - #191C1A - - #FBFDF9 - #191C1A - #DCE5DD - #404943 - - #707973 - #BFC9C2 - -``` - -**values-night/colors.xml (neu erstellen):** -```xml - - - #6DDBAC - #003826 - #005138 - #89F8C7 - - #B3CCBD - #1F352A - #354B40 - #CFE9D9 - - #A5CCE0 - #073543 - #254B5B - #C1E8FB - - #FFB4AB - #690005 - #93000A - #FFDAD6 - - #191C1A - #E1E3DF - - #191C1A - #E1E3DF - #404943 - #BFC9C2 - - #8A938C - #404943 - -``` - -**MainActivity.kt - Dynamic Colors aktivieren:** -```kotlin -override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - // Enable Dynamic Colors (Android 12+) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - DynamicColors.applyToActivityIfAvailable(this) - } - - setContentView(R.layout.activity_main) - // ... -} - -// Import hinzufügen: -import com.google.android.material.color.DynamicColors -import android.os.Build -``` - -**Betroffene Dateien:** -- `android/app/src/main/res/values/themes.xml` -- `android/app/src/main/res/values/colors.xml` -- `android/app/src/main/res/values-night/colors.xml` (neu) -- `android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt` - -**Zeitaufwand:** 15 Minuten - ---- - -#### Phase 4.2: MainActivity Layout (10 Min) - -**activity_main.xml - Material 3 Update:** -```xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -``` - -**Betroffene Dateien:** -- `android/app/src/main/res/layout/activity_main.xml` -- `android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt` - -**Zeitaufwand:** 10 Minuten - ---- - -#### Phase 4.3: Note Item Card (10 Min) - -**item_note.xml - Material 3 Card:** -```xml - - - - - - - - - - - - - - - - -``` - -**Betroffene Dateien:** -- `android/app/src/main/res/layout/item_note.xml` - -**Zeitaufwand:** 10 Minuten - ---- - -#### Phase 4.4: Editor Layout (10 Min) - -**activity_editor.xml - Material 3 TextInputLayouts:** -```xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -``` - -**Betroffene Dateien:** -- `android/app/src/main/res/layout/activity_editor.xml` - -**Zeitaufwand:** 10 Minuten - ---- - -#### Phase 4.5: Material Symbols Icons (15 Min) - -**Icons erstellen in `res/drawable/`:** - -1. **ic_add_24.xml** -```xml - - - -``` - -2. **ic_sync_24.xml** -3. **ic_settings_24.xml** -4. **ic_cloud_done_24.xml** -5. **ic_cloud_sync_24.xml** -6. **ic_warning_24.xml** -7. **ic_server_24.xml** -8. **ic_person_24.xml** -9. **ic_lock_24.xml** -10. **ic_cloud_download_24.xml** -11. **ic_check_24.xml** - -Tool: https://fonts.google.com/icons - -**Betroffene Dateien:** -- `android/app/src/main/res/drawable/` (11 neue Icons) - -**Zeitaufwand:** 15 Minuten - ---- - -#### Phase 4.6: Splash Screen (30 Min) - -**themes.xml - Splash Screen hinzufügen:** -```xml - -``` - -**AndroidManifest.xml:** -```xml - - - -``` - -**MainActivity.kt:** -```kotlin -override fun onCreate(savedInstanceState: Bundle?) { - // Handle splash screen - installSplashScreen() - - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) -} - -// Import: -import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen -``` - -**build.gradle.kts:** -```kotlin -dependencies { - implementation("androidx.core:core-splashscreen:1.0.1") -} -``` - -**Betroffene Dateien:** -- `android/app/src/main/res/values/themes.xml` -- `android/app/src/main/AndroidManifest.xml` -- `android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt` -- `android/app/build.gradle.kts` - -**Zeitaufwand:** 30 Minuten - ---- - -### Material 3 Gesamtaufwand: ~90 Minuten - ---- - -### 5️⃣ F-Droid Release Vorbereitung ⚠️ MITTEL -**Problem:** -- Keine F-Droid Metadata vorhanden -- Keine Build-Variante ohne Google-Dependencies - -**Lösung - Verzeichnisstruktur:** -``` -simple-notes-sync/ -├── metadata/ -│ └── de-DE/ -│ ├── full_description.txt -│ ├── short_description.txt -│ ├── title.txt -│ └── changelogs/ -│ ├── 1.txt -│ ├── 2.txt -│ └── 3.txt -└── fastlane/ - └── metadata/ - └── android/ - └── de-DE/ - ├── images/ - │ ├── icon.png - │ ├── featureGraphic.png - │ └── phoneScreenshots/ - │ ├── 1.png - │ ├── 2.png - │ └── 3.png - ├── full_description.txt - ├── short_description.txt - └── title.txt -``` - -**metadata/de-DE/full_description.txt:** -``` -Simple Notes Sync - Deine privaten Notizen, selbst gehostet - -Eine minimalistische, datenschutzfreundliche Notizen-App mit automatischer WebDAV-Synchronisation. - -HAUPTMERKMALE: - -🔒 Datenschutz -• Alle Daten auf deinem eigenen Server -• Keine Cloud-Dienste von Drittanbietern -• Kein Tracking oder Analytics -• Open Source - transparent und überprüfbar - -☁️ Automatische Synchronisation -• WebDAV-Sync alle 30 Minuten -• Intelligente Netzwerkerkennung -• Nur im WLAN (konfigurierbar) -• Minimaler Akkuverbrauch (~0,4%/Tag) - -✨ Einfach & Schnell -• Klare, aufgeräumte Benutzeroberfläche -• Blitzschnelle Notiz-Erfassung -• Offline-First Design -• Material Design 3 - -🔧 Flexibel -• Funktioniert mit jedem WebDAV-Server -• Nextcloud, ownCloud, Apache, etc. -• Docker-Setup verfügbar -• Konflikterkennung und -lösung - -TECHNISCHE DETAILS: - -• Keine Google Services benötigt -• Keine unnötigen Berechtigungen -• Minimale App-Größe (~2-3 MB) -• Android 8.0+ kompatibel -• Kotlin + Material Design 3 - -PERFECT FÜR: - -• Schnelle Notizen und Ideen -• Einkaufslisten -• Todo-Listen -• Persönliche Gedanken -• Alle, die Wert auf Datenschutz legen - -Der Quellcode ist verfügbar auf: https://github.com/inventory69/simple-notes-sync -``` - -**metadata/de-DE/short_description.txt:** -``` -Minimalistische Notizen-App mit selbst-gehosteter WebDAV-Synchronisation -``` - -**metadata/de-DE/title.txt:** -``` -Simple Notes Sync -``` - -**Build-Flavor ohne Google:** -```kotlin -// build.gradle.kts -android { - flavorDimensions += "version" - productFlavors { - create("fdroid") { - dimension = "version" - // Keine Google/Firebase Dependencies - } - create("playstore") { - dimension = "version" - // Optional: Google Services für Analytics etc. - } - } -} - -dependencies { - // Base dependencies (alle Flavors) - implementation(libs.androidx.core.ktx) - implementation(libs.material) - - // PlayStore specific (optional) - "playstoreImplementation"("com.google.firebase:firebase-analytics:21.5.0") -} -``` - -**Betroffene Dateien:** -- `metadata/` (neu) -- `fastlane/` (neu) -- `android/app/build.gradle.kts` (Flavors hinzufügen) -- Screenshots erstellen (phone + tablet) - -**Zeitaufwand:** 3-4 Stunden (inkl. Screenshots) - ---- - -### 5️⃣ Material Design 3 Theme ⚠️ HOCH -**Problem:** -- Aktuelles Theme ist Material Design 2 -- Keine Dynamic Colors (Material You) -- Veraltete Farb-Palette - -**Lösung - themes.xml:** -```xml - - - - - - - - - - - -``` - -**colors.xml (Material 3 Baseline):** -```xml - - - - #006C4C - #FFFFFF - #89F8C7 - #002114 - - #4D6357 - #FFFFFF - #CFE9D9 - #0A1F16 - - #3D6373 - #FFFFFF - #C1E8FB - #001F29 - - #BA1A1A - #FFFFFF - #FFDAD6 - #410002 - - #FBFDF9 - #191C1A - - #FBFDF9 - #191C1A - #DCE5DD - #404943 - - #707973 - #BFC9C2 - -``` - -**Dynamic Colors aktivieren (MainActivity.kt):** -```kotlin -override fun onCreate(savedInstanceState: Bundle?) { - // Enable dynamic colors (Android 12+) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - DynamicColors.applyToActivityIfAvailable(this) - } - - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - // ... -} -``` - -**Dependency hinzufügen:** -```kotlin -// build.gradle.kts -dependencies { - implementation("com.google.android.material:material:1.11.0") -} -``` - -**Betroffene Dateien:** -- `android/app/src/main/res/values/themes.xml` -- `android/app/src/main/res/values/colors.xml` -- `android/app/src/main/res/values-night/colors.xml` (neu) -- `android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt` -- `android/app/build.gradle.kts` - -**Zeitaufwand:** 2-3 Stunden - ---- - -### 6️⃣ Settings UI mit Material 3 ⚠️ MITTEL -**Problem:** -- Plain TextInputLayouts ohne Icons -- Keine visuellen Gruppierungen -- Server-Status Wechsel nicht animiert - -**Lösung - activity_settings.xml:** -```xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -``` - -**Animierter Server-Status (SettingsActivity.kt):** -```kotlin -private fun updateServerStatus(status: ServerStatus) { - val chip = findViewById(R.id.chipServerStatus) - - // Animate transition - chip.animate() - .alpha(0f) - .setDuration(150) - .withEndAction { - when (status) { - ServerStatus.CHECKING -> { - chip.text = "🔍 Prüfe Server..." - chip.chipBackgroundColor = ColorStateList.valueOf( - getColor(R.color.md_theme_surfaceVariant) - ) - chip.setChipIconResource(R.drawable.ic_sync) - } - ServerStatus.REACHABLE -> { - chip.text = "✅ Server erreichbar" - chip.chipBackgroundColor = ColorStateList.valueOf( - getColor(R.color.md_theme_primaryContainer) - ) - chip.setChipIconResource(R.drawable.ic_check_circle) - } - ServerStatus.UNREACHABLE -> { - chip.text = "❌ Nicht erreichbar" - chip.chipBackgroundColor = ColorStateList.valueOf( - getColor(R.color.md_theme_errorContainer) - ) - chip.setChipIconResource(R.drawable.ic_error) - } - ServerStatus.NOT_CONFIGURED -> { - chip.text = "⚠️ Nicht konfiguriert" - chip.chipBackgroundColor = ColorStateList.valueOf( - getColor(R.color.md_theme_surfaceVariant) - ) - chip.setChipIconResource(R.drawable.ic_warning) - } - } - - chip.animate() - .alpha(1f) - .setDuration(150) - .start() - } - .start() -} - -enum class ServerStatus { - CHECKING, - REACHABLE, - UNREACHABLE, - NOT_CONFIGURED -} -``` - -**Icons benötigt (drawable/):** -- `ic_server.xml` -- `ic_person.xml` -- `ic_lock.xml` -- `ic_check_circle.xml` -- `ic_sync.xml` -- `ic_error.xml` -- `ic_warning.xml` - -**Betroffene Dateien:** -- `android/app/src/main/res/layout/activity_settings.xml` -- `android/app/src/main/java/dev/dettmer/simplenotes/SettingsActivity.kt` -- `android/app/src/main/res/drawable/` (Icons) - -**Zeitaufwand:** 3-4 Stunden - ---- - -### 7️⃣ Main Activity mit Material 3 Cards ⚠️ HOCH -**Problem:** -- Notizen in einfachen ListItems -- Keine Elevation/Shadow -- Swipe-to-Delete fehlt - -**Lösung - item_note.xml:** -```xml - - - - - - - - - - - - - - - - -``` - -**Swipe-to-Delete (MainActivity.kt):** -```kotlin -private fun setupRecyclerView() { - recyclerView = findViewById(R.id.recyclerView) - adapter = NotesAdapter { note -> - openNoteEditor(note.id) - } - - recyclerView.adapter = adapter - recyclerView.layoutManager = LinearLayoutManager(this) - - // Swipe-to-Delete - val swipeHandler = object : ItemTouchHelper.SimpleCallback( - 0, - ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT - ) { - override fun onMove( - recyclerView: RecyclerView, - viewHolder: RecyclerView.ViewHolder, - target: RecyclerView.ViewHolder - ): Boolean = false - - override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { - val position = viewHolder.adapterPosition - val note = adapter.notes[position] - - // Delete with undo - adapter.removeNote(position) - storage.deleteNote(note.id) - - Snackbar.make( - findViewById(R.id.coordinator), - "Notiz gelöscht", - Snackbar.LENGTH_LONG - ).setAction("RÜCKGÄNGIG") { - adapter.addNote(position, note) - storage.saveNote(note) - }.show() - } - - override fun onChildDraw( - c: Canvas, - recyclerView: RecyclerView, - viewHolder: RecyclerView.ViewHolder, - dX: Float, - dY: Float, - actionState: Int, - isCurrentlyActive: Boolean - ) { - val itemView = viewHolder.itemView - - val paint = Paint() - paint.color = getColor(R.color.md_theme_errorContainer) - - // Draw background - if (dX > 0) { - c.drawRect( - itemView.left.toFloat(), - itemView.top.toFloat(), - dX, - itemView.bottom.toFloat(), - paint - ) - } else { - c.drawRect( - itemView.right.toFloat() + dX, - itemView.top.toFloat(), - itemView.right.toFloat(), - itemView.bottom.toFloat(), - paint - ) - } - - super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) - } - } - - ItemTouchHelper(swipeHandler).attachToRecyclerView(recyclerView) -} -``` - -**Empty State (activity_main.xml):** -```xml - - - - - - - - - - - - - -``` - -**Extended FAB (activity_main.xml):** -```xml - -``` - -**Betroffene Dateien:** -- `android/app/src/main/res/layout/activity_main.xml` -- `android/app/src/main/res/layout/item_note.xml` -- `android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt` -- `android/app/src/main/java/dev/dettmer/simplenotes/adapters/NotesAdapter.kt` - -**Zeitaufwand:** 4-5 Stunden - ---- - -### 8️⃣ Editor mit Material 3 ⚠️ MITTEL -**Problem:** -- Einfache EditText-Felder -- Kein Character Counter -- Keine visuelle Trennung - -**Lösung - activity_editor.xml:** -```xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -``` - -**Betroffene Dateien:** -- `android/app/src/main/res/layout/activity_editor.xml` -- `android/app/src/main/java/dev/dettmer/simplenotes/NoteEditorActivity.kt` - -**Zeitaufwand:** 2 Stunden - ---- - -### 9️⃣ Splash Screen mit Material 3 ⚠️ NIEDRIG -**Problem:** -- Kein moderner Splash Screen - -**Lösung:** -```xml - - -``` - -```xml - - - - -``` - -```kotlin -// MainActivity.kt -override fun onCreate(savedInstanceState: Bundle?) { - // Handle the splash screen transition - installSplashScreen() - - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) -} -``` - -**Dependency:** -```kotlin -implementation("androidx.core:core-splashscreen:1.0.1") -``` - -**Betroffene Dateien:** -- `android/app/src/main/res/values/themes.xml` -- `android/app/src/main/AndroidManifest.xml` -- `android/app/src/main/java/dev/dettmer/simplenotes/MainActivity.kt` -- `android/app/build.gradle.kts` - -**Zeitaufwand:** 30 Minuten - ---- - -### 🔟 Deutsche Lokalisierung ⚠️ MITTEL -**Problem:** -- Einige Strings noch auf Englisch -- Release Notes englisch -- Error Messages englisch - -**Lösung - strings.xml vervollständigen:** -```xml - - - Simple Notes - - - Noch keine Notizen.\nTippe + um eine zu erstellen. - Notiz hinzufügen - Synchronisieren - Einstellungen - - - Notiz bearbeiten - Neue Notiz - Titel - Inhalt - Speichern - Löschen - Speichere… - ✓ Gespeichert - Änderungen werden automatisch gespeichert - - - Server-Einstellungen - Server URL - z.B. https://cloud.example.com/remote.php/dav/files/username/notes - Benutzername - Passwort - WLAN-Einstellungen - Heim-WLAN SSID - Auto-Sync aktiviert - Synchronisiert alle 30 Minuten - Auto-Sync funktioniert nur im selben WLAN-Netzwerk wie dein Server. Minimaler Akkuverbrauch (~0.4%/Tag). - Verbindung testen - Jetzt synchronisieren - Sync-Status - - - 🔍 Prüfe Server… - ✅ Server erreichbar - ❌ Nicht erreichbar - ⚠️ Nicht konfiguriert - - - Teste Verbindung… - Verbindung erfolgreich! - Verbindung fehlgeschlagen: %s - Synchronisiere… - Erfolgreich! %d Notizen synchronisiert - Sync fehlgeschlagen: %s - Sync abgeschlossen. %d Konflikte erkannt! - Notiz gespeichert - Notiz gelöscht - RÜCKGÄNGIG - - - Notiz löschen? - Diese Aktion kann nicht rückgängig gemacht werden. - Abbrechen - Hintergrund-Synchronisation - Damit die App im Hintergrund synchronisieren kann, muss die Akku-Optimierung deaktiviert werden.\n\nBitte wähle \'Nicht optimieren\' für Simple Notes. - Einstellungen öffnen - Später - - - Titel oder Inhalt darf nicht leer sein - Netzwerkfehler: %s - Server-Fehler: %s - Authentifizierung fehlgeschlagen - Unbekannter Fehler: %s - - - Notizen Synchronisierung - Benachrichtigungen über Sync-Status - Sync erfolgreich - %d Notizen synchronisiert - Sync fehlgeschlagen - %s - -``` - -**Betroffene Dateien:** -- `android/app/src/main/res/values/strings.xml` -- `.github/workflows/build-production-apk.yml` -- Alle `.kt` Dateien mit hardcoded strings - -**Zeitaufwand:** 2 Stunden - ---- - -## 📊 Zusammenfassung & Prioritäten - -### Phase 1: Kritische UX-Fixes (Sofort) ⚡ -**Zeitaufwand: ~3-4 Stunden** - -1. ✅ Server-Status Aktualisierung (15 min) -2. ✅ Auto-Save Indikator (1-2 h) -3. ✅ GitHub Releases auf Deutsch (30 min) -4. ✅ Server-Backup Wiederherstellung (2-3 h) - -### Phase 2: Material Design 3 Migration (1 Tag) 🎨 -**Zeitaufwand: ~90 Minuten** - -5. ✅ Theme & Dynamic Colors (15 min) -6. ✅ MainActivity Layout (10 min) -7. ✅ Note Item Card (10 min) -8. ✅ Editor Layout (10 min) -9. ✅ Settings Layout (10 min) - aus Phase 3 vorgezogen -10. ✅ Material Icons (15 min) -11. ✅ Splash Screen (30 min) - -### Phase 3: Advanced UI Features (2-3 Tage) 🚀 -**Zeitaufwand: ~4-5 Stunden** - -12. ✅ Swipe-to-Delete (1 h) -13. ✅ Empty State (30 min) -14. ✅ Animierte Server-Status Änderung (1 h) -15. ✅ Deutsche Lokalisierung vervollständigen (1-2 h) - -### Phase 4: F-Droid Release (1 Tag) 📦 -**Zeitaufwand: ~4 Stunden** - -16. ✅ F-Droid Metadata (3-4 h) -17. ✅ F-Droid Build-Flavor (30 min) - ---- - -## 🎯 Empfohlene Reihenfolge - -### Woche 1: Fundament & Kritische Fixes -**Tag 1 (3-4h):** Phase 1 - Kritische UX-Fixes -- Server-Status sofort grün nach Test -- Auto-Save mit visuellem Feedback -- Deutsche Release Notes -- **Server-Backup Funktion** ← NEU & WICHTIG - -**Tag 2 (1.5h):** Phase 2 Start - Material Design 3 Foundation -- Theme & Dynamic Colors aktivieren -- MainActivity Layout modernisieren -- Note Item Cards verbessern - -**Tag 3 (1.5h):** Phase 2 Fortführung - Material Design 3 -- Editor Layout upgraden -- Settings Layout modernisieren -- Material Icons erstellen -- Splash Screen implementieren - -### Woche 2: Polish & Release -**Tag 4 (2-3h):** Phase 3 - Advanced Features -- Swipe-to-Delete mit Animation -- Empty State mit Illustration -- Server-Status Animationen -- Deutsche Strings vervollständigen - -**Tag 5 (4h):** Phase 4 - F-Droid Vorbereitung -- Metadata erstellen -- Screenshots machen -- Build-Flavor konfigurieren - ---- - -## 🆕 Neue Features Zusammenfassung - -### Server-Backup Wiederherstellung -**Warum wichtig:** -- ✅ Gerätewechsel einfach -- ✅ Recovery nach App-Neuinstallation -- ✅ Datensicherheit erhöht -- ✅ User-Vertrauen gestärkt - -**Wo in der UI:** -- Settings Activity → neuer Button "Vom Server wiederherstellen" -- Warn-Dialog vor Ausführung -- Progress-Dialog während Download -- Success-Dialog mit Anzahl wiederhergestellter Notizen - -**Backend:** -- `WebDavSyncService.restoreFromServer()` -- `NotesStorage.clearAll()` -- Vollständiger Download aller Server-Notizen -- Überschreibt lokale Daten komplett - ---- - -## 📝 Material Design 3 - Schnellreferenz - -### Umgesetzt wird: -✅ **Dynamic Colors** - Farben aus Wallpaper (Android 12+) -✅ **Material 3 Components** - Cards, Buttons, TextInputs -✅ **16dp Corner Radius** - Modernere abgerundete Ecken -✅ **Material Symbols** - Neue Icon-Familie -✅ **Typography Scale** - Material 3 Text-Styles -✅ **Dark Mode** - Perfekt abgestimmte Nacht-Farben -✅ **Splash Screen API** - Android 12+ Native Splash - -### Design-Token: -- **Primary:** Grün (#006C4C) - Natur, Notizen, Wachstum -- **Secondary:** Grau-Grün - Subtil, harmonisch -- **Surface:** Hell/Dunkel - Abhängig von Theme -- **Shapes:** Small 12dp, Medium 16dp, Large 24dp - ---- - -## 📋 Checkliste vor Start - -- [ ] Branch erstellen: `git checkout -b feature/ux-improvements` -- [ ] Backup vom aktuellen Stand -- [ ] Material 3 Dependency prüfen: `com.google.android.material:material:1.11.0` -- [ ] Android Studio aktualisiert -- [ ] Testgerät mit Android 12+ für Dynamic Colors - ---- - -## 🧪 Testing nach Abschluss - -### Manuell: -- [ ] Alle Layouts auf Smartphone (Phone) -- [ ] Alle Layouts auf Tablet -- [ ] Dark Mode überall -- [ ] Light Mode überall -- [ ] Dynamic Colors (Android 12+) -- [ ] Server-Backup: Restore funktioniert -- [ ] Server-Backup: Dialog-Texte korrekt -- [ ] Auto-Save: Indikator erscheint -- [ ] Auto-Save: Speichert nach 2s -- [ ] Server-Status: Wird sofort aktualisiert -- [ ] Swipe-to-Delete: Animation smooth -- [ ] Empty State: Zeigt sich bei 0 Notizen -- [ ] Splash Screen: Erscheint beim Start -- [ ] Alle Icons: Richtige Farbe (Tint) -- [ ] Alle Buttons: Funktionieren -- [ ] Deutsch: Keine englischen Strings mehr - -### Automatisch: -- [ ] Build erfolgreich (Debug) -- [ ] Build erfolgreich (Release) -- [ ] APK Size akzeptabel (<5 MB) -- [ ] Keine Lint-Errors -- [ ] ProGuard-Regeln funktionieren - ---- - -## 📚 Referenzen & Tools - -### Material Design 3: -- [Material Design 3 Guidelines](https://m3.material.io/) -- [Material Theme Builder](https://material-foundation.github.io/material-theme-builder/) -- [Material Symbols Icons](https://fonts.google.com/icons) - -### Android: -- [Splash Screen API](https://developer.android.com/develop/ui/views/launch/splash-screen) -- [Dynamic Colors](https://developer.android.com/develop/ui/views/theming/dynamic-colors) - ---- - -## 📝 Nächste Schritte - -Soll ich mit **Phase 1** (kritische UX-Fixes + Server-Backup) beginnen? - -### Was ich jetzt machen würde: - -1. **Server-Backup implementieren** (2-3h) - - Höchste Priorität: User-requested Feature - - Kritisch für Datensicherheit - -2. **Server-Status sofort aktualisieren** (15 min) - - Schneller Win - - Verbessert UX sofort - -3. **Auto-Save Indikator** (1-2h) - - Eliminiert Verwirrung - - Modernes Pattern - -4. **Material 3 Foundation** (90 min) - - Theme & Colors - - Basis für alles weitere - -Diese 4 Tasks würden den größten Impact haben und sind in ~4-6 Stunden machbar! 🚀 diff --git a/QUICKSTART.md b/QUICKSTART.md index af08934..4828005 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -1,208 +1,267 @@ -# 🚀 Quick Start Guide +# Quick Start Guide - Simple Notes Sync 📝 -## ✅ Server ist bereits gestartet! - -Der WebDAV-Server läuft bereits auf: -- **Lokal:** `http://localhost:8080/` -- **Im Netzwerk:** `http://192.168.0.188:8080/` - -### Credentials -- **Username:** `noteuser` -- **Password:** `SimpleNotes2025!` - -## 📱 Nächste Schritte: Android App erstellen - -### Option 1: Mit Android Studio (Empfohlen) - -1. **Android Studio öffnen** - ``` - File → New → New Project - ``` - -2. **Template wählen:** - - Empty Views Activity - -3. **Projekt konfigurieren:** - ``` - Name: Simple Notes - Package: com.example.simplenotes - Save location: /home/liq/gitProjects/simple-notes-sync/android/ - Language: Kotlin - Minimum SDK: API 24 (Android 7.0) - Build configuration: Kotlin DSL - ``` - -4. **Dependencies hinzufügen:** - - Öffne `app/build.gradle.kts` und füge hinzu: - ```kotlin - dependencies { - // ... existing dependencies - - // WebDAV - implementation("com.github.thegrizzlylabs:sardine-android:0.8") - - // Coroutines - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") - - // JSON - implementation("com.google.code.gson:gson:2.10.1") - - // WorkManager - implementation("androidx.work:work-runtime-ktx:2.9.0") - } - ``` - - Und in `settings.gradle.kts`: - ```kotlin - dependencyResolutionManagement { - repositories { - google() - mavenCentral() - maven { url = uri("https://jitpack.io") } // Für Sardine - } - } - ``` - -5. **Code implementieren:** - - Alle Code-Beispiele findest du in: - - [ANDROID_GUIDE.md](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/ANDROID_GUIDE.md) - - Kopiere der Reihe nach: - - `models/Note.kt` - - `models/SyncStatus.kt` - - `storage/NotesStorage.kt` - - `utils/DeviceIdGenerator.kt` - - `utils/NotificationHelper.kt` - - `utils/Extensions.kt` - - `utils/Constants.kt` - - UI Layouts aus dem Guide - - Activities (MainActivity, NoteEditorActivity, SettingsActivity) - - `sync/WebDavSyncService.kt` - - `sync/WifiSyncReceiver.kt` - - `sync/SyncWorker.kt` - - `adapters/NotesAdapter.kt` - -6. **AndroidManifest.xml anpassen:** - ```xml - - - - - - - ``` - -7. **Build & Run:** - ``` - Build → Make Project - Run → Run 'app' - ``` - -8. **In der App konfigurieren:** - - Einstellungen öffnen - - Server URL: `http://192.168.0.188:8080/` - - Username: `noteuser` - - Password: `SimpleNotes2025!` - - Heim-WLAN SSID: `DeinWLANName` - - "Verbindung testen" → sollte erfolgreich sein ✓ - -### Option 2: Schritt-für-Schritt Implementation - -Folge dem [IMPLEMENTATION_PLAN.md](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/IMPLEMENTATION_PLAN.md) mit 6 Sprints: - -1. **Sprint 1:** Server & Foundation (bereits done ✓) -2. **Sprint 2:** Basic UI (4-6h) -3. **Sprint 3:** Settings & WebDAV (6h) -4. **Sprint 4:** Auto-Sync (6h) -5. **Sprint 5:** Conflicts & Errors (6h) -6. **Sprint 6:** Polish & Testing (6h) - -## 🧪 Server testen - -Der Server läuft bereits. Teste ihn: - -```bash -# Einfacher Test -curl -u noteuser:SimpleNotes2025! http://localhost:8080/ - -# Test-Notiz hochladen -echo '{"id":"test-123","title":"Test","content":"Hello World","createdAt":1703001234567,"updatedAt":1703001234567,"deviceId":"test","syncStatus":"SYNCED"}' > test.json - -curl -u noteuser:SimpleNotes2025! \ - -T test.json \ - http://localhost:8080/test.json - -# Test-Notiz abrufen -curl -u noteuser:SimpleNotes2025! http://localhost:8080/test.json - -# Löschen -curl -u noteuser:SimpleNotes2025! \ - -X DELETE \ - http://localhost:8080/test.json -``` - -## 📊 Server Management - -```bash -cd /home/liq/gitProjects/simple-notes-sync/server - -# Status -docker-compose ps - -# Logs -docker-compose logs -f - -# Stoppen -docker-compose down - -# Neu starten -docker-compose up -d - -# Daten ansehen -ls -la notes-data/ -``` - -## 🔧 Troubleshooting - -### Server nicht erreichbar von Android - -1. **Firewall prüfen:** - ```bash - sudo ufw status - sudo ufw allow 8080 - ``` - -2. **Ping-Test:** - ```bash - ping 192.168.0.188 - ``` - -3. **Port-Test:** - ```bash - telnet 192.168.0.188 8080 - ``` - -### Permission Denied in Android - -- Android 13+: POST_NOTIFICATIONS Permission akzeptieren -- Internet Permission in Manifest vorhanden? -- `usesCleartextTraffic="true"` gesetzt? - -## 📚 Weitere Hilfe - -- **Vollständige Doku:** [project-docs/simple-notes-sync](https://github.com/inventory69/project-docs/tree/main/simple-notes-sync) -- **Android Code:** [ANDROID_GUIDE.md](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/ANDROID_GUIDE.md) -- **Server Setup:** [SERVER_SETUP.md](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/SERVER_SETUP.md) -- **Notifications:** [NOTIFICATIONS.md](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/NOTIFICATIONS.md) +> Schritt-für-Schritt Anleitung zur Installation und Einrichtung --- -**Server Status:** ✅ Running on `http://192.168.0.188:8080/` -**Next:** Android App in Android Studio erstellen -**Estimated Time:** 18-24 Stunden für vollständige App +## Voraussetzungen -Viel Erfolg! 🚀 +- ✅ 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`) | + | **Gateway SSID** | Name deines WLAN-Netzwerks | + +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. **Gleiche WLAN?** + - Smartphone und Server müssen im selben Netzwerk sein + - Prüfe SSID in App-Einstellungen + +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. **Im richtigen WLAN?** + - Sync funktioniert nur wenn SSID = Gateway SSID + - Prüfe aktuelle SSID in Android-Einstellungen + +4. **Manuell testen:** + - ⚙️ Einstellungen → "Jetzt synchronisieren" + - Funktioniert das? → Auto-Sync sollte auch funktionieren + +--- + +### Notizen werden nicht angezeigt + +**Problem:** Nach Installation sind keine Notizen da, obwohl welche auf dem Server liegen + +**Lösung:** + +1. **Einmalig manuell synchronisieren:** + - ⚙️ Einstellungen → "Jetzt synchronisieren" + +2. **Server-Daten prüfen:** + ```bash + docker compose exec webdav ls -la /data/ + # Sollte .json Dateien zeigen + ``` + +--- + +### Fehler beim Sync + +**Problem:** Fehlermeldung beim Synchronisieren + +**Lösungen:** + +1. **"401 Unauthorized"** → Passwort falsch + - Prüfe Passwort in App-Einstellungen + - Vergleiche mit `.env` auf Server + +2. **"404 Not Found"** → URL falsch + - Sollte enden mit `/` (z.B. `http://192.168.1.100:8080/`) + +3. **"Network error"** → Keine Verbindung + - Siehe [Verbindungstest schlägt fehl](#verbindungstest-schlägt-fehl) + +--- + +## 📱 Updates + +### Automatisch mit Obtainium (empfohlen) + +1. **[Obtainium installieren](https://github.com/ImranR98/Obtanium/releases/latest)** + +2. **App hinzufügen:** + - URL: `https://github.com/inventory69/simple-notes-sync` + - Auto-Update aktivieren + +3. **Fertig!** Obtainium benachrichtigt dich bei neuen Versionen + +### Manuell + +1. Neue APK von [Releases](https://github.com/inventory69/simple-notes-sync/releases/latest) herunterladen + +2. Installieren (überschreibt alte Version) + +3. Alle Daten bleiben erhalten! + +--- + +## 🆘 Weitere Hilfe + +- **GitHub Issues:** [Problem melden](https://github.com/inventory69/simple-notes-sync/issues) +- **Vollständige Docs:** [DOCS.md](DOCS.md) +- **Server Setup Details:** [server/README.md](server/README.md) + +--- + +**Version:** 1.1.0 · **Erstellt:** Dezember 2025 diff --git a/README.md b/README.md index b7ac432..58616f1 100644 --- a/README.md +++ b/README.md @@ -1,130 +1,65 @@ # Simple Notes Sync 📝 -> **Minimalistische Android Notiz-App mit automatischer WLAN-Synchronisierung** +> Minimalistische Offline-Notizen mit Auto-Sync zu deinem eigenen Server [![Android](https://img.shields.io/badge/Android-8.0%2B-green.svg)](https://www.android.com/) -[![Kotlin](https://img.shields.io/badge/Kotlin-1.9%2B-blue.svg)](https://kotlinlang.org/) [![Material Design 3](https://img.shields.io/badge/Material-Design%203-green.svg)](https://m3.material.io/) [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) -Schlanke Offline-Notizen ohne Schnickschnack - deine Daten bleiben bei dir. Automatische Synchronisierung zu deinem eigenen WebDAV-Server, kein Google, kein Microsoft, keine Cloud. - -## ✨ Features - -- 📝 **Offline-First** - Notizen lokal gespeichert, immer verfügbar -- 🔄 **Auto-Sync** - Konfigurierbare Intervalle (15/30/60 Min.) mit ~0.2-0.8% Akku/Tag -- 🏠 **Self-Hosted** - Deine Daten auf deinem Server (WebDAV) -- 🎨 **Material Design 3** - Modern & Dynamic Theming -- 🔋 **Akkuschonend** - Optimiert für Hintergrund-Synchronisierung -- 🔐 **Privacy-First** - Kein Tracking, keine Analytics, keine Cloud -- 🚫 **Keine Berechtigungen** - Nur Internet für WebDAV Sync - -## 📥 Quick Download - -**Android APK:** [📱 Neueste Version herunterladen](https://github.com/inventory69/simple-notes-sync/releases/latest) - -💡 **Tipp:** Nutze [Obtainium](https://github.com/ImranR98/Obtainium) für automatische Updates! +**📱 [APK Download](https://github.com/inventory69/simple-notes-sync/releases/latest)** · **📖 [Dokumentation](DOCS.md)** · **🚀 [Quick Start](QUICKSTART.md)** --- -## 🚀 Schnellstart +## Features -### 1️⃣ WebDAV Server starten +- 📝 Offline-First - Notizen immer verfügbar +- 🔄 Auto-Sync - Konfigurierbare Intervalle (15/30/60 Min) +- 🏠 Self-Hosted - WebDAV auf deinem Server +- 🔐 Privacy-First - Keine Cloud, kein Tracking +- 🔋 Akkuschonend - ~0.2-0.8% pro Tag -```fish +--- + +## 🚀 Quick Start + +### 1. Server Setup + +```bash cd server cp .env.example .env -# Passwort in .env anpassen +# Passwort in .env setzen docker compose up -d ``` -### 2️⃣ App installieren & konfigurieren +➡️ **Details:** [Server Setup Guide](server/README.md) -1. APK herunterladen und installieren -2. App öffnen → **Einstellungen** (⚙️) -3. Server konfigurieren: - - URL: `http://192.168.0.XXX:8080/notes` - - Benutzername: `noteuser` - - Passwort: (aus `.env`) -4. **Auto-Sync aktivieren** -5. **Sync-Intervall wählen** (15/30/60 Min.) +### 2. App Installation -**Fertig!** Notizen werden automatisch synchronisiert 🎉 +1. [APK herunterladen](https://github.com/inventory69/simple-notes-sync/releases/latest) +2. Installieren & öffnen +3. ⚙️ Einstellungen → Server konfigurieren +4. Auto-Sync aktivieren + +➡️ **Details:** [Vollständige Anleitung](QUICKSTART.md) --- -## ⚙️ Sync-Intervalle +## 📚 Dokumentation -| Intervall | Akku/Tag | Anwendungsfall | -|-----------|----------|----------------| -| **15 Min** | ~0.8% (~23 mAh) | ⚡ Maximale Aktualität | -| **30 Min** | ~0.4% (~12 mAh) | ✓ Empfohlen - Ausgewogen | -| **60 Min** | ~0.2% (~6 mAh) | 🔋 Maximale Akkulaufzeit | - -💡 **Hinweis:** Android Doze Mode kann Sync im Standby auf ~60 Min. verzögern (betrifft alle Apps). +- **[Quick Start Guide](QUICKSTART.md)** - Schritt-für-Schritt Anleitung für Endbenutzer +- **[Server Setup](server/README.md)** - WebDAV Server konfigurieren +- **[Vollständige Docs](DOCS.md)** - Features, Troubleshooting, Build-Anleitung --- -## 🎉 Neue Features in v1.1.0 +## 🛠️ Entwicklung -### Konfigurierbare Sync-Intervalle -- ⏱️ Wählbare Intervalle: 15/30/60 Minuten -- 📊 Transparente Akkuverbrauchs-Anzeige -- ⚡ Sofortige Anwendung ohne App-Neustart - -### Über-Sektion -- 📱 App-Version & Build-Datum -- 🌐 Links zu GitHub Repo & Entwickler -- ⚖️ Lizenz-Information - -### Verbesserungen -- 🎯 Benutzerfreundliche Doze-Mode Erklärung -- 🔕 Keine störenden Sync-Fehler Toasts im Hintergrund -- 📝 Erweiterte Debug-Logs für Troubleshooting - ---- - -## 🛠️ Selbst bauen - -```fish +```bash cd android ./gradlew assembleStandardRelease -# APK: android/app/build/outputs/apk/standard/release/ ``` ---- - -## 🐛 Troubleshooting - -### Auto-Sync funktioniert nicht - -1. **Akku-Optimierung deaktivieren** - - Einstellungen → Apps → Simple Notes → Akku → Nicht optimieren -2. **WLAN-Verbindung prüfen** - - Funktioniert nur im selben Netzwerk wie Server -3. **Server-Status checken** - - Settings → "Verbindung testen" - -### Server nicht erreichbar - -```fish -# Status prüfen -docker compose ps - -# Logs ansehen -docker compose logs -f - -# IP-Adresse finden -ip addr show | grep "inet " | grep -v 127.0.0.1 -``` - -Mehr Details: [📖 Dokumentation](DOCS.md) - ---- - -## 🤝 Contributing - -Contributions sind willkommen! Bitte öffne ein Issue oder Pull Request. +➡️ **Details:** [Build-Anleitung in DOCS.md](DOCS.md) --- @@ -132,6 +67,4 @@ Contributions sind willkommen! Bitte öffne ein Issue oder Pull Request. MIT License - siehe [LICENSE](LICENSE) ---- - -**Version:** 1.1.0 · **Status:** ✅ Produktiv · **Gebaut mit:** Kotlin + Material Design 3 +**v1.1.0** · Gebaut mit Kotlin + Material Design 3 diff --git a/README.old.md b/README.old.md deleted file mode 100644 index cc67b6b..0000000 --- a/README.old.md +++ /dev/null @@ -1,335 +0,0 @@ -# Simple Notes Sync 📝 - -> Minimalistische Android-App für Offline-Notizen mit automatischer WLAN-Synchronisierung - -Eine schlanke Notiz-App ohne Schnickschnack - perfekt für schnelle Gedanken, die automatisch zu Hause synchronisiert werden. - ---- - -## ✨ Features - -- 📝 **Offline-first** - Notizen werden lokal gespeichert und sind immer verfügbar -- 🔄 **Auto-Sync** - Automatische Synchronisierung wenn du im Heimnetzwerk bist -- 🏠 **WebDAV Server** - Deine Daten bleiben bei dir (Docker-Container) -- 🔋 **Akkuschonend** - Nur ~0.4% Akkuverbrauch pro Tag -- 🚫 **Keine Cloud** - Keine Google, keine Microsoft, keine Drittanbieter -- 🔐 **Privacy** - Keine Tracking, keine Analytics, keine Standort-Berechtigungen - ---- - -## 📥 Installation - -### Android App - -**Option 1: APK herunterladen** - -1. Neueste [Release](../../releases/latest) öffnen -2. `app-debug.apk` herunterladen -3. APK auf dem Handy installieren - -**Option 2: Selbst bauen** - -```bash -cd android -./gradlew assembleDebug -# APK: android/app/build/outputs/apk/debug/app-debug.apk -``` - -### WebDAV Server - -Der Server läuft als Docker-Container und speichert deine Notizen. - -```bash -cd server -cp .env.example .env -nano .env # Passwort anpassen! -docker-compose up -d -``` - -**Server testen:** -```bash -curl -u noteuser:dein_passwort http://192.168.0.XXX:8080/ -``` - ---- - -## 🚀 Schnellstart - -1. **Server starten** (siehe oben) -2. **App installieren** und öffnen -3. **Einstellungen öffnen** (⚙️ Symbol oben rechts) -4. **Server konfigurieren:** - - Server-URL: `http://192.168.0.XXX:8080/notes` - - Benutzername: `noteuser` - - Passwort: (aus `.env` Datei) - - Auto-Sync: **AN** -5. **Fertig!** Notizen werden jetzt automatisch synchronisiert - ---- - -## 💡 Wie funktioniert Auto-Sync? - -Die App prüft **alle 30 Minuten**, ob: -- ✅ WLAN verbunden ist -- ✅ Server im gleichen Netzwerk erreichbar ist -- ✅ Neue Notizen vorhanden sind - -Wenn alle Bedingungen erfüllt → **Automatische Synchronisierung** - -**Wichtig:** Funktioniert nur im selben Netzwerk wie der Server (kein Internet-Zugriff nötig!) - ---- - -## 🔋 Akkuverbrauch - -| Komponente | Verbrauch/Tag | -|------------|---------------| -| WorkManager (alle 30 Min) | ~0.3% | -| Netzwerk-Checks | ~0.1% | -| **Total** | **~0.4%** | - -Bei einem 3000 mAh Akku entspricht das ~12 mAh pro Tag. - ---- - -## 📱 Screenshots - -_TODO: Screenshots hinzufügen_ - ---- - -## 🛠️ Technische Details - -Mehr Infos zur Architektur und Implementierung findest du in der [technischen Dokumentation](DOCS.md). - -**Stack:** -- **Android:** Kotlin, Material Design 3, WorkManager -- **Server:** Docker, WebDAV (bytemark/webdav) -- **Sync:** Sardine Android (WebDAV Client) - ---- - -## 📄 Lizenz - -[Lizenz hier einfügen] - ---- - -## 🤝 Beitragen - -Contributions sind willkommen! Bitte öffne ein Issue oder Pull Request. - ---- - -## 📄 Lizenz - -MIT License - siehe [LICENSE](LICENSE) - ---- - -**Projekt Start:** 19. Dezember 2025 -**Status:** ✅ Funktional & Produktiv - -## 📖 Dokumentation - -### In diesem Repository: - -- **[QUICKSTART.md](QUICKSTART.md)** - Schnellstart-Anleitung -- **[server/README.md](server/README.md)** - Server-Verwaltung - -### Vollständige Dokumentation (project-docs): - -- [README.md](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/README.md) - Projekt-Übersicht & Architektur -- [IMPLEMENTATION_PLAN.md](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/IMPLEMENTATION_PLAN.md) - Detaillierter Sprint-Plan -- [SERVER_SETUP.md](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/SERVER_SETUP.md) - Server-Setup Details -- [ANDROID_GUIDE.md](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/ANDROID_GUIDE.md) - 📱 Kompletter Android-Code -- [NOTIFICATIONS.md](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/NOTIFICATIONS.md) - Notification-System Details -- [WINDOWS_SETUP.md](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/WINDOWS_SETUP.md) - 🪟 Windows + Android Studio Setup -- [CODE_REFERENCE.md](https://github.com/inventory69/project-docs/blob/main/simple-notes-sync/CODE_REFERENCE.md) - Schnelle Code-Referenz - -## ⚙️ Server Konfiguration - -**Standard-Credentials:** -- Username: `noteuser` -- Password: Siehe `.env` im `server/` Verzeichnis - -**Server-URL:** -- Lokal: `http://localhost:8080/` -- Im Netzwerk: `http://YOUR_IP:8080/` - -IP-Adresse finden: -```bash -ip addr show | grep "inet " | grep -v 127.0.0.1 -``` - -## 📱 Android App Setup - -### Vorraussetzungen - -- Android Studio Hedgehog (2023.1.1) oder neuer -- JDK 17 -- Min SDK 24 (Android 7.0) -- Target SDK 34 (Android 14) - -### In App konfigurieren - -1. App starten -2. Einstellungen öffnen -3. Server-URL eintragen (z.B. `http://192.168.1.100:8080/`) -4. Username & Passwort eingeben -5. Heim-WLAN SSID eingeben -6. "Verbindung testen" - -## 🔧 Entwicklung - -### Server-Management - -```bash -# Status prüfen -docker-compose ps - -# Logs anschauen -docker-compose logs -f - -# Neustarten -docker-compose restart - -# Stoppen -docker-compose down -``` - -### Android-Build - -```bash -cd android -./gradlew assembleDebug - -# APK Location: -# app/build/outputs/apk/debug/app-debug.apk -``` - -## 🧪 Testing - -### Server-Test - -```bash -# Testdatei hochladen -echo '{"id":"test","title":"Test","content":"Hello"}' > test.json -curl -u noteuser:password -T test.json http://localhost:8080/test.json - -# Datei abrufen -curl -u noteuser:password http://localhost:8080/test.json - -# Datei löschen -curl -u noteuser:password -X DELETE http://localhost:8080/test.json -``` - -### Android-App - -1. Notiz erstellen → speichern → in Liste sichtbar ✓ -2. WLAN verbinden → Auto-Sync ✓ -3. Server offline → Fehlermeldung ✓ -4. Konflikt-Szenario → Auflösung ✓ - -## 📦 Deployment - -### Server (Production) - -**Option 1: Lokaler Server (Raspberry Pi, etc.)** -```bash -docker-compose up -d -``` - -**Option 2: VPS (DigitalOcean, Hetzner, etc.)** -```bash -# Mit HTTPS (empfohlen) -# Zusätzlich: Reverse Proxy (nginx/Caddy) + Let's Encrypt -``` - -### Android App - -```bash -# Release Build -./gradlew assembleRelease - -# APK signieren -# Play Store Upload oder Direct Install -``` - -## 🔐 Security - -**Entwicklung:** -- ✅ HTTP Basic Auth -- ✅ Nur im lokalen Netzwerk - -**Produktion:** -- ⚠️ HTTPS mit SSL/TLS (empfohlen) -- ⚠️ Starkes Passwort -- ⚠️ Firewall-Regeln -- ⚠️ VPN für externen Zugriff - -## 🐛 Troubleshooting - -### Server startet nicht - -```bash -# Port bereits belegt? -sudo netstat -tlnp | grep 8080 - -# Logs checken -docker-compose logs webdav -``` - -### Android kann nicht verbinden - -- Ist Android im gleichen WLAN? -- Ist die Server-IP korrekt? -- Firewall blockiert Port 8080? -- Credentials korrekt? - -```bash -# Ping zum Server -ping YOUR_SERVER_IP - -# Port erreichbar? -telnet YOUR_SERVER_IP 8080 -``` - -## 📝 TODO / Roadmap - -### Version 1.0 (MVP) -- [x] Docker WebDAV Server -- [ ] Android Basic CRUD -- [ ] Auto-Sync bei WLAN -- [ ] Error Handling -- [ ] Notifications - -### Version 1.1 -- [ ] Suche -- [ ] Dark Mode -- [ ] Markdown-Support - -### Version 2.0 -- [ ] Desktop-Client (Flutter Desktop) -- [ ] Tags/Kategorien -- [ ] Verschlüsselung -- [ ] Shared Notes - -## 📄 License - -MIT License - siehe [LICENSE](LICENSE) - -## 👤 Author - -Created for personal use - 2025 - -## 🙏 Acknowledgments - -- [bytemark/webdav](https://hub.docker.com/r/bytemark/webdav) - Docker WebDAV Server -- [Sardine Android](https://github.com/thegrizzlylabs/sardine-android) - WebDAV Client -- [Android WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager) - Background Tasks - ---- - -**Project Start:** 19. Dezember 2025 -**Status:** 🚧 In Development