@selenite/graph-editor
Version:
A graph editor for visual programming, based on rete and svelte.
90 lines (89 loc) • 3.18 kB
JavaScript
import { tick } from 'svelte';
/**
* This class is a singleton that manages a queue of notifications.
*/
class Notifications {
static #instance;
static get instance() {
if (!Notifications.#instance) {
Notifications.#instance = new Notifications();
}
return Notifications.#instance;
}
queue = $state([]);
maxNotifs = $state(4);
autoHideTime = $state(3000);
hideAnimTime = $state(300);
displayed = $state([]);
constructor() { }
hide(id) {
const notif = this.displayed.filter((n) => n.notif.id === id).forEach((n) => n.remove());
this.queue = this.queue.filter((n) => n.id !== id);
}
async show(notif) {
console.debug('showing notification with title:', notif.title, 'and message:', notif.message);
this.queue.push(notif);
await this.updateDisplayed();
}
success(notif) {
this.show({ title: 'Success', ...notif, color: 'success' });
}
warn(notif) {
this.show({ title: 'Warning', ...notif, color: 'warning' });
}
error(notif) {
this.show({ title: 'Error', ...notif, color: 'error' });
}
info(notif) {
this.show({ ...notif, color: 'info' });
}
removeDisplayed(notif) {
const i = this.displayed.findIndex((n) => n === notif);
if (i !== -1) {
this.displayed.splice(i, 1);
}
this.updateDisplayed();
}
updateDisplayed() {
if (this.displayed.length < this.maxNotifs) {
const notif = this.queue.shift();
if (notif) {
let hideTimeout;
let removeTimeout;
let hideTime = typeof notif.autoClose === 'number' ? notif.autoClose : this.autoHideTime;
const displayedNotif = $state({
notif,
visible: true,
remove: () => {
displayedNotif.remove = () => {
console.debug('Already removing notif');
};
if (hideTimeout)
clearTimeout(hideTimeout);
if (removeTimeout)
clearTimeout(removeTimeout);
displayedNotif.visible = false;
setTimeout(() => this.removeDisplayed(displayedNotif), hideTime);
}
});
this.displayed.push(displayedNotif);
// await tick();
if (notif.autoClose !== false) {
// Hide notif timeout
hideTimeout = setTimeout(() => {
displayedNotif.visible = false;
}, hideTime - this.hideAnimTime);
// Remove notif timeout
removeTimeout = setTimeout(() => this.removeDisplayed(displayedNotif), hideTime);
}
}
}
}
}
export const notifications = Notifications.instance;
export const notificationsSetup = {
name: 'notifications',
setup: ({ factory }) => {
factory.notifications = notifications;
}
};