Files
Melo/CHANGELOG.md
T
dustinandClaude Opus 5 1325badf90 Equalizer (nativ), Dolby-Atmos-Zugang und Auto-Wiedergabe bei Kopfhoerern
- Native Bruecke AudioEffectsBridge.kt: Equalizer + BassBoost + Virtualizer
  auf der Audio-Session des Players, inkl. System-Klangeffekt-Panel
- Dart-Seite AudioEffects: Presets, Baender, Bass/Immersiv, persistiert
- EqualizerScreen nach Vorlage inkl. Drehregler (CustomPainter)
- Auto-Wiedergabe bei verbundenen Kopfhoerern (Klinke + Bluetooth)
- MODIFY_AUDIO_SETTINGS im Manifest
- Einstellungen: neuer Bereich "Ton"

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011snPXPafPC5i87o68H14W7
2026-08-20 18:35:06 +02:00

308 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 (AZ#)** 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 (`<path>`), nackte URLs (`<url>`), `Bearer`-Token,
JWTs (`<jwt>`) und lange Hex-IDs (`<hex>`).
- `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)