taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

TransactionButton.swift (4060B)


      1 /*
      2  * This file is part of GNU Taler, ©2022-26 Taler Systems S.A.
      3  * See LICENSE.md
      4  */
      5 /**
      6  * @author Marc Stibane
      7  */
      8 import SwiftUI
      9 import taler_swift
     10 import AVFoundation
     11 
     12 struct WarningButton: View {
     13     let warningText: String?
     14     let buttonTitle: String
     15     let buttonIcon: String?
     16     let role: ButtonRole?
     17     @Binding var disabled: Bool
     18     let action: () -> Void
     19 
     20     @AppStorage("shouldShowWarning") var shouldShowWarning: Bool = true
     21     @State private var showAlert: Bool = false
     22 
     23     var body: some View {
     24         Button(//role: role,
     25              action: {
     26                 if !disabled {
     27                     if shouldShowWarning && (role == .destructive || role == .cancel) {
     28                         showAlert = true
     29                     } else {
     30                         action()
     31                     }
     32                 }
     33         }) {
     34             HStack(spacing: 20) {
     35                 if let buttonIcon {
     36                     Image(systemName: buttonIcon)
     37                 }
     38                 Text(buttonTitle)
     39             }
     40             .frame(maxWidth: .infinity)
     41             .foregroundColor(role == .destructive ? WalletColors().errorColor
     42                                                   : WalletColors().primaryAccent)
     43         }
     44         .talerFont(.title1)
     45         .buttonStyle(.bordered)
     46         .controlSize(.large)
     47         .disabled(disabled)
     48         .alert(warningText ?? EMPTYSTRING, isPresented: $showAlert, actions: {
     49                 Button("Cancel", role: .cancel) {
     50                     showAlert = false
     51                 }
     52                 Button(buttonTitle) {
     53                     showAlert = false
     54                     action()
     55                 }
     56             }, message: { Text("This operation cannot be undone") }
     57         )
     58     }
     59 }
     60 // MARK: -
     61 struct TransactionButton: View {
     62     let transactionId: String
     63     let command: TxAction
     64     let warning: String?
     65     @Binding var didExecute: Bool
     66     let action: (_ transactionId: String, _ viewHandles: Bool) async throws -> Void
     67 
     68     @State private var disabled: Bool = false
     69     @State private var executed: Bool = false
     70     @State private var buttonTitle: String = EMPTYSTRING
     71 
     72     @MainActor
     73     private func doAction() {
     74         disabled = true     // don't try this more than once
     75         Task { // runs on MainActor
     76             do {
     77                 try await action(transactionId, false)
     78 //                symLog.log("\(executed) \(transactionId)")
     79                 executed = true             // change button text
     80                 didExecute = true
     81             } catch {
     82                 disabled = false            // allow the user to retry after a failure
     83             }
     84         }
     85     }
     86 
     87     var body: some View {
     88         let isDestructive = (command == .delete) || (command == .fail)
     89         let isCancel = (command == .abort)
     90         let role: ButtonRole? = isDestructive ? .destructive
     91                               : isCancel      ? .cancel
     92                                               : nil
     93         let buttonTitle = executed ? command.localizedActionExecuted
     94                                    : command.localizedActionTitle
     95         WarningButton(warningText: warning,
     96                       buttonTitle: buttonTitle,
     97                        buttonIcon: command.localizedActionImage,
     98                              role: role,                                        // TODO: WalletColors().errorColor
     99                          disabled: $disabled,
    100                            action: doAction)
    101     }
    102 }
    103 // MARK: -
    104 #if DEBUG
    105 //struct TransactionButton_Previews: PreviewProvider {
    106 //
    107 //    static func action(_ transactionId: String, _ viewHandles: Bool) async throws {
    108 //        print(transactionId)
    109 //    }
    110 //
    111 //    static var previews: some View {
    112 //        List {
    113 //            TransactionButton(transactionId: "Button pressed", command: .abort,
    114 //                              warning: "Are you sure you want to abort this transaction?",
    115 //                              didExecute: <#Binding<Bool>#>,
    116 //                              action: action)
    117 //        }
    118 //    }
    119 //}
    120 #endif