PageRenderTime 26ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/booktype/apps/edit/static/edit/js/booktype/media.js

https://gitlab.com/wilane/Booktype
JavaScript | 293 lines | 207 code | 61 blank | 25 comment | 11 complexity | 5ee0df8c1dd33d0612fd173f388ba659 MD5 | raw file
  1. /*
  2. This file is part of Booktype.
  3. Copyright (c) 2013 Aleksandar Erkalovic <aleksandar.erkalovic@sourcefabric.org>
  4. Booktype is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU Affero General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. Booktype is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with Booktype. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. (function (win, jquery, _) {
  16. 'use strict';
  17. jquery.namespace('win.booktype.editor.media');
  18. win.booktype.editor.media = (function () {
  19. var fileUpload;
  20. var MediaItem = Backbone.Model.extend({
  21. defaults: {
  22. id: 0,
  23. name: '',
  24. preview: '',
  25. size: 0,
  26. created: '',
  27. status: null,
  28. dimension: null
  29. },
  30. getDimension: function () {
  31. var d = this.get('dimension');
  32. return d !== null ? d[0] + 'x' + d[1] : '';
  33. },
  34. getSize: function () {
  35. return win.booktype.utils.formatSize(this.get('size'));
  36. }
  37. });
  38. var MediaCollection = Backbone.Collection.extend({
  39. model: MediaItem
  40. });
  41. var MediaView = Backbone.View.extend({
  42. templRow: _.template('<tr>\
  43. <td>\
  44. <input type="checkbox" name="attachment" value="<%= id %>">\
  45. </td>\
  46. <td><a href="<%= link %>" target="_new"><img src="<%= preview %>" alt="<%= name %>" /></a></td>\
  47. <td><a href="<%= link %>" target="_new"><%= name %></a></td>\
  48. <td><%= dimension %></td>\
  49. <td class="size"><%= size %></td>\
  50. <td><%= date %></td>\
  51. </tr>'),
  52. render: function () {
  53. var $this = this;
  54. var rows = this.model.map(function (item) {
  55. return $this.templRow({
  56. 'name': item.get('name'),
  57. 'preview': item.get('preview'),
  58. 'id': item.get('id'),
  59. 'link': 'static/' + item.get('name'),
  60. 'size': item.getSize(),
  61. 'dimension': item.getDimension(),
  62. 'date': item.get('created')
  63. });
  64. });
  65. this.$el.html(rows.join(''));
  66. return this;
  67. }
  68. });
  69. var mediaItems = new MediaCollection();
  70. var mediaView = null;
  71. var MediaRouter = Backbone.Router.extend({
  72. routes: {
  73. 'media': 'media'
  74. },
  75. media: function () {
  76. var $d = jquery.Deferred();
  77. var activePanel = win.booktype.editor.getActivePanel();
  78. activePanel.hide(function () {
  79. win.booktype.editor.data.activePanel = win.booktype.editor.data.panels['media'];
  80. win.booktype.editor.data.activePanel.show();
  81. $d.resolve();
  82. });
  83. return $d.promise();
  84. }
  85. });
  86. var router = new MediaRouter();
  87. var drawAttachments = function () {
  88. if (mediaView) {
  89. mediaView.render();
  90. }
  91. };
  92. var loadAttachments = function () {
  93. win.booktype.ui.notify(win.booktype._('loading_media_files', 'Loading media files'));
  94. win.booktype.sendToCurrentBook({'command': 'attachments_list'},
  95. function (data) {
  96. win.booktype.ui.notify();
  97. mediaItems.reset(_.map(data.attachments, function (itm) { return new MediaItem(itm); }));
  98. drawAttachments();
  99. // disable delete button by default
  100. jquery('#delete-selected-items').attr('disabled', 'disabled');
  101. window.scrollTo(0, 0);
  102. }
  103. );
  104. };
  105. var _hideUploadProgress = function () {
  106. jquery('span.cancel-upload').fadeOut(function () {
  107. jquery('DIV.contentHeader .progress-bar').css('width', '0%');
  108. });
  109. jquery('#fileupload').prop('disabled', false);
  110. };
  111. var _show = function () {
  112. jquery('#button-media').addClass("active");
  113. var t = win.booktype.ui.getTemplate('templateMediaContent');
  114. jquery('#content').html(t);
  115. jquery('DIV.contentHeader .progress-bar').css('width', '0px');
  116. jquery('span.cancel-upload').hide();
  117. var t2 = win.booktype.ui.getTemplate('templateMediaToolbar');
  118. jquery('DIV.contentHeader').html(t2);
  119. jquery('DIV.contentHeader [rel=tooltip]').tooltip({container: 'body'});
  120. // Setup media widget
  121. mediaView = new MediaView({model: mediaItems, el: jquery('#content table tbody')});
  122. loadAttachments();
  123. jquery('#content #delete-selected-items').on('click', function () {
  124. var lst = win._.map(jquery('#content table INPUT[type=checkbox]:checked'), function (elem) { return jquery(elem).val(); }).join(',');
  125. jquery('#removeMedia').modal('show');
  126. jquery('#removeMedia INPUT[name=attachments]').val(lst);
  127. });
  128. jquery(document).on('change', '#content .mediaTable input[type="checkbox"]', function () {
  129. var checked_count = jquery('#content .mediaTable input[type="checkbox"]:checked').length;
  130. if (checked_count) {
  131. jquery('#delete-selected-items').removeAttr('disabled');
  132. } else {
  133. jquery('#delete-selected-items').attr('disabled', 'disabled');
  134. }
  135. });
  136. jquery('#removeMedia .remove-media').bind('click.media', function () {
  137. if (jquery('#removeMedia INPUT[name=understand]:checked').val() === 'on') {
  138. var lst = jquery('#removeMedia INPUT[name=attachments]').attr('value').split(',');
  139. if (lst.length === 0) { return; }
  140. win.booktype.ui.notify(win.booktype._('removing_media_files', 'Removing media files'));
  141. win.booktype.sendToCurrentBook({'command': 'attachments_delete', 'attachments': lst},
  142. function (data) {
  143. win.booktype.ui.notify();
  144. loadAttachments();
  145. jquery('#removeMedia').modal('hide');
  146. // Trigger event
  147. jquery(document).trigger('booktype-attachment-deleted');
  148. }
  149. );
  150. }
  151. });
  152. fileUpload = null;
  153. jquery('#fileupload').fileupload({
  154. dataType: 'json',
  155. sequentialUploads: true,
  156. done: function (e, data) {
  157. // data.result.files
  158. _hideUploadProgress();
  159. loadAttachments();
  160. jquery(document).trigger('booktype-attachment-uploaded', [data.files]);
  161. },
  162. add: function (e, data) {
  163. if (win.booktype.editor.getActivePanel().name !== 'media') { return; }
  164. var fileName = null;
  165. if (!_.isUndefined(data.files[0])) {
  166. fileName = data.files[0].name;
  167. }
  168. if (fileName) {
  169. if (win.booktype.utils.isUploadAllowed(fileName)) {
  170. jquery('#progress').show();
  171. jquery('span.cancel-upload').show();
  172. jquery('#fileupload').prop('disabled', true);
  173. fileUpload = data.submit();
  174. } else {
  175. var $error = jquery('#uploadMediaError');
  176. $error.modal('show');
  177. }
  178. }
  179. },
  180. progressall: function (e, data) {
  181. var progress = parseInt(data.loaded / data.total * 100, 10);
  182. jquery('DIV.contentHeader .progress-bar').css('width', progress + '%');
  183. },
  184. formData: {'clientID': win.booktype.clientID}
  185. });
  186. jquery('span.cancel-upload').on('click', function () {
  187. fileUpload.abort();
  188. _hideUploadProgress();
  189. });
  190. // Trigger events
  191. jquery(document).trigger('booktype-ui-panel-active', ['media', this]);
  192. };
  193. var _hide = function (callback) {
  194. // Hide tooltip
  195. jquery('DIV.contentHeader [rel=tooltip]').tooltip('destroy');
  196. jquery('#button-media').removeClass("active");
  197. jquery('#removeMedia .remove-media').unbind('click.media');
  198. mediaView.remove();
  199. mediaView = null;
  200. // Hide content
  201. jquery('#content').empty();
  202. jquery('DIV.contentHeader').empty();
  203. if (!_.isUndefined(callback)) {
  204. callback();
  205. }
  206. };
  207. var _init = function () {
  208. jquery('#button-media').on('click', function (e) { Backbone.history.navigate('media', true); });
  209. // Remove Media
  210. jquery('#removeMedia').on('show.bs.modal', function () {
  211. jquery('#removeMedia .remove-media').prop('disabled', true);
  212. jquery('#removeMedia INPUT[name=understand]').prop('checked', false);
  213. });
  214. jquery('#removeMedia .close-button').on('click', function () {
  215. jquery('#removeMedia').modal('hide');
  216. });
  217. jquery('#removeMedia INPUT[name=understand]').on('change', function () {
  218. var $this = jquery(this);
  219. jquery('#removeMedia .remove-media').prop('disabled', !$this.is(':checked'));
  220. });
  221. };
  222. return {
  223. 'init': _init,
  224. 'show': _show,
  225. 'hide': _hide,
  226. 'name': 'media'
  227. };
  228. })();
  229. })(window, jQuery, _);