openOutpaint/js/lib/notifications.js
Victor Seiji Hariki 995478c662 custom alerts and notifications
Adds custom notifications and dialog boxes. prompt() calls still not
updated

Signed-off-by: Victor Seiji Hariki <victorseijih@gmail.com>
2023-02-14 23:45:24 -03:00

180 lines
4.7 KiB
JavaScript

/**
* Enum representing the location of the notifications
* @readonly
* @enum {string}
*/
const NotificationLocation = {
TOPLEFT: "top-left",
TOPCENTER: "top-center",
TOPRIGHT: "top-right",
BOTTOMLEFT: "bottom-left",
BOTTOMCENTER: "bottom-center",
BOTTOMRIGHT: "bottom-right",
};
/**
* Enum representing notification types
* @readonly
* @enum {string}
*/
const NotificationType = {
INFO: "info",
ERROR: "error",
WARN: "warn",
SUCCESS: "success",
};
/**
* Responsible for the notification system
*/
const notifications = {
/** @type {NotificationLocation} */
_location: NotificationLocation.BOTTOMLEFT,
/** @type {NotificationLocation} */
get location() {
return this.location;
},
/** @type {NotificationLocation} */
set location(location) {
this._location = location;
},
// Notification Area Element
_areaEl: null,
// Dialog BG Element
_dialogBGEl: null,
// Dialog Element
_dialogEl: null,
/**
* Creates a simple notification for the user. Equivalent to alert()
*
* @param {string | HTMLElement} message Message to display to the user.
* @param {Object} options Extra options for the notification.
* @param {NotificationType} type Notification type
*/
notify(message, options = {}) {
defaultOpt(options, {
type: NotificationType.INFO,
timeout: config.notificationTimeout,
});
const notificationEl = document.createElement("div");
notificationEl.classList.add("notification", "expanded", options.type);
notificationEl.title = new Date().toISOString();
notificationEl.addEventListener("click", () =>
notificationEl.classList.toggle("expanded")
);
const contentEl = document.createElement("div");
contentEl.classList.add("notification-content");
contentEl.innerHTML = message;
notificationEl.append(contentEl);
const closeBtn = document.createElement("button");
closeBtn.classList.add("notification-closebtn");
closeBtn.addEventListener("click", () => notificationEl.remove());
notificationEl.append(closeBtn);
this._areaEl.prepend(notificationEl);
if (options.timeout)
setTimeout(() => {
if (this._areaEl.contains(notificationEl)) {
notificationEl.remove();
}
}, options.timeout);
},
/**
* Creates a dialog box for the user with set options.
*
* @param {string} title The title of the dialog box to be displayed to the user.
* @param {string | HTMLElement} message The message to be displayed to the user.
* @param {Object} options Extra options for the dialog.
* @param {Array<{label: string, value: any}>} options.choices The choices to be displayed to the user.
*/
async dialog(title, message, options = {}) {
defaultOpt(options, {
// By default, it is a await notifications.dialogation dialog
choices: [
{label: "No", value: false},
{label: "Yes", value: true},
],
});
const titleEl = this._dialogEl.querySelector(".dialog-title");
titleEl.textContent = title;
const contentEl = this._dialogEl.querySelector(".dialog-content");
contentEl.innerHTML = message;
const choicesEl = this._dialogEl.querySelector(".dialog-choices");
while (choicesEl.firstChild) {
choicesEl.firstChild.remove();
}
return new Promise((resolve, reject) => {
options.choices.forEach((choice) => {
const choiceBtn = document.createElement("button");
choiceBtn.textContent = choice.label;
choiceBtn.addEventListener("click", () => {
this._dialogBGEl.style.display = "none";
this._dialogEl.style.display = "none";
resolve(choice.value);
});
choicesEl.append(choiceBtn);
});
this._dialogBGEl.style.display = "flex";
this._dialogEl.style.display = "block";
});
},
};
var k = 0;
window.addEventListener("DOMContentLoaded", () => {
// Creates the notification area
const notificationArea = document.createElement("div");
notificationArea.classList.add(
"notification-area",
NotificationLocation.BOTTOMLEFT
);
notifications._areaEl = notificationArea;
document.body.appendChild(notificationArea);
// Creates the dialog box element
const dialogBG = document.createElement("div");
dialogBG.classList.add("dialog-bg");
dialogBG.style.display = "none";
const dialogEl = document.createElement("div");
dialogEl.classList.add("dialog");
dialogEl.style.display = "none";
const titleEl = document.createElement("div");
titleEl.classList.add("dialog-title");
const contentEl = document.createElement("div");
contentEl.classList.add("dialog-content");
const choicesEl = document.createElement("div");
choicesEl.classList.add("dialog-choices");
dialogEl.append(titleEl);
dialogEl.append(contentEl);
dialogEl.append(choicesEl);
dialogBG.append(dialogEl);
notifications._dialogEl = dialogEl;
notifications._dialogBGEl = dialogBG;
document.body.appendChild(dialogBG);
});