Die Ansichten sprechen nicht mehr mit Plex

Start, Suche, Mediathek, Detailseiten und Downloads arbeiten jetzt mit
`MediaItem` und dem `MediaBackend`-Vertrag. Damit sind sie fertig für
einen zweiten Server, ohne dass an ihnen noch etwas zu tun wäre.

Dabei sind ein paar Namen ehrlicher geworden: aus `grandparentTitle`
wurde `seriesTitle`, aus `viewedLeafCount` `playedEpisodeCount`. Und
`TagStrip` nahm bisher Plex-Marken mit Kennung und Rolle entgegen, um
davon nur den Namen anzuzeigen — Genres sind jetzt schlicht Zeichenketten.

`Arrangement` ist aus PlexKit heraus und generisch: dieselbe Rechnung
gilt für jede Liste, die jemand selbst zusammenstellt. Phase 3 baut die
konfigurierbare Seitenleiste darauf, statt sie ein zweites Mal — und ein
zweites Mal falsch — zu schreiben.

Die Fehlerübersetzung gibt es nur noch einmal. Es waren zwei, und sie
waren bereits auseinandergelaufen: derselbe Fehler bekam je nach
Bildschirm eine andere Erklärung.

Das Nachladen der Mediathek bleibt unangetastet: eine lange Liste, die
fünf Einträge vor dem Ende nachlädt. `MediaPage` heißt zwar Seite, ist
aber eine technische Portion — Blättern mit „weiter zu Seite 2" gehört
nicht in eine Mediathek, in der man stöbert. Der Kommentar dort sagt das
jetzt ausdrücklich, damit es niemand später „aufräumt".

Player, Live-TV und die Download-Engine sprechen noch unmittelbar mit
Plex. Sie folgen als Nächstes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-09-13 12:46:52 +02:00
co-authored by Claude Opus 5
parent effdcd4532
commit fe2d730c00
30 changed files with 432 additions and 318 deletions
+14 -14
View File
@@ -1,10 +1,10 @@
import SwiftUI
import FlixyDesign
import PlexKit
import MediaKit
/// Eine waagerechte Reihe von Titeln.
struct MediaRow: View {
let hub: PlexHub
let row: MediaRowGroup
@Environment(FlixySession.self) private var session
@@ -17,15 +17,15 @@ struct MediaRow: View {
var body: some View {
VStack(alignment: .leading, spacing: FlixySpacing.regular) {
Text(hub.title)
Text(row.title)
.font(.flixyRowHeader)
.foregroundStyle(Color.flixyTextPrimary)
.padding(.horizontal, FlixySpacing.screenMargin)
ScrollView(.horizontal) {
LazyHStack(spacing: FlixySpacing.regular) {
ForEach(hub.items) { item in
NavigationLink(value: MediaRoute(ratingKey: item.ratingKey, title: item.title)) {
ForEach(row.items) { item in
NavigationLink(value: MediaRoute(ratingKey: item.id, title: item.title)) {
card(for: item)
}
.buttonStyle(.plain)
@@ -47,12 +47,12 @@ struct MediaRow: View {
/// dafür ist das Querformat richtig. Wer dagegen aussucht, was er als
/// Nächstes sehen will, sucht nach Plakaten.
@ViewBuilder
private func card(for item: PlexItem) -> some View {
if hub.isContinueWatching {
private func card(for item: MediaItem) -> some View {
if row.isContinueWatching {
LandscapeCard(
title: item.rowTitle,
subtitle: item.cardSubtitle,
artworkURL: session.server?.artworkURL(
artworkURL: session.backend?.artworkURL(
path: item.rowArtworkPath,
width: 440,
height: 248
@@ -64,7 +64,7 @@ struct MediaRow: View {
PosterCard(
title: item.rowTitle,
subtitle: item.cardSubtitle,
artworkURL: session.server?.artworkURL(
artworkURL: session.backend?.artworkURL(
path: item.posterArtworkPath,
width: 300,
height: 450
@@ -76,7 +76,7 @@ struct MediaRow: View {
}
}
extension PlexItem {
extension MediaItem {
/// Der Titel auf einer Kachel in einer Reihe.
///
/// Groß steht, worum es geht: bei einer Folge ihr eigener Titel, bei
@@ -87,9 +87,9 @@ extension PlexItem {
switch kind {
case .episode: title
// Die Serie steht je nach Antwort mal unter `parentTitle`, mal unter
// `grandparentTitle`. Fehlt beides, bleibt „Staffel 2" — besser als
// `seriesTitle`. Fehlt beides, bleibt „Staffel 2" — besser als
// gar keine Beschriftung.
case .season: parentTitle ?? grandparentTitle ?? title
case .season: parentTitle ?? seriesTitle ?? title
default: title
}
}
@@ -101,7 +101,7 @@ extension PlexItem {
/// würde; dort ist `art` (das Hintergrundbild) die bessere Wahl.
var rowArtworkPath: String? {
switch kind {
case .episode: thumb ?? grandparentThumb
case .episode: thumb ?? seriesThumb
default: art ?? thumb
}
}
@@ -113,7 +113,7 @@ extension PlexItem {
/// Wiedererkennen wertlos.
var posterArtworkPath: String? {
switch kind {
case .episode: grandparentThumb ?? parentThumb ?? thumb
case .episode: seriesThumb ?? parentThumb ?? thumb
default: thumb
}
}