summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-04-19 12:42:47 -0300
committerSebastian <sebasjm@gmail.com>2023-04-19 12:42:47 -0300
commitd483a3f5574355ed9c43eb6ddea59e5734323cf0 (patch)
tree2f4e3830512b50808b396991791c3c8877e5676e /packages/taler-wallet-webextension
parent7330f0daf907133876baf8831c44ec34cec326e5 (diff)
downloadwallet-core-d483a3f5574355ed9c43eb6ddea59e5734323cf0.tar.gz
wallet-core-d483a3f5574355ed9c43eb6ddea59e5734323cf0.tar.bz2
wallet-core-d483a3f5574355ed9c43eb6ddea59e5734323cf0.zip
fix #7704
Diffstat (limited to 'packages/taler-wallet-webextension')
-rw-r--r--packages/taler-wallet-webextension/src/NavigationBar.tsx16
-rw-r--r--packages/taler-wallet-webextension/src/background.dev.ts1
-rw-r--r--packages/taler-wallet-webextension/src/background.ts2
-rw-r--r--packages/taler-wallet-webextension/src/components/EnabledBySettings.tsx (renamed from packages/taler-wallet-webextension/src/components/JustInDevMode.tsx)19
-rw-r--r--packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx7
-rw-r--r--packages/taler-wallet-webextension/src/components/TermsOfService/utils.ts16
-rw-r--r--packages/taler-wallet-webextension/src/context/devContext.ts70
-rw-r--r--packages/taler-wallet-webextension/src/cta/Payment/state.ts2
-rw-r--r--packages/taler-wallet-webextension/src/cta/PaymentTemplate/views.tsx1
-rw-r--r--packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts1
-rw-r--r--packages/taler-wallet-webextension/src/hooks/useSettings.ts1
-rw-r--r--packages/taler-wallet-webextension/src/hooks/useWalletDevMode.ts52
-rw-r--r--packages/taler-wallet-webextension/src/platform/api.ts31
-rw-r--r--packages/taler-wallet-webextension/src/platform/firefox.ts2
-rw-r--r--packages/taler-wallet-webextension/src/popup/Application.tsx19
-rw-r--r--packages/taler-wallet-webextension/src/popupEntryPoint.dev.tsx1
-rw-r--r--packages/taler-wallet-webextension/src/popupEntryPoint.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/test-utils.ts1
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Application.tsx853
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx6
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts7
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx16
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Settings.tsx183
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Transaction.tsx15
-rw-r--r--packages/taler-wallet-webextension/src/walletEntryPoint.dev.tsx1
-rw-r--r--packages/taler-wallet-webextension/src/walletEntryPoint.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/wxApi.ts2
-rw-r--r--packages/taler-wallet-webextension/src/wxBackend.ts7
28 files changed, 650 insertions, 686 deletions
diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx b/packages/taler-wallet-webextension/src/NavigationBar.tsx
index d6b22ba28..806646a02 100644
--- a/packages/taler-wallet-webextension/src/NavigationBar.tsx
+++ b/packages/taler-wallet-webextension/src/NavigationBar.tsx
@@ -26,7 +26,7 @@
*/
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { Fragment, h, VNode } from "preact";
-import { JustInDevMode } from "./components/JustInDevMode.js";
+import { EnabledBySettings } from "./components/EnabledBySettings.js";
import {
NavigationHeader,
NavigationHeaderHolder,
@@ -183,11 +183,11 @@ export function PopupNavBar({ path }: { path?: PopupNavBarOptions }): VNode {
<a href={Pages.balance} class={path === "balance" ? "active" : ""}>
<i18n.Translate>Balance</i18n.Translate>
</a>
- <JustInDevMode>
+ <EnabledBySettings name="backup">
<a href={Pages.backup} class={path === "backup" ? "active" : ""}>
<i18n.Translate>Backup</i18n.Translate>
</a>
- </JustInDevMode>
+ </EnabledBySettings>
<div style={{ display: "flex", paddingTop: 4, justifyContent: "right" }}>
{attentionCount > 0 ? (
<a href={Pages.notifications}>
@@ -238,11 +238,11 @@ export function WalletNavBar({ path }: { path?: WalletNavBarOptions }): VNode {
<a href={Pages.balance} class={path === "balance" ? "active" : ""}>
<i18n.Translate>Balance</i18n.Translate>
</a>
- <JustInDevMode>
+ <EnabledBySettings name="backup">
<a href={Pages.backup} class={path === "backup" ? "active" : ""}>
<i18n.Translate>Backup</i18n.Translate>
</a>
- </JustInDevMode>
+ </EnabledBySettings>
{attentionCount > 0 ? (
<a href={Pages.notifications}>
@@ -252,11 +252,11 @@ export function WalletNavBar({ path }: { path?: WalletNavBarOptions }): VNode {
<Fragment />
)}
- <JustInDevMode>
+ <EnabledBySettings name="advanceMode">
<a href={Pages.dev} class={path === "dev" ? "active" : ""}>
- <i18n.Translate>Dev</i18n.Translate>
+ <i18n.Translate>Dev tools</i18n.Translate>
</a>
- </JustInDevMode>
+ </EnabledBySettings>
<div
style={{ display: "flex", paddingTop: 4, justifyContent: "right" }}
diff --git a/packages/taler-wallet-webextension/src/background.dev.ts b/packages/taler-wallet-webextension/src/background.dev.ts
index 9ed0e1b8f..96cf63409 100644
--- a/packages/taler-wallet-webextension/src/background.dev.ts
+++ b/packages/taler-wallet-webextension/src/background.dev.ts
@@ -27,7 +27,6 @@ import { platform, setupPlatform } from "./platform/background.js";
import devAPI from "./platform/dev.js";
import { wxMain } from "./wxBackend.js";
-console.log("Wallet setup for Dev API");
setupPlatform(devAPI);
async function start() {
diff --git a/packages/taler-wallet-webextension/src/background.ts b/packages/taler-wallet-webextension/src/background.ts
index 0d5a186d2..7df66eff8 100644
--- a/packages/taler-wallet-webextension/src/background.ts
+++ b/packages/taler-wallet-webextension/src/background.ts
@@ -35,10 +35,8 @@ const isFirefox =
// FIXME: create different entry point for any platform instead of
// switching in runtime
if (isFirefox) {
- console.log("Wallet setup for Firefox API");
setupPlatform(firefoxAPI);
} else {
- console.log("Wallet setup for Chrome API");
setupPlatform(chromeAPI);
}
diff --git a/packages/taler-wallet-webextension/src/components/JustInDevMode.tsx b/packages/taler-wallet-webextension/src/components/EnabledBySettings.tsx
index a29bea791..6f666d301 100644
--- a/packages/taler-wallet-webextension/src/components/JustInDevMode.tsx
+++ b/packages/taler-wallet-webextension/src/components/EnabledBySettings.tsx
@@ -14,14 +14,25 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
import { ComponentChildren, Fragment, h, VNode } from "preact";
-import { useDevContext } from "../context/devContext.js";
+import { useSettings } from "../hooks/useSettings.js";
+import { Settings } from "../platform/api.js";
-export function JustInDevMode({
+export function EnabledBySettings<K extends keyof Settings>({
children,
+ value,
+ name,
}: {
+ name: K;
+ value?: Settings[K];
children: ComponentChildren;
}): VNode {
- const { devMode } = useDevContext();
- if (!devMode) return <Fragment />;
+ const [settings] = useSettings();
+ if (value === undefined) {
+ if (!settings[name]) return <Fragment />;
+ return <Fragment>{children}</Fragment>;
+ }
+ if (settings[name] !== value) {
+ return <Fragment />;
+ }
return <Fragment>{children}</Fragment>;
}
diff --git a/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx b/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx
index f8203f38a..2979c28e5 100644
--- a/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx
+++ b/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx
@@ -17,8 +17,8 @@ import { TalerErrorDetail, TranslatedString } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
import arrowDown from "../svg/chevron-down.svg";
-import { useDevContext } from "../context/devContext.js";
import { ErrorBox } from "./styled/index.js";
+import { EnabledBySettings } from "./EnabledBySettings.js";
export function ErrorTalerOperation({
title,
@@ -27,7 +27,6 @@ export function ErrorTalerOperation({
title?: TranslatedString;
error?: TalerErrorDetail;
}): VNode | null {
- const { devMode } = useDevContext();
const [showErrorDetail, setShowErrorDetail] = useState(false);
if (!title || !error) return null;
@@ -62,11 +61,11 @@ export function ErrorTalerOperation({
<b>{error.hint}</b> {!errorHint ? "" : `: ${errorHint}`}{" "}
</div>
</div>
- {devMode && (
+ <EnabledBySettings name="showJsonOnError">
<div style={{ textAlign: "left", overflowX: "auto" }}>
<pre>{JSON.stringify(error, undefined, 2)}</pre>
</div>
- )}
+ </EnabledBySettings>
</Fragment>
)}
</ErrorBox>
diff --git a/packages/taler-wallet-webextension/src/components/TermsOfService/utils.ts b/packages/taler-wallet-webextension/src/components/TermsOfService/utils.ts
index 391932574..fdca78ee5 100644
--- a/packages/taler-wallet-webextension/src/components/TermsOfService/utils.ts
+++ b/packages/taler-wallet-webextension/src/components/TermsOfService/utils.ts
@@ -14,7 +14,11 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { ExchangeTosStatus, GetExchangeTosResult } from "@gnu-taler/taler-util";
+import {
+ ExchangeTosStatus,
+ GetExchangeTosResult,
+ Logger,
+} from "@gnu-taler/taler-util";
export function buildTermsOfServiceState(
tos: GetExchangeTosResult,
@@ -27,6 +31,8 @@ export function buildTermsOfServiceState(
return { content, status: tos.tosStatus, version: tos.currentEtag };
}
+const logger = new Logger("termsofservice");
+
function parseTermsOfServiceContent(
type: string,
text: string,
@@ -36,28 +42,28 @@ function parseTermsOfServiceContent(
const document = new DOMParser().parseFromString(text, "text/xml");
return { type: "xml", document };
} catch (e) {
- console.log(e);
+ logger.error("error parsing xml", e);
}
} else if (type === "text/html") {
try {
const href = new URL(text);
return { type: "html", href };
} catch (e) {
- console.log(e);
+ logger.error("error parsing url", e);
}
} else if (type === "text/json") {
try {
const data = JSON.parse(text);
return { type: "json", data };
} catch (e) {
- console.log(e);
+ logger.error("error parsing json", e);
}
} else if (type === "text/pdf") {
try {
const location = new URL(text);
return { type: "pdf", location };
} catch (e) {
- console.log(e);
+ logger.error("error parsing url", e);
}
}
const content = text;
diff --git a/packages/taler-wallet-webextension/src/context/devContext.ts b/packages/taler-wallet-webextension/src/context/devContext.ts
deleted file mode 100644
index e2ad2914b..000000000
--- a/packages/taler-wallet-webextension/src/context/devContext.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- *
- * @author Sebastian Javier Marchano (sebasjm)
- */
-
-import { createContext, h, VNode } from "preact";
-import { useContext } from "preact/hooks";
-import { useWalletDevMode } from "../hooks/useWalletDevMode.js";
-
-interface Type {
- devMode: boolean;
- toggle: () => Promise<void>;
-}
-const Context = createContext<Type>({
- devMode: false,
- toggle: async () => {
- null;
- },
-});
-
-export const useDevContext = (): Type => useContext(Context);
-
-export const DevContextProviderForTesting = ({
- value,
- children,
-}: {
- value?: boolean;
- children: any;
-}): VNode => {
- return h(Context.Provider, {
- value: {
- devMode: !!value,
- toggle: async () => {
- null;
- },
- },
- children,
- });
-};
-
-export const DevContextProvider = ({ children }: { children: any }): VNode => {
- const devModeToggle = useWalletDevMode();
- const value: Type = {
- devMode: !!devModeToggle.value,
- toggle: devModeToggle.toggle,
- };
- //support for function as children, useful for getting the value right away
- children =
- children.length === 1 && typeof children === "function"
- ? children(value)
- : children;
-
- return h(Context.Provider, { value, children });
-};
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/state.ts b/packages/taler-wallet-webextension/src/cta/Payment/state.ts
index b3d2e6e81..5cd4686ce 100644
--- a/packages/taler-wallet-webextension/src/cta/Payment/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Payment/state.ts
@@ -167,8 +167,6 @@ export function useComponentState({
if (fu) {
if (typeof window !== "undefined") {
document.location.href = fu;
- } else {
- console.log(`should d to ${fu}`);
}
}
onSuccess(res.transactionId);
diff --git a/packages/taler-wallet-webextension/src/cta/PaymentTemplate/views.tsx b/packages/taler-wallet-webextension/src/cta/PaymentTemplate/views.tsx
index 42e51014f..bd265750f 100644
--- a/packages/taler-wallet-webextension/src/cta/PaymentTemplate/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/PaymentTemplate/views.tsx
@@ -30,7 +30,6 @@ export function ReadyView({
}: State.FillTemplate): VNode {
const { i18n } = useTranslationContext();
- console.log("is summary", !!summary);
return (
<Fragment>
<section style={{ textAlign: "left" }}>
diff --git a/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts b/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts
index 3255c90e5..35b7148cc 100644
--- a/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useClipboardPermissions.ts
@@ -51,7 +51,6 @@ export function useClipboardPermissions(): ToggleHandler {
// .call("toggleHeaderListener", false)
// .then((r) => setEnabled(r.newValue));
// } catch (e) {
- // console.log(e);
// }
}
return;
diff --git a/packages/taler-wallet-webextension/src/hooks/useSettings.ts b/packages/taler-wallet-webextension/src/hooks/useSettings.ts
index 040fee424..1fa2b0539 100644
--- a/packages/taler-wallet-webextension/src/hooks/useSettings.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useSettings.ts
@@ -36,7 +36,6 @@ export function useSettings(): [
function updateField<T extends keyof Settings>(k: T, v: Settings[T]) {
const newValue = { ...parsed, [k]: v };
const json = JSON.stringify(newValue);
- console.log(json);
update(json);
}
return [parsed, updateField];
diff --git a/packages/taler-wallet-webextension/src/hooks/useWalletDevMode.ts b/packages/taler-wallet-webextension/src/hooks/useWalletDevMode.ts
deleted file mode 100644
index db7effe96..000000000
--- a/packages/taler-wallet-webextension/src/hooks/useWalletDevMode.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2022 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
-import { useEffect, useState } from "preact/hooks";
-import { useBackendContext } from "../context/backend.js";
-
-type Result = {
- value: boolean | undefined;
- toggle: () => Promise<void>;
-};
-
-export function useWalletDevMode(): Result {
- const [enabled, setEnabled] = useState<undefined | boolean>(undefined);
- const api = useBackendContext();
- // const { pushAlertOnError } = useAlertContext();
-
- async function handleOpen(): Promise<void> {
- const nextValue = !enabled;
- await api.wallet.call(WalletApiOperation.SetDevMode, {
- devModeEnabled: nextValue,
- });
- setEnabled(nextValue);
- return;
- }
-
- useEffect(() => {
- async function getValue(): Promise<void> {
- const res = await api.wallet.call(WalletApiOperation.GetVersion, {});
- setEnabled(res.devMode);
- }
- getValue();
- }, []);
-
- return {
- value: enabled,
- toggle: handleOpen,
- };
-}
diff --git a/packages/taler-wallet-webextension/src/platform/api.ts b/packages/taler-wallet-webextension/src/platform/api.ts
index f87500c4f..f8fa0a848 100644
--- a/packages/taler-wallet-webextension/src/platform/api.ts
+++ b/packages/taler-wallet-webextension/src/platform/api.ts
@@ -15,7 +15,11 @@
*/
import { CoreApiResponse, NotificationType } from "@gnu-taler/taler-util";
-import { WalletOperations } from "@gnu-taler/taler-wallet-core";
+import {
+ WalletConfig,
+ WalletConfigParameter,
+ WalletOperations,
+} from "@gnu-taler/taler-wallet-core";
import { BackgroundOperations } from "../wxApi.js";
import {
ExtensionOperations,
@@ -87,12 +91,35 @@ export interface WalletWebExVersion {
version: string;
}
-export interface Settings {
+type F = WalletConfig["features"];
+type kf = keyof F;
+type WebexWalletConfig = {
+ [P in keyof F as `wallet${Capitalize<P>}`]: F[P];
+};
+
+export interface Settings extends WebexWalletConfig {
injectTalerSupport: boolean;
+ advanceMode: boolean;
+ backup: boolean;
+ langSelector: boolean;
+ showJsonOnError: boolean;
+ extendedAccountTypes: boolean;
+ //WORKAROUND
+ //Able to delete tx in dev mode
+ //FIXME: remove this when DD37 is implemented
+ deleteActiveTransactions: boolean;
}
export const defaultSettings: Settings = {
injectTalerSupport: false,
+ advanceMode: false,
+ backup: false,
+ langSelector: false,
+ deleteActiveTransactions: false,
+ showJsonOnError: false,
+ extendedAccountTypes: false,
+ walletAllowHttp: false,
+ walletBatchWithdrawal: false,
};
/**
diff --git a/packages/taler-wallet-webextension/src/platform/firefox.ts b/packages/taler-wallet-webextension/src/platform/firefox.ts
index 01848e1ab..9f666e7ae 100644
--- a/packages/taler-wallet-webextension/src/platform/firefox.ts
+++ b/packages/taler-wallet-webextension/src/platform/firefox.ts
@@ -45,7 +45,7 @@ function isFirefox(): boolean {
}
function addPermissionsListener(callback: (p: Permissions) => void): void {
- console.log("addPermissionListener is not supported for Firefox");
+ throw Error("addPermissionListener is not supported for Firefox");
}
function getPermissionsApi(): CrossBrowserPermissionsApi {
diff --git a/packages/taler-wallet-webextension/src/popup/Application.tsx b/packages/taler-wallet-webextension/src/popup/Application.tsx
index c03360486..e0cb840aa 100644
--- a/packages/taler-wallet-webextension/src/popup/Application.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Application.tsx
@@ -20,6 +20,10 @@
* @author sebasjm
*/
+import {
+ 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";
@@ -27,29 +31,22 @@ import { useEffect, useState } from "preact/hooks";
import PendingTransactions from "../components/PendingTransactions.js";
import { PopupBox } 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 { useTalerActionURL } from "../hooks/useTalerActionURL.js";
+import { strings } from "../i18n/strings.js";
import { Pages, PopupNavBar, PopupNavBarOptions } from "../NavigationBar.js";
import { platform } from "../platform/foreground.js";
import { BackupPage } from "../wallet/BackupPage.js";
import { ProviderDetailPage } from "../wallet/ProviderDetailPage.js";
import { BalancePage } from "./BalancePage.js";
import { TalerActionFound } from "./TalerActionFound.js";
-import { strings } from "../i18n/strings.js";
export function Application(): VNode {
return (
<TranslationProvider source={strings}>
- <DevContextProvider>
- <IoCProviderForRuntime>
- <ApplicationView />
- </IoCProviderForRuntime>
- </DevContextProvider>
+ <IoCProviderForRuntime>
+ <ApplicationView />
+ </IoCProviderForRuntime>
</TranslationProvider>
);
}
diff --git a/packages/taler-wallet-webextension/src/popupEntryPoint.dev.tsx b/packages/taler-wallet-webextension/src/popupEntryPoint.dev.tsx
index 6b42e5809..f0bc81399 100644
--- a/packages/taler-wallet-webextension/src/popupEntryPoint.dev.tsx
+++ b/packages/taler-wallet-webextension/src/popupEntryPoint.dev.tsx
@@ -27,7 +27,6 @@ import { setupPlatform } from "./platform/foreground.js";
import devAPI from "./platform/dev.js";
import { Application } from "./popup/Application.js";
-console.log("Wallet setup for Dev API");
setupPlatform(devAPI);
function main(): void {
diff --git a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
index 22aba6c9d..08915ea96 100644
--- a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
+++ b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
@@ -32,10 +32,8 @@ import { Application } from "./popup/Application.js";
//switching in runtime
const isFirefox = typeof (window as any)["InstallTrigger"] !== "undefined";
if (isFirefox) {
- console.log("Wallet setup for Firefox API");
setupPlatform(firefoxAPI);
} else {
- console.log("Wallet setup for Chrome API");
setupPlatform(chromeAPI);
}
diff --git a/packages/taler-wallet-webextension/src/test-utils.ts b/packages/taler-wallet-webextension/src/test-utils.ts
index d85d992b1..1d2538703 100644
--- a/packages/taler-wallet-webextension/src/test-utils.ts
+++ b/packages/taler-wallet-webextension/src/test-utils.ts
@@ -41,7 +41,6 @@ import { strings } from "./i18n/strings.js";
// When doing tests we want the requestAnimationFrame to be as fast as possible.
// without this option the RAF will timeout after 100ms making the tests slower
options.requestAnimationFrame = (fn: () => void) => {
- // console.log("RAF called")
return fn();
};
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>
diff --git a/packages/taler-wallet-webextension/src/walletEntryPoint.dev.tsx b/packages/taler-wallet-webextension/src/walletEntryPoint.dev.tsx
index c2906373c..60a5970e4 100644
--- a/packages/taler-wallet-webextension/src/walletEntryPoint.dev.tsx
+++ b/packages/taler-wallet-webextension/src/walletEntryPoint.dev.tsx
@@ -27,7 +27,6 @@ import { setupPlatform } from "./platform/foreground.js";
import devAPI from "./platform/dev.js";
import { Application } from "./wallet/Application.js";
-console.log("Wallet setup for Dev API");
setupPlatform(devAPI);
function main(): void {
diff --git a/packages/taler-wallet-webextension/src/walletEntryPoint.tsx b/packages/taler-wallet-webextension/src/walletEntryPoint.tsx
index 84822b8e6..1bd42796b 100644
--- a/packages/taler-wallet-webextension/src/walletEntryPoint.tsx
+++ b/packages/taler-wallet-webextension/src/walletEntryPoint.tsx
@@ -33,10 +33,8 @@ const isFirefox = typeof (window as any)["InstallTrigger"] !== "undefined";
//FIXME: create different entry point for any platform instead of
//switching in runtime
if (isFirefox) {
- console.log("Wallet setup for Firefox API");
setupPlatform(firefoxAPI);
} else {
- console.log("Wallet setup for Chrome API");
setupPlatform(chromeAPI);
}
diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts
index d15528699..ce1dac14f 100644
--- a/packages/taler-wallet-webextension/src/wxApi.ts
+++ b/packages/taler-wallet-webextension/src/wxApi.ts
@@ -156,7 +156,7 @@ class WalletApiClientImpl implements WalletCoreApiClient {
};
response = await platform.sendMessageToBackground(message);
} catch (e) {
- console.log("Error calling backend");
+ logger.error("Error calling backend", e);
throw new Error(`Error contacting backend: ${e}`);
}
if (response.type === "error") {
diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts
index bf91e8521..8acc41247 100644
--- a/packages/taler-wallet-webextension/src/wxBackend.ts
+++ b/packages/taler-wallet-webextension/src/wxBackend.ts
@@ -319,12 +319,19 @@ async function reinitWallet(): Promise<void> {
timer = new SetTimeoutTimerAPI();
}
+ const settings = await platform.getSettingsFromStorage();
logger.info("Setting up wallet");
const wallet = await Wallet.create(
currentDatabase,
httpLib,
timer,
cryptoWorker,
+ {
+ features: {
+ allowHttp: settings.walletAllowHttp,
+ batchWithdrawal: settings.walletBatchWithdrawal,
+ },
+ },
);
try {
await wallet.handleCoreApiRequest("initWallet", "native-init", {});