APIs

Show:
  1. /**
  2. Add block view is a UI component which allows selection and insertion of a new component (i.e. QR / RSS ...)
  3. or a resource to be added to the currently selected timeline_channel.
  4. We also skip displaying certain components / scenes dependon
  5.  
  6.  
  7. @class AddBlockView
  8. @constructor
  9. @return {object} instantiated AddBlockView
  10. **/
  11. define(['jquery', 'backbone', 'StackView', 'ScreenTemplateFactory', 'bootbox'], function ($, Backbone, StackView, ScreenTemplateFactory, Bootbox) {
  12.  
  13. /**
  14. Custom event fired when a new block is added to timeline_channel
  15. @event ADD_NEW_BLOCK_CHANNEL
  16. @param {this} caller
  17. @param {self} context caller
  18. @param {event} player_code which represents a specific code assigned for each block type
  19. @static
  20. @final
  21. **/
  22. BB.EVENTS.ADD_NEW_BLOCK_CHANNEL = 'ADD_NEW_BLOCK_CHANNEL';
  23.  
  24. /**
  25. Custom event fired when a new block is added to scene
  26. @event ADD_NEW_BLOCK_SCENE
  27. @param {this} caller
  28. @param {self} context caller
  29. @param {event} player_code which represents a specific code assigned for each block type
  30. @static
  31. @final
  32. **/
  33. BB.EVENTS.ADD_NEW_BLOCK_SCENE = 'ADD_NEW_BLOCK_SCENE';
  34.  
  35. /**
  36. Custom event fired when a new block is added to scene
  37. @event ADD_NEW_BLOCK_SCENE
  38. @param {this} caller
  39. @param {self} context caller
  40. @param {event} player_code which represents a specific code assigned for each block type
  41. @static
  42. @final
  43. **/
  44. BB.EVENTS.ADD_NEW_BLOCK_LIST = 'ADD_NEW_BLOCK_LIST';
  45.  
  46.  
  47. /** SERVICES **/
  48. BB.SERVICES.ADD_BLOCK_VIEW = 'AddBlockView';
  49. BB.SERVICES.ADD_SCENE_BLOCK_VIEW = 'AddSceneBlockView';
  50.  
  51. var AddBlockView = BB.View.extend({
  52.  
  53. /**
  54. Constructor
  55. @method initialize
  56. **/
  57. initialize: function (options) {
  58. var self = this;
  59.  
  60. self.m_sceneMime = undefined;
  61. self.m_placement = options.placement;
  62.  
  63. // Clone the AddBlockTemplate
  64. var e = $(Elements.ADD_BLOCK_TEMPLATE).clone();
  65. $(self.options.el).append(e).fadeIn();
  66. $(e).show();
  67. self.el = self.$el[0];
  68.  
  69. $(self.el).find('#prev').on('click', function () {
  70. self._goBack();
  71. return false;
  72. });
  73.  
  74. self.listenTo(self.options.stackView, BB.EVENTS.SELECTED_STACK_VIEW, function (e) {
  75. if (e == self)
  76. self._render();
  77. });
  78. self._buildBSAccordion();
  79. },
  80.  
  81. /**
  82. Build lists of components, resources and scenes (respectively showing what's needed per placement mode)
  83. Once an LI is selected proper event fired to announce block is added.
  84. @method _render
  85. @return none
  86. **/
  87. _render: function () {
  88. var self = this;
  89.  
  90. BB.comBroker.getService(BB.SERVICES.PROPERTIES_VIEW).resetPropertiesView();
  91.  
  92. $(Elements.ADD_COMPONENT_BLOCK_LIST, self.el).empty();
  93. $(Elements.ADD_RESOURCE_BLOCK_LIST, self.el).empty();
  94. $(Elements.ADD_SCENE_BLOCK_LIST, self.el).empty();
  95.  
  96. /////////////////////////////////////////////////////////
  97. // show component selection list
  98. /////////////////////////////////////////////////////////
  99. var components = BB.PepperHelper.getBlocks();
  100. var primeUpgradeText = $(Elements.MSG_BOOTBOX_ENTERPRISE_UPGRADE).text();
  101. var bufferFreeComp = '';
  102. var bufferPrimeComp = '';
  103. var specialJsonItemName = '';
  104. var specialJsonItemColor = '';
  105. //var sceneHasMimeType = '';
  106. for (var componentID in components) {
  107. var primeSnippet = '';
  108. var faOpacity = 1;
  109. var bufferSwitch = 0;
  110.  
  111. if (componentID == BB.CONSTS.BLOCKCODE_IMAGE ||
  112. componentID == BB.CONSTS.BLOCKCODE_SVG ||
  113. componentID == BB.CONSTS.BLOCKCODE_TWITTER ||
  114. componentID == BB.CONSTS.BLOCKCODE_TWITTER_ITEM ||
  115. componentID == BB.CONSTS.BLOCKCODE_VIDEO ||
  116. componentID == BB.CONSTS.BLOCKCODE_SCENE ||
  117. (self.m_placement == BB.CONSTS.PLACEMENT_CHANNEL && componentID == BB.CONSTS.BLOCKCODE_JSON_ITEM) ||
  118. (self.m_placement == BB.CONSTS.PLACEMENT_CHANNEL && componentID == BB.CONSTS.BLOCKCODE_TWITTER_ITEM) ||
  119. (self.m_placement == BB.CONSTS.PLACEMENT_SCENE && componentID == BB.CONSTS.BLOCKCODE_JSON) ||
  120. (self.m_placement == BB.CONSTS.PLACEMENT_SCENE && componentID == BB.CONSTS.BLOCKCODE_WORLD_WEATHER) ||
  121. (self.m_placement == BB.CONSTS.PLACEMENT_SCENE && componentID == BB.CONSTS.BLOCKCODE_GOOGLE_SHEETS) ||
  122. (self.m_placement == BB.CONSTS.PLACEMENT_SCENE && componentID == BB.CONSTS.BLOCKCODE_TWITTER)) {
  123. continue;
  124. }
  125.  
  126. // if PLACEMENT_SCENE and mimetype is set to specific, don't show any JSON based players
  127. if (self.m_sceneMime && self.m_placement == BB.CONSTS.PLACEMENT_SCENE) {
  128. var jsonBasedPlayerXML = BB.PepperHelper.getBlockBoilerplate(componentID).getDefaultPlayerData(BB.CONSTS.PLACEMENT_SCENE);
  129. jsonBasedPlayerXML = $.parseXML(jsonBasedPlayerXML);
  130. if ($(jsonBasedPlayerXML).find('Json').length > 0)
  131. continue;
  132. }
  133.  
  134. // 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
  135. if (self.m_sceneMime && self.m_placement == BB.CONSTS.PLACEMENT_SCENE && componentID == BB.CONSTS.BLOCKCODE_JSON_ITEM) {
  136. specialJsonItemName = BB.lib.capitaliseFirst(self.m_sceneMime.split('.')[1]);
  137. specialJsonItemColor = BB.CONSTS['THEME'] === 'light' ? '#A9CFFA' : '#262627';
  138. } else {
  139. specialJsonItemName = '';
  140. specialJsonItemColor = '';
  141. }
  142.  
  143. // check if and how to render components depending on user account type
  144. switch (self._checkAllowedComponent(componentID)) {
  145. case 0:
  146. {
  147. continue;
  148. break;
  149. }
  150.  
  151. case 1:
  152. {
  153. bufferSwitch = 1;
  154. primeSnippet = '';
  155. faOpacity = 1;
  156. break;
  157. }
  158.  
  159. case 2:
  160. {
  161. bufferSwitch = 2;
  162. primeSnippet = '<button type="button" class="primeComponent btn btn-primary btn-xs">' + primeUpgradeText + '</button>'
  163. faOpacity = 0.7;
  164. break;
  165. }
  166. }
  167.  
  168. 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) + '">';
  169. snippet += ' <i style="opacity: ' + faOpacity + '" class="fa ' + components[componentID].fontAwesome + '"></i>';
  170. snippet += ' <span style="opacity: ' + faOpacity + '"> ' + (specialJsonItemName != '' ? specialJsonItemName : components[componentID].name) + '</span>';
  171. snippet += ' <h6 style="opacity: ' + faOpacity + '"> ' + components[componentID].description + '</h6>' + primeSnippet;
  172. snippet += ' </li>';
  173.  
  174. bufferSwitch == 1 ? bufferFreeComp += snippet : bufferPrimeComp += snippet;
  175. }
  176.  
  177. $(Elements.ADD_COMPONENT_BLOCK_LIST, self.el).append(bufferFreeComp);
  178. $(Elements.ADD_COMPONENT_BLOCK_LIST, self.el).append(bufferPrimeComp);
  179.  
  180. /////////////////////////////////////////////////////////
  181. // show resource selection list
  182. /////////////////////////////////////////////////////////
  183.  
  184. var recResources = pepper.getResources();
  185. $(recResources).each(function (i) {
  186.  
  187. // dont process deleted resources
  188. if (recResources[i]['change_type'] == 3)
  189. return;
  190.  
  191. var size = (parseInt(recResources[i]['resource_bytes_total']) / 1000).toFixed(2);
  192. var resourceDescription = 'size: ' + size + 'K dimension: ' + recResources[i]['resource_pixel_width'] + 'x' + recResources[i]['resource_pixel_height'];
  193. 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'] + '">' +
  194. '<i class="fa ' + BB.PepperHelper.getFontAwesome(recResources[i]['resource_type']) + '"></i>' +
  195. '<span>' + recResources[i]['resource_name'] + '</span>' +
  196. '<br/><small>' + resourceDescription + '</small>' +
  197. '</li>';
  198. $(Elements.ADD_RESOURCE_BLOCK_LIST, self.el).append(snippet);
  199. });
  200.  
  201. /////////////////////////////////////////////////////////
  202. // show scene selection list in Scene or block list modes
  203. /////////////////////////////////////////////////////////
  204.  
  205. if (self.m_placement == BB.CONSTS.PLACEMENT_CHANNEL || self.m_placement == BB.CONSTS.PLACEMENT_LISTS) {
  206. var scenes = pepper.getScenes();
  207. _.each(scenes, function (scene, i) {
  208. var label = $(scene).find('Player').eq(0).attr('label');
  209. var sceneID = $(scene).find('Player').eq(0).attr('id');
  210.  
  211. // don't allow adding mimetype scenes to channels directly as needs to be added via Player block
  212. if (self.m_placement == BB.CONSTS.PLACEMENT_CHANNEL) {
  213. var mimeType = BB.Pepper.getSceneMime(sceneID);
  214. if (!_.isUndefined(mimeType))
  215. return;
  216. }
  217.  
  218. sceneID = pepper.sterilizePseudoId(sceneID);
  219. var snippet = '<li class="list-group-item ' + BB.lib.unclass(Elements.CLASS_ADD_BLOCK_LIST_ITEMS, self.el) + '" data-scene_id="' + sceneID + '">' +
  220. '<i class="fa ' + BB.PepperHelper.getFontAwesome('scene') + '"></i>' +
  221. '<span>' + label + '</span>' +
  222. '<br/><small></small>' +
  223. '</li>';
  224. $(Elements.ADD_SCENE_BLOCK_LIST, self.el).append(snippet);
  225. });
  226. }
  227.  
  228. if (self.m_placement == BB.CONSTS.PLACEMENT_SCENE) {
  229. $(Elements.ADD_COMPONENTS_BLOCK_LIST_CONTAINER, self.el).show();
  230. $(Elements.ADD_SCENE_BLOCK_LIST_CONTAINER, self.el).hide();
  231. }
  232.  
  233.  
  234. if (self.m_placement == BB.CONSTS.PLACEMENT_LISTS) {
  235. $(Elements.ADD_COMPONENTS_BLOCK_LIST_CONTAINER, self.el).hide();
  236. $(Elements.ADD_SCENE_BLOCK_LIST_CONTAINER, self.el).show();
  237. }
  238.  
  239.  
  240. if (self.m_placement == BB.CONSTS.PLACEMENT_CHANNEL) {
  241. $(Elements.ADD_COMPONENTS_BLOCK_LIST_CONTAINER, self.el).show();
  242. $(Elements.ADD_SCENE_BLOCK_LIST_CONTAINER, self.el).show();
  243. }
  244.  
  245.  
  246. self._listenSelection();
  247.  
  248. //reset mimetype
  249. self.m_sceneMime = undefined;
  250. },
  251.  
  252. /**
  253. Listen to list selection of components / resources / scenes
  254. @method _listenSelection
  255. **/
  256. _listenSelection: function () {
  257. var self = this;
  258. $(Elements.CLASS_ADD_BLOCK_LIST_ITEMS, self.el).on('click', function (e) {
  259. var component_id = $(e.target).closest('li').data('component_id');
  260. var resource_id = $(e.target).closest('li').data('resource_id');
  261. var scene_id = $(e.target).closest('li').data('scene_id');
  262. var primeComp = $(e.target).closest('li').find(Elements.CLASS_PRIME_COMPONENT);
  263. var blockCode = -1;
  264.  
  265. if (primeComp.length > 0) {
  266. $(Elements.UPGRADE_MODAL).modal('show');
  267. return;
  268. //Bootbox.dialog({
  269. // message: $(Elements.MSG_BOOTBOX_ENTERPRISE_UPGRADE_TEXT).text(),
  270. // title: $(Elements.MSG_BOOTBOX_ENTERPRISE_UPGRADE).text(),
  271. // buttons: {
  272. // success: {
  273. // label: $(Elements.MSG_BOOTBOX_ENTERPRISE_UPGRADE).text(),
  274. // className: "btn-success",
  275. // callback: function () {
  276. // BB.comBroker.getService(BB.SERVICES.NAVIGATION_VIEW).selectNavigation(Elements.CLASSS_PRO_STUDIO_PANEL);
  277. // }
  278. // },
  279. // main: {
  280. // label: $(Elements.MSG_BOOTBOX_OK).text(),
  281. // className: "btn-primary"
  282. // }
  283. // }
  284. //});
  285. }
  286.  
  287. if (!_.isUndefined(component_id)) {
  288. blockCode = component_id;
  289. } else if (!_.isUndefined(resource_id)) {
  290. blockCode = BB.PepperHelper.getBlockCodeFromFileExt(pepper.getResourceType(resource_id));
  291. } else if (!_.isUndefined(scene_id)) {
  292. blockCode = 3510;
  293. }
  294.  
  295. var eventName;
  296. switch (self.options.placement) {
  297. case BB.CONSTS.PLACEMENT_CHANNEL:
  298. {
  299. eventName = BB.EVENTS.ADD_NEW_BLOCK_CHANNEL;
  300. break;
  301. }
  302. case BB.CONSTS.PLACEMENT_SCENE:
  303. {
  304. eventName = BB.EVENTS.ADD_NEW_BLOCK_SCENE;
  305. break;
  306. }
  307. case BB.CONSTS.PLACEMENT_LISTS:
  308. {
  309. eventName = BB.EVENTS.ADD_NEW_BLOCK_LIST;
  310. break;
  311. }
  312. }
  313.  
  314. BB.comBroker.fire(eventName, this, self.options.placement, {
  315. blockCode: blockCode,
  316. resourceID: resource_id,
  317. sceneID: scene_id
  318. });
  319. self.deSelectView();
  320. });
  321. },
  322.  
  323. /**
  324. Check if component is allowed under enterprise / prime membership
  325. Note that if running under Hybrid or Private server default is to always allow
  326. all components
  327. @method _checkAllowedComponent
  328. @param {Number} i_componentID
  329. @return {Number} 0 = hide, 1 = show, 2 = upgradable
  330. **/
  331. _checkAllowedComponent: function (i_componentID) {
  332. if (window.g_private_hybrid)
  333. return 1;
  334. // free component so show it
  335.  
  336. // FasterQ, open to all
  337. if (i_componentID == 6100) {
  338. return 1;
  339. }
  340. var appID = BB.PepperHelper.getBlockBoilerplate(i_componentID).app_id;
  341. if (_.isUndefined(appID))
  342. return 1;
  343.  
  344. // component is prime, account is free type, upgradable
  345. if (pepper.getUserData().resellerID == 1)
  346. return 2;
  347.  
  348. // account is under a reseller and component not available, hide it
  349. if (pepper.getUserData().resellerID != 1 && _.isUndefined(pepper.getUserData().components[appID]))
  350. return 0;
  351.  
  352. // account is under a reseller and component is available, show it
  353. return 1;
  354. },
  355.  
  356. /**
  357. Hook onto bootstrap accordion so user can select new block to add
  358. @method _buildBSAccordion
  359. **/
  360. _buildBSAccordion: function () {
  361. var self = this;
  362. var uniqueID = _.uniqueId('addBlockAccord');
  363. self.$el.find('#addNewBlockListPanel').attr('id', uniqueID);
  364. self.$el.find('a').attr('data-parent', '#' + uniqueID).eq(0);
  365. for (var i = 0; i < 3; i++) {
  366. var unique = _.uniqueId('addBlockAccord')
  367. self.$el.find('a').eq(i).attr('href', '#' + unique);
  368. self.$el.find('.panel-collapse').eq(i).attr('id', unique);
  369. }
  370. },
  371.  
  372. /**
  373. Go back after selection
  374. @method _goBack
  375. **/
  376. _goBack: function () {
  377. var self = this;
  378. switch (self.options.placement) {
  379. case BB.CONSTS.PLACEMENT_CHANNEL:
  380. {
  381. self.options.stackView.slideToPage(self.options.from, 'left');
  382. break;
  383. }
  384. case BB.CONSTS.PLACEMENT_SCENE:
  385. {
  386. self.m_sceneSliderView = BB.comBroker.getService(BB.SERVICES['SCENE_SLIDER_VIEW']);
  387. self.m_sceneSliderView.slideToPage(Elements.SCENE_SLIDER_ELEMENT_VIEW, 'left');
  388. break;
  389. }
  390. case BB.CONSTS.PLACEMENT_LISTS:
  391. {
  392. self.options.stackView.slideToPage(self.options.from, 'left');
  393. break;
  394. }
  395. }
  396. },
  397.  
  398. /**
  399. Select current view which will animate page loading
  400. @method selectView
  401. **/
  402. selectView: function () {
  403. var self = this;
  404. self.options.stackView.slideToPage(self, 'right');
  405. },
  406.  
  407. /**
  408. Deselect current view which will animate page unloading
  409. @method deSelectView
  410. **/
  411. deSelectView: function () {
  412. var self = this;
  413. self._goBack();
  414. },
  415.  
  416. /**
  417. Allow us to control the current placement of the module so the behaviour can be according
  418. to where the instance resides (i.e.: current launch is from Block collection list of from Channel list
  419. for example)
  420. @method setPlacement
  421. @param {Number} i_playerData
  422. **/
  423. setPlacement: function (i_placement) {
  424. var self = this;
  425. self.m_placement = self.options.placement = i_placement;
  426. },
  427.  
  428. /**
  429. Allow us to control the view depending upon the current mimetype of the scene that launched this
  430. instance. Keep in mind that m_sceneMime is only set for one duration of _render.
  431. Once rendered the list, we reset the m_sceneMime back to undefined so
  432. @method setSceneMime
  433. @param {String} i_mimeType
  434. **/
  435. setSceneMime: function (i_mimeType) {
  436. var self = this;
  437. self.m_sceneMime = i_mimeType;
  438. }
  439. });
  440.  
  441. return AddBlockView;
  442. });
  443.  
  444.