„Werner Beinhart" über dem Bild von John Wick. Von mir eingebaut, im
Commit, der die Überblendung umgestellt hat.
**Der Grund ist der Umbau selbst.** Vorher bekam der Aufmacher je Titel
eine neue Identität; sein Zustand begann damit jedes Mal von vorn. Seit
er bleibt und nur seine Angaben wechseln, überlebt auch der geladene
Schriftzug den Wechsel — und `availableLogo` gab ihn heraus, ohne zu
prüfen, ob er überhaupt zum aktuellen Titel gehört:
if let logo { return logo } // ← zu irgendeinem Film
Jetzt trägt der Zustand die Adresse mit, zu der er gehört, und wird nur
herausgegeben, wenn sie zur aktuellen passt. Passt sie nicht, gilt der
Zwischenspeicher — und wenn auch der nichts hat, der gesetzte Titel. Nie
der falsche Schriftzug.
**Dieselbe Falle steckte in `FlixyArtwork`**, nur unauffälliger: auch
dort hielt `loaded` ein Bild ohne Angabe, wozu es gehört, und `load()`
brach deswegen früh ab („ist ja schon eins da"). Solange jede Kachel ihre
eigene Identität hat, fällt das nicht auf. Der Aufmacher hat seit dem
Umbau keine mehr.
Die Regel dahinter gilt allgemein: **ein Zustand, der etwas
zwischenspeichert, muss sagen, wozu es gehört** — sonst gilt er für
alles.
Die Attrappe liefert jetzt Schriftzüge (`Logo`-Bildmarke). Ohne sie fällt
der Aufmacher auf den gesetzten Titel zurück, und dieser ganze Weg wäre
im Simulator gar nicht zu sehen — genau deshalb ist der Fehler erst beim
Nutzer aufgefallen.
iOS und tvOS bauen, 476 Tests grün.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Im Commit davor blendete nur noch das Bild über; Schriftzug, Zeile und
Knöpfe standen still und wechselten schlagartig. Das war zu viel
weggenommen: die Bewegung gehört dazu.
Jetzt wandert der Text wieder mit — aber an der richtigen Stelle im
Stapel. Der Aufmacher zeichnet seinen Inhalt während eines Wechsels
zweimal: den weichenden deckend, den kommenden mit demselben Einblenden
und demselben Hereinrutschen wie das Bild darunter. Beides liegt **über**
dem Verlauf, und dort kostet es ihn nichts.
Der Unterschied zum alten Aufbau ist genau diese Reihenfolge. Vorher
lagen zwei **vollständige** Aufmacher übereinander, jeder mit eigenem
Verlauf — und zwei halbdurchsichtige Verläufe ergeben zusammen keinen
ganzen. Jetzt gibt es einen Verlauf, einmal, in voller Stärke.
Nachgemessen über einen auf sechs Sekunden gestreckten Wechsel, an
derselben Stelle im Bild:
ursprünglich 68 .. 154
jetzt 63 .. 75
Dafür ist der Textsatz in `HeroBanner` eine eigene Funktion geworden —
es gibt ihn während eines Wechsels zweimal — und `HeroSection.metadata`
ist `static`, weil die Zeile auch für den weichenden Titel gebraucht
wird. `titleView` und `plainTitle` sind darin aufgegangen.
iOS und tvOS bauen, 476 Tests grün.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Beim Wechsel im Karussell war der Verlauf nach unten für einen Moment
weg: das Bild stand bis unten hell da, und erst nach dem Übergang kam das
Abdunkeln zurück.
**Der Grund steckt in der Form der Überblendung.** Das Karussell legte
zwei vollständige Aufmacher übereinander und blendete den oberen ein. Nur
bringt jeder von beiden seinen eigenen Verlauf mit — und zwei
halbdurchsichtige Verläufe ergeben zusammen keinen ganzen.
Gemessen, an derselben Stelle im Bild, über einen auf sechs Sekunden
gestreckten Wechsel:
Ruhezustand 68 .. 75
Mitte des Wechsels 137 ← fast doppelt so hell
Zwei naheliegende Reparaturen habe ich davor versucht und verworfen,
weil die Messung sie widerlegt hat: dem weichenden Aufmacher die
Animation zu nehmen (wurde schlechter, 152) und beide Ebenen
gegenläufig zu blenden (brachte einen dunklen Einbruch auf 35 dazu).
Beide behandelten das Symptom, nicht die Form.
**Jetzt wechselt nur das Bild.** `HeroBanner` nimmt zusätzlich die
weichende Bildadresse entgegen und blendet **innen** über; Verlauf,
Schriftzug und Knöpfe liegen einmal darüber und ändern sich dabei nicht.
Damit kann der Verlauf gar nicht mehr schwächer werden — nicht weil es
jetzt richtig gerechnet wird, sondern weil es nur noch einen gibt.
Nachgemessen, derselbe Wechsel:
vorher 68 .. 154
jetzt 63 .. 75
Die Aufmacher-Ansicht behält dabei ihre Identität, statt je Titel eine
neue zu bekommen: eine neue hiesse Einfügen und Entfernen, und SwiftUI
blendete sie dann zusätzlich ein — noch eine Überblendung über der
gemeinten.
iOS und tvOS bauen, 476 Tests grün.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Drei Sachen am Karussell.
Die Vorschlaege wechselten bei jedem Start, obwohl es dafuer laengst ein
Zeitfenster von sechs Stunden gab. Der Grund: das Los hing an der Position
in der Liste, nicht am Titel. Kam einer dazu, verschwand einer, oder
aenderte sich ein Fortschritt, bekamen alle dahinter ein anderes Los — und
„Weiterschauen\" waechst und schrumpft staendig. Jetzt haengt das Los an der
Kennung; wer dazukommt, stoert niemanden. Als eigener Typ mit elf Tests,
weil „es wechselt zu oft\" kein Befund ist, den man debuggen kann.
Folgen zeigten kein Bild. Die Kette Folge → Serie gab es zwar, aber sie
hoerte beim ersten Glied auf, das sich **zusammensetzen** liess — und ob es
das Bild dahinter gibt, stellt sich erst beim Abruf heraus. Die Reihenfolge
wandert deshalb ins Laden: Folge, Staffel, Serie, der Reihe nach, bis eine
Adresse antwortet.
Und auf dem Mac gibt es jetzt Pfeile links und rechts, sobald der Zeiger
ueber dem Aufmacher liegt, sowie Punkte, die unter dem Zeiger wachsen und
auf die man springen kann. Nur dort: auf dem iPad und dem iPhone wischt man
ohnehin, und zwei Knoepfe staenden nur im Bild.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der schwarze Streifen über der Navigation war kein gezeichneter Balken,
sondern fehlender Inhalt: der gesamte Baum saß innerhalb des
Sicherheitsrands. Deshalb erreichte kein noch so gut gesetzter Rand
weiter unten die Fläche darüber — Inhalt kam dort nie hin.
Jetzt reißt der HStack den Rand oben auf und gibt den Platz kontrolliert
zurück: Seitenleiste und Insel bekommen ihren Abstand zur Statusleiste
explizit, der Inhalt bekommt ihn als Sicherheitsrand. Der Aufmacher
nimmt ihn sich wieder — um genau diese Strecke höher und um genau diese
Strecke größer, sodass unten alles bleibt, wo es war. Dazu ein knapper
Verlauf oben, damit Uhrzeit und Batterie auch über einem hellen Bild
lesbar bleiben.
Und die Leiste oben fährt beim Scrollen weg. Nur sie: der
Sicherheitsrand darunter bleibt stehen, sonst ruckte die Seite bei jedem
Ein- und Ausblenden unter dem Finger weg.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Unter dem Folgentitel stand „S2 E1" als Text, und wer zur Serie wollte, musste
darunter eine Knopfreihe finden. Jetzt steht dort „Serienname · Staffel 2 ·
Episode 1", und Serienname wie Staffel führen dorthin, wohin sie zeigen. Der
Name steht ohnehin da — dann soll er auch der Weg sein.
`HeroBanner` nimmt dafür wahlweise eine fertige Zeile entgegen statt eines
Textes. Gebaut wird sie beim Aufrufer, weil nur der weiß, wohin ein Teil führt;
die Gestaltung kennt keine Ziele.
Die Knopfreihe bleibt bei Staffeln, wo sie der einzige Weg nach oben ist, und
entfällt bei Folgen.
Beim Entfernen eines Downloads gibt es keine Rückfrage mehr. Sie stand da, weil
„löschen" nach etwas Endgültigem klingt — es ist aber nur die heruntergeladene
Kopie, der Titel bleibt auf dem Server. Wer nach links wischt und auf „Löschen"
tippt, hat zweimal gesagt, was er will.
Und das Umschalten sieht jetzt nach Umzug aus: die Seitenleiste klappt nach
oben weg, die Leiste oben schiebt sich seitwärts herein — und zurück genauso.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Auf dem iPad beschneidet der TabView seinen Inhalt, auf dem Mac nicht.
Gemessen: unter der Leiste war dort gar kein Bild — die Fläche blieb
gleichmäßig dunkel, während der Aufmacher daneben bei 60 lag. Der negative
Rand, mit dem der Aufmacher unter die Leiste greifen sollte, wurde schlicht
abgeschnitten, und übrig blieb der schwarze Spalt dazwischen.
Also weg damit. Die Leiste steht in einem HStack neben dem Inhalt: kein
negativer Rand, keine Maske, kein Sicherheitsrand je Bildschirm, keine
Sonderfälle für geschobene Bildschirme. Die Leiste hat ihren Abstand zu drei
Seiten und zum Inhalt keinen — dort schließt er unmittelbar an.
Die Startseite hat keine Navigationsleiste mehr. Sie war leer und belegte
trotzdem ihre Höhe; der Aufmacher fing dadurch tiefer an als die Leiste
daneben, und genau diese Kante sah man. Auf den geschobenen Bildschirmen
bleibt sie, dort trägt sie den Zurück-Weg.
Und Wischen auf dem Aufmacher schluckt das Scrollen nicht mehr. `minimumDistance: 0`
ließ die Geste sofort greifen — wer nach oben wischte, bei dem passierte
nichts. Jetzt vierundzwanzig Punkte und nur, wenn es waagerecht gemeint ist;
das Anhalten des Wechsels übernimmt eine eigene Tippgeste.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ein negativer Rand dehnt, was er umschließt, meldet nach außen aber die alte
Breite. Er stand ganz oben, also legten sich Verlauf und Schrift nur über den
alten Bereich — und die zwölf Punkte daneben blieben ohne Verlauf und damit
hell. Gemessen: dort 60 Helligkeit, im Inhaltsbereich 19, bei gleichem Bild.
Jetzt wird erst der Verlauf gelegt, dann gedehnt, dann die Schrift gesetzt. Der
Verlauf deckt bis zum Rand, die Schrift bleibt auf der gemeldeten Breite und
fängt von selbst dort an, wo auch die Reihen darunter anfangen.
Der Weg dorthin ging über drei Irrtümer, die alle widerlegt sind: nicht
`glassEffect` (der Streifen blieb bei undurchsichtiger Fläche), nicht der
Platzhalter (er blieb bei grünem Platzhalter), nicht der Scroll-Anzeiger (er
blieb ohne Bildlaufansicht). Die Bildlaufansicht in der Leiste ist trotzdem
draußen — sie wurde nicht gebraucht.
Dazu: der Aufmacher nimmt die volle Höhe statt achtundachtzig Prozent, der
Haarstrich der Leiste ist zurückhaltender, und auf dem iPhone ist der Aufmacher
das **Plakat** statt des Hintergrundbilds. Ein 16:9-Bild hochkant zeigt einen
Ausschnitt aus der Mitte; ein Plakat ist von vornherein hochkant und passt
ohne Beschnitt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Aufmacher nimmt jetzt achtundachtzig Prozent der sichtbaren Höhe, statt
sich seine Höhe aus 16:9 auszurechnen. Ein Aufmacher, der ein Drittel hoch ist,
sieht aus wie ein breites Vorschaubild; die zwölf Prozent Rest sind Absicht,
dort lugt die erste Reihe herein und sagt, dass es weitergeht. Auf schmalen
Geräten bleibt es beim Hochformat.
`FlixyArtwork` kann dafür den Rahmen ausfüllen, den es bekommt. Das
Seitenverhältnis bleibt trotzdem wichtig — danach werden die Bilder beim Server
angefordert.
Und `glassEffect` ist raus. Er zeichnet an seiner Kante einen Lichtsaum, und
über einem hellen Aufmacher wurde daraus ein heller Balken von mehreren Punkten
Breite neben der Leiste — kein Rand, sondern ein Streifen. Von einer Kante war
gleichzeitig nichts zu erkennen.
Von Hand sind es drei Lagen: ein trübes Material, ein Schleier gegen die
durchziehende Startseite, und ein Haarstrich, der oben links aufhellt und unten
rechts nachlässt. Dazu ein Schatten — was schwebt, wirft einen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Vier Dinge, die zusammengehören:
Die Spiegelung ist weg. `backgroundExtensionEffect` füllt die Fläche unter der
Leiste, indem er den Bildrand gespiegelt weiterzeichnet — und je größer die zu
füllende Fläche wurde, desto mehr übernahm der Spiegel das Bild. Auf dem iPhone
legte er sich ohne jede Seitenleiste über den Statusbalken. Jetzt läuft das
Bild selbst weiter, über einen negativen Rand.
Es endet dabei an der **Kante der Leiste**, nicht am Fensterrand. Der
Unterschied sind zwölf Punkte, und die waren deutlich zu sehen: neben der
schwebenden Leiste stand ein heller Streifen Bild, den nichts abdeckte.
Das Seitenverhältnis im Karussell musste weichen. Es legte den Aufmacher auf
die Breite des Inhaltsbereichs fest; weil er nach links unter die Leiste
greift, blieb rechts genau so viel schwarz übrig, wie er links gewann.
Und die Maße, in denen das Hintergrundbild angefordert wird, richten sich jetzt
nach dem Rahmen, in dem es landet. Vorher wurden 900×1200 geholt — hochkant —
und in einem 16:9-Rahmen gezeigt: zu sehen war ein Streifen aus der Mitte, oben
und unten fehlte je ein Drittel.
Dazu: auf schmalen Geräten ist der Aufmacher hochkant. In 16:9 blieben auf
einem iPhone keine zweihundertzwanzig Punkte Höhe, und Schriftzug, Zeile,
Beschreibung und zwei Knöpfe lagen übereinander.
Und ein Schleier unter dem Glas der Leiste. Reines Glas zeigt alles, was
dahinter vorbeizieht, und beim Scrollen zieht die ganze Startseite vorbei — aus
den ruhigen Beschriftungen wurde ein unruhiger Brei. Der Schleier nimmt der
Bewegung die Schärfe, ohne die Fläche zuzumauern.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die System-Seitenleiste sitzt auf dem iPad als schwebende Fläche und auf dem
Mac angeklebt am Fensterrand. `preferredLayout = .overlap` ist die dafür
vorgesehene Bitte, und macOS verwirft sie stillschweigend — gemessen, nicht
vermutet.
Statt deshalb die ganze Navigation neu zu bauen, bleibt der `TabView` stehen
und verliert nur sein Kleid: `TabChromeSuppressor` blendet Seiten- und
Tableiste aus, gezeichnet wird darüber. Auswahl, ein eigener Navigationsstapel
je Eintrag, erhaltener Scrollstand beim Wechseln — all das macht weiter das
System. Dass das Ausblenden geht, war kein Ratschluss: derselbe Griff hatte die
Leiste vorher schon versuchsweise verschwinden lassen.
Neu sind `FlixySidebar` (schwebende Fläche mit eigenem Rand, Mediatheken
einklappbar, Konto unten) und `FlixyTopBar` (dieselben Einträge als Leiste
oben, Mediatheken als Menü, weil oben der Platz waagerecht begrenzt ist). Das
iPhone bleibt beim System: dort gibt es keine Seitenleiste, sondern die Leiste
unten, und die ist überall dieselbe.
Der Platz für die Leiste ist ein **Sicherheitsrand**, kein Abstand, und er
hängt je Bildschirm — weder `TabView` noch `NavigationStack` reichen ihn an
ihren Inhalt weiter. Damit bleibt eine Reihe fensterbreit und schiebt ihre
Kacheln beim Wischen hinter die Leiste, stellt aber im Ruhezustand keine
dorthin. Der Aufmacher darf über seinen Bereich hinaus; das `.clipped()` im
Karussell musste dafür weichen, es schnitt genau das ab.
Noch nicht dabei: „Bearbeiten" mit Ziehen und Ein-/Ausblenden. Die Einträge
stehen in fester Reihenfolge.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Schriftzug hing weiter nicht an der Animation, und der Zwischenspeicher war
nicht schuld: er lag im Actor, und ein `await` kostet immer mindestens einen
Durchlauf. Das neue Bild erschien deshalb im ersten Bild ohne Schriftzug und im
zweiten mit — er sprang also getrennt herein, obwohl er längst da war.
Der Speicher liegt jetzt außerhalb des Actors und lässt sich beim Zeichnen
lesen. Das gilt für alle Bilder: auch eine zurückscrollende Kachel blitzt nicht
mehr kurz grau auf.
Zur Seitenleiste auf dem Mac, gemessen statt vermutet: `automatic` löst sich
laut Apples eigener Beschreibung auf iOS zu `overlap` auf (die Leiste schwebt
über dem Inhalt) und auf macOS zu `tile` (sie schiebt ihn zur Seite und klebt
am Fensterrand). Der Griff dorthin sitzt richtig — derselbe Weg hat die Leiste
auf Kommando ganz ausgeblendet —, aber `overlap` wird auf dem Mac
stillschweigend verworfen. Die Bitte bleibt trotzdem stehen; sie kostet nichts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`AsyncImage` bringt seine eigene Einblendung mit und fängt erst an zu laden,
wenn es erscheint. Beim Überblenden des Aufmachers blendete sich der Schriftzug
des Films deshalb getrennt und später ein, während Titelzeile, Beschreibung und
Knöpfe längst mitgewandert waren — zwei Bewegungen, wo eine sein soll.
Jetzt lädt er über denselben Zwischenspeicher wie alle anderen Bilder, und das
Karussell holt ihn zusammen mit dem Hintergrundbild vor. Beim Erscheinen liegt
er bereit und macht mit, was der Aufmacher macht.
Dazu ein kleines Hilfsprogramm, das die Fensterkennung eines laufenden
Programms ausgibt, damit `screencapture -l` genau dessen Fenster fotografiert
und sonst nichts vom Bildschirm. Das System-Python bringt PyObjC nicht mehr
mit, und ohne Kennung gibt es keinen Weg dorthin.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der gespiegelte Ausschnitt hinter der Seitenleiste war nicht das Problem —
JellyTV macht es genauso. Auffällig wurde er erst durch die Bewegung: beim
seitlichen Durchblättern wanderten das echte und das gespiegelte Stück
gegeneinander, und die Naht dazwischen war das auffälligste Ding auf dem
Bildschirm.
Jetzt rutscht das neue Bild 32 Punkte herein und blendet dabei über das alte.
Nichts wandert weit genug, als dass ein Versatz auffiele. Wischen blättert
weiter, nach vorn wie zurück; das nächste Bild wird geholt, solange das
aktuelle noch steht, sonst blendet der Aufmacher auf eine graue Fläche über.
Dazu ein Testziel, das die App mit der Attrappe in einen Zustand fährt und
fotografiert. Der Grund ist ein wiederkehrender Fehler: Aussagen über das
Aussehen waren Vermutungen, weil niemand hinsehen konnte — der Simulator kennt
keinen Befehl fürs Antippen, und dieses Xcode bringt kein Simulator-Fenster
mehr mit. Damit ist „sieht es so aus?" eine Frage, die sich beantworten lässt.
Die Startargument-Anmeldung an der Attrappe steht unter #if DEBUG und führt am
Schlüsselbund vorbei: kein echter Server, kein echtes Konto, kein echter Token.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Drei Gründe, warum der Mac anders aussah, und keiner davon war Geschmack.
**Die Schrift.** macOS rendert dieselben Textstile deutlich kleiner als iOS:
`largeTitle` misst dort 26 Punkt statt 34, Fließtext 13 statt 17. Eine
Oberfläche, die auf dem iPad stimmt, wirkt damit zusammengeschrumpft. Auf dem
Mac stehen jetzt feste Größen — die von iOS. Das kostet dort Dynamic Type;
vertretbar, weil macOS keine systemweite Textgröße kennt und man ein Fenster
stattdessen größer ziehen kann.
**Der Aufmacher wächst mit.** Das war der zweite, größere Teil: das Bild ist so
breit wie das Fenster, die Schrift darauf war es nicht. Bei 1280 Punkt Breite
wirkt ein 34-Punkt-Titel verloren, bei 834 auf dem iPad genau richtig. Titel,
Schriftzug, Angaben und Abstände richten sich jetzt nach der Breite des
Aufmachers — mit dem iPad als Bezug und einem Deckel, damit ein Fenster über
die ganze Wand nicht in Plakatschrift endet. Die Beschreibung bekommt
außerdem eine Zeilenbreite: ein Satz über 1280 Punkt ist unlesbar, das Auge
verliert die Zeile.
**Die Seitenleiste.** Sie richtet sich nach ihrem Inhalt, und bei Wörtern wie
„Start" fällt sie auf eine Breite zusammen, in der schon der Kontoname darunter
nicht mehr Platz hatte — daher das „S…". Die Beschriftungen haben jetzt eine
Mindestbreite.
**Die Formulare.** Auf dem Mac nahm SwiftUI den Spalten-Stil: Beschriftungen
rechts ausgerichtet, keine abgesetzten Abschnitte. Jetzt derselbe gruppierte
Stil wie auf iOS.
Dazu: Scrollbalken sind weg. Der graue Streifen unter dem Aufmacher kam daher,
dass in den Systemeinstellungen „Scrollbalken immer einblenden" steht —
dagegen reicht `.hidden` nicht, `.never` schon. Und das Fenster öffnet mit
1280 × 820 statt in Notizzettelgröße, ohne graue Titelleiste.
263 Tests grün, iOS baut unverändert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
**Eine Taste zum Vergrößern** unten rechts auf der Kachel. Das Antippen der
Fläche vergrößert weiterhin, aber auf derselben Fläche liegen schon das Ziehen
und das Aufziehen — und was dabei danebengeht, sieht aus wie „reagiert nicht".
Ein Knopf geht nicht daneben.
**Ton und Untertitel getrennt.** Es sind zwei verschiedene Fragen: die Tonspur
stellt man einmal am Anfang um, die Untertitel mitten im Film. In einem
gemeinsamen Blatt scrollte man jedes Mal an der anderen Liste vorbei. Das
Untertitel-Symbol ist gefüllt, solange welche laufen — so sieht man es, ohne
das Blatt zu öffnen. Und eine Auswahl schließt das Blatt jetzt selbst.
**AirPlay.** Nicht nachgebaut, sondern die Systemstelle: sie kennt Geräte, die
eine App nie aufzählen könnte. Der Knopf erscheint nur beim Systemplayer — VLC
zeichnet selbst und kann kein AirPlay, und ein Knopf, der dort ins Leere
führte, wäre schlimmer als keiner.
**Die Qualität steht als Text da**, nicht als drei Schieberegler: „1080p",
„720p", „Auto". Bei „automatisch" steht dort, was gerade tatsächlich ankommt —
das weiß nur der Player, und ihn zu fragen ist ehrlicher, als „Auto"
hinzuschreiben und die Antwort schuldig zu bleiben.
Dazu die Einstellungen mit farbigen Symbolen und einer Kopfkarte je Bereich.
Das ist nicht nur Zierde: in einer Liste aus zehn gleich aussehenden Zeilen
findet das Auge nichts wieder, und „das mit dem blauen Zahnrad" ist eine
brauchbare Beschreibung. Die Farben sind fest und ausdrücklich **nicht** die
Akzentfarbe — trüge alles dieselbe, unterschiede sie nichts mehr.
Und der Aufmacher läuft jetzt unter der Seitenleiste weiter
(`backgroundExtensionEffect`): die Ränder werden gespiegelt und weich
fortgeschrieben, während Titel und Knöpfe stehen bleiben. Vorher endete das
Bild an der Kante der Leiste, und beim Weiterwandern schob sich das nächste an
einer harten Linie ins Bild.
263 Tests grün. Player-Knöpfe und Einstellungen angesehen; den Aufmacher hinter
der Leiste konnte ich an den einfarbigen Flächen der Attrappe nicht sicher
beurteilen — der Simulator ist dabei erneut abgestürzt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Senderliste
Plex liefert die Sender verschachtelt in der Antwort auf /livetv/dvrs
mit — jeder Empfänger bringt seine eigenen unter `Device` → `Channel`.
Mein getrennter Endpunkt /livetv/dvrs/{id}/channels war eine Vermutung
und lieferte nichts. Bei einem Server mit über dreißig eingerichteten
Sendern stand deshalb „Keine Sender".
Die verschachtelte Liste hat jetzt Vorrang, der Endpunkt bleibt als
Rückfalllinie. `ChannelMapping` wird als ältere Schreibweise ebenfalls
gelesen, und der Empfänger-Schlüssel kommt je nach Serverfassung als
Zahl oder als Zeichenkette.
Bleibt die Liste leer, sagt die Ansicht jetzt welcher Weg was ergeben
hat. In einem Bereich ohne offizielle Beschreibung ist das die Angabe,
mit der sich der nächste Fehler finden lässt.
Schriftzüge
Plex liefert bei vielen Filmen ein `clearLogo` — den Schriftzug in
seiner eigenen Type, freigestellt. Der tritt jetzt im Aufmacher an die
Stelle des gesetzten Titels.
Dabei ein Fallstrick: /photo/:/transcode liefert JPEG, und JPEG kennt
keine Transparenz. Über den Bild-Transcoder geladen wäre aus dem
freigestellten Logo ein schwarzer Kasten geworden. Es wird deshalb
unverändert geladen. Fehlt der Schriftzug oder scheitert das Laden,
bleibt es beim Titel.
161 Tests.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
iPad meldete sich nie an
Die Ursache ist unangenehm speziell: Wer im Browser schon bei Plex
angemeldet ist, wird von app.plex.tv/auth sofort auf watch.plex.tv
weitergeschickt — OHNE dass der Code verknüpft wird. Man sieht sich
angemeldet, die App wartet vergeblich, und es gibt keinerlei Hinweis.
Jetzt wird plex.tv/link mit eingetragenem Code geöffnet. Diese Seite
tut nur eine Sache: den Code bestätigen. Die Gerätekennung steckt
ohnehin schon im PIN.
Dazu ein Ausweg: bleibt es nach fünfzehn Sekunden ohne Token, erscheint
der Code im Anmeldebildschirm zum Abtippen. Schließt man das Fenster
ohne Erfolg, bleibt er stehen statt abzumelden — er gilt weiter.
Download fragte nicht nach der Qualität
Jetzt Original, Full HD, HD oder Sparsam, jeweils mit geschätzter
Größe. Die Größe ist das eigentliche Entscheidungskriterium — „Full HD"
allein sagt nicht, ob es aufs Telefon passt.
Die komprimierten Stufen laufen über den Universal-Transcoder und sind
weiterhin NICHT am Server geprüft; steht so im Quelltext.
Schwarzes Bild ohne Anzeige
Der Player kannte nur „spielt" und „spielt nicht". Wartete er auf
Daten, stand man vor einem Standbild ohne Hinweis. Es gibt jetzt einen
eigenen Pufferzustand mit Anzeige.
Aufmacher war beschnitten
Er stand auf 3:4, Plex liefert als `art` aber 16:9 — mit scaledToFill
ging links und rechts je ein Viertel verloren, ohne dass man es dem
Bild ansah. Die Seitenverhältnisse liegen jetzt an einer Stelle in
FlixyAspectRatio.
Schwarze Leiste über dem Aufmacher
.ultraThinMaterial statt undurchsichtigem Grund: das Bild läuft
unscharf hinter der Leiste weiter, statt an einer harten Kante zu
enden. Weichgezeichnet, nicht abgedunkelt.
139 Tests.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Legt das Fundament für den Plex-Client an:
- XcodeGen-Projekt nach dem Muster von Onyx (com.scarriffleservices,
strict concurrency, Projektdatei nicht eingecheckt)
- FlixyKit mit vier Modulen: PlexKit, FlixyDesign, FlixyPlayback,
FlixyDownloads. macOS steht als Plattform mit drin, damit die
Logik-Tests ohne Simulator laufen.
- FlixyDesign: dunkle Farb-Tokens, Schriftskala, Poster- und
Querformat-Kacheln, Aufmacher-Bild. Die Akzentfarbe fließt über die
Umgebung und wird per WCAG-Rechnung lesbar gehalten.
- PlexKit: Kopfzeilen-Identität, Transport-Protokoll, Fehlerarten und
die Medienmodelle samt nachsichtigem Decoder.
- FlixyPlayback: VideoPlayerEngine-Protokoll und PlaybackDecider — die
eine Funktion, an der Phase 2 das Transcoding andockt.
- Ausfahrbare Seitenleiste auf dem iPhone, Split-View auf dem iPad.
- 45 Tests, alle grün.
VLCKit 4.0.0-a24 ist vorab geprüft: baut über SPM unter Swift 6 mit
strict concurrency. Die iOS-Slice ist mit 239 MB allerdings gewichtig,
deshalb bekommt sie in Phase 1 ein eigenes Target.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>