diff --git a/Jel.xcodeproj/project.pbxproj b/Jel.xcodeproj/project.pbxproj index cd85c84..695650b 100644 --- a/Jel.xcodeproj/project.pbxproj +++ b/Jel.xcodeproj/project.pbxproj @@ -8,15 +8,14 @@ /* Begin PBXBuildFile section */ 3D1015D92B27F57400F5C29A /* AddServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D1015D82B27F57400F5C29A /* AddServerView.swift */; }; - 3D1015DC2B27F5D300F5C29A /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 3D1015DA2B27F5D300F5C29A /* Model.xcdatamodeld */; }; - 3D1015DE2B27F79900F5C29A /* DatamodelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D1015DD2B27F79900F5C29A /* DatamodelController.swift */; }; 3D1015E42B28000E00F5C29A /* AuthStateController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D1015E32B28000E00F5C29A /* AuthStateController.swift */; }; - 3D16FC3C2B2CDFB500E6D8B3 /* LibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D16FC3B2B2CDFB500E6D8B3 /* LibraryView.swift */; }; + 3D16FC3C2B2CDFB500E6D8B3 /* DashboardLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D16FC3B2B2CDFB500E6D8B3 /* DashboardLibraryView.swift */; }; 3D41D1F52B2C962500E58234 /* AppearancePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D41D1F42B2C962500E58234 /* AppearancePicker.swift */; }; 3D41D1FA2B2CAE0000E58234 /* LibraryIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D41D1F92B2CAE0000E58234 /* LibraryIconView.swift */; }; 3D7709392B29139700199889 /* Pulse in Frameworks */ = {isa = PBXBuildFile; productRef = 3D7709382B29139700199889 /* Pulse */; }; 3D77093B2B29139700199889 /* PulseUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3D77093A2B29139700199889 /* PulseUI */; }; 3D8AB2A52B36440D005BD7D0 /* BlurHashDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D8AB2A42B36440D005BD7D0 /* BlurHashDecode.swift */; }; + 3D8AB2A82B366353005BD7D0 /* LibraryDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D8AB2A72B366353005BD7D0 /* LibraryDetailView.swift */; }; 3D9063CB2B279A310063DD2A /* JelApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D9063CA2B279A310063DD2A /* JelApp.swift */; }; 3D9063CD2B279A310063DD2A /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D9063CC2B279A310063DD2A /* ContentView.swift */; }; 3D9063CF2B279A320063DD2A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3D9063CE2B279A320063DD2A /* Assets.xcassets */; }; @@ -68,13 +67,12 @@ /* Begin PBXFileReference section */ 3D1015D42B27F49000F5C29A /* JellyfinKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = JellyfinKit; path = ../JellyfinKit; sourceTree = ""; }; 3D1015D82B27F57400F5C29A /* AddServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddServerView.swift; sourceTree = ""; }; - 3D1015DB2B27F5D300F5C29A /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = ""; }; - 3D1015DD2B27F79900F5C29A /* DatamodelController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatamodelController.swift; sourceTree = ""; }; 3D1015E32B28000E00F5C29A /* AuthStateController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthStateController.swift; sourceTree = ""; }; - 3D16FC3B2B2CDFB500E6D8B3 /* LibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryView.swift; sourceTree = ""; }; + 3D16FC3B2B2CDFB500E6D8B3 /* DashboardLibraryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardLibraryView.swift; sourceTree = ""; }; 3D41D1F42B2C962500E58234 /* AppearancePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearancePicker.swift; sourceTree = ""; }; 3D41D1F92B2CAE0000E58234 /* LibraryIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryIconView.swift; sourceTree = ""; }; 3D8AB2A42B36440D005BD7D0 /* BlurHashDecode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = ""; }; + 3D8AB2A72B366353005BD7D0 /* LibraryDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryDetailView.swift; sourceTree = ""; }; 3D9063C72B279A310063DD2A /* Jel.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Jel.app; sourceTree = BUILT_PRODUCTS_DIR; }; 3D9063CA2B279A310063DD2A /* JelApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JelApp.swift; sourceTree = ""; }; 3D9063CC2B279A310063DD2A /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -131,6 +129,7 @@ 3DAA71C42B31E11D00D5FB33 /* Utility */, 3D9063CC2B279A310063DD2A /* ContentView.swift */, 3DDD67902B293B780026781E /* Dashboard */, + 3D8AB2A62B366309005BD7D0 /* Library */, 3DDD67942B29E27A0026781E /* Settings */, 3D91FDC52B28C28900919017 /* SignIn */, ); @@ -140,7 +139,6 @@ 3D1015DF2B27F8EE00F5C29A /* Controllers */ = { isa = PBXGroup; children = ( - 3D1015DD2B27F79900F5C29A /* DatamodelController.swift */, 3D1015E32B28000E00F5C29A /* AuthStateController.swift */, 3DF1ED3D2B282836000AD8EA /* JellyfinClientController.swift */, 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */, @@ -157,11 +155,11 @@ path = Models; sourceTree = ""; }; - 3D41D1F82B2CADF500E58234 /* Library */ = { + 3D8AB2A62B366309005BD7D0 /* Library */ = { isa = PBXGroup; children = ( - 3D16FC3B2B2CDFB500E6D8B3 /* LibraryView.swift */, 3D41D1F92B2CAE0000E58234 /* LibraryIconView.swift */, + 3D8AB2A72B366353005BD7D0 /* LibraryDetailView.swift */, ); path = Library; sourceTree = ""; @@ -198,7 +196,6 @@ 3D9063CE2B279A320063DD2A /* Assets.xcassets */, 3D9063D02B279A320063DD2A /* Jel.entitlements */, 3D9063D12B279A320063DD2A /* Preview Content */, - 3D1015DA2B27F5D300F5C29A /* Model.xcdatamodeld */, ); path = Jel; sourceTree = ""; @@ -249,8 +246,8 @@ 3DDD67902B293B780026781E /* Dashboard */ = { isa = PBXGroup; children = ( - 3D41D1F82B2CADF500E58234 /* Library */, 3DDD67922B293BC40026781E /* DashboardView.swift */, + 3D16FC3B2B2CDFB500E6D8B3 /* DashboardLibraryView.swift */, ); path = Dashboard; sourceTree = ""; @@ -403,20 +400,19 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 3D1015DE2B27F79900F5C29A /* DatamodelController.swift in Sources */, 3D9063CD2B279A310063DD2A /* ContentView.swift in Sources */, 3DF1ED3E2B282836000AD8EA /* JellyfinClientController.swift in Sources */, 3D1015D92B27F57400F5C29A /* AddServerView.swift in Sources */, 3D9063CB2B279A310063DD2A /* JelApp.swift in Sources */, 3D91FDCD2B2907E800919017 /* JellyfinDateFormatter.swift in Sources */, - 3D1015DC2B27F5D300F5C29A /* Model.xcdatamodeld in Sources */, 3D91FDC92B28C62800919017 /* SignInView.swift in Sources */, + 3D8AB2A82B366353005BD7D0 /* LibraryDetailView.swift in Sources */, 3DDD67932B293BC40026781E /* DashboardView.swift in Sources */, 3D41D1FA2B2CAE0000E58234 /* LibraryIconView.swift in Sources */, 3D8AB2A52B36440D005BD7D0 /* BlurHashDecode.swift in Sources */, 3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */, 3D91FDCB2B28CA2500919017 /* SignInToServerView.swift in Sources */, - 3D16FC3C2B2CDFB500E6D8B3 /* LibraryView.swift in Sources */, + 3D16FC3C2B2CDFB500E6D8B3 /* DashboardLibraryView.swift in Sources */, 3DAA71C62B31E19200D5FB33 /* AsyncImageView.swift in Sources */, 3D1015E42B28000E00F5C29A /* AuthStateController.swift in Sources */, 3DDD67962B29E28B0026781E /* SettingsView.swift in Sources */, @@ -811,19 +807,6 @@ productName = JellyfinKit; }; /* End XCSwiftPackageProductDependency section */ - -/* Begin XCVersionGroup section */ - 3D1015DA2B27F5D300F5C29A /* Model.xcdatamodeld */ = { - isa = XCVersionGroup; - children = ( - 3D1015DB2B27F5D300F5C29A /* Model.xcdatamodel */, - ); - currentVersion = 3D1015DB2B27F5D300F5C29A /* Model.xcdatamodel */; - path = Model.xcdatamodeld; - sourceTree = ""; - versionGroupType = wrapper.xcdatamodel; - }; -/* End XCVersionGroup section */ }; rootObject = 3D9063BF2B279A310063DD2A /* Project object */; } diff --git a/Jel/Controllers/DatamodelController.swift b/Jel/Controllers/DatamodelController.swift deleted file mode 100644 index 4beb173..0000000 --- a/Jel/Controllers/DatamodelController.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// DatamodelController.swift -// Jel -// -// Created by zerocool on 12/11/23. -// - -import CoreData - -struct DatamodelController { - static let shared = DatamodelController() - - let container: NSPersistentContainer - - init() { - container = NSPersistentContainer(name: "Model") - - container.loadPersistentStores(completionHandler: {(storeDescription, error) in - if let error = error as NSError? { - fatalError("Unresolved error \(error), \(error.userInfo)") - } - }) - container.viewContext.automaticallyMergesChangesFromParent = true - } -} diff --git a/Jel/JelApp.swift b/Jel/JelApp.swift index ab7a74d..5dce28d 100644 --- a/Jel/JelApp.swift +++ b/Jel/JelApp.swift @@ -9,7 +9,6 @@ import SwiftUI @main struct JelApp: App { - let datamodelController = DatamodelController.shared let jellyfinClientController = JellyfinClientController(authHeaders: AuthHeaders( Client: "Jel", Device: UIDevice.current.systemName, @@ -20,8 +19,6 @@ struct JelApp: App { var body: some Scene { WindowGroup { ContentView() - .environment(\.managedObjectContext, - datamodelController.container.viewContext) .environmentObject(jellyfinClientController) .task { AuthStateController.shared.load() diff --git a/Jel/Views/Dashboard/Library/LibraryView.swift b/Jel/Views/Dashboard/DashboardLibraryView.swift similarity index 76% rename from Jel/Views/Dashboard/Library/LibraryView.swift rename to Jel/Views/Dashboard/DashboardLibraryView.swift index 63bfd64..98c92c0 100644 --- a/Jel/Views/Dashboard/Library/LibraryView.swift +++ b/Jel/Views/Dashboard/DashboardLibraryView.swift @@ -1,5 +1,5 @@ // -// LibraryView.swift +// DashboardLibraryView.swift // Jel // // Created by zerocool on 12/15/23. @@ -8,7 +8,7 @@ import SwiftUI import JellyfinKit -struct LibraryView: View { +struct DashboardLibraryView: View { @EnvironmentObject var jellyfinClient: JellyfinClientController @StateObject var authState: AuthStateController = AuthStateController.shared @@ -19,7 +19,12 @@ struct LibraryView: View { HStack { ForEach(libraries) {library in if library.collectionType == "movies" || library.collectionType == "tvshows" { - LibraryIconView(library: library) + NavigationLink { + LibraryDetailView(library: library) + } label: { + LibraryIconView(library: library, height: 200) + .padding() + } } } } @@ -32,7 +37,6 @@ struct LibraryView: View { libraries = results } } catch { - print(error) } } } diff --git a/Jel/Views/Dashboard/DashboardView.swift b/Jel/Views/Dashboard/DashboardView.swift index 2658180..50d3538 100644 --- a/Jel/Views/Dashboard/DashboardView.swift +++ b/Jel/Views/Dashboard/DashboardView.swift @@ -14,10 +14,10 @@ struct DashboardView: View { var body: some View { NavigationStack { VStack { - LibraryView() + DashboardLibraryView() } .toolbar { - ToolbarItem { + ToolbarItem(placement: .topBarTrailing) { Button { showingSettingsSheet.toggle() } label: { @@ -32,6 +32,6 @@ struct DashboardView: View { } } -#Preview { - DashboardView() -} +//#Preview { +// DashboardView() +//} diff --git a/Jel/Views/Library/LibraryDetailView.swift b/Jel/Views/Library/LibraryDetailView.swift new file mode 100644 index 0000000..3d5a04b --- /dev/null +++ b/Jel/Views/Library/LibraryDetailView.swift @@ -0,0 +1,43 @@ +// +// 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 + @State var items: [BaseItemDto]? = [] + + var body: some View { + ScrollView { + ForEach(items ?? []) {item in + LibraryIconView(library: item, imageType: "Primary", width: 120) + .padding() + } + } + .navigationTitle(library.name ?? "Unknown") + .onAppear { + Task { + let params = Paths.GetItemsParameters(userID: authState.userId, parentID: library.id) + let request = Paths.getItems(parameters: params) + + do { + let res = try await jellyfinClient.send(request) + items = res.value.items + } catch { + } + } + } + } +} + +#Preview { + LibraryDetailView(library: BaseItemDto()) +} diff --git a/Jel/Views/Dashboard/Library/LibraryIconView.swift b/Jel/Views/Library/LibraryIconView.swift similarity index 76% rename from Jel/Views/Dashboard/Library/LibraryIconView.swift rename to Jel/Views/Library/LibraryIconView.swift index 0131ff7..e5f42b0 100644 --- a/Jel/Views/Dashboard/Library/LibraryIconView.swift +++ b/Jel/Views/Library/LibraryIconView.swift @@ -7,23 +7,26 @@ import SwiftUI import JellyfinKit -import BlurHashKit struct LibraryIconView: View { @EnvironmentObject var jellyfinClient: JellyfinClientController @State var library: BaseItemDto + @State var loadingImage: Bool = true + @State var imageType: String = "Primary" + var width: CGFloat? + var height: CGFloat? @State var loadedImageBinaryData: Data? var body: some View { VStack { AsyncImageView(imageId: library.id ?? "", - blurhash: library.imageBlurHashes?.primary?[library.imageTags?["Primary"] ?? ""] ?? "", - imageType: "Primary") + blurhash: library.imageBlurHashes?.primary?[library.imageTags?[imageType] ?? ""] ?? "", + imageType: imageType) .aspectRatio(contentMode: .fill) - .frame(width: 255, height: 150) + .frame(width: width, height: height) .clipShape(RoundedRectangle(cornerRadius: 5))