diff --git a/apps/ios/Shared/Model/ChatModel.swift b/apps/ios/Shared/Model/ChatModel.swift index 13fe0737e2..62ff48c4a4 100644 --- a/apps/ios/Shared/Model/ChatModel.swift +++ b/apps/ios/Shared/Model/ChatModel.swift @@ -87,8 +87,8 @@ final class ChatModel: ObservableObject { @Published var showCallView = false // remote desktop @Published var remoteCtrlSession: RemoteCtrlSession? - // currently showing QR code - @Published var connReqInv: String? + // currently showing invitation connection id + @Published var invitationConnId: String? // audio recording and playback @Published var stopPreviousRecPlay: URL? = nil // coordinates currently playing source @Published var draft: ComposeState? @@ -620,10 +620,7 @@ final class ChatModel: ObservableObject { } func dismissConnReqView(_ id: String) { - if let connReqInv = connReqInv, - let c = getChat(id), - case let .contactConnection(contactConnection) = c.chatInfo, - connReqInv == contactConnection.connReqInv { + if id == invitationConnId { dismissAllSheets() } } diff --git a/apps/ios/Shared/Views/NewChat/AddContactView.swift b/apps/ios/Shared/Views/NewChat/AddContactView.swift index a48d91b922..bcfa138dd5 100644 --- a/apps/ios/Shared/Views/NewChat/AddContactView.swift +++ b/apps/ios/Shared/Views/NewChat/AddContactView.swift @@ -40,7 +40,7 @@ struct AddContactView: View { } } } - .onAppear { chatModel.connReqInv = connReqInvitation } + // .onAppear { chatModel.connReqInv = connReqInvitation } .onChange(of: incognitoDefault) { incognito in Task { do { diff --git a/apps/ios/Shared/Views/NewChat/CreateLinkView.swift b/apps/ios/Shared/Views/NewChat/CreateLinkView.swift index 75db9b3167..614b9dd0bd 100644 --- a/apps/ios/Shared/Views/NewChat/CreateLinkView.swift +++ b/apps/ios/Shared/Views/NewChat/CreateLinkView.swift @@ -62,8 +62,8 @@ struct CreateLinkView: View { createInvitation() } } - .onAppear { m.connReqInv = connReqInvitation } - .onDisappear { m.connReqInv = nil } + // .onAppear { m.connReqInv = connReqInvitation } + // .onDisappear { m.connReqInv = nil } .navigationTitle(selection.title) .navigationBarTitleDisplayMode(.large) } @@ -77,7 +77,7 @@ struct CreateLinkView: View { m.updateContactConnection(pcc) connReqInvitation = connReq contactConnection = pcc - m.connReqInv = connReq + // m.connReqInv = connReq } } else { await MainActor.run { diff --git a/apps/ios/Shared/Views/NewChat/NewChatView.swift b/apps/ios/Shared/Views/NewChat/NewChatView.swift index 0eeb662080..45d83150fc 100644 --- a/apps/ios/Shared/Views/NewChat/NewChatView.swift +++ b/apps/ios/Shared/Views/NewChat/NewChatView.swift @@ -31,8 +31,10 @@ struct NewChatView: View { @EnvironmentObject var m: ChatModel @State var selection: NewChatOption @State var showQRCodeScanner = false - @State private var connReqInvitation: String = "" + @State private var invitationUsed: Bool = false + @State private var connectionChatCreated: Bool = false @State private var contactConnection: PendingContactConnection? = nil + @State private var connReqInvitation: String = "" @State private var creatingConnReq = false @State private var someAlert: SomeAlert? @@ -66,7 +68,11 @@ struct NewChatView: View { switch selection { case .invite: if connReqInvitation != "" { - InviteView(contactConnection: $contactConnection, connReqInvitation: connReqInvitation) + InviteView( + invitationUsed: $invitationUsed, + contactConnection: $contactConnection, + connReqInvitation: connReqInvitation + ) } else if creatingConnReq { creatingLinkProgressView() } else { @@ -82,7 +88,22 @@ struct NewChatView: View { .onAppear { createInvitation(selection) } - .onDisappear { m.connReqInv = nil } + .onChange(of: invitationUsed) { used in + if used && !connectionChatCreated, + let conn = contactConnection { + m.updateContactConnection(conn) + connectionChatCreated = true + } + } + .onDisappear { + m.invitationConnId = nil + if !connectionChatCreated, + let conn = contactConnection { + Task { + try await apiDeleteChat(type: .contactConnection, id: conn.apiId) + } + } + } .alert(item: $someAlert) { a in switch a { case let .someAlert(alert, _): alert @@ -98,11 +119,9 @@ struct NewChatView: View { let (r, alert) = await apiAddContact(incognito: incognitoGroupDefault.get()) if let (connReq, pcc) = r { await MainActor.run { - // TODO add connection to model if shared, or view dismissed by connected event - m.updateContactConnection(pcc) connReqInvitation = connReq contactConnection = pcc - m.connReqInv = connReq + m.invitationConnId = pcc.id } } else { await MainActor.run { @@ -140,6 +159,7 @@ struct NewChatView: View { private struct InviteView: View { @EnvironmentObject var chatModel: ChatModel + @Binding var invitationUsed: Bool @Binding var contactConnection: PendingContactConnection? var connReqInvitation: String @AppStorage(GROUP_DEFAULT_INCOGNITO, store: groupDefaults) private var incognitoDefault = false @@ -160,6 +180,7 @@ private struct InviteView: View { logger.error("apiSetConnectionIncognito error: \(responseError(error))") } } + setInvitationUsed() } } @@ -183,6 +204,7 @@ private struct InviteView: View { linkTextView(link) Button { showShareSheet(items: [link]) + setInvitationUsed() } label: { Image(systemName: "square.and.arrow.up") } @@ -191,7 +213,7 @@ private struct InviteView: View { private func qrCodeView() -> some View { Section("Or show this code") { - SimpleXLinkQRCode(uri: connReqInvitation) + SimpleXLinkQRCode(uri: connReqInvitation, onShare: setInvitationUsed) .padding() .background( RoundedRectangle(cornerRadius: 12, style: .continuous) @@ -203,6 +225,12 @@ private struct InviteView: View { .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)) } } + + private func setInvitationUsed() { + if !invitationUsed { + invitationUsed = true + } + } } private enum ConnectAlert: Identifiable { diff --git a/apps/ios/Shared/Views/NewChat/QRCode.swift b/apps/ios/Shared/Views/NewChat/QRCode.swift index 4bec3f8e66..552d521822 100644 --- a/apps/ios/Shared/Views/NewChat/QRCode.swift +++ b/apps/ios/Shared/Views/NewChat/QRCode.swift @@ -32,9 +32,10 @@ struct SimpleXLinkQRCode: View { let uri: String var withLogo: Bool = true var tintColor = UIColor(red: 0.023, green: 0.176, blue: 0.337, alpha: 1) + var onShare: (() -> Void)? = nil var body: some View { - QRCode(uri: simplexChatLink(uri), withLogo: withLogo, tintColor: tintColor) + QRCode(uri: simplexChatLink(uri), withLogo: withLogo, tintColor: tintColor, onShare: onShare) } } @@ -48,6 +49,7 @@ struct QRCode: View { let uri: String var withLogo: Bool = true var tintColor = UIColor(red: 0.023, green: 0.176, blue: 0.337, alpha: 1) + var onShare: (() -> Void)? = nil @State private var image: UIImage? = nil @State private var makeScreenshotBinding: () -> Void = {} @@ -72,7 +74,9 @@ struct QRCode: View { .onAppear { makeScreenshotBinding = { let size = CGSizeMake(1024 / UIScreen.main.scale, 1024 / UIScreen.main.scale) - showShareSheet(items: [makeScreenshot(geo.frame(in: .local).origin, size)])} + showShareSheet(items: [makeScreenshot(geo.frame(in: .local).origin, size)]) + onShare?() + } } .frame(width: geo.size.width, height: geo.size.height) } @@ -81,7 +85,6 @@ struct QRCode: View { .onAppear { image = image ?? generateImage(uri)?.replaceColor(UIColor.black, tintColor) } - } }