Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// Transaction+Extensions.swift
//
// Copyright © 2026 Gini GmbH. All rights reserved.
//

import SwiftUI

extension Transaction {
// Disables ambient UIKit animation inheritance (e.g. keyboard CATransaction).
static var withoutAnimation: Transaction {
Comment thread
zladzeyka marked this conversation as resolved.
var transaction = Transaction()
transaction.disablesAnimations = true
return transaction
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,11 @@ final class PaymentReviewObservableModel: ObservableObject {
model.strings.invoiceImageAccessibilityLabel
}

/**
Reflects whether the amount field inside the payment information form is currently focused.
Changes trigger a re-render of `PaymentReviewContentView` so the landscape Done toolbar
can appear or disappear in sync with keyboard focus.
*/
// Reflects amount-field focus so PaymentReviewContentView re-renders the landscape toolbar.
var isAmountFieldFocused: Bool {
paymentInformationObservableModel.isAmountFieldFocused
}
Comment thread
zladzeyka marked this conversation as resolved.
Outdated

/**
The localized title for the keyboard Done button.
*/
var keyboardDoneButtonTitle: String {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] Can we please add the doc comment back
/** The localized title for the keyboard Done button. */

containerViewModel.strings.keyboardDoneButtonTitle
}
Expand All @@ -70,19 +63,14 @@ final class PaymentReviewObservableModel: ObservableObject {
model.delegate?.trackOnPaymentReviewCloseKeyboardClicked()
}

/**
Validates the amount field as if it had just lost focus.
Called explicitly by the landscape Done button, which resigns first responder via
UIKit rather than setting `focusedField = nil`. SwiftUI's `@FocusState` update from
a UIKit `resignFirstResponder` call is not guaranteed to be synchronous, so relying
solely on `onChange(of: focusedField)` to trigger validation can cause the error
message to appear only on the second Done press. Calling this directly — mirroring
what the portrait Done button does — ensures validation runs immediately.
*/
// Validates the amount field as if it just lost focus.
// Called by the landscape Done button which resigns first responder via UIKit — SwiftUI's
// @FocusState update is not guaranteed synchronous, so validation would otherwise fire
// only on the second Done press.
func validateAmountFieldOnKeyboardDismiss() {
Comment thread
zladzeyka marked this conversation as resolved.
Outdated
paymentInformationObservableModel.handleAmountFocusChange(isFocused: false)
}

@Published private var showBanner: Bool

@Published var cellViewModels: [PageCollectionCellViewModel] = []
Expand Down Expand Up @@ -209,8 +197,8 @@ final class PaymentReviewObservableModel: ObservableObject {
}

private func setupBindings() {
// Forward `isAmountFieldFocused` changes from the inner observable model so that
// `PaymentReviewContentView` re-renders when the amount field gains or loses focus.
// Forward isAmountFieldFocused changes so PaymentReviewContentView re-renders
// its landscape keyboard toolbar when the amount field gains or loses focus.
paymentInformationObservableModel.$isAmountFieldFocused
.sink { [weak self] _ in self?.objectWillChange.send() }
.store(in: &cancellables)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import GiniUtilites
/** Identifies which payment form field is currently focused.
Stored in the observable model so focus can be restored after orientation changes recreate the view.
*/
enum ActivePaymentField: Equatable {
enum ActivePaymentField: Hashable {
Comment thread
zladzeyka marked this conversation as resolved.
Outdated
case recipient
case iban
case amount
Expand Down
Loading
Loading