// // ItemPage.swift // Luminate // // Created by Brendan Szymanski on 6/16/25. // // Copyright 2026 Brendan Szymanski // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // SPDX-License-Identifier: GPL-3.0-or-later // import Adwaita import LuminateCore import LuminateDI import LuminateUI public struct ItemPage: View { private var title: String? private var parentId: String? private var type: DisplayType @Binding var navigation: NavigationStack @State private var items: [BaseItemDto] = [] @State private var isLoading = false @Injected(\.client) var client @Injected(\.userId) var userId nonisolated public init( title: String, items: [BaseItemDto], type: DisplayType = .mixed, navigation: Binding> ) { self.title = title self._items = .init(wrappedValue: items) self.parentId = nil self.type = type _navigation = navigation } nonisolated public init( item: BaseItemDto, type: DisplayType = .mixed, navigation: Binding> ) { self.title = item.name self.parentId = item.id self.type = type _isLoading = .init(wrappedValue: item.id != nil) _navigation = navigation } public var view: Body { ScrollView { Clamp() .maximumSize(1550) .tighteningThreshold(550) .child { if isLoading, parentId != nil { Spinner() } else { ItemGrid( items: items, type: type, navigation: $navigation, title: title ) .padding(32, .vertical) } } } .hscrollbarPolicy(.never) .propagateNaturalHeight() .onAppear { loadIfNeeded() } } private func loadIfNeeded() { guard let parentId else { return } Task { let result = try? await client.getItems( userId: userId, parentId: parentId, fields: [.primaryImageAspectRatio], sortBy: [.sortName], sortOrder: [.ascending] ) items = result?.items ?? [] isLoading = false } } }