123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 |
- /* global $, APP, toastr */
- const logger = require("jitsi-meet-logger").getLogger(__filename);
-
- import UIUtil from './UIUtil';
- import jitsiLocalStorage from '../../util/JitsiLocalStorage';
-
- /**
- * Flag for enable/disable of the notifications.
- * @type {boolean}
- */
- let notificationsEnabled = true;
-
- /**
- * Flag for enabling/disabling popups.
- * @type {boolean}
- */
- let popupEnabled = true;
-
- /**
- * Currently displayed two button dialog.
- * @type {null}
- */
- let twoButtonDialog = null;
-
- /**
- * Generates html for dont show again checkbox.
- * @param {object} options options
- * @param {string} options.id the id of the checkbox.
- * @param {string} options.textKey the key for the text displayed next to
- * checkbox
- * @param {boolean} options.checked if true the checkbox is foing to be checked
- * by default.
- * @returns {string}
- */
- function generateDontShowCheckbox(options) {
- if(!isDontShowAgainEnabled(options)) {
- return "";
- }
-
- let checked
- = (options.checked === true) ? "checked" : "";
- return `<br />
- <label>
- <input type='checkbox' ${checked} id='${options.id}' />
- <span data-i18n='${options.textKey}'></span>
- </label>`;
- }
-
- /**
- * Checks whether the dont show again checkbox was checked before.
- * @param {object} options - options for dont show again checkbox.
- * @param {string} options.id the id of the checkbox.
- * @param {string} options.localStorageKey the key for the local storage. if
- * not provided options.id will be used.
- * @returns {boolean} true if the dialog mustn't be displayed and
- * false otherwise.
- */
- function dontShowTheDialog(options) {
- if(isDontShowAgainEnabled(options)) {
- if(jitsiLocalStorage.getItem(options.localStorageKey || options.id)
- === "true") {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Wraps the submit function to process the dont show again status and store
- * it.
- * @param {object} options - options for dont show again checkbox.
- * @param {string} options.id the id of the checkbox.
- * @param {Array} options.buttonValues The button values that will trigger
- * storing he checkbox value
- * @param {string} options.localStorageKey the key for the local storage. if
- * not provided options.id will be used.
- * @param {Function} submitFunction the submit function to be wrapped
- * @returns {Function} wrapped function
- */
- function dontShowAgainSubmitFunctionWrapper(options, submitFunction) {
- if(isDontShowAgainEnabled(options)) {
- return (...args) => {
- logger.debug(args, options.buttonValues);
- //args[1] is the value associated with the pressed button
- if(!options.buttonValues || options.buttonValues.length === 0
- || options.buttonValues.indexOf(args[1]) !== -1 ) {
- let checkbox = $(`#${options.id}`);
- if (checkbox.length) {
- jitsiLocalStorage.setItem(
- options.localStorageKey || options.id,
- checkbox.prop("checked"));
- }
- }
- submitFunction(...args);
- };
- } else {
- return submitFunction;
- }
- }
-
- /**
- * Check whether dont show again checkbox is enabled or not.
- * @param {object} options - options for dont show again checkbox.
- * @returns {boolean} true if enabled and false if not.
- */
- function isDontShowAgainEnabled(options) {
- return typeof options === "object";
- }
-
- var messageHandler = {
- OK: "dialog.OK",
- CANCEL: "dialog.Cancel",
-
- /**
- * Shows a message to the user.
- *
- * @param titleKey the key used to find the translation of the title of the
- * message, if a message title is not provided.
- * @param messageKey the key used to find the translation of the message
- * @param i18nOptions the i18n options (optional)
- * @param closeFunction function to be called after
- * the prompt is closed (optional)
- * @return the prompt that was created, or null
- */
- openMessageDialog:
- function(titleKey, messageKey, i18nOptions, closeFunction) {
- if (!popupEnabled)
- return null;
-
- let dialog = $.prompt(
- APP.translation.generateTranslationHTML(messageKey, i18nOptions),
- {
- title: this._getFormattedTitleString(titleKey),
- persistent: false,
- promptspeed: 0,
- classes: this._getDialogClasses(),
- close: function (e, v, m, f) {
- if(closeFunction)
- closeFunction(e, v, m, f);
- }
- });
- APP.translation.translateElement(dialog, i18nOptions);
- return $.prompt.getApi();
- },
- /**
- * Shows a message to the user with two buttons: first is given as a
- * parameter and the second is Cancel.
- *
- * @param titleKey the key for the title of the message
- * @param msgKey the key for the message
- * @param msgString the text of the message
- * @param persistent boolean value which determines whether the message is
- * persistent or not
- * @param leftButton the fist button's text
- * @param submitFunction function to be called on submit
- * @param loadedFunction function to be called after the prompt is fully
- * loaded
- * @param closeFunction function to be called after the prompt is closed
- * @param focus optional focus selector or button index to be focused after
- * the dialog is opened
- * @param defaultButton index of default button which will be activated when
- * the user press 'enter'. Indexed from 0.
- * @param {object} dontShowAgain - options for dont show again checkbox.
- * @param {string} dontShowAgain.id the id of the checkbox.
- * @param {string} dontShowAgain.textKey the key for the text displayed
- * next to checkbox
- * @param {boolean} dontShowAgain.checked if true the checkbox is foing to
- * be checked
- * @param {Array} dontShowAgain.buttonValues The button values that will
- * trigger storing the checkbox value
- * @param {string} dontShowAgain.localStorageKey the key for the local
- * storage. if not provided dontShowAgain.id will be used.
- * @return the prompt that was created, or null
- */
- openTwoButtonDialog: function(options) {
- let {
- titleKey,
- msgKey,
- msgString,
- leftButtonKey,
- submitFunction,
- loadedFunction,
- closeFunction,
- focus,
- size,
- defaultButton,
- wrapperClass,
- classes,
- dontShowAgain
- } = options;
-
- if (!popupEnabled || twoButtonDialog)
- return null;
-
- if(dontShowTheDialog(dontShowAgain)) {
- // Maybe we should pass some parameters here? I'm not sure
- // and currently we don't need any parameters.
- submitFunction();
- return null;
- }
-
- var buttons = [];
-
- var leftButton = leftButtonKey ?
- APP.translation.generateTranslationHTML(leftButtonKey) :
- APP.translation.generateTranslationHTML('dialog.Submit');
- buttons.push({ title: leftButton, value: true});
-
- var cancelButton
- = APP.translation.generateTranslationHTML("dialog.Cancel");
- buttons.push({title: cancelButton, value: false});
-
- var message = msgString;
- if (msgKey) {
- message = APP.translation.generateTranslationHTML(msgKey);
- }
- message += generateDontShowCheckbox(dontShowAgain);
- classes = classes || this._getDialogClasses(size);
- if (wrapperClass) {
- classes.prompt += ` ${wrapperClass}`;
- }
-
- twoButtonDialog = $.prompt(message, {
- title: this._getFormattedTitleString(titleKey),
- persistent: false,
- buttons: buttons,
- defaultButton: defaultButton,
- focus: focus,
- loaded: loadedFunction,
- promptspeed: 0,
- classes,
- submit: dontShowAgainSubmitFunctionWrapper(dontShowAgain,
- function (e, v, m, f) {
- twoButtonDialog = null;
- if (v && submitFunction) {
- submitFunction(e, v, m, f);
- }
- }),
- close: function (e, v, m, f) {
- twoButtonDialog = null;
- if (closeFunction) {
- closeFunction(e, v, m, f);
- }
- }
- });
- APP.translation.translateElement(twoButtonDialog);
- return $.prompt.getApi();
- },
-
- /**
- * Shows a message to the user with two buttons: first is given as a
- * parameter and the second is Cancel.
- *
- * @param titleKey the key for the title of the message
- * @param msgString the text of the message
- * @param persistent boolean value which determines whether the message is
- * persistent or not
- * @param buttons object with the buttons. The keys must be the name of the
- * button and value is the value that will be passed to
- * submitFunction
- * @param submitFunction function to be called on submit
- * @param loadedFunction function to be called after the prompt is fully
- * loaded
- * @param closeFunction function to be called on dialog close
- * @param {object} dontShowAgain - options for dont show again checkbox.
- * @param {string} dontShowAgain.id the id of the checkbox.
- * @param {string} dontShowAgain.textKey the key for the text displayed
- * next to checkbox
- * @param {boolean} dontShowAgain.checked if true the checkbox is foing to
- * be checked
- * @param {Array} dontShowAgain.buttonValues The button values that will
- * trigger storing the checkbox value
- * @param {string} dontShowAgain.localStorageKey the key for the local
- * storage. if not provided dontShowAgain.id will be used.
- */
- openDialog: function (titleKey, msgString, persistent, buttons,
- submitFunction, loadedFunction, closeFunction, dontShowAgain) {
- if (!popupEnabled)
- return;
-
- if(dontShowTheDialog(dontShowAgain)) {
- // Maybe we should pass some parameters here? I'm not sure
- // and currently we don't need any parameters.
- submitFunction();
- return;
- }
-
- let args = {
- title: this._getFormattedTitleString(titleKey),
- persistent: persistent,
- buttons: buttons,
- defaultButton: 1,
- promptspeed: 0,
- loaded: function() {
- if (loadedFunction) {
- loadedFunction.apply(this, arguments);
- }
- // Hide the close button
- if (persistent) {
- $(".jqiclose", this).hide();
- }
- },
- submit: dontShowAgainSubmitFunctionWrapper(
- dontShowAgain, submitFunction),
- close: closeFunction,
- classes: this._getDialogClasses()
- };
-
- if (persistent) {
- args.closeText = '';
- }
-
- let dialog = $.prompt(
- msgString + generateDontShowCheckbox(dontShowAgain), args);
- APP.translation.translateElement(dialog);
- return $.prompt.getApi();
- },
-
- /**
- * Returns the formatted title string.
- *
- * @return the title string formatted as a div.
- */
- _getFormattedTitleString(titleKey) {
- let $titleString = $('<h2>');
- $titleString.addClass('aui-dialog2-header-main');
- $titleString.attr('data-i18n',titleKey);
- return $('<div>').append($titleString).html();
- },
-
- /**
- * Returns the dialog css classes.
- *
- * @return the dialog css classes
- */
- _getDialogClasses(size = 'small') {
- return {
- box: '',
- form: '',
- prompt: `dialog aui-layer aui-dialog2 aui-dialog2-${size}`,
- close: 'aui-icon aui-icon-small aui-iconfont-close-dialog',
- fade: 'aui-blanket',
- button: 'button-control',
- message: 'aui-dialog2-content',
- buttons: 'aui-dialog2-footer',
- defaultButton: 'button-control_primary',
- title: 'aui-dialog2-header'
- };
- },
-
- /**
- * Shows a dialog with different states to the user.
- *
- * @param statesObject object containing all the states of the dialog.
- * @param options impromptu options
- * @param translateOptions options passed to translation
- */
- openDialogWithStates: function (statesObject, options, translateOptions) {
- if (!popupEnabled)
- return;
- let { classes, size } = options;
- let defaultClasses = this._getDialogClasses(size);
- options.classes = Object.assign({}, defaultClasses, classes);
- options.promptspeed = options.promptspeed || 0;
-
- for (let state in statesObject) {
- let currentState = statesObject[state];
- if(currentState.titleKey) {
- currentState.title
- = this._getFormattedTitleString(currentState.titleKey);
- }
- }
- let dialog = $.prompt(statesObject, options);
- APP.translation.translateElement(dialog, translateOptions);
- return $.prompt.getApi();
- },
-
- /**
- * Opens new popup window for given <tt>url</tt> centered over current
- * window.
- *
- * @param url the URL to be displayed in the popup window
- * @param w the width of the popup window
- * @param h the height of the popup window
- * @param onPopupClosed optional callback function called when popup window
- * has been closed.
- *
- * @returns {object} popup window object if opened successfully or undefined
- * in case we failed to open it(popup blocked)
- */
- openCenteredPopup: function (url, w, h, onPopupClosed) {
- if (!popupEnabled)
- return;
-
- var l = window.screenX + (window.innerWidth / 2) - (w / 2);
- var t = window.screenY + (window.innerHeight / 2) - (h / 2);
- var popup = window.open(
- url, '_blank',
- 'top=' + t + ', left=' + l + ', width=' + w + ', height=' + h + '');
- if (popup && onPopupClosed) {
- var pollTimer = window.setInterval(function () {
- if (popup.closed !== false) {
- window.clearInterval(pollTimer);
- onPopupClosed();
- }
- }, 200);
- }
-
- return popup;
- },
-
- /**
- * Shows a dialog prompting the user to send an error report.
- *
- * @param titleKey the title of the message
- * @param msgKey the text of the message
- * @param error the error that is being reported
- */
- openReportDialog: function(titleKey, msgKey, error) {
- this.openMessageDialog(titleKey, msgKey);
- logger.log(error);
- //FIXME send the error to the server
- },
-
- /**
- * Shows an error dialog to the user.
- * @param titleKey the title of the message.
- * @param msgKey the text of the message.
- */
- showError: function(titleKey, msgKey) {
-
- if (!titleKey) {
- titleKey = "dialog.oops";
- }
- if (!msgKey) {
- msgKey = "dialog.defaultError";
- }
- messageHandler.openMessageDialog(titleKey, msgKey);
- },
-
- /**
- * Displays a notification.
- * @param displayName the display name of the participant that is
- * associated with the notification.
- * @param displayNameKey the key from the language file for the display
- * name. Only used if displayName i not provided.
- * @param cls css class for the notification
- * @param messageKey the key from the language file for the text of the
- * message.
- * @param messageArguments object with the arguments for the message.
- * @param options passed to toastr (e.g. timeOut)
- */
- notify: function(displayName, displayNameKey, cls, messageKey,
- messageArguments, options) {
-
- // If we're in ringing state we skip all toaster notifications.
- if(!notificationsEnabled || APP.UI.isOverlayVisible())
- return;
-
- var displayNameSpan = '<span class="nickname" ';
- if (displayName) {
- displayNameSpan += ">" + UIUtil.escapeHtml(displayName);
- } else {
- displayNameSpan += "data-i18n='" + displayNameKey + "'>";
- }
- displayNameSpan += "</span>";
- let element = toastr.info(
- displayNameSpan + '<br>' +
- '<span class=' + cls + ' data-i18n="' + messageKey + '"' +
- (messageArguments?
- " data-i18n-options='"
- + JSON.stringify(messageArguments) + "'"
- : "") + "></span>", null, options);
- APP.translation.translateElement(element);
- return element;
- },
-
- /**
- * Removes the toaster.
- * @param toasterElement
- */
- remove: function(toasterElement) {
- toasterElement.remove();
- },
-
- /**
- * Enables / disables notifications.
- */
- enableNotifications: function (enable) {
- notificationsEnabled = enable;
- },
-
- enablePopups: function (enable) {
- popupEnabled = enable;
- },
-
- /**
- * Returns true if dialog is opened
- * false otherwise
- * @returns {boolean} isOpened
- */
- isDialogOpened: function () {
- return !!$.prompt.getCurrentStateName();
- }
- };
-
- module.exports = messageHandler;
|