This repository has been archived on 2026-08-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
melo-app/.hermes/plans/2026-07-23_180000-melo-server-sync.md
T

172 lines
5.2 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.
# Melo App Server-Sync & Widgets Implementation Plan
> **Für Hermes:** Schritt-für-Schritt abarbeiten, keine Tasks springen.
**Goal:** Melo App um Widgets + Hidden Message "Seit 2008" erweitern, dann Server-Sync auf Aingrad aufsetzen (Musik zentral lagern, von jedem Gerät abrufbar).
**Architektur:**
- Phase 1+2: Reine App-Erweiterungen (Widgets + Easter Egg)
- Phase 3: Server als Caddy-File-Server + JSON-API, App holt Song-Liste und lädt runter
**Tech Stack:** Flutter/Dart, Caddy (läuft auf Aingrad), SQLite (bereits vorhanden)
---
## Phase 1: Widgets
### Task 1: Home-Widget (Recent Songs)
**Objective:** Widget zeigt die letzten 5 abgespielten Songs auf dem Home-Screen
**Files:**
- Create: `lib/widgets/recent_widget.dart`
- Modify: `lib/screens/home_screen.dart` (Widget einbauen)
- Modify: `lib/viewmodels/melo_home_viewmodel.dart` (letzte Songs laden)
**Schritte:**
1. `recent_widget.dart` erstellen kleiner Container mit den letzten 5 Songs, ähnlich wie StatistikCard aufgebaut (schwarz/rot Design)
2. ViewModel: `letzteSongs` laden aus `wiedergabe_verlauf`-Tabelle via `db.positionAktualisieren` die Tabelle existiert bereits
3. `home_screen.dart`: Widget unter StatistikCard einbauen
4. Nur sichtbar wenn `letzteSongs.isNotEmpty`
**Code-Skizze recent_widget.dart (~40 Zeilen):**
```dart
class RecentWidget extends StatelessWidget {
final List<Song> songs;
final void Function(Song) onPlay;
// UI: kleiner Container, 5 horizontale Einträge mit Cover + Titel
}
```
---
### Task 2: Tag-Statistik-Widget
**Objective:** Widget zeigt wie viele Songs pro Tag existieren (kleine Übersicht)
**Files:**
- Create: `lib/widgets/tag_stats_widget.dart`
- Modify: `lib/viewmodels/melo_home_viewmodel.dart` (Tag-Counts berechnen)
- Modify: `lib/screens/home_screen.dart`
**Schritte:**
1. ViewModel: `Map<String, int> tagCounts` zählt Songs pro Tag-Namen
2. `tag_stats_widget.dart` horizontale Chips mit Tag-Name + Count
3. In home_screen unter Tags-Leiste einbauen
---
## Phase 2: Hidden Message "Seit 2008"
### Task 3: Easter Egg auf dem Home-Screen
**Objective:** Versteckte Nachricht "Seit 2008" die nach 10 Song-Playbacks erscheint
**Files:**
- Modify: `lib/viewmodels/melo_home_viewmodel.dart` (Counter + Logik)
- Modify: `lib/screens/home_screen.dart` (Anzeige)
**Schritte:**
1. ViewModel: `int _playCount = 0; bool get zeigeBotschaft => _playCount >= 10;`
2. Bei jedem `spieleSong()``_playCount++`, bei 10 → `zeigeBotschaft = true`
3. UI: Wenn `zeigeBotschaft`, zeige ein rotes Herz mit "💌 Seit 2008" zwischen Header und StatistikCard
4. Nach einmaligem Anzeigen → `_playCount` zurücksetzen oder ausblendbar
**Code (~15 Zeilen ViewModel + ~10 Zeilen UI)**
---
## Phase 3: Server-Sync
### Task 4: Caddy-Subdomain einrichten
**Objective:** `musik.baka-net.de` served Musik-Ordner + JSON-Liste
**Files:**
- Modify: `/etc/caddy/Caddyfile` (auf Aingrad)
**Schritte:**
1. Ordner erstellen: `mkdir -p /home/dustin/musik/songs`
2. Caddyfile-Eintrag:
```
musik.baka-net.de {
root * /home/dustin/musik
file_server browse
@auth {
path /upload*
}
basicauth @auth {
melo HASH_PASSWORT
}
}
```
3. JSON-API Script: `/home/dustin/musik/api/songs.json` generiert Liste aller `.mp3`/`.m4a`/`.flac` Dateien mit Metadaten
4. `caddy reload`
---
### Task 5: ServerSyncService in der App
**Objective:** Neuer Service ruft Server-Liste ab und managed Downloads
**Files:**
- Create: `lib/services/server_sync_service.dart`
- Create: `lib/models/server_status.dart`
- Modify: `lib/screens/home_screen.dart` (neuer Tab)
**Schritte:**
1. `ServerSyncService` mit Methoden:
- `Future<List<ServerSong>> fetchServerList()` ruft `musik.baka-net.de/api/songs.json` ab
- `Future<Song?> downloadSong(ServerSong s)` lädt runter, speichert lokal + in DB
- `Future<bool> istBereitsLokal(ServerSong s)` checkt ob Datei existiert
2. Neuer Screen/Sheet: "📡 Server"-Button im Header öffnet Server-Browser
- Zeigt alle Songs auf dem Server
- Status: "Downloaded ✓" / "Download ⬇"
- Fortschrittsbalken wie beim YouTube-Download
---
### Task 6: Auto-Scan von Server-Songs
**Objective:** Einmal pro Session prüfen ob Server neue Songs hat
**Files:**
- Modify: `lib/viewmodels/melo_home_viewmodel.dart`
- Modify: `lib/services/server_sync_service.dart`
**Schritte:**
1. `ladeSongs()` → zusätzlich Server-Scan starten (im Hintergrund)
2. Neue Songs automatisch in DB eintragen (ohne Download nur Metadaten)
3. Badge im Server-Button: "3 neue Songs"
---
## Abhängigkeiten
```
Phase 1 (Widgets) → Phase 2 (Hidden Message) → Phase 3 (Server-Sync)
Alles unabhängig von Server
```
## Validation
- Widgets: Nach App-Neustart sichtbar, reagieren auf Song-Änderungen
- Hidden Message: Nach 10 Playbacks erscheint "Seit 2008"
- Server-Sync: `curl https://musik.baka-net.de/api/songs.json` liefert JSON
- App: Server-Tab zeigt Songs, Download funktioniert, Musik spielt ab
## Offene Fragen
- Soll Hidden Message persistiert werden (einmalig, nie wieder)?
- Auth für Download nötig oder öffentlich? (Server intern → öffentlich okay)
- Auto-Upload von lokal gescannten Songs zum Server? (Nur Download, kein Upload)