From 2619848a70d1c1cf366a288dcb889103b7464f1c Mon Sep 17 00:00:00 2001 From: Shav Kinderlehrer Date: Wed, 21 Feb 2024 14:45:48 -0500 Subject: [PATCH] Finish ItemSeriesEpisodeIconView + make geo size globally available --- Jel.xcodeproj/project.pbxproj | 4 ++ Jel/Controllers/ScreenSize.swift | 12 ++++++ Jel/JelApp.swift | 27 +++++++++---- Jel/Views/Dashboard/DashboardView.swift | 28 ++++++------- .../Series/ItemSeriesEpisodeIconView.swift | 39 +++++++++++-------- .../Item/Series/ItemSeriesEpisodesView.swift | 2 +- Jel/Views/Utility/StickyHeaderView.swift | 3 +- 7 files changed, 72 insertions(+), 43 deletions(-) create mode 100644 Jel/Controllers/ScreenSize.swift diff --git a/Jel.xcodeproj/project.pbxproj b/Jel.xcodeproj/project.pbxproj index e7ac9c3..f86762b 100644 --- a/Jel.xcodeproj/project.pbxproj +++ b/Jel.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ 3D41D1FA2B2CAE0000E58234 /* ItemIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D41D1F92B2CAE0000E58234 /* ItemIconView.swift */; }; 3D4C15722B3CAA670035373E /* DashboardSectionTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D4C15712B3CAA670035373E /* DashboardSectionTitleView.swift */; }; 3D58F07E2B4DB19300DB2936 /* TextRatingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D58F07D2B4DB19300DB2936 /* TextRatingView.swift */; }; + 3D6A0DC12B867B4C001FDA40 /* ScreenSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D6A0DC02B867B4C001FDA40 /* ScreenSize.swift */; }; 3D6A7DB92B7C5D3900A5E31B /* ItemSeasonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D6A7DB82B7C5D3900A5E31B /* ItemSeasonView.swift */; }; 3D74AE122B7D4EB000C17F2E /* UIScreenWidthExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D74AE112B7D4EB000C17F2E /* UIScreenWidthExtension.swift */; }; 3D7709392B29139700199889 /* Pulse in Frameworks */ = {isa = PBXBuildFile; productRef = 3D7709382B29139700199889 /* Pulse */; }; @@ -83,6 +84,7 @@ 3D41D1F92B2CAE0000E58234 /* ItemIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemIconView.swift; sourceTree = ""; }; 3D4C15712B3CAA670035373E /* DashboardSectionTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardSectionTitleView.swift; sourceTree = ""; }; 3D58F07D2B4DB19300DB2936 /* TextRatingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRatingView.swift; sourceTree = ""; }; + 3D6A0DC02B867B4C001FDA40 /* ScreenSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenSize.swift; sourceTree = ""; }; 3D6A7DB82B7C5D3900A5E31B /* ItemSeasonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemSeasonView.swift; sourceTree = ""; }; 3D74AE112B7D4EB000C17F2E /* UIScreenWidthExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIScreenWidthExtension.swift; sourceTree = ""; }; 3D8AB2A42B36440D005BD7D0 /* BlurHashDecode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = ""; }; @@ -152,6 +154,7 @@ 3D1015E32B28000E00F5C29A /* AuthStateController.swift */, 3DF1ED3D2B282836000AD8EA /* JellyfinClientController.swift */, 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */, + 3D6A0DC02B867B4C001FDA40 /* ScreenSize.swift */, ); path = Controllers; sourceTree = ""; @@ -386,6 +389,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 3D6A0DC12B867B4C001FDA40 /* ScreenSize.swift in Sources */, 3D9063CD2B279A310063DD2A /* ContentView.swift in Sources */, 3D13F96F2B38A32500E91913 /* StickyHeaderView.swift in Sources */, 3DF1ED3E2B282836000AD8EA /* JellyfinClientController.swift in Sources */, diff --git a/Jel/Controllers/ScreenSize.swift b/Jel/Controllers/ScreenSize.swift new file mode 100644 index 0000000..972d395 --- /dev/null +++ b/Jel/Controllers/ScreenSize.swift @@ -0,0 +1,12 @@ +// +// ScreenSize.swift +// Jel +// +// Created by zerocool on 2/21/24. +// + +import Foundation + +class ScreenSize: ObservableObject { + @Published var size: CGSize = CGSize(width: 0, height: 0) +} diff --git a/Jel/JelApp.swift b/Jel/JelApp.swift index 5dce28d..234c130 100644 --- a/Jel/JelApp.swift +++ b/Jel/JelApp.swift @@ -16,16 +16,27 @@ struct JelApp: App { Version: Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "0.0.0", Token: "")) + @StateObject var size: ScreenSize = ScreenSize() + var body: some Scene { WindowGroup { - ContentView() - .environmentObject(jellyfinClientController) - .task { - AuthStateController.shared.load() - SettingsController.shared.load() - jellyfinClientController.setUrl(url: AuthStateController.shared.serverUrl) - jellyfinClientController.setToken(token: AuthStateController.shared.authToken ?? "") - } + GeometryReader {geo in + ContentView() + .environmentObject(jellyfinClientController) + .environmentObject(size) + .onChange(of: geo.size) { + size.size = geo.size + } + .onAppear { + size.size = geo.size + } + .task { + AuthStateController.shared.load() + SettingsController.shared.load() + jellyfinClientController.setUrl(url: AuthStateController.shared.serverUrl) + jellyfinClientController.setToken(token: AuthStateController.shared.authToken ?? "") + } + } } } } diff --git a/Jel/Views/Dashboard/DashboardView.swift b/Jel/Views/Dashboard/DashboardView.swift index 931a884..508d002 100644 --- a/Jel/Views/Dashboard/DashboardView.swift +++ b/Jel/Views/Dashboard/DashboardView.swift @@ -10,8 +10,7 @@ import JellyfinKit struct DashboardView: View { @State var showingSettingsSheet: Bool = false - @ObservedObject var authState: AuthStateController = AuthStateController.shared - @State var refresh: Bool = true + var body: some View { ScrollView { @@ -25,23 +24,20 @@ struct DashboardView: View { .padding([.top, .leading]) } } - } - .navigationTitle("Home") - .toolbar { - ToolbarItem(placement: .topBarTrailing) { - Button { - showingSettingsSheet.toggle() - } label: { - Label("Settings", systemImage: "gear") + .navigationTitle("Home") + .toolbar { + ToolbarItem(placement: .topBarTrailing) { + Button { + showingSettingsSheet.toggle() + } label: { + Label("Settings", systemImage: "gear") + } } } + .sheet(isPresented: $showingSettingsSheet) { + SettingsView(showingSettingsView: $showingSettingsSheet) + } } - .sheet(isPresented: $showingSettingsSheet) { - SettingsView(showingSettingsView: $showingSettingsSheet) - } - .onChange(of: authState.loggedIn, { - refresh = !authState.loggedIn - }) } } diff --git a/Jel/Views/Item/Series/ItemSeriesEpisodeIconView.swift b/Jel/Views/Item/Series/ItemSeriesEpisodeIconView.swift index fea8997..9217bea 100644 --- a/Jel/Views/Item/Series/ItemSeriesEpisodeIconView.swift +++ b/Jel/Views/Item/Series/ItemSeriesEpisodeIconView.swift @@ -12,23 +12,30 @@ import ExpandableText struct ItemSeriesEpisodeIconView: View { var item: BaseItemDto + @EnvironmentObject var size: ScreenSize + + var iconWidthMultiplier: CGFloat = 0.35 + var body: some View { - HStack(alignment: .top) { - VStack(alignment: .leading) { - Text("Episode \(item.indexNumber ?? 0)") - .foregroundStyle(Color.secondary) - .font(.callout) - ItemIconView(item: item, width: UIScreen.screenWidth * 0.5, contentMode: .fill) - .setAspectRatio(item.primaryImageAspectRatio ?? 1.7) - } - .frame(width: UIScreen.screenWidth * 0.5) - - VStack(alignment: .leading) { - Text(item.name ?? "Episode \(item.indexNumber ?? 0)") - .font(.callout) - .bold() - Text(item.overview ?? "") - .frame(height: (UIScreen.screenWidth * 0.5) / (item.primaryImageAspectRatio ?? 1.7)) // Calculate optimal amount of lines based on episode image + VStack(alignment: .leading) { + HStack(alignment: .top) { + ItemIconView(item: item, width: (size.size.width * iconWidthMultiplier), height: (size.size.width * iconWidthMultiplier) / 1.7) + + VStack(alignment: .leading) { + Text("Episode \(item.indexNumber ?? 0)") + .foregroundStyle(Color.secondary) + .font(.caption) + Text(item.name ?? "---") + .bold() + .lineLimit(nil) + + Text(item.overview ?? "") + .foregroundStyle(Color.secondary) + .font(.callout) + + Spacer() + } + .frame(height: (size.size.width * iconWidthMultiplier) / 1.7) } } } diff --git a/Jel/Views/Item/Series/ItemSeriesEpisodesView.swift b/Jel/Views/Item/Series/ItemSeriesEpisodesView.swift index 2588515..17d5c9b 100644 --- a/Jel/Views/Item/Series/ItemSeriesEpisodesView.swift +++ b/Jel/Views/Item/Series/ItemSeriesEpisodesView.swift @@ -17,7 +17,7 @@ struct ItemSeriesEpisodesView: View { @State var episodeItems: [BaseItemDto] = [] var body: some View { - VStack { + VStack(alignment: .leading) { ForEach(episodeItems) {episode in ItemSeriesEpisodeIconView(item: episode) } diff --git a/Jel/Views/Utility/StickyHeaderView.swift b/Jel/Views/Utility/StickyHeaderView.swift index b3bfd02..decc867 100644 --- a/Jel/Views/Utility/StickyHeaderView.swift +++ b/Jel/Views/Utility/StickyHeaderView.swift @@ -8,7 +8,6 @@ import SwiftUI struct StickyHeaderView: View { - var minHeight: CGFloat var content: Content @@ -28,7 +27,7 @@ struct StickyHeaderView: View { .frame(width: geo.size.width, height: geo.size.height + geo.frame(in: .global).minY) } } - .frame(minWidth: UIScreen.current?.bounds.width ?? 200, minHeight: minHeight) + .frame(minWidth: UIScreen.screenWidth, minHeight: minHeight) } }