Files
Flaro/Flixy/Views/Navigation/MediaStack.swift
T
ScarriffleandClaude Opus 5 a665d79e6d Antippen spielt ab — und vier Dinge, die daneben lagen
**Antippen startet, langes Drücken führt auf die Detailseite.** Am Telefon
und am iPad; am Mac bleibt der Klick die Seite, denn dort gibt es den
Abspielknopf beim Überfahren und langes Drücken ist keine übliche Geste.

Die Hürde war nicht die Geste, sondern das Schieben: ein `NavigationLink`
schiebt selbst, ein Menüeintrag kann es nicht. Der Stapel ist deshalb ein
eigener Typ mit Pfad (`MediaStack`) und reicht eine Schiebefunktion über
die Umgebung nach innen — denselben Weg nimmt schon die Meldung, dass sich
am Server etwas geändert hat.

**Zwei Knöpfe übereinander auf der Detailseite.** Das Monogramm hing als
Überzug an `mediaStack` — also über **jedem** Bildschirm dieses Stapels,
auch den geschobenen, und dort über deren Drei-Punkte-Menü. Es gilt jetzt
für die Startseite und endet mit ihr.

**Der Kopf der Detailseite war viel zu flach.** Dort stand kein
Seitenverhältnis, also galt die Vorgabe 16∶9 — während `HeroArtwork` auf
einem schmalen Gerät ein **Plakat** anfordert, also hochkant. Zu sehen war
ein Streifen aus der Mitte. Der Aufmacher auf der Startseite macht es seit
Langem richtig; die beiden Detailseiten nicht.

**Die Mediathekenleiste stand linksbündig in einer halbleeren Kapsel.**
Jetzt ist sie so breit wie ihr Inhalt und mittig. `ViewThatFits` nimmt die
ungescrollte Reihe, solange sie passt, sonst die scrollbare — damit steht
nirgends eine Zahl, ab wann es kippt.

**Und der Grund, warum die Mediathekenauswahl beim Nutzer nie griff:**
Plex. Dessen Hubs sagten nicht, aus welcher Mediathek sie stammen, also
warf der Filter jede Reihe weg und fiel auf „alles" zurück — ein Schalter,
der nichts tut. `PlexHub` liest jetzt `librarySectionID`, als Zahl oder
als Zeichenkette, je nachdem was der Server liefert. Vier Tests dazu.

Das ist **kein** Wiederaufnehmen der Plex-Arbeit: es repariert eine
Funktion, die dort gelogen hat. Neues kommt weiterhin nicht dazu.

iOS und tvOS bauen, 476 Tests grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-01 10:39:45 +02:00

50 lines
2.1 KiB
Swift

import SwiftUI
import MediaKit
/// Ein Navigationsstapel mit allen Zielen — und einem Weg, von innen zu
/// schieben.
///
/// **Warum der Pfad hier liegt und nicht beim System.** Ein `NavigationLink`
/// schiebt selbst; wer stattdessen aus einem Knopf heraus schieben will,
/// braucht eine Bindung. Genau das verlangt die Kachel, seit Antippen
/// abspielt: der Weg auf die Detailseite führt dann über das Kontextmenü, und
/// ein Menüeintrag ist kein Link.
///
/// **Die Ziele stehen hier und nur hier.** Sie je Bildschirm anzumelden hat
/// schon einmal nicht funktioniert: liegen zwei Bildschirme übereinander,
/// entscheidet sonst die Reihenfolge, und ein Tippen landete im Nichts.
struct MediaStack<Content: View>: View {
@ViewBuilder let content: () -> Content
@Environment(FlixySession.self) private var session
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
content()
.navigationDestination(for: MediaRoute.self) { MediaDetailView(route: $0) }
.navigationDestination(for: LibraryRoute.self) { route in
if let library = session.libraries.first(where: { $0.id == route.id }) {
LibraryView(library: library)
}
}
.navigationDestination(for: LiveTVRoute.self) { _ in LiveTVView() }
.navigationDestination(for: SearchRoute.self) { _ in SearchView() }
}
.environment(\.flixyPush) { ziel in path.append(ziel) }
}
}
extension EnvironmentValues {
/// Schiebt ein Ziel auf den Stapel, in dem man gerade steht.
///
/// **Über die Umgebung, weil der Weg sonst lang ist.** Eine Kachel steckt
/// in einer Reihe, die in der Startseite steckt, die im Stapel steckt.
/// Eine Bindung durch jede Ebene zu reichen hiesse, drei Ansichten um ein
/// Argument zu erweitern, das sie nur weitergeben.
///
/// Die Voreinstellung tut nichts: ausserhalb eines Stapels gibt es nichts
/// zu schieben, und ein Absturz wäre die schlechtere Antwort.
@Entry var flixyPush: (any Hashable) -> Void = { _ in }
}