# Changelog Alle nennenswerten Änderungen an diesem Projekt werden hier dokumentiert. Format angelehnt an [Keep a Changelog](https://keepachangelog.com/de/1.0.0/). ## [Unreleased] ### 🎚️ Equalizer, Dolby Atmos und automatische Wiedergabe (2026-08-20) - ✅ **Was:** Die Einstellungen haben einen neuen Bereich **Ton** mit Equalizer, Dolby Atmos und der automatischen Wiedergabe bei Kopfhörern. - 🎛️ **Equalizer (echt, nicht nachgebaut):** Neuer Bildschirm mit den Klangprofilen deines Geräts (Normal, Rock, Pop …), den Frequenzbändern als senkrechte Regler mit Beschriftung (60Hz … 14.0kHz) und den beiden Drehreglern **Bass** und **Immersives Audio** — wie auf deinem Bild. Zum Regeln senkrecht über den Drehregler wischen. Alle Werte werden gespeichert und nach dem Neustart wiederhergestellt. - 🔊 **Wie das technisch geht:** Neue native Android-Brücke (`AudioEffectsBridge.kt`) auf `android.media.audiofx` — Equalizer, BassBoost und Virtualizer hängen an der Audio-Session des Players. Da just_audio die Session-ID erst beim Abspielen meldet, verbindet sich die App bei jedem Wechsel automatisch neu. Bietet ein Gerät einen Effekt nicht an, wird er ausgegraut statt die App abstürzen zu lassen. - 🎬 **Dolby Atmos:** Öffnet die **Klangeffekte des Systems** — auf deinem POCO ist das die Dolby-Atmos-Seite. Eine App kann Dolby Atmos nicht selbst steuern; der System-Weg ist der einzige, der wirklich funktioniert. Bietet ein Gerät die Seite nicht an, sagt Melo das. - 🎧 **Automatische Wiedergabe:** Neuer Schalter — sobald Kopfhörer verbunden werden (Klinke **oder Bluetooth**), spielt Melo weiter. Eine bereits laufende Wiedergabe wird nie unterbrochen, und ohne Warteschlange passiert nichts. - 🔧 **Details:** - Neu: `player/audio_effects.dart` (6 Tests, u. a. Grenzwerte und Wiederherstellen), `player/headphone_autoplay.dart` (6 Tests), `settings/equalizer_screen.dart` inkl. selbst gezeichnetem Drehregler. - `MODIFY_AUDIO_SETTINGS` im Manifest ergänzt (nötig für die Effekte). - `MainActivity.kt` registriert die Brücke und gibt die Effekte beim Beenden wieder frei. - ✅ **Getestet:** 141 Tests grün, `flutter analyze` ohne Befund. ### 🏷️ Kategorien, Metadaten-Ansicht und Expertenmodus (2026-08-20) - ✅ **Was:** Jeder Song kann jetzt **mehreren Kategorien** angehören. Sie stehen in der Songzeile hinter dem Künstler ("Neoni | Trap cool · Chill") — genau wie in deinem Entwurf. - 📥 **Woher sie kommen:** Beim Scan aus dem **Genre-Tag** der Datei. Mehrere Werte in einem Tag werden automatisch getrennt (`;` `,` `|` `/`), doppelte fallen weg. Über **⋮ → Metadaten → Bearbeiten** kannst du Kategorien selbst hinzufügen oder entfernen; bereits vergebene Kategorien werden als Vorschläge angeboten. - 🔒 **Von Hand schlägt Automatik:** Sobald du die Kategorien eines Songs selbst änderst, überschreibt ein späterer Scan sie **nicht** mehr. - 🖼️ **Gleiche Kategorie = gleiches Coverbild:** Neue Einstellung unter *Einstellungen → Darstellung* (standardmäßig **an**, jederzeit abschaltbar). Ist sie an, zeigen alle Songs einer Kategorie das Bild der **ersten** Kategorie; hat die Kategorie kein Bild, bleibt das eigene Cover. Im Metadaten-Fenster ist die bildgebende Kategorie mit einem Bild-Symbol markiert. - 🔬 **Expertenmodus:** Im Metadaten-Fenster ausklappbar — Titel, Künstler, Album, Dauer, Wiedergaben, Hinzugefügt-Datum, Herkunft der Kategorien, Format, Dateigröße und Pfad. - 🔧 **Details:** - DB-Schema 4: neue Tabelle `song_categories` (Song ↔ Kategorie mit Reihenfolge) und Spalte `categories_edited`. Bestehende Bibliotheken werden automatisch migriert. - Neu: `library/categories.dart` (reine Logik: Tag zerlegen, Cover je Kategorie ermitteln — 12 Tests), `library/category_service.dart` (hält Kategorien + Cover-Zuordnung einmal zentral, 3 Tests), `library/song_detail_sheet.dart`, `settings/app_settings.dart`. - Beide Scanner (Android-MediaStore und Ordner-Scan) schreiben die Kategorien mit. - Das Drei-Punkte-Menü der Songzeile ersetzt den bisherigen Playlist-Knopf und enthält "Metadaten" und "Zu Wiedergabeliste hinzufügen". - ✅ **Getestet:** 129 Tests grün, `flutter analyze` ohne Befund. ### 🎨 Neue Melo-Oberfläche: 4 Tabs + Sortierung (2026-08-20) - ✅ **Was:** Die App hat jetzt die von dir gewünschte Struktur mit **4 Tabs: Meine Musik · Suche · Favoriten · Download**. "Meine Musik" ist der neue Startbildschirm — **ohne Topbar**, wie du es wolltest. - 🎵 **Meine Musik:** Oben eine Kopfzeile mit Einstellungs-Icon (links), Suchfeld (Mitte) und ?-Icon für die Musikerkennung (rechts, kommt später). Darunter Schnellzugriff-Karten (Favoriten · Wiedergabelisten · Zuletzt · Künstler · Alben), dann **Shuffle-Wiedergabe + Sortieren**, dann die komplette Liederliste. - ↕️ **Sortieren (neu!):** Über das Symbol rechts neben "Shuffle-Wiedergabe" kannst du wählen zwischen **Zuletzt hinzugefügt**, **Name (A–Z–#)** und **Wie oft abgespielt** — jeweils auf- oder absteigend. Die Wahl wird gespeichert und überlebt einen Neustart. Bei "Name" stehen Buchstaben vorne und Ziffern/Sonderzeichen hinten unter "#"; Umlaute sortieren richtig ein (Ärger steht bei A, nicht hinter Z). - ❤️ **Favoriten-Tab:** eigener Tab mit Shuffle-Wiedergabe und **genau derselben Sortierung** — mit eigener, getrennt gespeicherter Einstellung. - ⬇️ **Download-Tab:** durchsucht den verbundenen Navidrome-Server (Alben/Künstler); abgespielte Titel werden weiterhin automatisch lokal zwischengespeichert. - 🔢 **"Wie oft abgespielt" zählt jetzt wirklich:** Neue Spalte `playCount` in der Datenbank (Schema 3, bestehende Bibliotheken werden automatisch migriert). Gezählt wird beim Start eines Titels — nicht sekündlich, solange er läuft. - 🎨 **Farben:** Schwarz auf **#0B0B10** und Melo-Rot **#c0392b** (vorher ein helleres Rot). - 🔧 **Details:** - Neu: `library/song_sort.dart` (reine Sortier-Logik, 11 Tests), `shared/sort_store.dart` (Speichern der Wahl, 4 Tests), `shared/sortable_song_list.dart` (Shuffle + Sortier-Menü), `library/my_music_screen.dart`, `library/favorites_screen.dart`, `downloads/downloads_screen.dart`. - Der alte `library_screen.dart` (Tabs Alle/Künstler/Alben/Server) ist entfallen — seine Inhalte leben jetzt in "Meine Musik" (Alle), als eigene Bildschirme (Künstler/Alben) und im Download-Tab (Server). - **Musik hinzufügen** und **Erneut scannen** saßen in der entfernten Topbar und stehen jetzt in den **Einstellungen → Bibliothek** (zusätzlich weiterhin im leeren Zustand von "Meine Musik"). - Der Mini-Player ist jetzt auf allen Tabs sichtbar (vorher war der Player ein eigener Tab). - 🐛 **Nebenbei gefixt:** Das Sortier-Menü ist scrollbar — auf niedrigen Bildschirmen bzw. im Querformat war der "Übernehmen"-Knopf sonst nicht erreichbar. Schnellzugriff-Karten liefen um 2 Pixel über. - ✅ **Getestet:** 107 Tests grün, `flutter analyze` ohne Befund. ### 🔎 Login-Dialog zeigt jetzt die echte Server-Fehlermeldung (2026-08-20) - ✅ **Was:** Schlägt der Navidrome-Login fehl, zeigt der Dialog jetzt die Original-Meldung des Servers (z. B. „Wrong username or password") statt nur „Login fehlgeschlagen". So ist sofort klar, ob das Passwort falsch ist oder ein Netzwerkproblem vorliegt. - 🔧 **Details:** - `NavidromeService.letzterLoginFehler` hält die Server-Meldung des letzten abgelehnten Logins fest (wird bei jedem Ping zurückgesetzt). - Das Fehler-Log enthält jetzt die Passwort-**Länge** (`pwLen=…`, nie das Passwort selbst) — ein Tippfehler wird so im Log sofort sichtbar (`Melo…!` hat 11 Zeichen). - 🐛 **Hintergrund (tiefe Debug-Runde):** Server-seitig ist alles nachweislich korrekt — Subsonic-API (`/rest/*`) läuft trotz SSO-Umbau ohne Forward-Auth, DB-Passwort für „Baka" stimmt, und die exakte App-Token-Logik (Base64-Salt + md5) wurde 8/8-mal erfolgreich gegen den Live-Server reproduziert. Die Ablehnungen kommen von einem falschen Passwort-Wert auf dem Gerät; die neue Fehlermeldung macht genau das künftig direkt sichtbar. ### 🔎 Login-Diagnose: Passwort-Sichtbarkeit + Trim (2026-08-20) - 🐛 **„Login fehlgeschlagen" trotz korrekter Zugangsdaten:** Systematische Analyse (App-Code, App-Logs, Caddy/Navidrome-Logs, 1:1-Nachbau des App-Requests inkl. Salt/Token) hat bewiesen: **App-Code, Server, User „Baka" und Passwort sind korrekt** — der Fehler lag im auf dem Gerät verwendeten Credential-Wert (der ältere Build mit dem Ping-Fehlalarm persistierte ungültige Zugangsdaten; verdeckte Tippfehler im Passwortfeld blieben unsichtbar). - 🔧 **Passwort-Anzeigen-Umschalter** (Auge-Icon) im Navidrome-Login — Tippfehler werden sichtbar. - 🔧 **URL + Passwort werden getrimmt** (randständige Leerzeichen aus Autofill / Tastatur entfernt). - 🔧 **Default-User im Login ist jetzt „Baka"** (vorher „Dustin") — verhindert versehentlichen Login mit falschem User. - ℹ️ Ein erfolgreicher Login überschreibt die alten (ungültigen) gespeicherten Zugangsdaten — der Ping-Fix aus dieser Version stellt sicher, dass künftig nur noch gültige Credentials gespeichert werden. ### 🔒 Datenschutz: Log-Bereinigung vor Server-Upload (2026-08-20) - ✅ **Was:** Diagnose-Logs werden jetzt zentral bereinigt, bevor sie an `logs.baka-net.de` gehen. Der lokale `debugPrint` bleibt vollständig. - 🔧 **Details:** - Freitext-Scrubber für `message` + `stackTrace`: maskiert sensible `key=value`-Fragmente (`user=`, `pw=`, `password=`, `token=`, `secret=`, `url=`), Datei-Pfade (``), nackte URLs (``), `Bearer`-Token, JWTs (``) und lange Hex-IDs (``). - `stackTrace` wird auf max. 8 Zeilen gekürzt. - `deviceModel` sendet nur noch die grobe Plattform (`android`/`ios`) statt Hersteller+Modell (war ein Geräte-Fingerprint) — `device_info_plus` im Logger entfernt. - 🐛 **Fix (Quelle):** Der Navidrome-Login in `settings_screen` loggte Benutzername + Server-URL im Klartext (`Login: url=… user=…`). Diese Aufrufe senden jetzt nur noch den neutralen Status inkl. `pwLeer`-Flag. - 🧪 **Tests:** neue Suite `test/logger_service_test.dart` (9 Tests) — 79/79 grün, `flutter analyze` ohne Issues. - ℹ️ **Offen:** Opt-in/Einwilligung für den Diagnose-Versand bleibt ein separater Folgeschritt (braucht UI). ### 🐛 Server-Bibliothek lädt + Tab abgeschnitten (2026-08-20) - 🐛 **Server-Bibliothek lud nicht ("Erneut versuchen"):** Ursache war, dass der Code das Subsonic-`status`-Feld ignorierte. Navidrome liefert auch bei falschem Passwort **HTTP 200** mit `status:"failed"` — `ping()` meldete dadurch fälschlich „Login ok", und `getAlben`/`getArtists` behandelten die Fehlerantwort still als „leer". - 🔧 `ping()` prüft jetzt den Body (`status`) — kein Fehlalarm mehr beim Login. - 🔧 `getAlben`/`getArtists` werfen bei `status:"failed"` eine `NavidromeException` mit Server-Meldung statt still `[]` zurückzugeben. - 🔧 Der Server-Tab zeigt die echte Server-Fehlermeldung (z. B. „Wrong username or password") statt nur „Keine Alben geladen". - 🔧 Album-Abruf nutzt jetzt den ID3-Endpoint `getAlbumList2` (konsistent zu `getArtists`) — der alte Folder-Endpoint `getAlbumList` liefert bei tag-organisierten Libraries leer. - 🐛 **Tab „🌐 Server" war abgeschnitten** (nur „Serve" sichtbar): Die 4 festen Tabs waren zu eng. `labelPadding` verkleinert (engere Abstände) — Schriftgröße unverändert. - 🧪 Neue Tests: `test/navidrome_parse_test.dart` (5). 84/84 grün, analyze sauber. ### 🔧 Log-Upload System - Fixes (2026-08-19) - ✅ **ERROR-Level Logging**: Fehler werden SOFORT zum Server hochgeladen (async/await Fixed) - ✅ **Navidrome-Service Error Logging**: Alle API-Fehler (ping, getAlben, getSongs, getFavorites, getArtists, getArtistSongs, getLyrics, scrobble, getBookmarks, getPlaylists, getPlaylistSongs) werden jetzt mit `logger.error()` zum Server geloggt (statt nur debugPrint) - ✅ **Login-Fehler Detail-Logging**: Fehler enthalten URL, User, Exception-Typ und StackTrace - ✅ **HTTP-Error bei Stream**: Stream-Fehler mit HTTP-Statuscode werden auch geloggt - ✅ **Payload-Format**: Logs senden als `{"logs": [...]}` Array zum Server ### 🎉 RELEASE BUILD v3: Phase 2 + Login + Auto-Bugreport System! **Build Date:** 2026-08-19 21:30 **APK (Release/Universal):** `app-release.apk` (22.3 MB) — **Mit Auto-Logger + Login-Improvements!** **APK (ARM64-Specific):** `app-arm64-v8a-release.apk` (21 MB) — **Optimal für POCO X7 Pro** **Tests:** 70/70 ✅ **Build Status:** ✅ SUCCESS **Neue Features in dieser Build:** - ✨ Login-Verbesserungen: Auto-URL + User-Buttons + Gast-Modus - 📊 Auto-Bugreport System: Logger sendet Fehler sofort + andere Logs gesammelt zum Server - Device-Info (Model + OS) + Timestamp + Stack-Traces - Integration in Navidrome-Service für Login-Fehler-Diagnose - 📝 Alle Phase-2-Features (Sync, Caching, Player, Controls) - 🔒 Secure Credential-Speicherung - 🎵 Enhanced MiniPlayer mit Skip-Buttons ### Phase 2 (Part 1-8 Completed — MILESTONE!) - 🗄️ **Auto-Caching**: Lieder werden automatisch beim Streamen lokal gespeichert! - Cache-First-Logik: Existierende Dateien lokal spielen - Fallback: Vom Server streamen wenn kein Cache - Cache-Speicher-Status in Settings (MB/KB/B) mit Clear-Button - 🗄️ **CacheManager**: MD5-Hash-basierte Cache-Verwaltung (getCacheSize, clearCache) - 📴 **Offline-Mode**: Toggle in Settings aktiviert Offline-Betrieb (nur gecachte Lieder spielen) - 🎤 **Artist-Browse**: Toggle in Navidrome-Tab zwischen Albums ↔ Künstler, Tap lädt alle Songs des Künstlers - 🌟 **Favoriten-Sync**: Button in Settings lädt Server-Favoriten und importiert sie lokal - 📊 **History-Sync**: Wiedergabe-Position vom Server laden + alle 5s zum Server senden (Subsonic-Bookmarks) - 📋 **Playlisten-Sync**: Button in Settings lädt alle Server-Playlisten (mit 🌐 Präfix zur Unterscheidung) - 🔒 **Lock-Screen Controls**: Notification mit Play/Pause/Skip-Buttons auf Android Lock Screen - 🎵 **Enhanced MiniPlayer**: Now-Playing Widget auf allen Tabs mit Skip-Buttons + Progress-Bar - Infrastructure für Multi-Device Sync vorbereitet ### Added - 🌐 **Musikserver-Tab** in Bibliothek: Zeige Alben vom Navidrome-Server, tippe um Album abzuspielen - 📝 **Lyrics-Anzeige**: Lyrics-Button im Now-Playing Screen, Bottom-Sheet mit Song-Lyrics vom Server - 🔀 **Shuffle & Repeat Modi**: Shuffle-Button (aktiv = rot), Repeat-Cycle (Off → All → One), beide im Player - 🌐 Navidrome-Integration (Musikserver-Verbindung): Settings-Tab bietet Login/Logout für Subsonic-API-kompatible Server - Navidrome-Service mit sichere Credential-Speicherung (Secure Storage + SharedPreferences) - Server-Album-Browser: Lädt Alben vom Server, zeigt Songcount, tippe um Album in Queue zu laden - Server-APIs erweitert: getArtists(), getArtistSongs(), setFavorite(), getFavorites(), getLyrics() (Phase 2 vorbereitet) - Dependencies für Navidrome hinzugefügt: http, crypto, shared_preferences, flutter_secure_storage ### Known Limitations (Phase 2) - Server-Favoriten-Sync: APIs vorhanden, UI-Integration in Phase 2 - Artist-Browse: APIs vorhanden, UI in Phase 2 - Server-Caching: Musik wird nicht lokal für Offline gecacht (Phase 2) - Lyrics-Sync: Keine Timed-Synchronisation (Phase 2+) ## [1.0.0-alpha] ### Added - Playlisten-Tab: Favoriten-Kurzeinstieg oben, Liste aller Playlisten mit Songanzahl, Erstellen-Dialog (FAB), Löschen mit Bestätigung - 🎵➕ Songs per Bottom-Sheet zu Playlisten hinzufügen (neuer Button in der Songliste, neben dem Favoriten-Herz) - Playlist-Detailansicht: Songs per Drag & Drop umsortieren, einzeln entfernen, Antippen spielt die Playlist ab dieser Stelle - Datenbank: Playlisten, Favoriten und Wiedergabe-Historie Tabellen (Drift, Schema v2) - PlaylistService für Playlisten- und Favoriten-Verwaltung - ❤️ Favoriten-Herz in der Songliste (ausgefüllt/leer) - ❤️ Favoriten-Herz auch im Now-Playing-Screen (aktueller Song) - Bibliothek: Künstler- und Alben-Tabs neben "Alle" — Songs werden clientseitig aus der bestehenden Songliste gruppiert (alphabetisch sortiert, fehlender Künstler/Album → "Unbekannt" / "Unbekanntes Album"); Antippen öffnet die Songliste des jeweiligen Künstlers/Albums, Alben zeigen zusätzlich das Cover - Warteschlangen-Ansicht (Queue-Button in der Now-Playing-AppBar): zeigt die aktuelle Wiedergabeliste, hebt den laufenden Titel hervor, per Antippen direkt zu einem Titel springen, Titel entfernen oder per Drag & Drop umsortieren — ohne Änderungen am Audio-Handler (Queue wird clientseitig neu berechnet und neu geladen) - Wiedergabeposition wird alle 5 Sekunden gespeichert und beim erneuten Abspielen eines Songs automatisch fortgesetzt (kein Resume bei den letzten 3 Sekunden eines Songs, um ein sofortiges Ende zu vermeiden) - Settings-Tab: Bibliotheks-Statistik (Song-Anzahl + Gesamtspieldauer), Musik-Berechtigung mit Link in die Systemeinstellungen, kurzer "Über Melo"-Abschnitt — bewusst ohne Platzhalter für Profil/Cloud-Sync/ Geräte-Verwaltung, da es dafür noch kein Account-/Cloud-System gibt (Phase 2) **Damit ist das komplette 5-Tab-MVP fertig: Player / Bibliothek / Playlisten / Suche / Settings — inklusive Playlisten, Favoriten, Warteschlangen-Verwaltung, Künstler-/Alben-Browsing und automatischem Fortsetzen der Wiedergabeposition.** ### Changed - Now-Playing-Screen läuft jetzt als eigener Tab statt als gepushter Screen (kein Schließen-Button mehr in der AppBar) - MediaItem trägt jetzt die Song-UUID mit (`extras['songId']`), nicht mehr nur die Datei-URI - Finales 5-Tab-Layout: Player / Bibliothek / Playlisten / Suche / Settings (Playlisten und Settings vorerst als Platzhalter) - "Zuletzt hinzugefügt" aus der alten Startseite ist jetzt Teil der Bibliothek (horizontale Leiste oben) - MiniPlayer wird auf dem Player-Tab ausgeblendet (dort läuft schon die volle Ansicht) ### Fixed - 🐛 Der APK-Build funktioniert jetzt überhaupt. Drei Dinge waren nötig: `compileSdk = 37` und `kotlin.jvm.target.validation.mode=warning` existierten bisher nur lokal auf dem Server und fehlten im Repo — ohne sie bricht der Build ab, weil `permission_handler` SDK 37 verlangt. Zusätzlich hebt ein Gradle- Workaround jetzt Plugin-Module mit zu altem `compileSdk` auf 36 an: `on_audio_query_android` kompiliert gegen SDK 33, seine AndroidX-Abhängigkeiten verlangen aber mindestens 34 (16 Metadaten-Konflikte). ### Removed - Alte Startseite (`home_screen.dart`) entfernt — Funktionalität in die Bibliothek verschoben ### Known Issues - Genre-Browsing fehlt noch: die `Songs`-Tabelle hat keine Genre-Spalte und keiner der Scanner (scan_service.dart, android_scan.dart) liest Genre- Metadaten aus den Dateien aus. Das ursprünglich geplante dritte Bibliotheks- Tab "Genres" ist deshalb nicht umgesetzt — braucht eine Schema-Migration plus Metadaten-Extraktion im Scanner (eigene Aufgabe, außerhalb dieses Tasks)