diff --git a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj index 7af03fb1..b0049c9a 100644 --- a/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj +++ b/ui/BankingiOSApp/BankingiOSApp.xcodeproj/project.pbxproj @@ -20,6 +20,7 @@ 3608D6C224FBA9C6006C93A8 /* TrianglePointingDown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3608D6C124FBA9C6006C93A8 /* TrianglePointingDown.swift */; }; 3608D6C624FBAB41006C93A8 /* TanGeneratorPositionMarker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3608D6C524FBAB41006C93A8 /* TanGeneratorPositionMarker.swift */; }; 3642F00A2500F5AE005186FE /* Divider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3642F0092500F5AE005186FE /* Divider.swift */; }; + 3642F00C25010021005186FE /* UIKitActivityIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3642F00B25010021005186FE /* UIKitActivityIndicator.swift */; }; 366744E224FC4E96002B235A /* SectionWithRightAlignedEditButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366744E124FC4E96002B235A /* SectionWithRightAlignedEditButton.swift */; }; 366FA4DA24C472A90094F009 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366FA4D924C472A90094F009 /* Extensions.swift */; }; 366FA4DC24C479120094F009 /* BankInfoListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 366FA4DB24C479120094F009 /* BankInfoListItem.swift */; }; @@ -152,6 +153,7 @@ 3608D6C124FBA9C6006C93A8 /* TrianglePointingDown.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrianglePointingDown.swift; sourceTree = ""; }; 3608D6C524FBAB41006C93A8 /* TanGeneratorPositionMarker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TanGeneratorPositionMarker.swift; sourceTree = ""; }; 3642F0092500F5AE005186FE /* Divider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Divider.swift; sourceTree = ""; }; + 3642F00B25010021005186FE /* UIKitActivityIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitActivityIndicator.swift; sourceTree = ""; }; 366744E124FC4E96002B235A /* SectionWithRightAlignedEditButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionWithRightAlignedEditButton.swift; sourceTree = ""; }; 366FA4D924C472A90094F009 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 366FA4DB24C479120094F009 /* BankInfoListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BankInfoListItem.swift; sourceTree = ""; }; @@ -474,6 +476,7 @@ 3608D6C524FBAB41006C93A8 /* TanGeneratorPositionMarker.swift */, 366744E124FC4E96002B235A /* SectionWithRightAlignedEditButton.swift */, 3642F0092500F5AE005186FE /* Divider.swift */, + 3642F00B25010021005186FE /* UIKitActivityIndicator.swift */, ); path = views; sourceTree = ""; @@ -646,6 +649,7 @@ 36BE064F24C9A17F00CBBB68 /* ImageTanView.swift in Sources */, 36E21EDB24DC990300649DC8 /* LabelledUIKitTextField.swift in Sources */, 36BE068D24CE41E700CBBB68 /* Styles.swift in Sources */, + 3642F00C25010021005186FE /* UIKitActivityIndicator.swift in Sources */, 36E21ECB24D88DF000649DC8 /* UIKitExtensions.swift in Sources */, 360782C524E541970098FEFE /* ScaleImageView.swift in Sources */, 366744E224FC4E96002B235A /* SectionWithRightAlignedEditButton.swift in Sources */, diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/AddAccountDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/AddAccountDialog.swift index 597438be..bb357c48 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/views/AddAccountDialog.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/AddAccountDialog.swift @@ -13,6 +13,8 @@ struct AddAccountDialog: View { @State private var password = "" + @State private var isTryingToAddAccount = false + @State private var errorMessage: Message? = nil @@ -48,11 +50,13 @@ struct AddAccountDialog: View { Section { HStack { Spacer() - Button(action: { self.addAccount() }, - label: { Text("Add") }) - .disabled(!self.isRequiredDataEntered()) + + Button("Add") { self.addAccount() } + .disabled( !self.isRequiredDataEntered() || isTryingToAddAccount) + Spacer() } + .overlay(UIKitActivityIndicator($isTryingToAddAccount), alignment: .leading) } } @@ -65,7 +69,7 @@ struct AddAccountDialog: View { func handleReturnKeyPress() -> Bool { - if self.isRequiredDataEntered() { + if self.isRequiredDataEntered() && isTryingToAddAccount == false { self.addAccount() return true @@ -82,6 +86,8 @@ struct AddAccountDialog: View { func addAccount() { if let bank = bank { + isTryingToAddAccount = true + presenter.addAccountAsync(bankInfo: bank, customerId: customerId, pin: password) { (response) in self.handleAddAccountResponse(response) } @@ -89,6 +95,8 @@ struct AddAccountDialog: View { } func handleAddAccountResponse(_ response: AddAccountResponse) { + isTryingToAddAccount = false + if (response.isSuccessful) { DispatchQueue.main.async { // dispatch async as may EnterTanDialog is still displayed so dismiss() won't dismiss this view self.presentation.wrappedValue.dismiss() diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/TransferMoneyDialog.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/TransferMoneyDialog.swift index fbab5cca..7ef9e80a 100644 --- a/ui/BankingiOSApp/BankingiOSApp/ui/views/TransferMoneyDialog.swift +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/TransferMoneyDialog.swift @@ -43,6 +43,8 @@ struct TransferMoneyDialog: View { @State private var instantPayment = false + @State private var isTransferringMoney = false + @State private var transferMoneyResponseMessage: Message? = nil private let inputValidator = InputValidator() @@ -165,11 +167,13 @@ struct TransferMoneyDialog: View { Section { HStack { Spacer() - Button(action: { self.transferMoney() }, - label: { Text("Transfer Money") }) - .disabled( !self.isRequiredDataEntered()) + + Button("Transfer Money") { self.transferMoney() } + .disabled( !self.isRequiredDataEntered() || isTransferringMoney) + Spacer() } + .overlay(UIKitActivityIndicator($isTransferringMoney), alignment: .leading) } } .onAppear { @@ -197,7 +201,7 @@ struct TransferMoneyDialog: View { private func handleReturnKeyPress() -> Bool { - if self.isRequiredDataEntered() { + if self.isRequiredDataEntered() && isTransferringMoney == false { self.transferMoney() return true @@ -371,6 +375,8 @@ struct TransferMoneyDialog: View { private func transferMoney() { if let amount = inputValidator.convertAmountString(enteredAmountString: self.amount) { + isTransferringMoney = true + let data = TransferMoneyData(account: account!, creditorName: remitteeName, creditorIban: remitteeIban, creditorBic: remitteeBic, amount: amount, usage: usage, instantPayment: instantPayment) presenter.transferMoneyAsync(data: data) { response in @@ -380,6 +386,8 @@ struct TransferMoneyDialog: View { } private func handleTransferMoneyResponse(_ data: TransferMoneyData, _ response: BankingClientResponse) { + isTransferringMoney = false + if (response.isSuccessful) { self.transferMoneyResponseMessage = Message(message: Text("Successfully transferred \(data.amount) \("€") to \(data.creditorName)"), primaryButton: .ok { self.presentation.wrappedValue.dismiss() diff --git a/ui/BankingiOSApp/BankingiOSApp/ui/views/UIKitActivityIndicator.swift b/ui/BankingiOSApp/BankingiOSApp/ui/views/UIKitActivityIndicator.swift new file mode 100644 index 00000000..9a8d7d14 --- /dev/null +++ b/ui/BankingiOSApp/BankingiOSApp/ui/views/UIKitActivityIndicator.swift @@ -0,0 +1,40 @@ +import SwiftUI +import UIKit + + +struct UIKitActivityIndicator: UIViewRepresentable { + + private let style: UIActivityIndicatorView.Style + + @Binding private var isAnimating: Bool + + + init(_ isAnimating: Binding = .constant(true), _ style: UIActivityIndicatorView.Style = .medium) { + _isAnimating = isAnimating + + self.style = style + } + + + func makeUIView(context: UIViewRepresentableContext) -> UIActivityIndicatorView { + let indicatorView = UIActivityIndicatorView(style: style) + + indicatorView.hidesWhenStopped = true + + return indicatorView + } + + func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext) { + isAnimating ? uiView.startAnimating() : uiView.stopAnimating() + } + +} + + +struct UIKitActivityIndicator_Previews: PreviewProvider { + + static var previews: some View { + UIKitActivityIndicator() + } + +}