diff --git a/TalerWallet1/Model/Model+TalDir.swift b/TalerWallet1/Model/Model+TalDir.swift index 31ec8a24..f86edf0f 100644 --- a/TalerWallet1/Model/Model+TalDir.swift +++ b/TalerWallet1/Model/Model+TalDir.swift @@ -66,6 +66,16 @@ fileprivate struct AddContact: WalletBackendFormattedRequest { func args() -> Args { Args(contact: contact) } struct Response: Decodable {} } +/// A request to delete a contact +fileprivate struct DeleteContact: WalletBackendFormattedRequest { + var contact: ContactEntry + var operation: String { "deleteContact" } + struct Args: Encodable { + var contact: ContactEntry + } + func args() -> Args { Args(contact: contact) } + struct Response: Decodable {} +} // MARK: - Contact calls extension WalletModel { nonisolated func getContacts(viewHandles: Bool = false) @@ -85,6 +95,12 @@ extension WalletModel { // controller.progressToken = request.operation let _ = try await sendRequest(request, viewHandles: viewHandles) } + + nonisolated func deleteContact(_ contact: ContactEntry, viewHandles: Bool = false) + async throws { // M for MainActor + let request = DeleteContact(contact: contact) + let _ = try await sendRequest(request, viewHandles: viewHandles) + } } // MARK: - Alias Types struct TaldirAliasType: Codable, Hashable { diff --git a/TalerWallet1/Views/TalDir/ContactsView.swift b/TalerWallet1/Views/TalDir/ContactsView.swift index 3faac812..7d893912 100644 --- a/TalerWallet1/Views/TalDir/ContactsView.swift +++ b/TalerWallet1/Views/TalDir/ContactsView.swift @@ -96,6 +96,22 @@ struct ContactsView: View { String(localized: "TitleContacts", defaultValue: "Contacts") } + /// wallet-core has had `deleteContact` all along; nothing in the app called it, + /// so a contact - including a mistyped one - could never be removed + @ViewBuilder func deleteButton(_ contact: ContactEntry) -> some View { + Button(role: .destructive) { + Task { // runs on MainActor + if let _ = try? await model.deleteContact(contact) { + await controller.loadContacts(stack.push()) + } + } + } label: { + Label("Delete", systemImage: "trash") + } + .tint(WalletColors().negative) + .accessibilityIdentifier("button.contact.delete") + } + var body: some View { #if PRINT_CHANGES let _ = Self._printChanges() @@ -120,6 +136,7 @@ struct ContactsView: View { contact: contact, talerURI: talerURI, subject: subject) + .swipeActions(edge: .trailing) { deleteButton(contact) } } } } @@ -132,6 +149,7 @@ struct ContactsView: View { contact: contact, talerURI: talerURI, subject: subject) + .swipeActions(edge: .trailing) { deleteButton(contact) } } } }