import { getUiElements } from '../view/UiElements'; /** * Silex, live web creation * http://projects.silexlabs.org/?/silex/ * * Copyright (c) 2012 Silex Labs * http://www.silexlabs.org/ * * Silex is available under the GPL license * http://www.silexlabs.org/silex/silex-licensing/ */ interface Dialog { set(optoins: any); close(); destroy(); setContent(el: HTMLElement|DocumentFragment); } interface Options { labelOk?: string; labelCancel?: string; defaultValue?: string; cancel?: () => {}; title: string; content: string; placeholder?: string; } /** * @fileoverview Helper class for common tasks * */ export class SilexNotification { static get isActive(): boolean { return !!SilexNotification.currentDialog && !document.querySelector('.alerts').classList.contains('closed'); } /** * flag to indicate wether a modal dialog is opened */ private static get currentDialog(): HTMLElement { return document.querySelector(`.${SilexNotification.NOTIFICATION_CSS_CLASS}`); } /** * close (cancel) the current notification */ static close(isOk= false) { if (SilexNotification.currentDialog) { // hide dialogs const container: HTMLElement = document.querySelector('.alerts'); container.classList.add('closed'); // cleanup const cbk = isOk ? SilexNotification.cbkOk : SilexNotification.cbkCancel; SilexNotification.currentDialog.remove(); SilexNotification.cbkCancel = null; SilexNotification.cbkOk = null; // all done, we can open another one or do something cbk(); } } /** * display a message */ static alert(title: string, content: string, ok: () => any, labelOk: string = 'ok') { SilexNotification.close(); SilexNotification.create(SilexNotification.getMarkup({ labelOk, title, content, })); SilexNotification.cbkCancel = SilexNotification.cbkOk = () => ok(); (SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_ok`) as HTMLElement).onclick = (e) => SilexNotification.close(); } /** * ask for a text */ static prompt(title: string, content: string, defaultValue: string, placeholder: string, cbk: (isOk: boolean, value: string) => any, labelOk: string = 'ok', labelCancel: string = 'cancel') { SilexNotification.close(); SilexNotification.create(SilexNotification.getMarkup({ labelOk, labelCancel, defaultValue, title, content, placeholder, })); const input: HTMLInputElement = SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_value`); SilexNotification.cbkOk = () => { cbk(true, input.value); }; SilexNotification.cbkCancel = () => { cbk(false, null); }; (SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_ok`) as HTMLElement).onclick = (e) => SilexNotification.close(true); (SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_cancel`) as HTMLElement).onclick = (e) => SilexNotification.close(false); } /** * ask for confirmation */ static confirm(title: string, content: string, cbk: (isOk: boolean) => any, labelOk: string = 'ok', labelCancel: string = 'cancel') { SilexNotification.close(); SilexNotification.create(SilexNotification.getMarkup({ labelOk, labelCancel, title, content, })); SilexNotification.cbkOk = () => cbk(true); SilexNotification.cbkCancel = () => cbk(false); (SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_ok`) as HTMLElement).onclick = (e) => SilexNotification.close(true); (SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_cancel`) as HTMLElement).onclick = (e) => SilexNotification.close(false); } /** * notify the user with success formatting */ static notifySuccess(message: string) { const container: HTMLElement = document.querySelector('.alerts-notify'); const el = document.createElement('p'); el.innerHTML = message; container.appendChild(el); const id = setTimeout(() => { el.remove(); }, SilexNotification.NOTIFICATION_DURATION_MS); el.onclick = (e) => { clearTimeout(id); el.remove(); }; } /** * notify the user with success formatting */ static notifyError(message: string) { console.error(message); SilexNotification.notifySuccess(message); } /** * change the text of the current notification */ static setContent(el: HTMLElement|DocumentFragment, keepExisiting= false) { if (SilexNotification.currentDialog) { const container = SilexNotification.currentDialog.querySelector(`.${SilexNotification.NOTIFICATION_CSS_CLASS}_content`); if (!keepExisiting) { container.innerHTML = ''; } container.appendChild(el); } } /** * change the text of the current notification */ static setText(text: string) { if (SilexNotification.currentDialog) { const el = document.createElement('div'); el.insertAdjacentHTML('afterbegin', `

${text}

`); SilexNotification.setContent(el); } } /** * add a button to the button bar */ static addButton(el: HTMLElement|DocumentFragment) { if (SilexNotification.currentDialog) { SilexNotification.currentDialog.querySelector(`.${SilexNotification.NOTIFICATION_CSS_CLASS}_buttons`); } } /** * add an HTML panel with info of type "while you wait, here is an info" */ static setInfoPanel(element: HTMLElement) { if (SilexNotification.currentDialog) { let infoPanel = SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_info`) as HTMLElement; if (!infoPanel) { infoPanel = document.createElement('div'); infoPanel.insertAdjacentHTML('afterbegin', `

`); SilexNotification.setContent(infoPanel, true); } // limit height so that small screens still see the close button const stage = getUiElements().stage.querySelector('iframe'); infoPanel.style.maxHeight = Math.round(stage.clientHeight * 2 / 3) + 'px'; SilexNotification.currentDialog.insertBefore(infoPanel, SilexNotification.currentDialog.childNodes[SilexNotification.currentDialog.childNodes.length - 1]); infoPanel.innerHTML = ''; infoPanel.appendChild(element); } } private static NOTIFICATION_DURATION_MS = 30000; private static NOTIFICATION_CSS_CLASS = 'notification-dialog'; private static cbkOk: () => void; private static cbkCancel: () => void; private static getMarkup(options: Options) { return `

${options.title}

${options.content} ${ typeof options.defaultValue !== 'undefined' ? ` ` : '' }

${options.labelCancel ? `` : ''} ${options.labelOk ? `` : ''}
`; } private static create(markup: string) { const container: HTMLElement = document.querySelector('.alerts'); container.insertAdjacentHTML('afterbegin', markup); container.classList.remove('closed'); const input = (SilexNotification.currentDialog.querySelector(`#${SilexNotification.NOTIFICATION_CSS_CLASS}_value`) as HTMLElement); if (input) { input.focus(); } } constructor() { throw new Error('this is a static class and it canot be instanciated'); } } // else { // Notifications are not supported or denied // } // Desktop notifications disabled because it disturbs more than it serves // FIXME: remove all calls to nativeNotification since it is not useful anymore // Notification.activateNative(); // :facepalm: