diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/wallet')
5 files changed, 468 insertions, 309 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts index 94020069b..10fcd84ce 100644 --- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts +++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts @@ -32,7 +32,6 @@ import { } from "./views.js"; export interface Props { - currency: string; onBack: () => Promise<void>; onComplete: (pid: string) => Promise<void>; onPaymentRequired: (uri: string) => Promise<void>; diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts index 32c48be91..1b30ed0cd 100644 --- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts +++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/state.ts @@ -144,7 +144,6 @@ function useUrlState<T>( } export function useComponentState({ - currency, onBack, onComplete, onPaymentRequired, diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts index 9abb672fa..3241a3ab0 100644 --- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts +++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/test.ts @@ -26,7 +26,6 @@ import { Props } from "./index.js"; import { useComponentState } from "./state.js"; const props: Props = { - currency: "KUDOS", onBack: nullFunction, onComplete: nullFunction, onPaymentRequired: nullFunction, diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx index d150ebfaf..8b77e152c 100644 --- a/packages/taler-wallet-webextension/src/wallet/Application.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx @@ -20,352 +20,452 @@ * @author sebasjm */ +import { TranslatedString } from "@gnu-taler/taler-util"; import { createHashHistory } from "history"; -import { Fragment, h, VNode } from "preact"; +import { ComponentChildren, Fragment, h, VNode } from "preact"; import Router, { route, Route } from "preact-router"; -import Match from "preact-router/match"; -import { useEffect, useState } from "preact/hooks"; +import { useEffect } from "preact/hooks"; import { LogoHeader } from "../components/LogoHeader.js"; import PendingTransactions from "../components/PendingTransactions.js"; -import { SuccessBox, WalletBox } from "../components/styled/index.js"; +import { + SubTitle, + WalletAction, + WalletBox, +} from "../components/styled/index.js"; import { DevContextProvider } from "../context/devContext.js"; import { IoCProviderForRuntime } from "../context/iocContext.js"; import { TranslationProvider, useTranslationContext, } from "../context/translation.js"; +import { DepositPage as DepositPageCTA } from "../cta/Deposit/index.js"; +import { InvoiceCreatePage } from "../cta/InvoiceCreate/index.js"; +import { InvoicePayPage } from "../cta/InvoicePay/index.js"; import { PaymentPage } from "../cta/Payment/index.js"; +import { RecoveryPage } from "../cta/Recovery/index.js"; import { RefundPage } from "../cta/Refund/index.js"; import { TipPage } from "../cta/Tip/index.js"; +import { TransferCreatePage } from "../cta/TransferCreate/index.js"; +import { TransferPickupPage } from "../cta/TransferPickup/index.js"; import { WithdrawPageFromParams, WithdrawPageFromURI, } from "../cta/Withdraw/index.js"; -import { DepositPage as DepositPageCTA } from "../cta/Deposit/index.js"; -import { Pages, WalletNavBar } from "../NavigationBar.js"; -import { DeveloperPage } from "./DeveloperPage.js"; +import { WalletNavBarOptions, Pages, WalletNavBar } from "../NavigationBar.js"; +import { platform } from "../platform/api.js"; +import { AddBackupProviderPage } from "./AddBackupProvider/index.js"; import { BackupPage } from "./BackupPage.js"; import { DepositPage } from "./DepositPage/index.js"; +import { DestinationSelectionPage } from "./DestinationSelection/index.js"; +import { DeveloperPage } from "./DeveloperPage.js"; import { ExchangeAddPage } from "./ExchangeAddPage.js"; import { HistoryPage } from "./History.js"; +import { NotificationsPage } from "./Notifications/index.js"; import { ProviderDetailPage } from "./ProviderDetailPage.js"; +import { QrReaderPage } from "./QrReader.js"; import { SettingsPage } from "./Settings.js"; import { TransactionPage } from "./Transaction.js"; import { WelcomePage } from "./Welcome.js"; -import { QrReaderPage } from "./QrReader.js"; -import { platform } from "../platform/api.js"; -import { DestinationSelectionPage } from "./DestinationSelection/index.js"; -import { ExchangeSelectionPage } from "./ExchangeSelection/index.js"; -import { TransferCreatePage } from "../cta/TransferCreate/index.js"; -import { InvoiceCreatePage } from "../cta/InvoiceCreate/index.js"; -import { TransferPickupPage } from "../cta/TransferPickup/index.js"; -import { InvoicePayPage } from "../cta/InvoicePay/index.js"; -import { RecoveryPage } from "../cta/Recovery/index.js"; -import { AddBackupProviderPage } from "./AddBackupProvider/index.js"; -import { NotificationsPage } from "./Notifications/index.js"; export function Application(): VNode { - const [globalNotification, setGlobalNotification] = useState< - VNode | undefined - >(undefined); - const hash_history = createHashHistory(); - function clearNotification(): void { - setGlobalNotification(undefined); - } - function clearNotificationWhenMovingOut(): void { - // const movingOutFromNotification = - // globalNotification && e.url !== globalNotification.to; - if (globalNotification) { - //&& movingOutFromNotification) { - setGlobalNotification(undefined); - } - } const { i18n } = useTranslationContext(); + const hash_history = createHashHistory(); + async function redirectToTxInfo(tid: string): Promise<void> { + redirectTo(Pages.balanceTransaction({ tid })); + } return ( <TranslationProvider> <DevContextProvider> <IoCProviderForRuntime> - {/* <Match/> won't work in the first render if <Router /> is not called first */} - {/* https://github.com/preactjs/preact-router/issues/415 */} <Router history={hash_history}> - <Match default> - {({ path }: { path: string }) => { - if (path && path.startsWith("/cta")) return; - return ( - <Fragment> - <LogoHeader /> - <WalletNavBar path={path} /> - {shouldShowPendingOperations(path) && ( - <div - style={{ - backgroundColor: "lightcyan", - display: "flex", - justifyContent: "center", - }} - > - <PendingTransactions - goToTransaction={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </div> - )} - </Fragment> - ); - }} - </Match> - </Router> - <WalletBox> - {globalNotification && ( - <SuccessBox onClick={clearNotification}> - <div>{globalNotification}</div> - </SuccessBox> - )} - <Router - history={hash_history} - onChange={clearNotificationWhenMovingOut} - > - <Route path={Pages.welcome} component={WelcomePage} /> - - {/** - * BALANCE - */} + <Route + path={Pages.welcome} + component={() => ( + <WalletTemplate> + <WelcomePage /> + </WalletTemplate> + )} + /> - <Route - path={Pages.balanceHistory.pattern} - component={HistoryPage} - goToWalletDeposit={(currency: string) => - redirectTo(Pages.sendCash({ amount: `${currency}:0` })) - } - goToWalletManualWithdraw={(currency?: string) => - redirectTo( - Pages.receiveCash({ - amount: !currency ? undefined : `${currency}:0`, - }), - ) - } - /> - <Route path={Pages.exchanges} component={ExchangeSelectionPage} /> - <Route - path={Pages.sendCash.pattern} - type="send" - component={DestinationSelectionPage} - goToWalletBankDeposit={(amount: string) => - redirectTo(Pages.balanceDeposit({ amount })) - } - goToWalletWalletSend={(amount: string) => - redirectTo(Pages.ctaTransferCreate({ amount })) - } - /> - <Route - path={Pages.receiveCash.pattern} - type="get" - component={DestinationSelectionPage} - goToWalletManualWithdraw={(amount?: string) => - redirectTo(Pages.ctaWithdrawManual({ amount })) - } - goToWalletWalletInvoice={(amount?: string) => - redirectTo(Pages.ctaInvoiceCreate({ amount })) - } - /> + <Route + path={Pages.qr} + component={() => ( + <WalletTemplate goToTransaction={redirectToTxInfo}> + <QrReaderPage + onDetected={(talerActionUrl: string) => { + platform.openWalletURIFromPopup(talerActionUrl); + }} + /> + </WalletTemplate> + )} + /> - <Route - path={Pages.balanceTransaction.pattern} - component={TransactionPage} - goToWalletHistory={(currency?: string) => - redirectTo(Pages.balanceHistory({ currency })) - } - /> + <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.balanceDeposit.pattern} - component={DepositPage} - onCancel={(currency: string) => { - redirectTo(Pages.balanceHistory({ currency })); - }} - onSuccess={(currency: string) => { - redirectTo(Pages.balanceHistory({ currency })); - setGlobalNotification( - <i18n.Translate> - All done, your transaction is in progress - </i18n.Translate>, - ); - }} - /> - {/** - * PENDING - */} - <Route - path={Pages.qr} - component={QrReaderPage} - onDetected={(talerActionUrl: string) => { - platform.openWalletURIFromPopup(talerActionUrl); - }} - /> + <Route + path={Pages.balanceHistory.pattern} + component={() => ( + <WalletTemplate + path="balance" + goToTransaction={redirectToTxInfo} + > + <HistoryPage + 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.settings} component={SettingsPage} /> - <Route path={Pages.notifications} component={NotificationsPage} /> + <Route + path={Pages.balanceTransaction.pattern} + component={({ tid }: { tid: string }) => ( + <WalletTemplate path="balance"> + <TransactionPage + tid={tid} + goToWalletHistory={(currency?: string) => + redirectTo(Pages.balanceHistory({ currency })) + } + /> + </WalletTemplate> + )} + /> - {/** - * BACKUP - */} - <Route - path={Pages.backup} - component={BackupPage} - onAddProvider={() => redirectTo(Pages.backupProviderAdd)} - /> - <Route - path={Pages.backupProviderDetail.pattern} - component={ProviderDetailPage} - onPayProvider={(uri: string) => - redirectTo(`${Pages.ctaPay}?talerPayUri=${uri}`) - } - onWithdraw={(amount: string) => - redirectTo(Pages.receiveCash({ amount })) - } - onBack={() => redirectTo(Pages.backup)} - /> - <Route - path={Pages.backupProviderAdd} - component={AddBackupProviderPage} - onPaymentRequired={(uri: string) => - redirectTo(`${Pages.ctaPay}?talerPayUri=${uri}`) - } - onComplete={(pid: string) => - redirectTo(Pages.backupProviderDetail({ pid })) - } - onBack={() => redirectTo(Pages.backup)} - /> + <Route + path={Pages.balanceDeposit.pattern} + component={() => ( + <WalletTemplate path="balance"> + <DepositPage + onCancel={(currency: string) => { + redirectTo(Pages.balanceHistory({ currency })); + }} + onSuccess={(currency: string) => { + redirectTo(Pages.balanceHistory({ currency })); + }} + /> + </WalletTemplate> + )} + /> - {/** - * SETTINGS - */} - <Route - path={Pages.settingsExchangeAdd.pattern} - component={ExchangeAddPage} - onBack={() => redirectTo(Pages.balance)} - /> + <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 - */} + {/** + * DEV + */} + <Route + path={Pages.dev} + component={() => ( + <WalletTemplate path="dev" goToTransaction={redirectToTxInfo}> + <DeveloperPage /> + </WalletTemplate> + )} + /> - <Route path={Pages.dev} component={DeveloperPage} /> + {/** + * CALL TO ACTION + */} + <Route + path={Pages.ctaPay} + component={({ talerPayUri }: { talerPayUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash payment`}> + <PaymentPage + talerPayUri={talerPayUri} + goToWalletManualWithdraw={(amount?: string) => + redirectTo(Pages.receiveCash({ amount })) + } + cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaRefund} + component={({ talerRefundUri }: { talerRefundUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash refund`}> + <RefundPage + talerRefundUri={talerRefundUri} + cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaTips} + component={({ talerTipUri }: { talerTipUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash tip`}> + <TipPage + talerTipUri={talerTipUri} + onCancel={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaWithdraw} + component={({ + talerWithdrawUri, + }: { + talerWithdrawUri: string; + }) => ( + <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}> + <WithdrawPageFromURI + talerWithdrawUri={talerWithdrawUri} + 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={({ + amountStr, + talerDepositUri, + }: { + amountStr: string; + talerDepositUri: string; + }) => ( + <CallToActionTemplate title={i18n.str`Digital cash deposit`}> + <DepositPageCTA + amountStr={amountStr} + talerDepositUri={talerDepositUri} + 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={({ talerPayPullUri }: { talerPayPullUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash invoice`}> + <InvoicePayPage + talerPayPullUri={talerPayPullUri} + goToWalletManualWithdraw={(amount?: string) => + redirectTo(Pages.receiveCash({ amount })) + } + onClose={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + )} + /> + <Route + path={Pages.ctaTransferPickup} + component={({ talerPayPushUri }: { talerPayPushUri: string }) => ( + <CallToActionTemplate title={i18n.str`Digital cash transfer`}> + <TransferPickupPage + talerPayPushUri={talerPayPushUri} + 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={talerRecoveryUri} + onCancel={() => redirectTo(Pages.balance)} + onSuccess={() => redirectTo(Pages.backup)} + /> + </CallToActionTemplate> + )} + /> - {/** - * CALL TO ACTION - */} - <Route - path={Pages.ctaPay} - component={PaymentPage} - goToWalletManualWithdraw={(amount?: string) => - redirectTo(Pages.receiveCash({ amount })) - } - cancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - <Route - path={Pages.ctaRefund} - component={RefundPage} - cancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - <Route - path={Pages.ctaTips} - component={TipPage} - onCancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - <Route - path={Pages.ctaWithdraw} - component={WithdrawPageFromURI} - cancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - <Route - path={Pages.ctaWithdrawManual.pattern} - component={WithdrawPageFromParams} - cancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - <Route - path={Pages.ctaDeposit} - component={DepositPageCTA} - cancel={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - <Route - path={Pages.ctaInvoiceCreate.pattern} - component={InvoiceCreatePage} - onClose={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - <Route - path={Pages.ctaTransferCreate.pattern} - component={TransferCreatePage} - onClose={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - <Route - path={Pages.ctaInvoicePay} - component={InvoicePayPage} - goToWalletManualWithdraw={(amount?: string) => - redirectTo(Pages.receiveCash({ amount })) - } - onClose={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - <Route - path={Pages.ctaTransferPickup} - component={TransferPickupPage} - onClose={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - <Route - path={Pages.ctaRecovery} - component={RecoveryPage} - onCancel={() => redirectTo(Pages.balance)} - onSuccess={() => redirectTo(Pages.backup)} - /> + {/** + * 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> - </WalletBox> + <Route + default + component={() => <Redirect to={Pages.balanceHistory({})} />} + /> + </Router> </IoCProviderForRuntime> </DevContextProvider> </TranslationProvider> @@ -403,3 +503,40 @@ function shouldShowPendingOperations(url: string): boolean { Pages.backup, ].some((p) => matchesRoute(url, p)); } + +function CallToActionTemplate({ + title, + children, +}: { + title: TranslatedString; + children: ComponentChildren; +}): VNode { + return ( + <WalletAction> + <LogoHeader /> + <SubTitle>{title}</SubTitle> + {children} + </WalletAction> + ); +} + +function WalletTemplate({ + path, + children, + goToTransaction, +}: { + path?: WalletNavBarOptions; + children: ComponentChildren; + goToTransaction?: (id: string) => Promise<void>; +}): VNode { + return ( + <Fragment> + <LogoHeader /> + <WalletNavBar path={path} /> + {goToTransaction ? ( + <PendingTransactions goToTransaction={goToTransaction} /> + ) : undefined} + <WalletBox>{children}</WalletBox> + </Fragment> + ); +} diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx index 4805c03ca..74e7ce611 100644 --- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx @@ -92,6 +92,7 @@ type CoinsInfo = CoinDumpJson["coins"]; type CalculatedCoinfInfo = { ageKeysCount: number | undefined; denom_value: number; + denom_fraction: number; //remain_value: number; status: string; from_refresh: boolean; @@ -151,7 +152,8 @@ export function View({ } prev[cur.exchange_base_url].push({ ageKeysCount: cur.ageCommitmentProof?.proof.privateKeys.length, - denom_value: parseFloat(Amounts.stringifyValue(denom)), + denom_value: denom.value, + denom_fraction: denom.fraction, // remain_value: parseFloat( // Amounts.stringifyValue(Amounts.parseOrThrow(cur.remaining_value)), // ), @@ -340,7 +342,10 @@ export function View({ {Object.keys(money_by_exchange).map((ex, idx) => { const allcoins = money_by_exchange[ex]; allcoins.sort((a, b) => { - return b.denom_value - a.denom_value; + if (b.denom_value !== a.denom_value) { + return b.denom_value - a.denom_value; + } + return b.denom_fraction - a.denom_fraction; }); const coins = allcoins.reduce( @@ -407,11 +412,31 @@ function ShowAllCoins({ const { i18n } = useTranslationContext(); const [collapsedSpent, setCollapsedSpent] = useState(true); const [collapsedUnspent, setCollapsedUnspent] = useState(false); - const total = coins.usable.reduce((prev, cur) => prev + cur.denom_value, 0); + const totalUsable = coins.usable.reduce( + (prev, cur) => + Amounts.add(prev, { + currency: "NONE", + fraction: cur.denom_fraction, + value: cur.denom_value, + }).amount, + Amounts.zeroOfCurrency("NONE"), + ); + const totalSpent = coins.spent.reduce( + (prev, cur) => + Amounts.add(prev, { + currency: "NONE", + fraction: cur.denom_fraction, + value: cur.denom_value, + }).amount, + Amounts.zeroOfCurrency("NONE"), + ); return ( <Fragment> <p> - <b>{ex}</b>: {total} {currencies[ex]} + <b>{ex}</b>: {Amounts.stringifyValue(totalUsable)} {currencies[ex]} + </p> + <p> + spent: {Amounts.stringifyValue(totalSpent)} {currencies[ex]} </p> <p onClick={() => setCollapsedUnspent(true)}> <b> |