diff options
Diffstat (limited to 'packages/taler-wallet-webextension')
6 files changed, 79 insertions, 75 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts index 838739ad1..daba6aba4 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts @@ -94,9 +94,9 @@ export namespace State { currentAccount: PaytoUri; totalFee: AmountJson; - totalToDeposit: AmountJson; amount: AmountFieldHandler; + totalToDeposit: AmountFieldHandler; account: SelectFieldHandler; cancelHandler: ButtonHandler; depositHandler: ButtonHandler; diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts index 97b2ab517..b674665cf 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts @@ -15,19 +15,18 @@ */ import { - AmountJson, Amounts, - DepositGroupFees, KnownBankAccountsInfo, parsePaytoUri, PaytoUri, stringifyPaytoUri, + TransactionAmountMode } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { useState } from "preact/hooks"; import { alertFromError, useAlertContext } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; -import { useTranslationContext } from "@gnu-taler/web-util/browser"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { RecursiveState } from "../../utils/index.js"; import { Props, State } from "./index.js"; @@ -83,8 +82,11 @@ export function useComponentState({ if (hook.hasError) { return { status: "error", - error: alertFromError(i18n, - i18n.str`Could not load balance information`, hook), + error: alertFromError( + i18n, + i18n.str`Could not load balance information`, + hook, + ), }; } const { accounts, balances } = hook.response; @@ -141,21 +143,23 @@ export function useComponentState({ } const firstAccount = accounts[0].uri; const currentAccount = !selectedAccount ? firstAccount : selectedAccount; - - return () => { - // eslint-disable-next-line react-hooks/rules-of-hooks - const [amount, setAmount] = useState<AmountJson>( - initialValue ?? ({} as any), + const zero = Amounts.zeroOfCurrency(currency) + return (): State => { + const [instructed, setInstructed] = useState( + {amount: initialValue ?? zero, type: TransactionAmountMode.Raw}, ); - const amountStr = Amounts.stringify(amount); + const amountStr = Amounts.stringify(instructed.amount); const depositPaytoUri = stringifyPaytoUri(currentAccount); - // eslint-disable-next-line react-hooks/rules-of-hooks const hook = useAsyncAsHook(async () => { - const fee = await api.wallet.call(WalletApiOperation.PrepareDeposit, { - amount: amountStr, - depositPaytoUri, - }); + const fee = await api.wallet.call( + WalletApiOperation.ConvertDepositAmount, + { + amount: amountStr, + type: instructed.type, + depositPaytoUri, + }, + ); return { fee }; }, [amountStr, depositPaytoUri]); @@ -183,18 +187,16 @@ export function useComponentState({ const totalFee = fee !== undefined - ? Amounts.sum([fee.fees.wire, fee.fees.coin, fee.fees.refresh]).amount + ? Amounts.sub(fee.effectiveAmount, fee.rawAmount).amount : Amounts.zeroOfCurrency(currency); - const totalToDeposit = - fee !== undefined - ? Amounts.sub(amount, totalFee).amount - : Amounts.zeroOfCurrency(currency); + const totalToDeposit = Amounts.parseOrThrow(fee.rawAmount); + const totalEffective = Amounts.parseOrThrow(fee.effectiveAmount); - const isDirty = amount !== initialValue; + const isDirty = instructed.amount !== initialValue; const amountError = !isDirty ? undefined - : Amounts.cmp(balance, amount) === -1 + : Amounts.cmp(balance, totalEffective) === -1 ? `Too much, your current balance is ${Amounts.stringifyValue(balance)}` : undefined; @@ -207,7 +209,7 @@ export function useComponentState({ if (!currency) return; const depositPaytoUri = stringifyPaytoUri(currentAccount); - const amountStr = Amounts.stringify(amount); + const amountStr = Amounts.stringify(totalEffective); await api.wallet.call(WalletApiOperation.CreateDepositGroup, { amount: amountStr, depositPaytoUri, @@ -220,8 +222,19 @@ export function useComponentState({ error: undefined, currency, amount: { - value: amount, - onInput: pushAlertOnError(async (a) => setAmount(a)), + value: totalEffective, + onInput: pushAlertOnError(async (a) => setInstructed({ + amount: a, + type: TransactionAmountMode.Effective, + })), + error: amountError, + }, + totalToDeposit: { + value: totalToDeposit, + onInput: pushAlertOnError(async (a) => setInstructed({ + amount: a, + type: TransactionAmountMode.Raw, + })), error: amountError, }, onAddAccount: { @@ -244,7 +257,6 @@ export function useComponentState({ onClick: unableToDeposit ? undefined : pushAlertOnError(doSend), }, totalFee, - totalToDeposit, }; }; } @@ -269,7 +281,7 @@ export function createLabelsForBankAccount( ): { [value: string]: string } { const initialList: Record<string, string> = {}; if (!knownBankAccounts.length) return initialList; - return knownBankAccounts.reduce((prev, cur, i) => { + return knownBankAccounts.reduce((prev, cur) => { prev[stringifyPaytoUri(cur.uri)] = cur.alias; return prev; }, initialList); diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx index c23f83fdd..0ed62220b 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx @@ -53,7 +53,10 @@ export const WithNoAccountForIBAN = tests.createExample(ReadyView, { onClick: nullFunction, }, totalFee: Amounts.zeroOfCurrency("USD"), - totalToDeposit: Amounts.parseOrThrow("USD:10"), + totalToDeposit: { + onInput:nullFunction, + value: Amounts.parseOrThrow("USD:10"), + }, // onCalculateFee: alwaysReturnFeeToOne, }); @@ -82,7 +85,10 @@ export const WithIBANAccountTypeSelected = tests.createExample(ReadyView, { onClick: nullFunction, }, totalFee: Amounts.zeroOfCurrency("USD"), - totalToDeposit: Amounts.parseOrThrow("USD:10"), + totalToDeposit: { + onInput:nullFunction, + value: Amounts.parseOrThrow("USD:10"), + }, // onCalculateFee: alwaysReturnFeeToOne, }); @@ -111,6 +117,9 @@ export const NewBitcoinAccountTypeSelected = tests.createExample(ReadyView, { onClick: nullFunction, }, totalFee: Amounts.zeroOfCurrency("USD"), - totalToDeposit: Amounts.parseOrThrow("USD:10"), + totalToDeposit: { + onInput:nullFunction, + value: Amounts.parseOrThrow("USD:10"), + }, // onCalculateFee: alwaysReturnFeeToOne, }); diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts index 157cb868a..1144095e1 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts @@ -20,17 +20,16 @@ */ import { + AmountResponse, Amounts, AmountString, - DepositGroupFees, parsePaytoUri, - PrepareDepositResponse, ScopeType, - stringifyPaytoUri, + stringifyPaytoUri } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { expect } from "chai"; import * as tests from "@gnu-taler/web-util/testing"; +import { expect } from "chai"; import { nullFunction } from "../../mui/handlers.js"; import { createWalletApiMock } from "../../test-utils.js"; @@ -38,24 +37,14 @@ import { useComponentState } from "./state.js"; const currency = "EUR"; const amount = `${currency}:0`; -const withoutFee = (): PrepareDepositResponse => ({ - effectiveDepositAmount: `${currency}:5` as AmountString, - totalDepositCost: `${currency}:5` as AmountString, - fees: { - coin: Amounts.stringify(`${currency}:0`), - wire: Amounts.stringify(`${currency}:0`), - refresh: Amounts.stringify(`${currency}:0`), - }, +const withoutFee = (value: number): AmountResponse => ({ + effectiveAmount: `${currency}:${value}` as AmountString, + rawAmount: `${currency}:${value}` as AmountString, }); -const withSomeFee = (): PrepareDepositResponse => ({ - effectiveDepositAmount: `${currency}:5` as AmountString, - totalDepositCost: `${currency}:5` as AmountString, - fees: { - coin: Amounts.stringify(`${currency}:1`), - wire: Amounts.stringify(`${currency}:1`), - refresh: Amounts.stringify(`${currency}:1`), - }, +const withSomeFee = (value: number, fee: number): AmountResponse => ({ + effectiveAmount: `${currency}:${value}` as AmountString, + rawAmount: `${currency}:${value - fee}` as AmountString, }); describe("DepositPage states", () => { @@ -195,9 +184,9 @@ describe("DepositPage states", () => { }, ); handler.addWalletCallResponse( - WalletApiOperation.PrepareDeposit, + WalletApiOperation.ConvertDepositAmount, undefined, - withoutFee(), + withoutFee(0), ); const hookBehavior = await tests.hookBehaveLikeThis( @@ -255,15 +244,15 @@ describe("DepositPage states", () => { }, ); handler.addWalletCallResponse( - WalletApiOperation.PrepareDeposit, + WalletApiOperation.ConvertDepositAmount, undefined, - withoutFee(), + withoutFee(0), ); handler.addWalletCallResponse( - WalletApiOperation.PrepareDeposit, + WalletApiOperation.ConvertDepositAmount, undefined, - withoutFee(), + withoutFee(0), ); const accountSelected = stringifyPaytoUri(ibanPayto.uri); @@ -345,19 +334,19 @@ describe("DepositPage states", () => { }, ); handler.addWalletCallResponse( - WalletApiOperation.PrepareDeposit, + WalletApiOperation.ConvertDepositAmount, undefined, - withoutFee(), + withoutFee(0), ); handler.addWalletCallResponse( - WalletApiOperation.PrepareDeposit, + WalletApiOperation.ConvertDepositAmount, undefined, - withSomeFee(), + withSomeFee(10,3), ); handler.addWalletCallResponse( - WalletApiOperation.PrepareDeposit, + WalletApiOperation.ConvertDepositAmount, undefined, - withSomeFee(), + withSomeFee(10,3), ); const accountSelected = stringifyPaytoUri(ibanPayto.uri); @@ -404,7 +393,7 @@ describe("DepositPage states", () => { expect(state.account.value).eq(accountSelected); expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:10")); expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); - expect(state.totalToDeposit).deep.eq( + expect(state.totalToDeposit.value).deep.eq( Amounts.parseOrThrow(`${currency}:7`), ); expect(state.depositHandler.onClick).not.undefined; @@ -416,7 +405,7 @@ describe("DepositPage states", () => { expect(state.account.value).eq(accountSelected); expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:10")); expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); - expect(state.totalToDeposit).deep.eq( + expect(state.totalToDeposit.value).deep.eq( Amounts.parseOrThrow(`${currency}:7`), ); expect(state.depositHandler.onClick).not.undefined; diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx index 37f1c252d..b3607ebba 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx @@ -26,7 +26,7 @@ import { Grid } from "../../mui/Grid.js"; import { State } from "./index.js"; export function AmountOrCurrencyErrorView( - p: State.AmountOrCurrencyError, + _p: State.AmountOrCurrencyError, ): VNode { const { i18n } = useTranslationContext(); @@ -156,12 +156,7 @@ export function ReadyView(state: State.Ready): VNode { /> </Grid> <Grid item xs={1}> - <AmountField - label={i18n.str`Net amount`} - handler={{ - value: state.totalToDeposit, - }} - /> + <AmountField label={i18n.str`Net amount`} handler={state.totalToDeposit} /> </Grid> </Grid> </section> @@ -180,7 +175,7 @@ export function ReadyView(state: State.Ready): VNode { ) : ( <Button variant="contained" onClick={state.depositHandler.onClick}> <i18n.Translate> - Deposit {Amounts.stringifyValue(state.totalToDeposit)}{" "} + Deposit {Amounts.stringifyValue(state.totalToDeposit.value)}{" "} {state.currency} </i18n.Translate> </Button> diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx b/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx index 7b80977f3..b995a44d0 100644 --- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx @@ -130,7 +130,6 @@ export function ReadyView({ ))} </div> <div style={{ border: "1px solid gray", padding: 8, borderRadius: 5 }}> - --- {uri.value} --- <p> <CustomFieldByAccountType type={accountType.value as AccountType} |