diff options
16 files changed, 117 insertions, 100 deletions
diff --git a/packages/taler-wallet-webextension/dev.mjs b/packages/taler-wallet-webextension/dev.mjs index 6c88f8a24..842424a9d 100755 --- a/packages/taler-wallet-webextension/dev.mjs +++ b/packages/taler-wallet-webextension/dev.mjs @@ -24,9 +24,6 @@ function broadcast(file, event) { }); }, devServerBroadcastDelay); } -wss.addListener("connection", () => { - console.log("new client") -}) const watcher = chokidar .watch(toWatch, { @@ -63,5 +60,8 @@ const server = await esbuild process.exit(1) }); -console.log("ready!", server.port); +console.log(`Dev server is ready at http://localhost:${server.port}/. +http://localhost:${server.port}/stories.html for the components stories. +The server is running a using websocket at ${devServerPort} to notify code change and live reload. +`); diff --git a/packages/taler-wallet-webextension/package.json b/packages/taler-wallet-webextension/package.json index bf586834b..07495a274 100644 --- a/packages/taler-wallet-webextension/package.json +++ b/packages/taler-wallet-webextension/package.json @@ -12,6 +12,7 @@ "test": "mocha --enable-source-maps 'dist/**/*.test.js'", "test:coverage": "nyc pnpm test", "compile": "tsc && ./build-fast-with-linaria.mjs", + "dev": "./dev.mjs", "compile:test": "rollup -c rollup.config.test.js -m", "prepare": "rollup -c -m", "pretty": "prettier --write src", diff --git a/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx b/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx index f37a212f7..0f1806fbf 100644 --- a/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx +++ b/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx @@ -5,7 +5,8 @@ import { Transaction, } from "@gnu-taler/taler-util"; import { Fragment, h, JSX, VNode } from "preact"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { useEffect } from "preact/hooks"; +import { useAsyncAsHook, useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js"; import { Avatar } from "../mui/Avatar.js"; import { Typography } from "../mui/Typography.js"; import * as wxApi from "../wxApi.js"; @@ -17,9 +18,14 @@ interface Props extends JSX.HTMLAttributes { } export function PendingTransactions({ goToTransaction }: Props): VNode { - const state = useAsyncAsHook(wxApi.getTransactions, [ - NotificationType.WithdrawGroupFinished, - ]); + const state = useAsyncAsHook2(wxApi.getTransactions); + + useEffect(() => { + wxApi.onUpdateNotification([NotificationType.WithdrawGroupFinished], () => { + state?.retry(); + }); + }); + const transactions = !state || state.hasError ? [] diff --git a/packages/taler-wallet-webextension/src/cta/Pay.tsx b/packages/taler-wallet-webextension/src/cta/Pay.tsx index 832b4879c..9b7f7862f 100644 --- a/packages/taler-wallet-webextension/src/cta/Pay.tsx +++ b/packages/taler-wallet-webextension/src/cta/Pay.tsx @@ -181,7 +181,7 @@ export function useComponentState( if (typeof window !== "undefined") { document.location.href = fu; } else { - console.log(`should redirect to ${fu}`); + console.log(`should d to ${fu}`); } } setPayResult(res); diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx index 21f98ec9a..56c64a6d7 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx +++ b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx @@ -40,7 +40,11 @@ import { WalletAction, } from "../components/styled/index.js"; import { useTranslationContext } from "../context/translation.js"; -import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { + HookError, + useAsyncAsHook, + useAsyncAsHook2, +} from "../hooks/useAsyncAsHook.js"; import { buildTermsOfServiceState } from "../utils/index.js"; import { ButtonHandler, SelectFieldHandler } from "../mui/handlers.js"; import * as wxApi from "../wxApi.js"; @@ -99,7 +103,7 @@ export function useComponentState( /** * Ask the wallet about the withdraw URI */ - const uriInfoHook = useAsyncAsHook(async () => { + const uriInfoHook = useAsyncAsHook2(async () => { if (!talerWithdrawUri) throw Error("ERROR_NO-URI-FOR-WITHDRAWAL"); const uriInfo = await api.getWithdrawalDetailsForUri({ @@ -147,44 +151,36 @@ export function useComponentState( /** * For the exchange selected, bring the status of the terms of service */ - const terms = useAsyncAsHook( - async () => { - if (!thisExchange) return false; + const terms = useAsyncAsHook2(async () => { + if (!thisExchange) return false; - const exchangeTos = await api.getExchangeTos(thisExchange, ["text/xml"]); + const exchangeTos = await api.getExchangeTos(thisExchange, ["text/xml"]); - const state = buildTermsOfServiceState(exchangeTos); + const state = buildTermsOfServiceState(exchangeTos); - return { state }; - }, - [], - [thisExchange], - ); + return { state }; + }, [thisExchange]); /** * With the exchange and amount, ask the wallet the information * about the withdrawal */ - const info = useAsyncAsHook( - async () => { - if (!thisExchange || !amount) return false; - - const info = await api.getExchangeWithdrawalInfo({ - exchangeBaseUrl: thisExchange, - amount, - tosAcceptedFormat: ["text/xml"], - }); - - const withdrawalFee = Amounts.sub( - Amounts.parseOrThrow(info.withdrawalAmountRaw), - Amounts.parseOrThrow(info.withdrawalAmountEffective), - ).amount; - - return { info, withdrawalFee }; - }, - [], - [thisExchange, amount], - ); + const info = useAsyncAsHook2(async () => { + if (!thisExchange || !amount) return false; + + const info = await api.getExchangeWithdrawalInfo({ + exchangeBaseUrl: thisExchange, + amount, + tosAcceptedFormat: ["text/xml"], + }); + + const withdrawalFee = Amounts.sub( + Amounts.parseOrThrow(info.withdrawalAmountRaw), + Amounts.parseOrThrow(info.withdrawalAmountEffective), + ).amount; + + return { info, withdrawalFee }; + }, [thisExchange, amount]); const [reviewing, setReviewing] = useState<boolean>(false); const [reviewed, setReviewed] = useState<boolean>(false); diff --git a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx index 37000bd38..d67e44346 100644 --- a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx +++ b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx @@ -16,7 +16,7 @@ import { Amounts, Balance, NotificationType } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; -import { useState } from "preact/hooks"; +import { useEffect, useState } from "preact/hooks"; import { BalanceTable } from "../components/BalanceTable.js"; import { JustInDevMode } from "../components/JustInDevMode.js"; import { Loading } from "../components/Loading.js"; @@ -24,7 +24,7 @@ import { LoadingError } from "../components/LoadingError.js"; import { MultiActionButton } from "../components/MultiActionButton.js"; import { ButtonBoxPrimary, ButtonPrimary } from "../components/styled/index.js"; import { useTranslationContext } from "../context/translation.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js"; import { AddNewActionView } from "../wallet/AddNewActionView.js"; import * as wxApi from "../wxApi.js"; import { NoBalanceHelp } from "./NoBalanceHelp.js"; @@ -41,9 +41,14 @@ export function BalancePage({ }: Props): VNode { const { i18n } = useTranslationContext(); const [addingAction, setAddingAction] = useState(false); - const state = useAsyncAsHook(wxApi.getBalance, [ - NotificationType.WithdrawGroupFinished, - ]); + const state = useAsyncAsHook2(wxApi.getBalance); + + useEffect(() => { + wxApi.onUpdateNotification([NotificationType.WithdrawGroupFinished], () => { + state?.retry(); + }); + }); + const balances = !state || state.hasError ? [] : state.response.balances; if (!state) { diff --git a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx index 505aa600b..00386b461 100644 --- a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx @@ -41,7 +41,7 @@ import { SmallText, } from "../components/styled/index.js"; import { useTranslationContext } from "../context/translation.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js"; import { Pages } from "../NavigationBar.js"; import * as wxApi from "../wxApi.js"; @@ -51,7 +51,7 @@ interface Props { export function BackupPage({ onAddProvider }: Props): VNode { const { i18n } = useTranslationContext(); - const status = useAsyncAsHook(wxApi.getBackupInfo); + const status = useAsyncAsHook2(wxApi.getBackupInfo); if (!status) { return <Loading />; } diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx index 98328ae4a..2bbd9f2e9 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx @@ -32,7 +32,7 @@ import { WarningBox, } from "../components/styled/index.js"; import { useTranslationContext } from "../context/translation.js"; -import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { HookError, useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js"; import { ButtonHandler, SelectFieldHandler, @@ -98,7 +98,7 @@ export function useComponentState( onSuccess: (currency: string) => void, api: typeof wxApi, ): State { - const hook = useAsyncAsHook(async () => { + const hook = useAsyncAsHook2(async () => { const { balances } = await api.getBalance(); const { accounts } = await api.listKnownBankAccounts(currency); const defaultSelectedAccount = @@ -117,10 +117,6 @@ export function useComponentState( const [fee, setFee] = useState<DepositGroupFees | undefined>(undefined); - // const hookResponse = !hook || hook.hasError ? undefined : hook.response; - - // useEffect(() => {}, [hookResponse]); - if (!hook || hook.hasError) { return { status: "loading", diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx index a54c16754..c70850c6d 100644 --- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx @@ -23,12 +23,12 @@ import { import { PendingTaskInfo } from "@gnu-taler/taler-wallet-core"; import { format } from "date-fns"; import { Fragment, h, VNode } from "preact"; -import { useRef, useState } from "preact/hooks"; +import { useEffect, useRef, useState } from "preact/hooks"; import { Diagnostics } from "../components/Diagnostics.js"; import { NotifyUpdateFadeOut } from "../components/styled/index.js"; import { Time } from "../components/Time.js"; import { useTranslationContext } from "../context/translation.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js"; import { useDiagnostics } from "../hooks/useDiagnostics.js"; import * as wxApi from "../wxApi.js"; @@ -38,7 +38,7 @@ export function DeveloperPage(): VNode { const listenAllEvents = Array.from<NotificationType>({ length: 1 }); listenAllEvents.includes = () => true; // includes every event - const response = useAsyncAsHook(async () => { + const response = useAsyncAsHook2(async () => { const op = await wxApi.getPendingOperations(); const c = await wxApi.dumpCoins(); const ex = await wxApi.listExchanges(); @@ -47,7 +47,13 @@ export function DeveloperPage(): VNode { coins: c.coins, exchanges: ex.exchanges, }; - }, listenAllEvents); + }); + + useEffect(() => { + wxApi.onUpdateNotification(listenAllEvents, () => { + response?.retry(); + }); + }); const nonResponse = { operations: [], coins: [], exchanges: [] }; const { operations, coins, exchanges } = diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx index 135cf68d8..a9e12505d 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx @@ -8,7 +8,7 @@ import { } from "../components/styled/index.js"; import { useTranslationContext } from "../context/translation.js"; import { TermsOfServiceSection } from "../cta/TermsOfServiceSection.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js"; import { buildTermsOfServiceState, TermsState } from "../utils/index.js"; import * as wxApi from "../wxApi.js"; @@ -23,7 +23,7 @@ export function ExchangeAddConfirmPage({ onCancel, onConfirm, }: Props): VNode { - const detailsHook = useAsyncAsHook(async () => { + const detailsHook = useAsyncAsHook2(async () => { const tos = await wxApi.getExchangeTos(url, ["text/xml"]); const tosState = buildTermsOfServiceState(tos); diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx index df423bb2b..2cf8ac647 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx @@ -20,7 +20,7 @@ import { } from "@gnu-taler/taler-util"; import { h, VNode } from "preact"; import { useState } from "preact/hooks"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js"; import { queryToSlashKeys } from "../utils/index.js"; import * as wxApi from "../wxApi.js"; import { ExchangeAddConfirmPage } from "./ExchangeAddConfirm.js"; @@ -36,7 +36,7 @@ export function ExchangeAddPage({ currency, onBack }: Props): VNode { { url: string; config: TalerConfigResponse } | undefined >(undefined); - const knownExchangesResponse = useAsyncAsHook(wxApi.listExchanges); + const knownExchangesResponse = useAsyncAsHook2(wxApi.listExchanges); const knownExchanges = !knownExchangesResponse ? [] : knownExchangesResponse.hasError diff --git a/packages/taler-wallet-webextension/src/wallet/History.tsx b/packages/taler-wallet-webextension/src/wallet/History.tsx index 51ffcb31a..cc99a8d0b 100644 --- a/packages/taler-wallet-webextension/src/wallet/History.tsx +++ b/packages/taler-wallet-webextension/src/wallet/History.tsx @@ -21,7 +21,7 @@ import { Transaction, } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; -import { useState } from "preact/hooks"; +import { useEffect, useState } from "preact/hooks"; import { Loading } from "../components/Loading.js"; import { LoadingError } from "../components/LoadingError.js"; import { @@ -35,7 +35,7 @@ import { import { Time } from "../components/Time.js"; import { TransactionItem } from "../components/TransactionItem.js"; import { useTranslationContext } from "../context/translation.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js"; import { NoBalanceHelp } from "../popup/NoBalanceHelp.js"; import * as wxApi from "../wxApi.js"; @@ -50,13 +50,16 @@ export function HistoryPage({ goToWalletDeposit, }: Props): VNode { const { i18n } = useTranslationContext(); - const state = useAsyncAsHook( - async () => ({ - b: await wxApi.getBalance(), - tx: await wxApi.getTransactions(), - }), - [NotificationType.WithdrawGroupFinished], - ); + const state = useAsyncAsHook2(async () => ({ + b: await wxApi.getBalance(), + tx: await wxApi.getTransactions(), + })); + + useEffect(() => { + wxApi.onUpdateNotification([NotificationType.WithdrawGroupFinished], () => { + state?.retry(); + }); + }); if (!state) { return <Loading />; diff --git a/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx b/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx index 8b8d375de..1d0e81e01 100644 --- a/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx @@ -23,11 +23,11 @@ import { PaytoUri, } from "@gnu-taler/taler-util"; import { h, VNode } from "preact"; -import { useState } from "preact/hooks"; +import { useEffect, useState } from "preact/hooks"; import { Loading } from "../components/Loading.js"; import { LoadingError } from "../components/LoadingError.js"; import { useTranslationContext } from "../context/translation.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { useAsyncAsHook, useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js"; import * as wxApi from "../wxApi.js"; import { CreateManualWithdraw } from "./CreateManualWithdraw.js"; import { ReserveCreated } from "./ReserveCreated.js"; @@ -50,9 +50,12 @@ export function ManualWithdrawPage({ currency, onCancel }: Props): VNode { >(undefined); const [error, setError] = useState<string | undefined>(undefined); - const state = useAsyncAsHook(wxApi.listExchanges, [ - NotificationType.ExchangeAdded, - ]); + const state = useAsyncAsHook2(wxApi.listExchanges); + useEffect(() => { + wxApi.onUpdateNotification([NotificationType.ExchangeAdded], () => { + state?.retry(); + }); + }); const { i18n } = useTranslationContext(); async function doCreate( diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx index bf9f55b10..1228c7951 100644 --- a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx @@ -34,7 +34,7 @@ import { } from "../components/styled/index.js"; import { Time } from "../components/Time.js"; import { useTranslationContext } from "../context/translation.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js"; import * as wxApi from "../wxApi.js"; interface Props { @@ -54,7 +54,7 @@ export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode { return providers.length ? providers[0] : null; } - const state = useAsyncAsHook(getProviderInfo); + const state = useAsyncAsHook2(getProviderInfo); if (!state) { return <Loading />; diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.tsx index 9a41bcc25..eefa5f385 100644 --- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx @@ -29,7 +29,7 @@ import { } from "../components/styled/index.js"; import { useDevContext } from "../context/devContext.js"; import { useTranslationContext } from "../context/translation.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js"; import { useBackupDeviceName } from "../hooks/useBackupDeviceName.js"; import { useExtendedPermissions } from "../hooks/useExtendedPermissions.js"; import { Pages } from "../NavigationBar.js"; @@ -40,13 +40,11 @@ export function SettingsPage(): VNode { const [permissionsEnabled, togglePermissions] = useExtendedPermissions(); const { devMode, toggleDevMode } = useDevContext(); const { name, update } = useBackupDeviceName(); - // const [lang, changeLang] = useLang(); - const exchangesHook = useAsyncAsHook(wxApi.listExchanges); + + const exchangesHook = useAsyncAsHook2(wxApi.listExchanges); return ( <SettingsView - // lang={lang} - // changeLang={changeLang} knownExchanges={ !exchangesHook || exchangesHook.hasError ? [] @@ -63,8 +61,6 @@ export function SettingsPage(): VNode { } export interface ViewProps { - // lang: string; - // changeLang: (s: string) => void; deviceName: string; setDeviceName: (s: string) => Promise<void>; permissionsEnabled: boolean; diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx index 4a6c218c7..cf87089b1 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx @@ -16,7 +16,6 @@ import { AbsoluteTime, - AmountLike, Amounts, NotificationType, parsePaytoUri, @@ -26,7 +25,7 @@ import { } from "@gnu-taler/taler-util"; import { differenceInSeconds } from "date-fns"; import { ComponentChildren, Fragment, h, VNode } from "preact"; -import { useState } from "preact/hooks"; +import { useEffect, useState } from "preact/hooks"; import emptyImg from "../../static/img/empty.png"; import { Amount } from "../components/Amount.js"; import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType.js"; @@ -49,28 +48,34 @@ import { } from "../components/styled/index.js"; import { Time } from "../components/Time.js"; import { useTranslationContext } from "../context/translation.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js"; import * as wxApi from "../wxApi.js"; interface Props { tid: string; goToWalletHistory: (currency?: string) => void; } + +async function getTransaction(tid: string): Promise<Transaction> { + const res = await wxApi.getTransactions(); + const ts = res.transactions.filter((t) => t.transactionId === tid); + if (ts.length > 1) throw Error("more than one transaction with this id"); + if (ts.length === 1) { + return ts[0]; + } + throw Error("no transaction found"); +} + export function TransactionPage({ tid, goToWalletHistory }: Props): VNode { const { i18n } = useTranslationContext(); - async function getTransaction(): Promise<Transaction> { - const res = await wxApi.getTransactions(); - const ts = res.transactions.filter((t) => t.transactionId === tid); - if (ts.length > 1) throw Error("more than one transaction with this id"); - if (ts.length === 1) { - return ts[0]; - } - throw Error("no transaction found"); - } - const state = useAsyncAsHook(getTransaction, [ - NotificationType.WithdrawGroupFinished, - ]); + const state = useAsyncAsHook2(() => getTransaction(tid)); + + useEffect(() => { + wxApi.onUpdateNotification([NotificationType.WithdrawGroupFinished], () => { + state?.retry(); + }); + }); if (!state) { return <Loading />; |