2023-12-23 05:53:44 +00:00
|
|
|
//
|
|
|
|
// LibraryDetailView.swift
|
|
|
|
// Jel
|
|
|
|
//
|
|
|
|
// Created by zerocool on 12/22/23.
|
|
|
|
//
|
|
|
|
|
|
|
|
import SwiftUI
|
|
|
|
import JellyfinKit
|
|
|
|
|
|
|
|
struct LibraryDetailView: View {
|
|
|
|
@EnvironmentObject var jellyfinClient: JellyfinClientController
|
|
|
|
@StateObject var authState: AuthStateController = AuthStateController.shared
|
|
|
|
|
|
|
|
@State var library: BaseItemDto
|
2024-01-08 02:21:36 +00:00
|
|
|
@State var items: [BaseItemDto]? = []
|
2024-01-08 00:20:56 +00:00
|
|
|
var filter: (_ items: [BaseItemDto]) -> [BaseItemDto]
|
2023-12-25 05:41:45 +00:00
|
|
|
|
2023-12-23 05:53:44 +00:00
|
|
|
|
2023-12-23 16:14:53 +00:00
|
|
|
@State var loading: Bool = true
|
|
|
|
|
2023-12-25 05:41:45 +00:00
|
|
|
|
|
|
|
@State var searchText: String = ""
|
|
|
|
@State var searchResultHints: SearchHintResult?
|
|
|
|
@State var searchResultItems: [BaseItemDto]?
|
2023-12-23 16:14:53 +00:00
|
|
|
let columns = [
|
|
|
|
GridItem(.adaptive(minimum: 150))
|
|
|
|
]
|
2023-12-23 05:53:44 +00:00
|
|
|
var body: some View {
|
2023-12-23 16:14:53 +00:00
|
|
|
if loading {
|
|
|
|
ProgressView()
|
|
|
|
.progressViewStyle(.circular)
|
2023-12-25 05:41:45 +00:00
|
|
|
} else {
|
|
|
|
EmptyView()
|
2023-12-23 16:14:53 +00:00
|
|
|
}
|
2023-12-23 05:53:44 +00:00
|
|
|
ScrollView {
|
2023-12-23 16:14:53 +00:00
|
|
|
LazyVGrid(columns: columns) {
|
2023-12-27 13:25:35 +00:00
|
|
|
// uses searchResultItems only if searchText is not empty
|
|
|
|
ForEach(!searchText.isEmpty ? (searchResultItems ?? items) ?? [] : items ?? []) {item in
|
|
|
|
NavigationLink {
|
|
|
|
ItemView(item: item)
|
|
|
|
} label: {
|
2024-01-30 21:52:53 +00:00
|
|
|
ItemIconView(item: item, width: 150)
|
2023-12-27 18:07:20 +00:00
|
|
|
.showCaption()
|
2023-12-27 13:25:35 +00:00
|
|
|
.setAspectRatio(item.primaryImageAspectRatio ?? 0.6)
|
|
|
|
.padding()
|
|
|
|
|
2023-12-25 05:41:45 +00:00
|
|
|
}
|
2023-12-27 13:25:35 +00:00
|
|
|
.buttonStyle(PlainButtonStyle())
|
2023-12-25 05:41:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-25 06:02:38 +00:00
|
|
|
.if(!loading) {view in
|
|
|
|
view.searchable(text: $searchText)
|
2023-12-27 13:25:35 +00:00
|
|
|
.onChange(of: searchText) {
|
|
|
|
Task {
|
|
|
|
let parameters = Paths.GetParameters(
|
|
|
|
userID: AuthStateController.shared.userId,
|
|
|
|
searchTerm: searchText.lowercased(),
|
|
|
|
parentID: library.id
|
|
|
|
)
|
|
|
|
searchResultHints = await jellyfinClient.search(parameters: parameters)
|
|
|
|
|
|
|
|
searchResultItems = items?.filter { item in
|
|
|
|
for hint in searchResultHints?.searchHints ?? [] {
|
|
|
|
if hint.name == item.name {
|
|
|
|
return true
|
|
|
|
}
|
2023-12-25 06:02:38 +00:00
|
|
|
}
|
2023-12-27 13:25:35 +00:00
|
|
|
return false
|
2023-12-25 05:41:45 +00:00
|
|
|
}
|
2023-12-23 19:15:01 +00:00
|
|
|
}
|
2023-12-23 16:14:53 +00:00
|
|
|
}
|
2023-12-23 05:53:44 +00:00
|
|
|
}
|
|
|
|
.onAppear {
|
2024-01-08 02:21:36 +00:00
|
|
|
if items?.count ?? 0 > 0 {
|
|
|
|
items = self.filter(items ?? [])
|
|
|
|
items?.sort(by: {$0.name?.lowercased() ?? "" < $1.name?.lowercased() ?? ""})
|
|
|
|
loading = false
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2023-12-23 05:53:44 +00:00
|
|
|
Task {
|
2023-12-27 13:25:35 +00:00
|
|
|
let params = Paths.GetItemsParameters(
|
|
|
|
userID: authState.userId,
|
2024-01-09 17:32:06 +00:00
|
|
|
parentID: library.id
|
2023-12-27 13:25:35 +00:00
|
|
|
)
|
2023-12-23 05:53:44 +00:00
|
|
|
let request = Paths.getItems(parameters: params)
|
|
|
|
|
|
|
|
do {
|
|
|
|
let res = try await jellyfinClient.send(request)
|
|
|
|
items = res.value.items
|
2024-01-08 00:20:56 +00:00
|
|
|
items = self.filter(items ?? [])
|
2023-12-25 01:01:52 +00:00
|
|
|
items?.sort(by: {$0.name?.lowercased() ?? "" < $1.name?.lowercased() ?? ""})
|
2023-12-23 16:14:53 +00:00
|
|
|
loading = false
|
2023-12-23 05:53:44 +00:00
|
|
|
} catch {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-23 16:14:53 +00:00
|
|
|
//#Preview {
|
|
|
|
// LibraryDetailView(library: BaseItemDto())
|
|
|
|
//}
|