From e807d063195b1299dcaeb6e7213d7e3d300a3112 Mon Sep 17 00:00:00 2001 From: Shav Kinderlehrer Date: Sun, 7 Jan 2024 21:21:36 -0500 Subject: [PATCH] Fix ItemMediaView NavigationTitle + Implement Genre Filtering --- Jel.xcodeproj/project.pbxproj | 17 +++++++++++++ .../xcshareddata/swiftpm/Package.resolved | 9 +++++++ Jel/Views/Library/Item/ItemGenresView.swift | 19 +++++++++++---- Jel/Views/Library/Item/ItemMediaView.swift | 24 ++++++++++++------- Jel/Views/Library/LibraryDetailView.swift | 9 ++++++- 5 files changed, 64 insertions(+), 14 deletions(-) diff --git a/Jel.xcodeproj/project.pbxproj b/Jel.xcodeproj/project.pbxproj index 9846bd4..2190f02 100644 --- a/Jel.xcodeproj/project.pbxproj +++ b/Jel.xcodeproj/project.pbxproj @@ -18,6 +18,7 @@ 3D13F96F2B38A32500E91913 /* StickyHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D13F96E2B38A32500E91913 /* StickyHeaderView.swift */; }; 3D16FC3C2B2CDFB500E6D8B3 /* DashboardLibraryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D16FC3B2B2CDFB500E6D8B3 /* DashboardLibraryView.swift */; }; 3D3816C92B4B5648006414D7 /* ItemGenresView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D3816C82B4B5648006414D7 /* ItemGenresView.swift */; }; + 3D3816CE2B4B78BB006414D7 /* VisibilityTrackingScrollView in Frameworks */ = {isa = PBXBuildFile; productRef = 3D3816CD2B4B78BB006414D7 /* VisibilityTrackingScrollView */; }; 3D41D1F52B2C962500E58234 /* AppearancePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D41D1F42B2C962500E58234 /* AppearancePicker.swift */; }; 3D41D1FA2B2CAE0000E58234 /* ItemIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D41D1F92B2CAE0000E58234 /* ItemIconView.swift */; }; 3D4C15722B3CAA670035373E /* DashboardSectionTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D4C15712B3CAA670035373E /* DashboardSectionTitleView.swift */; }; @@ -123,6 +124,7 @@ buildActionMask = 2147483647; files = ( 3D13F95C2B375A9E00E91913 /* NukeUI in Frameworks */, + 3D3816CE2B4B78BB006414D7 /* VisibilityTrackingScrollView in Frameworks */, 3D77093B2B29139700199889 /* PulseUI in Frameworks */, 3D7709392B29139700199889 /* Pulse in Frameworks */, 3D9064592B27E4C70063DD2A /* JellyfinKit in Frameworks */, @@ -334,6 +336,7 @@ 3D77093A2B29139700199889 /* PulseUI */, 3D13F9592B375A9E00E91913 /* Nuke */, 3D13F95B2B375A9E00E91913 /* NukeUI */, + 3D3816CD2B4B78BB006414D7 /* VisibilityTrackingScrollView */, ); productName = Jel; productReference = 3D9063C72B279A310063DD2A /* Jel.app */; @@ -410,6 +413,7 @@ packageReferences = ( 3D7709372B29139700199889 /* XCRemoteSwiftPackageReference "Pulse" */, 3D13F9582B375A9E00E91913 /* XCRemoteSwiftPackageReference "Nuke" */, + 3D3816CC2B4B78BA006414D7 /* XCRemoteSwiftPackageReference "VisibilityTrackingScrollView" */, ); productRefGroup = 3D9063C82B279A310063DD2A /* Products */; projectDirPath = ""; @@ -852,6 +856,14 @@ minimumVersion = 12.2.0; }; }; + 3D3816CC2B4B78BA006414D7 /* XCRemoteSwiftPackageReference "VisibilityTrackingScrollView" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/elegantchaos/VisibilityTrackingScrollView"; + requirement = { + kind = upToNextMinorVersion; + minimumVersion = 1.0.0; + }; + }; 3D7709372B29139700199889 /* XCRemoteSwiftPackageReference "Pulse" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/kean/Pulse"; @@ -873,6 +885,11 @@ package = 3D13F9582B375A9E00E91913 /* XCRemoteSwiftPackageReference "Nuke" */; productName = NukeUI; }; + 3D3816CD2B4B78BB006414D7 /* VisibilityTrackingScrollView */ = { + isa = XCSwiftPackageProductDependency; + package = 3D3816CC2B4B78BA006414D7 /* XCRemoteSwiftPackageReference "VisibilityTrackingScrollView" */; + productName = VisibilityTrackingScrollView; + }; 3D7709382B29139700199889 /* Pulse */ = { isa = XCSwiftPackageProductDependency; package = 3D7709372B29139700199889 /* XCRemoteSwiftPackageReference "Pulse" */; diff --git a/Jel.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Jel.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index ac5b537..c9b17cb 100644 --- a/Jel.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Jel.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -36,6 +36,15 @@ "revision": "4ce950479707ea109f229d7230ec074a133b15d7", "version": "0.2.1" } + }, + { + "package": "VisibilityTrackingScrollView", + "repositoryURL": "https://github.com/elegantchaos/VisibilityTrackingScrollView", + "state": { + "branch": null, + "revision": "9a5788298a1e238ed1e1f51b195a1296125a5a8c", + "version": "1.0.3" + } } ] }, diff --git a/Jel/Views/Library/Item/ItemGenresView.swift b/Jel/Views/Library/Item/ItemGenresView.swift index 25b86e4..5bfccb0 100644 --- a/Jel/Views/Library/Item/ItemGenresView.swift +++ b/Jel/Views/Library/Item/ItemGenresView.swift @@ -14,7 +14,7 @@ struct ItemGenresView: View { @StateObject var authState: AuthStateController = AuthStateController.shared var item: BaseItemDto - @State var library: BaseItemDto = BaseItemDto() + @State var libraryItems: [BaseItemDto]? = [] var body: some View { VStack(alignment: .leading) { @@ -25,7 +25,7 @@ struct ItemGenresView: View { HStack { ForEach(item.genres ?? [], id: \.self) {genre in NavigationLink { - LibraryDetailView(library: library) {items in + LibraryDetailView(library: BaseItemDto(name: genre), items: libraryItems) {items in var matchingItems: [BaseItemDto] = [] for item in items { @@ -47,10 +47,21 @@ struct ItemGenresView: View { } .onAppear { Task { - let request = Paths.getItem(userID: authState.userId ?? "", itemID: item.parentID ?? "") + let parameters = Paths.GetItemsParameters( + userID: authState.userId ?? "", + isRecursive: true, + fields: [.primaryImageAspectRatio, + .genres, + .taglines, + .overview, + .parentID], + includeItemTypes: [.movie, .series], + genres: item.genres ?? [] + ) + let request = Paths.getItems(parameters: parameters) do { let res = try await jellyfinClient.send(request) - library = res.value + libraryItems = res.value.items ?? [] } catch { } } diff --git a/Jel/Views/Library/Item/ItemMediaView.swift b/Jel/Views/Library/Item/ItemMediaView.swift index dfb6c7a..4b8f863 100644 --- a/Jel/Views/Library/Item/ItemMediaView.swift +++ b/Jel/Views/Library/Item/ItemMediaView.swift @@ -7,6 +7,7 @@ import SwiftUI import JellyfinKit +import VisibilityTrackingScrollView struct ItemMediaView: View { @EnvironmentObject var jellyfinClient: JellyfinClientController @@ -15,7 +16,7 @@ struct ItemMediaView: View { @State var item: BaseItemDto @State var loading: Bool = true - @State var navigationTitle: String = "" + @State var pageScrolled: Bool = false var body: some View { GeometryReader {geo in @@ -23,7 +24,7 @@ struct ItemMediaView: View { ProgressView() .progressViewStyle(.circular) } else { - ScrollView { + ScrollView() { ItemHeaderView(item: item) .padding(.bottom) .background { @@ -31,11 +32,8 @@ struct ItemMediaView: View { EmptyView() .onChange(of: geo.frame(in: .global).minY) { let minY = geo.frame(in: .global).minY - if minY < 0 { - navigationTitle = item.name ?? "" - } else { - navigationTitle = "" - } + + pageScrolled = minY < 0 } } } @@ -49,6 +47,8 @@ struct ItemMediaView: View { ForEach(item.overview?.components(separatedBy: "
") ?? [], id: \.self) {overview in Text(overview) } + + ItemGenresView(item: item) } .if(max(geo.safeAreaInsets.leading, geo.safeAreaInsets.trailing) > 0) {view in view @@ -62,9 +62,15 @@ struct ItemMediaView: View { .ignoresSafeArea() } } - .toolbarRole(.editor) .navigationBarTitleDisplayMode(.inline) - .navigationTitle(navigationTitle) + .navigationTitle(item.name ?? "Untitled") + .toolbarRole(.editor) + .toolbar { + ToolbarItem(placement: .principal) { + Text(pageScrolled ? item.name ?? "Untitled" : "") + .bold() + } + } .scrollIndicators(.hidden) .onAppear { Task { diff --git a/Jel/Views/Library/LibraryDetailView.swift b/Jel/Views/Library/LibraryDetailView.swift index b645a8a..8c74140 100644 --- a/Jel/Views/Library/LibraryDetailView.swift +++ b/Jel/Views/Library/LibraryDetailView.swift @@ -13,9 +13,9 @@ struct LibraryDetailView: View { @StateObject var authState: AuthStateController = AuthStateController.shared @State var library: BaseItemDto + @State var items: [BaseItemDto]? = [] var filter: (_ items: [BaseItemDto]) -> [BaseItemDto] - @State var items: [BaseItemDto]? = [] @State var loading: Bool = true @@ -73,6 +73,13 @@ struct LibraryDetailView: View { } } .onAppear { + if items?.count ?? 0 > 0 { + items = self.filter(items ?? []) + items?.sort(by: {$0.name?.lowercased() ?? "" < $1.name?.lowercased() ?? ""}) + loading = false + return + } + Task { let params = Paths.GetItemsParameters( userID: authState.userId,