From 4ec0f962b2a175ae5f1e3e55a720f9534618a4ad Mon Sep 17 00:00:00 2001 From: Shav Kinderlehrer Date: Mon, 8 Jan 2024 14:00:59 -0500 Subject: [PATCH] Refactor ItemViews --- Jel.xcodeproj/project.pbxproj | 4 ++ Jel/Controllers/UIScreenCurrent.swift | 28 ++++++++ Jel/Views/Library/Item/ItemHeaderView.swift | 15 ++--- Jel/Views/Library/Item/ItemMediaView.swift | 64 +++---------------- Jel/Views/Library/Item/ItemView.swift | 24 +++---- .../Library/Item/Types/ItemMovieView.swift | 44 ++++++++++--- Jel/Views/Utility/StickyHeaderView.swift | 13 ++-- 7 files changed, 103 insertions(+), 89 deletions(-) create mode 100644 Jel/Controllers/UIScreenCurrent.swift diff --git a/Jel.xcodeproj/project.pbxproj b/Jel.xcodeproj/project.pbxproj index ae590fc..cee92ab 100644 --- a/Jel.xcodeproj/project.pbxproj +++ b/Jel.xcodeproj/project.pbxproj @@ -41,6 +41,7 @@ 3DAFA8EC2B394F9F00D71AD1 /* ViewConditionalMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8EB2B394F9F00D71AD1 /* ViewConditionalMethod.swift */; }; 3DAFA8EF2B3B707B00D71AD1 /* ItemMovieView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DAFA8EE2B3B707B00D71AD1 /* ItemMovieView.swift */; }; 3DBAC9E22B4C31BE005F8764 /* ItemPeopleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DBAC9E12B4C31BE005F8764 /* ItemPeopleView.swift */; }; + 3DBAC9E42B4C7404005F8764 /* UIScreenCurrent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DBAC9E32B4C7404005F8764 /* UIScreenCurrent.swift */; }; 3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */; }; 3DDD67932B293BC40026781E /* DashboardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67922B293BC40026781E /* DashboardView.swift */; }; 3DDD67962B29E28B0026781E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67952B29E28B0026781E /* SettingsView.swift */; }; @@ -111,6 +112,7 @@ 3DAFA8EB2B394F9F00D71AD1 /* ViewConditionalMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewConditionalMethod.swift; sourceTree = ""; }; 3DAFA8EE2B3B707B00D71AD1 /* ItemMovieView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemMovieView.swift; sourceTree = ""; }; 3DBAC9E12B4C31BE005F8764 /* ItemPeopleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemPeopleView.swift; sourceTree = ""; }; + 3DBAC9E32B4C7404005F8764 /* UIScreenCurrent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIScreenCurrent.swift; sourceTree = ""; }; 3DC0E5802B2832B9001CCE96 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = ""; }; 3DDD67922B293BC40026781E /* DashboardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardView.swift; sourceTree = ""; }; @@ -168,6 +170,7 @@ 3D1015E32B28000E00F5C29A /* AuthStateController.swift */, 3DF1ED3D2B282836000AD8EA /* JellyfinClientController.swift */, 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */, + 3DBAC9E32B4C7404005F8764 /* UIScreenCurrent.swift */, ); path = Controllers; sourceTree = ""; @@ -466,6 +469,7 @@ 3D3816C92B4B5648006414D7 /* ItemGenresView.swift in Sources */, 3DAFA8EC2B394F9F00D71AD1 /* ViewConditionalMethod.swift in Sources */, 3D9063CB2B279A310063DD2A /* JelApp.swift in Sources */, + 3DBAC9E42B4C7404005F8764 /* UIScreenCurrent.swift in Sources */, 3D13F9692B389FA300E91913 /* ViewOffsetKey.swift in Sources */, 3D91FDCD2B2907E800919017 /* JellyfinDateFormatter.swift in Sources */, 3D91FDC92B28C62800919017 /* SignInView.swift in Sources */, diff --git a/Jel/Controllers/UIScreenCurrent.swift b/Jel/Controllers/UIScreenCurrent.swift new file mode 100644 index 0000000..86d4ca0 --- /dev/null +++ b/Jel/Controllers/UIScreenCurrent.swift @@ -0,0 +1,28 @@ +// +// UIScreenCurrent.swift +// Jel +// +// Created by zerocool on 1/8/24. +// + +import Foundation +import SwiftUI + +extension UIWindow { + static var current: UIWindow? { + for scene in UIApplication.shared.connectedScenes { + guard let windowScene = scene as? UIWindowScene else { continue } + for window in windowScene.windows { + if window.isKeyWindow { return window } + } + } + return nil + } +} + + +extension UIScreen { + static var current: UIScreen? { + UIWindow.current?.screen + } +} diff --git a/Jel/Views/Library/Item/ItemHeaderView.swift b/Jel/Views/Library/Item/ItemHeaderView.swift index afcc21e..44be776 100644 --- a/Jel/Views/Library/Item/ItemHeaderView.swift +++ b/Jel/Views/Library/Item/ItemHeaderView.swift @@ -22,11 +22,10 @@ struct ItemHeaderView: View { var body: some View { ZStack(alignment: .bottom) { - StickyHeaderView(minHeight: 300) { + StickyHeaderView(minHeight: 400) { ItemIconView(item: item, imageType: "Backdrop", contentMode: .fill) .setCornerRadius(0) .overlay(overlayGradient.opacity(0.8)) - .mask(overlayGradientMask) } HStack { @@ -39,12 +38,12 @@ struct ItemHeaderView: View { } .padding([.leading, .trailing]) } - .scrollTransition {content, phase in - content - .scaleEffect(phase.isIdentity ? 1 : 2) - .opacity(phase.isIdentity ? 1 : 0.1) - .blur(radius: phase.isIdentity ? 0 : 50) - } +// .scrollTransition {content, phase in +// content +// .scaleEffect(phase.isIdentity ? 1 : 2) +// .opacity(phase.isIdentity ? 1 : 0.1) +// .blur(radius: phase.isIdentity ? 0 : 50) +// } } } diff --git a/Jel/Views/Library/Item/ItemMediaView.swift b/Jel/Views/Library/Item/ItemMediaView.swift index 2e6f133..1d1e53d 100644 --- a/Jel/Views/Library/Item/ItemMediaView.swift +++ b/Jel/Views/Library/Item/ItemMediaView.swift @@ -9,68 +9,24 @@ import SwiftUI import JellyfinKit import VisibilityTrackingScrollView -struct ItemMediaView: View { +struct ItemMediaView: View { @EnvironmentObject var jellyfinClient: JellyfinClientController @StateObject var authState: AuthStateController = AuthStateController.shared - @State var item: BaseItemDto - @ViewBuilder var playButton: () -> Content + var item: BaseItemDto - @State var pageScrolled: Bool = false var body: some View { - GeometryReader {geo in - ScrollView() { - ItemHeaderView(item: item) - .padding(.bottom) - .background { - GeometryReader {geo in - EmptyView() - .onChange(of: geo.frame(in: .global).minY) { - let minY = geo.frame(in: .global).minY - - pageScrolled = minY < 0 - } - } - } - - playButton() - - VStack(alignment: .leading) { - Text(item.taglines?.count ?? 0 > 0 ? item.taglines?[0] ?? "" : "") - .font(.headline) - .frame(maxWidth: .infinity, alignment: .leading) - .padding(.bottom) - - ForEach(item.overview?.components(separatedBy: "
") ?? [], id: \.self) {overview in - Text(overview) - } - - ItemGenresView(item: item) - .padding(.vertical) - } - .if(max(geo.safeAreaInsets.leading, geo.safeAreaInsets.trailing) > 0) {view in - view - .padding(max(geo.safeAreaInsets.leading, geo.safeAreaInsets.trailing)) - } - .if(max(geo.safeAreaInsets.leading, geo.safeAreaInsets.trailing) <= 0) {view in - view - .padding() - } - } - .ignoresSafeArea() - } - .navigationBarTitleDisplayMode(.inline) - .navigationTitle(item.name ?? "Untitled") - .toolbarRole(.editor) - .toolbar { - ToolbarItem(placement: .principal) { - Text(pageScrolled ? item.name ?? "Untitled" : "") - .bold() + VStack(alignment: .leading) { + Text(item.taglines?.count ?? 0 > 0 ? item.taglines?[0] ?? "" : "") + .font(.headline) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.bottom) + + ForEach(item.overview?.components(separatedBy: "
") ?? [], id: \.self) {overview in + Text(overview) } } - .scrollIndicators(.hidden) - } } diff --git a/Jel/Views/Library/Item/ItemView.swift b/Jel/Views/Library/Item/ItemView.swift index 21d6c77..de4dc1b 100644 --- a/Jel/Views/Library/Item/ItemView.swift +++ b/Jel/Views/Library/Item/ItemView.swift @@ -10,18 +10,20 @@ import JellyfinKit struct ItemView: View { @State var item: BaseItemDto - var body: some View { - switch item.type { - case .movie: - ItemMovieView(item: item) - default: - ItemMediaView(item: item) { - EmptyView() - } + var body: some View { + ScrollView { + VStack { + switch item.type { + case .movie: + ItemMovieView(item: item) + default: + ItemMediaView(item: item) + } } } + } } -#Preview { - ItemView(item: BaseItemDto()) -} +//#Preview { +// ItemView(item: BaseItemDto()) +//} diff --git a/Jel/Views/Library/Item/Types/ItemMovieView.swift b/Jel/Views/Library/Item/Types/ItemMovieView.swift index b621d2e..fcf8c06 100644 --- a/Jel/Views/Library/Item/Types/ItemMovieView.swift +++ b/Jel/Views/Library/Item/Types/ItemMovieView.swift @@ -11,19 +11,43 @@ import JellyfinKit struct ItemMovieView: View { var item: BaseItemDto - var body: some View { - VStack { - ItemMediaView(item: item) { - Button("Play") { - + @State var pageScrolled: Bool = false + + var body: some View { + VStack { + ItemHeaderView(item: item) + .foregroundStyle(.white) + .background { + GeometryReader {geo in + EmptyView() + .onChange(of: geo.frame(in: .global).minY) { + let minY = geo.frame(in: .global).minY + + pageScrolled = minY < 0 + } } - .buttonStyle(.borderedProminent) } - - ItemPeopleView(item: item) - } - .padding() + + ItemMediaView(item: item) + .padding() + + ItemGenresView(item: item) + .padding() + + ItemPeopleView(item: item) + .padding() } + .navigationBarTitleDisplayMode(.inline) + .navigationTitle(item.name ?? "Untitled") + .toolbarRole(.editor) + .toolbar { + ToolbarItem(placement: .principal) { + Text(pageScrolled ? item.name ?? "Untitled" : "") + .bold() + } + } + .toolbarBackground(pageScrolled ? .visible : .hidden) + } } //#Preview { diff --git a/Jel/Views/Utility/StickyHeaderView.swift b/Jel/Views/Utility/StickyHeaderView.swift index 52dc26d..b3bfd02 100644 --- a/Jel/Views/Utility/StickyHeaderView.swift +++ b/Jel/Views/Utility/StickyHeaderView.swift @@ -27,12 +27,13 @@ struct StickyHeaderView: View { .offset(y: -geo.frame(in: .global).minY) .frame(width: geo.size.width, height: geo.size.height + geo.frame(in: .global).minY) } - }.frame(minHeight: minHeight) + } + .frame(minWidth: UIScreen.current?.bounds.width ?? 200, minHeight: minHeight) } } -#Preview { - StickyHeaderView { - Text("Test") - } -} +//#Preview { +// StickyHeaderView { +// Text("Test") +// } +//}