luminate-old/Sources/Luminate/Pages/ItemPage.swift

108 lines
3.1 KiB
Swift

//
// ItemPage.swift
// Luminate
//
// Created by Brendan Szymanski on 6/16/25.
//
// Copyright 2026 Brendan Szymanski <hello@bscubed.dev>
//
// 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 <https://www.gnu.org/licenses/>.
//
// 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<Page>
@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<NavigationStack<Page>>
) {
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<NavigationStack<Page>>
) {
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
}
}
}