diff options
| author | Andrea Ulliana <aul@odoo.com> | 2018-10-19 10:19:34 +0000 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2018-11-28 09:49:10 +0000 |
| commit | c64c646d62a658c94f2d81eea9a2797a4ce024ea (patch) | |
| tree | c8cf7d926dff81a318b6291ff5003d87a6024480 | |
| parent | 08230abe3c4a0bad84e9bf52125a7cf6bf0c3858 (diff) | |
[REF] website_slides: reorganize javascript
| -rw-r--r-- | addons/website_slides/static/src/js/slides.js | 76 | ||||
| -rw-r--r-- | addons/website_slides/static/src/js/slides_embed.js | 115 | ||||
| -rw-r--r-- | addons/website_slides/static/src/js/slides_like.js | 136 | ||||
| -rw-r--r-- | addons/website_slides/static/src/js/slides_share.js | 215 | ||||
| -rw-r--r-- | addons/website_slides/static/src/js/slides_upload.js | 456 |
5 files changed, 589 insertions, 409 deletions
diff --git a/addons/website_slides/static/src/js/slides.js b/addons/website_slides/static/src/js/slides.js index 0377394c452..bea4146bfe6 100644 --- a/addons/website_slides/static/src/js/slides.js +++ b/addons/website_slides/static/src/js/slides.js @@ -2,34 +2,56 @@ odoo.define('website_slides.slides', function (require) { "use strict"; - var time = require('web.time'); - require('root.widget'); +var time = require('web.time'); +require('root.widget'); +var sAnimations = require('website.content.snippets.animation'); - (function () { - $("timeago.timeago").each(function (index, el) { - var datetime = $(el).attr('datetime'), - datetime_obj = time.str_to_datetime(datetime), - // if presentation 7 days, 24 hours, 60 min, 60 second, 1000 millis old(one week) - // then return fix formate string else timeago - display_str = ""; - if (datetime_obj && new Date().getTime() - datetime_obj.getTime() > 7 * 24 * 60 * 60 * 1000) { - display_str = moment(datetime_obj).format('ll'); - } else { - display_str = moment(datetime_obj).fromNow(); - } - $(el).text(display_str); - }); +var page_widgets = {}; - // To prevent showing channel settings alert box once user closed it. - $('.o_slides_hide_channel_settings').on('click', function(ev) { - var channel_id = $(this).data("channelId"); - ev.preventDefault(); - document.cookie = "slides_channel_" + channel_id + " = closed"; - return true; - }); - })(); +sAnimations.registry.websiteSlides = sAnimations.Class.extend({ + selector: 'main', + read_events: { + 'each timeago.timeago': '_onTimeAgo', + 'click .o_slides_hide_channel_settings': '_onHideChannelSettings', + }, - return { - page_widgets: {}, - } + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @override + * @param {Object} index + * @param {Object} el + */ + _onTimeAgo: function (index, el) { + var datetime = $(el).attr('datetime'), + datetime_obj = time.str_to_datetime(datetime), + // if presentation 7 days, 24 hours, 60 min, 60 second, 1000 millis old(one week) + // then return fix formate string else timeago + display_str = ""; + if (datetime_obj && new Date().getTime() - datetime_obj.getTime() > 7 * 24 * 60 * 60 * 1000) { + display_str = moment(datetime_obj).format('ll'); + } else { + display_str = moment(datetime_obj).fromNow(); + } + $(el).text(display_str); + }, + /** + * To prevent showing channel settings alert box once user closed it. + * + * @override + * @param {Object} ev + */ + _onHideChannelSettings: function (ev) { + var channel_id = $(this).data("channelId"); + ev.preventDefault(); + document.cookie = "slides_channel_" + channel_id + " = closed"; + return true; + }, +}); + +return { + page_widgets: page_widgets, +}; }); diff --git a/addons/website_slides/static/src/js/slides_embed.js b/addons/website_slides/static/src/js/slides_embed.js index 2ba46a1990d..dcb72d7765c 100644 --- a/addons/website_slides/static/src/js/slides_embed.js +++ b/addons/website_slides/static/src/js/slides_embed.js @@ -1,50 +1,77 @@ /*global $, _, PDFSlidesViewer*/ odoo.define('website_slides.slides_embed', function (require) { - "use strict"; - - var time = require('web.time'); - var Widget = require('web.Widget'); - require('website_slides.slides'); - - (function () { - /* - * Embedded Code Widget - */ - var SlideSocialEmbed = Widget.extend({ - events: { - 'change input' : 'change_page', - }, - init: function(parent, max_page){ - this._super(parent); - this.max_page = max_page || false; - }, - change_page: function(ev){ - ev.preventDefault(); - var input = this.$('input'); - var page = parseInt(input.val()); - if (this.max_page && !(page > 0 && page <= this.max_page)) { - page = 1; - } - this.update_embedded_code(page); - }, - update_embedded_code: function(page){ - var embed_input = this.$('.slide_embed_code'); - var new_code = embed_input.val().replace(/(page=).*?([^\d]+)/, '$1' + page + '$2'); - embed_input.val(new_code); - }, - }); +"use strict"; - $('iframe.o_wslides_iframe_viewer').ready(function() { - // TODO : make it work. For now, once the iframe is loaded, the value of #page_count is - // still now set (the pdf is still loading) - var $iframe = $(this); - var max_page = $iframe.contents().find('#page_count').val(); - slides.page_widgets['social_embed'] = new SlideSocialEmbed($iframe, max_page).setElement($('.oe_slide_js_embed_code_widget')); - }); - - })(); - +var Widget = require('web.Widget'); +require('website_slides.slides'); +var sAnimations = require('website.content.snippets.animation'); + +// Embedded Code Widget +var SlideSocialEmbed = Widget.extend({ + events: { + 'change input' : '_changePage', + }, + /** + * @override + * @param {Object} parent + * @param {Number} max_page + */ + init: function (parent, max_page){ + this._super(parent); + this.max_page = max_page || false; + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + * @param {Object} ev + */ + _changePage: function (ev){ + ev.preventDefault(); + var input = this.$('input'); + var page = parseInt(input.val()); + if (this.max_page && !(page > 0 && page <= this.max_page)) { + page = 1; + } + this._updateEmbeddedCode(page); + }, + /** + * @private + * @param {Number} page + */ + _updateEmbeddedCode: function (page){ + var embed_input = this.$('.slide_embed_code'); + var new_code = embed_input.val().replace(/(page=).*?([^\d]+)/, '$1' + page + '$2'); + embed_input.val(new_code); + }, +}); + +sAnimations.registry.websiteSlidesEmbed = sAnimations.Class.extend({ + selector: 'main', + read_events: { + 'ready iframe.o_wslides_iframe_viewer': '_onIframeViewer', + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @override + */ + _onIframeViewer: function () { + // TODO : make it work. For now, once the iframe is loaded, the value of #page_count is + // still now set (the pdf is still loading) + var $iframe = $(this); + var max_page = $iframe.contents().find('#page_count').val(); + new SlideSocialEmbed($iframe, max_page).setElement($('.oe_slide_js_embed_code_widget')); + }, }); +}); + /** This file is a minimal version of the PDFViewer widget. It is NOT use in the website_slides module, but it is @@ -250,5 +277,3 @@ $(document).ready(function () { }); } }); - - diff --git a/addons/website_slides/static/src/js/slides_like.js b/addons/website_slides/static/src/js/slides_like.js index d9c0da2afa2..3f3033c6098 100644 --- a/addons/website_slides/static/src/js/slides_like.js +++ b/addons/website_slides/static/src/js/slides_like.js @@ -1,63 +1,85 @@ /*global $, _, PDFJS */ odoo.define('website_slides.slides_like', function (require) { - "use strict"; - - var ajax = require('web.ajax'); - var core = require('web.core'); - var Widget = require('web.Widget'); - var local_storage = require('web.local_storage'); - var slides = require('website_slides.slides'); - - var _t = core._t; - - (function () { +"use strict"; + +var ajax = require('web.ajax'); +var core = require('web.core'); +var Widget = require('web.Widget'); +var local_storage = require('web.local_storage'); +var sAnimations = require('website.content.snippets.animation'); +var slides = require('website_slides.slides'); + +var _t = core._t; + +// Like/Dislike Buttons Widget +var LikeButton = Widget.extend({ + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + * @param {Object} $el + */ + setElement: function ($el){ + this._super.apply(this, arguments); + this.$el.on('click', this, _.bind(this._applyAction, this)); + }, + /** + * @private + * @param {Object} ev + */ + _applyAction: function (ev){ + var button = $(ev.currentTarget); + var slide_id = button.data('slide-id'); + var user_id = button.data('user-id'); + var is_public = button.data('public-user'); + var href = button.data('href'); + if (is_public){ + this._popoverAlert(button, _.str.sprintf(_t('Please <a href="/web?redirect=%s">login</a> to vote this slide'), (document.URL))); + } else { + var target = button.find('.fa'); + if (local_storage.getItem('slide_vote_' + slide_id) !== user_id.toString()) { + ajax.jsonRpc(href, 'call', {slide_id: slide_id}).then(function (data) { + target.text(data); + local_storage.setItem('slide_vote_' + slide_id, user_id); + }); + } else { + this._popoverAlert(button, _t('You have already voted for this slide')); + } + } + }, + /** + * @private + * @param {Object} $el + * @param {String} message + */ + _popoverAlert: function ($el, message){ + $el.popover({ + trigger: 'focus', + placement: 'bottom', + container: 'body', + html: true, + content: function () { + return message; + } + }).popover('show'); + }, +}); + +sAnimations.registry.websiteSlidesLike = sAnimations.Class.extend({ + selector: 'main', + + /** + * @override + * @param {Object} parent + */ + start: function (parent) { var widget_parent = $('body'); - - /* - * Like/Dislike Buttons Widget - */ - var LikeButton = Widget.extend({ - setElement: function($el){ - this._super.apply(this, arguments); - this.$el.on('click', this, _.bind(this.apply_action, this)); - }, - apply_action: function(ev){ - var button = $(ev.currentTarget); - var slide_id = button.data('slide-id'); - var user_id = button.data('user-id'); - var is_public = button.data('public-user'); - var href = button.data('href'); - if(is_public){ - this.popover_alert(button, _.str.sprintf(_t('Please <a href="/web?redirect=%s">login</a> to vote this slide'), (document.URL))); - }else{ - var target = button.find('.fa'); - if (local_storage.getItem('slide_vote_' + slide_id) !== user_id.toString()) { - ajax.jsonRpc(href, 'call', {slide_id: slide_id}).then(function (data) { - target.text(data); - local_storage.setItem('slide_vote_' + slide_id, user_id); - }); - } else { - this.popover_alert(button, _t('You have already voted for this slide')); - } - } - }, - popover_alert: function($el, message){ - $el.popover({ - trigger: 'focus', - placement: 'bottom', - container: 'body', - html: true, - content: function(){ - return message; - } - }).popover('show'); - }, - }); - slides.page_widgets['likeButton'] = new LikeButton(widget_parent).setElement($('.oe_slide_js_like')); slides.page_widgets['dislikeButton'] = new LikeButton(widget_parent).setElement($('.oe_slide_js_unlike')); - - })(); - + return this._super.apply(this, arguments); + }, +}); }); -
\ No newline at end of file diff --git a/addons/website_slides/static/src/js/slides_share.js b/addons/website_slides/static/src/js/slides_share.js index 72e810f16f6..e1ef6118cfe 100644 --- a/addons/website_slides/static/src/js/slides_share.js +++ b/addons/website_slides/static/src/js/slides_share.js @@ -1,43 +1,56 @@ odoo.define('website_slides.slides_share', function (require) { - "use strict"; - var ajax = require('web.ajax'); - var Widget = require('web.Widget'); - var slides = require('website_slides.slides'); +"use strict"; +var ajax = require('web.ajax'); +var Widget = require('web.Widget'); +var sAnimations = require('website.content.snippets.animation'); +var slides = require('website_slides.slides'); - (function () { - var widget_parent = $('body'); +// Send by email Widget +var ShareMail = Widget.extend({ + events: { + 'click button': '_sendMail', + }, - /* - * Send by email Widget - */ - var ShareMail = Widget.extend({ - events: { - 'click button' : 'send_mail', - }, - send_mail: function(){ - var self = this; - var input = this.$('input'); - var slide_id = this.$('button').data('slide-id'); - if(input.val() && input[0].checkValidity()){ - this.$el.removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid'); - ajax.jsonRpc('/slides/slide/send_share_email', 'call', { - slide_id: slide_id, - email: input.val(), - }).then(function () { - self.$el.html($('<div class="alert alert-info" role="alert"><strong>Thank you!</strong> Mail has been sent.</div>')); - }); - }else{ - this.$el.addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid'); - input.focus(); - } - }, - }); + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + */ + _sendMail: function () { + var self = this; + var input = this.$('input'); + var slide_id = this.$('button').data('slide-id'); + if (input.val() && input[0].checkValidity()){ + this.$el.removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid'); + ajax.jsonRpc('/slides/slide/send_share_email', 'call', { + slide_id: slide_id, + email: input.val(), + }).then(function () { + self.$el.html($('<div class="alert alert-info" role="alert"><strong>Thank you!</strong> Mail has been sent.</div>')); + }); + } else { + this.$el.addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid'); + input.focus(); + } + }, +}); +sAnimations.registry.websiteSlidesShare = sAnimations.Class.extend({ + selector: 'main', + read_events: { + 'click a.o_slides_social_share': '_onSlidesSocialShare' + }, + + /** + * @override + * @param {Object} parent + */ + start: function (parent) { + var widget_parent = $('body'); slides.page_widgets['share_mail'] = new ShareMail(widget_parent).setElement($('.oe_slide_js_share_email')); - /* - * Social Sharing Statistics Widget - */ if ($('div#statistic').length) { var slide_url = $("div#statistic").attr('slide-url'); var social_urls = { @@ -45,66 +58,84 @@ odoo.define('website_slides.slides_share', function (require) { 'twitter': 'https://cdn.api.twitter.com/1/urls/count.json?url=', 'facebook': 'https://graph.facebook.com/?id=', 'gplus': 'https://clients6.google.com/rpc' - } - - var update_statistics = function(social_site, slide_url) { - if (social_site == 'gplus') { - $.ajax({ - url: social_urls['gplus'], - type: "POST", - dataType: 'json', - contentType: 'application/json', - data: JSON.stringify([{ - "method": "pos.plusones.get", - "id": "p", - "params": { - "nolog": true, - "id": slide_url, - "source": "widget", - "userId": "@viewer", - "groupId": "@self" - }, - // TDE NOTE: should there be a key here ? - "jsonrpc": "2.0", - "apiVersion": "v1" - }]), - success: function(data) { - $('#google-badge').text(data[0].result.metadata.globalCounts.count || 0); - $('#total-share').text(parseInt($('#total-share').text()) + parseInt($('#google-badge').text())); - }, - }); - } else { - $.ajax({ - url: social_urls[social_site] + slide_url, - dataType: 'jsonp', - success: function(data) { - var shareCount = (social_site === 'facebook' ? data.shares : data.count) || 0; - $('#' + social_site + '-badge').text(shareCount); - $('#total-share').text(parseInt($('#total-share').text()) + parseInt($('#' + social_site+ '-badge').text())); - }, - }); - } }; + } - $.each(social_urls, function(key, value) { - update_statistics(key, slide_url); - }); + $.each(social_urls, function (key, value) { + this._updateStatistics(key, slide_url); + }); + }, - $("a.o_slides_social_share").on('click', function(ev) { - ev.preventDefault(); - var key = $(ev.currentTarget).attr('social-key'); - var popUpURL = $(ev.currentTarget).attr('href'); - var popUp = window.open( - popUpURL, - 'Share Dialog', - 'width=626,height=436'); - $(window).on('focus', function() { - if (popUp.closed) { - update_statistics(key, slide_url); - $(window).off('focus'); - } - }); + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + * @param {string} social_site + * @param {string} slide_url + */ + _updateStatistics: function (social_site, slide_url) { + if (social_site === 'gplus') { + $.ajax({ + url: this.social_urls['gplus'], + type: "POST", + dataType: 'json', + contentType: 'application/json', + data: JSON.stringify([{ + "method": "pos.plusones.get", + "id": "p", + "params": { + "nolog": true, + "id": slide_url, + "source": "widget", + "userId": "@viewer", + "groupId": "@self" + }, + // TDE NOTE: should there be a key here ? + "jsonrpc": "2.0", + "apiVersion": "v1" + }]), + success: function (data) { + $('#google-badge').text(data[0].result.metadata.globalCounts.count || 0); + $('#total-share').text(parseInt($('#total-share').text()) + parseInt($('#google-badge').text())); + }, + }); + } else { + $.ajax({ + url: this.social_urls[social_site] + slide_url, + dataType: 'jsonp', + success: function (data) { + var shareCount = (social_site === 'facebook' ? data.shares : data.count) || 0; + $('#' + social_site + '-badge').text(shareCount); + $('#total-share').text(parseInt($('#total-share').text()) + parseInt($('#' + social_site+ '-badge').text())); + }, }); } - })(); -})
\ No newline at end of file + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @override + * @param {Object} ev + */ + _onSlidesSocialShare: function (ev) { + ev.preventDefault(); + var key = $(ev.currentTarget).attr('social-key'); + var popUpURL = $(ev.currentTarget).attr('href'); + var popUp = window.open( + popUpURL, + 'Share Dialog', + 'width=626,height=436'); + $(window).on('focus', function () { + if (popUp.closed) { + this._updateStatistics(key, this.slide_url); + $(window).off('focus'); + } + }); + }, +}); +}); diff --git a/addons/website_slides/static/src/js/slides_upload.js b/addons/website_slides/static/src/js/slides_upload.js index aa638882930..382caf451e2 100644 --- a/addons/website_slides/static/src/js/slides_upload.js +++ b/addons/website_slides/static/src/js/slides_upload.js @@ -1,202 +1,95 @@ odoo.define('website_slides.upload', function (require) { "use strict"; +var sAnimations = require('website.content.snippets.animation'); var ajax = require('web.ajax'); var core = require('web.core'); var Widget = require('web.Widget'); -require('web.dom_ready'); -var weContext = require("web_editor.context"); var slides = require('website_slides.slides'); -var qweb = core.qweb; var _t = core._t; -if (!$('.oe_slide_js_upload').length) { - return $.Deferred().reject("DOM doesn't contain '.oe_slide_js_upload'"); -} - -ajax.loadXML('/website_slides/static/src/xml/website_slides.xml', qweb); - var SlideDialog = Widget.extend({ template: 'website.slide.upload', events: { 'hidden.bs.modal': 'destroy', - 'click button.save': 'save', - 'click button[data-dismiss="modal"]': 'cancel', - 'change input#upload': 'slide_upload', - 'change input#url': 'slide_url', + 'click button.save': '_save', + 'click button[data-dismiss="modal"]': '_cancel', + 'change input#upload': '_slideUpload', + 'change input#url': '_slideUrl', 'click .list-group-item': function (ev) { this.$('.list-group-item').removeClass('active'); $(ev.target).closest('li').addClass('active'); } }, + + /** + * @override + * @param {Object} el + * @param {number} channel_id + */ init: function (el, channel_id) { this._super(el, channel_id); this.channel_id = parseInt(channel_id, 10); this.file = {}; this.index_content = ""; }, - start: function () { + /** + * @override + * @param {Object} parent + */ + start: function (parent) { this.$el.modal({ backdrop: 'static' }); - this.set_category_id(); - this.set_tag_ids(); + this._setCategoryId(); + this._setTagIds(); }, - slide_url: function (ev) { - var self = this, - value = { - 'url': $(ev.target).val(), - 'channel_id': self.channel_id - }; - this.$('.alert-warning').remove(); - this.is_valid_url = false; - this.$('.save').button('loading'); - ajax.jsonRpc('/slides/dialog_preview/', 'call', value).then(function (data) { - self.$('.save').button('reset'); - if (data.error) { - self.display_alert(data.error); - } else { - self.$("#slide-image").attr("src", data.url_src); - self.$('#name').val(data.title); - self.$('#description').val(data.description); - self.is_valid_url = true; - } - }); - }, - check_unique_slide: function (file_name) { + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + * @param {string} file_name + */ + _checkUniqueSlide: function (file_name) { var self = this; - return ajax.jsonRpc('/web/dataset/call_kw', 'call', { + return this._rpc({ model: 'slide.slide', method: 'search_count', args: [[['channel_id', '=', self.channel_id], ['name', '=', file_name]]], - kwargs: { - context: weContext.get(), // TODO use this._rpc - } }); }, - slide_upload: function (ev) { - var self = this, - file = ev.target.files[0], - is_image = /^image\/.*/.test(file.type), - loaded = false; - this.file.name = file.name; - this.file.type = file.type; - if (!(is_image || this.file.type === 'application/pdf')) { - this.display_alert(_t("Invalid file type. Please select pdf or image file")); - this.reset_file(); - return; - } - if (file.size / 1024 / 1024 > 25) { - this.display_alert(_t("File is too big. File size cannot exceed 25MB")); - this.reset_file(); - return; - } - this.$('.alert-warning').remove(); - var BinaryReader = new FileReader(); - // file read as DataURL - BinaryReader.readAsDataURL(file); - BinaryReader.onloadend = function (upload) { - var buffer = upload.target.result; - if (is_image) { - self.$("#slide-image").attr("src", buffer); - } - buffer = buffer.split(',')[1]; - self.file.data = buffer; - }; - - if (file.type === 'application/pdf') { - var ArrayReader = new FileReader(); - this.$('.save').button('loading'); - // file read as ArrayBuffer for PDFJS get_Document API - ArrayReader.readAsArrayBuffer(file); - ArrayReader.onload = function (evt) { - var buffer = evt.target.result; - var passwordNeeded = function () { - self.display_alert(_t("You can not upload password protected file.")); - self.reset_file(); - self.$('.save').button('reset'); - }; - PDFJS.getDocument(new Uint8Array(buffer), null, passwordNeeded).then(function getPdf(pdf) { - pdf.getPage(1).then(function getFirstPage(page) { - var scale = 1; - var viewport = page.getViewport(scale); - var canvas = document.getElementById('data_canvas'); - var context = canvas.getContext('2d'); - canvas.height = viewport.height; - canvas.width = viewport.width; - // Render PDF page into canvas context - page.render({ - canvasContext: context, - viewport: viewport - }).then(function () { - var image_data = self.$('#data_canvas')[0].toDataURL(); - self.$("#slide-image").attr("src", image_data); - if (loaded) { - self.$('.save').button('reset'); - } - loaded = true; - - }); - }); - var maxPages = pdf.pdfInfo.numPages; - var page, j; - self.index_content = ""; - for (j = 1; j <= maxPages; j += 1) { - page = pdf.getPage(j); - page.then(function (page_obj) { - var page_number = page_obj.pageIndex + 1; - page_obj.getTextContent().then(function (data) { - var page_content = ''; - _.each(data.items, function (obj) { - page_content = page_content + obj.str + " "; - }); - // page_content may contain null characters - page_content = page_content.replace(/\0/g, ""); - self.index_content = self.index_content + page_number + ". " + page_content + '\n'; - if (maxPages === page_number) { - if (loaded) { - self.$('.save').button('reset'); - } - loaded = true; - } - }); - }); - } - }); - }; - } - - var input = file.name; - var input_val = input.substr(0, input.lastIndexOf('.')) || input; - this.check_unique_slide(input_val).then(function (exist) { - if (exist) { - var message = _t("Channel contains the given title, please change before Save or Publish."); - self.display_alert(message); - } - self.$('#name').val(input_val); - }); - }, - reset_file: function () { + /** + * @private + */ + _resetFile: function () { var control = this.$('#upload'); control.replaceWith(control = control.clone(true)); this.file.name = false; }, - display_alert: function (message) { + /** + * @private + * @param {string} message + */ + _displayAlert: function (message) { this.$('.alert-warning').remove(); $('<div class="alert alert-warning" role="alert">' + message + '</div>').insertBefore(this.$('form')); }, /** - Wrapper for select2 load data from server at once and store it. - - @param {String} Placeholder for element. - @param {bool} true for multiple selection box, false for single selection - @param {Function} Function to fetch data from remote location should return $.deferred object - resolved data should be array of object with id and name. eg. [{'id': id, 'name': 'text'}, ...] - @returns {Object} select2 wrapper object + * Wrapper for select2 load data from server at once and store it. + * + * @private + * @param {String} Placeholder for element. + * @param {bool} true for multiple selection box, false for single selection + * @param {Function} Function to fetch data from remote location should return $.deferred object + * resolved data should be array of object with id and name. eg. [{'id': id, 'name': 'text'}, ...] + * @returns {Object} select2 wrapper object */ - select2_wrapper: function (tag, multi, fetch_fnc) { + _select2Wrapper: function (tag, multi, fetch_fnc) { return { width: '100%', placeholder: tag, @@ -248,45 +141,57 @@ var SlideDialog = Widget.extend({ } }; }, - // Category management from select2 - set_category_id: function () { + /** + * Category management from select2 + * + * @private + */ + _setCategoryId: function () { var self = this; - $('#category_id').select2(this.select2_wrapper(_t('Category'), false, + $('#category_id').select2(this._select2Wrapper(_t('Category'), false, function () { - return ajax.jsonRpc("/web/dataset/call_kw", 'call', { + return this._rpc({ model: 'slide.category', method: 'search_read', args: [], kwargs: { fields: ['name'], domain: [['channel_id', '=', self.channel_id]], - context: weContext.get(), // TODO use this._rpc } }); })); }, - get_category_id: function () { + /** + * @private + */ + _getCategoryId: function () { var value = $('#category_id').select2('data'); if (value && value.create) { return [0, {'name': value.text}]; } return [value ? value.id : null]; }, - // Tags management from select2 - set_tag_ids: function () { - $('#tag_ids').select2(this.select2_wrapper(_t('Tags'), true, function () { - return ajax.jsonRpc("/web/dataset/call_kw", 'call', { + /** + * Tags management from select2 + * + * @private + */ + _setTagIds: function () { + $('#tag_ids').select2(this._select2Wrapper(_t('Tags'), true, function () { + return this._rpc({ model: 'slide.tag', method: 'search_read', args: [], kwargs: { fields: ['name'], - context: weContext.get(), // TODO use this._rpc } }); })); }, - get_tag_ids: function () { + /** + * @private + */ + _getTagIds: function () { var res = []; _.each($('#tag_ids').select2('data'), function (val) { @@ -298,9 +203,12 @@ var SlideDialog = Widget.extend({ }); return res; }, + /** + * @private + */ // TODO: Remove this part, as now SVG support in image resize tools is included //Python PIL does not support SVG, so converting SVG to PNG - svg_to_png: function () { + _svgToPng: function () { var img = this.$el.find("img#slide-image")[0]; var canvas = document.createElement("canvas"); canvas.width = img.width; @@ -308,16 +216,20 @@ var SlideDialog = Widget.extend({ canvas.getContext("2d").drawImage(img, 0, 0); return canvas.toDataURL("image/png").split(',')[1]; }, - // Values and save - get_value: function () { + /** + * Values and save + * + * @private + */ + _getValue: function () { var canvas = this.$('#data_canvas')[0], values = { 'channel_id': this.channel_id || '', 'name': this.$('#name').val(), 'url': this.$('#url').val(), 'description': this.$('#description').val(), - 'tag_ids': this.get_tag_ids(), - 'category_id': this.get_category_id() + 'tag_ids': this._getTagIds(), + 'category_id': this._getCategoryId() }; if (this.file.type === 'application/pdf') { _.extend(values, { @@ -332,12 +244,15 @@ var SlideDialog = Widget.extend({ _.extend(values, { 'slide_type': 'infographic', 'mime_type': this.file.type === 'image/svg+xml' ? 'image/png' : this.file.type, - 'datas': this.file.type === 'image/svg+xml' ? this.svg_to_png() : this.file.data + 'datas': this.file.type === 'image/svg+xml' ? this._svgToPng() : this.file.data }); } return values; }, - validate: function () { + /** + * @private + */ + _validate: function () { this.$('.form-group').removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid'); if (!this.$('#name').val()) { this.$('#name').closest('.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid'); @@ -350,10 +265,19 @@ var SlideDialog = Widget.extend({ } return true; }, - save: function (ev) { + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @override + * @param {Object} ev + */ + _save: function (ev) { var self = this; - if (this.validate()) { - var values = this.get_value(); + if (this._validate()) { + var values = this._getValue(); if ($(ev.target).data('published')) { values.website_published = true; } @@ -361,7 +285,7 @@ var SlideDialog = Widget.extend({ this.$('.modal-footer, .modal-body').hide(); ajax.jsonRpc("/slides/add_slide", 'call', values).then(function (data) { if (data.error) { - self.display_alert(data.error); + self._displayAlert(data.error); self.$('.oe_slides_upload_loading').hide(); self.$('.modal-footer, .modal-body').show(); @@ -371,20 +295,176 @@ var SlideDialog = Widget.extend({ }); } }, - cancel: function () { + /** + * @override + */ + _cancel: function () { this.trigger("cancel"); - } -}); + }, + /** + * @override + * @param {Object} ev + */ + _slideUpload: function (ev) { + var self = this, + file = ev.target.files[0], + is_image = /^image\/.*/.test(file.type), + loaded = false; + this.file.name = file.name; + this.file.type = file.type; + if (!(is_image || this.file.type === 'application/pdf')) { + this._displayAlert(_t("Invalid file type. Please select pdf or image file")); + this._resetFile(); + return; + } + if (file.size / 1024 / 1024 > 25) { + this._displayAlert(_t("File is too big. File size cannot exceed 25MB")); + this._resetFile(); + return; + } + this.$('.alert-warning').remove(); + var BinaryReader = new FileReader(); + // file read as DataURL + BinaryReader.readAsDataURL(file); + BinaryReader.onloadend = function (upload) { + var buffer = upload.target.result; + if (is_image) { + self.$("#slide-image").attr("src", buffer); + } + buffer = buffer.split(',')[1]; + self.file.data = buffer; + }; + + if (file.type === 'application/pdf') { + var ArrayReader = new FileReader(); + this.$('.save').button('loading'); + // file read as ArrayBuffer for PDFJS get_Document API + ArrayReader.readAsArrayBuffer(file); + ArrayReader.onload = function (evt) { + var buffer = evt.target.result; + var passwordNeeded = function () { + self._displayAlert(_t("You can not upload password protected file.")); + self._resetFile(); + self.$('.save').button('reset'); + }; + PDFJS.getDocument(new Uint8Array(buffer), null, passwordNeeded).then(function getPdf(pdf) { + pdf.getPage(1).then(function getFirstPage(page) { + var scale = 1; + var viewport = page.getViewport(scale); + var canvas = document.getElementById('data_canvas'); + var context = canvas.getContext('2d'); + canvas.height = viewport.height; + canvas.width = viewport.width; + // Render PDF page into canvas context + page.render({ + canvasContext: context, + viewport: viewport + }).then(function () { + var image_data = self.$('#data_canvas')[0].toDataURL(); + self.$("#slide-image").attr("src", image_data); + if (loaded) { + self.$('.save').button('reset'); + } + loaded = true; + + }); + }); + var maxPages = pdf.pdfInfo.numPages; + var page, j; + self.index_content = ""; + for (j = 1; j <= maxPages; j += 1) { + page = pdf.getPage(j); + page.then(function (page_obj) { + var page_number = page_obj.pageIndex + 1; + page_obj.getTextContent().then(function (data) { + var page_content = ''; + _.each(data.items, function (obj) { + page_content = page_content + obj.str + " "; + }); + // page_content may contain null characters + page_content = page_content.replace(/\0/g, ""); + self.index_content = self.index_content + page_number + ". " + page_content + '\n'; + if (maxPages === page_number) { + if (loaded) { + self.$('.save').button('reset'); + } + loaded = true; + } + }); + }); + } + }); + }; + } + + var input = file.name; + var input_val = input.substr(0, input.lastIndexOf('.')) || input; + this._checkUniqueSlide(input_val).then(function (exist) { + if (exist) { + var message = _t("Channel contains the given title, please change before Save or Publish."); + self._displayAlert(message); + } + self.$('#name').val(input_val); + }); + }, + /** + * @override + * @param {Object} ev + */ + _slideUrl: function (ev) { + var self = this, + value = { + 'url': $(ev.target).val(), + 'channel_id': self.channel_id + }; + this.$('.alert-warning').remove(); + this.is_valid_url = false; + this.$('.save').button('loading'); + ajax.jsonRpc('/slides/dialog_preview/', 'call', value).then(function (data) { + self.$('.save').button('reset'); + if (data.error) { + self._displayAlert(data.error); + } else { + self.$("#slide-image").attr("src", data.url_src); + self.$('#name').val(data.title); + self.$('#description').val(data.description); + self.is_valid_url = true; + } + }); + }, -// bind the event to the button -$('.oe_slide_js_upload').on('click', function () { - var channel_id = $(this).attr('channel_id'); - slides.page_widgets['upload_dialog'] = new SlideDialog(this, channel_id).appendTo(document.body); }); -// automatically open the upload dialog if requested from query string -if ($.deparam.querystring().enable_slide_upload !== undefined) { - $('.oe_slide_js_upload').click(); -} +sAnimations.registry.websiteSlidesUpload = sAnimations.Class.extend({ + selector: '.oe_slide_js_upload', + xmlDependencies: ['/website_slides/static/src/xml/website_slides.xml'], + read_events: { + 'click .oe_slide_js_upload': '_bindEventButton', + }, + + /** + * @override + * @param {Object} parent + */ + start: function (parent) { + // Automatically open the upload dialog if requested from query string + if ($.deparam.querystring().enable_slide_upload !== undefined) { + $('.oe_slide_js_upload').click(); + } + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @override + */ + _bindEventButton: function () { + var channel_id = $(this).attr('channel_id'); + slides.page_widgets['upload_dialog'] = new SlideDialog(this, channel_id).appendTo(document.body); + }, + +}); }); |
