From 34bca1c8fac4ace7fb2189e2ad7fda4e6a6f647d Mon Sep 17 00:00:00 2001 From: Justin Mazzocchi <2831158+jzzocc@users.noreply.github.com> Date: Wed, 9 Sep 2020 17:52:46 -0700 Subject: [PATCH] Refactoring --- Localizations/Localizable.strings | 1 + .../ViewModels/AddIdentityViewModel.swift | 109 ++++++++---------- Views/AddIdentityView.swift | 6 + 3 files changed, 56 insertions(+), 60 deletions(-) diff --git a/Localizations/Localizable.strings b/Localizations/Localizable.strings index 7774361..5e02fa3 100644 --- a/Localizations/Localizable.strings +++ b/Localizations/Localizable.strings @@ -5,6 +5,7 @@ "add-identity.instance-url" = "Instance URL"; "add-identity.log-in" = "Log in"; "add-identity.browse-anonymously" = "Browse anonymously"; +"add-identity.unable-to-connect-to-instance" = "Unable to connect to instance"; "secondary-navigation.manage-accounts" = "Manage Accounts"; "secondary-navigation.lists" = "Lists"; "secondary-navigation.preferences" = "Preferences"; diff --git a/ViewModels/Sources/ViewModels/AddIdentityViewModel.swift b/ViewModels/Sources/ViewModels/AddIdentityViewModel.swift index 955b9aa..b1d7a6a 100644 --- a/ViewModels/Sources/ViewModels/AddIdentityViewModel.swift +++ b/ViewModels/Sources/ViewModels/AddIdentityViewModel.swift @@ -4,6 +4,10 @@ import Combine import Foundation import ServiceLayer +public enum AddIdentityError: Error { + case unableToConnectToInstance +} + public final class AddIdentityViewModel: ObservableObject { @Published public var urlFieldText = "" @Published public var alertItem: AlertItem? @@ -24,24 +28,61 @@ public final class AddIdentityViewModel: ObservableObject { public extension AddIdentityViewModel { func logInTapped() { - let identityID = UUID() - let instanceURL: URL + addIdentity(authenticated: true) + } - do { - instanceURL = try checkedURL() - } catch { - alertItem = AlertItem(error: error) + func browseAnonymouslyTapped() { + addIdentity(authenticated: false) + } + + func refreshFilter() { + instanceFilterService.updateFilter() + .sink { _ in } + .store(in: &cancellables) + } +} + +private extension AddIdentityViewModel { + private static let filteredURL = URL(string: "https://filtered")! + private static let HTTPSPrefix = "https://" + + func addIdentity(authenticated: Bool) { + let identityID = UUID() + let url: URL + + if urlFieldText.hasPrefix(Self.HTTPSPrefix), let prefixedURL = URL(string: urlFieldText) { + url = prefixedURL + } else if let unprefixedURL = URL(string: Self.HTTPSPrefix + urlFieldText) { + url = unprefixedURL + } else { + alertItem = AlertItem(error: AddIdentityError.unableToConnectToInstance) return } - allIdentitiesService.createIdentity(id: identityID, url: instanceURL, authenticated: true) + if instanceFilterService.isFiltered(url: url) { + loading = true + + DispatchQueue.main.asyncAfter(deadline: .now() + .random(in: 0.01...0.1)) { + self.alertItem = AlertItem(error: AddIdentityError.unableToConnectToInstance) + self.loading = false + } + + return + } + + allIdentitiesService.createIdentity( + id: identityID, + url: url, + authenticated: authenticated) .receive(on: DispatchQueue.main) .catch { [weak self] error -> Empty in if case AuthenticationError.canceled = error { // no-op } else { - self?.alertItem = AlertItem(error: error) + let displayedError = error is URLError ? AddIdentityError.unableToConnectToInstance : error + + self?.alertItem = AlertItem(error: displayedError) } return Empty() @@ -58,56 +99,4 @@ public extension AddIdentityViewModel { } receiveValue: { _ in } .store(in: &cancellables) } - - func browseAnonymouslyTapped() { - let identityID = UUID() - let instanceURL: URL - - do { - instanceURL = try checkedURL() - } catch { - alertItem = AlertItem(error: error) - - return - } - - // TODO: Ensure instance has not disabled public preview - allIdentitiesService.createIdentity(id: identityID, url: instanceURL, authenticated: false) - .assignErrorsToAlertItem(to: \.alertItem, on: self) - .sink { [weak self] in - guard let self = self, case .finished = $0 else { return } - - self.addedIdentityIDSubject.send(identityID) - } receiveValue: { _ in } - .store(in: &cancellables) - } - - func refreshFilter() { - instanceFilterService.updateFilter() - .sink { _ in } - .store(in: &cancellables) - } -} - -private extension AddIdentityViewModel { - private static let filteredURL = URL(string: "https://filtered")! - private static let HTTPSPrefix = "https://" - - func checkedURL() throws -> URL { - let url: URL - - if urlFieldText.hasPrefix(Self.HTTPSPrefix), let prefixedURL = URL(string: urlFieldText) { - url = prefixedURL - } else if let unprefixedURL = URL(string: Self.HTTPSPrefix + urlFieldText) { - url = unprefixedURL - } else { - throw URLError(.badURL) - } - - if instanceFilterService.isFiltered(url: url) { - return Self.filteredURL - } - - return url - } } diff --git a/Views/AddIdentityView.swift b/Views/AddIdentityView.swift index 8b3a817..5d9fcaa 100644 --- a/Views/AddIdentityView.swift +++ b/Views/AddIdentityView.swift @@ -41,6 +41,12 @@ extension AddIdentityView { } } +extension AddIdentityError: LocalizedError { + public var errorDescription: String? { + NSLocalizedString("add-identity.unable-to-connect-to-instance", comment: "") + } +} + #if DEBUG import PreviewViewModels