UNPKG

@selenite/graph-editor

Version:

A graph editor for visual programming, based on rete and svelte.

90 lines (89 loc) 3.18 kB
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; } };