diff options
author | Sebastian <sebasjm@gmail.com> | 2023-01-09 08:38:48 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-01-09 08:38:48 -0300 |
commit | 9b04d8bf3581d162cbd631892ca115df811c46f8 (patch) | |
tree | 42b7da7cc3a3f8186823a7571aa221dc8e9aa7a5 /packages/taler-wallet-webextension/src/context/alert.ts | |
parent | 14f3d1e06dda003d457f2b3531e197011a284244 (diff) | |
download | wallet-core-9b04d8bf3581d162cbd631892ca115df811c46f8.tar.xz |
fix #7152
Diffstat (limited to 'packages/taler-wallet-webextension/src/context/alert.ts')
-rw-r--r-- | packages/taler-wallet-webextension/src/context/alert.ts | 118 |
1 files changed, 118 insertions, 0 deletions
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 <http://www.gnu.org/licenses/> + */ + +/** + * + * @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<Type>(initial); + +type AlertWithDate = Alert & { since: Date }; + +type Props = Partial<Type> & { + children: ComponentChildren; +}; + +export const AlertProvider = ({ children }: Props): VNode => { + const timeout = 3000; + + const [alerts, setAlerts] = useState<AlertWithDate[]>([]); + + 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, + }; +} |