import SwiftUI import HaloDesign import MediaKit /// Eine waagerechte Reihe von Titeln. struct MediaRow: View { let row: MediaRowGroup /// Wird durchgereicht — siehe `QuickPlayTile`. var opensDetails: Bool = false @Environment(HaloSession.self) private var session @Environment(HomeLayoutSettings.self) private var layout /// Breit genug, dass die übernächste Kachel angeschnitten ist — das zeigt, /// dass es weitergeht, ohne einen Pfeil dafür zu brauchen. private var landscapeWidth: CGFloat { 220 * layout.cardScale } /// Schmaler, weil hochkant: bei gleicher Höhe passen so mehr Plakate /// nebeneinander, und mehr Auswahl auf einen Blick ist genau der Zweck. /// /// Beide mit demselben Faktor: ihr Verhältnis zueinander soll stimmen, /// egal wie groß es insgesamt eingestellt ist. private var posterWidth: CGFloat { 116 * layout.cardScale } var body: some View { VStack(alignment: .leading, spacing: HaloSpacing.regular) { Text(row.title) .font(.haloRowHeader) .foregroundStyle(Color.haloTextPrimary) .padding(.horizontal, HaloSpacing.screenMargin) ScrollView(.horizontal) { LazyHStack(spacing: HaloSpacing.regular) { ForEach(row.items) { item in QuickPlayTile(item: item, opensDetails: opensDetails) { card(for: item) } } } .padding(.horizontal, HaloSpacing.screenMargin) // Ohne dieses Ziel rasten die Kacheln nicht ein und die Reihe // bleibt an beliebiger Stelle stehen. .scrollTargetLayout() } .scrollTargetBehavior(.viewAligned) .scrollIndicators(.never) } } /// Szenenbild beim Weiterschauen, sonst das Plakat. /// /// Angefangenes erkennt man an der Szene, an der man aufgehört hat — /// 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: MediaItem) -> some View { if row.isContinueWatching { LandscapeCard( title: item.rowTitle, subtitle: item.cardSubtitle, artworkURL: session.backend?.artworkURL( path: item.rowArtworkPath, width: 440, height: 248 ), progress: item.watchProgress ) .frame(width: landscapeWidth) } else { PosterCard( title: item.rowTitle, subtitle: item.cardSubtitle, artworkURL: session.backend?.artworkURL( path: item.posterArtworkPath, width: 300, height: 450 ), progress: item.watchProgress ) .frame(width: posterWidth) } } }