gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 04/04: show deposit transaction info


From: gnunet
Subject: [taler-wallet-core] 04/04: show deposit transaction info
Date: Sun, 15 Jan 2023 21:50:15 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

commit bd57fa46a44db8e8c685b40f66eaa7998e71efa5
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Sun Jan 15 17:49:57 2023 -0300

    show deposit transaction info
---
 .../src/wallet/DepositPage/state.ts                | 222 ++++++++++-----------
 .../src/wallet/DepositPage/test.ts                 |  23 ++-
 .../src/wallet/Transaction.tsx                     |  52 +++--
 3 files changed, 164 insertions(+), 133 deletions(-)

diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts 
b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
index 1b628047a..d7d9f2da7 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
@@ -29,13 +29,14 @@ import { alertFromError, useAlertContext } from 
"../../context/alert.js";
 import { useBackendContext } from "../../context/backend.js";
 import { useTranslationContext } from "../../context/translation.js";
 import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
+import { RecursiveState } from "../../utils/index.js";
 import { Props, State } from "./index.js";
 
 export function useComponentState({
   amount: amountStr,
   onCancel,
   onSuccess,
-}: Props): State {
+}: Props): RecursiveState<State> {
   const api = useBackendContext();
   const { i18n } = useTranslationContext();
   const { pushAlertOnError } = useAlertContext();
@@ -49,9 +50,7 @@ export function useComponentState({
     );
     const { accounts } = await api.wallet.call(
       WalletApiOperation.ListKnownBankAccounts,
-      {
-        currency,
-      },
+      { currency },
     );
 
     return { accounts, balances };
@@ -61,13 +60,11 @@ export function useComponentState({
     parsed !== undefined
       ? parsed
       : currency !== undefined
-      ? Amounts.zeroOfCurrency(currency)
-      : undefined;
+        ? Amounts.zeroOfCurrency(currency)
+        : undefined;
   // const [accountIdx, setAccountIdx] = useState<number>(0);
-  const [amount, setAmount] = useState<AmountJson>(initialValue ?? ({} as 
any));
   const [selectedAccount, setSelectedAccount] = useState<PaytoUri>();
 
-  const [fee, setFee] = useState<DepositGroupFees | undefined>(undefined);
   const [addingAccount, setAddingAccount] = useState(false);
 
   if (!currency) {
@@ -91,7 +88,12 @@ export function useComponentState({
   }
   const { accounts, balances } = hook.response;
 
-  // const parsedAmount = Amounts.parse(`${currency}:${amount}`);
+  async function updateAccountFromList(accountStr: string): Promise<void> {
+    const uri = !accountStr ? undefined : parsePaytoUri(accountStr);
+    if (uri) {
+      setSelectedAccount(uri);
+    }
+  }
 
   if (addingAccount) {
     return {
@@ -139,128 +141,110 @@ export function useComponentState({
   const firstAccount = accounts[0].uri;
   const currentAccount = !selectedAccount ? firstAccount : selectedAccount;
 
-  if (fee === undefined) {
-    getFeeForAmount(currentAccount, amount, api.wallet).then((initialFee) => {
-      setFee(initialFee);
-    });
-    return {
-      status: "loading",
-      error: undefined,
-    };
-  }
+  return () => {
+    // eslint-disable-next-line react-hooks/rules-of-hooks
+    const [amount, setAmount] = useState<AmountJson>(
+      initialValue ?? ({} as any),
+    );
+    const amountStr = Amounts.stringify(amount);
+    const depositPaytoUri = 
`payto://${currentAccount.targetType}/${currentAccount.targetPath}`;
 
-  const accountMap = createLabelsForBankAccount(accounts);
+    // eslint-disable-next-line react-hooks/rules-of-hooks
+    const hook = useAsyncAsHook(async () => {
+      const fee = await api.wallet.call(WalletApiOperation.GetFeeForDeposit, {
+        amount: amountStr,
+        depositPaytoUri,
+      });
 
-  async function updateAccountFromList(accountStr: string): Promise<void> {
-    const uri = !accountStr ? undefined : parsePaytoUri(accountStr);
-    if (uri) {
-      try {
-        const result = await getFeeForAmount(uri, amount, api.wallet);
-        setSelectedAccount(uri);
-        setFee(result);
-      } catch (e) {
-        setSelectedAccount(uri);
-        setFee(undefined);
-      }
-    }
-  }
+      return { fee };
+    }, [amountStr, depositPaytoUri]);
 
-  async function updateAmount(newAmount: AmountJson): Promise<void> {
-    // const parsed = Amounts.parse(`${currency}:${numStr}`);
-    try {
-      const result = await getFeeForAmount(
-        currentAccount,
-        newAmount,
-        api.wallet,
-      );
-      setAmount(newAmount);
-      setFee(result);
-    } catch (e) {
-      setAmount(newAmount);
-      setFee(undefined);
+    if (!hook) {
+      return {
+        status: "loading",
+        error: undefined,
+      };
+    }
+    if (hook.hasError) {
+      return {
+        status: "error",
+        error: alertFromError(
+          i18n.str`Could not load fee for amount ${amountStr}`,
+          hook,
+        ),
+      };
     }
-  }
 
-  const totalFee =
-    fee !== undefined
-      ? Amounts.sum([fee.wire, fee.coin, fee.refresh]).amount
-      : Amounts.zeroOfCurrency(currency);
+    const { fee } = hook.response;
 
-  const totalToDeposit =
-    fee !== undefined
-      ? Amounts.sub(amount, totalFee).amount
-      : Amounts.zeroOfCurrency(currency);
+    const accountMap = createLabelsForBankAccount(accounts);
 
-  const isDirty = amount !== initialValue;
-  const amountError = !isDirty
-    ? undefined
-    : Amounts.cmp(balance, amount) === -1
-    ? `Too much, your current balance is ${Amounts.stringifyValue(balance)}`
-    : undefined;
+    const totalFee =
+      fee !== undefined
+        ? Amounts.sum([fee.wire, fee.coin, fee.refresh]).amount
+        : Amounts.zeroOfCurrency(currency);
 
-  const unableToDeposit =
-    Amounts.isZero(totalToDeposit) || //deposit may be zero because of fee
-    fee === undefined || //no fee calculated yet
-    amountError !== undefined; //amount field may be invalid
+    const totalToDeposit =
+      fee !== undefined
+        ? Amounts.sub(amount, totalFee).amount
+        : Amounts.zeroOfCurrency(currency);
 
-  async function doSend(): Promise<void> {
-    if (!currency) return;
+    const isDirty = amount !== initialValue;
+    const amountError = !isDirty
+      ? undefined
+      : Amounts.cmp(balance, amount) === -1
+        ? `Too much, your current balance is 
${Amounts.stringifyValue(balance)}`
+        : undefined;
 
-    const depositPaytoUri = stringifyPaytoUri(currentAccount);
-    const amountStr = Amounts.stringify(amount);
-    await api.wallet.call(WalletApiOperation.CreateDepositGroup, {
-      amount: amountStr,
-      depositPaytoUri,
-    });
-    onSuccess(currency);
-  }
+    const unableToDeposit =
+      Amounts.isZero(totalToDeposit) || //deposit may be zero because of fee
+      fee === undefined || //no fee calculated yet
+      amountError !== undefined; //amount field may be invalid
 
-  return {
-    status: "ready",
-    error: undefined,
-    currency,
-    amount: {
-      value: amount,
-      onInput: pushAlertOnError(updateAmount),
-      error: amountError,
-    },
-    onAddAccount: {
-      onClick: pushAlertOnError(async () => {
-        setAddingAccount(true);
-      }),
-    },
-    account: {
-      list: accountMap,
-      value: stringifyPaytoUri(currentAccount),
-      onChange: pushAlertOnError(updateAccountFromList),
-    },
-    currentAccount,
-    cancelHandler: {
-      onClick: pushAlertOnError(async () => {
-        onCancel(currency);
-      }),
-    },
-    depositHandler: {
-      onClick: unableToDeposit ? undefined : pushAlertOnError(doSend),
-    },
-    totalFee,
-    totalToDeposit,
-    // currentAccount,
-    // parsedAmount,
-  };
-}
+    async function doSend(): Promise<void> {
+      if (!currency) return;
 
-async function getFeeForAmount(
-  p: PaytoUri,
-  a: AmountJson,
-  wallet: ReturnType<typeof useBackendContext>["wallet"],
-): Promise<DepositGroupFees> {
-  const depositPaytoUri = `payto://${p.targetType}/${p.targetPath}`;
-  const amount = Amounts.stringify(a);
-  return await wallet.call(WalletApiOperation.GetFeeForDeposit, {
-    amount,
-    depositPaytoUri,
-  });
+      const depositPaytoUri = stringifyPaytoUri(currentAccount);
+      const amountStr = Amounts.stringify(amount);
+      await api.wallet.call(WalletApiOperation.CreateDepositGroup, {
+        amount: amountStr,
+        depositPaytoUri,
+      });
+      onSuccess(currency);
+    }
+
+    return {
+      status: "ready",
+      error: undefined,
+      currency,
+      amount: {
+        value: amount,
+        onInput: pushAlertOnError(async (a) => setAmount(a)),
+        error: amountError,
+      },
+      onAddAccount: {
+        onClick: pushAlertOnError(async () => {
+          setAddingAccount(true);
+        }),
+      },
+      account: {
+        list: accountMap,
+        value: stringifyPaytoUri(currentAccount),
+        onChange: pushAlertOnError(updateAccountFromList),
+      },
+      currentAccount,
+      cancelHandler: {
+        onClick: pushAlertOnError(async () => {
+          onCancel(currency);
+        }),
+      },
+      depositHandler: {
+        onClick: unableToDeposit ? undefined : pushAlertOnError(doSend),
+      },
+      totalFee,
+      totalToDeposit,
+    };
+  };
 }
 
 export function labelForAccountType(id: string): string {
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts 
b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
index 42b76cf50..bfd69f945 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
@@ -264,6 +264,15 @@ describe("DepositPage states", () => {
           
expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`));
           expect(state.depositHandler.onClick).undefined;
         },
+        (state) => {
+          if (state.status !== "ready") expect.fail();
+          expect(state.cancelHandler.onClick).not.undefined;
+          expect(state.currency).eq(currency);
+          expect(state.account.value).eq(accountSelected);
+          expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:0"));
+          
expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`));
+          expect(state.depositHandler.onClick).undefined;
+        },
       ],
       TestingContext,
     );
@@ -341,7 +350,7 @@ describe("DepositPage states", () => {
           expect(state.account.value).eq(accountSelected);
           expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:0"));
           expect(state.depositHandler.onClick).undefined;
-          
expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`));
+          
expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`));
 
           expect(state.amount.onInput).not.undefined;
           if (!state.amount.onInput) return;
@@ -359,6 +368,18 @@ describe("DepositPage states", () => {
           );
           expect(state.depositHandler.onClick).not.undefined;
         },
+        (state) => {
+          if (state.status !== "ready") expect.fail();
+          expect(state.cancelHandler.onClick).not.undefined;
+          expect(state.currency).eq(currency);
+          expect(state.account.value).eq(accountSelected);
+          expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:10"));
+          
expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`));
+          expect(state.totalToDeposit).deep.eq(
+            Amounts.parseOrThrow(`${currency}:7`),
+          );
+          expect(state.depositHandler.onClick).not.undefined;
+        },
       ],
       TestingContext,
     );
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx 
b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
index 5ed05f87f..cc3a65f2d 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
@@ -38,7 +38,7 @@ import {
 } from "@gnu-taler/taler-util";
 import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
 import { styled } from "@linaria/react";
-import { differenceInSeconds } from "date-fns";
+import { differenceInSeconds, isAfter, isFuture, isPast } from "date-fns";
 import { ComponentChildren, Fragment, h, VNode } from "preact";
 import { useEffect, useState } from "preact/hooks";
 import emptyImg from "../../static/img/empty.png";
@@ -641,6 +641,11 @@ export function TransactionView({
   if (transaction.type === TransactionType.Deposit) {
     const total = Amounts.parseOrThrow(transaction.amountRaw);
     const payto = parsePaytoUri(transaction.targetPaytoUri);
+
+    const wireTime = AbsoluteTime.fromTimestamp(
+      transaction.wireTransferDeadline,
+    );
+    const shouldBeWired = wireTime.t_ms !== "never" && isPast(wireTime.t_ms);
     return (
       <TransactionTemplate
         transaction={transaction}
@@ -663,18 +668,39 @@ export function TransactionView({
           text={<DepositDetails transaction={transaction} />}
           kind="neutral"
         />
-        <Part
-          title={i18n.str`Wire transfer deadline`}
-          text={
-            <Time
-              timestamp={AbsoluteTime.fromTimestamp(
-                transaction.wireTransferDeadline,
-              )}
-              format="dd MMMM yyyy 'at' HH:mm"
-            />
-          }
-          kind="neutral"
-        />
+        {!shouldBeWired ? (
+          <Part
+            title={i18n.str`Wire transfer deadline`}
+            text={
+              <Time timestamp={wireTime} format="dd MMMM yyyy 'at' HH:mm" />
+            }
+            kind="neutral"
+          />
+        ) : transaction.wireTransferProgress === 0 ? (
+          <AlertView
+            alert={{
+              type: "warning",
+              message: i18n.str`Wire transfer is not initiated`,
+              description: i18n.str` `,
+            }}
+          />
+        ) : transaction.wireTransferProgress === 100 ? (
+          <AlertView
+            alert={{
+              type: "success",
+              message: i18n.str`Wire transfer completed`,
+              description: i18n.str` `,
+            }}
+          />
+        ) : (
+          <AlertView
+            alert={{
+              type: "info",
+              message: i18n.str`Wire transfer in progress`,
+              description: i18n.str` `,
+            }}
+          />
+        )}
       </TransactionTemplate>
     );
   }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]