diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/wallet')
7 files changed, 104 insertions, 81 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.test.ts b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.test.ts index c757610fc..37c50285b 100644 --- a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.test.ts +++ b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.test.ts @@ -129,6 +129,8 @@ describe("CreateManualWithdraw states", () => { expect(parsedAmount).equal(undefined); + expect(amount.onInput).not.undefined; + if (!amount.onInput) return; amount.onInput("12"); } @@ -188,6 +190,8 @@ async function defaultTestForInputText( const field = getField(); const initialValue = field.value; nextValue = `${initialValue} something else`; + expect(field.onInput).not.undefined; + if (!field.onInput) return; field.onInput(nextValue); } diff --git a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx index 5320c6fe2..dd80faccd 100644 --- a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx +++ b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx @@ -260,7 +260,7 @@ export function CreateManualWithdraw({ <input type="number" value={state.amount.value} - onInput={(e) => state.amount.onInput(e.currentTarget.value)} + // onInput={(e) => state.amount.onInput(e.currentTarget.value)} /> </div> </InputWithLabel> diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts index 2693db79e..d8b752d44 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts @@ -49,7 +49,6 @@ export function useComponentState( parsed !== undefined ? Amounts.stringifyValue(parsed) : "0"; // const [accountIdx, setAccountIdx] = useState<number>(0); const [amount, setAmount] = useState(initialValue); - const [selectedAccount, setSelectedAccount] = useState<PaytoUri>(); const [fee, setFee] = useState<DepositGroupFees | undefined>(undefined); @@ -124,6 +123,16 @@ export function useComponentState( const firstAccount = accounts[0].uri const currentAccount = !selectedAccount ? firstAccount : selectedAccount; + if (fee === undefined && parsedAmount) { + getFeeForAmount(currentAccount, parsedAmount, api).then(initialFee => { + setFee(initialFee) + }) + return { + status: "loading", + error: undefined, + }; + } + const accountMap = createLabelsForBankAccount(accounts); async function updateAccountFromList(accountStr: string): Promise<void> { diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts index 9f336ac1a..17e17d185 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts @@ -167,6 +167,11 @@ describe("DepositPage states", () => { accounts: [ibanPayto], }, ); + handler.addWalletCallResponse( + WalletApiOperation.GetFeeForDeposit, + undefined, + withoutFee(), + ); const { pullLastResultOrThrow, waitForStateUpdate, assertNoPendingUpdate } = mountHook(() => useComponentState(props, mock)); @@ -177,6 +182,11 @@ describe("DepositPage states", () => { } expect(await waitForStateUpdate()).true; + { + const { status } = pullLastResultOrThrow(); + expect(status).equal("loading"); + } + expect(await waitForStateUpdate()).true; { const r = pullLastResultOrThrow(); @@ -219,6 +229,12 @@ describe("DepositPage states", () => { undefined, withoutFee(), ); + + handler.addWalletCallResponse( + WalletApiOperation.GetFeeForDeposit, + undefined, + withoutFee(), + ); handler.addWalletCallResponse( WalletApiOperation.GetFeeForDeposit, undefined, @@ -239,6 +255,12 @@ describe("DepositPage states", () => { } expect(await waitForStateUpdate()).true; + { + const { status } = pullLastResultOrThrow(); + expect(status).equal("loading"); + } + + expect(await waitForStateUpdate()).true; const accountSelected = stringifyPaytoUri(ibanPayto.uri); { @@ -364,6 +386,11 @@ describe("DepositPage states", () => { handler.addWalletCallResponse( WalletApiOperation.GetFeeForDeposit, undefined, + withoutFee(), + ); + handler.addWalletCallResponse( + WalletApiOperation.GetFeeForDeposit, + undefined, withSomeFee(), ); handler.addWalletCallResponse( @@ -381,6 +408,13 @@ describe("DepositPage states", () => { } expect(await waitForStateUpdate()).true; + + { + const { status } = pullLastResultOrThrow(); + expect(status).equal("loading"); + } + + expect(await waitForStateUpdate()).true; const accountSelected = stringifyPaytoUri(ibanPayto.uri); { @@ -409,6 +443,8 @@ describe("DepositPage states", () => { expect(r.depositHandler.onClick).undefined; expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); + expect(r.amount.onInput).not.undefined; + if (!r.amount.onInput) return; r.amount.onInput("10"); } diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx index e864c8413..771db828d 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx @@ -16,6 +16,7 @@ import { Amounts, PaytoUri } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; +import { AmountField } from "../../components/AmountField.js"; import { ErrorMessage } from "../../components/ErrorMessage.js"; import { LoadingError } from "../../components/LoadingError.js"; import { SelectList } from "../../components/SelectList.js"; @@ -28,6 +29,7 @@ import { } from "../../components/styled/index.js"; import { useTranslationContext } from "../../context/translation.js"; import { Button } from "../../mui/Button.js"; +import { Grid } from "../../mui/Grid.js"; import { State } from "./index.js"; export function LoadingErrorView({ error }: State.LoadingUriError): VNode { @@ -167,48 +169,33 @@ export function ReadyView(state: State.Ready): VNode { <p> <AccountDetails account={state.currentAccount} /> </p> - <InputWithLabel invalid={!!state.amount.error}> - <label> - <i18n.Translate>Amount</i18n.Translate> - </label> - <div> - <span>{state.currency}</span> - <input - type="number" - value={state.amount.value} - onInput={(e) => state.amount.onInput(e.currentTarget.value)} + <Grid container spacing={2} columns={1}> + <Grid item xs={1}> + <AmountField + label={<i18n.Translate>Amount</i18n.Translate>} + currency={state.currency} + handler={state.amount} /> - </div> - {state.amount.error && <ErrorText>{state.amount.error}</ErrorText>} - </InputWithLabel> - - <InputWithLabel> - <label> - <i18n.Translate>Deposit fee</i18n.Translate> - </label> - <div> - <span>{state.currency}</span> - <input - type="number" - disabled - value={Amounts.stringifyValue(state.totalFee)} + </Grid> + <Grid item xs={1}> + <AmountField + label={<i18n.Translate>Deposit fee</i18n.Translate>} + currency={state.currency} + handler={{ + value: Amounts.stringifyValue(state.totalFee), + }} /> - </div> - </InputWithLabel> - - <InputWithLabel> - <label> - <i18n.Translate>Total deposit</i18n.Translate> - </label> - <div> - <span>{state.currency}</span> - <input - type="number" - disabled - value={Amounts.stringifyValue(state.totalToDeposit)} + </Grid> + <Grid item xs={1}> + <AmountField + label={<i18n.Translate>Total deposit</i18n.Translate>} + currency={state.currency} + handler={{ + value: Amounts.stringifyValue(state.totalToDeposit), + }} /> - </div> - </InputWithLabel> + </Grid> + </Grid> </section> <footer> <Button diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx b/packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx index c584f2aae..ba1a560ef 100644 --- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx @@ -19,6 +19,7 @@ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { styled } from "@linaria/react"; import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; +import { AmountField } from "../components/AmountField.js"; import { Loading } from "../components/Loading.js"; import { LoadingError } from "../components/LoadingError.js"; import { SelectList } from "../components/SelectList.js"; @@ -32,6 +33,7 @@ import { useTranslationContext } from "../context/translation.js"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { Button } from "../mui/Button.js"; import { Grid } from "../mui/Grid.js"; +import { TextFieldHandler } from "../mui/handlers.js"; import { Paper } from "../mui/Paper.js"; import { TextField } from "../mui/TextField.js"; import { Pages } from "../NavigationBar.js"; @@ -283,11 +285,6 @@ export function DestinationSelectionGetCash({ const [currency, setCurrency] = useState(parsedInitialAmount?.currency); const [amount, setAmount] = useState(parsedInitialAmountValue); - function positiveSetAmount(e: string):void { - const value = Number.parseInt(e, 10); - if (value < 0) return - setAmount(String(value)) - } const { i18n } = useTranslationContext(); const previous1: Contact[] = []; const previous2: Contact[] = [ @@ -326,19 +323,13 @@ export function DestinationSelectionGetCash({ <i18n.Translate>Specify the amount and the origin</i18n.Translate> </h1> <Grid container columns={2} justifyContent="space-between"> - <TextField - label="Amount" - type="number" - min="0" - variant="filled" - error={invalid} + <AmountField + label={<i18n.Translate>Amount</i18n.Translate>} + currency={currency} required - startAdornment={ - <div style={{ padding: "25px 12px 8px 12px" }}>{currency}</div> - } - value={amount} - onChange={(e) => { - setAmount(e); + handler={{ + onInput: async (s) => setAmount(s), + value: amount, }} /> <Button onClick={async () => setCurrency(undefined)}> @@ -431,11 +422,6 @@ export function DestinationSelectionSendCash({ const currency = parsedInitialAmount?.currency; const [amount, setAmount] = useState(parsedInitialAmountValue); - function positiveSetAmount(e: string):void { - const value = Number.parseInt(e, 10); - if (value < 0) return - setAmount(String(value)) - } const { i18n } = useTranslationContext(); const previous1: Contact[] = []; const previous2: Contact[] = [ @@ -474,19 +460,13 @@ export function DestinationSelectionSendCash({ </h1> <div> - <TextField - label="Amount" - type="number" - min="0" - variant="filled" + <AmountField + label={<i18n.Translate>Amount</i18n.Translate>} + currency={currency} required - error={invalid} - startAdornment={ - <div style={{ padding: "25px 12px 8px 12px" }}>{currency}</div> - } - value={amount} - onChange={(e) => { - positiveSetAmount(e); + handler={{ + onInput: async (s) => setAmount(s), + value: amount, }} /> </div> diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx b/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx index 832ca91b7..326e078f4 100644 --- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx @@ -416,9 +416,10 @@ function BitcoinAddressAccount({ field }: { field: TextFieldHandler }): VNode { fullWidth value={value} error={value !== undefined && !!errors?.value} + disabled={!field.onInput} onChange={(v) => { setValue(v); - if (!errors) { + if (!errors && field.onInput) { field.onInput(`payto://bitcoin/${v}`); } }} @@ -456,9 +457,10 @@ function TalerBankAddressAccount({ fullWidth value={host} error={host !== undefined && !!errors?.host} + disabled={!field.onInput} onChange={(v) => { setHost(v); - if (!errors) { + if (!errors && field.onInput) { field.onInput(`payto://x-taler-bank/${v}/${account}`); } }} @@ -470,11 +472,12 @@ function TalerBankAddressAccount({ label="Bank account" variant="standard" fullWidth + disabled={!field.onInput} value={account} error={account !== undefined && !!errors?.account} onChange={(v) => { setAccount(v || ""); - if (!errors) { + if (!errors && field.onInput) { field.onInput(`payto://x-taler-bank/${host}/${v}`); } }} @@ -502,9 +505,10 @@ function IbanAddressAccount({ field }: { field: TextFieldHandler }): VNode { fullWidth value={number} error={number !== undefined && !!errors?.number} + disabled={!field.onInput} onChange={(v) => { setNumber(v); - if (!errors) { + if (!errors && field.onInput) { field.onInput(`payto://iban/${v}?receiver-name=${name}`); } }} @@ -518,10 +522,13 @@ function IbanAddressAccount({ field }: { field: TextFieldHandler }): VNode { fullWidth value={name} error={name !== undefined && !!errors?.name} + disabled={!field.onInput} onChange={(v) => { setName(v); - if (!errors) { - field.onInput(`payto://iban/${number}?receiver-name=${encodeURIComponent(v)}`); + if (!errors && field.onInput) { + field.onInput( + `payto://iban/${number}?receiver-name=${encodeURIComponent(v)}`, + ); } }} /> |