Refactoring

This commit is contained in:
Justin Mazzocchi 2020-09-10 17:24:12 -07:00
parent 36d809fc85
commit 1d425a97f0
No known key found for this signature in database
GPG Key ID: E223E6937AAFB01C
2 changed files with 44 additions and 41 deletions

View File

@ -18,16 +18,24 @@ public struct InstanceURLService {
} }
public extension InstanceURLService { public extension InstanceURLService {
static func url(text: String) -> URL? { func url(text: String) -> URL? {
guard text.count >= shortestPossibleURLLength else { return nil } guard text.count >= Self.shortestPossibleURLLength else { return nil }
if text.hasPrefix(httpsPrefix), let prefixedURL = URL(string: text) { let url: URL
return prefixedURL
} else if let unprefixedURL = URL(string: httpsPrefix + text) { if text.hasPrefix(Self.httpsPrefix), let prefixedURL = URL(string: text) {
return unprefixedURL 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<Instance?, Never> { func instance(url: URL) -> AnyPublisher<Instance?, Never> {
@ -52,23 +60,6 @@ public extension InstanceURLService {
.eraseToAnyPublisher() .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<Never, Never> { func updateFilter() -> AnyPublisher<Never, Never> {
httpClient.request(UpdatedFilterTarget()) httpClient.request(UpdatedFilterTarget())
.handleEvents(receiveOutput: { userDefaultsClient.updatedInstanceFilter = $0 }) .handleEvents(receiveOutput: { userDefaultsClient.updatedInstanceFilter = $0 })
@ -104,4 +95,21 @@ private extension InstanceURLService {
var filter: BloomFilter<String> { var filter: BloomFilter<String> {
userDefaultsClient.updatedInstanceFilter ?? Self.defaultFilter 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
}
} }

View File

@ -28,17 +28,23 @@ public final class AddIdentityViewModel: ObservableObject {
addedIdentityID = addedIdentityIDSubject.eraseToAnyPublisher() addedIdentityID = addedIdentityIDSubject.eraseToAnyPublisher()
let url = $urlFieldText let url = $urlFieldText
.debounce(for: 0.5, scheduler: DispatchQueue.main) .debounce(for: 0.5, scheduler: DispatchQueue.global())
.removeDuplicates() .removeDuplicates()
.compactMap(InstanceURLService.url(text:)) .map(instanceURLService.url(text:))
.filter { !instanceURLService.isFiltered(url: $0) }
.share() .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) .receive(on: DispatchQueue.main)
.assign(to: &$instance) .assign(to: &$instance)
url.flatMap(instanceURLService.isPublicTimelineAvailable(url:)) url.compactMap { $0 }
.flatMap(instanceURLService.isPublicTimelineAvailable(url:))
.combineLatest(urlPresent)
.map { $0 && $1 }
.receive(on: DispatchQueue.main) .receive(on: DispatchQueue.main)
.assign(to: &$isPublicTimelineAvailable) .assign(to: &$isPublicTimelineAvailable)
} }
@ -64,23 +70,12 @@ private extension AddIdentityViewModel {
func addIdentity(authenticated: Bool) { func addIdentity(authenticated: Bool) {
let identityID = UUID() let identityID = UUID()
guard let url = InstanceURLService.url(text: urlFieldText) else { guard let url = instanceURLService.url(text: urlFieldText) else {
alertItem = AlertItem(error: AddIdentityError.unableToConnectToInstance) alertItem = AlertItem(error: AddIdentityError.unableToConnectToInstance)
return 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( allIdentitiesService.createIdentity(
id: identityID, id: identityID,
url: url, url: url,