diff options
author | Sebastian <sebasjm@gmail.com> | 2023-04-19 12:42:47 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-04-19 12:42:47 -0300 |
commit | d483a3f5574355ed9c43eb6ddea59e5734323cf0 (patch) | |
tree | 2f4e3830512b50808b396991791c3c8877e5676e /packages/taler-wallet-webextension/src/wallet | |
parent | 7330f0daf907133876baf8831c44ec34cec326e5 (diff) | |
download | wallet-core-d483a3f5574355ed9c43eb6ddea59e5734323cf0.tar.xz |
fix #7704
Diffstat (limited to 'packages/taler-wallet-webextension/src/wallet')
6 files changed, 567 insertions, 513 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx index ff8cf0314..5c75b734b 100644 --- a/packages/taler-wallet-webextension/src/wallet/Application.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx @@ -20,15 +20,21 @@ * @author sebasjm */ +import { TranslatedString } from "@gnu-taler/taler-util"; import { - TalerUriAction, - TranslatedString, - parseTalerUri, -} from "@gnu-taler/taler-util"; + TranslationProvider, + useTranslationContext, +} from "@gnu-taler/web-util/lib/index.browser"; import { createHashHistory } from "history"; -import { ComponentChildren, Fragment, h, VNode } from "preact"; -import { route, Route, Router } from "preact-router"; +import { ComponentChildren, Fragment, VNode, h } from "preact"; +import { Route, Router, route } from "preact-router"; import { useEffect } from "preact/hooks"; +import { + Pages, + WalletNavBar, + WalletNavBarOptions, + getPathnameForTalerURI, +} from "../NavigationBar.js"; import { AlertView, CurrentAlerts } from "../components/CurrentAlerts.js"; import { LogoHeader } from "../components/LogoHeader.js"; import PendingTransactions from "../components/PendingTransactions.js"; @@ -39,12 +45,7 @@ import { WalletBox, } from "../components/styled/index.js"; import { AlertProvider } from "../context/alert.js"; -import { DevContextProvider } from "../context/devContext.js"; import { IoCProviderForRuntime } from "../context/iocContext.js"; -import { - TranslationProvider, - useTranslationContext, -} from "@gnu-taler/web-util/lib/index.browser"; import { DepositPage as DepositPageCTA } from "../cta/Deposit/index.js"; import { InvoiceCreatePage } from "../cta/InvoiceCreate/index.js"; import { InvoicePayPage } from "../cta/InvoicePay/index.js"; @@ -59,12 +60,7 @@ import { WithdrawPageFromParams, WithdrawPageFromURI, } from "../cta/Withdraw/index.js"; -import { - Pages, - WalletNavBar, - WalletNavBarOptions, - getPathnameForTalerURI, -} from "../NavigationBar.js"; +import { strings } from "../i18n/strings.js"; import { platform } from "../platform/foreground.js"; import CloseIcon from "../svg/close_24px.svg"; import { AddBackupProviderPage } from "./AddBackupProvider/index.js"; @@ -80,7 +76,6 @@ import { QrReaderPage } from "./QrReader.js"; import { SettingsPage } from "./Settings.js"; import { TransactionPage } from "./Transaction.js"; import { WelcomePage } from "./Welcome.js"; -import { strings } from "../i18n/strings.js"; export function Application(): VNode { const { i18n } = useTranslationContext(); @@ -91,433 +86,421 @@ export function Application(): VNode { } return ( <TranslationProvider source={strings}> - <DevContextProvider> - <IoCProviderForRuntime> - <Router history={hash_history}> - <Route - path={Pages.welcome} - component={() => ( - <WalletTemplate> - <WelcomePage /> - </WalletTemplate> - )} - /> + <IoCProviderForRuntime> + <Router history={hash_history}> + <Route + path={Pages.welcome} + component={() => ( + <WalletTemplate> + <WelcomePage /> + </WalletTemplate> + )} + /> - <Route - path={Pages.qr} - component={() => ( - <WalletTemplate goToTransaction={redirectToTxInfo}> - <QrReaderPage - onDetected={(talerActionUrl: string) => { - platform.openWalletURIFromPopup(talerActionUrl); - }} - /> - </WalletTemplate> - )} - /> + <Route + path={Pages.qr} + component={() => ( + <WalletTemplate goToTransaction={redirectToTxInfo}> + <QrReaderPage + onDetected={(talerActionUrl: string) => { + platform.openWalletURIFromPopup(talerActionUrl); + }} + /> + </WalletTemplate> + )} + /> - <Route - path={Pages.settings} - component={() => ( - <WalletTemplate goToTransaction={redirectToTxInfo}> - <SettingsPage /> - </WalletTemplate> - )} - /> - <Route - path={Pages.notifications} - component={() => ( - <WalletTemplate> - <NotificationsPage /> - </WalletTemplate> - )} - /> - {/** - * SETTINGS - */} - <Route - path={Pages.settingsExchangeAdd.pattern} - component={() => ( - <WalletTemplate> - <ExchangeAddPage onBack={() => redirectTo(Pages.balance)} /> - </WalletTemplate> - )} - /> + <Route + path={Pages.settings} + component={() => ( + <WalletTemplate goToTransaction={redirectToTxInfo}> + <SettingsPage /> + </WalletTemplate> + )} + /> + <Route + path={Pages.notifications} + component={() => ( + <WalletTemplate> + <NotificationsPage /> + </WalletTemplate> + )} + /> + {/** + * SETTINGS + */} + <Route + path={Pages.settingsExchangeAdd.pattern} + component={() => ( + <WalletTemplate> + <ExchangeAddPage onBack={() => redirectTo(Pages.balance)} /> + </WalletTemplate> + )} + /> - <Route - path={Pages.balanceHistory.pattern} - component={({ currency }: { currency?: string }) => ( - <WalletTemplate - path="balance" - goToTransaction={redirectToTxInfo} - > - <HistoryPage - currency={currency} - goToWalletDeposit={(currency: string) => - redirectTo(Pages.sendCash({ amount: `${currency}:0` })) - } - goToWalletManualWithdraw={(currency?: string) => - redirectTo( - Pages.receiveCash({ - amount: !currency ? undefined : `${currency}:0`, - }), - ) - } - /> - </WalletTemplate> - )} - /> - <Route - path={Pages.sendCash.pattern} - component={({ amount }: { amount?: string }) => ( - <WalletTemplate path="balance"> - <DestinationSelectionPage - type="send" - amount={amount} - goToWalletBankDeposit={(amount: string) => - redirectTo(Pages.balanceDeposit({ amount })) - } - goToWalletWalletSend={(amount: string) => - redirectTo(Pages.ctaTransferCreate({ amount })) - } - /> - </WalletTemplate> - )} - /> - <Route - path={Pages.receiveCash.pattern} - component={({ amount }: { amount?: string }) => ( - <WalletTemplate path="balance"> - <DestinationSelectionPage - type="get" - amount={amount} - goToWalletManualWithdraw={(amount?: string) => - redirectTo(Pages.ctaWithdrawManual({ amount })) - } - goToWalletWalletInvoice={(amount?: string) => - redirectTo(Pages.ctaInvoiceCreate({ amount })) - } - /> - </WalletTemplate> - )} - /> + <Route + path={Pages.balanceHistory.pattern} + component={({ currency }: { currency?: string }) => ( + <WalletTemplate path="balance" goToTransaction={redirectToTxInfo}> + <HistoryPage + currency={currency} + goToWalletDeposit={(currency: string) => + redirectTo(Pages.sendCash({ amount: `${currency}:0` })) + } + goToWalletManualWithdraw={(currency?: string) => + redirectTo( + Pages.receiveCash({ + amount: !currency ? undefined : `${currency}:0`, + }), + ) + } + /> + </WalletTemplate> + )} + /> + <Route + path={Pages.sendCash.pattern} + component={({ amount }: { amount?: string }) => ( + <WalletTemplate path="balance"> + <DestinationSelectionPage + type="send" + amount={amount} + goToWalletBankDeposit={(amount: string) => + redirectTo(Pages.balanceDeposit({ amount })) + } + goToWalletWalletSend={(amount: string) => + redirectTo(Pages.ctaTransferCreate({ amount })) + } + /> + </WalletTemplate> + )} + /> + <Route + path={Pages.receiveCash.pattern} + component={({ amount }: { amount?: string }) => ( + <WalletTemplate path="balance"> + <DestinationSelectionPage + type="get" + amount={amount} + goToWalletManualWithdraw={(amount?: string) => + redirectTo(Pages.ctaWithdrawManual({ amount })) + } + goToWalletWalletInvoice={(amount?: string) => + redirectTo(Pages.ctaInvoiceCreate({ amount })) + } + /> + </WalletTemplate> + )} + /> - <Route - path={Pages.balanceTransaction.pattern} - component={({ tid }: { tid: string }) => ( - <WalletTemplate path="balance"> - <TransactionPage - tid={tid} - goToWalletHistory={(currency?: string) => - redirectTo(Pages.balanceHistory({ currency })) - } - /> - </WalletTemplate> - )} - /> + <Route + path={Pages.balanceTransaction.pattern} + component={({ tid }: { tid: string }) => ( + <WalletTemplate path="balance"> + <TransactionPage + tid={tid} + goToWalletHistory={(currency?: string) => + redirectTo(Pages.balanceHistory({ currency })) + } + /> + </WalletTemplate> + )} + /> - <Route - path={Pages.balanceDeposit.pattern} - component={({ amount }: { amount: string }) => ( - <WalletTemplate path="balance"> - <DepositPage - amount={amount} - onCancel={(currency: string) => { - redirectTo(Pages.balanceHistory({ currency })); - }} - onSuccess={(currency: string) => { - redirectTo(Pages.balanceHistory({ currency })); - }} - /> - </WalletTemplate> - )} - /> + <Route + path={Pages.balanceDeposit.pattern} + component={({ amount }: { amount: string }) => ( + <WalletTemplate path="balance"> + <DepositPage + amount={amount} + onCancel={(currency: string) => { + redirectTo(Pages.balanceHistory({ currency })); + }} + onSuccess={(currency: string) => { + redirectTo(Pages.balanceHistory({ currency })); + }} + /> + </WalletTemplate> + )} + /> - <Route - path={Pages.backup} - component={() => ( - <WalletTemplate - path="backup" - goToTransaction={redirectToTxInfo} - > - <BackupPage - onAddProvider={() => redirectTo(Pages.backupProviderAdd)} - /> - </WalletTemplate> - )} - /> - <Route - path={Pages.backupProviderDetail.pattern} - component={({ pid }: { pid: string }) => ( - <WalletTemplate> - <ProviderDetailPage - pid={pid} - onPayProvider={(uri: string) => - redirectTo(`${Pages.ctaPay}?talerPayUri=${uri}`) - } - onWithdraw={(amount: string) => - redirectTo(Pages.receiveCash({ amount })) - } - onBack={() => redirectTo(Pages.backup)} - /> - </WalletTemplate> - )} - /> - <Route - path={Pages.backupProviderAdd} - component={() => ( - <WalletTemplate> - <AddBackupProviderPage - onPaymentRequired={(uri: string) => - redirectTo(`${Pages.ctaPay}?talerPayUri=${uri}`) - } - onComplete={(pid: string) => - redirectTo(Pages.backupProviderDetail({ pid })) - } - onBack={() => redirectTo(Pages.backup)} - /> - </WalletTemplate> - )} - /> + <Route + path={Pages.backup} + component={() => ( + <WalletTemplate path="backup" goToTransaction={redirectToTxInfo}> + <BackupPage + onAddProvider={() => redirectTo(Pages.backupProviderAdd)} + /> + </WalletTemplate> + )} + /> + <Route + path={Pages.backupProviderDetail.pattern} + component={({ pid }: { pid: string }) => ( + <WalletTemplate> + <ProviderDetailPage + pid={pid} + onPayProvider={(uri: string) => + redirectTo(`${Pages.ctaPay}?talerPayUri=${uri}`) + } + onWithdraw={(amount: string) => + redirectTo(Pages.receiveCash({ amount })) + } + onBack={() => redirectTo(Pages.backup)} + /> + </WalletTemplate> + )} + /> + <Route + path={Pages.backupProviderAdd} + component={() => ( + <WalletTemplate> + <AddBackupProviderPage + onPaymentRequired={(uri: string) => + redirectTo(`${Pages.ctaPay}?talerPayUri=${uri}`) + } + onComplete={(pid: string) => + redirectTo(Pages.backupProviderDetail({ pid })) + } + onBack={() => redirectTo(Pages.backup)} + /> + </WalletTemplate> + )} + /> - {/** - * DEV - */} - <Route - path={Pages.dev} - component={() => ( - <WalletTemplate path="dev" goToTransaction={redirectToTxInfo}> - <DeveloperPage /> - </WalletTemplate> - )} - /> + {/** + * DEV + */} + <Route + path={Pages.dev} + component={() => ( + <WalletTemplate path="dev" goToTransaction={redirectToTxInfo}> + <DeveloperPage /> + </WalletTemplate> + )} + /> - {/** - * CALL TO ACTION - */} - <Route - path={Pages.defaultCta.pattern} - component={({ uri }: { uri: string }) => { - const path = getPathnameForTalerURI(uri); - if (!path) { - return ( - <CallToActionTemplate title={i18n.str`Taler URI handler`}> - <AlertView - alert={{ - type: "warning", - message: i18n.str`Could not found a handler for the Taler URI`, - description: i18n.str`The uri read in the path parameter is not valid: "${uri}"`, - }} - /> - </CallToActionTemplate> - ); - } - return <Redirect to={path} />; - }} - /> - <Route - path={Pages.ctaPay} - component={({ talerUri }: { talerUri: string }) => ( - <CallToActionTemplate title={i18n.str`Digital cash payment`}> - <PaymentPage - talerPayUri={decodeURIComponent(talerUri)} - goToWalletManualWithdraw={(amount?: string) => - redirectTo(Pages.receiveCash({ amount })) - } - cancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} - /> - <Route - path={Pages.ctaPayTemplate} - component={({ talerUri }: { talerUri: string }) => ( - <CallToActionTemplate title={i18n.str`Digital cash payment`}> - <PaymentTemplatePage - talerTemplateUri={decodeURIComponent(talerUri)} - goToWalletManualWithdraw={(amount?: string) => - redirectTo(Pages.receiveCash({ amount })) - } - cancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} - /> - <Route - path={Pages.ctaRefund} - component={({ talerUri }: { talerUri: string }) => ( - <CallToActionTemplate title={i18n.str`Digital cash refund`}> - <RefundPage - talerRefundUri={decodeURIComponent(talerUri)} - cancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} - /> - <Route - path={Pages.ctaTips} - component={({ talerUri }: { talerUri: string }) => ( - <CallToActionTemplate title={i18n.str`Digital cash tip`}> - <TipPage - talerTipUri={decodeURIComponent(talerUri)} - onCancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} - /> - <Route - path={Pages.ctaWithdraw} - component={({ talerUri }: { talerUri: string }) => ( - <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}> - <WithdrawPageFromURI - talerWithdrawUri={decodeURIComponent(talerUri)} - cancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} - /> - <Route - path={Pages.ctaWithdrawManual.pattern} - component={({ amount }: { amount: string }) => ( - <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}> - <WithdrawPageFromParams - amount={amount} - cancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} - /> - <Route - path={Pages.ctaDeposit} - component={({ - amount, - talerUri, - }: { - amount: string; - talerUri: string; - }) => ( - <CallToActionTemplate title={i18n.str`Digital cash deposit`}> - <DepositPageCTA - amountStr={amount} - talerDepositUri={decodeURIComponent(talerUri)} - cancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} - /> - <Route - path={Pages.ctaInvoiceCreate.pattern} - component={({ amount }: { amount: string }) => ( - <CallToActionTemplate title={i18n.str`Digital cash invoice`}> - <InvoiceCreatePage - amount={amount} - onClose={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} - /> - <Route - path={Pages.ctaTransferCreate.pattern} - component={({ amount }: { amount: string }) => ( - <CallToActionTemplate title={i18n.str`Digital cash transfer`}> - <TransferCreatePage - amount={amount} - onClose={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} - /> - <Route - path={Pages.ctaInvoicePay} - component={({ talerUri }: { talerUri: string }) => ( - <CallToActionTemplate title={i18n.str`Digital cash invoice`}> - <InvoicePayPage - talerPayPullUri={decodeURIComponent(talerUri)} - goToWalletManualWithdraw={(amount?: string) => - redirectTo(Pages.receiveCash({ amount })) - } - onClose={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} - /> - <Route - path={Pages.ctaTransferPickup} - component={({ talerUri }: { talerUri: string }) => ( - <CallToActionTemplate title={i18n.str`Digital cash transfer`}> - <TransferPickupPage - talerPayPushUri={decodeURIComponent(talerUri)} - onClose={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} - /> - <Route - path={Pages.ctaRecovery} - component={({ - talerRecoveryUri, - }: { - talerRecoveryUri: string; - }) => ( - <CallToActionTemplate title={i18n.str`Digital cash recovery`}> - <RecoveryPage - talerRecoveryUri={decodeURIComponent(talerRecoveryUri)} - onCancel={() => redirectTo(Pages.balance)} - onSuccess={() => redirectTo(Pages.backup)} - /> - </CallToActionTemplate> - )} - /> + {/** + * CALL TO ACTION + */} + <Route + path={Pages.defaultCta.pattern} + component={({ uri }: { uri: string }) => { + const path = getPathnameForTalerURI(uri); + if (!path) { + return ( + <CallToActionTemplate title={i18n.str`Taler URI handler`}> + <AlertView + alert={{ + type: "warning", + message: i18n.str`Could not found a handler for the Taler URI`, + description: i18n.str`The uri read in the path parameter is not valid: "${uri}"`, + }} + /> + </CallToActionTemplate> + ); + } + return <Redirect to={path} />; + }} + /> + <Route + path={Pages.ctaPay} + component={({ talerUri }: { talerUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash payment`}> + <PaymentPage + talerPayUri={decodeURIComponent(talerUri)} + goToWalletManualWithdraw={(amount?: string) => + redirectTo(Pages.receiveCash({ amount })) + } + cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaPayTemplate} + component={({ talerUri }: { talerUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash payment`}> + <PaymentTemplatePage + talerTemplateUri={decodeURIComponent(talerUri)} + goToWalletManualWithdraw={(amount?: string) => + redirectTo(Pages.receiveCash({ amount })) + } + cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaRefund} + component={({ talerUri }: { talerUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash refund`}> + <RefundPage + talerRefundUri={decodeURIComponent(talerUri)} + cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaTips} + component={({ talerUri }: { talerUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash tip`}> + <TipPage + talerTipUri={decodeURIComponent(talerUri)} + onCancel={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaWithdraw} + component={({ talerUri }: { talerUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}> + <WithdrawPageFromURI + talerWithdrawUri={decodeURIComponent(talerUri)} + cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaWithdrawManual.pattern} + component={({ amount }: { amount: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}> + <WithdrawPageFromParams + amount={amount} + cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaDeposit} + component={({ + amount, + talerUri, + }: { + amount: string; + talerUri: string; + }) => ( + <CallToActionTemplate title={i18n.str`Digital cash deposit`}> + <DepositPageCTA + amountStr={amount} + talerDepositUri={decodeURIComponent(talerUri)} + cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaInvoiceCreate.pattern} + component={({ amount }: { amount: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash invoice`}> + <InvoiceCreatePage + amount={amount} + onClose={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaTransferCreate.pattern} + component={({ amount }: { amount: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash transfer`}> + <TransferCreatePage + amount={amount} + onClose={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaInvoicePay} + component={({ talerUri }: { talerUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash invoice`}> + <InvoicePayPage + talerPayPullUri={decodeURIComponent(talerUri)} + goToWalletManualWithdraw={(amount?: string) => + redirectTo(Pages.receiveCash({ amount })) + } + onClose={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaTransferPickup} + component={({ talerUri }: { talerUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash transfer`}> + <TransferPickupPage + talerPayPushUri={decodeURIComponent(talerUri)} + onClose={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaRecovery} + component={({ talerRecoveryUri }: { talerRecoveryUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash recovery`}> + <RecoveryPage + talerRecoveryUri={decodeURIComponent(talerRecoveryUri)} + onCancel={() => redirectTo(Pages.balance)} + onSuccess={() => redirectTo(Pages.backup)} + /> + </CallToActionTemplate> + )} + /> - {/** - * NOT FOUND - * all redirects should be at the end - */} - <Route - path={Pages.balance} - component={() => <Redirect to={Pages.balanceHistory({})} />} - /> + {/** + * NOT FOUND + * all redirects should be at the end + */} + <Route + path={Pages.balance} + component={() => <Redirect to={Pages.balanceHistory({})} />} + /> - <Route - default - component={() => <Redirect to={Pages.balanceHistory({})} />} - /> - </Router> - </IoCProviderForRuntime> - </DevContextProvider> + <Route + default + component={() => <Redirect to={Pages.balanceHistory({})} />} + /> + </Router> + </IoCProviderForRuntime> </TranslationProvider> ); } diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx index 7f239f33d..8416e17e9 100644 --- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx @@ -17,7 +17,7 @@ import { styled } from "@linaria/react"; import { Fragment, h, VNode } from "preact"; import { AmountField } from "../../components/AmountField.js"; -import { JustInDevMode } from "../../components/JustInDevMode.js"; +import { EnabledBySettings } from "../../components/EnabledBySettings.js"; import { SelectList } from "../../components/SelectList.js"; import { Input, @@ -300,11 +300,11 @@ export function ReadySendView({ required handler={amountHandler} /> - <JustInDevMode> + <EnabledBySettings name="advanceMode"> <Button onClick={sendAll.onClick}> <i18n.Translate>Send all</i18n.Translate> </Button> - </JustInDevMode> + </EnabledBySettings> </Grid> <Grid container spacing={1} columns={1}> diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts b/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts index 1f8ab4883..641b47cd7 100644 --- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts @@ -23,10 +23,10 @@ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useState } from "preact/hooks"; import { alertFromError, useAlertContext } from "../../context/alert.js"; import { useBackendContext } from "../../context/backend.js"; -import { useDevContext } from "../../context/devContext.js"; import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser"; import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js"; import { AccountByType, Props, State } from "./index.js"; +import { useSettings } from "../../hooks/useSettings.js"; export function useComponentState({ currency, @@ -39,12 +39,11 @@ export function useComponentState({ const hook = useAsyncAsHook(() => api.wallet.call(WalletApiOperation.ListKnownBankAccounts, { currency }), ); - const { devMode } = useDevContext(); const accountType: Record<string, string> = { iban: "IBAN", - // "x-taler-bank": "Taler Bank", }; - if (devMode) { + const [settings] = useSettings(); + if (settings.extendedAccountTypes) { accountType["bitcoin"] = "Bitcoin"; accountType["x-taler-bank"] = "Taler Bank"; } diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx index 53bc577d4..89d92b82c 100644 --- a/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx @@ -47,27 +47,27 @@ const version = { export const AllOff = tests.createExample(TestedComponent, { deviceName: "this-is-the-device-name", - devModeToggle: { value: false, button: {} }, + advanceToggle: { value: false, button: {} }, autoOpenToggle: { value: false, button: {} }, - clipboardToggle: { value: false, button: {} }, + langToggle: { value: false, button: {} }, setDeviceName: () => Promise.resolve(), ...version, }); export const OneChecked = tests.createExample(TestedComponent, { deviceName: "this-is-the-device-name", - devModeToggle: { value: false, button: {} }, + advanceToggle: { value: false, button: {} }, autoOpenToggle: { value: false, button: {} }, - clipboardToggle: { value: false, button: {} }, + langToggle: { value: false, button: {} }, setDeviceName: () => Promise.resolve(), ...version, }); export const WithOneExchange = tests.createExample(TestedComponent, { deviceName: "this-is-the-device-name", - devModeToggle: { value: false, button: {} }, + advanceToggle: { value: false, button: {} }, autoOpenToggle: { value: false, button: {} }, - clipboardToggle: { value: false, button: {} }, + langToggle: { value: false, button: {} }, setDeviceName: () => Promise.resolve(), knownExchanges: [ { @@ -89,9 +89,9 @@ export const WithExchangeInDifferentState = tests.createExample( TestedComponent, { deviceName: "this-is-the-device-name", - devModeToggle: { value: false, button: {} }, + advanceToggle: { value: false, button: {} }, autoOpenToggle: { value: false, button: {} }, - clipboardToggle: { value: false, button: {} }, + langToggle: { value: false, button: {} }, setDeviceName: () => Promise.resolve(), knownExchanges: [ { diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.tsx index ae3a6e688..62a6c55ff 100644 --- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx @@ -17,12 +17,15 @@ import { ExchangeListItem, ExchangeTosStatus, + TranslatedString, WalletCoreVersion, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { Fragment, h, VNode } from "preact"; +import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser"; +import { Fragment, VNode, h } from "preact"; +import { Pages } from "../NavigationBar.js"; import { Checkbox } from "../components/Checkbox.js"; -import { JustInDevMode } from "../components/JustInDevMode.js"; +import { EnabledBySettings } from "../components/EnabledBySettings.js"; import { Part } from "../components/Part.js"; import { SelectList } from "../components/SelectList.js"; import { @@ -35,25 +38,20 @@ import { } from "../components/styled/index.js"; import { useAlertContext } from "../context/alert.js"; import { useBackendContext } from "../context/backend.js"; -import { useDevContext } from "../context/devContext.js"; -import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; -import { useSettings } from "../hooks/useSettings.js"; import { useBackupDeviceName } from "../hooks/useBackupDeviceName.js"; import { useClipboardPermissions } from "../hooks/useClipboardPermissions.js"; +import { useSettings } from "../hooks/useSettings.js"; import { ToggleHandler } from "../mui/handlers.js"; -import { Pages } from "../NavigationBar.js"; import { platform } from "../platform/foreground.js"; +import { Settings } from "../platform/api.js"; const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined; export function SettingsPage(): VNode { const [settings, updateSettings] = useSettings(); - const clipboardToggle = useClipboardPermissions(); - const { devMode, toggle } = useDevContext(); const { safely } = useAlertContext(); const { name, update } = useBackupDeviceName(); - const { pushAlertOnError } = useAlertContext(); const webex = platform.getWalletWebExVersion(); const api = useBackendContext(); @@ -76,16 +74,24 @@ export function SettingsPage(): VNode { value: settings.injectTalerSupport, button: { onClick: safely("update support injection", async () => { - console.log("click", settings.injectTalerSupport); updateSettings("injectTalerSupport", !settings.injectTalerSupport); }), }, }} - clipboardToggle={clipboardToggle} - devModeToggle={{ - value: devMode, + advanceToggle={{ + value: settings.advanceMode, button: { - onClick: pushAlertOnError(toggle), + onClick: safely("update advance mode", async () => { + updateSettings("advanceMode", !settings.advanceMode); + }), + }, + }} + langToggle={{ + value: settings.langSelector, + button: { + onClick: safely("update lang selector", async () => { + updateSettings("langSelector", !settings.langSelector); + }), }, }} webexVersion={{ @@ -101,8 +107,8 @@ export interface ViewProps { deviceName: string; setDeviceName: (s: string) => Promise<void>; autoOpenToggle: ToggleHandler; - clipboardToggle: ToggleHandler; - devModeToggle: ToggleHandler; + advanceToggle: ToggleHandler; + langToggle: ToggleHandler; knownExchanges: Array<ExchangeListItem>; coreVersion: WalletCoreVersion | undefined; webexVersion: { @@ -114,8 +120,8 @@ export interface ViewProps { export function SettingsView({ knownExchanges, autoOpenToggle, - clipboardToggle, - devModeToggle, + advanceToggle, + langToggle, coreVersion, webexVersion, }: ViewProps): VNode { @@ -204,45 +210,19 @@ export function SettingsView({ </LinkPrimary> </div> - <JustInDevMode> - <SubTitle> - <i18n.Translate>Display</i18n.Translate> - </SubTitle> - <Input> - <SelectList - label={<i18n.Translate>Current Language</i18n.Translate>} - list={supportedLang} - name="lang" - value={lang} - onChange={(v) => changeLanguage(v)} - /> - </Input> - </JustInDevMode> - <SubTitle> - <i18n.Translate>Version</i18n.Translate> - </SubTitle> - {coreVersion && ( - <Part - title={i18n.str`Wallet Core`} - text={ - <span> - {coreVersion.version}{" "} - <JustInDevMode>{coreVersion.hash}</JustInDevMode> - </span> - } - /> - )} <Part title={i18n.str`Web Extension`} text={ <span> {webexVersion.version}{" "} - <JustInDevMode>{webexVersion.hash}</JustInDevMode> + <EnabledBySettings name="advanceMode"> + {webexVersion.hash} + </EnabledBySettings> </span> } /> {coreVersion && ( - <JustInDevMode> + <EnabledBySettings name="advanceMode"> <Part title={i18n.str`Exchange compatibility`} text={<span>{coreVersion.exchange}</span>} @@ -255,18 +235,42 @@ export function SettingsView({ title={i18n.str`Bank compatibility`} text={<span>{coreVersion.bank}</span>} /> - </JustInDevMode> + </EnabledBySettings> )} <SubTitle> - <i18n.Translate>Troubleshooting</i18n.Translate> + <i18n.Translate>Advance mode</i18n.Translate> </SubTitle> <Checkbox - label={i18n.str`Developer mode`} + label={i18n.str`Enable advance mode`} name="devMode" - description={i18n.str`More options and information useful for debugging`} - enabled={devModeToggle.value!} - onToggle={devModeToggle.button.onClick!} + description={i18n.str`Show more information and options in the UI`} + enabled={advanceToggle.value!} + onToggle={advanceToggle.button.onClick!} + /> + <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> + </SubTitle> + <Input> + <SelectList + label={<i18n.Translate>Current Language</i18n.Translate>} + list={supportedLang} + name="lang" + value={lang} + onChange={(v) => changeLanguage(v)} + /> + </Input> + </EnabledBySettings> <SubTitle> <i18n.Translate>Navigator</i18n.Translate> </SubTitle> @@ -283,6 +287,77 @@ export function SettingsView({ enabled={autoOpenToggle.value!} onToggle={autoOpenToggle.button.onClick!} /> + <SubTitle> + <i18n.Translate>Version</i18n.Translate> + </SubTitle> + {coreVersion && ( + <Part + title={i18n.str`Wallet Core`} + text={ + <span> + {coreVersion.version}{" "} + <EnabledBySettings name="advanceMode"> + {coreVersion.hash} + </EnabledBySettings> + </span> + } + /> + )} + </section> + </Fragment> + ); +} + +type Info = { label: TranslatedString; description: TranslatedString }; +type Options = { + [k in keyof Settings]?: Info; +}; +function AdvanceSettings(): VNode { + const [settings, updateSettings] = useSettings(); + const { i18n } = useTranslationContext(); + const o: Options = { + backup: { + label: i18n.str`Show backup feature`, + description: i18n.str`Backup integration still in beta.`, + }, + deleteActiveTransactions: { + label: i18n.str`Show delete active transaction`, + description: i18n.str`Deleting active transaction is not safe and you may loose your coins.`, + }, + extendedAccountTypes: { + label: i18n.str`Show more account types on deposit`, + description: i18n.str`Extends the UI to more payment target types.`, + }, + showJsonOnError: { + label: i18n.str`Show JSON on error`, + description: i18n.str`Print more information about the error. Useful for debugging.`, + }, + walletAllowHttp: { + label: i18n.str`Allow HTTP connections`, + description: i18n.str`Using HTTP connection may be faster but unsafe (wallet restart required)`, + }, + walletBatchWithdrawal: { + label: i18n.str`Allow batch withdrawals`, + description: i18n.str`Using the batch withdrawal API allows faster withdrawals (wallet restart required)`, + }, + }; + return ( + <Fragment> + <section> + {Object.entries(o).map(([name, { label, description }]) => { + const settingsName = name as keyof Settings; + return ( + <Checkbox + label={label} + name={name} + description={description} + enabled={settings[settingsName]} + onToggle={async () => { + updateSettings(settingsName, !settings[settingsName]); + }} + /> + ); + })} </section> </Fragment> ); diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx index 1ef0f0b79..9bcae8997 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx @@ -34,6 +34,7 @@ import { WithdrawalType, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser"; import { styled } from "@linaria/react"; import { differenceInSeconds, isPast } from "date-fns"; import { ComponentChildren, Fragment, h, VNode } from "preact"; @@ -43,7 +44,6 @@ import { Amount } from "../components/Amount.js"; import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType.js"; import { CopyButton } from "../components/CopyButton.js"; import { AlertView, ErrorAlertView } from "../components/CurrentAlerts.js"; -import { JustInDevMode } from "../components/JustInDevMode.js"; import { Loading } from "../components/Loading.js"; import { Kind, Part, PartCollapsible, PartPayto } from "../components/Part.js"; import { QR } from "../components/QR.js"; @@ -61,12 +61,12 @@ import { import { Time } from "../components/Time.js"; import { alertFromError, useAlertContext } from "../context/alert.js"; import { useBackendContext } from "../context/backend.js"; -import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { Button } from "../mui/Button.js"; import { SafeHandler } from "../mui/handlers.js"; import { Pages } from "../NavigationBar.js"; import { assertUnreachable } from "../utils/index.js"; +import { EnabledBySettings } from "../components/EnabledBySettings.js"; interface Props { tid: string; @@ -359,18 +359,15 @@ function TransactionTemplate({ <i18n.Translate>Cancel</i18n.Translate> </Button> ) : ( - //WORKAROUND - //Able to delete tx in dev mode - //FIXME: remove this when DD37 is implemented - <JustInDevMode> + <EnabledBySettings name="deleteActiveTransactions"> <Button variant="contained" color="error" onClick={doCheckBeforeForget as SafeHandler<void>} > - <i18n.Translate>Forget</i18n.Translate> + <i18n.Translate>Delete</i18n.Translate> </Button> - </JustInDevMode> + </EnabledBySettings> ) ) : ( <Button @@ -378,7 +375,7 @@ function TransactionTemplate({ color="error" onClick={doCheckBeforeForget as SafeHandler<void>} > - <i18n.Translate>Forget</i18n.Translate> + <i18n.Translate>Delete</i18n.Translate> </Button> )} </div> |