[REF] website_slides: reorganize javascript
This commit is contained in:
@@ -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,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -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 () {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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 () {
|
||||
// Send by email Widget
|
||||
var ShareMail = Widget.extend({
|
||||
events: {
|
||||
'click button': '_sendMail',
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// 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');
|
||||
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// 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()));
|
||||
},
|
||||
});
|
||||
|
||||
$("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');
|
||||
}
|
||||
});
|
||||
} 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()));
|
||||
},
|
||||
});
|
||||
}
|
||||
})();
|
||||
})
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// 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');
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,81 +1,311 @@
|
||||
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) {
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_resetFile: function () {
|
||||
var control = this.$('#upload');
|
||||
control.replaceWith(control = control.clone(true));
|
||||
this.file.name = false;
|
||||
},
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
_select2Wrapper: function (tag, multi, fetch_fnc) {
|
||||
return {
|
||||
width: '100%',
|
||||
placeholder: tag,
|
||||
allowClear: true,
|
||||
formatNoMatches: false,
|
||||
multiple: multi,
|
||||
selection_data: false,
|
||||
fetch_rpc_fnc : fetch_fnc,
|
||||
formatSelection: function (data) {
|
||||
if (data.tag) {
|
||||
data.text = data.tag;
|
||||
}
|
||||
return data.text;
|
||||
},
|
||||
createSearchChoice: function (term, data) {
|
||||
var added_tags = $(this.opts.element).select2('data');
|
||||
if (_.filter(_.union(added_tags, data), function (tag) {
|
||||
return tag.text.toLowerCase().localeCompare(term.toLowerCase()) === 0;
|
||||
}).length === 0) {
|
||||
return {
|
||||
id: _.uniqueId('tag_'),
|
||||
create: true,
|
||||
tag: term,
|
||||
text: _.str.sprintf(_t("Create new tag '%s'"), term),
|
||||
};
|
||||
}
|
||||
},
|
||||
fill_data: function (query, data) {
|
||||
var that = this,
|
||||
tags = {results: []};
|
||||
_.each(data, function (obj) {
|
||||
if (that.matcher(query.term, obj.name)) {
|
||||
tags.results.push({id: obj.id, text: obj.name });
|
||||
}
|
||||
});
|
||||
query.callback(tags);
|
||||
},
|
||||
query: function (query) {
|
||||
var that = this;
|
||||
// fetch data only once and store it
|
||||
if (!this.selection_data) {
|
||||
this.fetch_rpc_fnc().then(function (data) {
|
||||
that.fill_data(query, data);
|
||||
that.selection_data = data;
|
||||
});
|
||||
} else {
|
||||
this.fill_data(query, this.selection_data);
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Category management from select2
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_setCategoryId: function () {
|
||||
var self = this;
|
||||
$('#category_id').select2(this._select2Wrapper(_t('Category'), false,
|
||||
function () {
|
||||
return this._rpc({
|
||||
model: 'slide.category',
|
||||
method: 'search_read',
|
||||
args: [],
|
||||
kwargs: {
|
||||
fields: ['name'],
|
||||
domain: [['channel_id', '=', self.channel_id]],
|
||||
}
|
||||
});
|
||||
}));
|
||||
},
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* @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'],
|
||||
}
|
||||
});
|
||||
}));
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getTagIds: function () {
|
||||
var res = [];
|
||||
_.each($('#tag_ids').select2('data'),
|
||||
function (val) {
|
||||
if (val.create) {
|
||||
res.push([0, 0, {'name': val.text}]);
|
||||
} else {
|
||||
res.push([4, val.id]);
|
||||
}
|
||||
});
|
||||
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
|
||||
_svgToPng: function () {
|
||||
var img = this.$el.find("img#slide-image")[0];
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
canvas.getContext("2d").drawImage(img, 0, 0);
|
||||
return canvas.toDataURL("image/png").split(',')[1];
|
||||
},
|
||||
/**
|
||||
* 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._getTagIds(),
|
||||
'category_id': this._getCategoryId()
|
||||
};
|
||||
if (this.file.type === 'application/pdf') {
|
||||
_.extend(values, {
|
||||
'image': canvas.toDataURL().split(',')[1],
|
||||
'index_content': this.index_content,
|
||||
'slide_type': canvas.height > canvas.width ? 'document' : 'presentation',
|
||||
'mime_type': this.file.type,
|
||||
'datas': this.file.data
|
||||
});
|
||||
}
|
||||
if (/^image\/.*/.test(this.file.type)) {
|
||||
_.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._svgToPng() : this.file.data
|
||||
});
|
||||
}
|
||||
return values;
|
||||
},
|
||||
/**
|
||||
* @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');
|
||||
return false;
|
||||
}
|
||||
var url = this.$('#url').val() ? this.is_valid_url : false;
|
||||
if (!(this.file.name || url)) {
|
||||
this.$('#url').closest('.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} ev
|
||||
*/
|
||||
_save: function (ev) {
|
||||
var self = this;
|
||||
if (this._validate()) {
|
||||
var values = this._getValue();
|
||||
if ($(ev.target).data('published')) {
|
||||
values.website_published = true;
|
||||
}
|
||||
this.$('.oe_slides_upload_loading').show();
|
||||
this.$('.modal-footer, .modal-body').hide();
|
||||
ajax.jsonRpc("/slides/add_slide", 'call', values).then(function (data) {
|
||||
if (data.error) {
|
||||
self._displayAlert(data.error);
|
||||
self.$('.oe_slides_upload_loading').hide();
|
||||
self.$('.modal-footer, .modal-body').show();
|
||||
|
||||
} else {
|
||||
window.location = data.url;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @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),
|
||||
@@ -83,13 +313,13 @@ var SlideDialog = Widget.extend({
|
||||
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();
|
||||
this._displayAlert(_t("Invalid file type. Please select pdf or image file"));
|
||||
this._resetFile();
|
||||
return;
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 25) {
|
||||
this.display_alert(_t("File is too big. File size cannot exceed 25MB"));
|
||||
this.reset_file();
|
||||
this._displayAlert(_t("File is too big. File size cannot exceed 25MB"));
|
||||
this._resetFile();
|
||||
return;
|
||||
}
|
||||
this.$('.alert-warning').remove();
|
||||
@@ -113,8 +343,8 @@ var SlideDialog = Widget.extend({
|
||||
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._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) {
|
||||
@@ -169,222 +399,72 @@ var SlideDialog = Widget.extend({
|
||||
|
||||
var input = file.name;
|
||||
var input_val = input.substr(0, input.lastIndexOf('.')) || input;
|
||||
this.check_unique_slide(input_val).then(function (exist) {
|
||||
this._checkUniqueSlide(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._displayAlert(message);
|
||||
}
|
||||
self.$('#name').val(input_val);
|
||||
});
|
||||
},
|
||||
reset_file: function () {
|
||||
var control = this.$('#upload');
|
||||
control.replaceWith(control = control.clone(true));
|
||||
this.file.name = false;
|
||||
},
|
||||
display_alert: function (message) {
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} ev
|
||||
*/
|
||||
_slideUrl: function (ev) {
|
||||
var self = this,
|
||||
value = {
|
||||
'url': $(ev.target).val(),
|
||||
'channel_id': self.channel_id
|
||||
};
|
||||
this.$('.alert-warning').remove();
|
||||
$('<div class="alert alert-warning" role="alert">' + message + '</div>').insertBefore(this.$('form'));
|
||||
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;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
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',
|
||||
},
|
||||
|
||||
/**
|
||||
Wrapper for select2 load data from server at once and store it.
|
||||
* @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();
|
||||
}
|
||||
},
|
||||
|
||||
@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) {
|
||||
return {
|
||||
width: '100%',
|
||||
placeholder: tag,
|
||||
allowClear: true,
|
||||
formatNoMatches: false,
|
||||
multiple: multi,
|
||||
selection_data: false,
|
||||
fetch_rpc_fnc : fetch_fnc,
|
||||
formatSelection: function (data) {
|
||||
if (data.tag) {
|
||||
data.text = data.tag;
|
||||
}
|
||||
return data.text;
|
||||
},
|
||||
createSearchChoice: function (term, data) {
|
||||
var added_tags = $(this.opts.element).select2('data');
|
||||
if (_.filter(_.union(added_tags, data), function (tag) {
|
||||
return tag.text.toLowerCase().localeCompare(term.toLowerCase()) === 0;
|
||||
}).length === 0) {
|
||||
return {
|
||||
id: _.uniqueId('tag_'),
|
||||
create: true,
|
||||
tag: term,
|
||||
text: _.str.sprintf(_t("Create new tag '%s'"), term),
|
||||
};
|
||||
}
|
||||
},
|
||||
fill_data: function (query, data) {
|
||||
var that = this,
|
||||
tags = {results: []};
|
||||
_.each(data, function (obj) {
|
||||
if (that.matcher(query.term, obj.name)) {
|
||||
tags.results.push({id: obj.id, text: obj.name });
|
||||
}
|
||||
});
|
||||
query.callback(tags);
|
||||
},
|
||||
query: function (query) {
|
||||
var that = this;
|
||||
// fetch data only once and store it
|
||||
if (!this.selection_data) {
|
||||
this.fetch_rpc_fnc().then(function (data) {
|
||||
that.fill_data(query, data);
|
||||
that.selection_data = data;
|
||||
});
|
||||
} else {
|
||||
this.fill_data(query, this.selection_data);
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
// Category management from select2
|
||||
set_category_id: function () {
|
||||
var self = this;
|
||||
$('#category_id').select2(this.select2_wrapper(_t('Category'), false,
|
||||
function () {
|
||||
return ajax.jsonRpc("/web/dataset/call_kw", 'call', {
|
||||
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 () {
|
||||
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', {
|
||||
model: 'slide.tag',
|
||||
method: 'search_read',
|
||||
args: [],
|
||||
kwargs: {
|
||||
fields: ['name'],
|
||||
context: weContext.get(), // TODO use this._rpc
|
||||
}
|
||||
});
|
||||
}));
|
||||
},
|
||||
get_tag_ids: function () {
|
||||
var res = [];
|
||||
_.each($('#tag_ids').select2('data'),
|
||||
function (val) {
|
||||
if (val.create) {
|
||||
res.push([0, 0, {'name': val.text}]);
|
||||
} else {
|
||||
res.push([4, val.id]);
|
||||
}
|
||||
});
|
||||
return res;
|
||||
},
|
||||
// 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 () {
|
||||
var img = this.$el.find("img#slide-image")[0];
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
canvas.getContext("2d").drawImage(img, 0, 0);
|
||||
return canvas.toDataURL("image/png").split(',')[1];
|
||||
},
|
||||
// Values and save
|
||||
get_value: 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()
|
||||
};
|
||||
if (this.file.type === 'application/pdf') {
|
||||
_.extend(values, {
|
||||
'image': canvas.toDataURL().split(',')[1],
|
||||
'index_content': this.index_content,
|
||||
'slide_type': canvas.height > canvas.width ? 'document' : 'presentation',
|
||||
'mime_type': this.file.type,
|
||||
'datas': this.file.data
|
||||
});
|
||||
}
|
||||
if (/^image\/.*/.test(this.file.type)) {
|
||||
_.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
|
||||
});
|
||||
}
|
||||
return values;
|
||||
},
|
||||
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');
|
||||
return false;
|
||||
}
|
||||
var url = this.$('#url').val() ? this.is_valid_url : false;
|
||||
if (!(this.file.name || url)) {
|
||||
this.$('#url').closest('.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
save: function (ev) {
|
||||
var self = this;
|
||||
if (this.validate()) {
|
||||
var values = this.get_value();
|
||||
if ($(ev.target).data('published')) {
|
||||
values.website_published = true;
|
||||
}
|
||||
this.$('.oe_slides_upload_loading').show();
|
||||
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.$('.oe_slides_upload_loading').hide();
|
||||
self.$('.modal-footer, .modal-body').show();
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
} else {
|
||||
window.location = data.url;
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_bindEventButton: function () {
|
||||
var channel_id = $(this).attr('channel_id');
|
||||
slides.page_widgets['upload_dialog'] = new SlideDialog(this, channel_id).appendTo(document.body);
|
||||
},
|
||||
cancel: function () {
|
||||
this.trigger("cancel");
|
||||
}
|
||||
});
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user