import { notification } from "antd";
import { ReactElement } from "react";
import {
defaults,
hash_string,
server_seconds_ago,
server_time,
} from "@cocalc/util/misc";
import { webapp_client } from "./webapp-client";
type NotificationType = "error" | "default" | "success" | "info" | "warning";
const default_timeout: { [key: string]: number } = {
error: 9,
default: 6,
success: 5,
info: 7,
};
const last_shown = {};
interface AlertMessageOptions {
type?: NotificationType;
title?: string | ReactElement<any>;
message?: string | ReactElement<any> | Error;
block?: boolean;
timeout?: number;
}
export function alert_message(opts: AlertMessageOptions = {}) {
opts = defaults(opts, {
type: "default",
title: undefined,
message: "",
block: undefined,
timeout: undefined,
});
if (opts.type == null) throw Error("bug");
if (opts.timeout == null) {
let t: number | undefined = default_timeout[opts.type];
if (t == null) {
t = 5;
}
opts.timeout = t;
}
if (opts.message instanceof Error) {
opts.message = `${opts.message}`;
} else if (opts.message === "string") {
const hash = hash_string(opts.message + opts.type);
if (last_shown[hash] >= server_seconds_ago(5)) {
return;
}
last_shown[hash] = server_time();
}
const f =
opts.type == "default" ? notification.open : notification[opts.type];
if (f == null) {
alert(`BUG: Unknown alert_message type ${opts.type}.`);
return;
}
f({
message: opts.title != null ? opts.title : "",
description: stripExcessiveError(opts.message),
duration: opts.block ? 0 : opts.timeout,
});
if (opts.type === "error") {
webapp_client.tracking_client.log_error(opts.message);
}
}
function stripExcessiveError(s) {
if (typeof s != "string") {
return s;
}
s = s.trim();
if (s.startsWith("Error: Error:")) {
s = s.slice("Error: ".length);
}
return s;
}