From a4ff43836581e5fc2dc7489aa89ccd53708232c4 Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Fri, 22 Sep 2023 22:18:25 -0600 Subject: Rough, untested attempt at rewards --- TalerWallet.xcodeproj/project.pbxproj | 21 +++++ TalerWallet1/Controllers/Controller.swift | 2 + TalerWallet1/Model/Model+Reward.swift | 24 +++++ .../Views/Sheets/Reward/RewardURIView.swift | 100 +++++++++++++++++++++ TalerWallet1/Views/Sheets/URLSheet.swift | 4 +- 5 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 TalerWallet1/Model/Model+Reward.swift create mode 100644 TalerWallet1/Views/Sheets/Reward/RewardURIView.swift diff --git a/TalerWallet.xcodeproj/project.pbxproj b/TalerWallet.xcodeproj/project.pbxproj index 83e73fd..573e7f5 100644 --- a/TalerWallet.xcodeproj/project.pbxproj +++ b/TalerWallet.xcodeproj/project.pbxproj @@ -254,6 +254,10 @@ 4EFA39612AA7946B00742548 /* ToSButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EFA395F2AA7946B00742548 /* ToSButtonView.swift */; }; ABC13AA32859962800D23185 /* taler-swift in Frameworks */ = {isa = PBXBuildFile; productRef = ABC13AA22859962800D23185 /* taler-swift */; }; ABE97B1D286D82BF00580772 /* AnyCodable in Frameworks */ = {isa = PBXBuildFile; productRef = ABE97B1C286D82BF00580772 /* AnyCodable */; }; + E3D1B2002ABE9631008F3F82 /* RewardURIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3D1B1FF2ABE9631008F3F82 /* RewardURIView.swift */; }; + E3D1B2012ABE9631008F3F82 /* RewardURIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3D1B1FF2ABE9631008F3F82 /* RewardURIView.swift */; }; + E3D1B2032ABE9993008F3F82 /* Model+Reward.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3D1B2022ABE9993008F3F82 /* Model+Reward.swift */; }; + E3D1B2042ABE9993008F3F82 /* Model+Reward.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3D1B2022ABE9993008F3F82 /* Model+Reward.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -425,6 +429,8 @@ D14AFD1D24D232B300C51073 /* Taler_Wallet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Taler_Wallet.app; sourceTree = BUILT_PRODUCTS_DIR; }; D14AFD3324D232B500C51073 /* TalerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TalerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; D14AFD3E24D232B500C51073 /* TalerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TalerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + E3D1B1FF2ABE9631008F3F82 /* RewardURIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RewardURIView.swift; sourceTree = ""; }; + E3D1B2022ABE9993008F3F82 /* Model+Reward.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Model+Reward.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -623,6 +629,7 @@ 4EB095322989CBFE0043A8A1 /* Model+Transactions.swift */, 4EB0953D2989CBFE0043A8A1 /* Model+Withdraw.swift */, 4EB0951E2989CBCB0043A8A1 /* Transaction.swift */, + E3D1B2022ABE9993008F3F82 /* Model+Reward.swift */, ); path = Model; sourceTree = ""; @@ -783,6 +790,7 @@ 4EEC157129F7188B00D46A03 /* Sheets */ = { isa = PBXGroup; children = ( + E3D1B1FE2ABE961C008F3F82 /* Reward */, 4EEC157729F9032900D46A03 /* Sheet.swift */, 4EEC157929F9427F00D46A03 /* QRSheet.swift */, 4E753A072A0B6A5F002D9328 /* ShareSheet.swift */, @@ -837,6 +845,14 @@ path = TalerUITests; sourceTree = ""; }; + E3D1B1FE2ABE961C008F3F82 /* Reward */ = { + isa = PBXGroup; + children = ( + E3D1B1FF2ABE9631008F3F82 /* RewardURIView.swift */, + ); + path = Reward; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1099,6 +1115,8 @@ 4E3EAE4E2A990778009F1BE8 /* AnyTransition+backslide.swift in Sources */, 4EFA39602AA7946B00742548 /* ToSButtonView.swift in Sources */, 4E3EAE4F2A990778009F1BE8 /* TwoRowButtons.swift in Sources */, + E3D1B2002ABE9631008F3F82 /* RewardURIView.swift in Sources */, + 4E3EAE4F2A990778009F1BE8 /* BalanceRowButtons.swift in Sources */, 4E3EAE502A990778009F1BE8 /* Model+Transactions.swift in Sources */, 4E3EAE512A990778009F1BE8 /* Controller+playSound.swift in Sources */, 4E3EAE522A990778009F1BE8 /* WalletEmptyView.swift in Sources */, @@ -1124,6 +1142,7 @@ 4E3EAE632A990778009F1BE8 /* WalletCore.swift in Sources */, 4E3EAE642A990778009F1BE8 /* LaunchAnimationView.swift in Sources */, 4E3EAE652A990778009F1BE8 /* SideBarView.swift in Sources */, + E3D1B2032ABE9993008F3F82 /* Model+Reward.swift in Sources */, 4E3EAE662A990778009F1BE8 /* PendingOpView.swift in Sources */, 4E3EAE672A990778009F1BE8 /* PendingOpsListView.swift in Sources */, 4E3EAE682A990778009F1BE8 /* WalletModel.swift in Sources */, @@ -1182,6 +1201,7 @@ 4EB095542989CBFE0043A8A1 /* Model+Payment.swift in Sources */, 4EB0954F2989CBFE0043A8A1 /* SettingsView.swift in Sources */, 4EB095552989CBFE0043A8A1 /* PaymentView.swift in Sources */, + E3D1B2012ABE9631008F3F82 /* RewardURIView.swift in Sources */, 4EB095612989CBFE0043A8A1 /* WithdrawURIView.swift in Sources */, 4EF840A72A0B85F400EE0D47 /* CopyShare.swift in Sources */, 4EB094ED298979620043A8A1 /* TalerWallet1App.swift in Sources */, @@ -1233,6 +1253,7 @@ 4EB095202989CBCB0043A8A1 /* WalletCore.swift in Sources */, 4EB095672989CBFE0043A8A1 /* LaunchAnimationView.swift in Sources */, 4EB095662989CBFE0043A8A1 /* SideBarView.swift in Sources */, + E3D1B2042ABE9993008F3F82 /* Model+Reward.swift in Sources */, 4EB0956F2989CBFE0043A8A1 /* PendingOpView.swift in Sources */, 4EB095702989CBFE0043A8A1 /* PendingOpsListView.swift in Sources */, 4EB095162989CBB00043A8A1 /* WalletModel.swift in Sources */, diff --git a/TalerWallet1/Controllers/Controller.swift b/TalerWallet1/Controllers/Controller.swift index fe55625..f57c775 100644 --- a/TalerWallet1/Controllers/Controller.swift +++ b/TalerWallet1/Controllers/Controller.swift @@ -149,6 +149,8 @@ extension Controller { return UrlCommand.payPush case "pay-template": return UrlCommand.payTemplate + case "tip": + return UrlCommand.reward default: symLog.log("unknown command taler://\(command)") } diff --git a/TalerWallet1/Model/Model+Reward.swift b/TalerWallet1/Model/Model+Reward.swift new file mode 100644 index 0000000..3b6fdda --- /dev/null +++ b/TalerWallet1/Model/Model+Reward.swift @@ -0,0 +1,24 @@ +/* + * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. + * See LICENSE.md + */ +import Foundation +import taler_swift + +fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for debugging + +extension WalletModel { + @MainActor + func prepareRewardM(url: String) async throws -> PrepareRewardResponse { + let request = PrepareRewardRequest(talerRewardUri: url) + let response = try await sendRequest(request, ASYNCDELAY) + return response + } + + @MainActor + func acceptRewardM(rewardId: String, currency: String) async throws { + let request = AcceptRewardRequest(walletRewardId: rewardId) + let _ = try await sendRequest(request, ASYNCDELAY) + } +} + diff --git a/TalerWallet1/Views/Sheets/Reward/RewardURIView.swift b/TalerWallet1/Views/Sheets/Reward/RewardURIView.swift new file mode 100644 index 0000000..b6fb709 --- /dev/null +++ b/TalerWallet1/Views/Sheets/Reward/RewardURIView.swift @@ -0,0 +1,100 @@ +/* + * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. + * See LICENSE.md + */ +import SwiftUI +import SymLog +import taler_swift + +struct RewardURIView: View { + private let symLog = SymLogV(0) + let stack: CallStack + let navTitle = String(localized: "Accept Reward", comment:"receive reward") + + @EnvironmentObject private var controller: Controller + @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic + + let url: URL + + @EnvironmentObject private var model: WalletModel + + func acceptAction(prepareRewardResult: PrepareRewardResponse) { + Task { // runs on MainActor + do { + try await model.acceptRewardM( + rewardId: prepareRewardResult.walletRewardId, + currency: prepareRewardResult.rewardAmountRaw.currencyStr) + + } catch { + controller.playSound(0) + // TODO: error + symLog.log(error.localizedDescription) + } + dismissTop() + } + } + + @State var prepareRewardResult: PrepareRewardResponse? = nil + + var body: some View { + if let prepareRewardResult { + let effective = prepareRewardResult.rewardAmountEffective + List { + let baseURL = prepareRewardResult.exchangeBaseUrl + let raw = prepareRewardResult.rewardAmountRaw + let currency = raw.currencyStr + let topTitle = String(localized: "Amount rewarded:") + + let fee = try! Amount.diff(raw, effective) // TODO: different currencies + ThreeAmountsView(topTitle: topTitle, + topAmount: raw, + fee: fee, + bottomTitle: String(localized: "\(currency) to receive:"), + bottomAmount: effective, + large: false, + pending: false, + incoming: true, + baseURL: baseURL) + } + .listStyle(myListStyle.style).anyView + .safeAreaInset(edge: .bottom) { + Button(navTitle, action: { acceptAction(prepareRewardResult: prepareRewardResult) }) + .buttonStyle(TalerButtonStyle(type: .prominent)) + .padding(.horizontal) + } + .navigationTitle(navTitle) + .onAppear() { + symLog.log("onAppear") + DebugViewC.shared.setSheetID(SHEET_PAYMENT) + } + } else { + let badURL = "Error in Link: \(url)" + WithdrawProgressView(message: url.host ?? badURL) + .navigationTitle("Find Exchange") + .task { + do { + symLog.log(".task") + let result = try await model.prepareRewardM(url: url.absoluteString) + prepareRewardResult = result + } catch { // TODO: error + symLog.log(error.localizedDescription) + } + } + } + } +} + +// MARK: - +struct RewardURIView_Previews: PreviewProvider { + static var previews: some View { + let details = PrepareRewardResponse( + walletRewardId: "txn:reward:12345", + accepted: false, + rewardAmountRaw: try! Amount(fromString: LONGCURRENCY + ":2.4"), + rewardAmountEffective: try! Amount(fromString: LONGCURRENCY + ":2.2"), + exchangeBaseUrl: "https://exchange.demo.taler.net/", + expirationTimestamp: Timestamp.inSomeDays(365)) + let url = URL(string: "taler://reward/survey")! + RewardURIView(stack: CallStack("Preview"), url: url, prepareRewardResult: details) + } +} diff --git a/TalerWallet1/Views/Sheets/URLSheet.swift b/TalerWallet1/Views/Sheets/URLSheet.swift index 4bb7a10..d467239 100644 --- a/TalerWallet1/Views/Sheets/URLSheet.swift +++ b/TalerWallet1/Views/Sheets/URLSheet.swift @@ -31,8 +31,8 @@ struct URLSheet: View { P2pReceiveURIView(stack: stack.push(), url: urlToOpen) case .payTemplate: PayTemplateView(stack: stack.push(), url: urlToOpen) -// case .reward: -// RewardURIView(url: urlToOpen) + case .reward: + RewardURIView(stack: stack.push(), url: urlToOpen) default: // Error view VStack { Text("unknown command") -- cgit v1.2.3