diff --git a/docs/superpowers/specs/2026-09-14-offene-punkte-und-weg-nach-vorn.md b/docs/superpowers/specs/2026-09-14-offene-punkte-und-weg-nach-vorn.md new file mode 100644 index 0000000..8d5962a --- /dev/null +++ b/docs/superpowers/specs/2026-09-14-offene-punkte-und-weg-nach-vorn.md @@ -0,0 +1,185 @@ +# Flixy — offene Punkte und der Weg nach vorn + +## Kontext + +Flixy gibt es als App für iPhone, iPad und Mac und seit heute als Weboberfläche für Rechner ohne App — Windows vor allem. In den letzten Stunden sind Live-TV für Jellyfin, ein randloser Aufmacher, ein Webfrontend und der Abgleich der Einstellungen entstanden. + +Vieles davon ist **gebaut, aber nicht belegt**. Der Anlass für diesen Plan ist doppelt: erstens eine ehrliche Liste dessen, was offen ist, zweitens die vier Stücke, die als Nächstes anstehen — die Weboberfläche brauchbar machen, eine Apple-TV-App, eine Admin-Oberfläche, und das Gefühl der Bedienung angleichen. + +Der Maßstab für den Funktionsumfang ist **JellyTV** (App Store), ausdrücklich als Anregung, nicht als Vorlage. Flixy kann dabei etwas, das JellyTV nicht kann: Plex als Server. + +**Ausdrücklich nicht gewollt:** iCloud-Sync der Einstellungen, Vision Pro, Push bei neuen Inhalten, Jellyseerr. + +--- + +## Teil A — Was offen ist + +### A1. Gebaut, aber nie an echten Daten geprüft + +Alles hiervon kompiliert und ist committet; keines davon hat je einen echten Server gesehen. + +| Was | Wo | Warum ungeprüft | +|---|---|---| +| **Live-TV für Jellyfin** — Sender, Programmführer, Einschalten | `JellyfinBackend+LiveTV.swift` | Kein Simulator-Zugang zu einem angemeldeten Server | +| **Aufnahmen und Timer** | `JellyfinBackend+Recordings.swift` | dito | +| **Plex-Live-TV nach dem Umbau** | `PlexBackend+LiveTV.swift` | **Das größte Risiko:** hier hat vorher etwas funktioniert, und die Schicht darunter wurde ausgetauscht | +| **Cover-Nachladen** (Wiederholung bei Zeitablauf) | `ArtworkLoader.swift` | Trat nur auf großen Fenstern mit vielen Kacheln auf | +| **Karussell-Auswahl alle 6 Stunden** | `HomeView.swift` | Wechselt erst nach Ablauf eines Fensters | +| **Kachelgröße und Aufmacherhöhe** | `HomeLayoutSettings.swift` | Neu, nie in der laufenden App gesehen | +| **Randloser Aufmacher, Insel blendet aus** | `RootView.swift`, `TopChrome.swift` | Vom Nutzer als „sieht ok aus" bestätigt, nicht im Einzelnen geprüft | + +### A2. Bewusst liegen gelassen + +- **Programmführer ohne Scroll-Melder** (`ProgramGuide.swift`): Die Insel bleibt dort beim Scrollen stehen, während sie überall sonst ausblendet. Verschachtelte Scroll-Struktur mit eigener `onScrollGeometryChange`-Logik — das Risiko war zu hoch für einen blinden Eingriff. +- **Doppelte Chrome-Zeile auf Detailseiten**: „Staffel 2" steht klein in der Leiste und groß im Bild. Entscheidung war, das zu bewerten, wenn der schwarze Balken weg ist. Er ist weg. + +### A3. Halbfertig im Arbeitsverzeichnis + +- **Phase 4 des Einstellungs-Abgleichs** (`web/frontend/index.html`, uncommittet): Wiedergabe (Tempo, Spulweite, Qualität) und Sprachen als Einstellungen, dazu Spulknöpfe und Tempo-Wahl im Player. Geschrieben, **nicht getestet**. + +### A4. Vom Nutzer angekündigt, noch nicht da + +- Screenshots von **JellyTV** für den Gefühls-Abgleich. +- Die **eine Sache**, die am iPhone-Bildschirmfoto aufgefallen war — nie genannt. + +--- + +## Teil B — Was gebaut werden soll + +Reihenfolge: **Web brauchbar → Admin → Apple TV.** Eine Oberfläche, die nichts kann, nützt niemandem. + +--- + +### B1. Das Web muss abspielen können + +**Befund.** Das Web ruft `/Items/{id}/PlaybackInfo` **kein einziges Mal** auf. Es baut die Stream-Adresse in `web/frontend/index.html:1395-1406` selbst zusammen und springt damit direkt zu einem geratenen Schritt. Im Swift-Code steht wörtlich, warum das nicht geht (`JellyfinBackend+Playback.swift:47-49`): + +> „Die Adresse kommt vom Server, nicht von uns. Er weiß, welche Spuren er kopieren kann und welche er neu rechnen muss; eine selbst zusammengebaute Adresse wäre eine Vermutung darüber." + +Es fehlen dadurch: `PlaySessionId`, die ausgehandelte `MediaSourceId`, die `TranscodingUrl` des Servers und die `DeviceId` am Stream. Der Stream-Abruf geht an `api()` vorbei und trägt **keine einzige Kopfzeile** — der Server sieht eine Anfrage ohne Gerät und ohne Sitzung. + +**Die Reihenfolge, die die App einhält und das Web nachziehen muss:** + +1. `POST /Items/{id}/PlaybackInfo` mit `DeviceProfile` → Vorbild: `playbackInfo` in `JellyfinBackend+Playback.swift:116-177` +2. Quelle aus `MediaSources` wählen (nicht `item.Id` annehmen — bei mehreren Fassungen falsch) +3. `TranscodingUrl` des Servers relativ zur Basisadresse auflösen +4. `PlaySessionId` mitführen — für Fortschritt und für `DELETE /Videos/ActiveEncodings` am Ende + +**Weitere Funde, die mitbehoben werden:** + +- **Fehler sind unsichtbar.** Kein `error`-Ereignis am `