import SwiftUI import FlixyDesign import PlexKit /// Eine waagerechte Reihe von Titeln. struct MediaRow: View { let hub: PlexHub @Environment(FlixySession.self) private var session /// Breit genug, dass die übernächste Kachel angeschnitten ist — das zeigt, /// dass es weitergeht, ohne einen Pfeil dafür zu brauchen. private let cardWidth: CGFloat = 220 var body: some View { VStack(alignment: .leading, spacing: FlixySpacing.regular) { Text(hub.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)) { LandscapeCard( title: item.rowTitle, subtitle: item.cardSubtitle, artworkURL: session.server?.artworkURL( path: item.rowArtworkPath, width: 440, height: 248 ), progress: item.watchProgress ) .frame(width: cardWidth) } .buttonStyle(.plain) } } .padding(.horizontal, FlixySpacing.screenMargin) // Ohne dieses Ziel rasten die Kacheln nicht ein und die Reihe // bleibt an beliebiger Stelle stehen. .scrollTargetLayout() } .scrollTargetBehavior(.viewAligned) .scrollIndicators(.hidden) } } } extension PlexItem { /// Der Titel auf einer Kachel in einer Reihe. /// /// Bei Folgen der Serientitel: in „Weiterschauen" stehen Folgen /// verschiedener Serien nebeneinander, und der Folgentitel allein sagt /// nicht, worum es geht. var rowTitle: String { kind == .episode ? (grandparentTitle ?? title) : title } /// Welches Bild auf die Querformat-Kachel gehört. /// /// Bei Folgen ist `thumb` das Szenenbild der Folge — genau richtig. Bei /// Filmen ist `thumb` das Hochkant-Plakat, das im Querformat beschnitten /// würde; dort ist `art` (das Hintergrundbild) die bessere Wahl. var rowArtworkPath: String? { switch kind { case .episode: thumb ?? grandparentThumb default: art ?? thumb } } }