From ce0be87c7f39e9763d835a685cb65eb38c7e68c3 Mon Sep 17 00:00:00 2001 From: Shav Kinderlehrer Date: Wed, 21 Feb 2024 12:20:24 -0500 Subject: [PATCH] Cleanup + change SignInView to be a sheet --- Jel.xcodeproj/project.pbxproj | 32 ++++++++++-------- Jel/Controllers/AuthStateController.swift | 4 +++ Jel/Extensions/BindingNot.swift | 18 ++++++++++ .../BlurHashDecode.swift | 0 .../JellyfinDateFormatter.swift | 0 .../JellyfinKitExtensions.swift | 0 .../UIScreenCurrent.swift | 0 .../UIScreenWidthExtension.swift | 0 .../ViewExtensions.swift | 0 Jel/Views/ContentView.swift | 33 ++++++++++++++----- .../Dashboard/DashboardLibraryView.swift | 2 +- Jel/Views/Dashboard/DashboardView.swift | 5 +++ Jel/Views/Item/ItemGenresView.swift | 2 +- .../Item/Person/ItemPersonDetailView.swift | 2 +- .../Item/Person/ItemPersonIconView.swift | 2 +- .../Item/Series/ItemSeriesEpisodesView.swift | 2 +- .../Item/Series/ItemSeriesSeasonsView.swift | 2 +- Jel/Views/Library/LibraryDetailView.swift | 2 +- Jel/Views/Settings/SettingsView.swift | 8 +++-- Jel/Views/SignIn/AddServerView.swift | 12 +++---- Jel/Views/SignIn/SignInToServerView.swift | 2 +- Jel/Views/SignIn/SignInView.swift | 9 +++-- 22 files changed, 94 insertions(+), 43 deletions(-) create mode 100644 Jel/Extensions/BindingNot.swift rename Jel/{Models => Extensions}/BlurHashDecode.swift (100%) rename Jel/{Models => Extensions}/JellyfinDateFormatter.swift (100%) rename Jel/{Models => Extensions}/JellyfinKitExtensions.swift (100%) rename Jel/{Controllers => Extensions}/UIScreenCurrent.swift (100%) rename Jel/{Models => Extensions}/UIScreenWidthExtension.swift (100%) rename Jel/{Models => Extensions}/ViewExtensions.swift (100%) diff --git a/Jel.xcodeproj/project.pbxproj b/Jel.xcodeproj/project.pbxproj index 6855a6e..e98363e 100644 --- a/Jel.xcodeproj/project.pbxproj +++ b/Jel.xcodeproj/project.pbxproj @@ -48,6 +48,7 @@ 3DBAC9E42B4C7404005F8764 /* UIScreenCurrent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DBAC9E32B4C7404005F8764 /* UIScreenCurrent.swift */; }; 3DBAC9EA2B4C8927005F8764 /* ItemPersonIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DBAC9E92B4C8927005F8764 /* ItemPersonIconView.swift */; }; 3DC6BA2D2B2A422300416B9F /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */; }; + 3DD6850C2B85A6A8002FAA1A /* BindingNot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DD6850B2B85A6A8002FAA1A /* BindingNot.swift */; }; 3DDD67932B293BC40026781E /* DashboardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67922B293BC40026781E /* DashboardView.swift */; }; 3DDD67962B29E28B0026781E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDD67952B29E28B0026781E /* SettingsView.swift */; }; 3DDF35D52B7D384000423923 /* ItemSeriesEpisodesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DDF35D42B7D384000423923 /* ItemSeriesEpisodesView.swift */; }; @@ -129,6 +130,7 @@ 3DBAC9E92B4C8927005F8764 /* ItemPersonIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemPersonIconView.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 = ""; }; + 3DD6850B2B85A6A8002FAA1A /* BindingNot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BindingNot.swift; sourceTree = ""; }; 3DDD67922B293BC40026781E /* DashboardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardView.swift; sourceTree = ""; }; 3DDD67952B29E28B0026781E /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; 3DDF35D42B7D384000423923 /* ItemSeriesEpisodesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemSeriesEpisodesView.swift; sourceTree = ""; }; @@ -189,23 +191,10 @@ 3D1015E32B28000E00F5C29A /* AuthStateController.swift */, 3DF1ED3D2B282836000AD8EA /* JellyfinClientController.swift */, 3DC6BA2C2B2A422300416B9F /* SettingsController.swift */, - 3DBAC9E32B4C7404005F8764 /* UIScreenCurrent.swift */, ); path = Controllers; sourceTree = ""; }; - 3D1015E02B27FE5700F5C29A /* Models */ = { - isa = PBXGroup; - children = ( - 3D91FDCC2B2907E800919017 /* JellyfinDateFormatter.swift */, - 3D8AB2A42B36440D005BD7D0 /* BlurHashDecode.swift */, - 3DAFA8E92B39039900D71AD1 /* JellyfinKitExtensions.swift */, - 3DAFA8EB2B394F9F00D71AD1 /* ViewExtensions.swift */, - 3D74AE112B7D4EB000C17F2E /* UIScreenWidthExtension.swift */, - ); - path = Models; - sourceTree = ""; - }; 3D13F95D2B375DAC00E91913 /* Item */ = { isa = PBXGroup; children = ( @@ -274,7 +263,7 @@ 3D9063C92B279A310063DD2A /* Jel */ = { isa = PBXGroup; children = ( - 3D1015E02B27FE5700F5C29A /* Models */, + 3DD6850A2B85A654002FAA1A /* Extensions */, 3D1015DF2B27F8EE00F5C29A /* Controllers */, 3D1015D72B27F54A00F5C29A /* Views */, 3D9063CA2B279A310063DD2A /* JelApp.swift */, @@ -341,6 +330,20 @@ path = Person; sourceTree = ""; }; + 3DD6850A2B85A654002FAA1A /* Extensions */ = { + isa = PBXGroup; + children = ( + 3DBAC9E32B4C7404005F8764 /* UIScreenCurrent.swift */, + 3D91FDCC2B2907E800919017 /* JellyfinDateFormatter.swift */, + 3D8AB2A42B36440D005BD7D0 /* BlurHashDecode.swift */, + 3DAFA8E92B39039900D71AD1 /* JellyfinKitExtensions.swift */, + 3DAFA8EB2B394F9F00D71AD1 /* ViewExtensions.swift */, + 3D74AE112B7D4EB000C17F2E /* UIScreenWidthExtension.swift */, + 3DD6850B2B85A6A8002FAA1A /* BindingNot.swift */, + ); + path = Extensions; + sourceTree = ""; + }; 3DDD67902B293B780026781E /* Dashboard */ = { isa = PBXGroup; children = ( @@ -522,6 +525,7 @@ 3DAFA8EF2B3B707B00D71AD1 /* ItemMovieView.swift in Sources */, 3D8AB2A82B366353005BD7D0 /* LibraryDetailView.swift in Sources */, 3DDD67932B293BC40026781E /* DashboardView.swift in Sources */, + 3DD6850C2B85A6A8002FAA1A /* BindingNot.swift in Sources */, 3D13F9612B37637500E91913 /* ItemMediaView.swift in Sources */, 3D2552492B7A8B3100192879 /* ItemSeriesSeasonsView.swift in Sources */, 3DFE7AF72B5260FF005461FE /* ItemPersonView.swift in Sources */, diff --git a/Jel/Controllers/AuthStateController.swift b/Jel/Controllers/AuthStateController.swift index d117820..11aacbf 100644 --- a/Jel/Controllers/AuthStateController.swift +++ b/Jel/Controllers/AuthStateController.swift @@ -14,6 +14,8 @@ class AuthStateController: ObservableObject { @Published var userId: String? @Published var username: String? + @Published var loaded: Bool = false + private let defaults = UserDefaults.standard static let shared = AuthStateController() @@ -40,6 +42,8 @@ class AuthStateController: ObservableObject { if let oldUsername = defaults.string(forKey: "AuthState_username") { self.username = oldUsername } + + self.loaded = true } func save() { diff --git a/Jel/Extensions/BindingNot.swift b/Jel/Extensions/BindingNot.swift new file mode 100644 index 0000000..92951b5 --- /dev/null +++ b/Jel/Extensions/BindingNot.swift @@ -0,0 +1,18 @@ +// +// BindingNot.swift +// Jel +// +// Created by zerocool on 2/20/24. +// + +import Foundation +import SwiftUI + +extension Binding where Value == Bool { + var not: Binding { + Binding( + get: { !self.wrappedValue }, + set: { self.wrappedValue = !$0 } + ) + } +} diff --git a/Jel/Models/BlurHashDecode.swift b/Jel/Extensions/BlurHashDecode.swift similarity index 100% rename from Jel/Models/BlurHashDecode.swift rename to Jel/Extensions/BlurHashDecode.swift diff --git a/Jel/Models/JellyfinDateFormatter.swift b/Jel/Extensions/JellyfinDateFormatter.swift similarity index 100% rename from Jel/Models/JellyfinDateFormatter.swift rename to Jel/Extensions/JellyfinDateFormatter.swift diff --git a/Jel/Models/JellyfinKitExtensions.swift b/Jel/Extensions/JellyfinKitExtensions.swift similarity index 100% rename from Jel/Models/JellyfinKitExtensions.swift rename to Jel/Extensions/JellyfinKitExtensions.swift diff --git a/Jel/Controllers/UIScreenCurrent.swift b/Jel/Extensions/UIScreenCurrent.swift similarity index 100% rename from Jel/Controllers/UIScreenCurrent.swift rename to Jel/Extensions/UIScreenCurrent.swift diff --git a/Jel/Models/UIScreenWidthExtension.swift b/Jel/Extensions/UIScreenWidthExtension.swift similarity index 100% rename from Jel/Models/UIScreenWidthExtension.swift rename to Jel/Extensions/UIScreenWidthExtension.swift diff --git a/Jel/Models/ViewExtensions.swift b/Jel/Extensions/ViewExtensions.swift similarity index 100% rename from Jel/Models/ViewExtensions.swift rename to Jel/Extensions/ViewExtensions.swift diff --git a/Jel/Views/ContentView.swift b/Jel/Views/ContentView.swift index 6c5ec59..3983392 100644 --- a/Jel/Views/ContentView.swift +++ b/Jel/Views/ContentView.swift @@ -9,22 +9,39 @@ import SwiftUI import PulseUI struct ContentView: View { - @EnvironmentObject var jellyfinClient: JellyfinClientController - - @StateObject var settingsController: SettingsController = SettingsController.shared - @StateObject var authState: AuthStateController = AuthStateController.shared - @State var showingConsoleSheet: Bool = false + @State var isSignedIn: Bool = true + var body: some View { VStack { - if !authState.loggedIn { - SignInView() - } else { + if isSignedIn { NavigationStack { DashboardView() } + } else { + VStack { + Text("You are not currently signed into a Jellyfin instance.") + .padding() + Button { + // toggle logged in so that it invalidates isSignedIn + authState.loggedIn = true + authState.loggedIn = false + } label: { + Text("Sign in") + } + } } } + .sheet(isPresented: $isSignedIn.not) { + SignInView() + .interactiveDismissDisabled() + } + .onChange(of: authState.loggedIn, { + isSignedIn = authState.loggedIn + }) + .onChange(of: authState.loaded, { + isSignedIn = authState.loggedIn + }) } } diff --git a/Jel/Views/Dashboard/DashboardLibraryView.swift b/Jel/Views/Dashboard/DashboardLibraryView.swift index 0510113..dc5189e 100644 --- a/Jel/Views/Dashboard/DashboardLibraryView.swift +++ b/Jel/Views/Dashboard/DashboardLibraryView.swift @@ -11,7 +11,7 @@ import JellyfinKit struct DashboardLibraryView: View { @EnvironmentObject var jellyfinClient: JellyfinClientController - @StateObject var authState: AuthStateController = AuthStateController.shared + @ObservedObject var authState: AuthStateController = AuthStateController.shared @State var libraries: [BaseItemDto] = [] @State var loading: Bool = true diff --git a/Jel/Views/Dashboard/DashboardView.swift b/Jel/Views/Dashboard/DashboardView.swift index 5ad25f8..931a884 100644 --- a/Jel/Views/Dashboard/DashboardView.swift +++ b/Jel/Views/Dashboard/DashboardView.swift @@ -10,6 +10,8 @@ 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 { @@ -37,6 +39,9 @@ struct DashboardView: View { .sheet(isPresented: $showingSettingsSheet) { SettingsView(showingSettingsView: $showingSettingsSheet) } + .onChange(of: authState.loggedIn, { + refresh = !authState.loggedIn + }) } } diff --git a/Jel/Views/Item/ItemGenresView.swift b/Jel/Views/Item/ItemGenresView.swift index 4e8321f..d775257 100644 --- a/Jel/Views/Item/ItemGenresView.swift +++ b/Jel/Views/Item/ItemGenresView.swift @@ -11,7 +11,7 @@ import JellyfinKit struct ItemGenresView: View { @EnvironmentObject var jellyfinClient: JellyfinClientController - @StateObject var authState: AuthStateController = AuthStateController.shared + @ObservedObject var authState: AuthStateController = AuthStateController.shared var item: BaseItemDto @State var libraryItems: [BaseItemDto]? = [] diff --git a/Jel/Views/Item/Person/ItemPersonDetailView.swift b/Jel/Views/Item/Person/ItemPersonDetailView.swift index 5e0bddf..cfb222a 100644 --- a/Jel/Views/Item/Person/ItemPersonDetailView.swift +++ b/Jel/Views/Item/Person/ItemPersonDetailView.swift @@ -9,7 +9,7 @@ import SwiftUI import JellyfinKit struct ItemPersonDetailView: View { - @StateObject var authState: AuthStateController = AuthStateController.shared + @ObservedObject var authState: AuthStateController = AuthStateController.shared @EnvironmentObject var jellyfinClient: JellyfinClientController var person: BaseItemPerson diff --git a/Jel/Views/Item/Person/ItemPersonIconView.swift b/Jel/Views/Item/Person/ItemPersonIconView.swift index b839deb..5b4c33c 100644 --- a/Jel/Views/Item/Person/ItemPersonIconView.swift +++ b/Jel/Views/Item/Person/ItemPersonIconView.swift @@ -25,7 +25,7 @@ struct ItemPersonIconPlaceholderView: View { } struct ItemPersonIconView: View { - @StateObject var authState: AuthStateController = AuthStateController.shared + @ObservedObject var authState: AuthStateController = AuthStateController.shared @EnvironmentObject var jellyfinClient: JellyfinClientController var person: BaseItemPerson diff --git a/Jel/Views/Item/Series/ItemSeriesEpisodesView.swift b/Jel/Views/Item/Series/ItemSeriesEpisodesView.swift index ae473ef..2588515 100644 --- a/Jel/Views/Item/Series/ItemSeriesEpisodesView.swift +++ b/Jel/Views/Item/Series/ItemSeriesEpisodesView.swift @@ -10,7 +10,7 @@ import JellyfinKit struct ItemSeriesEpisodesView: View { @EnvironmentObject var jellyfinClient: JellyfinClientController - @StateObject var authState: AuthStateController = AuthStateController.shared + @ObservedObject var authState: AuthStateController = AuthStateController.shared var item: BaseItemDto diff --git a/Jel/Views/Item/Series/ItemSeriesSeasonsView.swift b/Jel/Views/Item/Series/ItemSeriesSeasonsView.swift index a559174..d5c269b 100644 --- a/Jel/Views/Item/Series/ItemSeriesSeasonsView.swift +++ b/Jel/Views/Item/Series/ItemSeriesSeasonsView.swift @@ -12,7 +12,7 @@ struct ItemSeriesSeasonsView: View { var item: BaseItemDto @EnvironmentObject var jellyfinClient: JellyfinClientController - @StateObject var authState: AuthStateController = AuthStateController.shared + @ObservedObject var authState: AuthStateController = AuthStateController.shared @State var seriesItems: [BaseItemDto] = [] diff --git a/Jel/Views/Library/LibraryDetailView.swift b/Jel/Views/Library/LibraryDetailView.swift index c75cf39..dbc03d3 100644 --- a/Jel/Views/Library/LibraryDetailView.swift +++ b/Jel/Views/Library/LibraryDetailView.swift @@ -10,7 +10,7 @@ import JellyfinKit struct LibraryDetailView: View { @EnvironmentObject var jellyfinClient: JellyfinClientController - @StateObject var authState: AuthStateController = AuthStateController.shared + @ObservedObject var authState: AuthStateController = AuthStateController.shared @State var library: BaseItemDto @State var items: [BaseItemDto]? = [] diff --git a/Jel/Views/Settings/SettingsView.swift b/Jel/Views/Settings/SettingsView.swift index cff1fc3..8cd5a8a 100644 --- a/Jel/Views/Settings/SettingsView.swift +++ b/Jel/Views/Settings/SettingsView.swift @@ -11,9 +11,9 @@ import PulseUI struct SettingsView: View { @Binding var showingSettingsView: Bool - @StateObject var authState: AuthStateController = AuthStateController.shared - + @ObservedObject var authState: AuthStateController = AuthStateController.shared @ObservedObject var settingsController: SettingsController = SettingsController.shared + var body: some View { NavigationStack { Form { @@ -35,7 +35,11 @@ struct SettingsView: View { Button(role: .destructive) { authState.loggedIn = false + authState.authToken = nil authState.save() + + showingSettingsView.toggle() + settingsController.save() } label: { Text("Sign out") } diff --git a/Jel/Views/SignIn/AddServerView.swift b/Jel/Views/SignIn/AddServerView.swift index 40c2312..01d4a49 100644 --- a/Jel/Views/SignIn/AddServerView.swift +++ b/Jel/Views/SignIn/AddServerView.swift @@ -12,7 +12,7 @@ struct AddServerView: View { @ObservedObject var authState: AuthStateController = AuthStateController.shared @Binding var serverUrlIsValid: Bool - @State var serverUrlString: String = "http://" + @State var serverUrlString: String = "" @State var urlHasError: Bool = false @State var currentErrorMessage: String = "" @State var isLoading: Bool = false @@ -25,7 +25,7 @@ struct AddServerView: View { .font(.title) HStack { TextField(text: $serverUrlString) { - Text("http://jellyfin.example.com") + Text(verbatim: "https://jellyfin.example.com") } .keyboardType(.URL) .textContentType(.URL) @@ -102,7 +102,7 @@ struct AddServerView: View { } -#Preview { - AddServerView(serverUrlIsValid: .constant(false)) - -} +//#Preview { +// AddServerView(serverUrlIsValid: .constant(false)) +// +//} diff --git a/Jel/Views/SignIn/SignInToServerView.swift b/Jel/Views/SignIn/SignInToServerView.swift index 259e54d..18907a5 100644 --- a/Jel/Views/SignIn/SignInToServerView.swift +++ b/Jel/Views/SignIn/SignInToServerView.swift @@ -10,7 +10,7 @@ import SwiftUI struct SignInToServerView: View { @EnvironmentObject var jellyfinClient: JellyfinClientController - @StateObject var authState: AuthStateController = AuthStateController.shared + @ObservedObject var authState: AuthStateController = AuthStateController.shared @State var username: String = "" @State var password: String = "" diff --git a/Jel/Views/SignIn/SignInView.swift b/Jel/Views/SignIn/SignInView.swift index 729b34b..f3e2675 100644 --- a/Jel/Views/SignIn/SignInView.swift +++ b/Jel/Views/SignIn/SignInView.swift @@ -11,9 +11,8 @@ import PulseUI struct SignInView: View { @EnvironmentObject var jellyfinClient: JellyfinClientController - @StateObject var authState: AuthStateController = AuthStateController.shared + @ObservedObject var authState: AuthStateController = AuthStateController.shared @State var serverUrlIsValid: Bool = false - @State var showingConsoleSheet: Bool = false var body: some View { NavigationStack { @@ -40,6 +39,6 @@ struct SignInView: View { } } -#Preview { - SignInView() -} +//#Preview { +// SignInView() +//}