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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1fa8011094
commit
a665d79e6d
@@ -29,6 +29,8 @@ struct QuickPlayTile<Card: View>: View {
|
||||
/// Was die umgebende Seite tun soll, wenn sich am Server etwas geändert
|
||||
/// hat. Siehe `ItemActionEntries`.
|
||||
@Environment(\.flixyItemChanged) private var itemChanged
|
||||
/// Der Weg auf die Detailseite — siehe `MediaStack`.
|
||||
@Environment(\.flixyPush) private var push
|
||||
|
||||
private var isMac: Bool { FlixyPlatform.isMac }
|
||||
|
||||
@@ -37,10 +39,10 @@ struct QuickPlayTile<Card: View>: View {
|
||||
/// Eine Sammlung ist kein Titel — dort wäre der Knopf eine Behauptung.
|
||||
private var isPlayable: Bool { item.kind != .collection }
|
||||
|
||||
private var route: MediaRoute { MediaRoute(ratingKey: item.id, title: item.title) }
|
||||
|
||||
var body: some View {
|
||||
NavigationLink(value: MediaRoute(ratingKey: item.id, title: item.title)) {
|
||||
card()
|
||||
}
|
||||
kachel
|
||||
.buttonStyle(.plain)
|
||||
// **Als Überzug auf dem Link, nicht als Kind darin.**
|
||||
//
|
||||
@@ -66,6 +68,15 @@ struct QuickPlayTile<Card: View>: View {
|
||||
// Kachel steht.
|
||||
.contextMenu {
|
||||
if isPlayable {
|
||||
// **Am Telefon und am iPad führt der Weg zur Detailseite
|
||||
// hierher.** Antippen spielt dort ab; wer stattdessen
|
||||
// nachsehen will, was das überhaupt ist, drückt lang. Am Mac
|
||||
// ist es umgekehrt: dort öffnet der Klick die Seite, und zum
|
||||
// Starten gibt es den Knopf beim Überfahren.
|
||||
if !isMac {
|
||||
Button("hero.details", systemImage: "info.circle") { push(route) }
|
||||
Divider()
|
||||
}
|
||||
Button("tile.play", systemImage: "play.fill") { trigger() }
|
||||
Divider()
|
||||
}
|
||||
@@ -79,6 +90,13 @@ struct QuickPlayTile<Card: View>: View {
|
||||
// bleibt einer, und im Aktionen-Rotor steht „Abspielen". Zwanzig
|
||||
// Kacheln mit je zwei Elementen wären sechzig Wischer.
|
||||
.accessibilityAction(named: Text("tile.play")) { trigger() }
|
||||
// Für VoiceOver der zweite Weg: am Telefon führt das Antippen in den
|
||||
// Film, und die Detailseite wäre sonst nur über ein Kontextmenü zu
|
||||
// erreichen, das eine Geste verlangt.
|
||||
.accessibilityAction(named: Text("hero.details")) {
|
||||
if isMac { return }
|
||||
push(route)
|
||||
}
|
||||
// **Nur der Fehler, kein Kreisel.** Wer im Kontextmenü tippt, sieht
|
||||
// das Menü verschwinden; ein Kreisel auf der Kachel käme für eine
|
||||
// Aktion, die Millisekunden dauert, zu spät und ginge zu früh. Geht
|
||||
@@ -94,6 +112,30 @@ struct QuickPlayTile<Card: View>: View {
|
||||
}
|
||||
}
|
||||
|
||||
/// Die Kachel selbst — und was ein Antippen bedeutet.
|
||||
///
|
||||
/// **Am Telefon und am iPad spielt es ab.** Wer eine Kachel antippt, weiss
|
||||
/// meistens schon, was er sehen will; der Umweg über die Detailseite
|
||||
/// kostete zwei Schritte für eine Absicht. Die Seite ist weiter da — über
|
||||
/// langes Drücken, wo auch „gesehen" und „entfernen" stehen.
|
||||
///
|
||||
/// **Am Mac bleibt der Klick die Detailseite.** Dort gibt es den
|
||||
/// Abspielknopf beim Überfahren, und langes Drücken ist keine übliche
|
||||
/// Geste — ein Rechtsklick ist der Weg ins Menü, nicht in den Film.
|
||||
///
|
||||
/// Ein `NavigationLink` schiebt selbst; ein Knopf braucht dafür den Weg
|
||||
/// aus der Umgebung. Deshalb zwei Fassungen und nicht eine mit `if` im
|
||||
/// Inneren: die Kachel soll am Mac ein Link **sein**, nicht einer
|
||||
/// aussehen.
|
||||
@ViewBuilder
|
||||
private var kachel: some View {
|
||||
if isMac || !isPlayable {
|
||||
NavigationLink(value: route) { card() }
|
||||
} else {
|
||||
Button { trigger() } label: { card() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Oben rechts, weil der Fortschrittsbalken unten liegt.
|
||||
private var playButton: some View {
|
||||
Button(action: trigger) {
|
||||
|
||||
Reference in New Issue
Block a user