Show:
  1. /**
  2. ResourceListView is responsible for managing the UI of selecting, adding and deleting resources (i.e.: video, images and swfs)
  3. as well as property management of resources, such as renaming a resource.
  4. @class CompResourcesList
  5. @constructor
  6. @return {Object} instantiated CompResourcesList
  7. **/
  8. define(['jquery', 'backbone', 'bootstrapfileinput', 'video', 'platform'], function ($, Backbone, bootstrapfileinput, videojs, platform) {
  9.  
  10. var ResourceListView = BB.View.extend({
  11.  
  12. /**
  13. Init the ChannelList component and enable sortable channels UI via drag and drop operations.
  14. @method _init
  15. @return none
  16. **/
  17. initialize: function () {
  18. var self = this;
  19. self.m_property = BB.comBroker.getService(BB.SERVICES['PROPERTIES_VIEW']);
  20. self.m_property.initPanel(Elements.RESOURCE_LIST_PROPERTIES);
  21. self.m_videoPlayer = undefined;
  22. self._listenInputChange();
  23. self._initVideo();
  24. $('input[type=file]').bootstrapFileInput();
  25. self._listenRemoveResource();
  26. $(Elements.FILE_SELECTION).change(function (e) {
  27. self._onFileSelected(e);
  28. });
  29. self.render();
  30. },
  31.  
  32. /**
  33. When user changes text update msdb, we use xSavePlayerData
  34. as a json boilerplate that we append values to and save it in msdb as player_data
  35. @method _listenInputChange
  36. @return none
  37. **/
  38. _listenInputChange: function () {
  39. var self = this;
  40. var onChange = _.debounce(function (e) {
  41. var text = $(e.target).val();
  42. if (BB.lib.isEmpty(text))
  43. return;
  44. text = BB.lib.cleanProbCharacters(text,1);
  45. pepper.setResourceRecord(self.m_selected_resource_id, 'resource_name', text);
  46. var elem = self.$el.find('[data-resource_id="' + self.m_selected_resource_id + '"]');
  47. elem.find('span').text(text);
  48. }, 333);
  49. $(Elements.SELECTED_LIB_RESOURCE_NAME).on("input", onChange);
  50. },
  51.  
  52. /**
  53. Listen to remove resource event
  54. @method _listenRemoveResource
  55. @return none
  56. **/
  57. _listenRemoveResource: function () {
  58. var self = this;
  59. $(Elements.FILE_REMOVE).on('click', function (e) {
  60. if (self.m_selected_resource_id == undefined)
  61. return;
  62. // notify before so channel instances can remove blocks & after so channelList refresh UI
  63. BB.comBroker.fire(BB.EVENTS.REMOVING_RESOURCE, this, null, self.m_selected_resource_id);
  64. pepper.removeResource(self.m_selected_resource_id);
  65. pepper.removeBlocksWithResourceID(self.m_selected_resource_id);
  66. pepper.removeResourceFromBlockCollectionInScenes(self.m_selected_resource_id);
  67. pepper.removeResourceFromBlockCollectionsInChannel(self.m_selected_resource_id);
  68. self.render();
  69. self._listenResourceSelected();
  70. BB.comBroker.fire(BB.EVENTS.REMOVED_RESOURCE, this, null, self.m_selected_resource_id);
  71. });
  72. },
  73.  
  74. /**
  75. Listen to resource selection, populate the properties panel and open it if needed.
  76. @method _listenResourceSelected
  77. **/
  78. _listenResourceSelected: function () {
  79. var self = this;
  80.  
  81. $(Elements.CLASS_RESOURCES_LIST_ITEMS).off('click');
  82. $(Elements.CLASS_RESOURCES_LIST_ITEMS).on('click', function (e) {
  83. var resourceElem = $(e.target).closest('li');
  84. self.m_selected_resource_id = $(resourceElem).data('resource_id');
  85. $(Elements.CLASS_RESOURCES_LIST_ITEMS).removeClass('activated').find('a').removeClass('whiteFont');
  86. $(resourceElem).addClass('activated').find('a').addClass('whiteFont');
  87. var recResource = pepper.getResourceRecord(self.m_selected_resource_id);
  88. $(Elements.SELECTED_LIB_RESOURCE_NAME).val(recResource['resource_name']);
  89. self.m_property.viewPanel(Elements.RESOURCE_LIST_PROPERTIES);
  90.  
  91. if (platform.name == 'Chrome'){
  92. self._populateResourcePreviewCDN(recResource);
  93. } else {
  94. self._populateResourcePreviewLegacy(recResource);
  95. }
  96. return false;
  97. });
  98. },
  99.  
  100. /**
  101. Populate the resource preview with loaded resource file (none CDN)
  102. @method _populateResourcePreviewLegacy
  103. @param {Object} i_recResource
  104. **/
  105. _populateResourcePreviewLegacy: function (i_recResource) {
  106. var self = this;
  107. var path;
  108. if (self.m_videoPlayer){
  109. self.m_videoPlayer.pause();
  110. self.m_videoPlayer.load();
  111. }
  112.  
  113. switch (i_recResource['resource_type']){
  114. case 'jpg': {
  115. var ext = 'jpg';
  116. }
  117. case 'png': {
  118. if (!ext)
  119. ext = 'png';
  120. path = window.g_protocol + pepper.getUserData().domain + '/Resources/business' + pepper.getUserData().businessID + '/resources/' + pepper.getResourceNativeID(i_recResource['resource_id']) + '.' + ext;
  121. $(Elements.RESOURCE_PREVIEW_VIDEO).hide();
  122. $(Elements.RESOURCE_PREVIEW_IMAGE).fadeIn();
  123. $(Elements.RESOURCE_PREVIEW_SVG).hide();
  124. var $img = $(Elements.RESOURCE_PREVIEW_IMAGE).find('img');
  125. $img.attr('src',path);
  126. break;
  127. }
  128. case 'mp4': {
  129. var ext = 'mp4';
  130. }
  131. case 'flv': {
  132. if (!ext)
  133. ext = 'flv';
  134. $(Elements.RESOURCE_PREVIEW_IMAGE).hide();
  135. $(Elements.RESOURCE_PREVIEW_SVG).hide();
  136. $(Elements.RESOURCE_PREVIEW_VIDEO).fadeIn();
  137. path = window.g_protocol + pepper.getUserData().domain + '/Resources/business' + pepper.getUserData().businessID + '/resources/' + pepper.getResourceNativeID(i_recResource['resource_id']) + '.' + ext;
  138. $(Elements.VIDEO_PREVIEW).find('video:nth-child(1)').attr("src",path);
  139. break
  140. }
  141. case 'swf': {
  142. path = './_assets/flash.png';
  143. $(Elements.RESOURCE_PREVIEW_VIDEO).hide();
  144. $(Elements.RESOURCE_PREVIEW_SVG).hide();
  145. $(Elements.RESOURCE_PREVIEW_IMAGE).fadeIn();
  146. var $img = $(Elements.RESOURCE_PREVIEW_IMAGE).find('img');
  147. $img.attr('src',path);
  148. break
  149. }
  150. case 'svg': {
  151. path = window.g_protocol + pepper.getUserData().domain + '/Resources/business' + pepper.getUserData().businessID + '/resources/' + pepper.getResourceNativeID(i_recResource['resource_id']) + '.' + 'svg';
  152. $(Elements.RESOURCE_PREVIEW_VIDEO).hide();
  153. $(Elements.RESOURCE_PREVIEW_IMAGE).hide();
  154. $(Elements.RESOURCE_PREVIEW_SVG).fadeIn();
  155. var $img = $(Elements.RESOURCE_PREVIEW_SVG).find('object');
  156. var urlPath = $.base64.encode(path);
  157. var srvPath = 'https://secure.digitalsignage.com/proxyRequest/' + urlPath;
  158.  
  159. // load svg and force w/h
  160. $.get(srvPath, function(svg) {
  161. var svgHeight, svgWidth, re;
  162.  
  163. svgHeight = svg.match(/(height=")([^\"]*)/)[2];
  164. re = new RegExp('height="' + svgHeight + '"', "ig");
  165. svg = svg.replace(re, 'height="100"');
  166.  
  167. svgWidth = svg.match(/(width=")([^\"]*)/)[2];
  168. re = new RegExp('width="' + svgWidth + '"', "ig");
  169. svg = svg.replace(re, 'width="100"');
  170.  
  171. $('#resourcePreviewSVG').empty();
  172. var s = new String(svg);
  173. $('#resourcePreviewSVG').append(svg).wrap('<center>');
  174. });
  175. break
  176. }
  177. }
  178. },
  179.  
  180. /**
  181. Populate the resource preview with loaded resource file (CDN)
  182. @method _populateResourcePreviewCDN
  183. @param {Object} i_recResource
  184. **/
  185. _populateResourcePreviewCDN: function (i_recResource) {
  186. var self = this;
  187. if (self.m_videoPlayer){
  188. self.m_videoPlayer.pause();
  189. self.m_videoPlayer.load();
  190. }
  191. var path = window.g_protocol + 's3.signage.me/business' + pepper.getUserData().businessID + '/resources/';
  192.  
  193. switch (i_recResource['resource_type']){
  194. case 'jpg': {
  195. var ext = 'jpg';
  196. }
  197. case 'png': {
  198. if (!ext)
  199. ext = 'png';
  200. path += pepper.getResourceNativeID(i_recResource['resource_id']) + '.' + ext;
  201. $(Elements.RESOURCE_PREVIEW_VIDEO).hide();
  202. $(Elements.RESOURCE_PREVIEW_IMAGE).fadeIn();
  203. $(Elements.RESOURCE_PREVIEW_SVG).hide();
  204. var $img = $(Elements.RESOURCE_PREVIEW_IMAGE).find('img');
  205. $img.attr('src',path);
  206. break;
  207. }
  208. case 'mp4': {
  209. var ext = 'mp4';
  210. }
  211. case 'flv': {
  212. if (!ext)
  213. ext = 'flv';
  214. $(Elements.RESOURCE_PREVIEW_IMAGE).hide();
  215. $(Elements.RESOURCE_PREVIEW_SVG).hide();
  216. $(Elements.RESOURCE_PREVIEW_VIDEO).fadeIn();
  217. path += pepper.getResourceNativeID(i_recResource['resource_id']) + '.' + ext;
  218. // path = window.g_protocol + pepper.getUserData().domain + '/Resources/business' + pepper.getUserData().businessID + '/resources/' + pepper.getResourceNativeID(i_recResource['resource_id']) + '.' + ext;
  219. $(Elements.VIDEO_PREVIEW).find('video:nth-child(1)').attr("src",path);
  220. break
  221. }
  222. case 'swf': {
  223. path = './_assets/flash.png';
  224. $(Elements.RESOURCE_PREVIEW_VIDEO).hide();
  225. $(Elements.RESOURCE_PREVIEW_SVG).hide();
  226. $(Elements.RESOURCE_PREVIEW_IMAGE).fadeIn();
  227. var $img = $(Elements.RESOURCE_PREVIEW_IMAGE).find('img');
  228. $img.attr('src',path);
  229. break
  230. }
  231. case 'svg': {
  232. path = window.g_protocol + pepper.getUserData().domain + '/Resources/business' + pepper.getUserData().businessID + '/resources/' + pepper.getResourceNativeID(i_recResource['resource_id']) + '.' + 'svg';
  233. // path += pepper.getResourceNativeID(i_recResource['resource_id']) + '.' + 'svg';
  234. $(Elements.RESOURCE_PREVIEW_VIDEO).hide();
  235. $(Elements.RESOURCE_PREVIEW_IMAGE).hide();
  236. $(Elements.RESOURCE_PREVIEW_SVG).fadeIn();
  237. var $img = $(Elements.RESOURCE_PREVIEW_SVG).find('object');
  238. var urlPath = $.base64.encode(path);
  239. var srvPath = 'https://secure.digitalsignage.com/proxyRequest/' + urlPath;
  240.  
  241. // load svg and force w/h
  242. $.get(srvPath, function(svg) {
  243. var svgHeight, svgWidth, re;
  244.  
  245. svgHeight = svg.match(/(height=")([^\"]*)/)[2];
  246. re = new RegExp('height="' + svgHeight + '"', "ig");
  247. svg = svg.replace(re, 'height="100"');
  248.  
  249. svgWidth = svg.match(/(width=")([^\"]*)/)[2];
  250. re = new RegExp('width="' + svgWidth + '"', "ig");
  251. svg = svg.replace(re, 'width="100"');
  252.  
  253. $('#resourcePreviewSVG').empty();
  254. var s = new String(svg);
  255. $('#resourcePreviewSVG').append(svg).wrap('<center>');
  256. });
  257. break
  258. }
  259. }
  260. log('Loading file from ' + path);
  261. },
  262.  
  263. /**
  264. init HTML5 video.js component
  265. @method _listenAutoPopup
  266. **/
  267. _initVideo: function(){
  268. var self = this;
  269. videojs(BB.lib.unhash(Elements.VIDEO_PREVIEW)).ready(function () {
  270. self.m_videoPlayer = this;
  271. });
  272. },
  273.  
  274. /**
  275. On selecting new resources through multi-upload from local machine.
  276. @method _onFileSelected
  277. @return {number} -1 on fail or 1 on pass
  278. **/
  279. _onFileSelected: function (e) {
  280. var self = this;
  281. var status = pepper.uploadResources('file');
  282. if (status.length==0){
  283. bootbox.alert($(Elements.BOOTBOX_SUPPORTED_EXTENSIONS).text());
  284. return -1;
  285. }
  286.  
  287. self.render();
  288. self._listenResourceSelected();
  289. self._listenRemoveResource();
  290. var navigationView = BB.comBroker.getService(BB.SERVICES.NAVIGATION_VIEW);
  291. bootbox.alert($(Elements.MSG_BOOTBOX_WAIT_UPLOAD_RESOURCE).text());
  292. navigationView.save(function(){
  293. })
  294. setTimeout(function() {
  295. bootbox.hideAll();
  296. }, 3000);
  297. return 1;
  298. },
  299.  
  300.  
  301. /**
  302. Populate the UI with all resources for the account (i.e.: videos, images, swfs).
  303. @method render
  304. @return none
  305. **/
  306. render: function () {
  307. var self = this;
  308. $(Elements.RESOURCE_LIB_LIST).empty();
  309.  
  310. var recResources = pepper.getResources();
  311. $(recResources).each(function (i) {
  312. // dont process deleted resources
  313. if (recResources[i]['change_type'] == 3)
  314. return;
  315. var size = (parseInt(recResources[i]['resource_bytes_total']) / 1000).toFixed(2);
  316. var resourceDescription = 'size: ' + size + 'K dimenstion: ' + recResources[i]['resource_pixel_width'] + 'x' + recResources[i]['resource_pixel_height'];
  317. var resourceFontAwesome = BB.PepperHelper.getFontAwesome(recResources[i]['resource_type'])
  318. if (_.isUndefined(resourceFontAwesome)){
  319. bootbox.alert($(Elements.MSG_BOOTBOX_FILE_FORMAT_INVALID).text());
  320. } else {
  321. var snippet = '<li class="' + BB.lib.unclass(Elements.CLASS_RESOURCES_LIST_ITEMS) + ' list-group-item" data-resource_id="' + recResources[i]['resource_id'] + '">' +
  322. '<a href="#">' +
  323. '<i class="fa ' + resourceFontAwesome + '"></i>'+
  324. '<span>' + recResources[i]['resource_name'] + '</span>' +
  325. '<p>' + '' + '</p></a>' +
  326. '</a>' +
  327. '</li>';
  328.  
  329. $(Elements.RESOURCE_LIB_LIST).append($(snippet));
  330. }
  331. });
  332. self._listenResourceSelected();
  333. },
  334.  
  335. /**
  336. Unrender, future support
  337. @method unrender
  338. **/
  339. unrender: function(){
  340. var self = this;
  341. }
  342. });
  343.  
  344. return ResourceListView;
  345.  
  346. });