APIs

Show:
/**
 Add block view is a UI component which allows selection and insertion of a new component (i.e. QR / RSS ...)
 or a resource to be added to the currently selected timeline_channel.
 We also skip displaying certain components / scenes dependon


 @class AddBlockView
 @constructor
 @return {object} instantiated AddBlockView
 **/
define(['jquery', 'backbone', 'StackView', 'ScreenTemplateFactory', 'bootbox'], function ($, Backbone, StackView, ScreenTemplateFactory, Bootbox) {

    /**
     Custom event fired when a new block is added to timeline_channel
     @event ADD_NEW_BLOCK_CHANNEL
     @param {this} caller
     @param {self} context caller
     @param {event} player_code which represents a specific code assigned for each block type
     @static
     @final
     **/
    BB.EVENTS.ADD_NEW_BLOCK_CHANNEL = 'ADD_NEW_BLOCK_CHANNEL';

    /**
     Custom event fired when a new block is added to scene
     @event ADD_NEW_BLOCK_SCENE
     @param {this} caller
     @param {self} context caller
     @param {event} player_code which represents a specific code assigned for each block type
     @static
     @final
     **/
    BB.EVENTS.ADD_NEW_BLOCK_SCENE = 'ADD_NEW_BLOCK_SCENE';

    /**
     Custom event fired when a new block is added to scene
     @event ADD_NEW_BLOCK_SCENE
     @param {this} caller
     @param {self} context caller
     @param {event} player_code which represents a specific code assigned for each block type
     @static
     @final
     **/
    BB.EVENTS.ADD_NEW_BLOCK_LIST = 'ADD_NEW_BLOCK_LIST';


    /** SERVICES **/
    BB.SERVICES.ADD_BLOCK_VIEW = 'AddBlockView';
    BB.SERVICES.ADD_SCENE_BLOCK_VIEW = 'AddSceneBlockView';

    var AddBlockView = BB.View.extend({

        /**
         Constructor
         @method initialize
         **/
        initialize: function (options) {
            var self = this;

            self.m_sceneMime = undefined;
            self.m_placement = options.placement;

            // Clone the AddBlockTemplate
            var e = $(Elements.ADD_BLOCK_TEMPLATE).clone();
            $(self.options.el).append(e).fadeIn();
            $(e).show();
            self.el = self.$el[0];

            $(self.el).find('#prev').on('click', function () {
                self._goBack();
                return false;
            });

            self.listenTo(self.options.stackView, BB.EVENTS.SELECTED_STACK_VIEW, function (e) {
                if (e == self)
                    self._render();
            });
            self._buildBSAccordion();
        },

        /**
         Build lists of components, resources and scenes (respectively showing what's needed per placement mode)
         Once an LI is selected proper event fired to announce block is added.
         @method _render
         @return none
         **/
        _render: function () {
            var self = this;

            BB.comBroker.getService(BB.SERVICES.PROPERTIES_VIEW).resetPropertiesView();

            $(Elements.ADD_COMPONENT_BLOCK_LIST, self.el).empty();
            $(Elements.ADD_RESOURCE_BLOCK_LIST, self.el).empty();
            $(Elements.ADD_SCENE_BLOCK_LIST, self.el).empty();

            /////////////////////////////////////////////////////////
            // show component selection list
            /////////////////////////////////////////////////////////
            var components = BB.PepperHelper.getBlocks();
            var primeUpgradeText = $(Elements.MSG_BOOTBOX_ENTERPRISE_UPGRADE).text();
            var bufferFreeComp = '';
            var bufferPrimeComp = '';
            var specialJsonItemName = '';
            var specialJsonItemColor = '';
            //var sceneHasMimeType = '';
            for (var componentID in components) {
                var primeSnippet = '';
                var faOpacity = 1;
                var bufferSwitch = 0;

                if (componentID == BB.CONSTS.BLOCKCODE_IMAGE ||
                    componentID == BB.CONSTS.BLOCKCODE_SVG ||
                    componentID == BB.CONSTS.BLOCKCODE_TWITTER ||
                    componentID == BB.CONSTS.BLOCKCODE_TWITTER_ITEM ||
                    componentID == BB.CONSTS.BLOCKCODE_VIDEO ||
                    componentID == BB.CONSTS.BLOCKCODE_SCENE ||
                    (self.m_placement == BB.CONSTS.PLACEMENT_CHANNEL && componentID == BB.CONSTS.BLOCKCODE_JSON_ITEM) ||
                    (self.m_placement == BB.CONSTS.PLACEMENT_CHANNEL && componentID == BB.CONSTS.BLOCKCODE_TWITTER_ITEM) ||
                    (self.m_placement == BB.CONSTS.PLACEMENT_SCENE && componentID == BB.CONSTS.BLOCKCODE_JSON) ||
                    (self.m_placement == BB.CONSTS.PLACEMENT_SCENE && componentID == BB.CONSTS.BLOCKCODE_WORLD_WEATHER) ||
                    (self.m_placement == BB.CONSTS.PLACEMENT_SCENE && componentID == BB.CONSTS.BLOCKCODE_GOOGLE_SHEETS) ||
                    (self.m_placement == BB.CONSTS.PLACEMENT_SCENE && componentID == BB.CONSTS.BLOCKCODE_TWITTER)) {
                    continue;
                }

                // if PLACEMENT_SCENE and mimetype is set to specific, don't show any JSON based players
                if (self.m_sceneMime && self.m_placement == BB.CONSTS.PLACEMENT_SCENE) {
                    var jsonBasedPlayerXML = BB.PepperHelper.getBlockBoilerplate(componentID).getDefaultPlayerData(BB.CONSTS.PLACEMENT_SCENE);
                    jsonBasedPlayerXML = $.parseXML(jsonBasedPlayerXML);
                    if ($(jsonBasedPlayerXML).find('Json').length > 0)
                        continue;
                }

                // if PLACEMENT_SCENE and mimetype is set on scene, give special attention to JSON_ITEM component since it will often be the one user needs
                if (self.m_sceneMime && self.m_placement == BB.CONSTS.PLACEMENT_SCENE && componentID == BB.CONSTS.BLOCKCODE_JSON_ITEM) {
                    specialJsonItemName = BB.lib.capitaliseFirst(self.m_sceneMime.split('.')[1]);
                    specialJsonItemColor = BB.CONSTS['THEME'] === 'light' ? '#A9CFFA' : '#262627';
                } else {
                    specialJsonItemName = '';
                    specialJsonItemColor = '';
                }

                // check if and how to render components depending on user account type
                switch (self._checkAllowedComponent(componentID)) {
                    case 0:
                    {
                        continue;
                        break;
                    }

                    case 1:
                    {
                        bufferSwitch = 1;
                        primeSnippet = '';
                        faOpacity = 1;
                        break;
                    }

                    case 2:
                    {
                        bufferSwitch = 2;
                        primeSnippet = '<button type="button" class="primeComponent btn btn-primary btn-xs">' + primeUpgradeText + '</button>'
                        faOpacity = 0.7;
                        break;
                    }
                }

                var snippet = ' <li style="background-color: ' + specialJsonItemColor + '" class="list-group-item ' + BB.lib.unclass(Elements.CLASS_ADD_BLOCK_LIST_ITEMS, self.el) + '" data-component_id="' + componentID + '" data-component_name="' + (specialJsonItemName != '' ? specialJsonItemName : components[componentID].name) + '">';
                snippet += '        <i style="opacity: ' + faOpacity + '" class="fa ' + components[componentID].fontAwesome + '"></i>';
                snippet += '        <span style="opacity: ' + faOpacity + '"> ' + (specialJsonItemName != '' ? specialJsonItemName : components[componentID].name) + '</span>';
                snippet += '        <h6 style="opacity: ' + faOpacity + '"> ' + components[componentID].description + '</h6>' + primeSnippet;
                snippet += '    </li>';

                bufferSwitch == 1 ? bufferFreeComp += snippet : bufferPrimeComp += snippet;
            }

            $(Elements.ADD_COMPONENT_BLOCK_LIST, self.el).append(bufferFreeComp);
            $(Elements.ADD_COMPONENT_BLOCK_LIST, self.el).append(bufferPrimeComp);

            /////////////////////////////////////////////////////////
            // show resource selection list
            /////////////////////////////////////////////////////////

            var recResources = pepper.getResources();
            $(recResources).each(function (i) {

                // dont process deleted resources
                if (recResources[i]['change_type'] == 3)
                    return;

                var size = (parseInt(recResources[i]['resource_bytes_total']) / 1000).toFixed(2);
                var resourceDescription = 'size: ' + size + 'K dimension: ' + recResources[i]['resource_pixel_width'] + 'x' + recResources[i]['resource_pixel_height'];
                var snippet = '<li class="list-group-item ' + BB.lib.unclass(Elements.CLASS_ADD_BLOCK_LIST_ITEMS, self.el) + '" data-resource_id="' + recResources[i]['resource_id'] + '" data-resource_name="' + recResources[i]['resource_name'] + '">' +
                    '<i class="fa ' + BB.PepperHelper.getFontAwesome(recResources[i]['resource_type']) + '"></i>' +
                    '<span>' + recResources[i]['resource_name'] + '</span>' +
                    '<br/><small>' + resourceDescription + '</small>' +
                    '</li>';
                $(Elements.ADD_RESOURCE_BLOCK_LIST, self.el).append(snippet);
            });

            /////////////////////////////////////////////////////////
            // show scene selection list in Scene or block list modes
            /////////////////////////////////////////////////////////

            if (self.m_placement == BB.CONSTS.PLACEMENT_CHANNEL || self.m_placement == BB.CONSTS.PLACEMENT_LISTS) {
                var scenes = pepper.getScenes();
                _.each(scenes, function (scene, i) {
                    var label = $(scene).find('Player').eq(0).attr('label');
                    var sceneID = $(scene).find('Player').eq(0).attr('id');

                    // don't allow adding mimetype scenes to channels directly as needs to be added via Player block
                    if (self.m_placement == BB.CONSTS.PLACEMENT_CHANNEL) {
                        var mimeType = BB.Pepper.getSceneMime(sceneID);
                        if (!_.isUndefined(mimeType))
                            return;
                    }

                    sceneID = pepper.sterilizePseudoId(sceneID);
                    var snippet = '<li class="list-group-item ' + BB.lib.unclass(Elements.CLASS_ADD_BLOCK_LIST_ITEMS, self.el) + '" data-scene_id="' + sceneID + '">' +
                        '<i class="fa ' + BB.PepperHelper.getFontAwesome('scene') + '"></i>' +
                        '<span>' + label + '</span>' +
                        '<br/><small></small>' +
                        '</li>';
                    $(Elements.ADD_SCENE_BLOCK_LIST, self.el).append(snippet);
                });
            }

            if (self.m_placement == BB.CONSTS.PLACEMENT_SCENE) {
                $(Elements.ADD_COMPONENTS_BLOCK_LIST_CONTAINER, self.el).show();
                $(Elements.ADD_SCENE_BLOCK_LIST_CONTAINER, self.el).hide();
            }


            if (self.m_placement == BB.CONSTS.PLACEMENT_LISTS) {
                $(Elements.ADD_COMPONENTS_BLOCK_LIST_CONTAINER, self.el).hide();
                $(Elements.ADD_SCENE_BLOCK_LIST_CONTAINER, self.el).show();
            }


            if (self.m_placement == BB.CONSTS.PLACEMENT_CHANNEL) {
                $(Elements.ADD_COMPONENTS_BLOCK_LIST_CONTAINER, self.el).show();
                $(Elements.ADD_SCENE_BLOCK_LIST_CONTAINER, self.el).show();
            }


            self._listenSelection();

            //reset mimetype
            self.m_sceneMime = undefined;
        },

        /**
         Listen to list selection of components / resources / scenes
         @method _listenSelection
         **/
        _listenSelection: function () {
            var self = this;
            $(Elements.CLASS_ADD_BLOCK_LIST_ITEMS, self.el).on('click', function (e) {
                var component_id = $(e.target).closest('li').data('component_id');
                var resource_id = $(e.target).closest('li').data('resource_id');
                var scene_id = $(e.target).closest('li').data('scene_id');
                var primeComp = $(e.target).closest('li').find(Elements.CLASS_PRIME_COMPONENT);
                var blockCode = -1;

                if (primeComp.length > 0) {
                    $(Elements.UPGRADE_MODAL).modal('show');
                    return;
                    //Bootbox.dialog({
                    //    message: $(Elements.MSG_BOOTBOX_ENTERPRISE_UPGRADE_TEXT).text(),
                    //    title: $(Elements.MSG_BOOTBOX_ENTERPRISE_UPGRADE).text(),
                    //    buttons: {
                    //        success: {
                    //            label: $(Elements.MSG_BOOTBOX_ENTERPRISE_UPGRADE).text(),
                    //            className: "btn-success",
                    //            callback: function () {
                    //                BB.comBroker.getService(BB.SERVICES.NAVIGATION_VIEW).selectNavigation(Elements.CLASSS_PRO_STUDIO_PANEL);
                    //            }
                    //        },
                    //        main: {
                    //            label: $(Elements.MSG_BOOTBOX_OK).text(),
                    //            className: "btn-primary"
                    //        }
                    //    }
                    //});
                }

                if (!_.isUndefined(component_id)) {
                    blockCode = component_id;
                } else if (!_.isUndefined(resource_id)) {
                    blockCode = BB.PepperHelper.getBlockCodeFromFileExt(pepper.getResourceType(resource_id));
                } else if (!_.isUndefined(scene_id)) {
                    blockCode = 3510;
                }

                var eventName;
                switch (self.options.placement) {
                    case BB.CONSTS.PLACEMENT_CHANNEL:
                    {
                        eventName = BB.EVENTS.ADD_NEW_BLOCK_CHANNEL;
                        break;
                    }
                    case BB.CONSTS.PLACEMENT_SCENE:
                    {
                        eventName = BB.EVENTS.ADD_NEW_BLOCK_SCENE;
                        break;
                    }
                    case BB.CONSTS.PLACEMENT_LISTS:
                    {
                        eventName = BB.EVENTS.ADD_NEW_BLOCK_LIST;
                        break;
                    }
                }

                BB.comBroker.fire(eventName, this, self.options.placement, {
                    blockCode: blockCode,
                    resourceID: resource_id,
                    sceneID: scene_id
                });
                self.deSelectView();
            });
        },

        /**
         Check if component is allowed under enterprise / prime membership
         Note that if running under Hybrid or Private server default is to always allow
         all components
         @method _checkAllowedComponent
         @param {Number} i_componentID
         @return {Number} 0 = hide, 1 = show, 2 = upgradable
         **/
        _checkAllowedComponent: function (i_componentID) {
            if (window.g_private_hybrid)
                return 1;
            // free component so show it

            // FasterQ, open to all
            if (i_componentID == 6100) {
                return 1;
            }
            var appID = BB.PepperHelper.getBlockBoilerplate(i_componentID).app_id;
            if (_.isUndefined(appID))
                return 1;

            // component is prime, account is free type, upgradable
            if (pepper.getUserData().resellerID == 1)
                return 2;

            // account is under a reseller and component not available, hide it
            if (pepper.getUserData().resellerID != 1 && _.isUndefined(pepper.getUserData().components[appID]))
                return 0;

            // account is under a reseller and component is available, show it
            return 1;
        },

        /**
         Hook onto bootstrap accordion so user can select new block to add
         @method _buildBSAccordion
         **/
        _buildBSAccordion: function () {
            var self = this;
            var uniqueID = _.uniqueId('addBlockAccord');
            self.$el.find('#addNewBlockListPanel').attr('id', uniqueID);
            self.$el.find('a').attr('data-parent', '#' + uniqueID).eq(0);
            for (var i = 0; i < 3; i++) {
                var unique = _.uniqueId('addBlockAccord')
                self.$el.find('a').eq(i).attr('href', '#' + unique);
                self.$el.find('.panel-collapse').eq(i).attr('id', unique);
            }
        },

        /**
         Go back after selection
         @method _goBack
         **/
        _goBack: function () {
            var self = this;
            switch (self.options.placement) {
                case BB.CONSTS.PLACEMENT_CHANNEL:
                {
                    self.options.stackView.slideToPage(self.options.from, 'left');
                    break;
                }
                case BB.CONSTS.PLACEMENT_SCENE:
                {
                    self.m_sceneSliderView = BB.comBroker.getService(BB.SERVICES['SCENE_SLIDER_VIEW']);
                    self.m_sceneSliderView.slideToPage(Elements.SCENE_SLIDER_ELEMENT_VIEW, 'left');
                    break;
                }
                case BB.CONSTS.PLACEMENT_LISTS:
                {
                    self.options.stackView.slideToPage(self.options.from, 'left');
                    break;
                }
            }
        },

        /**
         Select current view which will animate page loading
         @method selectView
         **/
        selectView: function () {
            var self = this;
            self.options.stackView.slideToPage(self, 'right');
        },

        /**
         Deselect current view which will animate page unloading
         @method deSelectView
         **/
        deSelectView: function () {
            var self = this;
            self._goBack();
        },

        /**
         Allow us to control the current placement of the module so the behaviour can be according
         to where the instance resides (i.e.: current launch is from Block collection list of from Channel list
         for example)
         @method setPlacement
         @param {Number} i_playerData
         **/
        setPlacement: function (i_placement) {
            var self = this;
            self.m_placement = self.options.placement = i_placement;
        },

        /**
         Allow us to control the view depending upon the current mimetype of the scene that launched this
         instance. Keep in mind that m_sceneMime is only set for one duration of _render.
         Once rendered the list, we reset the m_sceneMime back to undefined so
         @method setSceneMime
         @param {String} i_mimeType
         **/
        setSceneMime: function (i_mimeType) {
            var self = this;
            self.m_sceneMime = i_mimeType;
        }
    });

    return AddBlockView;
});