UNPKG

terriajs

Version:

Geospatial data visualization platform.

74 lines (66 loc) 2.45 kB
import { action, computed, observable } from "mobx"; import { ReactNode } from "react"; import ViewState from "./ViewState"; export interface Notification { title: string | (() => string); message: string | ((viewState: ViewState) => ReactNode); confirmText?: string; denyText?: string; confirmAction?: () => void; denyAction?: () => void; hideUi?: boolean; type?: string; width?: number | string; height?: number | string; key?: string; /** If notification should not be shown to the user */ ignore?: boolean | (() => boolean); /** Called when notification is dismissed, this will also be triggered for confirm/deny actions */ onDismiss?: () => void; } /** * Tracks pending notifications, and provides and interface for adding and removing them. * Notification queue is first-in, first-out. * Notifications with the same key will only be added once. */ export default class NotificationState { @observable protected notifications: Notification[] = []; protected alreadyNotifiedKeys: Set<string> = new Set(); @action addNotificationToQueue(notification: Notification) { const alreadyQueued = this.notifications.filter( (item) => item.title === notification.title && item.message === notification.message ).length !== 0; const keyNotSeenBefore = notification.key === undefined || !this.alreadyNotifiedKeys.has(notification.key); if (!alreadyQueued && keyNotSeenBefore) { const ignore = typeof notification.ignore === "function" ? notification.ignore() : notification.ignore ?? false; if (!ignore) this.notifications.push(notification); } if (notification.key !== undefined) { this.alreadyNotifiedKeys.add(notification.key); } } @action dismissCurrentNotification(): Notification | undefined { const removed = this.notifications.shift(); removed?.onDismiss && removed.onDismiss(); // Remove all ignored notifications // This is needed here as the action of dismissing the current notification may change "ignore" status of notifications in stack this.notifications = this.notifications.filter( (n) => !(typeof n.ignore === "function" ? n.ignore() : n.ignore ?? false) ); return removed; } @computed get currentNotification(): Notification | undefined { return this.notifications.length > 0 ? this.notifications[0] : undefined; } }