From fbb37567460b689f01eb8a8717b9ac8673652c28 Mon Sep 17 00:00:00 2001 From: Shav Kinderlehrer Date: Tue, 12 Dec 2023 17:09:15 -0500 Subject: Implement signIn flow --- Jel/Views/AddServerView.swift | 109 ------------------------------ Jel/Views/SignIn/AddServerView.swift | 108 +++++++++++++++++++++++++++++ Jel/Views/SignIn/SignInToServerView.swift | 79 ++++++++++++++++++++++ Jel/Views/SignIn/SignInView.swift | 42 ++++++++++++ 4 files changed, 229 insertions(+), 109 deletions(-) delete mode 100644 Jel/Views/AddServerView.swift create mode 100644 Jel/Views/SignIn/AddServerView.swift create mode 100644 Jel/Views/SignIn/SignInToServerView.swift create mode 100644 Jel/Views/SignIn/SignInView.swift (limited to 'Jel/Views') diff --git a/Jel/Views/AddServerView.swift b/Jel/Views/AddServerView.swift deleted file mode 100644 index beab5e7..0000000 --- a/Jel/Views/AddServerView.swift +++ /dev/null @@ -1,109 +0,0 @@ -// -// AddServerView.swift -// Jel -// -// Created by zerocool on 12/11/23. -// - -import SwiftUI - -struct AddServerView: View { - @ObservedObject var authState: AuthStateController - - @State var serverUrlString: String = "" - @State var urlHasError: Bool = false - @State var currentErrorMessage: String = "" - @State var loading: Bool = false - - @FocusState var serverUrlIsFocused: Bool - - var body: some View { - VStack { - Text("Connect to a server") - .font(.title) - HStack { - - TextField(text: $serverUrlString) { - Text("http://jellyfin.example.com") - .foregroundStyle(.placeholder) - } - .keyboardType(.URL) - .textContentType(.URL) - .textFieldStyle(.roundedBorder) - .textInputAutocapitalization(.never) - .autocorrectionDisabled() - .focused($serverUrlIsFocused) - .onChange(of: serverUrlIsFocused) { - if serverUrlIsFocused { - urlHasError = false - } - } - .onSubmit { - Task { - await checkServerUrl() - } - } - - - if !loading { - Button(action: { - Task { - await checkServerUrl() - } - }) { - Label("Connect", systemImage: "arrow.right") - .labelStyle(.iconOnly) - } - .buttonStyle(.bordered) - .disabled(urlHasError) - } else { - ProgressView() - .progressViewStyle(.circular) - .padding() - } - } - .padding() - - if urlHasError { - Text(currentErrorMessage) - .font(.callout) - .foregroundStyle(.red) - } - } - } - - func checkServerUrl() async { - loading = true - serverUrlIsFocused = false - if isValidUrl(data: serverUrlString) { - let url = URL(string: serverUrlString)! - if await JellyfinClientController(serverUrl: url).isJellyfinServer() { - authState.serverUrl = url - urlHasError = false - } else { - urlHasError = true - currentErrorMessage = "Server not responding" - } - - } else { - urlHasError = true - currentErrorMessage = "Invalid url" - } - - loading = false - } - - func isValidUrl(data: String) -> Bool { - if let url = URL(string: data) { - if UIApplication.shared.canOpenURL(url) { - return true - } - } - return false - } - -} - -#Preview { - AddServerView(authState: AuthStateController()) -} diff --git a/Jel/Views/SignIn/AddServerView.swift b/Jel/Views/SignIn/AddServerView.swift new file mode 100644 index 0000000..516b982 --- /dev/null +++ b/Jel/Views/SignIn/AddServerView.swift @@ -0,0 +1,108 @@ +// +// AddServerView.swift +// Jel +// +// Created by zerocool on 12/11/23. +// + +import SwiftUI + +struct AddServerView: View { + @EnvironmentObject var jellyfinClient: JellyfinClientController + @ObservedObject var authState: AuthStateController + @Binding var serverUrlIsValid: Bool + + @State var serverUrlString: String = "http://" + @State var urlHasError: Bool = false + @State var currentErrorMessage: String = "" + @State var isLoading: Bool = false + + @FocusState var serverUrlIsFocused: Bool + + var body: some View { + VStack { + Text("Connect to a server") + .font(.title) + HStack { + TextField(text: $serverUrlString) { + Text("http://jellyfin.example.com") + } + .keyboardType(.URL) + .textContentType(.URL) + .textFieldStyle(.roundedBorder) + .textInputAutocapitalization(.never) + .autocorrectionDisabled() + .focused($serverUrlIsFocused) + .onSubmit { + Task { + await checkServerUrl() + } + } + + + if !isLoading { + Button(action: { + Task { + await checkServerUrl() + } + }) { + Label("Connect", systemImage: "arrow.right") + .labelStyle(.iconOnly) + } + .buttonStyle(.bordered) + } else { + ProgressView() + .progressViewStyle(.circular) + .padding([.leading, .trailing]) + } + } + .padding() + .disabled(isLoading) + + if urlHasError { + Text(currentErrorMessage) + .font(.callout) + .foregroundStyle(.red) + } + } + } + + func checkServerUrl() async { + isLoading = true + serverUrlIsFocused = false + if isValidUrl(data: serverUrlString) { + let url = URL(string: serverUrlString)! + jellyfinClient.setUrl(url: url) + if await jellyfinClient.isJellyfinServer() { + authState.serverUrl = url + authState.save() + urlHasError = false + serverUrlIsValid = true + } else { + urlHasError = true + currentErrorMessage = "Server not responding" + } + + } else { + urlHasError = true + currentErrorMessage = "Invalid url" + } + + isLoading = false + } + + func isValidUrl(data: String) -> Bool { + if let url = URL(string: data) { + if UIApplication.shared.canOpenURL(url) { + return true + } + } + return false + } + +} + +#Preview { + AddServerView(authState: AuthStateController(), serverUrlIsValid: .constant(false)) + +} diff --git a/Jel/Views/SignIn/SignInToServerView.swift b/Jel/Views/SignIn/SignInToServerView.swift new file mode 100644 index 0000000..ae8d82d --- /dev/null +++ b/Jel/Views/SignIn/SignInToServerView.swift @@ -0,0 +1,79 @@ +// +// SignInToServerView.swift +// Jel +// +// Created by zerocool on 12/12/23. +// + +import SwiftUI + +struct SignInToServerView: View { + @EnvironmentObject var jellyfinClient: JellyfinClientController + @ObservedObject var authState: AuthStateController + + @State var username: String = "" + @State var password: String = "" + + @State var isLoading: Bool = false + @State var hasError: Bool = false + + var body: some View { + VStack { + Text("Sign in") + .font(.title) + TextField(text: $username) { + Text("Username") + } + .textContentType(.username) + + SecureField(text: $password) { + Text("Password") + } + .textContentType(.password) + .onSubmit { + Task { + await logInToServer() + } + } + + if !isLoading { + Button { + Task { + await logInToServer() + } + } label: { + Text("Sign in") + } + .disabled(username.isEmpty || password.isEmpty) + } else { + ProgressView() + .progressViewStyle(.circular) + } + + if hasError { + Text("Unable to sign in") + .font(.callout) + .foregroundStyle(.red) + } + } + .padding() + .textFieldStyle(.roundedBorder) + .textInputAutocapitalization(.never) + .disabled(isLoading) + } + + func logInToServer() async { + isLoading = true + hasError = false + do { + try await jellyfinClient.signIn(username: username, pw: password) + } catch { + hasError = true + } + isLoading = false + } +} + +#Preview { + SignInToServerView(authState: AuthStateController()) +} diff --git a/Jel/Views/SignIn/SignInView.swift b/Jel/Views/SignIn/SignInView.swift new file mode 100644 index 0000000..c06788d --- /dev/null +++ b/Jel/Views/SignIn/SignInView.swift @@ -0,0 +1,42 @@ +// +// SignInView.swift +// Jel +// +// Created by zerocool on 12/12/23. +// + +import SwiftUI + +struct SignInView: View { + @EnvironmentObject var jellyfinClient: JellyfinClientController + @ObservedObject var authState: AuthStateController + @State var serverUrlIsValid: Bool = false + + var body: some View { + NavigationStack { + AddServerView(authState: authState, serverUrlIsValid: $serverUrlIsValid) + .navigationDestination(isPresented: $serverUrlIsValid) { + SignInToServerView(authState: authState) + } + } + .onAppear { + Task { + await checkLoadedServerUrl() + } + } + } + + func checkLoadedServerUrl() async { + if authState.serverUrl == nil { + return + } + + if await jellyfinClient.isJellyfinServer() { + serverUrlIsValid = true + } + } +} + +#Preview { + SignInView(authState: AuthStateController()) +} -- cgit v1.2.3