From 8eb3e505be967afde0053d5a392e8c6877d8f1dd Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 7 Mar 2024 09:24:23 +0100 Subject: bank SPA: increase notification timeout to two minutes --- packages/web-util/src/hooks/useNotifications.ts | 133 ++++++++++++++++-------- 1 file changed, 90 insertions(+), 43 deletions(-) (limited to 'packages/web-util') 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>(); 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 = 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>(resp: T, map: (d: T["case"]) => TranslatedString): void { +function errorMap>( + 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) => Promise; +export type ErrorNotificationHandler = ( + cb: (notify: typeof errorMap) => Promise, +) => Promise; /** * @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(); - 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) { 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 = , A, B>( onClick: () => Promise, - onOperationSuccess: ((result: T extends OperationOk ? T : never) => void) | ((result: T extends OperationOk ? T : never) => TranslatedString | undefined), - onOperationFail: (d: T extends OperationFail ? T : never) => TranslatedString, + onOperationSuccess: + | ((result: T extends OperationOk ? T : never) => void) + | (( + result: T extends OperationOk ? T : never, + ) => TranslatedString | undefined), + onOperationFail: ( + d: T extends OperationFail ? T : never, + ) => TranslatedString, onOperationComplete?: () => void, ) => ButtonHandler; -export function useLocalNotificationHandler(): [Notification | undefined, HandlerMaker, (n: NotificationMessage) => void] { +export function useLocalNotificationHandler(): [ + Notification | undefined, + HandlerMaker, + (n: NotificationMessage) => void, +] { const [value, setter] = useState(); - const notif = !value ? undefined : { - message: value, - remove: () => { - setter(undefined); - }, - } + const notif = !value + ? undefined + : { + message: value, + remove: () => { + setter(undefined); + }, + }; function makeHandler, A, B>( onClick: () => Promise, - onOperationSuccess: ((result: T extends OperationOk ? T : never) => void) | ((result: T extends OperationOk ? T : never) => TranslatedString | undefined), - onOperationFail: (d: T extends OperationFail ? T : never) => TranslatedString, + onOperationSuccess: + | ((result: T extends OperationOk ? T : never) => void) + | (( + result: T extends OperationOk ? T : never, + ) => TranslatedString | undefined), + onOperationFail: ( + d: T extends OperationFail ? T : never, + ) => TranslatedString, onOperationComplete?: () => void, ): ButtonHandler { - 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: { -- cgit v1.2.3