diff options
Diffstat (limited to 'packages/taler-wallet-webextension')
4 files changed, 135 insertions, 15 deletions
| diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts index ae4b3c436..f80e5a648 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts @@ -14,10 +14,18 @@   GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>   */ -import { AmountJson, ExchangeListItem } from "@gnu-taler/taler-util"; +import { +  AmountJson, +  AmountString, +  ExchangeListItem, +} from "@gnu-taler/taler-util";  import { Loading } from "../../components/Loading.js";  import { State as SelectExchangeState } from "../../hooks/useSelectedExchange.js"; -import { ButtonHandler, SelectFieldHandler } from "../../mui/handlers.js"; +import { +  AmountFieldHandler, +  ButtonHandler, +  SelectFieldHandler, +} from "../../mui/handlers.js";  import { StateViewMap, compose } from "../../utils/index.js";  import {    useComponentStateFromParams, @@ -37,10 +45,11 @@ export interface PropsFromURI {  }  export interface PropsFromParams { -  talerExchangeWithdrawUri: string; -  amount: string; +  talerExchangeWithdrawUri: string | undefined; +  amount: string | undefined;    cancel: () => Promise<void>;    onSuccess: (txid: string) => Promise<void>; +  onAmountChanged: (amount: AmountString) => Promise<void>;  }  export type State = @@ -64,7 +73,9 @@ export namespace State {    export interface SelectAmount {      status: "select-amount";      error: undefined; -    currentExchange: ExchangeListItem; +    exchangeBaseUrl: string; +    confirm: ButtonHandler; +    amount: AmountFieldHandler;      currency: string;    } diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts index f19f32ec0..46a72ac87 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts @@ -26,7 +26,7 @@ import {    stringifyWithdrawUri,  } from "@gnu-taler/taler-util";  import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { useState } from "preact/hooks"; +import { useEffect, 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"; @@ -39,16 +39,20 @@ export function useComponentStateFromParams({    talerExchangeWithdrawUri: maybeTalerUri,    amount,    cancel, +  onAmountChanged,    onSuccess,  }: PropsFromParams): RecursiveState<State> {    const api = useBackendContext();    const { i18n } = useTranslationContext(); +  const paramsAmount = amount ? Amounts.parse(amount) : undefined;    const uriInfoHook = useAsyncAsHook(async () => {      const exchanges = await api.wallet.call(        WalletApiOperation.ListExchanges,        {},      ); -    const uri = parseWithdrawExchangeUri(maybeTalerUri); +    const uri = maybeTalerUri +      ? parseWithdrawExchangeUri(maybeTalerUri) +      : undefined;      const exchangeByTalerUri = uri?.exchangeBaseUrl;      let ex: ExchangeFullDetails | undefined;      if (exchangeByTalerUri && uri.exchangePub) { @@ -65,11 +69,8 @@ export function useComponentStateFromParams({        ex = info.exchange;      } -    const chosenAmount = uri -      ? uri.amount -        ? Amounts.parseOrThrow(uri.amount) -        : Amounts.parseOrThrow(`${ex ? ex.currency : "KUDOS"}:66`) -      : Amounts.parseOrThrow(amount); +    const chosenAmount = +      !uri || !uri.amount ? undefined : Amounts.parse(uri.amount);      return { amount: chosenAmount, exchanges, exchange: ex };    }); @@ -85,10 +86,76 @@ export function useComponentStateFromParams({      };    } -  const chosenAmount = uriInfoHook.response.amount; +  useEffect(() => { +    uriInfoHook?.retry(); +  }, [amount]); +    const exchangeByTalerUri = uriInfoHook.response.exchange?.exchangeBaseUrl;    const exchangeList = uriInfoHook.response.exchanges.exchanges; +  const maybeAmount = uriInfoHook.response.amount ?? paramsAmount; + +  if (!maybeAmount) { +    const exchangeBaseUrl = +      uriInfoHook.response.exchange?.exchangeBaseUrl ?? +      (exchangeList.length > 0 ? exchangeList[0].exchangeBaseUrl : undefined); +    const currency = +      uriInfoHook.response.exchange?.currency ?? +      (exchangeList.length > 0 ? exchangeList[0].currency : undefined); + +    if (!exchangeBaseUrl) { +      return { +        status: "error", +        error: { +          message: i18n.str`Can't withdraw from exchange`, +          description: i18n.str`Missing base URL`, +          cause: undefined, +          context: {}, +          type: "error", +        }, +      }; +    } +    if (!currency) { +      return { +        status: "error", +        error: { +          message: i18n.str`Can't withdraw from exchange`, +          description: i18n.str`Missing unknown currency`, +          cause: undefined, +          context: {}, +          type: "error", +        }, +      }; +    } +    return () => { +      const { pushAlertOnError } = useAlertContext(); +      const [amount, setAmount] = useState<AmountJson>( +        Amounts.zeroOfCurrency(currency), +      ); +      const isValid = Amounts.isNonZero(amount); +      return { +        status: "select-amount", +        currency, +        exchangeBaseUrl, +        error: undefined, +        confirm: { +          onClick: isValid +            ? pushAlertOnError(async () => { +                onAmountChanged(Amounts.stringify(amount)); +              }) +            : undefined, +        }, +        amount: { +          value: amount, +          onInput: pushAlertOnError(async (e) => { +            setAmount(e); +          }), +        }, +      }; +    }; +  } +  const chosenAmount = maybeAmount; +    async function doManualWithdraw(      exchange: string,      ageRestricted: number | undefined, diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx index 57d6238b2..8a01edaaf 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx @@ -32,6 +32,8 @@ import {    WithdrawDetails,  } from "../../wallet/Transaction.js";  import { State } from "./index.js"; +import { Grid } from "../../mui/Grid.js"; +import { AmountField } from "../../components/AmountField.js";  export function SuccessView(state: State.Success): VNode {    const { i18n } = useTranslationContext(); @@ -143,11 +145,45 @@ function WithdrawWithMobile({    );  } -export function SelectAmountView({ currency }: State.SelectAmount): VNode { +export function SelectAmountView({ +  currency, +  amount, +  exchangeBaseUrl, +  confirm, +}: State.SelectAmount): VNode {    const { i18n } = useTranslationContext();    return (      <Fragment> -      <p>select the amount for ${currency}</p> +      <section style={{ textAlign: "left" }}> +        <Part +          title={ +            <div +              style={{ +                display: "flex", +                alignItems: "center", +              }} +            > +              <i18n.Translate>Exchange</i18n.Translate> +            </div> +          } +          text={<ExchangeDetails exchange={exchangeBaseUrl} />} +          kind="neutral" +          big +        /> +        <Grid container columns={2} justifyContent="space-between"> +          <AmountField label={i18n.str`Amount`} required handler={amount} /> +        </Grid> +      </section> +      <section> +        <Button +          variant="contained" +          color="info" +          disabled={!confirm.onClick} +          onClick={confirm.onClick} +        > +          <i18n.Translate>See details</i18n.Translate> +        </Button> +      </section>      </Fragment>    );  } diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx index 7d4dafb56..d8cb22bf0 100644 --- a/packages/taler-wallet-webextension/src/wallet/Application.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx @@ -400,6 +400,12 @@ export function Application(): VNode {              }) => (                <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}>                  <WithdrawPageFromParams +                  onAmountChanged={async (e) => { +                    const page = `${Pages.ctaWithdrawManual({ +                      amount, +                    })}?talerUri=${encodeURIComponent(talerUri)}`; +                    redirectTo(page); +                  }}                    talerExchangeWithdrawUri={talerUri}                    amount={amount}                    cancel={() => redirectTo(Pages.balance)} | 
