import SwiftUI import FlixyDesign import PlexKit /// Die Startseite: Aufmacher oben, darunter die Reihen vom Server. struct HomeView: View { @Environment(FlixySession.self) private var session @Environment(HomeLayoutSettings.self) private var layout @State private var state: LoadState<[PlexHub]> = .loading var body: some View { Group { switch state { case .loading: ProgressView().frame(maxWidth: .infinity, maxHeight: .infinity) case .failed(let message): ContentUnavailableView { Label("error.title", systemImage: "exclamationmark.triangle") } description: { Text(message) } actions: { Button("action.retry") { Task { await load() } } } case .loaded(let allHubs): let hubs = layout.apply(to: allHubs) if hubs.isEmpty { ContentUnavailableView { Label("home.empty.title", systemImage: "film.stack") } description: { Text("home.empty.description") } } else { content(hubs: hubs) } } } .background(Color.flixyCanvas) .navigationTitle(Branding.appName) .navigationBarTitleDisplayMode(.inline) .toolbar { SearchToolbarItem() } .navigationDestination(for: MediaRoute.self) { MediaDetailView(route: $0) } .task(id: session.server?.name) { await load() } .refreshable { await load() } } private func content(hubs: [PlexHub]) -> some View { ScrollView { LazyVStack(alignment: .leading, spacing: FlixySpacing.section) { if let featured = heroItem(in: hubs) { HeroSection(item: featured) } ForEach(hubs) { hub in MediaRow(hub: hub) } } .padding(.bottom, FlixySpacing.section) } .scrollIndicators(.hidden) } /// Was oben groß gezeigt wird. /// /// Erste Wahl ist etwas Angefangenes — wer die App öffnet, will meistens /// weiterschauen. Erst wenn es nichts Angefangenes gibt, tritt der /// Neuzugang an die Stelle. private func heroItem(in hubs: [PlexHub]) -> PlexItem? { let continuing = hubs.first { $0.hubIdentifier.contains("continue") } return continuing?.items.first ?? hubs.first?.items.first } private func load() async { guard let server = session.server else { return } state = await LoadState.load(keepingPrevious: state) { try await server.homeHubs() } } }