aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/NavigationBar.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/NavigationBar.tsx')
-rw-r--r--packages/taler-wallet-webextension/src/NavigationBar.tsx116
1 files changed, 78 insertions, 38 deletions
diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx b/packages/taler-wallet-webextension/src/NavigationBar.tsx
index fe348f7fb..7fb8dad8b 100644
--- a/packages/taler-wallet-webextension/src/NavigationBar.tsx
+++ b/packages/taler-wallet-webextension/src/NavigationBar.tsx
@@ -39,7 +39,10 @@ import qrIcon from "./svg/qr_code_24px.inline.svg";
import settingsIcon from "./svg/settings_black_24dp.inline.svg";
import warningIcon from "./svg/warning_24px.inline.svg";
import { parseTalerUri, TalerUriAction } from "@gnu-taler/taler-util";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import {
+ encodeCrockForURI,
+ useTranslationContext,
+} from "@gnu-taler/web-util/browser";
/**
* List of pages used by the wallet
@@ -60,10 +63,7 @@ function replaceAll(
): string {
let result = pattern;
for (const v in vars) {
- result = result.replace(
- vars[v],
- !values[v] ? "" : encodeURIComponent(values[v]),
- );
+ result = result.replace(vars[v], !values[v] ? "" : values[v]);
}
return result;
}
@@ -94,23 +94,43 @@ function pageDefinition<T extends object>(pattern: string): PageLocation<T> {
return f;
}
+/**
+ * taler action and scope info may contain
+ * character not suitable for URL
+ */
+type CrockEncodedString = string;
+
export const Pages = {
welcome: "/welcome",
balance: "/balance",
- balanceHistory: pageDefinition<{ currency?: string }>(
- "/balance/history/:currency?",
- ),
- searchHistory: pageDefinition<{ currency?: string }>(
- "/search/history/:currency?",
+ balanceHistory: pageDefinition<{ scope?: CrockEncodedString }>(
+ "/balance/history/:scope?",
),
- balanceDeposit: pageDefinition<{ amount: string }>(
- "/balance/deposit/:amount",
+ searchHistory: pageDefinition<{ scope?: CrockEncodedString }>(
+ "/search/history/:scope?",
),
balanceTransaction: pageDefinition<{ tid: string }>(
"/balance/transaction/:tid",
),
- sendCash: pageDefinition<{ amount?: string }>("/destination/send/:amount"),
- receiveCash: pageDefinition<{ amount?: string }>("/destination/get/:amount?"),
+ bankManange: pageDefinition<{ scope: CrockEncodedString }>(
+ "/bank/manage/:scope",
+ ),
+ balanceDeposit: pageDefinition<{
+ scope: CrockEncodedString;
+ }>("/balance/deposit/:scope"),
+ sendCash: pageDefinition<{ scope: CrockEncodedString; amount?: string }>(
+ "/destination/send/:scope/:amount?",
+ ),
+ // if no scope is specified, then exchange selection page will be shown
+ receiveCash: pageDefinition<{ scope?: CrockEncodedString; amount?: string }>(
+ "/destination/get/:scope?/:amount?",
+ ),
+ receiveCashForPurchase: pageDefinition<{ id?: string }>(
+ "/add-for-payment/purchase/:id",
+ ),
+ receiveCashForInvoice: pageDefinition<{ id?: string }>(
+ "/add-for-payment/purchase/:id",
+ ),
dev: "/dev",
exchanges: "/exchanges",
@@ -127,26 +147,40 @@ export const Pages = {
"/settings/exchange/add/:currency?",
),
- defaultCta: pageDefinition<{ uri: string }>("/taler-uri/:uri"),
- cta: pageDefinition<{ action: string }>("/cta/:action"),
+ defaultCta: pageDefinition<{ uri: CrockEncodedString }>("/taler-uri/:uri"),
+ // FIXME: mem leak problems
+ defaultCtaSimple: pageDefinition<{ uri: CrockEncodedString }>(
+ "/taler-uri-simple/:uri",
+ ),
+ cta: pageDefinition<{ action: CrockEncodedString }>("/cta/:action"),
ctaPay: "/cta/pay",
ctaPayTemplate: "/cta/pay/template",
ctaRecovery: "/cta/recovery",
ctaRefund: "/cta/refund",
ctaWithdraw: "/cta/withdraw",
- ctaDeposit: "/cta/deposit",
+ ctaDeposit: pageDefinition<{
+ scope: CrockEncodedString;
+ account: CrockEncodedString;
+ }>("/cta/deposit/:scope/:account"),
ctaExperiment: "/cta/experiment",
ctaAddExchange: "/cta/add/exchange",
- ctaInvoiceCreate: pageDefinition<{ amount?: string }>(
- "/cta/invoice/create/:amount?",
- ),
- ctaTransferCreate: pageDefinition<{ amount?: string }>(
- "/cta/transfer/create/:amount?",
- ),
+ ctaInvoiceCreate: pageDefinition<{
+ scope: CrockEncodedString;
+ }>("/cta/invoice/create/:scope/:amount?"),
+ ctaTransferCreate: pageDefinition<{
+ scope: CrockEncodedString;
+ }>("/cta/transfer/create/:scope/:amount?"),
ctaInvoicePay: "/cta/invoice/pay",
ctaTransferPickup: "/cta/transfer/pickup",
- ctaWithdrawManual: pageDefinition<{ amount?: string }>(
- "/cta/manual-withdraw/:amount?",
+
+ ctaWithdrawManualForScope: pageDefinition<{
+ scope: CrockEncodedString;
+ amount?: string;
+ }>("/cta/scope-withdraw/:scope/:amount?"),
+ ctaWithdrawManual: pageDefinition<{amount?: string;}>("/cta/manual-withdraw/:amount?"),
+ paytoQrs: pageDefinition<{ payto: CrockEncodedString }>("/payto/qrs/:payto?"),
+ paytoBanks: pageDefinition<{ payto: CrockEncodedString }>(
+ "/payto/banks/:payto?",
),
};
@@ -178,7 +212,7 @@ export function getPathnameForTalerURI(talerUri: string): string | undefined {
typeof Pages[pageName] === "function"
? (Pages[pageName] as any)()
: Pages[pageName];
- return `${pageString}?talerUri=${encodeURIComponent(talerUri)}`;
+ return `${pageString}?talerUri=${encodeCrockForURI(talerUri)}`;
}
export type PopupNavBarOptions = "balance" | "backup" | "dev";
@@ -195,17 +229,17 @@ export function PopupNavBar({ path }: { path?: PopupNavBarOptions }): VNode {
const { i18n } = useTranslationContext();
return (
<NavigationHeader>
- <a href={Pages.balance} class={path === "balance" ? "active" : ""}>
+ <a href={`#${Pages.balance}`} class={path === "balance" ? "active" : ""}>
<i18n.Translate>Balance</i18n.Translate>
</a>
<EnabledBySettings name="backup">
- <a href={Pages.backup} class={path === "backup" ? "active" : ""}>
+ <a href={`#${Pages.backup}`} class={path === "backup" ? "active" : ""}>
<i18n.Translate>Backup</i18n.Translate>
</a>
</EnabledBySettings>
<div style={{ display: "flex", paddingTop: 4, justifyContent: "right" }}>
{attentionCount > 0 ? (
- <a href={Pages.notifications}>
+ <a href={`#${Pages.notifications}`}>
<SvgIcon
title={i18n.str`Notifications`}
dangerouslySetInnerHTML={{ __html: warningIcon }}
@@ -215,14 +249,14 @@ export function PopupNavBar({ path }: { path?: PopupNavBarOptions }): VNode {
) : (
<Fragment />
)}
- <a href={Pages.qr}>
+ <a href={`#${Pages.qr}`}>
<SvgIcon
title={i18n.str`QR Reader and Taler URI`}
dangerouslySetInnerHTML={{ __html: qrIcon }}
color="white"
/>
</a>
- <a href={Pages.settings}>
+ <a href={`#${Pages.settings}`}>
<SvgIcon
title={i18n.str`Settings`}
dangerouslySetInnerHTML={{ __html: settingsIcon }}
@@ -250,17 +284,23 @@ export function WalletNavBar({ path }: { path?: WalletNavBarOptions }): VNode {
return (
<NavigationHeaderHolder>
<NavigationHeader>
- <a href={Pages.balance} class={path === "balance" ? "active" : ""}>
+ <a
+ href={`#${Pages.balance}`}
+ class={path === "balance" ? "active" : ""}
+ >
<i18n.Translate>Balance</i18n.Translate>
</a>
<EnabledBySettings name="backup">
- <a href={Pages.backup} class={path === "backup" ? "active" : ""}>
+ <a
+ href={`#${Pages.backup}`}
+ class={path === "backup" ? "active" : ""}
+ >
<i18n.Translate>Backup</i18n.Translate>
</a>
</EnabledBySettings>
{attentionCount > 0 ? (
- <a href={Pages.notifications}>
+ <a href={`#${Pages.notifications}`}>
<i18n.Translate>Notifications</i18n.Translate>
</a>
) : (
@@ -268,7 +308,7 @@ export function WalletNavBar({ path }: { path?: WalletNavBarOptions }): VNode {
)}
<EnabledBySettings name="advancedMode">
- <a href={Pages.dev} class={path === "dev" ? "active" : ""}>
+ <a href={`#${Pages.dev}`} class={path === "dev" ? "active" : ""}>
<i18n.Translate>Dev tools</i18n.Translate>
</a>
</EnabledBySettings>
@@ -276,21 +316,21 @@ export function WalletNavBar({ path }: { path?: WalletNavBarOptions }): VNode {
<div
style={{ display: "flex", paddingTop: 4, justifyContent: "right" }}
>
- <a href={Pages.searchHistory({})}>
+ <a href={`#${Pages.searchHistory({})}`}>
<SvgIcon
title={i18n.str`Search transactions`}
dangerouslySetInnerHTML={{ __html: searchIcon }}
color="white"
/>
</a>
- <a href={Pages.qr}>
+ <a href={`#${Pages.qr}`}>
<SvgIcon
title={i18n.str`QR Reader and Taler URI`}
dangerouslySetInnerHTML={{ __html: qrIcon }}
color="white"
/>
</a>
- <a href={Pages.settings}>
+ <a href={`#${Pages.settings}`}>
<SvgIcon
title={i18n.str`Settings`}
dangerouslySetInnerHTML={{ __html: settingsIcon }}