PageRenderTime 27ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://gitlab.com/wilane/Booktype
JavaScript | 410 lines | 285 code | 86 blank | 39 comment | 14 complexity | be4813edd5a19e5ef1bddfa5f6e187fc 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.covers');
  18. win.booktype.editor.covers = (function () {
  19. var fileUpload;
  20. var CoverItem = Backbone.Model.extend({
  21. defaults: {
  22. cid: 0,
  23. title: '',
  24. notes: '',
  25. filename: '',
  26. imageSrc: '',
  27. preview: '',
  28. size: 0,
  29. dimension: null,
  30. approved: null
  31. },
  32. getDimension: function () {
  33. var d = this.get('dimension');
  34. return d !== null ? d[0] + 'x' + d[1] : '';
  35. },
  36. getSize: function () {
  37. return win.booktype.utils.formatSize(this.get('size'));
  38. }
  39. });
  40. var CoverCollection = Backbone.Collection.extend({
  41. model: CoverItem
  42. });
  43. var CoverView = Backbone.View.extend({
  44. events: {
  45. 'change input[type=checkbox]': 'approvedChanged',
  46. 'click #btnEditCover': 'editCover',
  47. 'click #btnDeleteCover': 'deleteCover'
  48. },
  49. initialize : function () {
  50. this.templItem = _.template(jquery('#templateCoverBox').clone().html());
  51. },
  52. approvedChanged: function (e) {
  53. var isChecked = $(e.currentTarget).is(':checked');
  54. var cid = e.currentTarget.id;
  55. win.booktype.sendToCurrentBook({
  56. 'command': 'cover_approve',
  57. 'cid': cid,
  58. 'cover_status': isChecked
  59. },
  60. function () {
  61. loadCovers();
  62. });
  63. },
  64. editCover: function (e) {
  65. var $this = jquery(e.currentTarget);
  66. var $li = $this.parent().parent().parent();
  67. var cid = $li.data('cid');
  68. win.booktype.sendToCurrentBook({'command': 'cover_load', 'cid': cid},
  69. function (data) {
  70. win.booktype.ui.notify();
  71. var $upload = jquery('#editCover');
  72. jquery('input[name=cid]', $upload).val(data.cover.cid);
  73. jquery('input[name=title]', $upload).val(data.cover.title);
  74. jquery('input[name=creator]', $upload).val(data.cover.creator);
  75. jquery('textarea[name=notes]', $upload).val(data.cover.notes);
  76. var $lic = [];
  77. var $tc = _.template('<option value="<%= value %>" <%= selected? "selected" : "" %> ><%= name %></option>');
  78. _.each(data.licenses, function (elem) {
  79. $lic.push($tc({'selected': data.cover.license === elem[0], 'value': elem[0], 'name': elem[1]}));
  80. });
  81. jquery('select[name=license]', $upload).empty().append($lic);
  82. $upload.modal('show');
  83. }
  84. );
  85. },
  86. deleteCover: function (e) {
  87. var $this = jquery(e.currentTarget);
  88. var cid = $this.parent().parent().parent().data('cid');
  89. if (confirm(win.booktype._('cover_delete', 'Do you really want to delete this cover?')) === true) {
  90. win.booktype.sendToCurrentBook({'command': 'cover_delete', 'cid': cid},
  91. function (data) {
  92. loadCovers();
  93. });
  94. }
  95. return false;
  96. },
  97. render: function () {
  98. var $this = this;
  99. var covers = this.model.map(function (item) {
  100. return $this.templItem({
  101. 'cid': item.get('cid'),
  102. 'title': item.get('title'),
  103. 'notes': item.get('notes'),
  104. 'filename': item.get('filename'),
  105. 'imageSrc': '../_cover/' + item.get('cid') + '/cover' + item.get('filename') +'?preview=1',
  106. 'preview': item.get('preview'),
  107. 'size': item.getSize(),
  108. 'dimension': item.getDimension(),
  109. 'approved': item.get('approved')
  110. });
  111. });
  112. this.$el.html(covers.join(''));
  113. return this;
  114. }
  115. });
  116. var coverItems = new CoverCollection();
  117. var coverView = null;
  118. var CoverRouter = Backbone.Router.extend({
  119. routes: {
  120. 'covers': 'covers'
  121. },
  122. covers: function () {
  123. var $d = jquery.Deferred();
  124. var activePanel = win.booktype.editor.getActivePanel();
  125. activePanel.hide(function () {
  126. win.booktype.editor.data.activePanel = win.booktype.editor.data.panels.cover;
  127. win.booktype.editor.data.activePanel.show();
  128. $d.resolve();
  129. });
  130. return $d.promise();
  131. },
  132. });
  133. var router = new CoverRouter();
  134. /*******************************************************************************/
  135. /* DISPLAY COVERS */
  136. /*******************************************************************************/
  137. var filterCovers = function (filterID) {
  138. var $this = jquery('.contentHeader .btn-toolbar .btn-group .active input');
  139. var filterID = filterID || jquery($this).prop('id');
  140. // Should go somewhere out
  141. if (filterID === 'button-all') {
  142. jquery('DIV.coverThumbnail').css('display', '');
  143. }
  144. if (filterID === 'button-approved') {
  145. jquery('DIV.coverThumbnail DIV.coverOptions INPUT[type=checkbox]:checked').parent().parent().css('display', '');
  146. jquery('DIV.coverThumbnail DIV.coverOptions INPUT[type=checkbox]:not(:checked)').parent().parent().css('display', 'none');
  147. }
  148. if (filterID === 'button-pending') {
  149. jquery('DIV.coverThumbnail DIV.coverOptions INPUT[type=checkbox]:checked').parent().parent().css('display', 'none');
  150. jquery('DIV.coverThumbnail DIV.coverOptions INPUT[type=checkbox]:not(:checked)').parent().parent().css('display', '');
  151. }
  152. };
  153. var displayCovers = function () {
  154. if (coverView) {
  155. coverView.render();
  156. }
  157. filterCovers();
  158. // Init cover tooltips
  159. jquery('.coverOptions .btn').tooltip();
  160. };
  161. var loadCovers = function () {
  162. win.booktype.ui.notify(win.booktype._('loading_cover_files', 'Loading Cover Files'));
  163. win.booktype.sendToCurrentBook({'command': 'covers_data'},
  164. function (data) {
  165. win.booktype.ui.notify();
  166. coverItems.reset(_.map(data.covers, function (itm) { return new CoverItem(itm); }));
  167. displayCovers();
  168. });
  169. };
  170. /*******************************************************************************/
  171. /* SHOW */
  172. /*******************************************************************************/
  173. var _show = function () {
  174. win.booktype.ui.notify('Loading');
  175. jquery('#button-cover').addClass('active');
  176. jquery('#cover_error').hide();
  177. jquery(document).on('click', '#cover_error .close', function () {
  178. jquery('#cover_error').hide();
  179. });
  180. // set toolbar
  181. var t = win.booktype.ui.getTemplate('templateCoversToolbar');
  182. jquery('DIV.contentHeader').html(t);
  183. var t2 = win.booktype.ui.getTemplate('templateCoversContent');
  184. jquery('#content').html(t2);
  185. jquery('DIV.contentHeader [rel=tooltip]').tooltip({container: 'body'});
  186. coverView = new CoverView({model: coverItems, el: jquery('#content DIV.coversContainer')});
  187. loadCovers();
  188. fileUpload = null;
  189. jquery('#fileupload').fileupload({
  190. dataType: 'json',
  191. sequentialUploads: true,
  192. done: function (e, data) {
  193. loadCovers();
  194. jquery('#uploadCover').modal('hide');
  195. },
  196. add: function (e, data) {
  197. fileUpload = data;
  198. jquery('#cover_error').hide();
  199. if (!(/\.(gif|jpe?g|png|tif?f|xcf|psd|pdf|ps|svg|eps|ai|indd)$/i).test(fileUpload.files[0].name)) {
  200. jquery('#cover_error').show();
  201. return false;
  202. } else {
  203. win.booktype.sendToCurrentBook({'command': 'cover_upload'},
  204. function (data) {
  205. var $upload = jquery('#uploadCover');
  206. jquery('input[name=title]', $upload).val('');
  207. jquery('input[name=creator]', $upload).val('');
  208. jquery('textarea[name=notes]', $upload).val('');
  209. var $lic = [];
  210. var $tc = _.template('<option value="<%= value %>"><%= name %></option>');
  211. _.each(data.licenses, function (elem) {
  212. $lic.push($tc({'value': elem[0], 'name': elem[1]}));
  213. });
  214. jquery('select[name=license]', $upload).empty().append($lic);
  215. $upload.modal('show');
  216. });
  217. }
  218. },
  219. progressall: function (e, data) { }
  220. });
  221. jquery('#button-all').parent().addClass('active');
  222. jquery('.contentHeader .btn-toolbar input').on('change', function () {
  223. var $this = this;
  224. var filterID = jquery($this).prop('id');
  225. filterCovers(filterID);
  226. });
  227. jquery('#uploadCover .btn-primary').on('click', function () {
  228. var title = jquery('#uploadCover input[name=title]').val();
  229. var creator = jquery('#uploadCover input[name=creator]').val();
  230. var notes = jquery('#uploadCover textarea[name=notes]').val();
  231. var license = jquery('#uploadCover select[name=license]').val();
  232. if (jquery.trim(title) !== '') {
  233. fileUpload.formData = [{'name': 'title', 'value': title},
  234. {'name': 'creator', 'value': creator},
  235. {'name': 'notes', 'value': notes},
  236. {'name': 'license', 'value': license},
  237. {'name': 'clientID', 'value': win.booktype.clientID}];
  238. fileUpload.submit();
  239. } else {
  240. var title_input = jquery('#uploadCover input[name=title]');
  241. title_input.parent().parent().addClass('has-error');
  242. title_input.tooltip('destroy')
  243. .data('title', win.booktype._('title-validation-error', 'Title field is required.'))
  244. .addClass('error')
  245. .tooltip();
  246. return false;
  247. }
  248. });
  249. jquery('#uploadCover input[name=title]').on('keyup', function (e) {
  250. var $this = jquery(e.currentTarget);
  251. var parent = jquery($this).parent().parent();
  252. e.preventDefault();
  253. if ($this.val().length > 0 && parent.hasClass('has-error')) {
  254. parent.removeClass('has-error');
  255. $this.data('title', '')
  256. .removeClass('error')
  257. .tooltip('destroy');
  258. }
  259. });
  260. jquery('#editCover .btn-primary').on('click', function () {
  261. var $upload = jquery('#editCover');
  262. var cid = jquery('input[name=cid]', $upload).val();
  263. var title = jquery('input[name=title]', $upload).val();
  264. var creator = jquery('input[name=creator]', $upload).val();
  265. var notes = jquery('textarea[name=notes]', $upload).val();
  266. var license = jquery('select[name=license]', $upload).val();
  267. if (jquery.trim(title) !== '') {
  268. win.booktype.sendToCurrentBook({
  269. 'command': 'cover_save',
  270. 'cid': cid,
  271. 'title': title,
  272. 'creator': creator,
  273. 'notes': notes,
  274. 'license': license
  275. },
  276. function (data) {
  277. loadCovers();
  278. $upload.modal('hide');
  279. });
  280. }
  281. });
  282. jquery('.coverMessageButton').on('click', function() {
  283. jquery('.coverMessage').toggleClass('open');
  284. });
  285. // Load cover data
  286. loadCovers();
  287. window.scrollTo(0, 0);
  288. // Trigger events
  289. jquery(document).trigger('booktype-ui-panel-active', ['covers', this]);
  290. };
  291. /*******************************************************************************/
  292. /* HIDE */
  293. /*******************************************************************************/
  294. var _hide = function (callback) {
  295. jquery('#button-cover').removeClass('active');
  296. // Destroy tooltip
  297. jquery('DIV.contentHeader [rel=tooltip]').tooltip('destroy');
  298. // clear content
  299. jquery('#content').empty();
  300. jquery('DIV.contentHeader').empty();
  301. if (!_.isUndefined(callback)) {
  302. callback();
  303. }
  304. };
  305. /*******************************************************************************/
  306. /* INIT */
  307. /*******************************************************************************/
  308. var _init = function () {
  309. jquery('#button-cover').on('click', function (e) { Backbone.history.navigate('covers', true); });
  310. };
  311. /*******************************************************************************/
  312. /* EXPORT */
  313. /*******************************************************************************/
  314. return {
  315. 'init': _init,
  316. 'show': _show,
  317. 'hide': _hide,
  318. 'name': 'covers'
  319. };
  320. })();
  321. })(window, jQuery, _);