From 9b04d8bf3581d162cbd631892ca115df811c46f8 Mon Sep 17 00:00:00 2001
From: Sebastian
Date: Mon, 9 Jan 2023 08:38:48 -0300
Subject: [PATCH] fix #7152
---
.../taler-wallet-webextension/package.json | 2 +-
.../src/components/AmountField.stories.tsx | 2 +-
.../src/components/AmountField.tsx | 3 +-
.../src/components/BankDetailsByPaytoType.tsx | 35 ++----
.../src/components/Banner.tsx | 3 +-
.../src/components/Checkbox.tsx | 5 +-
.../src/components/CurrentAlerts.tsx | 108 ++++++++++++++++
.../src/components/ErrorMessage.tsx | 3 +-
.../src/components/ErrorTalerOperation.tsx | 4 +-
.../src/components/Loading.tsx | 96 +++++++++++---
.../src/components/LoadingError.tsx | 30 -----
.../src/components/MultiActionButton.tsx | 4 +-
.../src/components/Part.tsx | 10 +-
.../src/components/PaymentButtons.tsx | 13 +-
.../src/components/PendingTransactions.tsx | 2 +-
.../src/components/SelectList.tsx | 3 +-
.../ShowFullContractTermPopup.stories.tsx | 5 +-
.../components/ShowFullContractTermPopup.tsx | 16 +--
.../src/components/TermsOfService/index.ts | 22 ++--
.../src/components/TermsOfService/state.ts | 36 ++----
.../src/components/TermsOfService/views.tsx | 34 +----
.../src/components/styled/index.tsx | 2 +-
.../src/context/alert.ts | 118 +++++++++++++++++
.../src/cta/Deposit/index.ts | 11 +-
.../src/cta/Deposit/state.ts | 10 +-
.../src/cta/Deposit/test.ts | 8 +-
.../src/cta/Deposit/views.tsx | 18 +--
.../src/cta/InvoiceCreate/index.ts | 14 +--
.../src/cta/InvoiceCreate/state.ts | 37 ++++--
.../src/cta/InvoiceCreate/views.tsx | 44 +------
.../src/cta/InvoicePay/index.ts | 11 +-
.../src/cta/InvoicePay/state.ts | 16 ++-
.../src/cta/InvoicePay/views.tsx | 37 +-----
.../src/cta/Payment/index.ts | 11 +-
.../src/cta/Payment/state.ts | 16 ++-
.../src/cta/Payment/test.ts | 6 +-
.../src/cta/Payment/views.tsx | 34 ++---
.../src/cta/Recovery/index.ts | 11 +-
.../src/cta/Recovery/state.ts | 23 ++--
.../src/cta/Recovery/views.tsx | 16 ---
.../src/cta/Refund/index.ts | 16 +--
.../src/cta/Refund/state.ts | 16 ++-
.../src/cta/Refund/test.ts | 8 +-
.../src/cta/Refund/views.tsx | 29 +----
.../src/cta/Tip/index.ts | 16 +--
.../src/cta/Tip/state.ts | 16 ++-
.../src/cta/Tip/test.ts | 9 +-
.../src/cta/Tip/views.tsx | 28 +----
.../src/cta/TransferCreate/index.ts | 11 +-
.../src/cta/TransferCreate/state.ts | 16 ++-
.../src/cta/TransferCreate/views.tsx | 32 +----
.../src/cta/TransferPickup/index.ts | 11 +-
.../src/cta/TransferPickup/state.ts | 16 ++-
.../src/cta/TransferPickup/views.tsx | 35 +-----
.../src/cta/Withdraw/index.ts | 16 +--
.../src/cta/Withdraw/state.ts | 26 +++-
.../src/cta/Withdraw/test.ts | 8 +-
.../src/cta/Withdraw/views.tsx | 53 +-------
.../src/hooks/useAsyncAsHook.ts | 18 ++-
.../src/hooks/useLang.ts | 1 +
.../src/hooks/useLocalStorage.ts | 5 +-
.../src/mui/Alert.stories.tsx | 33 +++--
.../src/mui/Alert.tsx | 10 +-
.../src/mui/Paper.tsx | 3 -
.../src/mui/colors/manipulation.ts | 2 +-
.../src/platform/api.ts | 8 +-
.../src/platform/chrome.ts | 60 +++++----
.../src/platform/firefox.ts | 7 +-
.../src/popup/BalancePage.tsx | 24 ++--
.../src/popup/NoBalanceHelp.tsx | 2 +-
.../src/svg/progress.svg | 12 ++
.../src/test-utils.ts | 5 +-
.../src/wallet/AddBackupProvider/index.ts | 15 +--
.../src/wallet/AddBackupProvider/views.tsx | 16 +--
.../src/wallet/Application.tsx | 45 +++++--
.../src/wallet/BackupPage.tsx | 19 +--
.../src/wallet/DepositPage/index.ts | 10 +-
.../src/wallet/DepositPage/state.ts | 7 +-
.../src/wallet/DepositPage/views.tsx | 43 ++-----
.../src/wallet/DestinationSelection/index.ts | 11 +-
.../src/wallet/DestinationSelection/state.ts | 8 +-
.../src/wallet/DestinationSelection/views.tsx | 29 ++---
.../src/wallet/EmptyComponentExample/index.ts | 11 +-
.../wallet/EmptyComponentExample/views.tsx | 12 --
.../src/wallet/ExchangeSelection/index.ts | 9 +-
.../src/wallet/ExchangeSelection/state.ts | 10 +-
.../src/wallet/ExchangeSelection/views.tsx | 24 +---
.../src/wallet/ExchangeSetUrl.tsx | 6 +-
.../src/wallet/History.tsx | 15 ++-
.../src/wallet/ManageAccount/index.ts | 11 +-
.../src/wallet/ManageAccount/state.ts | 7 +-
.../src/wallet/ManageAccount/views.tsx | 21 +---
.../src/wallet/Notifications/index.ts | 11 +-
.../src/wallet/Notifications/state.ts | 11 +-
.../src/wallet/Notifications/views.tsx | 12 --
.../src/wallet/ProviderAddPage.tsx | 10 +-
.../src/wallet/ProviderDetailPage.tsx | 45 ++-----
.../src/wallet/ReserveCreated.tsx | 4 +-
.../src/wallet/Settings.tsx | 32 ++---
.../src/wallet/Transaction.tsx | 119 +++++++++---------
.../src/wallet/Welcome.tsx | 6 +-
.../taler-wallet-webextension/src/wxApi.ts | 44 +++++--
.../src/wxBackend.ts | 31 +++--
pnpm-lock.yaml | 21 ++--
104 files changed, 1076 insertions(+), 1030 deletions(-)
create mode 100644 packages/taler-wallet-webextension/src/components/CurrentAlerts.tsx
delete mode 100644 packages/taler-wallet-webextension/src/components/LoadingError.tsx
create mode 100644 packages/taler-wallet-webextension/src/context/alert.ts
create mode 100644 packages/taler-wallet-webextension/src/svg/progress.svg
diff --git a/packages/taler-wallet-webextension/package.json b/packages/taler-wallet-webextension/package.json
index 8a6c19406..87fb27a72 100644
--- a/packages/taler-wallet-webextension/package.json
+++ b/packages/taler-wallet-webextension/package.json
@@ -69,7 +69,7 @@
"preact-cli": "^3.3.5",
"preact-render-to-string": "^5.1.19",
"rimraf": "^3.0.2",
- "typescript": "^4.8.4"
+ "typescript": "4.9.4"
},
"nyc": {
"include": [
diff --git a/packages/taler-wallet-webextension/src/components/AmountField.stories.tsx b/packages/taler-wallet-webextension/src/components/AmountField.stories.tsx
index 9a1d96014..61c4a7661 100644
--- a/packages/taler-wallet-webextension/src/components/AmountField.stories.tsx
+++ b/packages/taler-wallet-webextension/src/components/AmountField.stories.tsx
@@ -49,7 +49,7 @@ function RenderAmount(): VNode {
Amount}
+ label={i18n.str`Amount`}
highestDenom={2000000}
lowestDenom={0.01}
handler={handler}
diff --git a/packages/taler-wallet-webextension/src/components/AmountField.tsx b/packages/taler-wallet-webextension/src/components/AmountField.tsx
index 2e8942f0d..4936e0604 100644
--- a/packages/taler-wallet-webextension/src/components/AmountField.tsx
+++ b/packages/taler-wallet-webextension/src/components/AmountField.tsx
@@ -21,6 +21,7 @@ import {
amountMaxValue,
Amounts,
Result,
+ TranslatedString,
} from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
@@ -37,7 +38,7 @@ export function AmountField({
highestDenom = 1,
required,
}: {
- label: VNode;
+ label: TranslatedString;
lowestDenom?: number;
highestDenom?: number;
required?: boolean;
diff --git a/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx b/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx
index 6f4980aff..d233547a4 100644
--- a/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx
+++ b/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx
@@ -19,6 +19,7 @@ import {
Amounts,
PaytoUri,
segwitMinAmount,
+ TranslatedString,
} from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { useEffect, useRef, useState } from "preact/hooks";
@@ -106,27 +107,18 @@ export function BankDetailsByPaytoType({
}
const accountPart = !payto.isKnown ? (
- Account}
- value={payto.targetPath}
- />
+
) : payto.targetType === "x-taler-bank" ? (
- Bank host}
- value={payto.host}
- />
- Bank account}
- value={payto.account}
- />
+
+
) : payto.targetType === "iban" ? (
{payto.bic !== undefined ? (
- BIC} value={payto.bic} />
+
) : undefined}
- IBAN} value={payto.iban} />
+
) : undefined;
@@ -146,19 +138,12 @@ export function BankDetailsByPaytoType({
{accountPart}
Amount}
+ name={i18n.str`Amount`}
value={ }
/>
- Subject}
- value={subject}
- literal
- />
+
{receiver ? (
- Receiver name}
- value={receiver}
- />
+
) : undefined}
@@ -200,7 +185,7 @@ function Row({
value,
literal,
}: {
- name: VNode;
+ name: TranslatedString;
value: string | VNode;
literal?: boolean;
}): VNode {
diff --git a/packages/taler-wallet-webextension/src/components/Banner.tsx b/packages/taler-wallet-webextension/src/components/Banner.tsx
index a91fd384f..40a4847b8 100644
--- a/packages/taler-wallet-webextension/src/components/Banner.tsx
+++ b/packages/taler-wallet-webextension/src/components/Banner.tsx
@@ -13,6 +13,7 @@
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
+import { TranslatedString } from "@gnu-taler/taler-util";
import { ComponentChildren, Fragment, h, JSX, VNode } from "preact";
import { Button } from "../mui/Button.js";
import { Divider } from "../mui/Divider.js";
@@ -20,7 +21,7 @@ import { Grid } from "../mui/Grid.js";
import { Paper } from "../mui/Paper.js";
interface Props extends JSX.HTMLAttributes {
- titleHead?: VNode;
+ titleHead?: VNode | TranslatedString;
children: ComponentChildren;
// elements: {
// icon?: VNode;
diff --git a/packages/taler-wallet-webextension/src/components/Checkbox.tsx b/packages/taler-wallet-webextension/src/components/Checkbox.tsx
index b6fa8b663..70dfab597 100644
--- a/packages/taler-wallet-webextension/src/components/Checkbox.tsx
+++ b/packages/taler-wallet-webextension/src/components/Checkbox.tsx
@@ -14,14 +14,15 @@
GNU Taler; see the file COPYING. If not, see
*/
+import { TranslatedString } from "@gnu-taler/taler-util";
import { h, VNode } from "preact";
interface Props {
enabled?: boolean;
onToggle?: () => Promise;
- label: VNode;
+ label: TranslatedString;
name: string;
- description?: VNode;
+ description?: VNode | TranslatedString;
}
export function Checkbox({
name,
diff --git a/packages/taler-wallet-webextension/src/components/CurrentAlerts.tsx b/packages/taler-wallet-webextension/src/components/CurrentAlerts.tsx
new file mode 100644
index 000000000..a56c82dee
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/components/CurrentAlerts.tsx
@@ -0,0 +1,108 @@
+/*
+ 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 { ComponentChildren, Fragment, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { useTranslationContext } from "../../../web-util/src/index.browser.js";
+import {
+ ErrorAlert,
+ Alert as AlertNotification,
+ useAlertContext,
+} from "../context/alert.js";
+import { Alert } from "../mui/Alert.js";
+
+/**
+ *
+ * @author sebasjm
+ */
+
+function AlertContext({
+ context,
+ cause,
+}: {
+ cause: unknown;
+ context: undefined | object;
+}): VNode {
+ const [more, setMore] = useState(false);
+ const { i18n } = useTranslationContext();
+ if (!more) {
+ return (
+
+ );
+ }
+ return (
+
+ {JSON.stringify(
+ context === undefined ? { cause } : { context, cause },
+ undefined,
+ 2,
+ )}
+
+ );
+}
+
+export function ErrorAlertView({
+ error: alert,
+ onClose,
+}: {
+ error: ErrorAlert;
+ onClose?: () => Promise;
+}): VNode {
+ return (
+
+
+
{alert.description}
+
+
+
+ );
+}
+
+export function AlertView({
+ alert,
+ onClose,
+}: {
+ alert: AlertNotification;
+ onClose?: () => Promise;
+}): VNode {
+ return (
+
+
+
+ );
+}
+
+export function CurrentAlerts(): VNode {
+ const { alerts, removeAlert } = useAlertContext();
+ if (alerts.length === 0) return ;
+ return (
+
+ {alerts.map((n, i) => (
+ removeAlert(n)} />
+ ))}
+
+ );
+}
+
+function Wrapper({ children }: { children: ComponentChildren }): VNode {
+ return {children}
;
+}
diff --git a/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx b/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx
index ce8dc0ad1..11f526865 100644
--- a/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx
+++ b/packages/taler-wallet-webextension/src/components/ErrorMessage.tsx
@@ -13,6 +13,7 @@
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
+import { TranslatedString } from "@gnu-taler/taler-util";
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
import arrowDown from "../svg/chevron-down.svg";
@@ -22,7 +23,7 @@ export function ErrorMessage({
title,
description,
}: {
- title: VNode;
+ title: TranslatedString;
description?: string | VNode;
}): VNode | null {
const [showErrorDetail, setShowErrorDetail] = useState(false);
diff --git a/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx b/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx
index a7223d2db..f8203f38a 100644
--- a/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx
+++ b/packages/taler-wallet-webextension/src/components/ErrorTalerOperation.tsx
@@ -13,7 +13,7 @@
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
-import { TalerErrorDetail } from "@gnu-taler/taler-util";
+import { TalerErrorDetail, TranslatedString } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
import arrowDown from "../svg/chevron-down.svg";
@@ -24,7 +24,7 @@ export function ErrorTalerOperation({
title,
error,
}: {
- title?: VNode;
+ title?: TranslatedString;
error?: TalerErrorDetail;
}): VNode | null {
const { devMode } = useDevContext();
diff --git a/packages/taler-wallet-webextension/src/components/Loading.tsx b/packages/taler-wallet-webextension/src/components/Loading.tsx
index f2195b646..3a6daaaa6 100644
--- a/packages/taler-wallet-webextension/src/components/Loading.tsx
+++ b/packages/taler-wallet-webextension/src/components/Loading.tsx
@@ -13,30 +13,88 @@
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
+import { css } from "@linaria/core";
import { Fragment, h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks";
import { useTranslationContext } from "../context/translation.js";
+import ProgressIcon from "../svg/progress.svg";
import { CenteredText } from "./styled/index.js";
+const fadeIn = css`
+ & {
+ animation: fadein 3s;
+ }
+ @keyframes fadein {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+ }
+`;
+
export function Loading(): VNode {
const { i18n } = useTranslationContext();
- const [tooLong, setTooLong] = useState(false);
- useEffect(() => {
- const id = setTimeout(() => {
- setTooLong(true);
- }, 500);
- return () => {
- clearTimeout(id);
- };
- });
- if (tooLong) {
- return (
-
- );
- }
- return ;
+ return (
+
+
+ Loading ...
+
+ {/* */}
+
+
+ );
}
+
+const ripple = css`
+ & {
+ display: inline-block;
+ position: relative;
+ width: var(--size);
+ height: var(--size);
+ }
+ & div {
+ position: absolute;
+ border: 4px solid black;
+ opacity: 1;
+ border-radius: 50%;
+ animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite;
+ }
+ & div:nth-child(2) {
+ animation-delay: -0.3s;
+ }
+ @keyframes lds-ripple {
+ 0% {
+ top: calc(var(--size) / 2);
+ left: calc(var(--size) / 2);
+ width: 0;
+ height: 0;
+ opacity: 0;
+ }
+ 14.9% {
+ top: calc(var(--size) / 2);
+ left: calc(var(--size) / 2);
+ width: 0;
+ height: 0;
+ opacity: 0;
+ }
+ 15% {
+ top: calc(var(--size) / 2);
+ left: calc(var(--size) / 2);
+ width: 0;
+ height: 0;
+ opacity: 1;
+ }
+ 100% {
+ top: 0px;
+ left: 0px;
+ width: var(--size);
+ height: var(--size);
+ opacity: 0;
+ }
+ }
+`;
diff --git a/packages/taler-wallet-webextension/src/components/LoadingError.tsx b/packages/taler-wallet-webextension/src/components/LoadingError.tsx
deleted file mode 100644
index 2cd8bee3b..000000000
--- a/packages/taler-wallet-webextension/src/components/LoadingError.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- 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 { h, VNode } from "preact";
-import { HookError } from "../hooks/useAsyncAsHook.js";
-import { ErrorMessage } from "./ErrorMessage.js";
-import { ErrorTalerOperation } from "./ErrorTalerOperation.js";
-
-export interface Props {
- title: VNode;
- error: HookError;
-}
-export function LoadingError({ title, error }: Props): VNode {
- if (error.operational) {
- return ;
- }
- return ;
-}
diff --git a/packages/taler-wallet-webextension/src/components/MultiActionButton.tsx b/packages/taler-wallet-webextension/src/components/MultiActionButton.tsx
index 673ff3dc2..d6a730a4f 100644
--- a/packages/taler-wallet-webextension/src/components/MultiActionButton.tsx
+++ b/packages/taler-wallet-webextension/src/components/MultiActionButton.tsx
@@ -13,7 +13,7 @@
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
-import { getUnpackedSettings } from "http2";
+import { TranslatedString } from "@gnu-taler/taler-util";
import { h, VNode } from "preact";
import { useState } from "preact/hooks";
import { Button } from "../mui/Button.js";
@@ -21,7 +21,7 @@ import arrowDown from "../svg/chevron-down.svg";
import { ParagraphClickable } from "./styled/index.js";
export interface Props {
- label: (s: string) => VNode;
+ label: (s: string) => TranslatedString;
actions: string[];
onClick: (s: string) => Promise;
}
diff --git a/packages/taler-wallet-webextension/src/components/Part.tsx b/packages/taler-wallet-webextension/src/components/Part.tsx
index a488ca4dc..1449bcac6 100644
--- a/packages/taler-wallet-webextension/src/components/Part.tsx
+++ b/packages/taler-wallet-webextension/src/components/Part.tsx
@@ -14,7 +14,11 @@
GNU Taler; see the file COPYING. If not, see
*/
-import { PaytoUri, stringifyPaytoUri } from "@gnu-taler/taler-util";
+import {
+ PaytoUri,
+ stringifyPaytoUri,
+ TranslatedString,
+} from "@gnu-taler/taler-util";
import { styled } from "@linaria/react";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
@@ -27,8 +31,8 @@ import {
export type Kind = "positive" | "negative" | "neutral";
interface Props {
- title: VNode | string;
- text: VNode | string;
+ title: VNode | TranslatedString;
+ text: VNode | TranslatedString;
kind?: Kind;
big?: boolean;
showSign?: boolean;
diff --git a/packages/taler-wallet-webextension/src/components/PaymentButtons.tsx b/packages/taler-wallet-webextension/src/components/PaymentButtons.tsx
index def1e16eb..30c2ef833 100644
--- a/packages/taler-wallet-webextension/src/components/PaymentButtons.tsx
+++ b/packages/taler-wallet-webextension/src/components/PaymentButtons.tsx
@@ -19,6 +19,7 @@ import {
Amounts,
PreparePayResult,
PreparePayResultType,
+ TranslatedString,
} from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
@@ -109,8 +110,10 @@ export function PaymentButtons({
{payStatus.paid && payStatus.contractTerms.fulfillment_message && (
Merchant message}
- text={payStatus.contractTerms.fulfillment_message}
+ title={i18n.str`Merchant message`}
+ text={
+ payStatus.contractTerms.fulfillment_message as TranslatedString
+ }
kind="neutral"
/>
)}
@@ -131,11 +134,7 @@ function PayWithMobile({ uri }: { uri: string }): VNode {
return (
setShowQR((qr) => !qr)}>
- {!showQR ? (
- Pay with a mobile phone
- ) : (
- Hide QR
- )}
+ {!showQR ? i18n.str`Pay with a mobile phone` : i18n.str`Hide QR`}
{showQR && (
diff --git a/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx b/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx
index e41ff2836..2bba86dba 100644
--- a/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx
+++ b/packages/taler-wallet-webextension/src/components/PendingTransactions.tsx
@@ -87,7 +87,7 @@ export function PendingTransactionsView({
}}
>
PENDING OPERATIONS}
+ titleHead={i18n.str`PENDING OPERATIONS`}
style={{
backgroundColor: "lightcyan",
maxHeight: 150,
diff --git a/packages/taler-wallet-webextension/src/components/SelectList.tsx b/packages/taler-wallet-webextension/src/components/SelectList.tsx
index 3ceac752e..809698711 100644
--- a/packages/taler-wallet-webextension/src/components/SelectList.tsx
+++ b/packages/taler-wallet-webextension/src/components/SelectList.tsx
@@ -14,6 +14,7 @@
GNU Taler; see the file COPYING. If not, see
*/
+import { TranslatedString } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { useTranslationContext } from "../context/translation.js";
import { NiceSelect } from "./styled/index.js";
@@ -21,7 +22,7 @@ import { NiceSelect } from "./styled/index.js";
interface Props {
value?: string;
onChange?: (s: string) => void;
- label: VNode;
+ label: VNode | TranslatedString;
list: {
[label: string]: string;
};
diff --git a/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.stories.tsx b/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.stories.tsx
index 841583113..8c94e6e60 100644
--- a/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.stories.tsx
+++ b/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.stories.tsx
@@ -94,7 +94,10 @@ export const Error = createExample(ErrorView, {
error: {
hasError: true,
message: "message",
- operational: false,
+ // details: {
+ // co
+ // },
+ type: "error",
// details: {
// code: 123,
// },
diff --git a/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx b/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx
index 47c10347c..9871611f2 100644
--- a/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx
+++ b/packages/taler-wallet-webextension/src/components/ShowFullContractTermPopup.tsx
@@ -22,15 +22,16 @@ import { styled } from "@linaria/react";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
import { Loading } from "../components/Loading.js";
-import { LoadingError } from "../components/LoadingError.js";
import { Modal } from "../components/Modal.js";
import { Time } from "../components/Time.js";
+import { alertFromError } from "../context/alert.js";
import { useBackendContext } from "../context/backend.js";
import { useTranslationContext } from "../context/translation.js";
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
import { ButtonHandler } from "../mui/handlers.js";
import { compose, StateViewMap } from "../utils/index.js";
import { Amount } from "./Amount.js";
+import { AlertView } from "./CurrentAlerts.js";
import { Link } from "./styled/index.js";
const ContractTermsTable = styled.table`
@@ -160,13 +161,12 @@ export function ErrorView({
const { i18n } = useTranslationContext();
return (
-
- Could not load purchase proposal details
-
- }
- error={error}
+
);
diff --git a/packages/taler-wallet-webextension/src/components/TermsOfService/index.ts b/packages/taler-wallet-webextension/src/components/TermsOfService/index.ts
index d7716f208..a8c1558d8 100644
--- a/packages/taler-wallet-webextension/src/components/TermsOfService/index.ts
+++ b/packages/taler-wallet-webextension/src/components/TermsOfService/index.ts
@@ -15,14 +15,13 @@
*/
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { ToggleHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
+import { ErrorAlertView } from "../CurrentAlerts.js";
import { useComponentState } from "./state.js";
import { TermsState } from "./utils.js";
import {
- ErrorAcceptingView,
- LoadingUriView,
ShowButtonsAcceptedTosView,
ShowButtonsNonAcceptedTosView,
ShowTosContentView,
@@ -35,8 +34,7 @@ export interface Props {
export type State =
| State.Loading
- | State.LoadingUriError
- | State.ErrorAccepting
+ | State.Error
| State.ShowButtonsAccepted
| State.ShowButtonsNotAccepted
| State.ShowContent;
@@ -47,14 +45,9 @@ export namespace State {
error: undefined;
}
- export interface LoadingUriError {
- status: "loading-error";
- error: HookError;
- }
-
- export interface ErrorAccepting {
- status: "error-accepting";
- error: HookError;
+ export interface Error {
+ status: "error";
+ error: ErrorAlert;
}
export interface BaseInfo {
@@ -79,11 +72,10 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-error": LoadingUriView,
+ error: ErrorAlertView,
"show-content": ShowTosContentView,
"show-buttons-accepted": ShowButtonsAcceptedTosView,
"show-buttons-not-accepted": ShowButtonsNonAcceptedTosView,
- "error-accepting": ErrorAcceptingView,
};
export const TermsOfService = compose(
diff --git a/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts b/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts
index 3b75965d3..c25c0ed13 100644
--- a/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts
+++ b/packages/taler-wallet-webextension/src/components/TermsOfService/state.ts
@@ -16,7 +16,9 @@
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useState } from "preact/hooks";
+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 { Props, State } from "./index.js";
import { buildTermsOfServiceState } from "./utils.js";
@@ -25,9 +27,8 @@ export function useComponentState({ exchangeUrl, onChange }: Props): State {
const api = useBackendContext();
const readOnly = !onChange;
const [showContent, setShowContent] = useState(readOnly);
- const [errorAccepting, setErrorAccepting] = useState(
- undefined,
- );
+ const { i18n } = useTranslationContext();
+ const { pushAlert } = useAlertContext();
/**
* For the exchange selected, bring the status of the terms of service
@@ -54,22 +55,13 @@ export function useComponentState({ exchangeUrl, onChange }: Props): State {
}
if (terms.hasError) {
return {
- status: "loading-error",
- error: terms,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load the status of the term of service`,
+ terms,
+ ),
};
}
-
- if (errorAccepting) {
- return {
- status: "error-accepting",
- error: {
- hasError: true,
- operational: false,
- message: errorAccepting.message,
- },
- };
- }
-
const { state } = terms.response;
async function onUpdate(accepted: boolean): Promise {
@@ -77,13 +69,13 @@ export function useComponentState({ exchangeUrl, onChange }: Props): State {
try {
if (accepted) {
- api.wallet.call(WalletApiOperation.SetExchangeTosAccepted, {
+ await api.wallet.call(WalletApiOperation.SetExchangeTosAccepted, {
exchangeBaseUrl: exchangeUrl,
etag: state.version,
});
} else {
// mark as not accepted
- api.wallet.call(WalletApiOperation.SetExchangeTosAccepted, {
+ await api.wallet.call(WalletApiOperation.SetExchangeTosAccepted, {
exchangeBaseUrl: exchangeUrl,
etag: undefined,
});
@@ -91,11 +83,7 @@ export function useComponentState({ exchangeUrl, onChange }: Props): State {
// setAccepted(accepted);
if (!readOnly) onChange(accepted); //external update
} catch (e) {
- if (e instanceof Error) {
- //FIXME: uncomment this and display error
- // setErrorAccepting(e.message);
- setErrorAccepting(e);
- }
+ pushAlert(alertFromError(i18n.str`Could not accept terms of service`, e));
}
}
diff --git a/packages/taler-wallet-webextension/src/components/TermsOfService/views.tsx b/packages/taler-wallet-webextension/src/components/TermsOfService/views.tsx
index a7e03fd01..0b5a71b3e 100644
--- a/packages/taler-wallet-webextension/src/components/TermsOfService/views.tsx
+++ b/packages/taler-wallet-webextension/src/components/TermsOfService/views.tsx
@@ -14,49 +14,23 @@
GNU Taler; see the file COPYING. If not, see
*/
+import { ExchangeTosStatus } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
-import { LoadingError } from "../../components/LoadingError.js";
-import { useTranslationContext } from "../../context/translation.js";
-import { TermsDocument, TermsState } from "./utils.js";
-import { State } from "./index.js";
import { CheckboxOutlined } from "../../components/CheckboxOutlined.js";
+import { ExchangeXmlTos } from "../../components/ExchangeToS.js";
import {
LinkSuccess,
TermsOfService,
WarningBox,
WarningText,
} from "../../components/styled/index.js";
-import { ExchangeXmlTos } from "../../components/ExchangeToS.js";
-import { ToggleHandler } from "../../mui/handlers.js";
+import { useTranslationContext } from "../../context/translation.js";
import { Button } from "../../mui/Button.js";
-import { ExchangeTosStatus } from "@gnu-taler/taler-util";
-
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load}
- error={error}
- />
- );
-}
-
-export function ErrorAcceptingView({ error }: State.ErrorAccepting): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load}
- error={error}
- />
- );
-}
+import { State } from "./index.js";
export function ShowButtonsAcceptedTosView({
termsAccepted,
showingTermsOfService,
- terms,
}: State.ShowButtonsAccepted): VNode {
const { i18n } = useTranslationContext();
const ableToReviewTermsOfService =
diff --git a/packages/taler-wallet-webextension/src/components/styled/index.tsx b/packages/taler-wallet-webextension/src/components/styled/index.tsx
index 8e98f75eb..e36502333 100644
--- a/packages/taler-wallet-webextension/src/components/styled/index.tsx
+++ b/packages/taler-wallet-webextension/src/components/styled/index.tsx
@@ -535,7 +535,7 @@ export const LinkDestructive = styled(Link)`
`;
export const LinkPrimary = styled(Link)`
- color: rgb(66, 184, 221);
+ color: black;
`;
export const ButtonPrimary = styled(ButtonVariant)<{ small?: boolean }>`
diff --git a/packages/taler-wallet-webextension/src/context/alert.ts b/packages/taler-wallet-webextension/src/context/alert.ts
new file mode 100644
index 000000000..cc98ec1e0
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/context/alert.ts
@@ -0,0 +1,118 @@
+/*
+ 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
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { TranslatedString } from "@gnu-taler/taler-util";
+import { ComponentChildren, createContext, h, VNode } from "preact";
+import { useContext, useState } from "preact/hooks";
+
+export type AlertType = "info" | "warning" | "error" | "success";
+
+export interface Alert {
+ message: TranslatedString;
+ description: TranslatedString | VNode;
+ type: AlertType;
+}
+
+export interface ErrorAlert extends Alert {
+ type: "error";
+ context: object;
+ cause: any;
+}
+
+type Type = {
+ alerts: Alert[];
+ pushAlert: (n: Alert) => void;
+ removeAlert: (n: Alert) => void;
+};
+
+const initial: Type = {
+ alerts: [],
+ pushAlert: () => {
+ null;
+ },
+ removeAlert: () => {
+ null;
+ },
+};
+
+const Context = createContext(initial);
+
+type AlertWithDate = Alert & { since: Date };
+
+type Props = Partial & {
+ children: ComponentChildren;
+};
+
+export const AlertProvider = ({ children }: Props): VNode => {
+ const timeout = 3000;
+
+ const [alerts, setAlerts] = useState([]);
+
+ const pushAlert = (n: Alert): void => {
+ const entry = { ...n, since: new Date() };
+ setAlerts((ns) => [...ns, entry]);
+ if (n.type !== "error") {
+ setTimeout(() => {
+ setAlerts((ns) => ns.filter((x) => x.since !== entry.since));
+ }, timeout);
+ }
+ };
+
+ const removeAlert = (alert: Alert): void => {
+ setAlerts((ns: AlertWithDate[]) => ns.filter((n) => n !== alert));
+ };
+
+ return h(Context.Provider, {
+ value: { alerts, pushAlert, removeAlert },
+ children,
+ });
+};
+
+export const useAlertContext = (): Type => useContext(Context);
+
+export function alertFromError(
+ message: TranslatedString,
+ error: unknown,
+ ...context: any[]
+): ErrorAlert {
+ let description = "" as TranslatedString;
+
+ const isObject = typeof error === "object" &&
+ error !== null;
+ const hasMessage =
+ isObject &&
+ "message" in error &&
+ typeof error.message === "string";
+
+ if (hasMessage) {
+ description = error.message as TranslatedString;
+ } else {
+ description = `Unknown error: ${String(error)}` as TranslatedString;
+ }
+
+ return {
+ type: "error",
+ message,
+ description,
+ cause: error,
+ context,
+ };
+}
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/index.ts b/packages/taler-wallet-webextension/src/cta/Deposit/index.ts
index 9ff3ddd1d..6b228188b 100644
--- a/packages/taler-wallet-webextension/src/cta/Deposit/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Deposit/index.ts
@@ -15,12 +15,13 @@
*/
import { AmountJson, AmountString } from "@gnu-taler/taler-util";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import { LoadingUriView, ReadyView } from "./views.js";
+import { ReadyView } from "./views.js";
export interface Props {
talerDepositUri: string | undefined;
@@ -37,8 +38,8 @@ export namespace State {
error: undefined;
}
export interface LoadingUriError {
- status: "loading-uri";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface Ready {
status: "ready";
@@ -57,7 +58,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-uri": LoadingUriView,
+ error: ErrorAlertView,
ready: ReadyView,
};
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/state.ts b/packages/taler-wallet-webextension/src/cta/Deposit/state.ts
index dba435611..4cee7cfd0 100644
--- a/packages/taler-wallet-webextension/src/cta/Deposit/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Deposit/state.ts
@@ -16,7 +16,9 @@
import { Amounts } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { Props, State } from "./index.js";
@@ -38,12 +40,16 @@ export function useComponentState({
});
return { deposit, uri: talerDepositUri, amount };
});
+ const { i18n } = useTranslationContext();
if (!info) return { status: "loading", error: undefined };
if (info.hasError) {
return {
- status: "loading-uri",
- error: info,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load the status of the term of service`,
+ info,
+ ),
};
}
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/test.ts b/packages/taler-wallet-webextension/src/cta/Deposit/test.ts
index 6a896fb7f..031dcffaa 100644
--- a/packages/taler-wallet-webextension/src/cta/Deposit/test.ts
+++ b/packages/taler-wallet-webextension/src/cta/Deposit/test.ts
@@ -50,12 +50,12 @@ describe("Deposit CTA states", () => {
expect(status).equals("loading");
},
({ status, error }) => {
- expect(status).equals("loading-uri");
+ expect(status).equals("error");
if (!error) expect.fail();
- if (!error.hasError) expect.fail();
- if (error.operational) expect.fail();
- expect(error.message).eq("ERROR_NO-URI-FOR-DEPOSIT");
+ // if (!error.hasError) expect.fail();
+ // if (error.operational) expect.fail();
+ expect(error.cause?.message).eq("ERROR_NO-URI-FOR-DEPOSIT");
},
],
TestingContext,
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx b/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx
index 2ec305de5..7fa43f878 100644
--- a/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx
@@ -17,7 +17,6 @@
import { Amounts } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { Amount } from "../../components/Amount.js";
-import { LoadingError } from "../../components/LoadingError.js";
import { LogoHeader } from "../../components/LogoHeader.js";
import { Part } from "../../components/Part.js";
import { SubTitle, WalletAction } from "../../components/styled/index.js";
@@ -30,17 +29,6 @@ import { State } from "./index.js";
* @author sebasjm
*/
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load deposit status}
- error={error}
- />
- );
-}
-
export function ReadyView(state: State.Ready): VNode {
const { i18n } = useTranslationContext();
@@ -55,7 +43,7 @@ export function ReadyView(state: State.Ready): VNode {
{Amounts.isNonZero(state.cost) && (
Cost}
+ title={i18n.str`Cost`}
text={ }
kind="negative"
/>
@@ -63,14 +51,14 @@ export function ReadyView(state: State.Ready): VNode {
{Amounts.isNonZero(state.fee) && (
Fee}
+ title={i18n.str`Fee`}
text={ }
kind="negative"
/>
)}
To be received}
+ title={i18n.str`To be received`}
text={ }
kind="positive"
/>
diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts
index 0569e8e5f..f39ab6794 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts
@@ -14,16 +14,17 @@
GNU Taler; see the file COPYING. If not, see
*/
-import { AmountJson, TalerErrorDetail } from "@gnu-taler/taler-util";
+import { AmountJson } from "@gnu-taler/taler-util";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { State as SelectExchangeState } from "../../hooks/useSelectedExchange.js";
import { ButtonHandler, TextFieldHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { ExchangeSelectionPage } from "../../wallet/ExchangeSelection/index.js";
import { NoExchangesView } from "../../wallet/ExchangeSelection/views.js";
import { useComponentState } from "./state.js";
-import { LoadingUriView, ReadyView } from "./views.js";
+import { ReadyView } from "./views.js";
export interface Props {
amount: string;
@@ -45,8 +46,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-uri";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface BaseInfo {
@@ -63,13 +64,12 @@ export namespace State {
requestAmount: AmountJson;
exchangeUrl: string;
error: undefined;
- operationError?: TalerErrorDetail;
}
}
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-uri": LoadingUriView,
+ error: ErrorAlertView,
"no-exchange": NoExchangesView,
"selecting-exchange": ExchangeSelectionPage,
ready: ReadyView,
diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
index 998270e53..46b1262b1 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
@@ -23,7 +23,9 @@ import {
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { isFuture, parse } from "date-fns";
import { useState } from "preact/hooks";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { useSelectedExchange } from "../../hooks/useSelectedExchange.js";
import { RecursiveState } from "../../utils/index.js";
@@ -40,6 +42,7 @@ export function useComponentState({
const hook = useAsyncAsHook(() =>
api.wallet.call(WalletApiOperation.ListExchanges, {}),
);
+ const { i18n } = useTranslationContext();
if (!hook) {
return {
@@ -49,10 +52,19 @@ export function useComponentState({
}
if (hook.hasError) {
return {
- status: "loading-uri",
- error: hook,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load the status of the term of service`,
+ hook,
+ ),
};
}
+ // if (hook.hasError) {
+ // return {
+ // status: "loading-uri",
+ // error: hook,
+ // };
+ // }
const exchangeList = hook.response.exchanges;
@@ -60,10 +72,6 @@ export function useComponentState({
const [subject, setSubject] = useState();
const [timestamp, setTimestamp] = useState();
- const [operationError, setOperationError] = useState<
- TalerErrorDetail | undefined
- >(undefined);
-
const selectedExchange = useSelectedExchange({
currency: amount.currency,
defaultExchange: undefined,
@@ -93,11 +101,19 @@ export function useComponentState({
error: undefined,
};
}
+
if (hook.hasError) {
return {
- status: "loading-uri",
- error: hook,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load the status of the term of service`,
+ hook,
+ ),
};
+ // return {
+ // status: "loading-uri",
+ // error: hook,
+ // };
}
const { amountEffective, amountRaw } = hook.response;
@@ -160,8 +176,8 @@ export function useComponentState({
subject === undefined
? undefined
: !subject
- ? "Can't be empty"
- : undefined,
+ ? "Can't be empty"
+ : undefined,
value: subject ?? "",
onInput: async (e) => setSubject(e),
},
@@ -183,7 +199,6 @@ export function useComponentState({
requestAmount,
toBeReceived,
error: undefined,
- operationError,
};
};
}
diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx
index 0ef5c697e..10e0e68d5 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx
@@ -17,41 +17,24 @@
import { format } from "date-fns";
import { h, VNode } from "preact";
import { ErrorTalerOperation } from "../../components/ErrorTalerOperation.js";
-import { LoadingError } from "../../components/LoadingError.js";
import { LogoHeader } from "../../components/LogoHeader.js";
import { Part } from "../../components/Part.js";
-import { QR } from "../../components/QR.js";
import {
- Link,
SubTitle,
SvgIcon,
WalletAction,
} from "../../components/styled/index.js";
import { useTranslationContext } from "../../context/translation.js";
import { Button } from "../../mui/Button.js";
-import { Grid } from "../../mui/Grid.js";
import { TextField } from "../../mui/TextField.js";
import editIcon from "../../svg/edit_24px.svg";
import { ExchangeDetails, InvoiceDetails } from "../../wallet/Transaction.js";
import { State } from "./index.js";
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load}
- error={error}
- />
- );
-}
-
export function ReadyView({
exchangeUrl,
subject,
expiration,
- cancel,
- operationError,
create,
toBeReceived,
requestAmount,
@@ -59,7 +42,7 @@ export function ReadyView({
}: State.Ready): VNode {
const { i18n } = useTranslationContext();
- async function oneDayExpiration() {
+ async function oneDayExpiration(): Promise {
if (expiration.onInput) {
expiration.onInput(
format(new Date().getTime() + 1000 * 60 * 60 * 24, "dd/MM/yyyy"),
@@ -67,14 +50,14 @@ export function ReadyView({
}
}
- async function oneWeekExpiration() {
+ async function oneWeekExpiration(): Promise {
if (expiration.onInput) {
expiration.onInput(
format(new Date().getTime() + 1000 * 60 * 60 * 24 * 7, "dd/MM/yyyy"),
);
}
}
- async function _20DaysExpiration() {
+ async function _20DaysExpiration(): Promise {
if (expiration.onInput) {
expiration.onInput(
format(new Date().getTime() + 1000 * 60 * 60 * 24 * 20, "dd/MM/yyyy"),
@@ -87,16 +70,6 @@ export function ReadyView({
Digital invoice
- {operationError && (
-
- Could not finish the invoice creation
-
- }
- error={operationError}
- />
- )}
Short description of the invoice
- }
+ helperText={i18n.str`Short description of the invoice`}
required
fullWidth
value={subject.value}
@@ -171,7 +142,7 @@ export function ReadyView({
Details}
+ title={i18n.str`Details`}
text={
Create
-
);
}
diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts
index f3de0885d..82b2c7af5 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts
@@ -20,12 +20,13 @@ import {
PreparePayResult,
TalerErrorDetail,
} from "@gnu-taler/taler-util";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import { LoadingUriView, ReadyView } from "./views.js";
+import { ReadyView } from "./views.js";
export interface Props {
talerPayPullUri: string;
@@ -48,8 +49,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-uri";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface BaseInfo {
@@ -83,7 +84,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-uri": LoadingUriView,
+ error: ErrorAlertView,
"no-balance-for-currency": ReadyView,
"no-enough-balance": ReadyView,
ready: ReadyView,
diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts
index c0b97c106..9c4a3162e 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts
@@ -25,7 +25,9 @@ import {
} from "@gnu-taler/taler-util";
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useEffect, useState } from "preact/hooks";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { Props, State } from "./index.js";
@@ -36,6 +38,7 @@ export function useComponentState({
onSuccess,
}: Props): State {
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
const hook = useAsyncAsHook(async () => {
const p2p = await api.wallet.call(WalletApiOperation.CheckPeerPullPayment, {
talerUri: talerPayPullUri,
@@ -63,10 +66,19 @@ export function useComponentState({
}
if (hook.hasError) {
return {
- status: "loading-uri",
- error: hook,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load the status of the term of service`,
+ hook,
+ ),
};
}
+ // if (hook.hasError) {
+ // return {
+ // status: "loading-uri",
+ // error: hook,
+ // };
+ // }
const { contractTerms, peerPullPaymentIncomingId } = hook.response.p2p;
diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx b/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx
index a53fa881a..6a9ab3cf7 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx
@@ -17,26 +17,14 @@
import { Fragment, h, VNode } from "preact";
import { Amount } from "../../components/Amount.js";
import { ErrorTalerOperation } from "../../components/ErrorTalerOperation.js";
-import { LoadingError } from "../../components/LoadingError.js";
import { LogoHeader } from "../../components/LogoHeader.js";
import { Part } from "../../components/Part.js";
+import { PaymentButtons } from "../../components/PaymentButtons.js";
import { Link, SubTitle, WalletAction } from "../../components/styled/index.js";
import { Time } from "../../components/Time.js";
import { useTranslationContext } from "../../context/translation.js";
-import { PaymentButtons } from "../../components/PaymentButtons";
import { State } from "./index.js";
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load}
- error={error}
- />
- );
-}
-
export function ReadyView(
state: State.Ready | State.NoBalanceForCurrency | State.NoEnoughBalance,
): VNode {
@@ -60,25 +48,15 @@ export function ReadyView(
{operationError && (
- Could not finish the payment operation
-
- }
+ title={i18n.str`Could not finish the payment operation`}
error={operationError}
/>
)}
} />
+ } />
Subject}
- text={{summary}
}
- />
- Amount}
- text={ }
- />
- Valid until}
+ title={i18n.str`Valid until`}
text={ }
kind="neutral"
/>
@@ -91,11 +69,6 @@ export function ReadyView(
payHandler={status === "ready" ? state.accept : undefined}
goToWalletManualWithdraw={state.goToWalletManualWithdraw}
/>
-
);
}
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/index.ts b/packages/taler-wallet-webextension/src/cta/Payment/index.ts
index 2dc6b6741..e844c1706 100644
--- a/packages/taler-wallet-webextension/src/cta/Payment/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Payment/index.ts
@@ -21,12 +21,13 @@ import {
PreparePayResultInsufficientBalance,
PreparePayResultPaymentPossible,
} from "@gnu-taler/taler-util";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import { BaseView, LoadingUriView } from "./views.js";
+import { BaseView } from "./views.js";
export interface Props {
talerPayUri?: string;
@@ -49,8 +50,8 @@ export namespace State {
error: undefined;
}
export interface LoadingUriError {
- status: "loading-uri";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
interface BaseInfo {
@@ -86,7 +87,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-uri": LoadingUriView,
+ error: ErrorAlertView,
"no-balance-for-currency": BaseView,
"no-enough-balance": BaseView,
confirmed: BaseView,
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/state.ts b/packages/taler-wallet-webextension/src/cta/Payment/state.ts
index d4adf4bcb..6d7ef6b20 100644
--- a/packages/taler-wallet-webextension/src/cta/Payment/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Payment/state.ts
@@ -23,7 +23,9 @@ import {
} from "@gnu-taler/taler-util";
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useEffect, useState } from "preact/hooks";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { Props, State } from "./index.js";
@@ -36,6 +38,7 @@ export function useComponentState({
}: Props): State {
const [payErrMsg, setPayErrMsg] = useState(undefined);
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
const hook = useAsyncAsHook(async () => {
if (!talerPayUri) throw Error("ERROR_NO-URI-FOR-PAYMENT");
@@ -80,10 +83,19 @@ export function useComponentState({
if (!hook) return { status: "loading", error: undefined };
if (hook.hasError) {
return {
- status: "loading-uri",
- error: hook,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load the status of the term of service`,
+ hook,
+ ),
};
}
+ // if (hook.hasError) {
+ // return {
+ // status: "loading-uri",
+ // error: hook,
+ // };
+ // }
const { payStatus } = hook.response;
const amount = Amounts.parseOrThrow(payStatus.amountRaw);
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/test.ts b/packages/taler-wallet-webextension/src/cta/Payment/test.ts
index 077930972..123e95a87 100644
--- a/packages/taler-wallet-webextension/src/cta/Payment/test.ts
+++ b/packages/taler-wallet-webextension/src/cta/Payment/test.ts
@@ -54,10 +54,10 @@ describe("Payment CTA states", () => {
expect(error).undefined;
},
({ status, error }) => {
- expect(status).equals("loading-uri");
+ expect(status).equals("error");
if (error === undefined) expect.fail();
- expect(error.hasError).true;
- expect(error.operational).false;
+ // expect(error.hasError).true;
+ // expect(error.operational).false;
},
],
TestingContext,
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx
index efc8bcfc4..244ac5886 100644
--- a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx
@@ -19,28 +19,17 @@ import {
Amounts,
MerchantContractTerms as ContractTerms,
PreparePayResultType,
+ TranslatedString,
} from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
-import { LoadingError } from "../../components/LoadingError.js";
import { Part } from "../../components/Part.js";
import { PaymentButtons } from "../../components/PaymentButtons.js";
-import { Link, SuccessBox, WarningBox } from "../../components/styled/index.js";
+import { SuccessBox, WarningBox } from "../../components/styled/index.js";
import { Time } from "../../components/Time.js";
import { useTranslationContext } from "../../context/translation.js";
import { MerchantDetails, PurchaseDetails } from "../../wallet/Transaction.js";
import { State } from "./index.js";
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load pay status}
- error={error}
- />
- );
-}
-
type SupportedStates =
| State.Ready
| State.Confirmed
@@ -66,17 +55,17 @@ export function BaseView(state: SupportedStates): VNode {
Purchase}
- text={contractTerms.summary}
+ title={i18n.str`Purchase`}
+ text={contractTerms.summary as TranslatedString}
kind="neutral"
/>
Merchant}
+ title={i18n.str`Merchant`}
text={ }
kind="neutral"
/>
Details}
+ title={i18n.str`Details`}
text={
{contractTerms.order_id && (
Receipt}
- text={`#${contractTerms.order_id}`}
+ title={i18n.str`Receipt`}
+ text={`#${contractTerms.order_id}` as TranslatedString}
kind="neutral"
/>
)}
{contractTerms.pay_deadline && (
Valid until}
+ title={i18n.str`Valid until`}
text={
-
);
}
diff --git a/packages/taler-wallet-webextension/src/cta/Recovery/index.ts b/packages/taler-wallet-webextension/src/cta/Recovery/index.ts
index 4a6fc79c9..79056c15b 100644
--- a/packages/taler-wallet-webextension/src/cta/Recovery/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Recovery/index.ts
@@ -14,12 +14,13 @@
GNU Taler; see the file COPYING. If not, see
*/
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import { LoadingUriView, ReadyView } from "./views.js";
+import { ReadyView } from "./views.js";
export interface Props {
talerRecoveryUri?: string;
@@ -36,8 +37,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-uri";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface BaseInfo {
@@ -53,7 +54,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-uri": LoadingUriView,
+ error: ErrorAlertView,
ready: ReadyView,
};
diff --git a/packages/taler-wallet-webextension/src/cta/Recovery/state.ts b/packages/taler-wallet-webextension/src/cta/Recovery/state.ts
index 4fef2c862..078e53bf9 100644
--- a/packages/taler-wallet-webextension/src/cta/Recovery/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Recovery/state.ts
@@ -16,7 +16,9 @@
import { parseRecoveryUri } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import { Alert } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { Props, State } from "./index.js";
export function useComponentState({
@@ -25,13 +27,16 @@ export function useComponentState({
onSuccess,
}: Props): State {
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
if (!talerRecoveryUri) {
return {
- status: "loading-uri",
+ status: "error",
error: {
- operational: false,
- hasError: true,
- message: "Missing URI",
+ type: "error",
+ message: i18n.str`Missing URI`,
+ description: i18n.str``,
+ cause: new Error("something"),
+ context: {},
},
};
}
@@ -39,11 +44,13 @@ export function useComponentState({
if (!info) {
return {
- status: "loading-uri",
+ status: "error",
error: {
- operational: false,
- hasError: true,
- message: "Could not be read",
+ type: "error",
+ message: i18n.str`Could not parse the recovery URI`,
+ description: i18n.str``,
+ cause: new Error("something"),
+ context: {},
},
};
}
diff --git a/packages/taler-wallet-webextension/src/cta/Recovery/views.tsx b/packages/taler-wallet-webextension/src/cta/Recovery/views.tsx
index 371516932..858349ef3 100644
--- a/packages/taler-wallet-webextension/src/cta/Recovery/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Recovery/views.tsx
@@ -15,28 +15,12 @@
*/
import { Fragment, h, VNode } from "preact";
-import { LoadingError } from "../../components/LoadingError.js";
import { LogoHeader } from "../../components/LogoHeader.js";
import { SubTitle, WalletAction } from "../../components/styled/index.js";
import { useTranslationContext } from "../../context/translation.js";
import { Button } from "../../mui/Button.js";
import { State } from "./index.js";
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
-
- Could not load backup recovery information
-
- }
- error={error}
- />
- );
-}
-
export function ReadyView({ accept, cancel }: State.Ready): VNode {
const { i18n } = useTranslationContext();
return (
diff --git a/packages/taler-wallet-webextension/src/cta/Refund/index.ts b/packages/taler-wallet-webextension/src/cta/Refund/index.ts
index f79a77680..e90f770ff 100644
--- a/packages/taler-wallet-webextension/src/cta/Refund/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Refund/index.ts
@@ -15,17 +15,13 @@
*/
import { AmountJson, Product } from "@gnu-taler/taler-util";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import {
- IgnoredView,
- InProgressView,
- LoadingUriView,
- ReadyView,
-} from "./views.js";
+import { IgnoredView, InProgressView, ReadyView } from "./views.js";
export interface Props {
talerRefundUri?: string;
@@ -47,8 +43,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-uri";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
interface BaseInfo {
@@ -81,7 +77,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-uri": LoadingUriView,
+ error: ErrorAlertView,
"in-progress": InProgressView,
ignored: IgnoredView,
ready: ReadyView,
diff --git a/packages/taler-wallet-webextension/src/cta/Refund/state.ts b/packages/taler-wallet-webextension/src/cta/Refund/state.ts
index 9e3311b65..5a5073ba3 100644
--- a/packages/taler-wallet-webextension/src/cta/Refund/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Refund/state.ts
@@ -17,7 +17,9 @@
import { Amounts, NotificationType } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useEffect, useState } from "preact/hooks";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { Props, State } from "./index.js";
@@ -27,6 +29,7 @@ export function useComponentState({
onSuccess,
}: Props): State {
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
const [ignored, setIgnored] = useState(false);
const info = useAsyncAsHook(async () => {
@@ -49,10 +52,19 @@ export function useComponentState({
}
if (info.hasError) {
return {
- status: "loading-uri",
- error: info,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load the status of the term of service`,
+ info,
+ ),
};
}
+ // if (info.hasError) {
+ // return {
+ // status: "loading-uri",
+ // error: info,
+ // };
+ // }
const { refund, uri } = info.response;
diff --git a/packages/taler-wallet-webextension/src/cta/Refund/test.ts b/packages/taler-wallet-webextension/src/cta/Refund/test.ts
index 24d483a9a..8c4daa4d2 100644
--- a/packages/taler-wallet-webextension/src/cta/Refund/test.ts
+++ b/packages/taler-wallet-webextension/src/cta/Refund/test.ts
@@ -53,11 +53,11 @@ describe("Refund CTA states", () => {
expect(error).undefined;
},
({ status, error }) => {
- expect(status).equals("loading-uri");
+ expect(status).equals("error");
if (!error) expect.fail();
- if (!error.hasError) expect.fail();
- if (error.operational) expect.fail();
- expect(error.message).eq("ERROR_NO-URI-FOR-REFUND");
+ // if (!error.hasError) expect.fail();
+ // if (error.operational) expect.fail();
+ expect(error.cause?.message).eq("ERROR_NO-URI-FOR-REFUND");
},
],
TestingContext,
diff --git a/packages/taler-wallet-webextension/src/cta/Refund/views.tsx b/packages/taler-wallet-webextension/src/cta/Refund/views.tsx
index a55bc43dd..16e1c519c 100644
--- a/packages/taler-wallet-webextension/src/cta/Refund/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Refund/views.tsx
@@ -17,26 +17,14 @@
import { Amounts } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { Amount } from "../../components/Amount.js";
-import { LoadingError } from "../../components/LoadingError.js";
import { LogoHeader } from "../../components/LogoHeader.js";
import { Part } from "../../components/Part.js";
+import { ProductList } from "../../components/ProductList.js";
import { Link, SubTitle, WalletAction } from "../../components/styled/index.js";
import { useTranslationContext } from "../../context/translation.js";
import { Button } from "../../mui/Button.js";
-import { ProductList } from "../../components/ProductList.js";
import { State } from "./index.js";
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load refund status}
- error={error}
- />
- );
-}
-
export function IgnoredView(state: State.Ignored): VNode {
const { i18n } = useTranslationContext();
@@ -73,13 +61,13 @@ export function InProgressView(state: State.InProgress): VNode {
Total to refund}
+ title={i18n.str`Total to refund`}
text={ }
kind="negative"
/>
Refunded}
+ title={i18n.str`Refunded`}
text={ }
kind="negative"
/>
@@ -112,21 +100,21 @@ export function ReadyView(state: State.Ready): VNode {
Order amount}
+ title={i18n.str`Order amount`}
text={ }
kind="neutral"
/>
{Amounts.isNonZero(state.granted) && (
Already refunded}
+ title={i18n.str`Already refunded`}
text={ }
kind="neutral"
/>
)}
Refund offered}
+ title={i18n.str`Refund offered`}
text={ }
kind="positive"
/>
@@ -147,11 +135,6 @@ export function ReadyView(state: State.Ready): VNode {
-
);
}
diff --git a/packages/taler-wallet-webextension/src/cta/Tip/index.ts b/packages/taler-wallet-webextension/src/cta/Tip/index.ts
index 62e0688be..5e56db7bc 100644
--- a/packages/taler-wallet-webextension/src/cta/Tip/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Tip/index.ts
@@ -15,17 +15,13 @@
*/
import { AmountJson } from "@gnu-taler/taler-util";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import {
- AcceptedView,
- IgnoredView,
- LoadingUriView,
- ReadyView,
-} from "./views.js";
+import { AcceptedView, IgnoredView, ReadyView } from "./views.js";
export interface Props {
talerTipUri?: string;
@@ -48,8 +44,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-uri";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface BaseInfo {
@@ -75,7 +71,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-uri": LoadingUriView,
+ error: ErrorAlertView,
accepted: AcceptedView,
ignored: IgnoredView,
ready: ReadyView,
diff --git a/packages/taler-wallet-webextension/src/cta/Tip/state.ts b/packages/taler-wallet-webextension/src/cta/Tip/state.ts
index e83755119..29a9c4c71 100644
--- a/packages/taler-wallet-webextension/src/cta/Tip/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Tip/state.ts
@@ -16,7 +16,9 @@
import { Amounts } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { Props, State } from "./index.js";
@@ -26,6 +28,7 @@ export function useComponentState({
onSuccess,
}: Props): State {
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
const tipInfo = useAsyncAsHook(async () => {
if (!talerTipUri) throw Error("ERROR_NO-URI-FOR-TIP");
const tip = await api.wallet.call(WalletApiOperation.PrepareTip, {
@@ -42,10 +45,19 @@ export function useComponentState({
}
if (tipInfo.hasError) {
return {
- status: "loading-uri",
- error: tipInfo,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load the status of the term of service`,
+ tipInfo,
+ ),
};
}
+ // if (tipInfo.hasError) {
+ // return {
+ // status: "loading-uri",
+ // error: tipInfo,
+ // };
+ // }
const { tip } = tipInfo.response;
diff --git a/packages/taler-wallet-webextension/src/cta/Tip/test.ts b/packages/taler-wallet-webextension/src/cta/Tip/test.ts
index 5688d82a9..2cc95f424 100644
--- a/packages/taler-wallet-webextension/src/cta/Tip/test.ts
+++ b/packages/taler-wallet-webextension/src/cta/Tip/test.ts
@@ -23,8 +23,7 @@ import { Amounts } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { expect } from "chai";
import { tests } from "../../../../web-util/src/index.browser.js";
-import { mountHook, nullFunction } from "../../test-utils.js";
-import { createWalletApiMock } from "../../test-utils.js";
+import { createWalletApiMock, nullFunction } from "../../test-utils.js";
import { Props } from "./index.js";
import { useComponentState } from "./state.js";
@@ -47,11 +46,9 @@ describe("Tip CTA states", () => {
expect(error).undefined;
},
({ status, error }) => {
- expect(status).equals("loading-uri");
+ expect(status).equals("error");
if (!error) expect.fail();
- if (!error.hasError) expect.fail();
- if (error.operational) expect.fail();
- expect(error.message).eq("ERROR_NO-URI-FOR-TIP");
+ expect(error.cause?.message).eq("ERROR_NO-URI-FOR-TIP");
},
],
TestingContext,
diff --git a/packages/taler-wallet-webextension/src/cta/Tip/views.tsx b/packages/taler-wallet-webextension/src/cta/Tip/views.tsx
index fbc93c5ab..000daf19e 100644
--- a/packages/taler-wallet-webextension/src/cta/Tip/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Tip/views.tsx
@@ -14,9 +14,9 @@
GNU Taler; see the file COPYING. If not, see
*/
+import { TranslatedString } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { Amount } from "../../components/Amount.js";
-import { LoadingError } from "../../components/LoadingError.js";
import { LogoHeader } from "../../components/LogoHeader.js";
import { Part } from "../../components/Part.js";
import { Link, SubTitle, WalletAction } from "../../components/styled/index.js";
@@ -24,17 +24,6 @@ import { useTranslationContext } from "../../context/translation.js";
import { Button } from "../../mui/Button.js";
import { State } from "./index.js";
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load tip status}
- error={error}
- />
- );
-}
-
export function IgnoredView(state: State.Ignored): VNode {
const { i18n } = useTranslationContext();
return (
@@ -66,18 +55,18 @@ export function ReadyView(state: State.Ready): VNode {
The merchant is offering you a tip
Amount}
+ title={i18n.str`Amount`}
text={ }
kind="positive"
/>
Merchant URL}
- text={state.merchantBaseUrl}
+ title={i18n.str`Merchant URL`}
+ text={state.merchantBaseUrl as TranslatedString}
kind="neutral"
/>
Exchange}
- text={state.exchangeBaseUrl}
+ title={i18n.str`Exchange`}
+ text={state.exchangeBaseUrl as TranslatedString}
kind="neutral"
/>
@@ -92,11 +81,6 @@ export function ReadyView(state: State.Ready): VNode {
-
);
}
diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts
index 0715bb60e..b191b4efa 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts
@@ -15,12 +15,13 @@
*/
import { AmountJson, TalerErrorDetail } from "@gnu-taler/taler-util";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { ButtonHandler, TextFieldHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import { LoadingUriView, ReadyView } from "./views.js";
+import { ReadyView } from "./views.js";
export interface Props {
amount: string;
@@ -37,8 +38,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-uri";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface BaseInfo {
@@ -59,7 +60,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-uri": LoadingUriView,
+ error: ErrorAlertView,
ready: ReadyView,
};
diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts
index c09a524c8..ecea53848 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts
@@ -22,7 +22,9 @@ import {
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { isFuture, parse } from "date-fns";
import { useState } from "preact/hooks";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { Props, State } from "./index.js";
@@ -33,6 +35,7 @@ export function useComponentState({
}: Props): State {
const api = useBackendContext();
const amount = Amounts.parseOrThrow(amountStr);
+ const { i18n } = useTranslationContext();
const [subject, setSubject] = useState();
const [timestamp, setTimestamp] = useState();
@@ -59,10 +62,19 @@ export function useComponentState({
}
if (hook.hasError) {
return {
- status: "loading-uri",
- error: hook,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load the status of the term of service`,
+ hook,
+ ),
};
}
+ // if (hook.hasError) {
+ // return {
+ // status: "loading-uri",
+ // error: hook,
+ // };
+ // }
const { amountEffective, amountRaw } = hook.response;
const debitAmount = Amounts.parseOrThrow(amountRaw);
diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx b/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx
index 0b034e3fb..cee61b3b8 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx
@@ -17,10 +17,8 @@
import { format } from "date-fns";
import { h, VNode } from "preact";
import { ErrorTalerOperation } from "../../components/ErrorTalerOperation.js";
-import { LoadingError } from "../../components/LoadingError.js";
import { LogoHeader } from "../../components/LogoHeader.js";
import { Part } from "../../components/Part.js";
-import { QR } from "../../components/QR.js";
import { Link, SubTitle, WalletAction } from "../../components/styled/index.js";
import { useTranslationContext } from "../../context/translation.js";
import { Button } from "../../mui/Button.js";
@@ -28,17 +26,6 @@ import { TextField } from "../../mui/TextField.js";
import { TransferDetails } from "../../wallet/Transaction.js";
import { State } from "./index.js";
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load}
- error={error}
- />
- );
-}
-
export function ReadyView({
subject,
expiration,
@@ -80,11 +67,7 @@ export function ReadyView({
{operationError && (
- Could not finish the transfer creation
-
- }
+ title={i18n.str`Could not finish the transfer creation`}
error={operationError}
/>
)}
@@ -93,9 +76,7 @@ export function ReadyView({
Short description of the transfer
- }
+ helperText={i18n.str`Short description of the transfer`}
error={subject.error}
required
fullWidth
@@ -138,7 +119,7 @@ export function ReadyView({
Details}
+ title={i18n.str`Details`}
text={
Create
-
);
}
diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts b/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts
index fe6fb2ada..7bb8785d7 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts
@@ -19,12 +19,13 @@ import {
AmountJson,
TalerErrorDetail,
} from "@gnu-taler/taler-util";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import { LoadingUriView, ReadyView } from "./views.js";
+import { ReadyView } from "./views.js";
export interface Props {
talerPayPushUri: string;
@@ -41,8 +42,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-uri";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface BaseInfo {
@@ -62,7 +63,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-uri": LoadingUriView,
+ error: ErrorAlertView,
ready: ReadyView,
};
diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts
index 82c95b0c6..04fc0e0a7 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts
@@ -22,7 +22,9 @@ import {
} from "@gnu-taler/taler-util";
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useState } from "preact/hooks";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { Props, State } from "./index.js";
@@ -32,6 +34,7 @@ export function useComponentState({
onSuccess,
}: Props): State {
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
const hook = useAsyncAsHook(async () => {
return await api.wallet.call(WalletApiOperation.CheckPeerPushPayment, {
talerUri: talerPayPushUri,
@@ -49,10 +52,19 @@ export function useComponentState({
}
if (hook.hasError) {
return {
- status: "loading-uri",
- error: hook,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load the status of the term of service`,
+ hook,
+ ),
};
}
+ // if (hook.hasError) {
+ // return {
+ // status: "loading-uri",
+ // error: hook,
+ // };
+ // }
const { contractTerms, peerPushPaymentIncomingId } = hook.response;
diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/views.tsx b/packages/taler-wallet-webextension/src/cta/TransferPickup/views.tsx
index c43b0ff52..d2402db3a 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferPickup/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/views.tsx
@@ -17,7 +17,6 @@
import { h, VNode } from "preact";
import { Amount } from "../../components/Amount.js";
import { ErrorTalerOperation } from "../../components/ErrorTalerOperation.js";
-import { LoadingError } from "../../components/LoadingError.js";
import { LogoHeader } from "../../components/LogoHeader.js";
import { Part } from "../../components/Part.js";
import { Link, SubTitle, WalletAction } from "../../components/styled/index.js";
@@ -26,17 +25,6 @@ import { useTranslationContext } from "../../context/translation.js";
import { Button } from "../../mui/Button.js";
import { State } from "./index.js";
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load}
- error={error}
- />
- );
-}
-
export function ReadyView({
accept,
summary,
@@ -54,25 +42,15 @@ export function ReadyView({
{operationError && (
- Could not finish the pickup operation
-
- }
+ title={i18n.str`Could not finish the pickup operation`}
error={operationError}
/>
)}
+ {summary}} />
+ } />
Subject}
- text={{summary}
}
- />
- Amount}
- text={ }
- />
- Valid until}
+ title={i18n.str`Valid until`}
text={ }
kind="neutral"
/>
@@ -84,11 +62,6 @@ export function ReadyView({
-
);
}
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
index 25d4e44e5..7dfc7c141 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
@@ -27,7 +27,9 @@ import {
import { ExchangeSelectionPage } from "../../wallet/ExchangeSelection/index.js";
import { NoExchangesView } from "../../wallet/ExchangeSelection/views.js";
-import { LoadingInfoView, LoadingUriView, SuccessView } from "./views.js";
+import { SuccessView } from "./views.js";
+import { ErrorAlert } from "../../context/alert.js";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
export interface PropsFromURI {
talerWithdrawUri: string | undefined;
@@ -44,7 +46,6 @@ export interface PropsFromParams {
export type State =
| State.Loading
| State.LoadingUriError
- | State.LoadingInfoError
| SelectExchangeState.NoExchange
| SelectExchangeState.Selecting
| State.Success;
@@ -55,12 +56,8 @@ export namespace State {
error: undefined;
}
export interface LoadingUriError {
- status: "uri-error";
- error: HookError;
- }
- export interface LoadingInfoError {
- status: "amount-error";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export type Success = {
@@ -86,8 +83,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "uri-error": LoadingUriView,
- "amount-error": LoadingInfoView,
+ error: ErrorAlertView,
"no-exchange": NoExchangesView,
"selecting-exchange": ExchangeSelectionPage,
success: SuccessView,
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
index d1853442b..18c467aae 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
@@ -23,7 +23,9 @@ import {
} from "@gnu-taler/taler-util";
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useState } from "preact/hooks";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { useSelectedExchange } from "../../hooks/useSelectedExchange.js";
import { RecursiveState } from "../../utils/index.js";
@@ -35,6 +37,7 @@ export function useComponentStateFromParams({
onSuccess,
}: PropsFromParams): RecursiveState {
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
const uriInfoHook = useAsyncAsHook(async () => {
const exchanges = await api.wallet.call(
WalletApiOperation.ListExchanges,
@@ -47,8 +50,11 @@ export function useComponentStateFromParams({
if (uriInfoHook.hasError) {
return {
- status: "uri-error",
- error: uriInfoHook,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load the list of exchanges`,
+ uriInfoHook,
+ ),
};
}
@@ -95,6 +101,7 @@ export function useComponentStateFromURI({
onSuccess,
}: PropsFromURI): RecursiveState {
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
/**
* Ask the wallet about the withdraw URI
*/
@@ -123,8 +130,11 @@ export function useComponentStateFromURI({
if (uriInfoHook.hasError) {
return {
- status: "uri-error",
- error: uriInfoHook,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load info from URI`,
+ uriInfoHook,
+ ),
};
}
@@ -194,6 +204,7 @@ function exchangeSelectionState(
}
return () => {
+ const { i18n } = useTranslationContext();
const [ageRestricted, setAgeRestricted] = useState(0);
const currentExchange = selectedExchange.selected;
const tosNeedToBeAccepted =
@@ -255,8 +266,11 @@ function exchangeSelectionState(
}
if (amountHook.hasError) {
return {
- status: "amount-error",
- error: amountHook,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load the withdrawal details`,
+ amountHook,
+ ),
};
}
if (!amountHook.response) {
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts
index 3277ac18d..2caa50dca 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts
@@ -84,11 +84,11 @@ describe("Withdraw CTA states", () => {
expect(status).equals("loading");
},
({ status, error }) => {
- if (status != "uri-error") expect.fail();
+ if (status != "error") expect.fail();
if (!error) expect.fail();
- if (!error.hasError) expect.fail();
- if (error.operational) expect.fail();
- expect(error.message).eq("ERROR_NO-URI-FOR-WITHDRAWAL");
+ // if (!error.hasError) expect.fail();
+ // if (error.operational) expect.fail();
+ expect(error.cause?.message).eq("ERROR_NO-URI-FOR-WITHDRAWAL");
},
],
TestingContext,
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
index 9dbe24b7e..cf87b35bb 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
@@ -19,16 +19,10 @@ import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
import { Amount } from "../../components/Amount.js";
import { ErrorTalerOperation } from "../../components/ErrorTalerOperation.js";
-import { LoadingError } from "../../components/LoadingError.js";
import { Part } from "../../components/Part.js";
import { QR } from "../../components/QR.js";
import { SelectList } from "../../components/SelectList.js";
-import {
- Input,
- Link,
- LinkSuccess,
- SvgIcon,
-} from "../../components/styled/index.js";
+import { Input, LinkSuccess, SvgIcon } from "../../components/styled/index.js";
import { TermsOfService } from "../../components/TermsOfService/index.js";
import { useTranslationContext } from "../../context/translation.js";
import { Button } from "../../mui/Button.js";
@@ -36,30 +30,6 @@ import editIcon from "../../svg/edit_24px.svg";
import { ExchangeDetails, WithdrawDetails } from "../../wallet/Transaction.js";
import { State } from "./index.js";
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not get the info from the URI
- }
- error={error}
- />
- );
-}
-
-export function LoadingInfoView({ error }: State.LoadingInfoError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not get info of withdrawal}
- error={error}
- />
- );
-}
-
export function SuccessView(state: State.Success): VNode {
const { i18n } = useTranslationContext();
const currentTosVersionIsAccepted =
@@ -68,11 +38,7 @@ export function SuccessView(state: State.Success): VNode {
{state.doWithdrawal.error && (
- Could not finish the withdrawal operation
-
- }
+ title={i18n.str`Could not finish the withdrawal operation`}
error={state.doWithdrawal.error.errorDetail}
/>
)}
@@ -103,7 +69,7 @@ export function SuccessView(state: State.Success): VNode {
big
/>
Details}
+ title={i18n.str`Details`}
text={
Age restriction}
+ label={i18n.str`Age restriction`}
list={state.ageRestriction.list}
name="age"
value={state.ageRestriction.value}
@@ -148,11 +114,6 @@ export function SuccessView(state: State.Success): VNode {
{state.talerWithdrawUri ? (
) : undefined}
-
);
}
@@ -168,11 +129,7 @@ function WithdrawWithMobile({
return (
setShowQR((qr) => !qr)}>
- {!showQR ? (
- Withdraw to a mobile phone
- ) : (
- Hide QR
- )}
+ {!showQR ? i18n.str`Withdraw to a mobile phone` : i18n.str`Hide QR`}
{showQR && (
diff --git a/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts b/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts
index 1b2929317..978ea90e1 100644
--- a/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts
@@ -16,6 +16,7 @@
import { TalerErrorDetail } from "@gnu-taler/taler-util";
import { TalerError } from "@gnu-taler/taler-wallet-core";
import { useEffect, useMemo, useState } from "preact/hooks";
+import { WalletError } from "../wxApi.js";
export interface HookOk
{
hasError: false;
@@ -26,13 +27,14 @@ export type HookError = HookGenericError | HookOperationalError;
export interface HookGenericError {
hasError: true;
- operational: false;
+ type: "error";
message: string;
}
export interface HookOperationalError {
hasError: true;
- operational: true;
+ type: "taler";
+ message: string;
details: TalerErrorDetail;
}
@@ -68,13 +70,21 @@ export function useAsyncAsHook(
if (e instanceof TalerError) {
setHookResponse({
hasError: true,
- operational: true,
+ type: "taler",
+ message: e.message,
details: e.errorDetail,
});
+ } else if (e instanceof WalletError) {
+ setHookResponse({
+ hasError: true,
+ type: "taler",
+ message: e.message,
+ details: e.errorDetail.errorDetail,
+ });
} else if (e instanceof Error) {
setHookResponse({
hasError: true,
- operational: false,
+ type: "error",
message: e.message,
});
}
diff --git a/packages/taler-wallet-webextension/src/hooks/useLang.ts b/packages/taler-wallet-webextension/src/hooks/useLang.ts
index 269fe6239..b1aa40015 100644
--- a/packages/taler-wallet-webextension/src/hooks/useLang.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useLang.ts
@@ -17,6 +17,7 @@
import { useNotNullLocalStorage } from "./useLocalStorage.js";
function getBrowserLang(): string | undefined {
+ if (typeof window === "undefined") return undefined;
if (window.navigator.languages) return window.navigator.languages[0];
if (window.navigator.language) return window.navigator.language;
return undefined;
diff --git a/packages/taler-wallet-webextension/src/hooks/useLocalStorage.ts b/packages/taler-wallet-webextension/src/hooks/useLocalStorage.ts
index 88b7655b6..387798c96 100644
--- a/packages/taler-wallet-webextension/src/hooks/useLocalStorage.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useLocalStorage.ts
@@ -75,6 +75,9 @@ export function useNotNullLocalStorage(
}
};
- const isSaved = window.localStorage.getItem(key) !== null;
+ const isSaved =
+ typeof window === "undefined"
+ ? false
+ : window.localStorage.getItem(key) !== null;
return [storedValue, setValue, isSaved];
}
diff --git a/packages/taler-wallet-webextension/src/mui/Alert.stories.tsx b/packages/taler-wallet-webextension/src/mui/Alert.stories.tsx
index 62f7a2993..b0c2a2730 100644
--- a/packages/taler-wallet-webextension/src/mui/Alert.stories.tsx
+++ b/packages/taler-wallet-webextension/src/mui/Alert.stories.tsx
@@ -19,6 +19,7 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
+import { TranslatedString } from "@gnu-taler/taler-util";
import { css } from "@linaria/core";
import { ComponentChildren, Fragment, h, VNode } from "preact";
import { Alert } from "./Alert.jsx";
@@ -53,16 +54,16 @@ export const BasicExample = (): VNode => (
export const WithTitle = (): VNode => (
-
+
this is an warning
-
+
this is an error
-
+
this is an success
-
+
this is an info
@@ -74,16 +75,32 @@ const showSomething = async function (): Promise {
export const WithAction = (): VNode => (
-
+
this is an warning
-
+
this is an error
-
+
this is an success
-
+
this is an info
diff --git a/packages/taler-wallet-webextension/src/mui/Alert.tsx b/packages/taler-wallet-webextension/src/mui/Alert.tsx
index 360c3c3cb..b00312a86 100644
--- a/packages/taler-wallet-webextension/src/mui/Alert.tsx
+++ b/packages/taler-wallet-webextension/src/mui/Alert.tsx
@@ -13,6 +13,7 @@
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
+import { TranslatedString } from "@gnu-taler/taler-util";
import { css } from "@linaria/core";
import { ComponentChildren, h, VNode } from "preact";
// eslint-disable-next-line import/extensions
@@ -61,7 +62,7 @@ const colorVariant = {
};
interface Props {
- title?: string;
+ title?: TranslatedString;
variant?: "filled" | "outlined" | "standard";
role?: string;
onClose?: () => Promise;
@@ -110,20 +111,20 @@ function Message({
title,
children,
}: {
- title?: string;
+ title?: TranslatedString;
children: ComponentChildren;
}): VNode {
return (
{title && (
@@ -160,6 +161,7 @@ export function Alert({
"--color-main": theme.palette[severity].main,
"--color-light": theme.palette[severity].light,
// ...(style as any),
+ textAlign: "left",
}}
elevation={1}
>
diff --git a/packages/taler-wallet-webextension/src/mui/Paper.tsx b/packages/taler-wallet-webextension/src/mui/Paper.tsx
index 3b5f24bc1..0c805e307 100644
--- a/packages/taler-wallet-webextension/src/mui/Paper.tsx
+++ b/packages/taler-wallet-webextension/src/mui/Paper.tsx
@@ -29,9 +29,6 @@ const borderVariant = {
`,
};
const baseStyle = css`
- background-color: ${theme.palette.background.paper};
- color: ${theme.palette.text.primary};
-
.theme-dark & {
background-image: var(--gradient-white-elevation);
}
diff --git a/packages/taler-wallet-webextension/src/mui/colors/manipulation.ts b/packages/taler-wallet-webextension/src/mui/colors/manipulation.ts
index 226d3c860..f9bf9eb2b 100644
--- a/packages/taler-wallet-webextension/src/mui/colors/manipulation.ts
+++ b/packages/taler-wallet-webextension/src/mui/colors/manipulation.ts
@@ -57,7 +57,7 @@ export function hexToRgb(color: string): string {
let colors = color.match(re);
if (colors && colors[0].length === 1) {
- colors = colors.map((n) => n + n);
+ colors = colors.map((n) => n + n) as RegExpMatchArray;
}
return colors
diff --git a/packages/taler-wallet-webextension/src/platform/api.ts b/packages/taler-wallet-webextension/src/platform/api.ts
index cd09f6438..40993477b 100644
--- a/packages/taler-wallet-webextension/src/platform/api.ts
+++ b/packages/taler-wallet-webextension/src/platform/api.ts
@@ -146,9 +146,9 @@ export interface BackgroundPlatformAPI {
*/
getPermissionsApi(): CrossBrowserPermissionsApi;
/**
- * Used by the wallet backend to send notification about new information
- * @param message
- */
+ * Used by the wallet backend to send notification about new information
+ * @param message
+ */
sendMessageToAllChannels(message: MessageFromBackend): void;
/**
@@ -196,7 +196,6 @@ export interface ForegroundPlatformAPI {
*/
openWalletURIFromPopup(talerUri: string): void;
-
/**
* Popup API
*
@@ -248,5 +247,4 @@ export interface ForegroundPlatformAPI {
listenToWalletBackground(
listener: (message: MessageFromBackend) => void,
): () => void;
-
}
diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts b/packages/taler-wallet-webextension/src/platform/chrome.ts
index e5efdec4e..fc51a65fb 100644
--- a/packages/taler-wallet-webextension/src/platform/chrome.ts
+++ b/packages/taler-wallet-webextension/src/platform/chrome.ts
@@ -14,17 +14,17 @@
GNU Taler; see the file COPYING. If not, see
*/
-import {
- classifyTalerUri, Logger,
- TalerUriType
-} from "@gnu-taler/taler-util";
+import { classifyTalerUri, Logger, TalerUriType } from "@gnu-taler/taler-util";
import { WalletOperations } from "@gnu-taler/taler-wallet-core";
import { BackgroundOperations } from "../wxApi.js";
import {
- BackgroundPlatformAPI, CrossBrowserPermissionsApi, ForegroundPlatformAPI, MessageFromBackend,
+ BackgroundPlatformAPI,
+ CrossBrowserPermissionsApi,
+ ForegroundPlatformAPI,
+ MessageFromBackend,
MessageFromFrontend,
MessageResponse,
- Permissions
+ Permissions,
} from "./api.js";
const api: BackgroundPlatformAPI & ForegroundPlatformAPI = {
@@ -306,13 +306,12 @@ function openWalletPageFromPopup(page: string): void {
});
}
-
let nextMessageIndex = 0;
/**
* To be used by the foreground
- * @param message
- * @returns
+ * @param message
+ * @returns
*/
async function sendMessageToBackground<
Op extends WalletOperations | BackgroundOperations,
@@ -321,13 +320,13 @@ async function sendMessageToBackground<
return new Promise((resolve, reject) => {
logger.trace("send operation to the wallet background", message);
- let timedout = false
+ let timedout = false;
setTimeout(() => {
- timedout = true
- reject("timedout")
+ timedout = true;
+ reject("timedout");
}, 2000);
chrome.runtime.sendMessage(messageWithId, (backgroundResponse) => {
- if (timedout) return false
+ if (timedout) return false;
if (chrome.runtime.lastError) {
reject(chrome.runtime.lastError.message);
} else {
@@ -358,7 +357,6 @@ function listenToWalletBackground(listener: (m: any) => void): () => void {
const allPorts: chrome.runtime.Port[] = [];
-
function sendMessageToAllChannels(message: MessageFromBackend): void {
for (const notif of allPorts) {
// const message: MessageFromBackend = { type: msg.type };
@@ -578,26 +576,26 @@ function setAlertedIcon(): void {
interface OffscreenCanvasRenderingContext2D
extends CanvasState,
- CanvasTransform,
- CanvasCompositing,
- CanvasImageSmoothing,
- CanvasFillStrokeStyles,
- CanvasShadowStyles,
- CanvasFilters,
- CanvasRect,
- CanvasDrawPath,
- CanvasUserInterface,
- CanvasText,
- CanvasDrawImage,
- CanvasImageData,
- CanvasPathDrawingStyles,
- CanvasTextDrawingStyles,
- CanvasPath {
+ CanvasTransform,
+ CanvasCompositing,
+ CanvasImageSmoothing,
+ CanvasFillStrokeStyles,
+ CanvasShadowStyles,
+ CanvasFilters,
+ CanvasRect,
+ CanvasDrawPath,
+ CanvasUserInterface,
+ CanvasText,
+ CanvasDrawImage,
+ CanvasImageData,
+ CanvasPathDrawingStyles,
+ CanvasTextDrawingStyles,
+ CanvasPath {
readonly canvas: OffscreenCanvas;
}
declare const OffscreenCanvasRenderingContext2D: {
prototype: OffscreenCanvasRenderingContext2D;
- new(): OffscreenCanvasRenderingContext2D;
+ new (): OffscreenCanvasRenderingContext2D;
};
interface OffscreenCanvas extends EventTarget {
@@ -610,7 +608,7 @@ interface OffscreenCanvas extends EventTarget {
}
declare const OffscreenCanvas: {
prototype: OffscreenCanvas;
- new(width: number, height: number): OffscreenCanvas;
+ new (width: number, height: number): OffscreenCanvas;
};
function createCanvas(size: number): OffscreenCanvas {
diff --git a/packages/taler-wallet-webextension/src/platform/firefox.ts b/packages/taler-wallet-webextension/src/platform/firefox.ts
index a36859a0b..7f6980be7 100644
--- a/packages/taler-wallet-webextension/src/platform/firefox.ts
+++ b/packages/taler-wallet-webextension/src/platform/firefox.ts
@@ -14,7 +14,12 @@
GNU Taler; see the file COPYING. If not, see
*/
-import { BackgroundPlatformAPI, CrossBrowserPermissionsApi, ForegroundPlatformAPI, Permissions } from "./api.js";
+import {
+ BackgroundPlatformAPI,
+ CrossBrowserPermissionsApi,
+ ForegroundPlatformAPI,
+ Permissions,
+} from "./api.js";
import chromePlatform, {
containsHostPermissions as chromeHostContains,
removeHostPermissions as chromeHostRemove,
diff --git a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
index 8786b2ff7..96f0f6dd9 100644
--- a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
+++ b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
@@ -19,12 +19,13 @@ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { Fragment, h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks";
import { BalanceTable } from "../components/BalanceTable.js";
+import { ErrorAlertView } from "../components/CurrentAlerts.js";
import { Loading } from "../components/Loading.js";
-import { LoadingError } from "../components/LoadingError.js";
import { MultiActionButton } from "../components/MultiActionButton.js";
+import { alertFromError, ErrorAlert } from "../context/alert.js";
import { useBackendContext } from "../context/backend.js";
import { useTranslationContext } from "../context/translation.js";
-import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
+import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
import { Button } from "../mui/Button.js";
import { ButtonHandler } from "../mui/handlers.js";
import { compose, StateViewMap } from "../utils/index.js";
@@ -47,7 +48,7 @@ export namespace State {
export interface Error {
status: "error";
- error: HookError;
+ error: ErrorAlert;
}
export interface Action {
@@ -73,6 +74,7 @@ function useComponentState({
goToWalletManualWithdraw,
}: Props): State {
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
const [addingAction, setAddingAction] = useState(false);
const state = useAsyncAsHook(() =>
api.wallet.call(WalletApiOperation.GetBalances, {}),
@@ -94,7 +96,7 @@ function useComponentState({
if (state.hasError) {
return {
status: "error",
- error: state,
+ error: alertFromError(i18n.str`Could not load the balance`, state),
};
}
if (addingAction) {
@@ -123,7 +125,7 @@ function useComponentState({
const viewMapping: StateViewMap = {
loading: Loading,
- error: ErrorView,
+ error: ErrorAlertView,
action: ActionView,
balance: BalanceView,
};
@@ -134,16 +136,6 @@ export const BalancePage = compose(
viewMapping,
);
-function ErrorView({ error }: State.Error): VNode {
- const { i18n } = useTranslationContext();
- return (
- Could not load balance page}
- error={error}
- />
- );
-}
-
function ActionView({ cancel }: State.Action): VNode {
return ;
}
@@ -179,7 +171,7 @@ export function BalanceView(state: State.Balances): VNode {
{currencyWithNonZeroAmount.length > 0 && (
Send {s} }
+ label={(s) => i18n.str`Send ${s}`}
actions={currencyWithNonZeroAmount}
onClick={(c) => state.goToWalletDeposit(c)}
/>
diff --git a/packages/taler-wallet-webextension/src/popup/NoBalanceHelp.tsx b/packages/taler-wallet-webextension/src/popup/NoBalanceHelp.tsx
index 7d2e15726..5eb31ba46 100644
--- a/packages/taler-wallet-webextension/src/popup/NoBalanceHelp.tsx
+++ b/packages/taler-wallet-webextension/src/popup/NoBalanceHelp.tsx
@@ -33,7 +33,7 @@ export function NoBalanceHelp({
const { i18n } = useTranslationContext();
return (
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/taler-wallet-webextension/src/test-utils.ts b/packages/taler-wallet-webextension/src/test-utils.ts
index 379513782..7e7ddd88d 100644
--- a/packages/taler-wallet-webextension/src/test-utils.ts
+++ b/packages/taler-wallet-webextension/src/test-utils.ts
@@ -32,6 +32,7 @@ import {
} from "preact";
import { render as renderToString } from "preact-render-to-string";
import { BackendProvider } from "./context/backend.js";
+import { TranslationProvider } from "./context/translation.js";
import { BackgroundApiClient, wxApi } from "./wxApi.js";
// When doing tests we want the requestAnimationFrame to be as fast as possible.
@@ -359,10 +360,12 @@ export function createWalletApiMock(): {
};
function TestingContext({
- children,
+ children: _cs,
}: {
children: ComponentChildren;
}): VNode {
+ let children = _cs;
+ children = create(TranslationProvider, { children }, children);
return create(
BackendProvider,
{
diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts
index 10fcd84ce..4ec4c0ffe 100644
--- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/index.ts
@@ -16,8 +16,9 @@
import { TalerErrorDetail } from "@gnu-taler/taler-util";
import { SyncTermsOfServiceResponse } from "@gnu-taler/taler-wallet-core";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import {
ButtonHandler,
TextFieldHandler,
@@ -25,11 +26,7 @@ import {
} from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import {
- ConfirmProviderView,
- LoadingUriView,
- SelectProviderView,
-} from "./views.js";
+import { ConfirmProviderView, SelectProviderView } from "./views.js";
export interface Props {
onBack: () => Promise;
@@ -50,8 +47,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-error";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface ConfirmProvider {
@@ -77,7 +74,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-error": LoadingUriView,
+ error: ErrorAlertView,
"select-provider": SelectProviderView,
"confirm-provider": ConfirmProviderView,
};
diff --git a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/views.tsx b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/views.tsx
index b633a595f..c3afc0d33 100644
--- a/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/views.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/AddBackupProvider/views.tsx
@@ -17,12 +17,10 @@
import { Amounts } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { Checkbox } from "../../components/Checkbox.js";
-import { LoadingError } from "../../components/LoadingError.js";
import {
LightText,
SmallLightText,
SubTitle,
- TermsOfService,
Title,
} from "../../components/styled/index.js";
import { useTranslationContext } from "../../context/translation.js";
@@ -30,17 +28,6 @@ import { Button } from "../../mui/Button.js";
import { TextField } from "../../mui/TextField.js";
import { State } from "./index.js";
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load}
- error={error}
- />
- );
-}
-
export function ConfirmProviderView({
url,
provider,
@@ -88,9 +75,8 @@ export function ConfirmProviderView({
of service
- {/* replace with */}
Accept terms of service}
+ label={i18n.str`Accept terms of service`}
name="terms"
onToggle={tos.button.onClick}
enabled={tos.value}
diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx
index 372db847c..46fe02225 100644
--- a/packages/taler-wallet-webextension/src/wallet/Application.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx
@@ -25,13 +25,17 @@ import { createHashHistory } from "history";
import { ComponentChildren, Fragment, h, VNode } from "preact";
import Router, { route, Route } from "preact-router";
import { useEffect } from "preact/hooks";
+import { CurrentAlerts } from "../components/CurrentAlerts.js";
import { LogoHeader } from "../components/LogoHeader.js";
import PendingTransactions from "../components/PendingTransactions.js";
import {
+ Link,
+ LinkPrimary,
SubTitle,
WalletAction,
WalletBox,
} from "../components/styled/index.js";
+import { AlertProvider } from "../context/alert.js";
import { DevContextProvider } from "../context/devContext.js";
import { IoCProviderForRuntime } from "../context/iocContext.js";
import {
@@ -66,6 +70,7 @@ import { QrReaderPage } from "./QrReader.js";
import { SettingsPage } from "./Settings.js";
import { TransactionPage } from "./Transaction.js";
import { WelcomePage } from "./Welcome.js";
+import CloseIcon from "../svg/close_24px.svg";
export function Application(): VNode {
const { i18n } = useTranslationContext();
@@ -495,15 +500,6 @@ function matchesRoute(url: string, route: string): boolean {
return !result ? false : true;
}
-function shouldShowPendingOperations(url: string): boolean {
- return [
- Pages.balanceHistory.pattern,
- Pages.dev,
- Pages.settings,
- Pages.backup,
- ].some((p) => matchesRoute(url, p));
-}
-
function CallToActionTemplate({
title,
children,
@@ -511,11 +507,35 @@ function CallToActionTemplate({
title: TranslatedString;
children: ComponentChildren;
}): VNode {
+ const { i18n } = useTranslationContext();
return (
+
{title}
- {children}
+
+
+ {children}
+
+
);
}
@@ -536,7 +556,10 @@ function WalletTemplate({
{goToTransaction ? (
) : undefined}
- {children}
+
+
+ {children}
+
);
}
diff --git a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
index 6e987f965..48c9c9cb1 100644
--- a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
@@ -29,8 +29,8 @@ import {
} from "date-fns";
import { Fragment, h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks";
+import { AlertView } from "../components/CurrentAlerts.js";
import { Loading } from "../components/Loading.js";
-import { LoadingError } from "../components/LoadingError.js";
import { QR } from "../components/QR.js";
import {
BoldLight,
@@ -42,6 +42,7 @@ import {
SmallText,
WarningBox,
} from "../components/styled/index.js";
+import { alertFromError } from "../context/alert.js";
import { useBackendContext } from "../context/backend.js";
import { useTranslationContext } from "../context/translation.js";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
@@ -117,9 +118,11 @@ export function BackupPage({ onAddProvider }: Props): VNode {
}
if (status.hasError) {
return (
- Could not load backup providers}
- error={status}
+
);
}
@@ -219,11 +222,9 @@ export function BackupView({
- {providers.length > 1 ? (
- Sync all backups
- ) : (
- Sync now
- )}
+ {providers.length > 1
+ ? i18n.str`Sync all backups`
+ : i18n.str`Sync now`}
Add provider
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
index 6ffbccc27..6de406400 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
@@ -15,8 +15,9 @@
*/
import { AmountJson, PaytoUri } from "@gnu-taler/taler-util";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import {
AmountFieldHandler,
ButtonHandler,
@@ -27,7 +28,6 @@ import { ManageAccountPage } from "../ManageAccount/index.js";
import { useComponentState } from "./state.js";
import {
AmountOrCurrencyErrorView,
- LoadingErrorView,
NoAccountToDepositView,
NoEnoughBalanceView,
ReadyView,
@@ -56,8 +56,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-error";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface AddingAccount {
@@ -107,7 +107,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-error": LoadingErrorView,
+ error: ErrorAlertView,
"amount-or-currency-error": AmountOrCurrencyErrorView,
"no-enough-balance": NoEnoughBalanceView,
"no-accounts": NoAccountToDepositView,
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
index 02e85a1c7..b597c77be 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
@@ -25,7 +25,9 @@ import {
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useState } from "preact/hooks";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { Props, State } from "./index.js";
@@ -36,6 +38,7 @@ export function useComponentState({
onSuccess,
}: Props): State {
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
const parsed = amountStr === undefined ? undefined : Amounts.parse(amountStr);
const currency = parsed !== undefined ? parsed.currency : currencyStr;
@@ -82,8 +85,8 @@ export function useComponentState({
}
if (hook.hasError) {
return {
- status: "loading-error",
- error: hook,
+ status: "error",
+ error: alertFromError(i18n.str`Could not load balance information`, hook),
};
}
const { accounts, balances } = hook.response;
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx
index 6a28f31e1..0d827db43 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx
@@ -18,31 +18,13 @@ import { Amounts, PaytoUri } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
import { AmountField } from "../../components/AmountField.js";
import { ErrorMessage } from "../../components/ErrorMessage.js";
-import { LoadingError } from "../../components/LoadingError.js";
import { SelectList } from "../../components/SelectList.js";
-import {
- ErrorText,
- Input,
- InputWithLabel,
- SubTitle,
- WarningBox,
-} from "../../components/styled/index.js";
+import { Input, SubTitle, WarningBox } from "../../components/styled/index.js";
import { useTranslationContext } from "../../context/translation.js";
import { Button } from "../../mui/Button.js";
import { Grid } from "../../mui/Grid.js";
import { State } from "./index.js";
-export function LoadingErrorView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load deposit balance}
- error={error}
- />
- );
-}
-
export function AmountOrCurrencyErrorView(
p: State.AmountOrCurrencyError,
): VNode {
@@ -50,11 +32,7 @@ export function AmountOrCurrencyErrorView(
return (
- A currency or an amount should be indicated
-
- }
+ title={i18n.str`A currency or an amount should be indicated`}
/>
);
}
@@ -66,11 +44,7 @@ export function NoEnoughBalanceView({
return (
- There is no enough balance to make a deposit for currency {currency}
-
- }
+ title={i18n.str`There is no enough balance to make a deposit for currency ${currency}`}
/>
);
}
@@ -150,7 +124,7 @@ export function ReadyView(state: State.Ready): VNode {
>
Select account}
+ label={i18n.str`Select account`}
list={state.account.list}
name="account"
value={state.account.value}
@@ -171,14 +145,11 @@ export function ReadyView(state: State.Ready): VNode {
- Amount}
- handler={state.amount}
- />
+
Deposit fee}
+ label={i18n.str`Deposit fee`}
handler={{
value: state.totalFee,
}}
@@ -186,7 +157,7 @@ export function ReadyView(state: State.Ready): VNode {
Total deposit}
+ label={i18n.str`Total deposit`}
handler={{
value: state.totalToDeposit,
}}
diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts
index f1e766a18..bd6b32e78 100644
--- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts
@@ -14,12 +14,13 @@
GNU Taler; see the file COPYING. If not, see
*/
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { AmountFieldHandler, ButtonHandler } from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import { LoadingUriView, ReadyView, SelectCurrencyView } from "./views.js";
+import { ReadyView, SelectCurrencyView } from "./views.js";
export type Props = PropsGet | PropsSend;
@@ -49,8 +50,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-error";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface SelectCurrency {
@@ -80,7 +81,7 @@ export type Contact = {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-error": LoadingUriView,
+ error: ErrorAlertView,
"select-currency": SelectCurrencyView,
ready: ReadyView,
};
diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts
index dd711f406..1fe324c5a 100644
--- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts
@@ -17,7 +17,9 @@
import { Amounts } from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useState } from "preact/hooks";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { assertUnreachable, RecursiveState } from "../../utils/index.js";
import { Contact, Props, State } from "./index.js";
@@ -58,6 +60,8 @@ export function useComponentState(props: Props): RecursiveState {
if (!amount) {
return () => {
+ // eslint-disable-next-line react-hooks/rules-of-hooks
+ const { i18n } = useTranslationContext();
// eslint-disable-next-line react-hooks/rules-of-hooks
const hook = useAsyncAsHook(() =>
api.wallet.call(WalletApiOperation.ListExchanges, {}),
@@ -71,8 +75,8 @@ export function useComponentState(props: Props): RecursiveState {
}
if (hook.hasError) {
return {
- status: "loading-error",
- error: hook,
+ status: "error",
+ error: alertFromError(i18n.str`Could not load exchanges`, hook),
};
}
const currencies: Record = {};
diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx
index a9a4b2e41..8a7a1fa97 100644
--- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx
@@ -16,7 +16,7 @@
import { styled } from "@linaria/react";
import { Fragment, h, VNode } from "preact";
-import { LoadingError } from "../../components/LoadingError.js";
+import { AmountField } from "../../components/AmountField.js";
import { SelectList } from "../../components/SelectList.js";
import {
Input,
@@ -25,24 +25,14 @@ import {
SvgIcon,
} from "../../components/styled/index.js";
import { useTranslationContext } from "../../context/translation.js";
-import { Pages } from "../../NavigationBar.js";
-import { Contact, State } from "./index.js";
-import arrowIcon from "../../svg/chevron-down.svg";
-import { AmountField } from "../../components/AmountField.js";
+import { Button } from "../../mui/Button.js";
import { Grid } from "../../mui/Grid.js";
import { Paper } from "../../mui/Paper.js";
-import { Button } from "../../mui/Button.js";
+import { Pages } from "../../NavigationBar.js";
+import arrowIcon from "../../svg/chevron-down.svg";
+import bankIcon from "../../svg/ri-bank-line.svg";
import { assertUnreachable } from "../../utils/index.js";
-
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
- return (
- Could not load}
- error={error}
- />
- );
-}
+import { Contact, State } from "./index.js";
export function SelectCurrencyView({
currencies,
@@ -61,7 +51,7 @@ export function SelectCurrencyView({
Known currencies}
+ label={i18n.str`Known currencies`}
list={currencies}
name="lang"
value={""}
@@ -214,7 +204,7 @@ export function ReadyGetView({
Amount}
+ label={i18n.str`Amount`}
required
handler={amountHandler}
/>
@@ -304,7 +294,7 @@ export function ReadySendView({
Amount}
+ label={i18n.str`Amount`}
required
handler={amountHandler}
/>
@@ -377,7 +367,6 @@ export function ReadySendView({
);
}
-import bankIcon from "../../svg/ri-bank-line.svg";
function RowExample({
info,
diff --git a/packages/taler-wallet-webextension/src/wallet/EmptyComponentExample/index.ts b/packages/taler-wallet-webextension/src/wallet/EmptyComponentExample/index.ts
index 95badb218..afbaf1945 100644
--- a/packages/taler-wallet-webextension/src/wallet/EmptyComponentExample/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/EmptyComponentExample/index.ts
@@ -14,11 +14,12 @@
GNU Taler; see the file COPYING. If not, see
*/
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import { LoadingUriView, ReadyView } from "./views.js";
+import { ReadyView } from "./views.js";
export interface Props {
p: string;
@@ -33,8 +34,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-error";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface BaseInfo {
@@ -48,7 +49,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-error": LoadingUriView,
+ error: ErrorAlertView,
ready: ReadyView,
};
diff --git a/packages/taler-wallet-webextension/src/wallet/EmptyComponentExample/views.tsx b/packages/taler-wallet-webextension/src/wallet/EmptyComponentExample/views.tsx
index 5784a7db5..dc8a42b84 100644
--- a/packages/taler-wallet-webextension/src/wallet/EmptyComponentExample/views.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/EmptyComponentExample/views.tsx
@@ -15,21 +15,9 @@
*/
import { h, VNode } from "preact";
-import { LoadingError } from "../../components/LoadingError.js";
import { useTranslationContext } from "../../context/translation.js";
import { State } from "./index.js";
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load}
- error={error}
- />
- );
-}
-
export function ReadyView({ error }: State.Ready): VNode {
const { i18n } = useTranslationContext();
diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts
index 10e44ce7d..299c236c4 100644
--- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts
@@ -20,7 +20,9 @@ import {
ExchangeListItem,
FeeDescriptionPair,
} from "@gnu-taler/taler-util";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
+import { ErrorAlert } from "../../context/alert.js";
import { HookError } from "../../hooks/useAsyncAsHook.js";
import { State as SelectExchangeState } from "../../hooks/useSelectedExchange.js";
import { ButtonHandler, SelectFieldHandler } from "../../mui/handlers.js";
@@ -28,7 +30,6 @@ import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
import {
ComparingView,
- ErrorLoadingView,
NoExchangesView,
PrivacyContentView,
ReadyView,
@@ -58,8 +59,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "error-loading";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface BaseInfo {
@@ -99,7 +100,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "error-loading": ErrorLoadingView,
+ error: ErrorAlertView,
comparing: ComparingView,
"no-exchange": NoExchangesView,
"showing-tos": TosContentView,
diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts
index 3c10febd9..cfb32cbbb 100644
--- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts
@@ -20,7 +20,9 @@ import {
WalletApiOperation,
} from "@gnu-taler/taler-wallet-core";
import { useState } from "preact/hooks";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { Props, State } from "./index.js";
@@ -31,6 +33,7 @@ export function useComponentState({
currentExchange,
}: Props): State {
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
const initialValue = exchanges.findIndex(
(e) => e.exchangeBaseUrl === currentExchange,
);
@@ -84,8 +87,11 @@ export function useComponentState({
}
if (hook.hasError) {
return {
- status: "error-loading",
- error: hook,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load exchange details info`,
+ hook,
+ ),
};
}
diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/views.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/views.tsx
index 26ff2c0d3..d01ce7ca0 100644
--- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/views.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/views.tsx
@@ -20,7 +20,6 @@ import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
import { Amount } from "../../components/Amount.js";
import { ErrorMessage } from "../../components/ErrorMessage.js";
-import { LoadingError } from "../../components/LoadingError.js";
import { SelectList } from "../../components/SelectList.js";
import { Input, SvgIcon } from "../../components/styled/index.js";
import { TermsOfService } from "../../components/TermsOfService/index.js";
@@ -110,17 +109,6 @@ const Container = styled.div`
}
`;
-export function ErrorLoadingView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load exchange fees}
- error={error}
- />
- );
-}
-
export function PrivacyContentView({
exchangeUrl,
onClose,
@@ -156,19 +144,11 @@ export function NoExchangesView({
}: SelectExchangeState.NoExchange): VNode {
const { i18n } = useTranslationContext();
if (!currency) {
- return (
- Could not find any exchange}
- />
- );
+ return ;
}
return (
- Could not find any exchange for the currency {currency}
-
- }
+ title={i18n.str`Could not find any exchange for the currency ${currency}`}
/>
);
}
diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx
index 8c31d8d95..404fc8bee 100644
--- a/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx
@@ -140,15 +140,13 @@ export function ExchangeSetUrlPage({
)}
{error && (
Unable to verify this exchange
- }
+ title={i18n.str`Unable to verify this exchange`}
description={error}
/>
)}
{confirmationError && (
Unable to add this exchange}
+ title={i18n.str`Unable to add this exchange`}
description={confirmationError}
/>
)}
diff --git a/packages/taler-wallet-webextension/src/wallet/History.tsx b/packages/taler-wallet-webextension/src/wallet/History.tsx
index 50f634f52..143d3adbb 100644
--- a/packages/taler-wallet-webextension/src/wallet/History.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/History.tsx
@@ -23,8 +23,8 @@ import {
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { Fragment, h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks";
+import { AlertView } from "../components/CurrentAlerts.js";
import { Loading } from "../components/Loading.js";
-import { LoadingError } from "../components/LoadingError.js";
import {
CenteredBoldText,
CenteredText,
@@ -33,6 +33,7 @@ import {
} from "../components/styled/index.js";
import { Time } from "../components/Time.js";
import { TransactionItem } from "../components/TransactionItem.js";
+import { alertFromError } from "../context/alert.js";
import { useBackendContext } from "../context/backend.js";
import { useTranslationContext } from "../context/translation.js";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
@@ -71,13 +72,11 @@ export function HistoryPage({
if (state.hasError) {
return (
-
- Could not load the list of transactions
-
- }
- error={state}
+
);
}
diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/index.ts b/packages/taler-wallet-webextension/src/wallet/ManageAccount/index.ts
index 8541821b7..3a00d48ce 100644
--- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/index.ts
@@ -15,8 +15,9 @@
*/
import { KnownBankAccountsInfo } from "@gnu-taler/taler-util";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import {
ButtonHandler,
SelectFieldHandler,
@@ -24,7 +25,7 @@ import {
} from "../../mui/handlers.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import { LoadingUriView, ReadyView } from "./views.js";
+import { ReadyView } from "./views.js";
export interface Props {
currency: string;
@@ -41,8 +42,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-error";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface BaseInfo {
@@ -68,7 +69,7 @@ export type AccountByType = {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-error": LoadingUriView,
+ error: ErrorAlertView,
ready: ReadyView,
};
diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts b/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts
index 9690a5c79..176a8d100 100644
--- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/state.ts
@@ -21,7 +21,9 @@ import {
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useState } from "preact/hooks";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { AccountByType, Props, State } from "./index.js";
@@ -31,6 +33,7 @@ export function useComponentState({
onCancel,
}: Props): State {
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
const hook = useAsyncAsHook(() =>
api.wallet.call(WalletApiOperation.ListKnownBankAccounts, { currency }),
);
@@ -47,8 +50,8 @@ export function useComponentState({
}
if (hook.hasError) {
return {
- status: "loading-error",
- error: hook,
+ status: "error",
+ error: alertFromError(i18n.str`Could not load known bank accounts`, hook),
};
}
diff --git a/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx b/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx
index 3af0d5505..e5be8d17d 100644
--- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx
@@ -23,11 +23,10 @@ import {
import { styled } from "@linaria/react";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
-import { LoadingError } from "../../components/LoadingError.js";
+import { ErrorMessage } from "../../components/ErrorMessage.js";
import { SelectList } from "../../components/SelectList.js";
import {
Input,
- LightText,
SubTitle,
SvgIcon,
WarningText,
@@ -37,10 +36,9 @@ import { Button } from "../../mui/Button.js";
import { TextFieldHandler } from "../../mui/handlers.js";
import { TextField } from "../../mui/TextField.js";
import checkIcon from "../../svg/check_24px.svg";
-import warningIcon from "../../svg/warning_24px.svg";
import deleteIcon from "../../svg/delete_24px.svg";
+import warningIcon from "../../svg/warning_24px.svg";
import { State } from "./index.js";
-import { ErrorMessage } from "../../components/ErrorMessage.js";
type AccountType = "bitcoin" | "x-taler-bank" | "iban";
type ComponentFormByAccountType = {
@@ -80,17 +78,6 @@ const AccountTable = styled.table`
}
`;
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load}
- error={error}
- />
- );
-}
-
export function ReadyView({
currency,
error,
@@ -118,14 +105,14 @@ export function ReadyView({
{error && (
Unable add this account}
+ title={i18n.str`Unable add this account`}
description={error}
/>
)}
Select account type}
+ label={i18n.str`Select account type`}
list={accountType.list}
name="accountType"
value={accountType.value}
diff --git a/packages/taler-wallet-webextension/src/wallet/Notifications/index.ts b/packages/taler-wallet-webextension/src/wallet/Notifications/index.ts
index 4697ca549..22b3adb0f 100644
--- a/packages/taler-wallet-webextension/src/wallet/Notifications/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/Notifications/index.ts
@@ -15,11 +15,12 @@
*/
import { UserAttentionUnreadList } from "@gnu-taler/taler-util";
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
+import { ErrorAlert } from "../../context/alert.js";
import { compose, StateViewMap } from "../../utils/index.js";
import { useComponentState } from "./state.js";
-import { LoadingUriView, ReadyView } from "./views.js";
+import { ReadyView } from "./views.js";
export type Props = object;
@@ -32,8 +33,8 @@ export namespace State {
}
export interface LoadingUriError {
- status: "loading-error";
- error: HookError;
+ status: "error";
+ error: ErrorAlert;
}
export interface BaseInfo {
@@ -49,7 +50,7 @@ export namespace State {
const viewMapping: StateViewMap = {
loading: Loading,
- "loading-error": LoadingUriView,
+ error: ErrorAlertView,
ready: ReadyView,
};
diff --git a/packages/taler-wallet-webextension/src/wallet/Notifications/state.ts b/packages/taler-wallet-webextension/src/wallet/Notifications/state.ts
index 648e490ce..0e06a1e75 100644
--- a/packages/taler-wallet-webextension/src/wallet/Notifications/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/Notifications/state.ts
@@ -15,12 +15,15 @@
*/
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import { alertFromError } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
+import { useTranslationContext } from "../../context/translation.js";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { Props, State } from "./index.js";
export function useComponentState(p: Props): State {
const api = useBackendContext();
+ const { i18n } = useTranslationContext();
const hook = useAsyncAsHook(async () => {
return await api.wallet.call(
WalletApiOperation.GetUserAttentionRequests,
@@ -34,10 +37,14 @@ export function useComponentState(p: Props): State {
error: undefined,
};
}
+
if (hook.hasError) {
return {
- status: "loading-error",
- error: hook,
+ status: "error",
+ error: alertFromError(
+ i18n.str`Could not load user attention request`,
+ hook,
+ ),
};
}
diff --git a/packages/taler-wallet-webextension/src/wallet/Notifications/views.tsx b/packages/taler-wallet-webextension/src/wallet/Notifications/views.tsx
index 9146d8837..8d0bb34c0 100644
--- a/packages/taler-wallet-webextension/src/wallet/Notifications/views.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Notifications/views.tsx
@@ -20,7 +20,6 @@ import {
AttentionType,
} from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";
-import { LoadingError } from "../../components/LoadingError.js";
import {
Column,
DateSeparator,
@@ -37,17 +36,6 @@ import { Pages } from "../../NavigationBar.js";
import { assertUnreachable } from "../../utils/index.js";
import { State } from "./index.js";
-export function LoadingUriView({ error }: State.LoadingUriError): VNode {
- const { i18n } = useTranslationContext();
-
- return (
- Could not load notifications}
- error={error}
- />
- );
-}
-
const term = 1000 * 60 * 60 * 24;
function normalizeToDay(x: number): number {
return Math.round(x / term) * term;
diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx
index eb86c9a3f..286a2a88d 100644
--- a/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx
@@ -127,11 +127,7 @@ export function SetUrlView({
{error && (
- Could not get provider information
-
- }
+ title={i18n.str`Could not get provider information`}
description={error}
/>
)}
@@ -223,7 +219,7 @@ export function ConfirmProviderView({
{Amounts.isZero(provider.annual_fee) ? (
- free of charge
+ i18n.str`free of charge`
) : (
{provider.annual_fee} per year of service
@@ -240,7 +236,7 @@ export function ConfirmProviderView({
Accept terms of service}
+ label={i18n.str`Accept terms of service`}
name="terms"
onToggle={async () => setAccepted((old) => !old)}
enabled={accepted}
diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx
index 46d54e871..9b72c0fae 100644
--- a/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ProviderDetailPage.tsx
@@ -23,11 +23,12 @@ import {
WalletApiOperation,
} from "@gnu-taler/taler-wallet-core";
import { Fragment, h, VNode } from "preact";
+import { AlertView } from "../components/CurrentAlerts.js";
import { ErrorMessage } from "../components/ErrorMessage.js";
import { Loading } from "../components/Loading.js";
-import { LoadingError } from "../components/LoadingError.js";
import { PaymentStatus, SmallLightText } from "../components/styled/index.js";
import { Time } from "../components/Time.js";
+import { alertFromError } from "../context/alert.js";
import { useBackendContext } from "../context/backend.js";
import { useTranslationContext } from "../context/translation.js";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
@@ -65,14 +66,11 @@ export function ProviderDetailPage({
}
if (state.hasError) {
return (
-
- There was an error loading the provider detail for "
- {providerURL}"
-
- }
- error={state}
+
);
}
@@ -270,9 +268,7 @@ function Error({ info }: { info: ProviderInfo }): VNode {
if (info.lastError) {
return (
This provider has reported an error
- }
+ title={i18n.str`This provider has reported an error`}
description={info.lastError.hint}
/>
);
@@ -282,32 +278,17 @@ function Error({ info }: { info: ProviderInfo }): VNode {
case "backup-conflicting-device":
return (
-
- There is conflict with another backup from{" "}
- {info.backupProblem.otherDeviceId}
-
-
- }
+ title={i18n.str`There is conflict with another backup from "${info.backupProblem.otherDeviceId}"`}
/>
);
case "backup-unreadable":
- return (
- Backup is not readable}
- />
- );
+ return ;
default:
return (
-
- Unknown backup problem: {JSON.stringify(info.backupProblem)}
-
-
- }
+ title={i18n.str`Unknown backup problem: ${JSON.stringify(
+ info.backupProblem,
+ )}`}
/>
);
}
diff --git a/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx
index a259f7c9a..c366f014f 100644
--- a/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx
@@ -42,8 +42,8 @@ export function ReserveCreated({
if (!paytoURI) {
return (
Could not parse the payto URI}
- description={Please check the uri }
+ title={i18n.str`Could not parse the payto URI`}
+ description={i18n.str`Please check the uri`}
/>
);
}
diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.tsx
index 768a4ca6a..ed1bc838a 100644
--- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx
@@ -111,13 +111,13 @@ export function SettingsView({
{autoOpenToggle.button.error && (
Could not toggle auto-open}
+ title={i18n.str`Could not toggle auto-open`}
error={autoOpenToggle.button.error.errorDetail}
/>
)}
{/* {clipboardToggle.button.error && (
Could not toggle clipboard}
+ title={i18n.str`Could not toggle clipboard`}
error={clipboardToggle.button.error.errorDetail}
/>
)} */}
@@ -125,11 +125,7 @@ export function SettingsView({
Navigator
- Automatically open wallet based on page content
-
- }
+ label={i18n.str`Automatically open wallet based on page content`}
name="autoOpen"
description={
@@ -142,9 +138,7 @@ export function SettingsView({
/>
{/*
- Automatically check clipboard for Taler URI
-
+ i18n.str`Automatically check clipboard for Taler URI`
}
name="clipboard"
description={
@@ -241,13 +235,9 @@ export function SettingsView({
Troubleshooting
Developer mode}
+ label={i18n.str`Developer mode`}
name="devMode"
- description={
-
- More options and information useful for debugging
-
- }
+ description={i18n.str`More options and information useful for debugging`}
enabled={devModeToggle.value!}
onToggle={devModeToggle.button.onClick!}
/>
@@ -271,7 +261,7 @@ export function SettingsView({
{coreVersion && (
Wallet Core}
+ title={i18n.str`Wallet Core`}
text={
{coreVersion.version}{" "}
@@ -281,7 +271,7 @@ export function SettingsView({
/>
)}
Web Extension}
+ title={i18n.str`Web Extension`}
text={
{webexVersion.version}{" "}
@@ -292,15 +282,15 @@ export function SettingsView({
{coreVersion && (
Exchange compatibility}
+ title={i18n.str`Exchange compatibility`}
text={{coreVersion.exchange} }
/>
Merchant compatibility}
+ title={i18n.str`Merchant compatibility`}
text={{coreVersion.merchant} }
/>
Bank compatibility}
+ title={i18n.str`Bank compatibility`}
text={{coreVersion.bank} }
/>
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
index b7eb4a947..542694490 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
@@ -32,6 +32,7 @@ import {
TransactionRefund,
TransactionTip,
TransactionType,
+ TranslatedString,
WithdrawalType,
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
@@ -43,9 +44,8 @@ import emptyImg from "../../static/img/empty.png";
import { Amount } from "../components/Amount.js";
import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType.js";
import { CopyButton } from "../components/CopyButton.js";
-import { ErrorTalerOperation } from "../components/ErrorTalerOperation.js";
+import { AlertView, ErrorAlertView } from "../components/CurrentAlerts.js";
import { Loading } from "../components/Loading.js";
-import { LoadingError } from "../components/LoadingError.js";
import { Kind, Part, PartCollapsible, PartPayto } from "../components/Part.js";
import { QR } from "../components/QR.js";
import { ShowFullContractTermPopup } from "../components/ShowFullContractTermPopup.js";
@@ -60,6 +60,7 @@ import {
WarningBox,
} from "../components/styled/index.js";
import { Time } from "../components/Time.js";
+import { alertFromError } from "../context/alert.js";
import { useBackendContext } from "../context/backend.js";
import { useTranslationContext } from "../context/translation.js";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
@@ -98,13 +99,11 @@ export function TransactionPage({
if (state.hasError) {
return (
-
- Could not load the transaction information
-
- }
- error={state}
+
);
}
@@ -199,14 +198,14 @@ export function TransactionView({
return (
-
- There was an error trying to complete the transaction
-
- }
- error={transaction?.error}
- />
+ {transaction?.error ? (
+
+ ) : undefined}
{transaction.pending && (
This transaction is not completed
@@ -367,7 +366,7 @@ export function TransactionView({
)}
Details}
+ title={i18n.str`Details`}
text={
{transaction.refunds.length > 0 ? (
Refunds}
+ title={i18n.str`Refunds`}
text={
{transaction.refunds.map((r, i) => {
@@ -462,7 +461,7 @@ export function TransactionView({
picked up.
Offer}
+ title={i18n.str`Offer`}
text={ }
kind="positive"
/>
@@ -480,17 +479,17 @@ export function TransactionView({
)}
Merchant}
+ title={i18n.str`Merchant`}
text={ }
kind="neutral"
/>
Invoice ID}
- text={transaction.info.orderId}
+ title={i18n.str`Invoice ID`}
+ text={transaction.info.orderId as TranslatedString}
kind="neutral"
/>
Details}
+ title={i18n.str`Details`}
text={
{payto && }
Details}
+ title={i18n.str`Details`}
text={ }
kind="neutral"
/>
Wire transfer deadline}
+ title={i18n.str`Wire transfer deadline`}
text={
Details}
+ title={i18n.str`Details`}
text={ }
/>
@@ -578,12 +577,12 @@ export function TransactionView({
{transaction.merchantBaseUrl}
{/* Merchant}
+ title={i18n.str`Merchant`}
text={ }
kind="neutral"
/> */}
Details}
+ title={i18n.str`Details`}
text={ }
/>
@@ -604,12 +603,12 @@ export function TransactionView({
Merchant}
- text={transaction.info.merchant.name}
+ title={i18n.str`Merchant`}
+ text={transaction.info.merchant.name as TranslatedString}
kind="neutral"
/>
Original order ID}
+ title={i18n.str`Original order ID`}
text={
Purchase summary}
- text={transaction.info.summary}
+ title={i18n.str`Purchase summary`}
+ text={transaction.info.summary as TranslatedString}
kind="neutral"
/>
Details}
+ title={i18n.str`Details`}
text={ }
/>
@@ -683,25 +682,25 @@ export function TransactionView({
{transaction.info.summary ? (
Subject}
- text={transaction.info.summary}
+ title={i18n.str`Subject`}
+ text={transaction.info.summary as TranslatedString}
kind="neutral"
/>
) : undefined}
Exchange}
- text={transaction.exchangeBaseUrl}
+ title={i18n.str`Exchange`}
+ text={transaction.exchangeBaseUrl as TranslatedString}
kind="neutral"
/>
{transaction.pending /** pending is not-pay */ && (
URI}
+ title={i18n.str`URI`}
text={ }
kind="neutral"
/>
)}
Details}
+ title={i18n.str`Details`}
text={
Subject}
- text={transaction.info.summary}
+ title={i18n.str`Subject`}
+ text={transaction.info.summary as TranslatedString}
kind="neutral"
/>
) : undefined}
Exchange}
- text={transaction.exchangeBaseUrl}
+ title={i18n.str`Exchange`}
+ text={transaction.exchangeBaseUrl as TranslatedString}
kind="neutral"
/>
Details}
+ title={i18n.str`Details`}
text={
Subject}
- text={transaction.info.summary}
+ title={i18n.str`Subject`}
+ text={transaction.info.summary as TranslatedString}
kind="neutral"
/>
) : undefined}
Exchange}
- text={transaction.exchangeBaseUrl}
+ title={i18n.str`Exchange`}
+ text={transaction.exchangeBaseUrl as TranslatedString}
kind="neutral"
/>
{/* {transaction.pending && ( //pending is not-received
)} */}
URI}
+ title={i18n.str`URI`}
text={ }
kind="neutral"
/>
Details}
+ title={i18n.str`Details`}
text={
Subject}
- text={transaction.info.summary}
+ title={i18n.str`Subject`}
+ text={transaction.info.summary as TranslatedString}
kind="neutral"
/>
) : undefined}
Exchange}
- text={transaction.exchangeBaseUrl}
+ title={i18n.str`Exchange`}
+ text={transaction.exchangeBaseUrl as TranslatedString}
kind="neutral"
/>
Details}
+ title={i18n.str`Details`}
text={
Products}
+ title={i18n.str`Products`}
text={
{info.products?.map((p, k) => (
@@ -1274,7 +1273,7 @@ export function PurchaseDetails({
Delivery}
+ title={i18n.str`Delivery`}
text={
Permissions
- Automatically open wallet based on page content
-
- }
+ label={i18n.str`Automatically open wallet based on page content`}
name="perm"
description={
diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts
index 5c2a577b3..a41372e37 100644
--- a/packages/taler-wallet-webextension/src/wxApi.ts
+++ b/packages/taler-wallet-webextension/src/wxApi.ts
@@ -25,6 +25,8 @@ import {
CoreApiResponse,
Logger,
NotificationType,
+ TalerErrorCode,
+ TalerErrorDetail,
WalletDiagnostics,
} from "@gnu-taler/taler-util";
import {
@@ -33,11 +35,14 @@ import {
WalletCoreOpKeys,
WalletCoreRequestType,
WalletCoreResponseType,
+ WalletOperations,
} from "@gnu-taler/taler-wallet-core";
-import { MessageFromBackend, MessageFromFrontendBackground, MessageFromFrontendWallet } from "./platform/api.js";
import {
- platform,
-} from "./platform/foreground.js";
+ MessageFromBackend,
+ MessageFromFrontendBackground,
+ MessageFromFrontendWallet,
+} from "./platform/api.js";
+import { platform } from "./platform/foreground.js";
/**
*
@@ -88,6 +93,25 @@ export interface BackgroundApiClient {
): Promise;
}
+export class WalletError extends Error {
+ public errorDetail: TalerError;
+
+ constructor(op: string, e: TalerError) {
+ super(`Wallet operation "${op}" failed: ${e.message}`);
+ this.errorDetail = e;
+ // Object.setPrototypeOf(this, WalletError.prototype);
+ }
+}
+export class BackgroundError extends Error {
+ public errorDetail: TalerErrorDetail;
+
+ constructor(op: string, e: TalerErrorDetail) {
+ super(`Background operation "${op}" failed: ${e.message}`);
+ this.errorDetail = e;
+ // Object.setPrototypeOf(this, BackgroundError.prototype);
+ }
+}
+
/**
* BackgroundApiClient integration with browser platform
*/
@@ -106,13 +130,18 @@ class BackgroundApiClientImpl implements BackgroundApiClient {
try {
response = await platform.sendMessageToBackground(message);
- } catch (e) {
+ } catch (error) {
console.log("Error calling backend");
- throw new Error(`Error contacting backend: ${e}`);
+ if (error instanceof Error) {
+ throw new BackgroundError(operation, {
+ code: TalerErrorCode.GENERIC_UNEXPECTED_REQUEST_ERROR,
+ });
+ }
+ throw error;
}
logger.info("got response", response);
if (response.type === "error") {
- throw TalerError.fromUncheckedDetail(response.error);
+ throw new BackgroundError(operation, response.error);
}
return response.result as any;
}
@@ -140,7 +169,8 @@ class WalletApiClientImpl implements WalletCoreApiClient {
}
logger.info("got response", response);
if (response.type === "error") {
- throw TalerError.fromUncheckedDetail(response.error);
+ const error = TalerError.fromUncheckedDetail(response.error);
+ throw new WalletError(operation, error);
}
return response.result as any;
}
diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts
index b75e92004..c7b964c28 100644
--- a/packages/taler-wallet-webextension/src/wxBackend.ts
+++ b/packages/taler-wallet-webextension/src/wxBackend.ts
@@ -46,9 +46,7 @@ import {
WalletStoresV1,
} from "@gnu-taler/taler-wallet-core";
import { BrowserHttpLib } from "./browserHttpLib.js";
-import {
- platform,
-} from "./platform/background.js";
+import { platform } from "./platform/background.js";
import {
MessageFromBackend,
MessageFromFrontend,
@@ -199,13 +197,22 @@ async function dispatch(
),
};
}
- const result = await handler(req.payload);
- return {
- type: "response",
- id: req.id,
- operation: String(req.operation),
- result,
- };
+ try {
+ const result = await handler(req.payload);
+ return {
+ type: "response",
+ id: req.id,
+ operation: String(req.operation),
+ result,
+ };
+ } catch (er) {
+ return {
+ type: "error",
+ id: req.id,
+ error: getErrorDetailFromException(er),
+ operation: String(req.operation),
+ };
+ }
}
if (req.channel === "wallet") {
@@ -232,7 +239,9 @@ async function dispatch(
id: anyReq.id,
operation: String(anyReq.operation),
error: getErrorDetailFromException(
- Error(`unknown channel ${anyReq.channel}`),
+ Error(
+ `unknown channel ${anyReq.channel}, should be "background" or "wallet"`,
+ ),
),
};
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6983ba177..0355f1535 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -649,7 +649,7 @@ importers:
qrcode-generator: ^1.4.4
rimraf: ^3.0.2
tslib: ^2.4.0
- typescript: ^4.8.4
+ typescript: 4.9.4
dependencies:
'@gnu-taler/taler-util': link:../taler-util
'@gnu-taler/taler-wallet-core': link:../taler-wallet-core
@@ -687,7 +687,7 @@ importers:
preact-cli: 3.4.1_i2jslynuqxjzp37vlc24guk7gu
preact-render-to-string: 5.2.6_preact@10.11.3
rimraf: 3.0.2
- typescript: 4.8.4
+ typescript: 4.9.4
packages/web-util:
specifiers:
@@ -8412,7 +8412,7 @@ packages:
minipass-pipeline: 1.2.4
mkdirp: 1.0.4
p-map: 4.0.0
- promise-inflight: 1.0.1
+ promise-inflight: 1.0.1_bluebird@3.7.2
rimraf: 3.0.2
ssri: 8.0.1
tar: 6.1.11
@@ -18096,15 +18096,6 @@ packages:
engines: {node: '>=0.4.0'}
dev: true
- /promise-inflight/1.0.1:
- resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
- peerDependencies:
- bluebird: '*'
- peerDependenciesMeta:
- bluebird:
- optional: true
- dev: true
-
/promise-inflight/1.0.1_bluebird@3.7.2:
resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
peerDependencies:
@@ -20691,6 +20682,12 @@ packages:
hasBin: true
dev: true
+ /typescript/4.9.4:
+ resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==}
+ engines: {node: '>=4.2.0'}
+ hasBin: true
+ dev: true
+
/uglify-js/3.17.4:
resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
engines: {node: '>=0.8.0'}