diff options
Diffstat (limited to 'packages/taler-wallet-webextension')
8 files changed, 74 insertions, 18 deletions
diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx b/packages/taler-wallet-webextension/src/NavigationBar.tsx index dd2d31c3d..231418861 100644 --- a/packages/taler-wallet-webextension/src/NavigationBar.tsx +++ b/packages/taler-wallet-webextension/src/NavigationBar.tsx @@ -84,7 +84,7 @@ function pageDefinition<T extends object>(pattern: string): PageLocation<T> { return { ...prev, [name]: cur }; }, {} as Record<string, string>); - const f = (values: T): string => replaceAll(pattern, vars, values); + const f = (values: T): string => replaceAll(pattern, vars, values ?? {}); f.pattern = pattern; return f; } @@ -152,6 +152,7 @@ const talerUriActionToPageName: { [TalerUriAction.PayPush]: "ctaTransferPickup", [TalerUriAction.Restore]: "ctaRecovery", [TalerUriAction.PayTemplate]: "ctaPayTemplate", + [TalerUriAction.WithdrawExchange]: "ctaWithdrawManual", [TalerUriAction.DevExperiment]: undefined, [TalerUriAction.Exchange]: undefined, [TalerUriAction.Auditor]: undefined, @@ -166,7 +167,11 @@ export function getPathnameForTalerURI(talerUri: string): string | undefined { if (!pageName) { return undefined; } - return `${Pages[pageName]}?talerUri=${encodeURIComponent(talerUri)}`; + const pageString: string = + typeof Pages[pageName] === "function" + ? (Pages[pageName] as any)() + : Pages[pageName]; + return `${pageString}?talerUri=${encodeURIComponent(talerUri)}`; } export type PopupNavBarOptions = "balance" | "backup" | "dev"; diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts index 45c37ba5c..ae4b3c436 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts @@ -16,20 +16,19 @@ import { AmountJson, ExchangeListItem } from "@gnu-taler/taler-util"; import { Loading } from "../../components/Loading.js"; -import { HookError } from "../../hooks/useAsyncAsHook.js"; import { State as SelectExchangeState } from "../../hooks/useSelectedExchange.js"; import { ButtonHandler, SelectFieldHandler } from "../../mui/handlers.js"; -import { compose, StateViewMap } from "../../utils/index.js"; +import { StateViewMap, compose } from "../../utils/index.js"; import { useComponentStateFromParams, useComponentStateFromURI, } from "./state.js"; +import { ErrorAlertView } from "../../components/CurrentAlerts.js"; +import { ErrorAlert } from "../../context/alert.js"; import { ExchangeSelectionPage } from "../../wallet/ExchangeSelection/index.js"; import { NoExchangesView } from "../../wallet/ExchangeSelection/views.js"; -import { SuccessView } from "./views.js"; -import { ErrorAlert } from "../../context/alert.js"; -import { ErrorAlertView } from "../../components/CurrentAlerts.js"; +import { SelectAmountView, SuccessView } from "./views.js"; export interface PropsFromURI { talerWithdrawUri: string | undefined; @@ -38,6 +37,7 @@ export interface PropsFromURI { } export interface PropsFromParams { + talerExchangeWithdrawUri: string; amount: string; cancel: () => Promise<void>; onSuccess: (txid: string) => Promise<void>; @@ -48,6 +48,7 @@ export type State = | State.LoadingUriError | SelectExchangeState.NoExchangeFound | SelectExchangeState.Selecting + | State.SelectAmount | State.Success; export namespace State { @@ -60,6 +61,13 @@ export namespace State { error: ErrorAlert; } + export interface SelectAmount { + status: "select-amount"; + error: undefined; + currentExchange: ExchangeListItem; + currency: string; + } + export type Success = { status: "success"; error: undefined; @@ -84,13 +92,14 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, error: ErrorAlertView, + "select-amount": SelectAmountView, "no-exchange-found": NoExchangesView, "selecting-exchange": ExchangeSelectionPage, success: SuccessView, }; export const WithdrawPageFromURI = compose( - "WithdrawPageFromURI", + "WithdrawPageFromURI_Withdraw", (p: PropsFromURI) => useComponentStateFromURI(p), viewMapping, ); diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts index 717d3ba6b..f19f32ec0 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts @@ -18,9 +18,12 @@ import { AmountJson, Amounts, + ExchangeFullDetails, ExchangeListItem, ExchangeTosStatus, TalerError, + parseWithdrawExchangeUri, + stringifyWithdrawUri, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; @@ -33,6 +36,7 @@ import { RecursiveState } from "../../utils/index.js"; import { PropsFromParams, PropsFromURI, State } from "./index.js"; export function useComponentStateFromParams({ + talerExchangeWithdrawUri: maybeTalerUri, amount, cancel, onSuccess, @@ -44,7 +48,29 @@ export function useComponentStateFromParams({ WalletApiOperation.ListExchanges, {}, ); - return { amount: Amounts.parseOrThrow(amount), exchanges }; + const uri = parseWithdrawExchangeUri(maybeTalerUri); + const exchangeByTalerUri = uri?.exchangeBaseUrl; + let ex: ExchangeFullDetails | undefined; + if (exchangeByTalerUri && uri.exchangePub) { + await api.wallet.call(WalletApiOperation.AddExchange, { + exchangeBaseUrl: exchangeByTalerUri, + masterPub: uri.exchangePub, + }); + const info = await api.wallet.call( + WalletApiOperation.GetExchangeDetailedInfo, + { + exchangeBaseUrl: exchangeByTalerUri, + }, + ); + + ex = info.exchange; + } + const chosenAmount = uri + ? uri.amount + ? Amounts.parseOrThrow(uri.amount) + : Amounts.parseOrThrow(`${ex ? ex.currency : "KUDOS"}:66`) + : Amounts.parseOrThrow(amount); + return { amount: chosenAmount, exchanges, exchange: ex }; }); if (!uriInfoHook) return { status: "loading", error: undefined }; @@ -60,6 +86,7 @@ export function useComponentStateFromParams({ } const chosenAmount = uriInfoHook.response.amount; + const exchangeByTalerUri = uriInfoHook.response.exchange?.exchangeBaseUrl; const exchangeList = uriInfoHook.response.exchanges.exchanges; async function doManualWithdraw( @@ -92,7 +119,7 @@ export function useComponentStateFromParams({ undefined, chosenAmount, exchangeList, - undefined, + exchangeByTalerUri, ); } diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx index 50bf99a0c..57d6238b2 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx @@ -142,3 +142,12 @@ function WithdrawWithMobile({ </section> ); } + +export function SelectAmountView({ currency }: State.SelectAmount): VNode { + const { i18n } = useTranslationContext(); + return ( + <Fragment> + <p>select the amount for ${currency}</p> + </Fragment> + ); +} diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts b/packages/taler-wallet-webextension/src/platform/chrome.ts index 34057a310..65670fb69 100644 --- a/packages/taler-wallet-webextension/src/platform/chrome.ts +++ b/packages/taler-wallet-webextension/src/platform/chrome.ts @@ -259,6 +259,7 @@ function openWalletURIFromPopup(uri: TalerUri): void { encodeURIComponent; let url: string | undefined = undefined; switch (uri.type) { + case TalerUriAction.WithdrawExchange: case TalerUriAction.Withdraw: url = chrome.runtime.getURL( `static/wallet.html#/cta/withdraw?talerUri=${encodeURIComponent( diff --git a/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx b/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx index af966a5ae..6a0585907 100644 --- a/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx +++ b/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx @@ -40,6 +40,7 @@ function ContentByUriType({ }) { const { i18n } = useTranslationContext(); switch (uri.type) { + case TalerUriAction.WithdrawExchange: case TalerUriAction.Withdraw: return ( <div> diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx index 13afccb6c..7d4dafb56 100644 --- a/packages/taler-wallet-webextension/src/wallet/Application.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx @@ -391,9 +391,16 @@ export function Application(): VNode { /> <Route path={Pages.ctaWithdrawManual.pattern} - component={({ amount }: { amount: string }) => ( + component={({ + amount, + talerUri, + }: { + amount: string; + talerUri: string; + }) => ( <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}> <WithdrawPageFromParams + talerExchangeWithdrawUri={talerUri} amount={amount} cancel={() => redirectTo(Pages.balance)} onSuccess={(tid: string) => diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.tsx index 6ca443d10..10bcee314 100644 --- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx @@ -250,13 +250,6 @@ export function SettingsView({ <EnabledBySettings name="advanceMode"> <AdvanceSettings /> </EnabledBySettings> - <Checkbox - label={i18n.str`Lang selector`} - name="langSelector" - description={i18n.str`Allows to manually change the language of the UI. Otherwise it will be automatically selected by your browser configuration.`} - enabled={langToggle.value!} - onToggle={langToggle.button.onClick!} - /> <EnabledBySettings name="langSelector"> <SubTitle> <i18n.Translate>Display</i18n.Translate> @@ -340,6 +333,10 @@ function AdvanceSettings(): VNode { label: i18n.str`Allow batch withdrawals`, description: i18n.str`Using the batch withdrawal API allows faster withdrawals (wallet restart required)`, }, + langSelector: { + label: i18n.str`Lang selector`, + description: i18n.str`Allows to manually change the language of the UI. Otherwise it will be automatically selected by your browser configuration.`, + }, }; return ( <Fragment> |