summaryrefslogtreecommitdiff
path: root/packages/web-util/src/hooks/useNotifications.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/web-util/src/hooks/useNotifications.ts')
-rw-r--r--packages/web-util/src/hooks/useNotifications.ts68
1 files changed, 55 insertions, 13 deletions
diff --git a/packages/web-util/src/hooks/useNotifications.ts b/packages/web-util/src/hooks/useNotifications.ts
index 000abbc94..99f4f2699 100644
--- a/packages/web-util/src/hooks/useNotifications.ts
+++ b/packages/web-util/src/hooks/useNotifications.ts
@@ -1,4 +1,5 @@
import {
+ AbsoluteTime,
Duration,
OperationFail,
OperationOk,
@@ -20,12 +21,18 @@ export type NotificationMessage = ErrorNotification | InfoNotification;
export interface ErrorNotification {
type: "error";
title: TranslatedString;
+ ack?: boolean;
+ timeout?: boolean;
description?: TranslatedString;
debug?: any;
+ when: AbsoluteTime;
}
export interface InfoNotification {
type: "info";
title: TranslatedString;
+ ack?: boolean;
+ timeout?: boolean;
+ when: AbsoluteTime;
}
const storage = memoryMap<Map<string, NotificationMessage>>();
@@ -35,11 +42,11 @@ export const GLOBAL_NOTIFICATION_TIMEOUT = Duration.fromSpec({
seconds: 5,
});
-function removeFromStorage(n: NotificationMessage) {
+function updateInStorage(n: NotificationMessage) {
const h = hash(n);
const mem = storage.get(NOTIFICATION_KEY) ?? new Map();
const newState = new Map(mem);
- newState.delete(h);
+ newState.set(h, n);
storage.set(NOTIFICATION_KEY, newState);
}
@@ -50,7 +57,8 @@ export function notify(notif: NotificationMessage): void {
if (GLOBAL_NOTIFICATION_TIMEOUT.d_ms !== "forever") {
setTimeout(() => {
- removeFromStorage(notif);
+ notif.timeout = true;
+ updateInStorage(notif);
}, GLOBAL_NOTIFICATION_TIMEOUT.d_ms);
}
@@ -66,6 +74,7 @@ export function notifyError(
title,
description,
debug,
+ when: AbsoluteTime.now(),
});
}
export function notifyException(title: TranslatedString, ex: Error) {
@@ -74,34 +83,40 @@ export function notifyException(title: TranslatedString, ex: Error) {
title,
description: ex.message as TranslatedString,
debug: ex.stack,
+ when: AbsoluteTime.now(),
});
}
export function notifyInfo(title: TranslatedString) {
notify({
type: "info" as const,
title,
+ when: AbsoluteTime.now(),
});
}
export type Notification = {
message: NotificationMessage;
- remove: () => void;
+ acknowledge: () => void;
};
export function useNotifications(): Notification[] {
- const [value, setter] = useState<Map<string, NotificationMessage>>(new Map());
+ const [, setLastUpdate] = useState<number>();
+ const value = storage.get(NOTIFICATION_KEY) ?? new Map();
+
useEffect(() => {
return storage.onUpdate(NOTIFICATION_KEY, () => {
- const mem = storage.get(NOTIFICATION_KEY) ?? new Map();
- setter(structuredClone(mem));
+ setLastUpdate(Date.now())
+ // const mem = storage.get(NOTIFICATION_KEY) ?? new Map();
+ // setter(structuredClone(mem));
});
});
return Array.from(value.values()).map((message, idx) => {
return {
message,
- remove: () => {
- removeFromStorage(message);
+ acknowledge: () => {
+ message.ack = true;
+ updateInStorage(message);
},
};
});
@@ -141,6 +156,7 @@ function errorMap<T extends OperationFail<unknown>>(
title: map(resp.case),
description: resp.detail.hint as TranslatedString,
debug: resp.detail,
+ when: AbsoluteTime.now(),
});
}
@@ -165,7 +181,7 @@ export function useLocalNotification(): [
? undefined
: {
message: value,
- remove: () => {
+ acknowledge: () => {
setter(undefined);
},
};
@@ -175,7 +191,7 @@ export function useLocalNotification(): [
return await cb(errorMap);
} catch (error: unknown) {
if (error instanceof TalerError) {
- notify(buildRequestErrorMessage(i18n, error));
+ notify(buildUnifiedRequestErrorMessage(i18n, error));
} else {
notifyError(
i18n.str`Operation failed, please report`,
@@ -212,7 +228,7 @@ export function useLocalNotificationHandler(): [
? undefined
: {
message: value,
- remove: () => {
+ acknowledge: () => {
setter(undefined);
},
};
@@ -241,18 +257,39 @@ export function useLocalNotificationHandler(): [
return [notif, makeHandler, setter];
}
-export function buildRequestErrorMessage(
+export function buildUnifiedRequestErrorMessage(
i18n: InternationalizationAPI,
cause: TalerError,
): ErrorNotification {
let result: ErrorNotification;
switch (cause.errorDetail.code) {
+ case TalerErrorCode.GENERIC_TIMEOUT: {
+ result = {
+ type: "error",
+ title: i18n.str`Request timeout`,
+ description: cause.message as TranslatedString,
+ debug: JSON.stringify(cause.errorDetail, undefined, 2),
+ when: AbsoluteTime.now(),
+ };
+ break;
+ }
+ case TalerErrorCode.GENERIC_CLIENT_INTERNAL_ERROR: {
+ result = {
+ type: "error",
+ title: i18n.str`Request cancelled`,
+ description: cause.message as TranslatedString,
+ debug: JSON.stringify(cause.errorDetail, undefined, 2),
+ when: AbsoluteTime.now(),
+ };
+ break;
+ }
case TalerErrorCode.WALLET_HTTP_REQUEST_GENERIC_TIMEOUT: {
result = {
type: "error",
title: i18n.str`Request timeout`,
description: cause.message as TranslatedString,
debug: JSON.stringify(cause.errorDetail, undefined, 2),
+ when: AbsoluteTime.now(),
};
break;
}
@@ -262,6 +299,7 @@ export function buildRequestErrorMessage(
title: i18n.str`Request throttled`,
description: cause.message as TranslatedString,
debug: JSON.stringify(cause.errorDetail, undefined, 2),
+ when: AbsoluteTime.now(),
};
break;
}
@@ -271,6 +309,7 @@ export function buildRequestErrorMessage(
title: i18n.str`Malformed response`,
description: cause.message as TranslatedString,
debug: JSON.stringify(cause.errorDetail, undefined, 2),
+ when: AbsoluteTime.now(),
};
break;
}
@@ -280,6 +319,7 @@ export function buildRequestErrorMessage(
title: i18n.str`Network error`,
description: cause.message as TranslatedString,
debug: JSON.stringify(cause.errorDetail, undefined, 2),
+ when: AbsoluteTime.now(),
};
break;
}
@@ -289,6 +329,7 @@ export function buildRequestErrorMessage(
title: i18n.str`Unexpected request error`,
description: cause.message as TranslatedString,
debug: JSON.stringify(cause.errorDetail, undefined, 2),
+ when: AbsoluteTime.now(),
};
break;
}
@@ -298,6 +339,7 @@ export function buildRequestErrorMessage(
title: i18n.str`Unexpected error`,
description: cause.message as TranslatedString,
debug: JSON.stringify(cause.errorDetail, undefined, 2),
+ when: AbsoluteTime.now(),
};
break;
}