diff --git a/ServiceLayer/Sources/ServiceLayer/Services/InstanceURLService.swift b/ServiceLayer/Sources/ServiceLayer/Services/InstanceURLService.swift index 6c09806..d69d9aa 100644 --- a/ServiceLayer/Sources/ServiceLayer/Services/InstanceURLService.swift +++ b/ServiceLayer/Sources/ServiceLayer/Services/InstanceURLService.swift @@ -18,16 +18,24 @@ public struct InstanceURLService { } public extension InstanceURLService { - static func url(text: String) -> URL? { - guard text.count >= shortestPossibleURLLength else { return nil } + func url(text: String) -> URL? { + guard text.count >= Self.shortestPossibleURLLength else { return nil } - if text.hasPrefix(httpsPrefix), let prefixedURL = URL(string: text) { - return prefixedURL - } else if let unprefixedURL = URL(string: httpsPrefix + text) { - return unprefixedURL + let url: URL + + if text.hasPrefix(Self.httpsPrefix), let prefixedURL = URL(string: text) { + url = prefixedURL + } else if let unprefixedURL = URL(string: Self.httpsPrefix + text) { + url = unprefixedURL + } else { + return nil } - return nil + if isFiltered(url: url) { + return nil + } + + return url } func instance(url: URL) -> AnyPublisher { @@ -52,23 +60,6 @@ public extension InstanceURLService { .eraseToAnyPublisher() } - func isFiltered(url: URL) -> Bool { - guard let host = url.host else { return true } - - let allHostComponents = host.components(separatedBy: ".") - var hostComponents = [String]() - - for component in allHostComponents.reversed() { - hostComponents.insert(component, at: 0) - - if filter.contains(hostComponents.joined(separator: ".")) { - return true - } - } - - return false - } - func updateFilter() -> AnyPublisher { httpClient.request(UpdatedFilterTarget()) .handleEvents(receiveOutput: { userDefaultsClient.updatedInstanceFilter = $0 }) @@ -104,4 +95,21 @@ private extension InstanceURLService { var filter: BloomFilter { userDefaultsClient.updatedInstanceFilter ?? Self.defaultFilter } + + private func isFiltered(url: URL) -> Bool { + guard let host = url.host else { return true } + + let allHostComponents = host.components(separatedBy: ".") + var hostComponents = [String]() + + for component in allHostComponents.reversed() { + hostComponents.insert(component, at: 0) + + if filter.contains(hostComponents.joined(separator: ".")) { + return true + } + } + + return false + } } diff --git a/ViewModels/Sources/ViewModels/AddIdentityViewModel.swift b/ViewModels/Sources/ViewModels/AddIdentityViewModel.swift index 6f1324f..ad4ef71 100644 --- a/ViewModels/Sources/ViewModels/AddIdentityViewModel.swift +++ b/ViewModels/Sources/ViewModels/AddIdentityViewModel.swift @@ -28,17 +28,23 @@ public final class AddIdentityViewModel: ObservableObject { addedIdentityID = addedIdentityIDSubject.eraseToAnyPublisher() let url = $urlFieldText - .debounce(for: 0.5, scheduler: DispatchQueue.main) + .debounce(for: 0.5, scheduler: DispatchQueue.global()) .removeDuplicates() - .compactMap(InstanceURLService.url(text:)) - .filter { !instanceURLService.isFiltered(url: $0) } + .map(instanceURLService.url(text:)) .share() + let urlPresent = url.map { $0 != nil }.share() - url.flatMap(instanceURLService.instance(url:)) + url.compactMap { $0 } + .flatMap(instanceURLService.instance(url:)) + .combineLatest(urlPresent) + .map { $1 ? $0 : nil } .receive(on: DispatchQueue.main) .assign(to: &$instance) - url.flatMap(instanceURLService.isPublicTimelineAvailable(url:)) + url.compactMap { $0 } + .flatMap(instanceURLService.isPublicTimelineAvailable(url:)) + .combineLatest(urlPresent) + .map { $0 && $1 } .receive(on: DispatchQueue.main) .assign(to: &$isPublicTimelineAvailable) } @@ -64,23 +70,12 @@ private extension AddIdentityViewModel { func addIdentity(authenticated: Bool) { let identityID = UUID() - guard let url = InstanceURLService.url(text: urlFieldText) else { + guard let url = instanceURLService.url(text: urlFieldText) else { alertItem = AlertItem(error: AddIdentityError.unableToConnectToInstance) return } - if instanceURLService.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,