VulpesOS/assets/webapps/system.gaiamobile.org/js/system_banner.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

168 lines
5 KiB
JavaScript

/* global LazyLoader */
'use strict';
(function(exports) {
/**
* SystemBanner displays a type of notification to the user in certain cases.
* It is a type of temporary notification that does not live in the
* notifications tray. Examples of the SystemBanner implementation include
* application installation, crash reporter, and low storage notices.
* @class SystemBanner
*/
function SystemBanner() {}
/**
* Amount of time before banner is automatically dismissed.
*/
SystemBanner.TIMEOUT = 4000;
SystemBanner.prototype = {
/**
* A reference to the SystemBanner element
* @memberof SystemBanner.prototype
* @type {Element}
*/
_banner: null,
/**
* Set when the clicked callback called. Bypasses dismiss.
* @memberof SystemBanner.prototype
* @type {Boolean}
*/
_clicked: false,
/**
* Set to true when the banner is currently showing to the user.
* @memberof SystemBanner.prototype
* @type {Boolean}
*/
_showing: false,
/**
* Generates and returns the banner if it does not exist
* @memberof SystemBanner.prototype
* @type {Function}
*/
getBanner: function() {
if (this._banner) {
return Promise.resolve(this._banner);
}
return LazyLoader.load('shared/elements/gaia-component/gaia-component.js')
.then(() => {
return LazyLoader.load('shared/elements/gaia-toast/gaia-toast.js');
})
.then(() => {
this._banner = document.createElement('gaia-toast');
this._banner.timeout = SystemBanner.TIMEOUT;
this._banner.className = 'banner';
this._banner.dataset.zIndexLevel = 'system-notification-banner';
var container = createChild(this._banner, 'div', 'container');
createChild(container, 'div', 'messages');
createChild(container, 'div', 'buttons');
return this._banner;
});
},
/**
* Shows a banner with a given message.
* Optionally shows a button with a given label/callback/dismiss.
* 'dismiss' is called when the banner is dismissed and button
* has not been clicked. It is optional.
* @memberof SystemBanner.prototype
* @param {String|Array} messages The messages to display
* @param {Object} buttonParams
* { label: l10nAttrs, callback: ..., dismiss: ... }
*/
show: function(messages, buttonParams) {
this._clicked = false;
this._showing = true;
return this.getBanner().then(banner => {
// Clear the button and message containers.
var messageContainer = banner.querySelector('.messages');
var buttonContainer = banner.querySelector('.buttons');
messageContainer.innerHTML = '';
buttonContainer.innerHTML = '';
// Populate banner with messages.
if (!Array.isArray(messages)) {
messages = [messages];
}
messages.forEach((chunk) => {
var p = createChild(messageContainer, 'p');
setElementL10n(p, chunk);
});
// Populate buttons if specified.
if (buttonParams) {
var button = createChild(buttonContainer, 'span');
button.className = 'button';
setElementL10n(button, buttonParams.label);
button.addEventListener('click', () => {
this._clicked = true;
this.hide();
buttonParams.callback && buttonParams.callback();
});
}
// Hide banner and invoke button dismiss() on click or timeout.
var hideBanner = () => {
this.hide();
if (!this._clicked) {
buttonParams && buttonParams.dismiss && buttonParams.dismiss();
}
};
banner.onclick = hideBanner;
setTimeout(hideBanner, SystemBanner.TIMEOUT);
document.getElementById('screen').appendChild(banner);
banner.show();
});
},
/**
* Hide the System Banner and remove it from the DOM.
*/
hide: function() {
if (!this._showing) {
return;
}
this._showing = false;
return this.getBanner().then(banner => {
banner.addEventListener('animationend', function removeBanner() {
banner.removeEventListener('animationend', removeBanner);
// Only remove banner if we haven't called show() in the meantime.
if (!this._showing) {
banner.parentNode && banner.parentNode.removeChild(banner);
}
}.bind(this));
banner.hide();
});
}
};
function createChild(parentEl, type, className) {
var el = document.createElement(type);
if (className) {
el.className = className;
}
parentEl.appendChild(el);
return el;
}
function setElementL10n(element, l10nAttrs) {
if (typeof(l10nAttrs) === 'string') {
element.setAttribute('data-l10n-id', l10nAttrs);
} else {
navigator.mozL10n.setAttributes(
element, l10nAttrs.id, l10nAttrs.args);
}
}
exports.SystemBanner = SystemBanner;
}(window));