From 1961f4744ca0db4666a2df4335c768ed86fc4e2f Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 2 Jun 2023 14:26:28 -0300 Subject: remove deprecated notifications, implement isOffline --- .../build-fast-with-linaria.mjs | 143 --------------------- packages/taler-wallet-webextension/dev.mjs | 2 +- .../src/components/styled/index.tsx | 11 ++ .../src/cta/InvoicePay/state.ts | 6 +- .../src/cta/Payment/state.ts | 2 +- .../src/cta/Payment/test.ts | 4 +- .../src/cta/PaymentTemplate/state.ts | 2 +- .../src/hooks/useIsOnline.ts | 14 ++ .../taler-wallet-webextension/src/platform/api.ts | 7 + .../src/platform/chrome.ts | 18 +++ .../taler-wallet-webextension/src/platform/dev.ts | 18 +++ .../src/wallet/Application.tsx | 9 ++ .../src/wallet/DeveloperPage.tsx | 6 +- packages/taler-wallet-webextension/test.mjs | 2 +- 14 files changed, 91 insertions(+), 153 deletions(-) delete mode 100755 packages/taler-wallet-webextension/build-fast-with-linaria.mjs create mode 100644 packages/taler-wallet-webextension/src/hooks/useIsOnline.ts diff --git a/packages/taler-wallet-webextension/build-fast-with-linaria.mjs b/packages/taler-wallet-webextension/build-fast-with-linaria.mjs deleted file mode 100755 index 9f31fa49c..000000000 --- a/packages/taler-wallet-webextension/build-fast-with-linaria.mjs +++ /dev/null @@ -1,143 +0,0 @@ -#!/usr/bin/env node -/* - 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 - */ - -import linaria from "@linaria/esbuild"; -import esbuild from "esbuild"; -import path from "path"; -import fs from "fs"; - -function getFilesInDirectory(startPath, regex) { - if (!fs.existsSync(startPath)) { - return; - } - const files = fs.readdirSync(startPath); - const result = files - .flatMap((file) => { - const filename = path.join(startPath, file); - - const stat = fs.lstatSync(filename); - if (stat.isDirectory()) { - return getFilesInDirectory(filename, regex); - } else if (regex.test(filename)) { - return filename; - } - }) - .filter((x) => !!x); - - return result; -} - -// eslint-disable-next-line no-undef -const BASE = process.cwd(); -const allTestFiles = getFilesInDirectory(path.join(BASE, "src"), /.test.ts$/); - -const preact = path.join( - BASE, - "node_modules", - "preact", - "compat", - "dist", - "compat.module.js", -); -const preactCompatPlugin = { - name: "preact-compat", - setup(build) { - build.onResolve({ filter: /^(react-dom|react)$/ }, (args) => ({ - path: preact, - })); - }, -}; - -const entryPoints = [ - "src/popupEntryPoint.tsx", - "src/popupEntryPoint.dev.tsx", - "src/walletEntryPoint.tsx", - "src/walletEntryPoint.dev.tsx", - "src/background.ts", - "src/stories.tsx", - "src/background.dev.ts", - "src/taler-wallet-interaction-loader.ts", - "src/taler-wallet-interaction-support.ts", - "src/browserWorkerEntry.ts", -]; - -let GIT_ROOT = BASE; -while (!fs.existsSync(path.join(GIT_ROOT, ".git")) && GIT_ROOT !== "/") { - GIT_ROOT = path.join(GIT_ROOT, "../"); -} -if (GIT_ROOT === "/") { - // eslint-disable-next-line no-undef - console.log("not found"); - // eslint-disable-next-line no-undef - process.exit(1); -} -const GIT_HASH = GIT_ROOT === "/" ? undefined : git_hash(); - -let _package = JSON.parse(fs.readFileSync(path.join(BASE, "package.json"))); - -function git_hash() { - const rev = fs - .readFileSync(path.join(GIT_ROOT, ".git", "HEAD")) - .toString() - .trim() - .split(/.*[: ]/) - .slice(-1)[0]; - if (rev.indexOf("/") === -1) { - return rev; - } else { - return fs.readFileSync(path.join(GIT_ROOT, ".git", rev)).toString().trim(); - } -} - -export const buildConfig = { - entryPoints: [...entryPoints, ...allTestFiles], - bundle: true, - outdir: "dist", - minify: false, - loader: { - ".svg": "text", - ".png": "dataurl", - ".jpeg": "dataurl", - }, - target: ["es6"], - format: "iife", - platform: "browser", - sourcemap: true, - jsxFactory: "h", - jsxFragment: "Fragment", - define: { - __VERSION__: `"${_package.version}"`, - __GIT_HASH__: `"${GIT_HASH}"`, - }, - plugins: [ - preactCompatPlugin, - linaria.default({ - babelOptions: { - babelrc: false, - configFile: "./babel.config-linaria.json", - }, - sourceMap: true, - }), - ], -}; - -await esbuild.build(buildConfig).catch((e) => { - // eslint-disable-next-line no-undef - console.log(e); - // eslint-disable-next-line no-undef - process.exit(1); -}); diff --git a/packages/taler-wallet-webextension/dev.mjs b/packages/taler-wallet-webextension/dev.mjs index 5577b1f0e..dc597c248 100755 --- a/packages/taler-wallet-webextension/dev.mjs +++ b/packages/taler-wallet-webextension/dev.mjs @@ -19,7 +19,7 @@ import { getFilesInDirectory, initializeDev } from "@gnu-taler/web-util/build"; import { serve } from "@gnu-taler/web-util/node"; import linaria from "@linaria/esbuild"; -const allStaticFiles = getFilesInDirectory("src/spa"); +const allStaticFiles = getFilesInDirectory("src/pwa"); const devEntryPoints = [ "src/popupEntryPoint.dev.tsx", diff --git a/packages/taler-wallet-webextension/src/components/styled/index.tsx b/packages/taler-wallet-webextension/src/components/styled/index.tsx index 92b8d2667..47b3c8e08 100644 --- a/packages/taler-wallet-webextension/src/components/styled/index.tsx +++ b/packages/taler-wallet-webextension/src/components/styled/index.tsx @@ -799,6 +799,17 @@ export const ErrorBox = styled.div` } `; +export const RedBanner = styled.div` + width: 80%; + padding: 4px; + text-align: center; + background: red; + border: 1px solid #df3a3a; + border-radius: 4px; + font-weight: bold; + margin: 4px; +`; + export const InfoBox = styled(ErrorBox)` color: black; background-color: #d1e7dd; diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts index 10f1ee849..c6512cd12 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts @@ -49,7 +49,7 @@ export function useComponentState({ useEffect(() => api.listener.onUpdateNotification( - [NotificationType.CoinWithdrawn], + [NotificationType.TransactionStateTransition], hook?.retry, ), ); @@ -123,7 +123,9 @@ export function useComponentState({ raw, goToWalletManualWithdraw, summary, - expiration: expiration ? AbsoluteTime.fromProtocolTimestamp(expiration) : undefined, + expiration: expiration + ? AbsoluteTime.fromProtocolTimestamp(expiration) + : undefined, }; if (!foundBalance) { diff --git a/packages/taler-wallet-webextension/src/cta/Payment/state.ts b/packages/taler-wallet-webextension/src/cta/Payment/state.ts index 586ef377c..4468438d1 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Payment/state.ts @@ -54,7 +54,7 @@ export function useComponentState({ useEffect( () => api.listener.onUpdateNotification( - [NotificationType.CoinWithdrawn], + [NotificationType.TransactionStateTransition], hook?.retry, ), [hook], diff --git a/packages/taler-wallet-webextension/src/cta/Payment/test.ts b/packages/taler-wallet-webextension/src/cta/Payment/test.ts index 655f21eb9..e2935fc4e 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Payment/test.ts @@ -541,7 +541,9 @@ describe("Payment CTA states", () => { // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); expect(state.payHandler.onClick).not.undefined; - handler.notifyEventFromWallet(NotificationType.CoinWithdrawn); + handler.notifyEventFromWallet( + NotificationType.TransactionStateTransition, + ); }, (state) => { if (state.status !== "ready") expect.fail(); diff --git a/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts b/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts index a33361be8..4a0b2911a 100644 --- a/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts +++ b/packages/taler-wallet-webextension/src/cta/PaymentTemplate/state.ts @@ -128,7 +128,7 @@ export function useComponentState({ } const errors = undefinedIfEmpty({ amount: amount && Amounts.isZero(amount) ? i18n.str`required` : undefined, - summary: !summary ? i18n.str`required` : undefined, + summary: summary !== undefined && !summary ? i18n.str`required` : undefined, }); return { status: "fill-template", diff --git a/packages/taler-wallet-webextension/src/hooks/useIsOnline.ts b/packages/taler-wallet-webextension/src/hooks/useIsOnline.ts new file mode 100644 index 000000000..8d26bf3b6 --- /dev/null +++ b/packages/taler-wallet-webextension/src/hooks/useIsOnline.ts @@ -0,0 +1,14 @@ +import { codecForBoolean } from "@gnu-taler/taler-util"; +import { buildStorageKey, useMemoryStorage } from "@gnu-taler/web-util/browser"; +import { platform } from "../platform/foreground.js"; +import { useEffect } from "preact/hooks"; + +export function useIsOnline(): boolean { + const { value, update } = useMemoryStorage("online", true); + useEffect(() => { + return platform.listenNetworkConnectionState((state) => { + update(state === "on"); + }); + }); + return value; +} diff --git a/packages/taler-wallet-webextension/src/platform/api.ts b/packages/taler-wallet-webextension/src/platform/api.ts index f985cc4f8..e3e97264d 100644 --- a/packages/taler-wallet-webextension/src/platform/api.ts +++ b/packages/taler-wallet-webextension/src/platform/api.ts @@ -286,4 +286,11 @@ export interface ForegroundPlatformAPI { listenToWalletBackground( listener: (message: MessageFromBackend) => void, ): () => void; + + /** + * Notify when platform went offline + */ + listenNetworkConnectionState( + listener: (state: "on" | "off") => void, + ): () => void; } diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts b/packages/taler-wallet-webextension/src/platform/chrome.ts index 0f6b5fb0d..34057a310 100644 --- a/packages/taler-wallet-webextension/src/platform/chrome.ts +++ b/packages/taler-wallet-webextension/src/platform/chrome.ts @@ -58,6 +58,7 @@ const api: BackgroundPlatformAPI & ForegroundPlatformAPI = { sendMessageToBackground, useServiceWorkerAsBackgroundProcess, keepAlive, + listenNetworkConnectionState, }; export default api; @@ -762,3 +763,20 @@ async function findTalerUriInActiveTab(): Promise { if (!tab || tab.id === undefined) return; return findTalerUriInTab(tab.id); } + +function listenNetworkConnectionState( + notify: (state: "on" | "off") => void, +): () => void { + function notifyOffline() { + notify("off"); + } + function notifyOnline() { + notify("on"); + } + window.addEventListener("offline", notifyOffline); + window.addEventListener("online", notifyOnline); + return () => { + window.removeEventListener("offline", notifyOffline); + window.removeEventListener("online", notifyOnline); + }; +} diff --git a/packages/taler-wallet-webextension/src/platform/dev.ts b/packages/taler-wallet-webextension/src/platform/dev.ts index 005421876..976ac05f5 100644 --- a/packages/taler-wallet-webextension/src/platform/dev.ts +++ b/packages/taler-wallet-webextension/src/platform/dev.ts @@ -34,6 +34,7 @@ const api: BackgroundPlatformAPI & ForegroundPlatformAPI = { keepAlive: (cb: VoidFunction) => cb(), findTalerUriInActiveTab: async () => undefined, findTalerUriInClipboard: async () => undefined, + listenNetworkConnectionState, getPermissionsApi: () => ({ addPermissionsListener: () => undefined, containsHostPermissions: async () => true, @@ -197,3 +198,20 @@ interface IframeMessageCommand { } export default api; + +function listenNetworkConnectionState( + notify: (state: "on" | "off") => void, +): () => void { + function notifyOffline() { + notify("off"); + } + function notifyOnline() { + notify("on"); + } + window.addEventListener("offline", notifyOffline); + window.addEventListener("online", notifyOnline); + return () => { + window.removeEventListener("offline", notifyOffline); + window.removeEventListener("online", notifyOnline); + }; +} diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx index 31a71e249..13afccb6c 100644 --- a/packages/taler-wallet-webextension/src/wallet/Application.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx @@ -44,6 +44,7 @@ import { LogoHeader } from "../components/LogoHeader.js"; import PendingTransactions from "../components/PendingTransactions.js"; import { LinkPrimary, + RedBanner, SubTitle, WalletAction, WalletBox, @@ -80,6 +81,7 @@ import { QrReaderPage } from "./QrReader.js"; import { SettingsPage } from "./Settings.js"; import { TransactionPage } from "./Transaction.js"; import { WelcomePage } from "./Welcome.js"; +import { useIsOnline } from "../hooks/useIsOnline.js"; export function Application(): VNode { const { i18n } = useTranslationContext(); @@ -585,8 +587,15 @@ function WalletTemplate({ children: ComponentChildren; goToTransaction?: (id: string) => Promise; }): VNode { + const online = useIsOnline(); + const { i18n } = useTranslationContext(); return ( + {!online && ( +
+ {i18n.str`Network is offline`} +
+ )} {goToTransaction ? ( diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx index 388a331e6..c5e5c3c07 100644 --- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx @@ -47,8 +47,6 @@ export function DeveloperPage(): VNode { const [status, timedOut] = useDiagnostics(); const listenAllEvents = Array.from({ length: 1 }); - //FIXME: waiting for retry notification make a always increasing loop of notifications - listenAllEvents.includes = (e) => e !== "waiting-for-retry"; // includes every event const api = useBackendContext(); @@ -405,7 +403,9 @@ export function View({ Database exported at