'use strict';
var _ = require('lodash'),
StorageUtils = require('storage-utils').default,
SHGlobals = require('sh-globals'),
NotificationView = require('notification-view'),
$body = $('body'),
$window = $(window),
$container = $('<div></div>'),
index = 0,
isWatchingScroll = false,
containerTopPos = 0,
notificationRemoved = function notificationRemoved() {
if (!SHGlobals.isMobile && !$container.children().length && isWatchingScroll) {
$window.off('scroll', onDesktopScroll);
isWatchingScroll = false;
}
},
onDesktopScroll = function onDesktopScroll(evt) {
var windowTop = $window.scrollTop(),
containerTop = (windowTop > containerTopPos) ? windowTop : containerTopPos;
$container.css({top: containerTop});
};
/**
* Adds the ability to dispatch notifications from anywhere within the application. Wrap the objects to be dispatched in an array to show multiple notifications at once.
* @module SHNotifications
* @example
* SHNotifications.add(
* {
* type: 'success'
* message: 'Success message here.'
* }
* );
*/
module.exports = {
/**
* Adds a notification to the queue.
* @static
* @function add
* @param {Object} data - The data to pass to the notification.
* @param {String} data.message - The message to display inside the notification.
* @param {String} [data.type] - The type of notification. ('success', 'error', 'warning')
* @param {Integer} [data.duration=3000] - The time (in ms) to show the notification for.
* @param {Boolean} [data.showClose=true] - Whether to show the close button.
* @param {Boolean} [data.autoClose=true] - Whether to automatically close the notification after duration.
* @param {Object} [data.cookie] - A cookie that, if present, only shows the notification once.
* @param {String} data.cookie.name - The name of the cookie.
* @param {Integer|Date} [data.cookie.expires] - The number of days (Integer) or the date (Date) that determines the lifetime of the cookie.
* @param {Array.<Object>} [data.buttons] - Adds buttons to the notification.
* @param {String} data.buttons.displayClass - The class to add to the button. ('Button' or 'Button-link')
* @param {String} data.buttons.clickClass - A unique class to this notification which can differentiate this button from others.
* @param {String} data.buttons.label - The button label.
* @param {Function} data.buttons.callback - The method to call when the button is clicked.
* @param {Array} [data.buttons.callbackParams] - Parameters to pass to the callback method.
* @example
* SHNotifications.add(
* {
* type: 'success'
* message: 'Success message here.'
* showClose: false,
* autoClose: false,
* duration: 2000,
* cookie: {
* name: 'nameOfCookie',
* expires: 1
* },
* buttons: [
* {
* displayClass: 'Button',
* clickClass: 'btn-label-1',
* label: 'Label 1',
* callback: cb,
* callbackParams: [true, 'hello']
* },
* {
* displayClass: 'Button-link',
* clickClass: 'btn-label-2',
* label: 'Label 2',
* callback: cb2,
* callbackParams: [this]
* }
* ]
* }
* );
* @returns {void}
*/
add: function(data) {
if (data.cookie) {
if (StorageUtils.get(data.cookie.name, 'cookie')) {
return;
} else {
var cookieExpires = null;
if (!_.isUndefined(data.cookie.expires)) {
cookieExpires = data.cookie.expires;
}
StorageUtils.set(data.cookie.name, '1', 'cookie', cookieExpires);
}
}
if (!$body.children('.notification-container').length) {
var $nav = $('.navbar'),
isSecondary = $nav.hasClass('navbar-secondary'),
containerCSS = {
top: isSecondary ? $nav.outerHeight() : 0,
zIndex: isSecondary ? 13 : 18
};
containerTopPos = containerCSS.top;
$body.append($container);
$container
.addClass('notification-container')
.css(containerCSS);
}
this._showNotifications(data);
},
_showNotifications: function(data) {
var self = this;
if (_.isArray(data)) {
_.each(data, function(notification, i) {
setTimeout(function() {
self._addNotification(notification, i);
}, (i * 500));
});
} else {
this._addNotification(data, index++);
}
},
_addNotification: function(data, zIndex) {
data.zIndex = zIndex;
var notificationView = new NotificationView({model: data});
notificationView.notificationRemoved.addOnce(notificationRemoved);
$container.prepend(notificationView.render().el);
if (!SHGlobals.isMobile && !isWatchingScroll) {
$window.on('scroll', onDesktopScroll);
onDesktopScroll();
isWatchingScroll = true;
}
}
};