taler-ios

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

commit 3feaf5c07b0544d8184989ff241ec7670e693e42
parent fb77be79cab23b0bb2d4738bd68e5df3be01e0de
Author: Marc Stibane <marc@taler.net>
Date:   Sat, 25 Feb 2023 19:03:54 +0100

Transaction List & Details

Diffstat:
MTalerWallet1/Views/HelperViews/Buttons.swift | 22++++++++++++++++++++++
MTalerWallet1/Views/Transactions/TransactionDetail.swift | 56+++++++++++++++++++++++++++++++++++---------------------
MTalerWallet1/Views/Transactions/TransactionsListView.swift | 67++++++++++++++++++++++++++++++++++++++++++++-----------------------
3 files changed, 101 insertions(+), 44 deletions(-)

diff --git a/TalerWallet1/Views/HelperViews/Buttons.swift b/TalerWallet1/Views/HelperViews/Buttons.swift @@ -37,6 +37,28 @@ struct PlusButton : View { } } +struct ArrowUpButton : View { + let action: () -> Void + + var body: some View { + Button(action: action) { + Image(systemName: "arrow.up.to.line") + } + .font(.title3) + } +} + +struct ArrowDownButton : View { + let action: () -> Void + + var body: some View { + Button(action: action) { + Image(systemName: "arrow.down.to.line") + } + .font(.title3) + } +} + struct ReloadButton : View { let disabled: Bool let action: () -> Void diff --git a/TalerWallet1/Views/Transactions/TransactionDetail.swift b/TalerWallet1/Views/Transactions/TransactionDetail.swift @@ -21,7 +21,6 @@ struct TransactionDetail: View { var body: some View { let common = transaction.common() - let details = transaction.detailsToShow() let dateString = TalerDater.dateString(from: common.timestamp) VStack() { @@ -30,14 +29,24 @@ struct TransactionDetail: View { .font(.title) .fontWeight(.medium) .padding(.bottom) + Spacer() Text("\(dateString)") - .font(.title) - .fontWeight(.medium) + .font(.title2) .padding(.vertical) switch transaction { case .withdrawal(let withdrawalTransaction): + details(transaction: transaction) threeAmounts(common: common, topTitle: "Chosen amount to withdraw:", bottomTitle: "Obtained coins:", incoming: true) case .payment(let paymentTransaction): + let details = paymentTransaction.details + let info = details.info + Text("Status: \(details.status)") + .font(.title2) + .padding(.bottom) + Text(info.summary) + .font(.title) + .lineLimit(4) + .padding(.bottom) threeAmounts(common: common, topTitle: "Sum to be paid:", bottomTitle: "Paid coins:", incoming: false) case .refund(let refundTransaction): threeAmounts(common: common, topTitle: "Refunded amount:", bottomTitle: "Obtained coins:", incoming: true) @@ -46,17 +55,6 @@ struct TransactionDetail: View { case .refresh(let refreshTransaction): threeAmounts(common: common, topTitle: "Refreshed amount:", bottomTitle: "Paid coins:", incoming: false) } - -// if let baseURL = transaction.exchangeBaseUrl { -// VStack { -// Text("From exchange:") -// .font(.title3) -// Text("\(baseURL.trimURL())") -// .font(.title) -// .fontWeight(.medium) -// } -// .frame(maxWidth: .infinity, alignment: .center) -// } Spacer() Button(role: .destructive, action: { // TODO: delete from wallet-core @@ -71,7 +69,6 @@ struct TransactionDetail: View { }) .buttonStyle(.bordered) .controlSize(.large) -// Spacer() } } } @@ -92,14 +89,31 @@ extension TransactionDetail { let inColor = Color("Incoming") AmountView(title: topTitle, - value: raw.readableDescription, color: labelColor) - .padding(.bottom) + value: raw.readableDescription, + color: labelColor) + .padding(.bottom) AmountView(title: "Exchange fee:", - value: fee.readableDescription, color: fee.isZero ? labelColor : outColor) - .padding(.bottom) + value: fee.readableDescription, + color: fee.isZero ? labelColor : outColor) + .padding(.bottom) AmountView(title: bottomTitle, - value: effective.readableDescription, color: incoming ? inColor : outColor) - .padding(.bottom) + value: effective.readableDescription, + color: incoming ? inColor : outColor) + .padding(.bottom) + } + } + struct details: View { + var transaction : Transaction + var body: some View { + let details = transaction.detailsToShow() + let keys = details.keys + if keys.contains(EXCHANGEBASEURL) { + if let baseURL = details[EXCHANGEBASEURL] { + Text("from \(baseURL.trimURL())") + .font(.title2) + .padding(.bottom) + } + } } } } diff --git a/TalerWallet1/Views/Transactions/TransactionsListView.swift b/TalerWallet1/Views/Transactions/TransactionsListView.swift @@ -28,8 +28,10 @@ struct TransactionsListView: View { if viewModel.transactions == nil { symLog { LoadingView(backButtonHidden: false) } } else { + let count = viewModel.transactions!.count + let title: String = "\(count) \(navTitle)" symLog { Content(symLog: symLog, viewModel: viewModel, reloadAction: reloadAction) - .navigationTitle(navTitle) + .navigationTitle(title) } } }.task { @@ -51,33 +53,46 @@ extension TransactionsListView { var reloadAction: () async throws -> () + @State private var upAction: () -> Void = {} + @State private var downAction: () -> Void = {} + var body: some View { let transactions = viewModel.transactions! - List(transactions) { transaction in - let common = transaction.common() - NavigationLink { - TransactionDetail(transaction: transaction) - } label: { - TransactionRow(transaction: transaction) - } - .swipeActions(edge: .leading, allowsFullSwipe: true) { - Button { - symLog?.log("bookmarked \(common.transactionId)") - // TODO: Bookmark - } label: { - Label("Bookmark", systemImage: "bookmark") - }.tint(.indigo) - } - .swipeActions(edge: .trailing, allowsFullSwipe: true) { - Button(role: .destructive) { - symLog?.log("deleted \(common.transactionId)") - // TODO: delete from Model. SwiftUI deletes this row from view already :-) + + ScrollViewReader { scrollView in + List { + ForEach (transactions.indices) { index in + let transaction = transactions[index] + let common = transaction.common() + NavigationLink { + TransactionDetail(transaction: transaction) } label: { - Label("Delete", systemImage: "trash") + TransactionRow(transaction: transaction) + } + .id(index) + .swipeActions(edge: .leading, allowsFullSwipe: true) { + Button { + symLog?.log("bookmarked \(common.transactionId)") + // TODO: Bookmark + } label: { + Label("Bookmark", systemImage: "bookmark") + }.tint(.indigo) + } + .swipeActions(edge: .trailing, allowsFullSwipe: true) { + Button(role: .destructive) { + symLog?.log("deleted \(common.transactionId)") + // TODO: delete from Model. SwiftUI deletes this row from view already :-) + } label: { + Label("Delete", systemImage: "trash") + } } } - } - .navigationBarTitleDisplayMode(.large) // .inline + .onAppear { + upAction = { withAnimation { scrollView.scrollTo(0) }} + downAction = { withAnimation { scrollView.scrollTo(transactions.count - 1) }} + downAction() + } + } .refreshable { do { symLog?.log("refreshing") @@ -87,6 +102,12 @@ extension TransactionsListView { symLog?.log(error.localizedDescription) } } + } + .navigationBarItems(trailing: HStack { + ArrowUpButton(action: upAction) + ArrowDownButton(action: downAction) + }) + .navigationBarTitleDisplayMode(.large) // .inline } } }