summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2024-03-07 09:24:23 +0100
committerFlorian Dold <florian@dold.me>2024-03-07 09:24:23 +0100
commit8eb3e505be967afde0053d5a392e8c6877d8f1dd (patch)
treec3f85273be9749fa8ecaaa0d3efab0cad1040fd3
parent574010b6e35ea8c654e83b4566366c86207f632f (diff)
downloadwallet-core-8eb3e505be967afde0053d5a392e8c6877d8f1dd.tar.gz
wallet-core-8eb3e505be967afde0053d5a392e8c6877d8f1dd.tar.bz2
wallet-core-8eb3e505be967afde0053d5a392e8c6877d8f1dd.zip
bank SPA: increase notification timeout to two minutes
-rw-r--r--packages/web-util/src/hooks/useNotifications.ts133
1 files changed, 90 insertions, 43 deletions
diff --git a/packages/web-util/src/hooks/useNotifications.ts b/packages/web-util/src/hooks/useNotifications.ts
index 9f955f92d..d8a927461 100644
--- a/packages/web-util/src/hooks/useNotifications.ts
+++ b/packages/web-util/src/hooks/useNotifications.ts
@@ -1,7 +1,19 @@
-import { Duration, OperationFail, OperationOk, OperationResult, TalerError, TalerErrorCode, TranslatedString } from "@gnu-taler/taler-util";
+import {
+ Duration,
+ OperationFail,
+ OperationOk,
+ OperationResult,
+ TalerError,
+ TalerErrorCode,
+ TranslatedString,
+} from "@gnu-taler/taler-util";
import { useEffect, useState } from "preact/hooks";
import { ButtonHandler } from "../components/Button.js";
-import { InternationalizationAPI, memoryMap, useTranslationContext } from "../index.browser.js";
+import {
+ InternationalizationAPI,
+ memoryMap,
+ useTranslationContext,
+} from "../index.browser.js";
export type NotificationMessage = ErrorNotification | InfoNotification;
@@ -19,17 +31,18 @@ export interface InfoNotification {
const storage = memoryMap<Map<string, NotificationMessage>>();
const NOTIFICATION_KEY = "notification";
-export const GLOBAL_NOTIFICATION_TIMEOUT: Duration = { d_ms: 3 * 1000 }
+export const GLOBAL_NOTIFICATION_TIMEOUT = Duration.fromSpec({
+ minutes: 2,
+});
function removeFromStorage(n: NotificationMessage) {
- const h = hash(n)
+ const h = hash(n);
const mem = storage.get(NOTIFICATION_KEY) ?? new Map();
const newState = new Map(mem);
newState.delete(h);
storage.set(NOTIFICATION_KEY, newState);
}
-
export function notify(notif: NotificationMessage): void {
const currentState: Map<string, NotificationMessage> =
storage.get(NOTIFICATION_KEY) ?? new Map();
@@ -37,7 +50,7 @@ export function notify(notif: NotificationMessage): void {
if (GLOBAL_NOTIFICATION_TIMEOUT.d_ms !== "forever") {
setTimeout(() => {
- removeFromStorage(notif)
+ removeFromStorage(notif);
}, GLOBAL_NOTIFICATION_TIMEOUT.d_ms);
}
@@ -55,10 +68,7 @@ export function notifyError(
debug,
});
}
-export function notifyException(
- title: TranslatedString,
- ex: Error,
-) {
+export function notifyException(title: TranslatedString, ex: Error) {
notify({
type: "error" as const,
title,
@@ -91,7 +101,7 @@ export function useNotifications(): Notification[] {
return {
message,
remove: () => {
- removeFromStorage(message)
+ removeFromStorage(message);
},
};
});
@@ -122,82 +132,119 @@ function hash(msg: NotificationMessage): string {
return hashCode(str);
}
-function errorMap<T extends OperationFail<unknown>>(resp: T, map: (d: T["case"]) => TranslatedString): void {
+function errorMap<T extends OperationFail<unknown>>(
+ resp: T,
+ map: (d: T["case"]) => TranslatedString,
+): void {
notify({
type: "error",
title: map(resp.case),
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
- })
+ });
}
-export type ErrorNotificationHandler = (cb: (notify: typeof errorMap) => Promise<void>) => Promise<void>;
+export type ErrorNotificationHandler = (
+ cb: (notify: typeof errorMap) => Promise<void>,
+) => Promise<void>;
/**
* @deprecated use useLocalNotificationHandler
- *
- * @returns
+ *
+ * @returns
*/
-export function useLocalNotification(): [Notification | undefined, (n: NotificationMessage) => void, ErrorNotificationHandler] {
+export function useLocalNotification(): [
+ Notification | undefined,
+ (n: NotificationMessage) => void,
+ ErrorNotificationHandler,
+] {
const { i18n } = useTranslationContext();
const [value, setter] = useState<NotificationMessage>();
- const notif = !value ? undefined : {
- message: value,
- remove: () => {
- setter(undefined);
- },
- }
+ const notif = !value
+ ? undefined
+ : {
+ message: value,
+ remove: () => {
+ setter(undefined);
+ },
+ };
async function errorHandling(cb: (notify: typeof errorMap) => Promise<void>) {
try {
- return await cb(errorMap)
+ return await cb(errorMap);
} catch (error: unknown) {
if (error instanceof TalerError) {
- notify(buildRequestErrorMessage(i18n, error))
+ notify(buildRequestErrorMessage(i18n, error));
} else {
notifyError(
i18n.str`Operation failed, please report`,
(error instanceof Error
? error.message
- : JSON.stringify(error)) as TranslatedString
- )
+ : JSON.stringify(error)) as TranslatedString,
+ );
}
-
}
}
- return [notif, setter, errorHandling]
+ return [notif, setter, errorHandling];
}
type HandlerMaker = <T extends OperationResult<A, B>, A, B>(
onClick: () => Promise<T | undefined>,
- onOperationSuccess: ((result: T extends OperationOk<any> ? T : never) => void) | ((result: T extends OperationOk<any> ? T : never) => TranslatedString | undefined),
- onOperationFail: (d: T extends OperationFail<any> ? T : never) => TranslatedString,
+ onOperationSuccess:
+ | ((result: T extends OperationOk<any> ? T : never) => void)
+ | ((
+ result: T extends OperationOk<any> ? T : never,
+ ) => TranslatedString | undefined),
+ onOperationFail: (
+ d: T extends OperationFail<any> ? T : never,
+ ) => TranslatedString,
onOperationComplete?: () => void,
) => ButtonHandler<T, A, B>;
-export function useLocalNotificationHandler(): [Notification | undefined, HandlerMaker, (n: NotificationMessage) => void] {
+export function useLocalNotificationHandler(): [
+ Notification | undefined,
+ HandlerMaker,
+ (n: NotificationMessage) => void,
+] {
const [value, setter] = useState<NotificationMessage>();
- const notif = !value ? undefined : {
- message: value,
- remove: () => {
- setter(undefined);
- },
- }
+ const notif = !value
+ ? undefined
+ : {
+ message: value,
+ remove: () => {
+ setter(undefined);
+ },
+ };
function makeHandler<T extends OperationResult<A, B>, A, B>(
onClick: () => Promise<T | undefined>,
- onOperationSuccess: ((result: T extends OperationOk<any> ? T : never) => void) | ((result: T extends OperationOk<any> ? T : never) => TranslatedString | undefined),
- onOperationFail: (d: T extends OperationFail<any> ? T : never) => TranslatedString,
+ onOperationSuccess:
+ | ((result: T extends OperationOk<any> ? T : never) => void)
+ | ((
+ result: T extends OperationOk<any> ? T : never,
+ ) => TranslatedString | undefined),
+ onOperationFail: (
+ d: T extends OperationFail<any> ? T : never,
+ ) => TranslatedString,
onOperationComplete?: () => void,
): ButtonHandler<T, A, B> {
- return { onClick, onNotification: setter, onOperationFail, onOperationSuccess, onOperationComplete }
+ return {
+ onClick,
+ onNotification: setter,
+ onOperationFail,
+ onOperationSuccess,
+ onOperationComplete,
+ };
}
- return [notif, makeHandler, setter]
+ return [notif, makeHandler, setter];
}
-export function buildRequestErrorMessage(i18n: InternationalizationAPI, cause: TalerError): ErrorNotification {
+export function buildRequestErrorMessage(
+ i18n: InternationalizationAPI,
+ cause: TalerError,
+): ErrorNotification {
let result: ErrorNotification;
switch (cause.errorDetail.code) {
case TalerErrorCode.WALLET_HTTP_REQUEST_GENERIC_TIMEOUT: {