summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2021-05-07 18:10:27 -0300
committerSebastian <sebasjm@gmail.com>2021-05-07 18:16:30 -0300
commit4ed4535bc090acf3e5a3b7781ba458d077aac751 (patch)
treee1c6af8a7e4c17b67992c824fb172b1bcd61601e
parent30f86f8748a0d9c23538e972d30270a4f1e83941 (diff)
downloadwallet-core-4ed4535bc090acf3e5a3b7781ba458d077aac751.tar.gz
wallet-core-4ed4535bc090acf3e5a3b7781ba458d077aac751.tar.bz2
wallet-core-4ed4535bc090acf3e5a3b7781ba458d077aac751.zip
preact routing on the wallet
-rw-r--r--packages/taler-wallet-webextension/package.json5
-rw-r--r--packages/taler-wallet-webextension/src/Application.tsx99
-rw-r--r--packages/taler-wallet-webextension/src/pageEntryPoint.ts39
-rw-r--r--packages/taler-wallet-webextension/src/pages/pay.tsx13
-rw-r--r--packages/taler-wallet-webextension/src/pages/popup.tsx150
-rw-r--r--packages/taler-wallet-webextension/src/pages/refund.tsx18
-rw-r--r--packages/taler-wallet-webextension/src/pages/tip.tsx11
-rw-r--r--packages/taler-wallet-webextension/src/pages/welcome.tsx67
-rw-r--r--packages/taler-wallet-webextension/src/pages/withdraw.tsx15
-rw-r--r--packages/taler-wallet-webextension/src/renderHtml.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/wxBackend.ts10
-rw-r--r--packages/taler-wallet-webextension/static/add-auditor.html33
-rw-r--r--packages/taler-wallet-webextension/static/auditors.html35
-rw-r--r--packages/taler-wallet-webextension/static/benchmark.html16
-rw-r--r--packages/taler-wallet-webextension/static/pay.html73
-rw-r--r--packages/taler-wallet-webextension/static/payback.html34
-rw-r--r--packages/taler-wallet-webextension/static/refund.html19
-rw-r--r--packages/taler-wallet-webextension/static/reset-required.html25
-rw-r--r--packages/taler-wallet-webextension/static/style/popup.css57
-rw-r--r--packages/taler-wallet-webextension/static/tip.html19
-rw-r--r--packages/taler-wallet-webextension/static/welcome.html24
-rw-r--r--packages/taler-wallet-webextension/static/withdraw.html22
-rw-r--r--pnpm-lock.yaml35
23 files changed, 321 insertions, 500 deletions
diff --git a/packages/taler-wallet-webextension/package.json b/packages/taler-wallet-webextension/package.json
index f9756fd32..b2179a66a 100644
--- a/packages/taler-wallet-webextension/package.json
+++ b/packages/taler-wallet-webextension/package.json
@@ -10,7 +10,8 @@
"scripts": {
"clean": "rimraf dist lib tsconfig.tsbuildinfo",
"test": "jest ./tests",
- "compile": "tsc && rollup -c"
+ "compile": "tsc && rollup -c",
+ "watch": "tsc --watch & rollup -w -c"
},
"dependencies": {
"@gnu-taler/taler-util": "workspace:*",
@@ -29,12 +30,14 @@
"@rollup/plugin-replace": "^2.3.4",
"@testing-library/preact": "^2.0.1",
"@types/chrome": "^0.0.128",
+ "@types/history": "^4.7.8",
"@types/jest": "^26.0.23",
"@types/node": "^14.14.22",
"ava": "3.15.0",
"babel-plugin-transform-react-jsx": "^6.24.1",
"enzyme": "^3.11.0",
"enzyme-adapter-preact-pure": "^3.1.0",
+ "history": "4.10.1",
"jest": "^26.6.3",
"jest-preset-preact": "^4.0.3",
"preact-cli": "^3.0.5",
diff --git a/packages/taler-wallet-webextension/src/Application.tsx b/packages/taler-wallet-webextension/src/Application.tsx
new file mode 100644
index 000000000..096f6a09a
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/Application.tsx
@@ -0,0 +1,99 @@
+import Router, { route, Route } from "preact-router";
+import { createHashHistory } from 'history';
+import { useEffect } from "preact/hooks";
+
+import { WalletPopup } from "./pages/popup";
+import { WithdrawalDialog } from "./pages/withdraw";
+import { Welcome } from "./pages/welcome";
+import { TalerPayDialog } from "./pages/pay";
+import { RefundStatusView } from "./pages/refund";
+import { TalerTipDialog } from './pages/tip';
+
+
+export enum Pages {
+ welcome = '/welcome',
+ pay = '/pay',
+ payback = '/payback',
+ refund = '/refund',
+ reset_required = '/reset-required',
+ return_coins = '/return-coins',
+ tips = '/tips',
+ withdraw = '/withdraw',
+ popup = '/popup/:rest',
+}
+
+export function Application() {
+ const sp = new URL(document.location.href).searchParams
+ const queryParams: any = {}
+ sp.forEach((v, k) => { queryParams[k] = v; });
+
+ return <Router history={createHashHistory()} >
+ <Route path={Pages.popup} component={WalletPopup} />
+
+ <Route path={Pages.welcome} component={() => {
+ return <section id="main">
+ <div style="border-bottom: 3px dashed #aa3939; margin-bottom: 2em;">
+ <h1 style="font-family: monospace; font-size: 250%;">
+ <span style="color: #aa3939;">❰</span>Taler Wallet<span style="color: #aa3939;">❱</span>
+ </h1>
+ </div>
+ <h1>Browser Extension Installed!</h1>
+ <div>
+ <Welcome />
+ </div>
+ </section>
+ }} />
+
+ <Route path={Pages.pay} component={() => {
+ return <section id="main">
+ <h1>GNU Taler Wallet</h1>
+ <article class="fade">
+ <TalerPayDialog talerPayUri={queryParams.talerPayUri} />
+ </article>
+ </section>
+ }} />
+
+ <Route path={Pages.refund} component={() => {
+ return <section id="main">
+ <h1>GNU Taler Wallet</h1>
+ <article class="fade">
+ <RefundStatusView talerRefundUri={queryParams.talerRefundUri} />
+ </article>
+ </section>
+ }} />
+
+ <Route path={Pages.tips} component={() => {
+ return <section id="main">
+ <h1>GNU Taler Wallet</h1>
+ <div>
+ <TalerTipDialog talerTipUri={queryParams.talerTipUri} />
+ </div>
+ </section>
+ }} />
+ <Route path={Pages.withdraw} component={() => {
+ return <section id="main">
+ <div style="border-bottom: 3px dashed #aa3939; margin-bottom: 2em;">
+ <h1 style="font-family: monospace; font-size: 250%;">
+ <span style="color: #aa3939;">❰</span>Taler Wallet<span style="color: #aa3939;">❱</span>
+ </h1>
+ </div>
+ <div class="fade">
+ <WithdrawalDialog talerWithdrawUri={queryParams.talerWithdrawUri} />
+ </div>
+ </section>
+ }} />
+
+ <Route path={Pages.reset_required} component={() => <div>no yet implemented</div>} />
+ <Route path={Pages.payback} component={() => <div>no yet implemented</div>} />
+ <Route path={Pages.return_coins} component={() => <div>no yet implemented</div>} />
+
+ <Route default component={Redirect} to='/popup/balance' />
+ </Router>
+}
+
+export function Redirect({ to }: { to: string }): null {
+ useEffect(() => {
+ route(to, true)
+ })
+ return null
+}
diff --git a/packages/taler-wallet-webextension/src/pageEntryPoint.ts b/packages/taler-wallet-webextension/src/pageEntryPoint.ts
index 06dc594c5..00fd5fc72 100644
--- a/packages/taler-wallet-webextension/src/pageEntryPoint.ts
+++ b/packages/taler-wallet-webextension/src/pageEntryPoint.ts
@@ -20,50 +20,17 @@
* @author Florian Dold <dold@taler.net>
*/
-import {render} from "preact";
-import { createPopup } from "./pages/popup";
-import { createWithdrawPage } from "./pages/withdraw";
-import { createWelcomePage } from "./pages/welcome";
-import { createPayPage } from "./pages/pay";
-import { createRefundPage } from "./pages/refund";
+import { render } from "preact";
import { setupI18n } from "@gnu-taler/taler-wallet-core";
-import { createTipPage } from './pages/tip';
+import { Application } from './Application';
function main(): void {
try {
- let mainElement;
- const m = location.pathname.match(/([^/]+)$/);
- if (!m) {
- throw Error("can't parse page URL");
- }
- const page = m[1];
- switch (page) {
- case "popup.html":
- mainElement = createPopup();
- break;
- case "withdraw.html":
- mainElement = createWithdrawPage();
- break;
- case "welcome.html":
- mainElement = createWelcomePage();
- break;
- case "pay.html":
- mainElement = createPayPage();
- break;
- case "refund.html":
- mainElement = createRefundPage();
- break;
- case "tip.html":
- mainElement = createTipPage();
- break;
- default:
- throw Error(`page '${page}' not implemented`);
- }
const container = document.getElementById("container");
if (!container) {
throw Error("container not found, can't mount page contents");
}
- render(mainElement, container);
+ render(Application(), container);
} catch (e) {
console.error("got error", e);
document.body.innerText = `Fatal error: "${e.message}". Please report this bug at https://bugs.gnunet.org/.`;
diff --git a/packages/taler-wallet-webextension/src/pages/pay.tsx b/packages/taler-wallet-webextension/src/pages/pay.tsx
index 80d846d67..10f83165d 100644
--- a/packages/taler-wallet-webextension/src/pages/pay.tsx
+++ b/packages/taler-wallet-webextension/src/pages/pay.tsx
@@ -41,7 +41,11 @@ import {
} from "@gnu-taler/taler-util";
import { JSX, VNode } from "preact";
-function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element {
+interface Props {
+ talerPayUri?: string
+}
+
+export function TalerPayDialog({ talerPayUri }: Props): JSX.Element {
const [payStatus, setPayStatus] = useState<PreparePayResult | undefined>(undefined);
const [payResult, setPayResult] = useState<ConfirmPayResult | undefined>(undefined);
const [payErrMsg, setPayErrMsg] = useState<string | undefined>("");
@@ -50,6 +54,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element {
let totalFees: AmountJson | undefined = undefined;
useEffect(() => {
+ if (!talerPayUri) return;
const doFetch = async (): Promise<void> => {
const p = await wxApi.preparePay(talerPayUri);
setPayStatus(p);
@@ -57,6 +62,10 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element {
doFetch();
}, [numTries, talerPayUri]);
+ if (!talerPayUri) {
+ return <span>missing pay uri</span>
+ }
+
if (!payStatus) {
return <span>Loading payment information ...</span>;
}
@@ -83,7 +92,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element {
return (
<span>
You have already paid for this article. Click{" "}
- <a href={fulfillmentUrl}>here</a> to view it again.
+ <a href={fulfillmentUrl} target="_bank" rel="external">here</a> to view it again.
</span>
);
} else {
diff --git a/packages/taler-wallet-webextension/src/pages/popup.tsx b/packages/taler-wallet-webextension/src/pages/popup.tsx
index cf76044ce..afd331c84 100644
--- a/packages/taler-wallet-webextension/src/pages/popup.tsx
+++ b/packages/taler-wallet-webextension/src/pages/popup.tsx
@@ -24,9 +24,7 @@
/**
* Imports.
*/
-import * as i18n from "../i18n";
-
-import {
+ import {
AmountJson,
Amounts,
BalancesResponse,
@@ -40,121 +38,43 @@ import {
Timestamp,
amountFractionalBase,
} from "@gnu-taler/taler-util";
-
-import { renderAmount, PageLink } from "../renderHtml";
+import { Component, ComponentChildren, JSX } from "preact";
+import { route, Route, Router } from 'preact-router';
+import { Match } from 'preact-router/match';
+import { useEffect, useState } from "preact/hooks";
+import * as i18n from "../i18n";
+import { PageLink, renderAmount } from "../renderHtml";
import * as wxApi from "../wxApi";
-
-import { useState, useEffect } from "preact/hooks";
-
import { PermissionsCheckbox } from "./welcome";
-import { JSXInternal } from "preact/src/jsx";
-import { Component, ComponentChild, ComponentChildren, JSX, toChildArray, VNode } from "preact";
-
-// FIXME: move to newer react functions
-
-class Router extends Component<any, any> {
- static setRoute(s: string): void {
- window.location.hash = s;
- }
-
- static getRoute(): string {
- // Omit the '#' at the beginning
- return window.location.hash.substring(1);
- }
-
- static onRoute(f: any): () => void {
- Router.routeHandlers.push(f);
- return () => {
- const i = Router.routeHandlers.indexOf(f);
- this.routeHandlers = this.routeHandlers.splice(i, 1);
- };
- }
-
- private static routeHandlers: any[] = [];
-
- componentWillMount(): void {
- console.log("router mounted");
- window.onhashchange = () => {
- this.setState({});
- for (const f of Router.routeHandlers) {
- f();
- }
- };
- }
-
- render(): JSX.Element {
- const route = window.location.hash.substring(1);
- console.log("rendering route", route);
- let defaultChild: ComponentChild | null = null;
- let foundChild: ComponentChild | null = null;
- toChildArray(this.props.children).forEach((child) => {
- const childProps: any = (child as any).props;
- if (!childProps) {
- return;
- }
- if (childProps.default) {
- defaultChild = child;
- }
- if (childProps.route === route) {
- foundChild = child;
- }
- });
- const c: ComponentChild | null = foundChild || defaultChild;
- if (!c) {
- throw Error("unknown route");
- }
- Router.setRoute((c as any).props.route);
- return <div>{c}</div>;
- }
-}
interface TabProps {
target: string;
+ current?: string;
children?: ComponentChildren;
}
function Tab(props: TabProps): JSX.Element {
let cssClass = "";
- if (props.target === Router.getRoute()) {
+ if (props.current === props.target) {
cssClass = "active";
}
- const onClick = (e: JSXInternal.TargetedMouseEvent<HTMLAnchorElement>): void => {
- Router.setRoute(props.target);
- e.preventDefault();
- };
return (
- <a onClick={onClick} href={props.target} className={cssClass}>
+ <a href={props.target} className={cssClass}>
{props.children}
</a>
);
}
-class WalletNavBar extends Component<any, any> {
- private cancelSubscription: any;
-
- componentWillMount(): void {
- this.cancelSubscription = Router.onRoute(() => {
- this.setState({});
- });
- }
-
- componentWillUnmount(): void {
- if (this.cancelSubscription) {
- this.cancelSubscription();
- }
- }
+function WalletNavBar({ current }: { current?: string }) {
- render(): JSX.Element {
- console.log("rendering nav bar");
- return (
- <div className="nav" id="header">
- <Tab target="/balance">{i18n.str`Balance`}</Tab>
- <Tab target="/history">{i18n.str`History`}</Tab>
- <Tab target="/settings">{i18n.str`Settings`}</Tab>
- <Tab target="/debug">{i18n.str`Debug`}</Tab>
- </div>
- );
- }
+ return (
+ <div className="nav" id="header">
+ <Tab target="/popup/balance" current={current}>{i18n.str`Balance`}</Tab>
+ <Tab target="/popup/history" current={current}>{i18n.str`History`}</Tab>
+ <Tab target="/popup/settings" current={current}>{i18n.str`Settings`}</Tab>
+ <Tab target="/popup/debug" current={current}>{i18n.str`Debug`}</Tab>
+ </div>
+ );
}
/**
@@ -174,7 +94,7 @@ function EmptyBalanceView(): JSX.Element {
return (
<i18n.Translate wrap="p">
You have no balance to show. Need some{" "}
- <PageLink pageName="welcome.html">help</PageLink> getting started?
+ <PageLink pageName="/welcome">help</PageLink> getting started?
</i18n.Translate>
);
}
@@ -494,7 +414,7 @@ function WalletHistory(props: any): JSX.Element {
return (
<div>
- {txs.map((tx,i) => (
+ {txs.map((tx, i) => (
<TransactionItem key={i} tx={tx} />
))}
</div>
@@ -525,7 +445,7 @@ async function confirmReset(): Promise<void> {
if (
confirm(
"Do you want to IRREVOCABLY DESTROY everything inside your" +
- " wallet and LOSE ALL YOUR COINS?",
+ " wallet and LOSE ALL YOUR COINS?",
)
) {
await wxApi.resetDb();
@@ -634,7 +554,7 @@ async function findTalerUriInActiveTab(): Promise<string | undefined> {
});
}
-function WalletPopup(): JSX.Element {
+export function WalletPopup(): JSX.Element {
const [talerActionUrl, setTalerActionUrl] = useState<string | undefined>(
undefined,
);
@@ -671,19 +591,29 @@ function WalletPopup(): JSX.Element {
}
return (
<div>
- <WalletNavBar />
+ <Match>{({ path }: any) => <WalletNavBar current={path} />}</Match>
<div style={{ margin: "1em" }}>
<Router>
- <WalletBalanceView route="/balance" default />
- <WalletSettings route="/settings" />
- <WalletDebug route="/debug" />
- <WalletHistory route="/history" />
+ <Route path={Pages.balance} component={WalletBalanceView} />
+ <Route path={Pages.settings} component={WalletSettings} />
+ <Route path={Pages.debug} component={WalletDebug} />
+ <Route path={Pages.history} component={WalletHistory} />
</Router>
</div>
</div>
);
}
-export function createPopup(): JSX.Element {
- return <WalletPopup />;
+enum Pages {
+ balance = '/popup/balance',
+ settings = '/popup/settings',
+ debug = '/popup/debug',
+ history = '/popup/history',
+}
+
+export function Redirect({ to }: { to: string }): null {
+ useEffect(() => {
+ route(to, true)
+ })
+ return null
}
diff --git a/packages/taler-wallet-webextension/src/pages/refund.tsx b/packages/taler-wallet-webextension/src/pages/refund.tsx
index 6525f68c6..49b78160e 100644
--- a/packages/taler-wallet-webextension/src/pages/refund.tsx
+++ b/packages/taler-wallet-webextension/src/pages/refund.tsx
@@ -26,18 +26,22 @@ import {
ApplyRefundResponse,
Amounts,
} from "@gnu-taler/taler-util";
-// import { h } from 'preact';
import { useEffect, useState } from "preact/hooks";
import { JSX } from "preact/jsx-runtime";
-function RefundStatusView(props: { talerRefundUri: string }): JSX.Element {
- const [applyResult, setApplyResult] = useState<ApplyRefundResponse|undefined>(undefined);
+interface Props {
+ talerRefundUri?: string
+}
+
+export function RefundStatusView({ talerRefundUri }: Props): JSX.Element {
+ const [applyResult, setApplyResult] = useState<ApplyRefundResponse | undefined>(undefined);
const [errMsg, setErrMsg] = useState<string | undefined>(undefined);
useEffect(() => {
+ if (!talerRefundUri) return;
const doFetch = async (): Promise<void> => {
try {
- const result = await wxApi.applyRefund(props.talerRefundUri);
+ const result = await wxApi.applyRefund(talerRefundUri);
setApplyResult(result);
} catch (e) {
console.error(e);
@@ -46,10 +50,14 @@ function RefundStatusView(props: { talerRefundUri: string }): JSX.Element {
}
};
doFetch();
- }, [props.talerRefundUri]);
+ }, [talerRefundUri]);
console.log("rendering");
+ if (!talerRefundUri) {
+ return <span>missing taler refund uri</span>;
+ }
+
if (errMsg) {
return <span>Error: {errMsg}</span>;
}
diff --git a/packages/taler-wallet-webextension/src/pages/tip.tsx b/packages/taler-wallet-webextension/src/pages/tip.tsx
index 65ddb3734..8528a5511 100644
--- a/packages/taler-wallet-webextension/src/pages/tip.tsx
+++ b/packages/taler-wallet-webextension/src/pages/tip.tsx
@@ -26,7 +26,11 @@ import { AmountView } from "../renderHtml";
import * as wxApi from "../wxApi";
import { JSX } from "preact/jsx-runtime";
-function TalerTipDialog({ talerTipUri }: { talerTipUri: string }): JSX.Element {
+interface Props {
+ talerTipUri?: string
+}
+
+export function TalerTipDialog({ talerTipUri }: Props): JSX.Element {
const [updateCounter, setUpdateCounter] = useState<number>(0);
const [prepareTipResult, setPrepareTipResult] = useState<
PrepareTipResult | undefined
@@ -35,6 +39,7 @@ function TalerTipDialog({ talerTipUri }: { talerTipUri: string }): JSX.Element {
const [tipIgnored, setTipIgnored] = useState(false);
useEffect(() => {
+ if (!talerTipUri) return;
const doFetch = async (): Promise<void> => {
const p = await wxApi.prepareTip({ talerTipUri });
setPrepareTipResult(p);
@@ -54,6 +59,10 @@ function TalerTipDialog({ talerTipUri }: { talerTipUri: string }): JSX.Element {
setTipIgnored(true);
};
+ if (!talerTipUri) {
+ return <span>missing tip uri</span>;
+ }
+
if (tipIgnored) {
return <span>You've ignored the tip.</span>;
}
diff --git a/packages/taler-wallet-webextension/src/pages/welcome.tsx b/packages/taler-wallet-webextension/src/pages/welcome.tsx
index 54819558c..61c9f036c 100644
--- a/packages/taler-wallet-webextension/src/pages/welcome.tsx
+++ b/packages/taler-wallet-webextension/src/pages/welcome.tsx
@@ -87,7 +87,7 @@ function Diagnostics(): JSX.Element | null {
<p>
Your wallet database is outdated. Currently automatic migration is
not supported. Please go{" "}
- <PageLink pageName="reset-required.html">here</PageLink> to reset
+ <PageLink pageName="/reset-required">here</PageLink> to reset
the wallet database.
</p>
) : null}
@@ -99,38 +99,38 @@ function Diagnostics(): JSX.Element | null {
return <p>Running diagnostics ...</p>;
}
-export function PermissionsCheckbox(): JSX.Element {
- const [extendedPermissionsEnabled, setExtendedPermissionsEnabled] = useState(
- false,
- );
- async function handleExtendedPerm(): Promise<void> {
- let nextVal: boolean | undefined;
- if (extendedPermissionsEnabled) {
- const granted = await new Promise<boolean>((resolve, reject) => {
- // We set permissions here, since apparently FF wants this to be done
- // as the result of an input event ...
- getPermissionsApi().request(extendedPermissions, (granted: boolean) => {
- if (chrome.runtime.lastError) {
- console.error("error requesting permissions");
- console.error(chrome.runtime.lastError);
- reject(chrome.runtime.lastError);
- return;
- }
- console.log("permissions granted:", granted);
- resolve(granted);
- });
+
+async function handleExtendedPerm(isEnabled: boolean, setEnable: (v:boolean) => void): Promise<void> {
+ let nextVal: boolean | undefined;
+
+ if (!isEnabled) {
+ const granted = await new Promise<boolean>((resolve, reject) => {
+ // We set permissions here, since apparently FF wants this to be done
+ // as the result of an input event ...
+ getPermissionsApi().request(extendedPermissions, (granted: boolean) => {
+ if (chrome.runtime.lastError) {
+ console.error("error requesting permissions");
+ console.error(chrome.runtime.lastError);
+ reject(chrome.runtime.lastError);
+ return;
+ }
+ console.log("permissions granted:", granted);
+ resolve(granted);
});
- const res = await wxApi.setExtendedPermissions(granted);
- console.log(res);
- nextVal = res.newValue;
- } else {
- const res = await wxApi.setExtendedPermissions(false);
- console.log(res);
- nextVal = res.newValue;
- }
- console.log("new permissions applied:", nextVal);
- setExtendedPermissionsEnabled(nextVal ?? false);
+ });
+ const res = await wxApi.setExtendedPermissions(granted);
+ nextVal = res.newValue;
+ } else {
+ const res = await wxApi.setExtendedPermissions(false);
+ nextVal = res.newValue;
}
+ console.log("new permissions applied:", nextVal);
+ setEnable(nextVal ?? false);
+}
+
+export function PermissionsCheckbox(): JSX.Element {
+ const [extendedPermissionsEnabled, setExtendedPermissionsEnabled] = useState(false);
+
useEffect(() => {
async function getExtendedPermValue(): Promise<void> {
const res = await wxApi.getExtendedPermissions();
@@ -138,11 +138,12 @@ export function PermissionsCheckbox(): JSX.Element {
}
getExtendedPermValue();
});
+
return (
<div>
<input
checked={extendedPermissionsEnabled}
- onChange={() => handleExtendedPerm()}
+ onChange={() => handleExtendedPerm(extendedPermissionsEnabled, setExtendedPermissionsEnabled) }
type="checkbox"
id="checkbox-perm"
style={{ width: "1.5em", height: "1.5em", verticalAlign: "middle" }}
@@ -168,7 +169,7 @@ export function PermissionsCheckbox(): JSX.Element {
);
}
-function Welcome(): JSX.Element {
+export function Welcome(): JSX.Element {
return (
<>
<p>Thank you for installing the wallet.</p>
diff --git a/packages/taler-wallet-webextension/src/pages/withdraw.tsx b/packages/taler-wallet-webextension/src/pages/withdraw.tsx
index 1d628be22..d99bcf9c0 100644
--- a/packages/taler-wallet-webextension/src/pages/withdraw.tsx
+++ b/packages/taler-wallet-webextension/src/pages/withdraw.tsx
@@ -34,12 +34,14 @@ import {
import { WithdrawUriInfoResponse } from "@gnu-taler/taler-util";
import { JSX } from "preact/jsx-runtime";
-function WithdrawalDialog(props: { talerWithdrawUri: string }): JSX.Element {
+interface Props {
+ talerWithdrawUri?: string;
+}
+export function WithdrawalDialog({ talerWithdrawUri }: Props): JSX.Element {
const [details, setDetails] = useState<WithdrawUriInfoResponse | undefined>(undefined);
const [selectedExchange, setSelectedExchange] = useState<
string | undefined
>(undefined);
- const talerWithdrawUri = props.talerWithdrawUri;
const [cancelled, setCancelled] = useState(false);
const [selecting, setSelecting] = useState(false);
const [errMsg, setErrMsg] = useState<string | undefined>("");
@@ -52,10 +54,9 @@ function WithdrawalDialog(props: { talerWithdrawUri: string }): JSX.Element {
}, []);
useEffect(() => {
+ if (!talerWithdrawUri) return
const fetchData = async (): Promise<void> => {
- const res = await getWithdrawalDetailsForUri({
- talerWithdrawUri: props.talerWithdrawUri,
- });
+ const res = await getWithdrawalDetailsForUri({ talerWithdrawUri });
setDetails(res);
if (res.defaultExchangeBaseUrl) {
setSelectedExchange(res.defaultExchangeBaseUrl);
@@ -64,6 +65,10 @@ function WithdrawalDialog(props: { talerWithdrawUri: string }): JSX.Element {
fetchData();
}, [selectedExchange, errMsg, selecting, talerWithdrawUri, updateCounter]);
+ if (!talerWithdrawUri) {
+ return <span>missing withdraw uri</span>;
+ }
+
if (!details) {
return <span>Loading...</span>;
}
diff --git a/packages/taler-wallet-webextension/src/renderHtml.tsx b/packages/taler-wallet-webextension/src/renderHtml.tsx
index 5574e96ea..2fde6f537 100644
--- a/packages/taler-wallet-webextension/src/renderHtml.tsx
+++ b/packages/taler-wallet-webextension/src/renderHtml.tsx
@@ -167,7 +167,7 @@ export function ProgressButton({isLoading, ...rest}: LoadingButtonProps): JSX.El
export function PageLink(
props: { pageName: string, children?: ComponentChildren },
): JSX.Element {
- const url = chrome.extension.getURL(`/${props.pageName}`);
+ const url = chrome.extension.getURL(`/static/popup.html#/${props.pageName}`);
return (
<a
className="actionLink"
diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts
index 22dd2c0e3..57146c0f5 100644
--- a/packages/taler-wallet-webextension/src/wxBackend.ts
+++ b/packages/taler-wallet-webextension/src/wxBackend.ts
@@ -276,7 +276,7 @@ try {
chrome.runtime.onInstalled.addListener((details) => {
console.log("onInstalled with reason", details.reason);
if (details.reason === "install") {
- const url = chrome.extension.getURL("/static/welcome.html");
+ const url = chrome.extension.getURL("/static/popup.html#/welcome");
chrome.tabs.create({ active: true, url: url });
}
});
@@ -311,7 +311,7 @@ function headerListener(
switch (uriType) {
case TalerUriType.TalerWithdraw:
return makeSyncWalletRedirect(
- "/static/withdraw.html",
+ "/static/popup.html#/withdraw",
details.tabId,
details.url,
{
@@ -320,7 +320,7 @@ function headerListener(
);
case TalerUriType.TalerPay:
return makeSyncWalletRedirect(
- "/static/pay.html",
+ "/static/popup.html#/pay",
details.tabId,
details.url,
{
@@ -329,7 +329,7 @@ function headerListener(
);
case TalerUriType.TalerTip:
return makeSyncWalletRedirect(
- "/static/tip.html",
+ "/static/popup.html#/tip",
details.tabId,
details.url,
{
@@ -338,7 +338,7 @@ function headerListener(
);
case TalerUriType.TalerRefund:
return makeSyncWalletRedirect(
- "/static/refund.html",
+ "/static/popup.html#/refund",
details.tabId,
details.url,
{
diff --git a/packages/taler-wallet-webextension/static/add-auditor.html b/packages/taler-wallet-webextension/static/add-auditor.html
deleted file mode 100644
index 47a97c075..000000000
--- a/packages/taler-wallet-webextension/static/add-auditor.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8" />
-
- <title>Taler Wallet: Add Auditor</title>
-
- <link rel="stylesheet" type="text/css" href="/style/wallet.css" />
-
- <link rel="icon" href="/img/icon.png" />
-
- <script src="/pageEntryPoint.js"></script>
-
- <style>
- .tree-item {
- margin: 2em;
- border-radius: 5px;
- border: 1px solid gray;
- padding: 1em;
- }
- .button-linky {
- background: none;
- color: black;
- text-decoration: underline;
- border: none;
- }
- </style>
- </head>
-
- <body>
- <div id="container"></div>
- </body>
-</html>
diff --git a/packages/taler-wallet-webextension/static/auditors.html b/packages/taler-wallet-webextension/static/auditors.html
deleted file mode 100644
index 15261290d..000000000
--- a/packages/taler-wallet-webextension/static/auditors.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8" />
- <title>Taler Wallet: Auditors</title>
-
- <link rel="stylesheet" type="text/css" href="/style/wallet.css" />
-
- <link rel="icon" href="/img/icon.png" />
-
- <script src="/dist/webextension/pageEntryPoint.js"></script>
-
- <style>
- body {
- font-size: 100%;
- }
- .tree-item {
- margin: 2em;
- border-radius: 5px;
- border: 1px solid gray;
- padding: 1em;
- }
- .button-linky {
- background: none;
- color: black;
- text-decoration: underline;
- border: none;
- }
- </style>
- </head>
-
- <body>
- <div id="container"></div>
- </body>
-</html>
diff --git a/packages/taler-wallet-webextension/static/benchmark.html b/packages/taler-wallet-webextension/static/benchmark.html
deleted file mode 100644
index d0ca32aeb..000000000
--- a/packages/taler-wallet-webextension/static/benchmark.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8" />
- <title>Taler Wallet: Benchmarks</title>
- <link rel="stylesheet" type="text/css" href="/static/style/wallet.css" />
- <link rel="icon" href="/static/img/icon.png" />
- <script src="/dist/pageEntryPoint.js"></script>
- </head>
- <body>
- <section id="main">
- <h1>Benchmarks</h1>
- <div id="container"></div>
- </section>
- </body>
-</html>
diff --git a/packages/taler-wallet-webextension/static/pay.html b/packages/taler-wallet-webextension/static/pay.html
deleted file mode 100644
index 129765815..000000000
--- a/packages/taler-wallet-webextension/static/pay.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8" />
- <title>Taler Wallet: Confirm Contract</title>
-
- <link rel="stylesheet" type="text/css" href="/static/style/pure.css" />
- <link rel="stylesheet" type="text/css" href="/static/style/wallet.css" />
- <link rel="icon" href="/static/img/icon.png" />
- <script src="/dist/pageEntryPoint.js"></script>
-
- <style>
- button.accept {
- background-color: #5757d2;
- border: 1px solid black;
- border-radius: 5px;
- margin: 1em 0;
- padding: 0.5em;
- font-weight: bold;
- color: white;
- }
- button.linky {
- background: none !important;
- border: none;
- padding: 0 !important;
-
- font-family: arial, sans-serif;
- color: #069;
- text-decoration: underline;
- cursor: pointer;
- }
-
- input.url {
- width: 25em;
- }
-
- button.accept:disabled {
- background-color: #dedbe8;
- border: 1px solid white;
- border-radius: 5px;
- margin: 1em 0;
- padding: 0.5em;
- font-weight: bold;
- color: #2c2c2c;
- }
-
- .errorbox {
- border: 1px solid;
- display: inline-block;
- margin: 1em;
- padding: 1em;
- font-weight: bold;
- background: #ff8a8a;
- }
-
- .okaybox {
- border: 1px solid;
- display: inline-block;
- margin: 1em;
- padding: 1em;
- font-weight: bold;
- background: #00fa9a;
- }
- </style>
- </head>
-
- <body>
- <section id="main">
- <h1>GNU Taler Wallet</h1>
- <article id="container" class="fade"></article>
- </section>
- </body>
-</html>
diff --git a/packages/taler-wallet-webextension/static/payback.html b/packages/taler-wallet-webextension/static/payback.html
deleted file mode 100644
index 7ca9dc974..000000000
--- a/packages/taler-wallet-webextension/static/payback.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8" />
- <title>Taler Wallet: Payback</title>
-
- <link rel="stylesheet" type="text/css" href="/style/pure.css" />
- <link rel="stylesheet" type="text/css" href="/style/wallet.css" />
- <link rel="icon" href="/img/icon.png" />
- <script src="/pageEntryPoint.js"></script>
-
- <style>
- body {
- font-size: 100%;
- }
- .tree-item {
- margin: 2em;
- border-radius: 5px;
- border: 1px solid gray;
- padding: 1em;
- }
- .button-linky {
- background: none;
- color: black;
- text-decoration: underline;
- border: none;
- }
- </style>
- </head>
-
- <body>
- <div id="container"></div>
- </body>
-</html>
diff --git a/packages/taler-wallet-webextension/static/refund.html b/packages/taler-wallet-webextension/static/refund.html
deleted file mode 100644
index 68c826bcf..000000000
--- a/packages/taler-wallet-webextension/static/refund.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8" />
- <title>Taler Wallet: Refund Status</title>
-
- <link rel="icon" href="/static/img/icon.png" />
- <link rel="stylesheet" type="text/css" href="/static/style/pure.css" />
- <link rel="stylesheet" type="text/css" href="/static/style/wallet.css" />
- <script src="/dist/pageEntryPoint.js"></script>
- </head>
-
- <body>
- <section id="main">
- <h1>GNU Taler Wallet</h1>
- <article id="container" class="fade"></article>
- </section>
- </body>
-</html>
diff --git a/packages/taler-wallet-webextension/static/reset-required.html b/packages/taler-wallet-webextension/static/reset-required.html
deleted file mode 100644
index 84943fbf1..000000000
--- a/packages/taler-wallet-webextension/static/reset-required.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8" />
- <title>Taler Wallet: Select Taler Provider</title>
-
- <link rel="icon" href="/img/icon.png" />
- <link rel="stylesheet" type="text/css" href="/style/pure.css" />
- <link rel="stylesheet" type="text/css" href="/style/wallet.css" />
- <script src="/pageEntryPoint.js"></script>
-
- <style>
- body {
- font-size: 100%;
- overflow-y: scroll;
- }
- </style>
- </head>
-
- <body>
- <section id="main">
- <div id="container"></div>
- </section>
- </body>
-</html>
diff --git a/packages/taler-wallet-webextension/static/style/popup.css b/packages/taler-wallet-webextension/static/style/popup.css
index cca002399..c0201e584 100644
--- a/packages/taler-wallet-webextension/static/style/popup.css
+++ b/packages/taler-wallet-webextension/static/style/popup.css
@@ -6,7 +6,7 @@
body {
min-height: 20em;
- width: 30em;
+ /* width: 30em; */
margin: 0;
padding: 0;
max-height: 800px;
@@ -183,3 +183,58 @@ input[type="radio"] {
text-align: center;
padding-top: 2em;
}
+
+/**
+ pay html
+*/
+button.accept {
+ background-color: #5757d2;
+ border: 1px solid black;
+ border-radius: 5px;
+ margin: 1em 0;
+ padding: 0.5em;
+ font-weight: bold;
+ color: white;
+}
+button.linky {
+ background: none !important;
+ border: none;
+ padding: 0 !important;
+
+ font-family: arial, sans-serif;
+ color: #069;
+ text-decoration: underline;
+ cursor: pointer;
+}
+
+input.url {
+ width: 25em;
+}
+
+button.accept:disabled {
+ background-color: #dedbe8;
+ border: 1px solid white;
+ border-radius: 5px;
+ margin: 1em 0;
+ padding: 0.5em;
+ font-weight: bold;
+ color: #2c2c2c;
+}
+
+.errorbox {
+ border: 1px solid;
+ display: inline-block;
+ margin: 1em;
+ padding: 1em;
+ font-weight: bold;
+ background: #ff8a8a;
+}
+
+.okaybox {
+ border: 1px solid;
+ display: inline-block;
+ margin: 1em;
+ padding: 1em;
+ font-weight: bold;
+ background: #00fa9a;
+}
diff --git a/packages/taler-wallet-webextension/static/tip.html b/packages/taler-wallet-webextension/static/tip.html
deleted file mode 100644
index 9c074e129..000000000
--- a/packages/taler-wallet-webextension/static/tip.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8" />
- <title>Taler Wallet: Received Tip</title>
-
- <link rel="icon" href="/static/img/icon.png" />
- <link rel="stylesheet" type="text/css" href="/static/style/pure.css" />
- <link rel="stylesheet" type="text/css" href="/static/style/wallet.css" />
- <script src="/dist/pageEntryPoint.js"></script>
- </head>
-
- <body>
- <section id="main">
- <h1>GNU Taler Wallet</h1>
- <div id="container"></div>
- </section>
- </body>
-</html>
diff --git a/packages/taler-wallet-webextension/static/welcome.html b/packages/taler-wallet-webextension/static/welcome.html
deleted file mode 100644
index e0b429f4b..000000000
--- a/packages/taler-wallet-webextension/static/welcome.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8" />
- <title>Taler Wallet Installed</title>
-
- <link rel="icon" href="/static/img/icon.png" />
- <link rel="stylesheet" type="text/css" href="/static/style/pure.css" />
- <link rel="stylesheet" type="text/css" href="/static/style/wallet.css" />
- <script src="/dist/pageEntryPoint.js"></script>
- </head>
-
- <body>
- <section id="main">
- <div style="border-bottom: 3px dashed #aa3939; margin-bottom: 2em;">
- <h1 style="font-family: monospace; font-size: 250%;">
- <span style="color: #aa3939;">❰</span>Taler Wallet<span style="color: #aa3939;">❱</span>
- </h1>
- </div>
- <h1>Browser Extension Installed!</h1>
- <div id="container">Loading...</div>
- </section>
- </body>
-</html>
diff --git a/packages/taler-wallet-webextension/static/withdraw.html b/packages/taler-wallet-webextension/static/withdraw.html
deleted file mode 100644
index b2b837658..000000000
--- a/packages/taler-wallet-webextension/static/withdraw.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta charset="UTF-8" />
- <title>Taler Wallet: Withdraw</title>
- <link rel="icon" href="/static/img/icon.png" />
- <link rel="stylesheet" type="text/css" href="/static/style/pure.css" />
- <link rel="stylesheet" type="text/css" href="/static/style/wallet.css" />
- <script src="/dist/pageEntryPoint.js"></script>
- </head>
-
- <body>
- <section id="main">
- <div style="border-bottom: 3px dashed #aa3939; margin-bottom: 2em;">
- <h1 style="font-family: monospace; font-size: 250%;">
- <span style="color: #aa3939;">❰</span>Taler Wallet<span style="color: #aa3939;">❱</span>
- </h1>
- </div>
- <div class="fade" id="container"></div>
- </section>
- </body>
-</html>
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 09b4f1c18..198562e9b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -216,12 +216,14 @@ importers:
'@rollup/plugin-replace': ^2.3.4
'@testing-library/preact': ^2.0.1
'@types/chrome': ^0.0.128
+ '@types/history': ^4.7.8
'@types/jest': ^26.0.23
'@types/node': ^14.14.22
ava: 3.15.0
babel-plugin-transform-react-jsx: ^6.24.1
enzyme: ^3.11.0
enzyme-adapter-preact-pure: ^3.1.0
+ history: 4.10.1
jest: ^26.6.3
jest-preset-preact: ^4.0.3
preact: ^10.5.13
@@ -251,12 +253,14 @@ importers:
'@rollup/plugin-replace': 2.3.4_rollup@2.37.1
'@testing-library/preact': 2.0.1_preact@10.5.13
'@types/chrome': 0.0.128
+ '@types/history': 4.7.8
'@types/jest': 26.0.23
'@types/node': 14.14.22
ava: 3.15.0
babel-plugin-transform-react-jsx: 6.24.1
enzyme: 3.11.0
enzyme-adapter-preact-pure: 3.1.0_enzyme@3.11.0+preact@10.5.13
+ history: 4.10.1
jest: 26.6.3
jest-preset-preact: 4.0.3_669f037bdb6c36f0a67e918c516dafdd
preact-cli: 3.0.5_c069246dc1d99535ac277c76f8ef56e0
@@ -2178,6 +2182,10 @@ packages:
resolution: {integrity: sha512-IG8AE1m2pWtPqQ7wXhFhy6Q59bwwnLwO36v5Rit2FrbXCIp8Sk8E2PfUCreyrdo17STwFSKDAkitVuVYbpEHvQ==}
dev: true
+ /@types/history/4.7.8:
+ resolution: {integrity: sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==}
+ dev: true
+
/@types/istanbul-lib-coverage/2.0.3:
resolution: {integrity: sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==}
dev: true
@@ -6569,6 +6577,17 @@ packages:
resolution: {integrity: sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==}
dev: true
+ /history/4.10.1:
+ resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==}
+ dependencies:
+ '@babel/runtime': 7.14.0
+ loose-envify: 1.4.0
+ resolve-pathname: 3.0.0
+ tiny-invariant: 1.1.0
+ tiny-warning: 1.0.3
+ value-equal: 1.0.1
+ dev: true
+
/hmac-drbg/1.0.1:
resolution: {integrity: sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=}
dependencies:
@@ -10818,6 +10837,10 @@ packages:
engines: {node: '>=8'}
dev: true
+ /resolve-pathname/3.0.0:
+ resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==}
+ dev: true
+
/resolve-url/0.2.1:
resolution: {integrity: sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=}
deprecated: https://github.com/lydell/resolve-url#deprecated
@@ -12097,6 +12120,14 @@ packages:
resolution: {integrity: sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=}
dev: true
+ /tiny-invariant/1.1.0:
+ resolution: {integrity: sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==}
+ dev: true
+
+ /tiny-warning/1.0.3:
+ resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
+ dev: true
+
/tmpl/1.0.4:
resolution: {integrity: sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=}
dev: true
@@ -12674,6 +12705,10 @@ packages:
engines: {node: '>= 0.10'}
dev: true
+ /value-equal/1.0.1:
+ resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==}
+ dev: true
+
/vary/1.1.2:
resolution: {integrity: sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=}
engines: {node: '>= 0.8'}