import { INotificaseBase, INotifier, NotificationAlign, NotificationContainer, NotificationModalType, NotificationRenderProps } from '@etsoo/notificationbase'; import { SiteUtils } from '../site/SiteUtils'; import { INotificationDom, NotificationDom, NotificationDomCallProps } from './NotificationDom'; /** * Notifier container interface */ export interface INotifierContainer extends INotifier {} /** * Notifier container */ export class NotifierContainer extends NotificationContainer implements INotifierContainer { private wrappers: { [K in NotificationAlign]?: HTMLDivElement; } = {}; /** * Constructor * @param props Renderer properties * @param className Style class name */ constructor(props: NotificationRenderProps = {}, className?: string) { // Item class const itemClass = className ? className + '-item' : className; // Super constructor super(async (notification, dismiss) => { // Notification creation or dismiss // Destruct const { id, modal, type } = notification; // HTML id const hid = 'id' + id; const { Modal, Toast } = await import('bootstrap'); // Modal if (modal || type in NotificationModalType) { if (dismiss) { const div = document.querySelector(`div.modal#${hid}`); if (div) { const modal = Modal.getInstance(div); if (modal) { modal.hide(); modal.dispose(); div.remove(); } } } else { const nu = notification.render(props, itemClass); if (nu) { nu.classList.add('etsoo-notifier-modal'); nu.id = hid; document.body.appendChild(nu); Modal.getOrCreateInstance(nu).show(); } } return; } // Message / toast // Align const align = notification.align; // Wrapper // position-absolute will ignore the scroll position let wrapper = this.wrappers[align]; if (wrapper == null) { wrapper = document.createElement('div'); wrapper.className = `toast-container position-fixed p-3 ${SiteUtils.getPlacement( align )}`; document.body.append(wrapper); this.wrappers[notification.align] = wrapper; } if (dismiss) { const nu = wrapper.querySelector(`#${hid}`); if (nu) { const toast = Toast.getInstance(nu); if (toast) { toast.hide(); // Bug for version 5.2.3 // toast.dispose(); nu.remove(); } } } else { const nu = notification.render(props, itemClass); if (nu) { nu.id = hid; wrapper.append(nu); Toast.getOrCreateInstance(nu, { autohide: false }).show(); } } }); } protected addRaw( data: INotificaseBase, modal?: boolean | undefined ): INotificationDom { // Destruct const { type, content, title, align, timespan = modal ? 0 : undefined, ...rest } = data; // Setup const n = new NotificationDom(type, content, title, align, timespan); // Assign other properties Object.assign(n, rest); // Is modal if (modal != null) n.modal = modal; // Add to the collection this.add(n); // Return return n; } }