import SwiftUI import FlixyDesign import MediaKit /// Der Aufmacher oben auf der Startseite des Fernsehers. /// /// Derselbe `HeroBanner` wie am Telefon — das Bauteil kennt keine Plattform, /// es setzt Bild, Verlauf und Text. Anders sind nur die Knöpfe: hier sind es /// Fokusziele, und sie müssen gross genug sein, dass man aus drei Metern /// sieht, welcher gerade dran ist. struct TVHeroSection: View { let item: MediaItem let onPlay: () -> Void let onDetails: () -> Void @Environment(FlixySession.self) private var session @Environment(\.flixyAccent) private var accent var body: some View { HeroBanner( title: item.rowTitle, metadata: metadaten, summary: item.summary, artworkURLs: session.backend.map { HeroArtwork.backdropURLs(for: item, backend: $0, compact: false) } ?? [], logoURL: session.backend.flatMap { HeroArtwork.logoURL(for: item, backend: $0) }, aspectRatio: FlixyAspectRatio.hero, // Der Aufmacher nimmt die Höhe, die das Karussell ihm gibt. fillsAvailableSpace: true ) { Button(action: onPlay) { Label(abspielTitel, systemImage: "play.fill") } .buttonStyle(.borderedProminent) .tint(accent) Button(action: onDetails) { Label("hero.details", systemImage: "info.circle") } .buttonStyle(.bordered) } } /// „Weiterschauen" statt „Abspielen", wenn schon etwas gesehen wurde. private var abspielTitel: LocalizedStringKey { item.watchProgress == nil ? "hero.play" : "hero.resume" } private var metadaten: String? { var teile: [String] = [] if item.kind == .episode, let staffel = item.parentIndex, let folge = item.index { // Ausgeschrieben: der Aufmacher am Fernseher ist 1760 Punkte // breit, und gelesen wird er aus drei Metern. teile.append(String(localized: "episode.long \(staffel) \(folge)")) } if let jahr = item.year { teile.append(String(jahr)) } if let dauer = item.duration { teile.append(Duration.milliseconds(dauer).runtimeLabel) } if let freigabe = item.contentRating { teile.append(freigabe) } return teile.isEmpty ? nil : teile.joined(separator: " · ") } }