modules/Notifications.js

import { Messaging } from './Messaging';
import mapObject from '../utils/mapObject';
import removeClass from '../utils/removeClass';
import query from '../utils/query';
import stripHtml from '../utils/stripHtml';
import addClass from '../utils/addClass';

/**
 * Notifications leaderboard widget
 * @param options {Object}
 * @constructor
 */
export const Notifications = function (options) {
  /**
   * Notifications settings
   * @memberOf Notifications
   * @constant
   * @type { Object }
   */
  this.settings = {
    container: null,
    detailsContainer: null,
    canvasInstance: null,
    lbWidget: null,
    eventStream: [],
    checkTimeout: 2000,
    onDisplayCheckTimeout: 10000,
    checkInterval: null,
    autoNotificationHideInterval: null,
    autoNotificationHideTime: 10000,
    displayInProgress: false,
    dataExtractionForCanvas: function (data, callback) {
      if (typeof data.metadata !== 'undefined' && data.metadata.length > 0 && typeof callback === 'function') {
        var found = false;
        mapObject(data.metadata, function (meta) {
          if (meta.key === 'webAsset' && !found) {
            const responseObj = {
              imageSrc: meta.value
            };
            found = true;
            console.log(responseObj);
            callback(responseObj);
          }
        });
      }
    }
  };

  if (typeof options !== 'undefined') {
    for (var opt in options) {
      if (options.hasOwnProperty(opt)) {
        this.settings[opt] = options[opt];
      }
    }
  }

  this.layoutWrapper = function () {
    var wrapper = document.createElement('div');
    var iconWrapper = document.createElement('div');
    var icon = document.createElement('div');

    var informationWrapper = document.createElement('div');
    var informationTopWrapper = document.createElement('div');
    var informationDetailsContainer = document.createElement('div');
    var informationDetailsLabel = document.createElement('div');
    var informationDetailsDescription = document.createElement('div');
    var informationWrapperClose = document.createElement('div');
    var informationClose = document.createElement('a');

    wrapper.setAttribute('class', 'cl-widget-notif-wrapper');
    iconWrapper.setAttribute('class', 'cl-widget-notif-icon-wrapper');
    icon.setAttribute('class', 'cl-widget-notif-icon');
    informationTopWrapper.setAttribute('class', 'cl-widget-notif-information-top-wrapper');
    informationWrapper.setAttribute('class', 'cl-widget-notif-information-wrapper');
    informationDetailsContainer.setAttribute('class', 'cl-widget-notif-information-details-wrapper');
    informationDetailsLabel.setAttribute('class', 'cl-widget-notif-information-details-label');
    informationDetailsDescription.setAttribute('class', 'cl-widget-notif-information-details-description');
    informationWrapperClose.setAttribute('class', 'cl-widget-notif-information-close-wrapper');
    informationClose.setAttribute('class', 'cl-widget-notif-information-close');

    informationClose.href = 'javascript:void(0);';
    informationClose.innerHTML = 'x';

    informationDetailsContainer.appendChild(informationDetailsLabel);
    informationDetailsContainer.appendChild(informationDetailsDescription);

    informationWrapperClose.appendChild(informationClose);
    informationWrapper.appendChild(informationWrapperClose);
    informationWrapper.appendChild(informationDetailsContainer);
    informationTopWrapper.appendChild(informationWrapper);
    iconWrapper.appendChild(icon);
    wrapper.appendChild(iconWrapper);
    wrapper.appendChild(informationTopWrapper);

    return wrapper;
  };

  var processed = {};
  this.startSSE = function () {
    var _this = this;

    _this.settings.sseInstance = new Messaging({
      sseUrl: _this.settings.lbWidget.settings.uri.gatewayDomain + _this.settings.lbWidget.settings.uri.memberSSE.replace(':space', _this.settings.lbWidget.settings.spaceName).replace(':id', _this.settings.lbWidget.settings.memberId),
      heartbeat: _this.settings.lbWidget.settings.uri.gatewayDomain + _this.settings.lbWidget.settings.uri.memberSSEHeartbeat.replace(':space', _this.settings.lbWidget.settings.spaceName).replace(':id', _this.settings.lbWidget.settings.memberId),
      ajax: {
        url: null,
        apiKey: {
          'X-API-KEY': _this.settings.lbWidget.settings.apiKey
        }
      },
      callback: function (data) {
        var dataKey = JSON.stringify(data);
        var currentTime = new Date().getTime();

        if (typeof processed[dataKey] === 'undefined' || (typeof processed[dataKey] !== 'undefined' && (processed[dataKey] + 10000) < currentTime)) {
          processed[JSON.stringify(data)] = currentTime;
          _this.settings.eventStream.push(data);
        }
      },
      onStartupError: function (settings) {
      },
      debug: true
    });
  };

  this.autoNotificationHide = function () {
    var _this = this;

    if (_this.settings.autoNotificationHideInterval) {
      clearTimeout(_this.settings.autoNotificationHideInterval);
    }

    _this.settings.autoNotificationHideInterval = setTimeout(function () {
      _this.hideNotification();
    }, _this.settings.autoNotificationHideTime);
  };

  this.hideNotification = function () {
    var _this = this;

    if (_this.settings.autoNotificationHideInterval) {
      clearTimeout(_this.settings.autoNotificationHideInterval);
    }

    _this.settings.displayInProgress = false;
    removeClass(query(_this.settings.container, '.cl-widget-notif-information-wrapper'), 'cl-show');
    setTimeout(function () {
      _this.settings.container.style.display = 'none';
    }, 200);
  };

  this.showAchievementNotification = function (data) {
    var _this = this;
    var label = query(_this.settings.detailsContainer, '.cl-widget-notif-information-details-label');
    var description = query(_this.settings.detailsContainer, '.cl-widget-notif-information-details-description');
    var descriptionText = stripHtml(data.data.description);

    label.innerHTML = (data.data.name.length > 23) ? data.data.name.substr(0, 23) + '...' : data.data.name;
    description.innerHTML = (descriptionText.length > 60) ? descriptionText.substr(0, 60) + '...' : descriptionText;

    _this.settings.detailsContainer.dataset.id = data.data.id;

    _this.settings.container.style.display = 'block';
    setTimeout(function () {
      addClass(query(_this.settings.container, '.cl-widget-notif-information-wrapper'), 'cl-show');
    }, 200);

    if (_this.settings.canvasInstance !== null) {
      _this.handleCanvasAnimations(data.data);
    }

    _this.autoNotificationHide();
  };

  this.handleCanvasAnimations = function (data) {
    const _this = this;

    _this.settings.dataExtractionForCanvas(data, function (canvasData) {
      if (canvasData.imageSrc.length > 0) {
        _this.settings.canvasInstance.settings.imageSrc = canvasData.imageSrc;
        _this.settings.canvasInstance.init();
      }
    });
  };

  this.eventStreamCheck = function () {
    var _this = this;

    if (_this.settings.checkInterval) {
      clearTimeout(_this.settings.checkInterval);
    }

    if (_this.settings.eventStream.length > 0 && !_this.settings.displayInProgress) {
      var data = _this.settings.eventStream[0];
      var index = _this.settings.eventStream.indexOf(data);

      if (typeof data.achievementId !== 'undefined') {
        _this.settings.displayInProgress = true;
        _this.settings.lbWidget.getAchievement(data.achievementId, function (data) {
          _this.showAchievementNotification(data);

          _this.settings.checkInterval = setTimeout(function () {
            _this.eventStreamCheck();
          }, _this.settings.onDisplayCheckTimeout);
        });

        _this.settings.eventStream.splice(index, 1);
      } else if (typeof data.notificationId !== 'undefined') {
        _this.settings.checkInterval = setTimeout(function () {
          _this.eventStreamCheck();
        }, _this.settings.checkTimeout);
      } else {
        _this.settings.checkInterval = setTimeout(function () {
          _this.eventStreamCheck();
        }, _this.settings.checkTimeout);
      }

      if (index > -1) {
        _this.settings.eventStream.splice(index, 1);
      }
    } else {
      _this.settings.checkInterval = setTimeout(function () {
        _this.eventStreamCheck();
      }, _this.settings.checkTimeout);
    }
  };

  this.init = function () {
    var _this = this;

    if (_this.settings.container === null) {
      _this.startSSE();
      _this.settings.container = _this.settings.lbWidget.settings.bindContainer.appendChild(_this.layoutWrapper());
      _this.settings.detailsContainer = query(_this.settings.container, '.cl-widget-notif-information-details-wrapper');
    } else {
      // terminate SSE
      _this.settings.sseInstance.closeChanel();

      // update the member
      _this.settings.sseInstance.settings.sseUrl = _this.settings.lbWidget.settings.uri.gatewayDomain + _this.settings.lbWidget.settings.uri.memberSSE.replace(':space', _this.settings.lbWidget.settings.spaceName).replace(':id', _this.settings.lbWidget.settings.memberId);
      _this.settings.sseInstance.settings.heartbeat = _this.settings.lbWidget.settings.uri.gatewayDomain + _this.settings.lbWidget.settings.uri.memberSSEHeartbeat.replace(':space', _this.settings.lbWidget.settings.spaceName).replace(':id', _this.settings.lbWidget.settings.memberId);

      // re-instantiate SSE
      _this.settings.sseInstance.openChanel();
    }

    _this.eventStreamCheck();
  };
};