From caa9a22d6970df331eebed032b9a9673d4217fc6 Mon Sep 17 00:00:00 2001
From: Sebastian
Date: Mon, 6 Dec 2021 15:27:20 -0300
Subject: check timeout when doing a query to /keys to add an exchange
---
.../src/wallet/ExchangeSetUrl.tsx | 118 +++++++++++++--------
1 file changed, 74 insertions(+), 44 deletions(-)
(limited to 'packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx')
diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx
index e87a8894f..d529d162b 100644
--- a/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx
@@ -17,52 +17,75 @@ import {
export interface Props {
initialValue?: string;
expectedCurrency?: string;
- knownExchanges: ExchangeListItem[];
onCancel: () => void;
onVerify: (s: string) => Promise;
onConfirm: (url: string) => Promise;
withError?: string;
}
+function useEndpointStatus(
+ endpoint: string,
+ onVerify: (e: string) => Promise,
+): {
+ loading: boolean;
+ error?: string;
+ endpoint: string;
+ result: T | undefined;
+ updateEndpoint: (s: string) => void;
+} {
+ const [value, setValue] = useState(endpoint);
+ const [dirty, setDirty] = useState(false);
+ const [loading, setLoading] = useState(false);
+ const [result, setResult] = useState(undefined);
+ const [error, setError] = useState(undefined);
+
+ const [handler, setHandler] = useState(undefined);
+
+ useEffect(() => {
+ if (!value) return;
+ window.clearTimeout(handler);
+ const h = window.setTimeout(async () => {
+ setDirty(true);
+ setLoading(true);
+ try {
+ const url = canonicalizeBaseUrl(value);
+ const result = await onVerify(url);
+ setResult(result);
+ setError(undefined);
+ setLoading(false);
+ } catch (e) {
+ const errorMessage =
+ e instanceof Error ? e.message : `unknown error: ${e}`;
+ setError(errorMessage);
+ setLoading(false);
+ setResult(undefined);
+ }
+ }, 500);
+ setHandler(h);
+ }, [value]);
+
+ return {
+ error: dirty ? error : undefined,
+ loading: loading,
+ result: result,
+ endpoint: value,
+ updateEndpoint: setValue,
+ };
+}
+
export function ExchangeSetUrlPage({
initialValue,
- knownExchanges,
expectedCurrency,
onCancel,
onVerify,
onConfirm,
- withError,
}: Props) {
- const [value, setValue] = useState(initialValue || "");
- const [dirty, setDirty] = useState(false);
- const [result, setResult] = useState(
- undefined,
- );
- const [error, setError] = useState(withError);
-
- useEffect(() => {
- try {
- const url = canonicalizeBaseUrl(value);
+ const { loading, result, endpoint, updateEndpoint, error } =
+ useEndpointStatus(initialValue ?? "", onVerify);
- const found =
- knownExchanges.findIndex((e) => e.exchangeBaseUrl === url) !== -1;
-
- if (found) {
- setError("This exchange is already known");
- return;
- }
- onVerify(url)
- .then((r) => {
- setResult(r);
- })
- .catch(() => {
- setResult(undefined);
- });
- setDirty(true);
- } catch {
- setResult(undefined);
- }
- }, [value]);
+ const [confirmationError, setConfirmationError] = useState<
+ string | undefined
+ >(undefined);
return (
@@ -72,21 +95,32 @@ export function ExchangeSetUrlPage({
) : (
Add exchange for {expectedCurrency}
)}
+ {result && expectedCurrency && expectedCurrency !== result.currency && (
+
+ This exchange doesn't match the expected currency{" "}
+ {expectedCurrency}
+
+ )}
+
-
+
setValue(e.currentTarget.value)}
+ value={endpoint}
+ onInput={(e) => updateEndpoint(e.currentTarget.value)}
/>
- {result && (
+ {loading &&
loading...
}
+ {result && !loading && (
@@ -100,12 +134,6 @@ export function ExchangeSetUrlPage({
)}
- {result && expectedCurrency && expectedCurrency !== result.currency && (
-
- This exchange doesn't match the expected currency{" "}
- {expectedCurrency}
-
- )}