diff --git a/Sources/Integration/Session/Session+Contacts.swift b/Sources/Integration/Session/Session+Contacts.swift index fa27fe2ece740c14217d809d8bab6fd48fae670a..3f6a27711512043b3677b0c54fcc68265a72192e 100644 --- a/Sources/Integration/Session/Session+Contacts.swift +++ b/Sources/Integration/Session/Session+Contacts.swift @@ -118,29 +118,41 @@ extension Session { } public func add(_ contact: Contact) throws { + /// Make sure we are not adding ourselves + /// guard contact.username != username else { throw NSError.create("You can't add yourself") } - var contactToOperate: Contact! + var contact = contact - if [.requestFailed, .confirmationFailed, .stranger].contains(contact.authStatus) { - contactToOperate = contact + /// Check if this contact is actually + /// being requested/confirmed after failing + /// + if [.requestFailed, .confirmationFailed].contains(contact.authStatus) { + /// If it is being re-requested or + /// re-confirmed, no need to save again + /// + contact.createdAt = Date() + + if contact.authStatus == .confirmationFailed { + try confirm(contact) + return + } } else { + /// If its not failed, lets make sure that + /// this is an actual new contact + /// if let _ = try? dbManager.fetchContacts(.init(id: [contact.id])).first { + /// Found a user w/ that id already stored + /// throw NSError.create("This user has already been requested") } - contactToOperate = try dbManager.saveContact(contact) + contact.authStatus = .requesting } - guard contactToOperate.authStatus != .confirmationFailed else { - contactToOperate.createdAt = Date() - try confirm(contact) - return - } - - contactToOperate.authStatus = .requesting + contact = try dbManager.saveContact(contact) let myself = client.bindings.meMarshalled( username!, @@ -148,22 +160,23 @@ extension Session { phone: isSharingPhone ? phone : nil ) - client.bindings.add(contactToOperate.marshaled!, from: myself) { [weak self, contactToOperate] in - guard let self = self, var contactToOperate = contactToOperate else { return } + client.bindings.add(contact.marshaled!, from: myself) { [weak self, contact] in + guard let self = self else { return } + var contact = contact do { switch $0 { case .success(let success): - contactToOperate.authStatus = success ? .requested : .requestFailed - contactToOperate = try self.dbManager.saveContact(contactToOperate) + contact.authStatus = success ? .requested : .requestFailed + contact = try self.dbManager.saveContact(contact) case .failure: - contactToOperate.authStatus = .requestFailed - contactToOperate.createdAt = Date() - contactToOperate = try self.dbManager.saveContact(contactToOperate) + contact.createdAt = Date() + contact.authStatus = .requestFailed + contact = try self.dbManager.saveContact(contact) self.toastController.enqueueToast(model: .init( - title: Localized.Requests.Failed.toast(contactToOperate.nickname ?? contact.username!), + title: Localized.Requests.Failed.toast(contact.nickname ?? contact.username!), color: Asset.accentDanger.color, leftImage: Asset.requestFailedToaster.image )) diff --git a/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift b/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift index 3789428ffa0a9539e35b3344fdd820ee896d03a2..313a3694ac8498710b4847c501f41a7889c6535a 100644 --- a/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift +++ b/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift @@ -3,6 +3,7 @@ import UIKit import Models import Shared import Combine +import XXModels import Integration import ToastFeature import CombineSchedulers @@ -32,7 +33,12 @@ final class RequestsSentViewModel { var backgroundScheduler: AnySchedulerOf<DispatchQueue> = DispatchQueue.global().eraseToAnyScheduler() init() { - session.dbManager.fetchContactsPublisher(.init(authStatus: [.requested])) + let query = Contact.Query(authStatus: [ + .requested, + .requesting + ]) + + session.dbManager.fetchContactsPublisher(query) .assertNoFailure() .removeDuplicates() .map { data -> NSDiffableDataSourceSnapshot<Section, RequestSent> in diff --git a/Sources/SearchFeature/ViewModels/SearchViewModel.swift b/Sources/SearchFeature/ViewModels/SearchViewModel.swift index 7b52fb9762f47cfab9d17f2fd02383560be228bd..5dae23c8883eeccafb3a66ac2c3dd339d45d1094 100644 --- a/Sources/SearchFeature/ViewModels/SearchViewModel.swift +++ b/Sources/SearchFeature/ViewModels/SearchViewModel.swift @@ -163,12 +163,9 @@ final class SearchViewModel { } func didSet(nickname: String, for contact: Contact) { - var contact = contact - contact.nickname = nickname - - backgroundScheduler.schedule { [weak self] in - guard let self = self else { return } - _ = try? self.session.dbManager.saveContact(contact) + if var contact = try? session.dbManager.fetchContacts(.init(id: [contact.id])).first { + contact.nickname = nickname + _ = try? session.dbManager.saveContact(contact) } }