import Adwaita import LuminateCore import LuminateDI public struct HomeView: View { nonisolated public init(navigation: Binding>) { _navigation = navigation } @Injected(\.client) var client @Injected(\.userId) var userId @Binding var navigation: NavigationStack @State private var resumeItems: [Components.Schemas.BaseItemDto] = [] @State private var nextUpItems: [Components.Schemas.BaseItemDto] = [] @State private var latestItems: [Components.Schemas.BaseItemDto] = [] @State private var libraries: [Components.Schemas.BaseItemDto] = [] @State private var isLoading = true @State private var isLoadingData = false public var view: Body { ScrollView { Clamp() .maximumSize(1550) .tighteningThreshold(550) .child { VStack { if isLoading { Spinner() .halign(.center) .valign(.center) .frame(minWidth: 64) .frame(maxWidth: 64) } else { if !resumeItems.isEmpty { let title = "Continue Watching" MediaRow( title: title, items: resumeItems, navigation: $navigation, onSeeAll: { navigation.push(.folder(title: title, items: resumeItems)) } ) .padding(32, .bottom) } if !nextUpItems.isEmpty { let title = "Next Up" MediaRow( title: title, items: nextUpItems, navigation: $navigation, onSeeAll: { navigation.push(.folder(title: title, items: nextUpItems)) } ) .padding(32, .bottom) } if !latestItems.isEmpty { let title = "Recently Added" MediaRow( title: title, items: latestItems, navigation: $navigation, onSeeAll: { navigation.push(.folder(title: title, items: latestItems)) } ) .padding(32, .bottom) } LibraryGrid( libraries: libraries, navigation: $navigation ) .padding(32, .bottom) } } .padding(8, .horizontal) .padding(32, .bottom) } } .hscrollbarPolicy(.never) .propagateNaturalHeight() .onAppear { loadHomeData() } } private func loadHomeData() { Task { async let resume = client.getItems( userId: userId, filters: [.isResumable], sortBy: [.datePlayed], sortOrder: [.descending], limit: 20, recursive: true ) async let nextUp = client.getNextUp(userId: userId, limit: 20) async let latest = client.getLatestMedia(userId: userId, limit: 20) async let views = client.getUserViews(userId: userId) do { let (resume, nextUp, latest, views) = try await (resume, nextUp, latest, views) resumeItems = resume.items ?? [] nextUpItems = nextUp.items ?? [] latestItems = latest libraries = views.items ?? [] isLoading = false } catch { isLoading = false } isLoadingData = false } } }