useAsync new API

This commit is contained in:
Sebastian 2022-04-25 22:37:41 -03:00
parent 1e6b2dd150
commit 65e6a8caa0
No known key found for this signature in database
GPG Key ID: BE4FF68352439FC1
16 changed files with 114 additions and 97 deletions

View File

@ -24,9 +24,6 @@ function broadcast(file, event) {
}); });
}, devServerBroadcastDelay); }, devServerBroadcastDelay);
} }
wss.addListener("connection", () => {
console.log("new client")
})
const watcher = chokidar const watcher = chokidar
.watch(toWatch, { .watch(toWatch, {
@ -63,5 +60,8 @@ const server = await esbuild
process.exit(1) 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.
`);

View File

@ -12,6 +12,7 @@
"test": "mocha --enable-source-maps 'dist/**/*.test.js'", "test": "mocha --enable-source-maps 'dist/**/*.test.js'",
"test:coverage": "nyc pnpm test", "test:coverage": "nyc pnpm test",
"compile": "tsc && ./build-fast-with-linaria.mjs", "compile": "tsc && ./build-fast-with-linaria.mjs",
"dev": "./dev.mjs",
"compile:test": "rollup -c rollup.config.test.js -m", "compile:test": "rollup -c rollup.config.test.js -m",
"prepare": "rollup -c -m", "prepare": "rollup -c -m",
"pretty": "prettier --write src", "pretty": "prettier --write src",

View File

@ -5,7 +5,8 @@ import {
Transaction, Transaction,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { Fragment, h, JSX, VNode } from "preact"; 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 { Avatar } from "../mui/Avatar.js";
import { Typography } from "../mui/Typography.js"; import { Typography } from "../mui/Typography.js";
import * as wxApi from "../wxApi.js"; import * as wxApi from "../wxApi.js";
@ -17,9 +18,14 @@ interface Props extends JSX.HTMLAttributes {
} }
export function PendingTransactions({ goToTransaction }: Props): VNode { export function PendingTransactions({ goToTransaction }: Props): VNode {
const state = useAsyncAsHook(wxApi.getTransactions, [ const state = useAsyncAsHook2(wxApi.getTransactions);
NotificationType.WithdrawGroupFinished,
]); useEffect(() => {
wxApi.onUpdateNotification([NotificationType.WithdrawGroupFinished], () => {
state?.retry();
});
});
const transactions = const transactions =
!state || state.hasError !state || state.hasError
? [] ? []

View File

@ -181,7 +181,7 @@ export function useComponentState(
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
document.location.href = fu; document.location.href = fu;
} else { } else {
console.log(`should redirect to ${fu}`); console.log(`should d to ${fu}`);
} }
} }
setPayResult(res); setPayResult(res);

View File

@ -40,7 +40,11 @@ import {
WalletAction, WalletAction,
} from "../components/styled/index.js"; } from "../components/styled/index.js";
import { useTranslationContext } from "../context/translation.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 { buildTermsOfServiceState } from "../utils/index.js";
import { ButtonHandler, SelectFieldHandler } from "../mui/handlers.js"; import { ButtonHandler, SelectFieldHandler } from "../mui/handlers.js";
import * as wxApi from "../wxApi.js"; import * as wxApi from "../wxApi.js";
@ -99,7 +103,7 @@ export function useComponentState(
/** /**
* Ask the wallet about the withdraw URI * Ask the wallet about the withdraw URI
*/ */
const uriInfoHook = useAsyncAsHook(async () => { const uriInfoHook = useAsyncAsHook2(async () => {
if (!talerWithdrawUri) throw Error("ERROR_NO-URI-FOR-WITHDRAWAL"); if (!talerWithdrawUri) throw Error("ERROR_NO-URI-FOR-WITHDRAWAL");
const uriInfo = await api.getWithdrawalDetailsForUri({ const uriInfo = await api.getWithdrawalDetailsForUri({
@ -147,44 +151,36 @@ export function useComponentState(
/** /**
* For the exchange selected, bring the status of the terms of service * For the exchange selected, bring the status of the terms of service
*/ */
const terms = useAsyncAsHook( const terms = useAsyncAsHook2(async () => {
async () => { if (!thisExchange) return false;
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 }; return { state };
}, }, [thisExchange]);
[],
[thisExchange],
);
/** /**
* With the exchange and amount, ask the wallet the information * With the exchange and amount, ask the wallet the information
* about the withdrawal * about the withdrawal
*/ */
const info = useAsyncAsHook( const info = useAsyncAsHook2(async () => {
async () => { if (!thisExchange || !amount) return false;
if (!thisExchange || !amount) return false;
const info = await api.getExchangeWithdrawalInfo({ const info = await api.getExchangeWithdrawalInfo({
exchangeBaseUrl: thisExchange, exchangeBaseUrl: thisExchange,
amount, amount,
tosAcceptedFormat: ["text/xml"], tosAcceptedFormat: ["text/xml"],
}); });
const withdrawalFee = Amounts.sub( const withdrawalFee = Amounts.sub(
Amounts.parseOrThrow(info.withdrawalAmountRaw), Amounts.parseOrThrow(info.withdrawalAmountRaw),
Amounts.parseOrThrow(info.withdrawalAmountEffective), Amounts.parseOrThrow(info.withdrawalAmountEffective),
).amount; ).amount;
return { info, withdrawalFee }; return { info, withdrawalFee };
}, }, [thisExchange, amount]);
[],
[thisExchange, amount],
);
const [reviewing, setReviewing] = useState<boolean>(false); const [reviewing, setReviewing] = useState<boolean>(false);
const [reviewed, setReviewed] = useState<boolean>(false); const [reviewed, setReviewed] = useState<boolean>(false);

View File

@ -16,7 +16,7 @@
import { Amounts, Balance, NotificationType } from "@gnu-taler/taler-util"; import { Amounts, Balance, NotificationType } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { BalanceTable } from "../components/BalanceTable.js"; import { BalanceTable } from "../components/BalanceTable.js";
import { JustInDevMode } from "../components/JustInDevMode.js"; import { JustInDevMode } from "../components/JustInDevMode.js";
import { Loading } from "../components/Loading.js"; import { Loading } from "../components/Loading.js";
@ -24,7 +24,7 @@ import { LoadingError } from "../components/LoadingError.js";
import { MultiActionButton } from "../components/MultiActionButton.js"; import { MultiActionButton } from "../components/MultiActionButton.js";
import { ButtonBoxPrimary, ButtonPrimary } from "../components/styled/index.js"; import { ButtonBoxPrimary, ButtonPrimary } from "../components/styled/index.js";
import { useTranslationContext } from "../context/translation.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 { AddNewActionView } from "../wallet/AddNewActionView.js";
import * as wxApi from "../wxApi.js"; import * as wxApi from "../wxApi.js";
import { NoBalanceHelp } from "./NoBalanceHelp.js"; import { NoBalanceHelp } from "./NoBalanceHelp.js";
@ -41,9 +41,14 @@ export function BalancePage({
}: Props): VNode { }: Props): VNode {
const { i18n } = useTranslationContext(); const { i18n } = useTranslationContext();
const [addingAction, setAddingAction] = useState(false); const [addingAction, setAddingAction] = useState(false);
const state = useAsyncAsHook(wxApi.getBalance, [ const state = useAsyncAsHook2(wxApi.getBalance);
NotificationType.WithdrawGroupFinished,
]); useEffect(() => {
wxApi.onUpdateNotification([NotificationType.WithdrawGroupFinished], () => {
state?.retry();
});
});
const balances = !state || state.hasError ? [] : state.response.balances; const balances = !state || state.hasError ? [] : state.response.balances;
if (!state) { if (!state) {

View File

@ -41,7 +41,7 @@ import {
SmallText, SmallText,
} from "../components/styled/index.js"; } from "../components/styled/index.js";
import { useTranslationContext } from "../context/translation.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 { Pages } from "../NavigationBar.js";
import * as wxApi from "../wxApi.js"; import * as wxApi from "../wxApi.js";
@ -51,7 +51,7 @@ interface Props {
export function BackupPage({ onAddProvider }: Props): VNode { export function BackupPage({ onAddProvider }: Props): VNode {
const { i18n } = useTranslationContext(); const { i18n } = useTranslationContext();
const status = useAsyncAsHook(wxApi.getBackupInfo); const status = useAsyncAsHook2(wxApi.getBackupInfo);
if (!status) { if (!status) {
return <Loading />; return <Loading />;
} }

View File

@ -32,7 +32,7 @@ import {
WarningBox, WarningBox,
} from "../components/styled/index.js"; } from "../components/styled/index.js";
import { useTranslationContext } from "../context/translation.js"; import { useTranslationContext } from "../context/translation.js";
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { HookError, useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js";
import { import {
ButtonHandler, ButtonHandler,
SelectFieldHandler, SelectFieldHandler,
@ -98,7 +98,7 @@ export function useComponentState(
onSuccess: (currency: string) => void, onSuccess: (currency: string) => void,
api: typeof wxApi, api: typeof wxApi,
): State { ): State {
const hook = useAsyncAsHook(async () => { const hook = useAsyncAsHook2(async () => {
const { balances } = await api.getBalance(); const { balances } = await api.getBalance();
const { accounts } = await api.listKnownBankAccounts(currency); const { accounts } = await api.listKnownBankAccounts(currency);
const defaultSelectedAccount = const defaultSelectedAccount =
@ -117,10 +117,6 @@ export function useComponentState(
const [fee, setFee] = useState<DepositGroupFees | undefined>(undefined); const [fee, setFee] = useState<DepositGroupFees | undefined>(undefined);
// const hookResponse = !hook || hook.hasError ? undefined : hook.response;
// useEffect(() => {}, [hookResponse]);
if (!hook || hook.hasError) { if (!hook || hook.hasError) {
return { return {
status: "loading", status: "loading",

View File

@ -23,12 +23,12 @@ import {
import { PendingTaskInfo } from "@gnu-taler/taler-wallet-core"; import { PendingTaskInfo } from "@gnu-taler/taler-wallet-core";
import { format } from "date-fns"; import { format } from "date-fns";
import { Fragment, h, VNode } from "preact"; 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 { Diagnostics } from "../components/Diagnostics.js";
import { NotifyUpdateFadeOut } from "../components/styled/index.js"; import { NotifyUpdateFadeOut } from "../components/styled/index.js";
import { Time } from "../components/Time.js"; import { Time } from "../components/Time.js";
import { useTranslationContext } from "../context/translation.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 { useDiagnostics } from "../hooks/useDiagnostics.js";
import * as wxApi from "../wxApi.js"; import * as wxApi from "../wxApi.js";
@ -38,7 +38,7 @@ export function DeveloperPage(): VNode {
const listenAllEvents = Array.from<NotificationType>({ length: 1 }); const listenAllEvents = Array.from<NotificationType>({ length: 1 });
listenAllEvents.includes = () => true; // includes every event listenAllEvents.includes = () => true; // includes every event
const response = useAsyncAsHook(async () => { const response = useAsyncAsHook2(async () => {
const op = await wxApi.getPendingOperations(); const op = await wxApi.getPendingOperations();
const c = await wxApi.dumpCoins(); const c = await wxApi.dumpCoins();
const ex = await wxApi.listExchanges(); const ex = await wxApi.listExchanges();
@ -47,7 +47,13 @@ export function DeveloperPage(): VNode {
coins: c.coins, coins: c.coins,
exchanges: ex.exchanges, exchanges: ex.exchanges,
}; };
}, listenAllEvents); });
useEffect(() => {
wxApi.onUpdateNotification(listenAllEvents, () => {
response?.retry();
});
});
const nonResponse = { operations: [], coins: [], exchanges: [] }; const nonResponse = { operations: [], coins: [], exchanges: [] };
const { operations, coins, exchanges } = const { operations, coins, exchanges } =

View File

@ -8,7 +8,7 @@ import {
} from "../components/styled/index.js"; } from "../components/styled/index.js";
import { useTranslationContext } from "../context/translation.js"; import { useTranslationContext } from "../context/translation.js";
import { TermsOfServiceSection } from "../cta/TermsOfServiceSection.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 { buildTermsOfServiceState, TermsState } from "../utils/index.js";
import * as wxApi from "../wxApi.js"; import * as wxApi from "../wxApi.js";
@ -23,7 +23,7 @@ export function ExchangeAddConfirmPage({
onCancel, onCancel,
onConfirm, onConfirm,
}: Props): VNode { }: Props): VNode {
const detailsHook = useAsyncAsHook(async () => { const detailsHook = useAsyncAsHook2(async () => {
const tos = await wxApi.getExchangeTos(url, ["text/xml"]); const tos = await wxApi.getExchangeTos(url, ["text/xml"]);
const tosState = buildTermsOfServiceState(tos); const tosState = buildTermsOfServiceState(tos);

View File

@ -20,7 +20,7 @@ import {
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import { useAsyncAsHook2 } from "../hooks/useAsyncAsHook.js";
import { queryToSlashKeys } from "../utils/index.js"; import { queryToSlashKeys } from "../utils/index.js";
import * as wxApi from "../wxApi.js"; import * as wxApi from "../wxApi.js";
import { ExchangeAddConfirmPage } from "./ExchangeAddConfirm.js"; import { ExchangeAddConfirmPage } from "./ExchangeAddConfirm.js";
@ -36,7 +36,7 @@ export function ExchangeAddPage({ currency, onBack }: Props): VNode {
{ url: string; config: TalerConfigResponse } | undefined { url: string; config: TalerConfigResponse } | undefined
>(undefined); >(undefined);
const knownExchangesResponse = useAsyncAsHook(wxApi.listExchanges); const knownExchangesResponse = useAsyncAsHook2(wxApi.listExchanges);
const knownExchanges = !knownExchangesResponse const knownExchanges = !knownExchangesResponse
? [] ? []
: knownExchangesResponse.hasError : knownExchangesResponse.hasError

View File

@ -21,7 +21,7 @@ import {
Transaction, Transaction,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { Loading } from "../components/Loading.js"; import { Loading } from "../components/Loading.js";
import { LoadingError } from "../components/LoadingError.js"; import { LoadingError } from "../components/LoadingError.js";
import { import {
@ -35,7 +35,7 @@ import {
import { Time } from "../components/Time.js"; import { Time } from "../components/Time.js";
import { TransactionItem } from "../components/TransactionItem.js"; import { TransactionItem } from "../components/TransactionItem.js";
import { useTranslationContext } from "../context/translation.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 { NoBalanceHelp } from "../popup/NoBalanceHelp.js";
import * as wxApi from "../wxApi.js"; import * as wxApi from "../wxApi.js";
@ -50,13 +50,16 @@ export function HistoryPage({
goToWalletDeposit, goToWalletDeposit,
}: Props): VNode { }: Props): VNode {
const { i18n } = useTranslationContext(); const { i18n } = useTranslationContext();
const state = useAsyncAsHook( const state = useAsyncAsHook2(async () => ({
async () => ({ b: await wxApi.getBalance(),
b: await wxApi.getBalance(), tx: await wxApi.getTransactions(),
tx: await wxApi.getTransactions(), }));
}),
[NotificationType.WithdrawGroupFinished], useEffect(() => {
); wxApi.onUpdateNotification([NotificationType.WithdrawGroupFinished], () => {
state?.retry();
});
});
if (!state) { if (!state) {
return <Loading />; return <Loading />;

View File

@ -23,11 +23,11 @@ import {
PaytoUri, PaytoUri,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
import { useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { Loading } from "../components/Loading.js"; import { Loading } from "../components/Loading.js";
import { LoadingError } from "../components/LoadingError.js"; import { LoadingError } from "../components/LoadingError.js";
import { useTranslationContext } from "../context/translation.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 * as wxApi from "../wxApi.js";
import { CreateManualWithdraw } from "./CreateManualWithdraw.js"; import { CreateManualWithdraw } from "./CreateManualWithdraw.js";
import { ReserveCreated } from "./ReserveCreated.js"; import { ReserveCreated } from "./ReserveCreated.js";
@ -50,9 +50,12 @@ export function ManualWithdrawPage({ currency, onCancel }: Props): VNode {
>(undefined); >(undefined);
const [error, setError] = useState<string | undefined>(undefined); const [error, setError] = useState<string | undefined>(undefined);
const state = useAsyncAsHook(wxApi.listExchanges, [ const state = useAsyncAsHook2(wxApi.listExchanges);
NotificationType.ExchangeAdded, useEffect(() => {
]); wxApi.onUpdateNotification([NotificationType.ExchangeAdded], () => {
state?.retry();
});
});
const { i18n } = useTranslationContext(); const { i18n } = useTranslationContext();
async function doCreate( async function doCreate(

View File

@ -34,7 +34,7 @@ import {
} from "../components/styled/index.js"; } from "../components/styled/index.js";
import { Time } from "../components/Time.js"; import { Time } from "../components/Time.js";
import { useTranslationContext } from "../context/translation.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"; import * as wxApi from "../wxApi.js";
interface Props { interface Props {
@ -54,7 +54,7 @@ export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode {
return providers.length ? providers[0] : null; return providers.length ? providers[0] : null;
} }
const state = useAsyncAsHook(getProviderInfo); const state = useAsyncAsHook2(getProviderInfo);
if (!state) { if (!state) {
return <Loading />; return <Loading />;

View File

@ -29,7 +29,7 @@ import {
} from "../components/styled/index.js"; } from "../components/styled/index.js";
import { useDevContext } from "../context/devContext.js"; import { useDevContext } from "../context/devContext.js";
import { useTranslationContext } from "../context/translation.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 { useBackupDeviceName } from "../hooks/useBackupDeviceName.js";
import { useExtendedPermissions } from "../hooks/useExtendedPermissions.js"; import { useExtendedPermissions } from "../hooks/useExtendedPermissions.js";
import { Pages } from "../NavigationBar.js"; import { Pages } from "../NavigationBar.js";
@ -40,13 +40,11 @@ export function SettingsPage(): VNode {
const [permissionsEnabled, togglePermissions] = useExtendedPermissions(); const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
const { devMode, toggleDevMode } = useDevContext(); const { devMode, toggleDevMode } = useDevContext();
const { name, update } = useBackupDeviceName(); const { name, update } = useBackupDeviceName();
// const [lang, changeLang] = useLang();
const exchangesHook = useAsyncAsHook(wxApi.listExchanges); const exchangesHook = useAsyncAsHook2(wxApi.listExchanges);
return ( return (
<SettingsView <SettingsView
// lang={lang}
// changeLang={changeLang}
knownExchanges={ knownExchanges={
!exchangesHook || exchangesHook.hasError !exchangesHook || exchangesHook.hasError
? [] ? []
@ -63,8 +61,6 @@ export function SettingsPage(): VNode {
} }
export interface ViewProps { export interface ViewProps {
// lang: string;
// changeLang: (s: string) => void;
deviceName: string; deviceName: string;
setDeviceName: (s: string) => Promise<void>; setDeviceName: (s: string) => Promise<void>;
permissionsEnabled: boolean; permissionsEnabled: boolean;

View File

@ -16,7 +16,6 @@
import { import {
AbsoluteTime, AbsoluteTime,
AmountLike,
Amounts, Amounts,
NotificationType, NotificationType,
parsePaytoUri, parsePaytoUri,
@ -26,7 +25,7 @@ import {
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { differenceInSeconds } from "date-fns"; import { differenceInSeconds } from "date-fns";
import { ComponentChildren, Fragment, h, VNode } from "preact"; 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 emptyImg from "../../static/img/empty.png";
import { Amount } from "../components/Amount.js"; import { Amount } from "../components/Amount.js";
import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType.js"; import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType.js";
@ -49,28 +48,34 @@ import {
} from "../components/styled/index.js"; } from "../components/styled/index.js";
import { Time } from "../components/Time.js"; import { Time } from "../components/Time.js";
import { useTranslationContext } from "../context/translation.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"; import * as wxApi from "../wxApi.js";
interface Props { interface Props {
tid: string; tid: string;
goToWalletHistory: (currency?: string) => void; 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 { export function TransactionPage({ tid, goToWalletHistory }: Props): VNode {
const { i18n } = useTranslationContext(); 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, [ const state = useAsyncAsHook2(() => getTransaction(tid));
NotificationType.WithdrawGroupFinished,
]); useEffect(() => {
wxApi.onUpdateNotification([NotificationType.WithdrawGroupFinished], () => {
state?.retry();
});
});
if (!state) { if (!state) {
return <Loading />; return <Loading />;