diff --git a/apps/ios/Shared/ContentView.swift b/apps/ios/Shared/ContentView.swift index fd9a70e0e..b9e7fb066 100644 --- a/apps/ios/Shared/ContentView.swift +++ b/apps/ios/Shared/ContentView.swift @@ -55,7 +55,7 @@ final class AlertManager: ObservableObject { func showAlert(_ alert: Alert) { logger.debug("AlertManager.showAlert") - DispatchQueue.main.async { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { self.alertView = alert self.presentAlert = true } diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index 2182bc13c..68f38e423 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -121,6 +121,7 @@ enum ChatResponse: Decodable, Error { case invitation(connReqInvitation: String) case sentConfirmation case sentInvitation + case contactAlreadyExists(contact: Contact) case contactDeleted(contact: Contact) case userProfileNoChange case userProfileUpdated(fromProfile: Profile, toProfile: Profile) @@ -161,6 +162,7 @@ enum ChatResponse: Decodable, Error { case .invitation: return "invitation" case .sentConfirmation: return "sentConfirmation" case .sentInvitation: return "sentInvitation" + case .contactAlreadyExists: return "contactAlreadyExists" case .contactDeleted: return "contactDeleted" case .userProfileNoChange: return "userProfileNoChange" case .userProfileUpdated: return "userProfileUpdated" @@ -204,6 +206,7 @@ enum ChatResponse: Decodable, Error { case let .invitation(connReqInvitation): return connReqInvitation case .sentConfirmation: return noDetails case .sentInvitation: return noDetails + case let .contactAlreadyExists(contact): return String(describing: contact) case let .contactDeleted(contact): return String(describing: contact) case .userProfileNoChange: return noDetails case let .userProfileUpdated(_, toProfile): return String(describing: toProfile) @@ -435,11 +438,36 @@ func apiAddContact() throws -> String { throw r } -func apiConnect(connReq: String) async throws { +func apiConnect(connReq: String) async throws -> Bool { let r = await chatSendCmd(.connect(connReq: connReq)) + let am = AlertManager.shared switch r { - case .sentConfirmation: return - case .sentInvitation: return + case .sentConfirmation: return true + case .sentInvitation: return true + case let .contactAlreadyExists(contact): + am.showAlertMsg( + title: "Contact already exists", + message: "You are already connected to \(contact.displayName) via this link." + ) + return false + case .chatCmdError(.error(.invalidConnReq)): + am.showAlertMsg( + title: "Invalid connection link", + message: "Please check that you used the correct link or ask your contact to send you another one." + ) + return false + case .chatCmdError(.errorAgent(.BROKER(.TIMEOUT))): + am.showAlertMsg( + title: "Connection timeout", + message: "Please check your network connection and try again" + ) + return false + case .chatCmdError(.errorAgent(.BROKER(.NETWORK))): + am.showAlertMsg( + title: "Connection error", + message: "Please check your network connection and try again" + ) + return false default: throw r } } diff --git a/apps/ios/Shared/Views/ChatList/ChatListView.swift b/apps/ios/Shared/Views/ChatList/ChatListView.swift index 766784b0e..f74e94a95 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListView.swift @@ -89,8 +89,10 @@ struct ChatListView: View { DispatchQueue.main.async { Task { do { - try await apiConnect(connReq: link) - connectionReqSentAlert(action == "contact" ? .contact : .invitation) + let ok = try await apiConnect(connReq: link) + if ok { + connectionReqSentAlert(action == "contact" ? .contact : .invitation) + } } catch { let err = error.localizedDescription AlertManager.shared.showAlertMsg(title: "Connection error", message: err) diff --git a/apps/ios/Shared/Views/NewChat/ConnectContactView.swift b/apps/ios/Shared/Views/NewChat/ConnectContactView.swift index 5b2faa1a6..2513801fc 100644 --- a/apps/ios/Shared/Views/NewChat/ConnectContactView.swift +++ b/apps/ios/Shared/Views/NewChat/ConnectContactView.swift @@ -10,7 +10,7 @@ import SwiftUI import CodeScanner struct ConnectContactView: View { - var completed: ((Error?) -> Void) + var completed: ((Result) -> Void) var body: some View { VStack { @@ -35,16 +35,16 @@ struct ConnectContactView: View { case let .success(r): Task { do { - try await apiConnect(connReq: r.string) - completed(nil) + let ok = try await apiConnect(connReq: r.string) + completed(.success(ok)) } catch { logger.error("ConnectContactView.processQRCode apiConnect error: \(error.localizedDescription)") - completed(error) + completed(.failure(error)) } } case let .failure(e): logger.error("ConnectContactView.processQRCode QR code error: \(e.localizedDescription)") - completed(e) + completed(.failure(e)) } } } diff --git a/apps/ios/Shared/Views/NewChat/NewChatButton.swift b/apps/ios/Shared/Views/NewChat/NewChatButton.swift index d984ddd0d..0fff56bf3 100644 --- a/apps/ios/Shared/Views/NewChat/NewChatButton.swift +++ b/apps/ios/Shared/Views/NewChat/NewChatButton.swift @@ -54,10 +54,11 @@ struct NewChatButton: View { ConnectContactView(completed: { err in connectContact = false DispatchQueue.global().async { - if let error = err { + switch (err) { + case let .success(ok): + if ok { connectionReqSentAlert(.invitation) } + case let .failure(error): connectionErrorAlert(error) - } else { - connectionReqSentAlert(.invitation) } } })