taler-ios

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

commit 94c259ecc144266319ccefb954a6a559be42a090
parent 7b05cff290c57036f19d25259a521be989be7470
Author: Marc Stibane <marc@taler.net>
Date:   Mon,  5 Oct 2026 08:29:28 +0200

improve look&feel

Diffstat:
MTalerWallet1/Views/HelperViews/LoadingView.swift | 31+++++++++++++++----------------
MTalerWallet1/Views/Main/ErrorView.swift | 13++++++-------
MTalerWallet1/Views/Transactions/TransactionRowView.swift | 2+-
MTalerWallet1/Views/Transactions/TransactionSummaryList.swift | 32+++++++++++++-------------------
MTalerWallet1/Views/Transactions/TransactionTypeDetail.swift | 34++++++++++++++++++++--------------
5 files changed, 55 insertions(+), 57 deletions(-)

diff --git a/TalerWallet1/Views/HelperViews/LoadingView.swift b/TalerWallet1/Views/HelperViews/LoadingView.swift @@ -140,25 +140,24 @@ struct LoadingView: View { var body: some View { +#if DEBUG2 + let background = developerMode ? Color.blue : nil +#else + let background: Color? = nil +#endif + let rotatingTaler = RotatingTaler(size: 100, + progress: true, // VoiceOver "In progress" + once: false, + background: background, + rotationEnabled: $rotationEnabled) + .id("rotatingTaler") let view = VStack(alignment: .center) { + Spacer() + rotatingTaler + Spacer() if controller.stalledConnection { StalledView() } else { - Spacer() -#if DEBUG - let background = developerMode ? Color.blue : nil -#else - let background = nil -#endif - RotatingTaler(size: 100, - progress: true, // VoiceOver "In progress" - once: false, - background: background, - rotationEnabled: $rotationEnabled) - .onTapGesture(count: 1) { - rotationEnabled.toggle() - } - Spacer() if let scopeInfo { if let urlStr = scopeInfo.url { Text(urlStr.trimURL) @@ -176,7 +175,7 @@ struct LoadingView: View { dismissButton } .frame(maxWidth: .infinity) - .padding() + .padding(.horizontal) .talerFont(.title) .navigationTitle(navTitle) .background(FullBackground()) diff --git a/TalerWallet1/Views/Main/ErrorView.swift b/TalerWallet1/Views/Main/ErrorView.swift @@ -44,6 +44,8 @@ struct ErrorBanner: View { } } + @ScaledMetric var frameHeight: CGFloat = 60 // relative to fontSize + var body: some View { let text = Text(errorText) .foregroundStyle(.white) @@ -52,7 +54,7 @@ struct ErrorBanner: View { if #available(iOS 26.0, *) { ContainerRelativeShape() .fill(errorColor) - .frame(height: 80) + .frame(height: frameHeight) .overlay { ZStack { VStack(spacing: 0) { @@ -63,10 +65,10 @@ struct ErrorBanner: View { text } } - } else { + } else { // ContainerRelativeShape exists since iOS 14, but doesn't work correctly text .frame(maxWidth: .infinity, alignment: .center) - .frame(height: 80) + .frame(height: frameHeight) .background { let radius = 12.0 if #available(iOS 16.4, *) { @@ -90,10 +92,7 @@ struct ErrorBanner: View { } } } - .transition(.asymmetric( - insertion: .move(edge: .top), - removal: .move(edge: .top) - )) + .transition(.move(edge: .top).combined(with: .scale)) } } diff --git a/TalerWallet1/Views/Transactions/TransactionRowView.swift b/TalerWallet1/Views/Transactions/TransactionRowView.swift @@ -279,7 +279,7 @@ struct TransactionRowView: View { #if DEBUG let background = developerMode ? Color.green : nil #else - let background = nil + let background: Color? = nil #endif RotatingTaler(size: 80, progress: true, once: false, background: background, diff --git a/TalerWallet1/Views/Transactions/TransactionSummaryList.swift b/TalerWallet1/Views/Transactions/TransactionSummaryList.swift @@ -292,22 +292,29 @@ struct TransactionSummaryList: View { : isRepurchase ? String(localized: "Already paid", comment:"repurchase merchant navTitle") : talerTX.localizedType } + var is26: Bool { + if #available(iOS 26.0, *) { true } else { false } + } var body: some View { #if PRINT_CHANGES let _ = Self._printChanges() let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear #endif - let is26: Bool = if #available(iOS 26.0, *) { true } else { false } +#if DEBUG + let background = developerMode ? Color.red : nil +#else + let background: Color? = nil +#endif let common = talerTX.common // let scope = common.scopes.first // might be nil if scopes == [] let locale = TalerDater.shared.locale - let isPaying = talerTX.isPayment && talerTX.isDialog + let isPayDialog = talerTX.isPayment && talerTX.isDialog Group { if common.type != .dummy && transactionId == common.transactionId { let list = List { if developerMode && withActions { suspendResume(common) } - if !isPaying { + if !isPayDialog { Section { HStack { VStack(alignment: .leading) { @@ -316,11 +323,6 @@ struct TransactionSummaryList: View { .talerFont(.title) } if isWorking { -#if DEBUG - let background = developerMode ? Color.red : nil -#else - let background = nil -#endif RotatingTaler(size: 80, progress: true, once: false, background: background, rotationEnabled: Binding.constant(true)) @@ -329,9 +331,7 @@ struct TransactionSummaryList: View { } } } - if controller.stalledConnection { -// StalledView() => show this in the safeArea - } else { + if !controller.stalledConnection { TransactionTypeDetail(stack: stack.push(), transaction: $talerTX, payNow: $payNow, @@ -340,25 +340,19 @@ struct TransactionSummaryList: View { effective: $effective, // return amount for "Pay <amount> now" possible: $paymentPossible, hasDone: hasDone) - - // TODO: Retry Countdown, Retry Now button -// if talerTX.isRetryable, let retryAction { -// TransactionButton(transactionId: common.transactionId, command: .retry, -// warning: nil, action: abortAction) -// } // Retry button if withActions { abortFailDelete(common) } } }.id(viewId) // change viewId to enforce a draw update .listStyle(myListStyle.style).anyView .background(FullBackground()) .navigationBarBackButtonHidden(hasDone) - .interactiveDismissDisabled(hasDone && !isPaying) // can only use "Done" button to dismiss + .interactiveDismissDisabled(hasDone && !isPayDialog) // can only use "Done" button to dismiss .safeAreaInset(edge: .bottom) { let cancelButton = Button("Cancel") { dismissTop(stack.push()) } .buttonStyle(TalerButtonStyle(type: .bordered)) .padding(is26 ? .horizontal : .all) let bottomButton = ZStack { - if isPaying, case .payment(let paymentTransaction) = talerTX { + if isPayDialog, case .payment(let paymentTransaction) = talerTX { let details = paymentTransaction.details if let effective, let terms = details.contractTerms, isFinished != true { let formatted = effective.formatted(currencyInfo) diff --git a/TalerWallet1/Views/Transactions/TransactionTypeDetail.swift b/TalerWallet1/Views/Transactions/TransactionTypeDetail.swift @@ -75,26 +75,32 @@ struct TransactionTypeDetail: View { let _ = Self._printChanges() let _ = symLog.vlog() #endif +#if DEBUG + let background = developerMode ? Color.orange : nil +#else + let background: Color? = nil +#endif let common = transaction.common let pending = transaction.isPending let isDialog = transaction.isDialog Group { switch transaction { case .dummy(_): Group { - let title = EMPTYSTRING - Text(title) - .talerFont(.body) - if common.isWorking { -#if DEBUG - let background = developerMode ? Color.orange : nil -#else - let background = nil -#endif - RotatingTaler(size: 100, progress: true, once: false, - background: background, - rotationEnabled: $rotationEnabled) - .frame(maxWidth: .infinity, alignment: .center) - // has its own accessibilityLabel + Section { + if common.isWorking { + HStack { + Spacer() + RotatingTaler(size: 100, progress: true, once: false, + background: background, + rotationEnabled: $rotationEnabled) + .frame(maxWidth: .infinity, alignment: .center) + // has its own accessibilityLabel + } + } else { + let title = EMPTYSTRING + Text(title) + .talerFont(.body) + } } } case .withdrawal(let withdrawalTransaction): Group {