summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/popup/Application.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/popup/Application.tsx')
-rw-r--r--packages/taler-wallet-webextension/src/popup/Application.tsx229
1 files changed, 229 insertions, 0 deletions
diff --git a/packages/taler-wallet-webextension/src/popup/Application.tsx b/packages/taler-wallet-webextension/src/popup/Application.tsx
new file mode 100644
index 000000000..cbb9b50b2
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/popup/Application.tsx
@@ -0,0 +1,229 @@
+/*
+ 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/>
+ */
+
+/**
+ * Main entry point for extension pages.
+ *
+ * @author sebasjm
+ */
+
+import {
+ TranslationProvider,
+ useTranslationContext,
+} from "@gnu-taler/web-util/browser";
+import { createHashHistory } from "history";
+import { ComponentChildren, Fragment, h, VNode } from "preact";
+import { route, Route, Router } from "preact-router";
+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 { IoCProviderForRuntime } from "../context/iocContext.js";
+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";
+
+export function Application(): VNode {
+ return (
+ <TranslationProvider source={strings}>
+ <IoCProviderForRuntime>
+ <ApplicationView />
+ </IoCProviderForRuntime>
+ </TranslationProvider>
+ );
+}
+function ApplicationView(): VNode {
+ const hash_history = createHashHistory();
+
+ const [action, setDismissed] = useTalerActionURL();
+
+ const actionUri = action?.uri;
+
+ useEffect(() => {
+ if (actionUri) {
+ route(Pages.cta({ action: encodeURIComponent(actionUri) }));
+ }
+ }, [actionUri]);
+
+ async function redirectToTxInfo(tid: string): Promise<void> {
+ redirectTo(Pages.balanceTransaction({ tid }));
+ }
+
+ function redirectToURL(str: string): void {
+ platform.openNewURLFromPopup(new URL(str))
+ }
+
+ return (
+ <Router history={hash_history}>
+ <Route
+ path={Pages.balance}
+ component={() => (
+ <PopupTemplate path="balance" goToTransaction={redirectToTxInfo} goToURL={redirectToURL}>
+ <BalancePage
+ goToWalletManualWithdraw={() => redirectTo(Pages.receiveCash({}))}
+ goToWalletDeposit={(currency: string) =>
+ redirectTo(Pages.sendCash({ amount: `${currency}:0` }))
+ }
+ goToWalletHistory={(currency: string) =>
+ redirectTo(Pages.balanceHistory({ currency }))
+ }
+ />
+ </PopupTemplate>
+ )}
+ />
+
+ <Route
+ path={Pages.cta.pattern}
+ component={function Action({ action }: { action: string }) {
+ // const [, setDismissed] = useTalerActionURL();
+
+ return (
+ <PopupTemplate goToURL={redirectToURL}>
+ <TalerActionFound
+ url={decodeURIComponent(action)}
+ onDismiss={() => {
+ setDismissed(true);
+ return redirectTo(Pages.balance);
+ }}
+ />
+ </PopupTemplate>
+ );
+ }}
+ />
+
+ <Route
+ path={Pages.backup}
+ component={() => (
+ <PopupTemplate path="backup" goToTransaction={redirectToTxInfo} goToURL={redirectToURL}>
+ <BackupPage
+ onAddProvider={() => redirectTo(Pages.backupProviderAdd)}
+ />
+ </PopupTemplate>
+ )}
+ />
+ <Route
+ path={Pages.backupProviderDetail.pattern}
+ component={({ pid }: { pid: string }) => (
+ <PopupTemplate path="backup" goToURL={redirectToURL}>
+ <ProviderDetailPage
+ onPayProvider={(uri: string) =>
+ redirectTo(`${Pages.ctaPay}?talerPayUri=${uri}`)
+ }
+ onWithdraw={(amount: string) =>
+ redirectTo(Pages.receiveCash({ amount }))
+ }
+ pid={pid}
+ onBack={() => redirectTo(Pages.backup)}
+ />
+ </PopupTemplate>
+ )}
+ />
+
+ <Route
+ path={Pages.balanceTransaction.pattern}
+ component={RedirectToWalletPage}
+ />
+ <Route
+ path={Pages.ctaWithdrawManual.pattern}
+ component={RedirectToWalletPage}
+ />
+ <Route
+ path={Pages.balanceDeposit.pattern}
+ component={RedirectToWalletPage}
+ />
+ <Route
+ path={Pages.balanceHistory.pattern}
+ component={RedirectToWalletPage}
+ />
+ <Route path={Pages.backupProviderAdd} component={RedirectToWalletPage} />
+ <Route
+ path={Pages.receiveCash.pattern}
+ component={RedirectToWalletPage}
+ />
+ <Route path={Pages.sendCash.pattern} component={RedirectToWalletPage} />
+ <Route path={Pages.ctaPayTemplate} component={RedirectToWalletPage} />
+ <Route path={Pages.ctaPay} component={RedirectToWalletPage} />
+ <Route path={Pages.qr} component={RedirectToWalletPage} />
+ <Route path={Pages.settings} component={RedirectToWalletPage} />
+ <Route
+ path={Pages.settingsExchangeAdd.pattern}
+ component={RedirectToWalletPage}
+ />
+ <Route path={Pages.dev} component={RedirectToWalletPage} />
+ <Route path={Pages.notifications} component={RedirectToWalletPage} />
+
+ <Route default component={Redirect} to={Pages.balance} />
+ </Router>
+ );
+}
+
+function RedirectToWalletPage(): VNode {
+ const page = (document.location.hash || "#/").replace("#", "");
+ const [showText, setShowText] = useState(false);
+ useEffect(() => {
+ platform.openWalletPageFromPopup(page);
+ setTimeout(() => {
+ setShowText(true);
+ }, 250);
+ });
+ const { i18n } = useTranslationContext();
+ if (!showText) return <Fragment />;
+ return (
+ <span>
+ <i18n.Translate>
+ this popup is being closed and you are being redirected to {page}
+ </i18n.Translate>
+ </span>
+ );
+}
+
+async function redirectTo(location: string): Promise<void> {
+ route(location);
+}
+
+function Redirect({ to }: { to: string }): null {
+ useEffect(() => {
+ route(to, true);
+ });
+ return null;
+}
+
+function PopupTemplate({
+ path,
+ children,
+ goToTransaction,
+ goToURL,
+}: {
+ path?: PopupNavBarOptions;
+ children: ComponentChildren;
+ goToTransaction?: (id: string) => Promise<void>;
+ goToURL: (s: string) => void;
+}): VNode {
+ return (
+ <Fragment>
+ <PendingTransactions goToTransaction={goToTransaction} goToURL={goToURL} />
+ <PopupNavBar path={path} />
+ <PopupBox>
+ <AlertProvider>{children}</AlertProvider>
+ </PopupBox>
+ </Fragment>
+ );
+}