Commit Graph
3 Commits
Author SHA1 Message Date
ScarriffleandClaude Opus 5 dc93d6e22e Der Aufmacher lässt sich auf Mediatheken einschränken
Mehrfachauswahl in den Einstellungen unter „Startseite": welche
Mediatheken den Aufmacher speisen dürfen. Haken statt Auswahlliste —
eine Liste könnte nur eine, und „keine" wäre dort ein Eintrag, den man
versehentlich trifft.

Dafür musste eine Reihe sagen können, woher sie kommt: `MediaRowGroup`
trägt jetzt eine `libraryID`. Jellyfin setzt sie an den „Neu in …"-Reihen
— die baut die App ohnehin je Mediathek.

Zwei Regeln, und beide sind Entscheidungen, keine Nebenwirkungen:

**Leer heisst alle.** Wer nichts ankreuzt, meint „mir ist es gleich",
nicht „nimm nichts". Ein leerer Aufmacher wäre der Fehler, den niemand
mit dieser Einstellung in Verbindung brächte.

**Reihen ohne Mediathek bleiben immer drin.** Weiterschauen, Als Nächstes
und Favoriten gehen quer durch alle, und aus welcher Mediathek eine
angefangene Folge stammt, sagt der Server an keiner Stelle. Sie
wegzuwerfen hiesse, jemandem das Angefangene zu nehmen, weil er
„Musikvideos" abgewählt hat. Der Hinweis unter der Auswahl sagt das auch
dem, der nicht in den Quelltext sieht.

Eingeschränkt wird **nur der Aufmacher**, nicht die Startseite: die
Reihe selbst bleibt stehen. Wer sie ganz loswerden will, blendet sie aus
— das ist eine andere Frage und hat ihren eigenen Schalter.

Fünf Tests an `HeroSelection.rows(_:limitedTo:)` halten die Regeln fest,
darunter der Fall einer gespeicherten Kennung, die es nicht mehr gibt.

**Plex bleibt aussen vor:** dort kommen die Reihen als fertige Hubs vom
Server, und `librarySectionID` wird in `PlexHub` nicht gelesen. Die
Auswahl schränkt dort also nichts ein. Nachzuholen, wenn Plex wieder
dran ist.

iOS und tvOS bauen, 468 Tests grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-01 08:24:09 +02:00
ScarriffleandClaude Opus 5 e801502c7a Ein Regal über der App — und ein Weg aus dem Player heraus
**Das Regal.** Wer im tvOS-Menü über der App steht, sah bisher das Icon
noch einmal gross. Jetzt stehen dort „Weiterschauen", „Als Nächstes" und
die Neuzugänge als Plakate, mit Fortschrittsbalken; ein Druck spielt ab,
ein Wisch nach unten öffnet die Detailseite.

**Warum es dafür eine App-Gruppe braucht.** Das Regal zeichnet eine
eigene Erweiterung, also ein anderer Prozess mit eigener Sandbox — und
tvOS ruft sie auf, während die App **nicht** läuft, mit weniger als einer
Sekunde Zeit. Kein Netzabruf, keine Anmeldung, kein Blättern. Also legt
die App beim Laden der Startseite hin, was das Regal braucht, und sonst
nichts: Titel, Bildadresse, Kennung, Fortschritt. Eine Datei, ein
`JSONDecoder`, fertig.

Die Bildadressen tragen den Zugangsschlüssel, weil Jellyfin ihn für
Bilder verlangt und die Erweiterung ihn sonst nirgends herbekäme. Die
Datei liegt in der App-Gruppe — erreichbar für die App und ihre
Erweiterungen, für sonst niemanden. Der Schlüsselbund bleibt, wo er ist.

**Und der Fehler, den du gefunden hast.** Solange der Stream noch
ausgehandelt wurde, gab es keinen Weg zurück: schwarzes Bild, Kreisel,
und der Menü-Knopf tat nichts. `AVPlayerViewController` fängt ihn nämlich
selbst ab — aber erst, wenn er einen Player mit einem Item hat, und genau
den gibt es in dem Moment noch nicht. Der Griff liegt jetzt eine Ebene
darüber, wo es ihn vom ersten Bild an gibt. Doppelt ist er nicht: greift
Apples Player zu, kommt der Befehl dort gar nicht mehr an.

**Was am Gerät noch offen ist.** Die App-Gruppe muss im Entwicklerkonto
eingetragen sein, sonst bleibt das Regal leer — im Simulator legt das
System sie von selbst an, auf einem echten Apple TV nicht. Geprüft ist,
dass die App die Datei schreibt (drei Reihen, richtige Adressen) und dass
tvOS das Schema kennt. Dass das Regal beim Darüberstehen auch zeichnet,
lässt sich ohne Fernbedienung nicht auslösen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-29 20:14:38 +02:00
ScarriffleandClaude Opus 5 87f23afe90 Die Startseite am Fernseher — und die Ladeschicht nur einmal
Aufmacher, Reihen, Mediatheken, Raster. Der sichtbare Teil ist neu; der
Teil darunter ist derselbe wie am Telefon, und das war die eigentliche
Arbeit.

**Herausgelöst statt kopiert.** `HomeFeed` und `LibraryFeed` tragen jetzt,
was vorher in `HomeView` und `LibraryView` stand: laden, ordnen, den
Aufmacher auslosen, den Zwischenspeicher abziehen, entdoppeln, nach einem
Fehlschlag sperren. Das zu kopieren wäre der schlimmste Ausgang dieses
Vorhabens gewesen — an mindestens drei dieser Stellen klebte schon je ein
Fehler, der sich als „es sind nicht alle Filme drin" äusserte und sonst
nichts. Einer davon, das Los des Aufmachers an der Position statt am
Titel, wäre in einer Kopie ein zweites Mal zu finden gewesen.

Mitgewandert sind `rowTitle`, `rowArtworkPath`, `posterArtworkPath`,
`runtimeLabel` und `HeroArtwork`: reine Ableitungen, die in einer
Ansichtsdatei lagen und deshalb nur das Telefon übersetzte.

**Nachgeladen wird am Fokus, nicht am Erscheinen.** Die alte Regel hiess
„die letzten fünf" und hing daran, dass eine Kachel sichtbar wird. Beim
ersten Zeichnen erscheinen aber alle sechzig, auch die letzten fünf — das
Nachladen lief sofort los statt beim Blättern. Auf einem Raster aus sechs
Spalten sind fünf Einträge ausserdem nicht einmal eine Zeile. `PagingWindow`
rechnet deshalb in Zeilen; sechs Tests halten es fest, darunter der Fall,
der die alte Regel entlarvt.

**Der Fokus setzt den Aufmacher.** Wer durch „Zuletzt hinzugefügt"
wandert, sieht oben, was er gerade anschaut. Kein Wechsel im Sieben-
sekundentakt wie am Telefon: vor einem Fernseher wäre ein Bild, das sich
von allein austauscht, während man es liest, eine Zumutung.

**Drei Dinge, die erst der Simulator zeigte.** Die Seiten müssen
bildfüllend laufen, weil ein Aufmacher, der achtzig Punkte vor der
Bildschirmkante aufhört, nach Fehler aussieht — also trägt `screenMargin`
auf tvOS den Überscan mit. Die Karten brauchen einen Fokus-Rückruf, weil
`\.isFocused` den nächsten fokussierbaren Vorfahren meint und das in einer
Reihe aus Karten nicht verlässlich die Karte ist. Und der Bau scheiterte
an „Unable to resolve module dependency: VLCKit" — der Abhängigkeits-
Sucher prüft `canImport(FlixyVLC)` auch für ein Ziel, das es nie verlinkt.
Ein `&& !os(tvOS)` genügt; das Paket selbst bleibt unverändert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-29 19:36:49 +02:00