diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index f04a61c4903..11b5fb0edeb 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -35,6 +35,28 @@ class WebsiteSlides(http.Controller): request.session[slide_key] = viewed_slides return True + def _check_session_slide_vote(self, slide, upvote=True): + if not request.session.get('__wslides_upvote'): + request.session['__wslides_upvote'] = [] + if not request.session.get('__wslides_downvote'): + request.session['__wslides_downvote'] = [] + if upvote and slide.id in request.session['__wslides_upvote']: + return False + if not upvote and slide.id in request.session['__wslides_downvote']: + return False + if upvote and slide.id in request.session['__wslides_downvote']: + request.session['__wslides_downvote'].remove(slide.id) + return 0 + if not upvote and slide.id in request.session['__wslides_upvote']: + request.session['__wslides_upvote'].remove(slide.id) + return 0 + if upvote: + request.session['__wslides_upvote'].append(slide.id) + return 1 + if not upvote: + request.session['__wslides_downvote'].append(slide.id) + return -1 + def _get_slide_detail(self, slide): most_viewed_slides = slide.get_most_viewed_slides(self._slides_per_list) related_slides = slide.get_related_slides(self._slides_per_list) @@ -43,7 +65,7 @@ class WebsiteSlides(http.Controller): 'most_viewed_slides': most_viewed_slides, 'related_slides': related_slides, 'user': request.env.user, - 'is_public_user': request.env.user == request.website.user_id, + 'is_public_user': request.website.is_public_user(), 'comments': slide.channel_id.can_see_full and slide.website_message_ids or [], 'private': not slide.channel_id.can_see_full, } @@ -66,7 +88,7 @@ class WebsiteSlides(http.Controller): return request.render('website_slides.channels', { 'channels': channels, 'user': request.env.user, - 'is_public_user': request.env.user == request.website.user_id + 'is_public_user': request.website.is_public_user(), }) def sitemap_slide(env, rule, qs): @@ -142,7 +164,7 @@ class WebsiteSlides(http.Controller): 'sorting': sorting, 'user': user, 'pager': pager, - 'is_public_user': user == request.website.user_id, + 'is_public_user': request.website.is_public_user(), 'display_channel_settings': not request.httprequest.cookies.get('slides_channel_%s' % (channel.id), False) and channel.can_see_full, } if search: @@ -209,16 +231,24 @@ class WebsiteSlides(http.Controller): # JSONRPC @http.route('/slides/slide/like', type='json', auth="user", website=True) - def slide_like(self, slide_id): + def slide_like(self, slide_id, upvote): + if request.website.is_public_user(): + return {'error': 'public_user'} slide = request.env['slide.slide'].browse(int(slide_id)) - slide.likes += 1 - return slide.likes - - @http.route('/slides/slide/dislike', type='json', auth="user", website=True) - def slide_dislike(self, slide_id): - slide = request.env['slide.slide'].browse(int(slide_id)) - slide.dislikes += 1 - return slide.dislikes + slide.check_access_rights('read') + slide.check_access_rule('read') + check = self._check_session_slide_vote(slide, upvote=upvote) + if check is False: + return {'error': 'vote_done'} + if check == 1: + slide.sudo().likes += 1 + elif check == 0 and upvote: + slide.sudo().dislikes -= 1 + elif check == 0 and not upvote: + slide.sudo().likes -= 1 + else: + slide.sudo().dislikes += 1 + return {'state': check, 'likes': slide.likes, 'dislikes': slide.dislikes} @http.route(['/slides/slide/send_share_email'], type='json', auth='user', website=True) def slide_send_share_email(self, slide_id, email): @@ -296,6 +326,22 @@ class WebsiteSlides(http.Controller): return {'error': _('Internal server error, please try again later or contact administrator.\nHere is the error message: %s') % e} return {'url': "/slides/slide/%s" % (slide_id.id)} + @http.route(['/slides/tag/search_read'], type='json', auth='user', methods=['POST'], website=True) + def slide_tag_search_read(self, fields, domain): + can_create = request.env['slide.tag'].check_access_rights('create', raise_exception=False) + return { + 'read_results': request.env['slide.tag'].search_read(domain, fields), + 'can_create': can_create, + } + + @http.route(['/slides/category/search_read'], type='json', auth='user', methods=['POST'], website=True) + def slide_category_search_read(self, fields, domain): + can_create = request.env['slide.category'].check_access_rights('create', raise_exception=False) + return { + 'read_results': request.env['slide.category'].search_read(domain, fields), + 'can_create': can_create, + } + # -------------------------------------------------- # EMBED IN THIRD PARTY WEBSITES # -------------------------------------------------- diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py index fb56ca97b25..fae545c87e9 100644 --- a/addons/website_slides/models/slide_channel.py +++ b/addons/website_slides/models/slide_channel.py @@ -127,9 +127,9 @@ class Channel(models.Model): @api.one @api.depends('visibility', 'group_ids', 'upload_group_ids') def _compute_access(self): - self.can_see = self.visibility in ['public', 'private'] or bool(self.group_ids & self.env.user.groups_id) + self.can_see = self.visibility in ['public', 'partial'] or bool(self.group_ids & self.env.user.groups_id) self.can_see_full = self.visibility == 'public' or bool(self.group_ids & self.env.user.groups_id) - self.can_upload = self.can_see and (not self.upload_group_ids or bool(self.upload_group_ids & self.env.user.groups_id)) + self.can_upload = not self.env.user.share and (not self.upload_group_ids or bool(self.upload_group_ids & self.env.user.groups_id)) @api.multi @api.depends('name') diff --git a/addons/website_slides/static/src/js/slides_like.js b/addons/website_slides/static/src/js/slides_like.js index e5ad9e22d7b..c32f484a713 100644 --- a/addons/website_slides/static/src/js/slides_like.js +++ b/addons/website_slides/static/src/js/slides_like.js @@ -11,42 +11,14 @@ var _t = core._t; var LikeButton = Widget.extend({ events: { - 'click': '_onClick', + 'click .o_wslides_like_up': '_onClickUp', + 'click .o_wslides_like_down': '_onClickDown', }, //-------------------------------------------------------------------------- // Private //-------------------------------------------------------------------------- - /** - * @private - * @param {Object} ev - */ - _applyAction: function (ev) { - var button = $(ev.currentTarget); - var slideID = button.data('slide-id'); - var userID = button.data('user-id'); - var isPublic = button.data('public-user'); - var href = button.data('href'); - if (isPublic) { - this._popoverAlert(button, _.str.sprintf(_t('Please login to vote this slide'), (document.URL))); - } else { - var target = button.find('.fa'); - if (localStorage.getItem('slide_vote_' + slideID) !== userID.toString()) { - this._rpc({ - route: href, - params: { - slide_id: slideID, - }, - }).then(function (data) { - target.text(data); - localStorage.setItem('slide_vote_' + slideID, userID); - }); - } else { - this._popoverAlert(button, _t('You have already voted for this slide')); - } - } - }, /** * @private * @param {Object} $el @@ -71,8 +43,38 @@ var LikeButton = Widget.extend({ /** * @private */ - _onClick: function () { - this._applyAction(); + _onClick: function (slideId, voteType) { + var self = this; + this._rpc({ + route: '/slides/slide/like', + params: { + slide_id: slideId, + upvote: voteType === 'like', + }, + }).then(function (data) { + if (! data.error) { + self.$el.find('span.o_wslides_like_up span').text(data.likes); + self.$el.find('span.o_wslides_like_down span').text(data.dislikes); + } else { + if (data.error === 'public_user') { + self._popoverAlert(self.$el, _.str.sprintf(_t('Please login to vote this slide'), (document.URL))); + } else if (data.error === 'vote_done') { + self._popoverAlert(self.$el, _t('You have already voted for this slide')); + } else { + self._popoverAlert(self.$el, _t('Unknown error')); + } + } + }); + }, + + _onClickUp: function (event) { + var slideId = $(event.currentTarget).data('slide-id'); + return this._onClick(slideId, 'like'); + }, + + _onClickDown: function (event) { + var slideId = $(event.currentTarget).data('slide-id'); + return this._onClick(slideId, 'dislike'); }, }); @@ -83,10 +85,9 @@ sAnimations.registry.websiteSlidesLike = sAnimations.Class.extend({ * @override * @param {Object} parent */ - start: function (parent) { + start: function () { var defs = [this._super.apply(this, arguments)]; - defs.push(new LikeButton(this).attachTo($('.oe_slide_js_like'))); - defs.push(new LikeButton(this).attachTo($('.oe_slide_js_unlike'))); + defs.push(new LikeButton(this).attachTo($('.o_wslides_like'))); return $.when.apply($, defs); }, }); diff --git a/addons/website_slides/static/src/js/slides_share.js b/addons/website_slides/static/src/js/slides_share.js index b90f7398ab0..1dfaa3aee41 100644 --- a/addons/website_slides/static/src/js/slides_share.js +++ b/addons/website_slides/static/src/js/slides_share.js @@ -50,12 +50,13 @@ sAnimations.registry.websiteSlidesShare = sAnimations.Class.extend({ * @param {Object} parent */ start: function (parent) { + var self = this; var defs = [this._super.apply(this, arguments)]; defs.push(new ShareMail(this).attachTo($('.oe_slide_js_share_email'))); if ($('div#statistic').length) { - var slideURL = $('div#statistic').attr('slide-url'); - var socialURLs = { + this.slideURL = $('div#statistic').attr('slide-url'); + this.socialURLs = { linkedin: 'https://www.linkedin.com/countserv/count/share?url=', twitter: 'https://cdn.api.twitter.com/1/urls/count.json?url=', facebook: 'https://graph.facebook.com/?id=', @@ -63,9 +64,9 @@ sAnimations.registry.websiteSlidesShare = sAnimations.Class.extend({ }; } - _.each(socialURLs, function (value, key) { - this._updateStatistics(key, slideURL); - }); + _.each(this.socialURLs, function (value, key) { + self._updateStatistics(key, self.slideURL); + }); return $.when.apply($, defs); }, @@ -80,9 +81,10 @@ sAnimations.registry.websiteSlidesShare = sAnimations.Class.extend({ * @param {string} slide_url */ _updateStatistics: function (socialSite, slideURL) { + var self = this; if (socialSite === 'gplus') { $.ajax({ - url: this.social_urls['gplus'], + url: self.socialURLs['gplus'], type: 'POST', dataType: 'json', contentType: 'application/json', @@ -107,7 +109,7 @@ sAnimations.registry.websiteSlidesShare = sAnimations.Class.extend({ }); } else { $.ajax({ - url: this.social_urls[socialSite] + slideURL, + url: self.socialURLs[socialSite] + slideURL, dataType: 'jsonp', success: function (data) { var shareCount = (socialSite === 'facebook' ? data.shares : data.count) || 0; diff --git a/addons/website_slides/static/src/js/slides_upload.js b/addons/website_slides/static/src/js/slides_upload.js index dd1c9a6f3a1..5db2c3c5326 100644 --- a/addons/website_slides/static/src/js/slides_upload.js +++ b/addons/website_slides/static/src/js/slides_upload.js @@ -53,7 +53,6 @@ var SlideDialog = Widget.extend({ * @param {string} file_name */ _checkUniqueSlide: function (fileName) { - var self = this; return this._rpc({ model: 'slide.slide', method: 'search_count', @@ -107,12 +106,16 @@ var SlideDialog = Widget.extend({ if (_.filter(_.union(addedTags, 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), - }; + if (this.opts.can_create) { + return { + id: _.uniqueId('tag_'), + create: true, + tag: term, + text: _.str.sprintf(_t("Create new tag '%s'"), term), + }; + } else { + return undefined; + } } }, fill_data: function (query, data) { @@ -130,8 +133,9 @@ var SlideDialog = Widget.extend({ // 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; + that.can_create = data.can_create; + that.fill_data(query, data.read_results); + that.selection_data = data.read_results; }); } else { this.fill_data(query, this.selection_data); @@ -148,11 +152,9 @@ var SlideDialog = Widget.extend({ var self = this; $('#category_id').select2(this._select2Wrapper(_t('Category'), false, function () { - return this._rpc({ - model: 'slide.category', - method: 'search_read', - args: [], - kwargs: { + return self._rpc({ + route: '/slides/category/search_read', + params: { fields: ['name'], domain: [['channel_id', '=', self.channel_id]], } @@ -175,13 +177,13 @@ var SlideDialog = Widget.extend({ * @private */ _setTagIds: function () { + var self = this; $('#tag_ids').select2(this._select2Wrapper(_t('Tags'), true, function () { - return this._rpc({ - model: 'slide.tag', - method: 'search_read', - args: [], - kwargs: { + return self._rpc({ + route: '/slides/tag/search_read', + params: { fields: ['name'], + domain: [], } }); })); diff --git a/addons/website_slides/static/src/scss/website_slides.scss b/addons/website_slides/static/src/scss/website_slides.scss index f67344fdbb6..e39e803c877 100644 --- a/addons/website_slides/static/src/scss/website_slides.scss +++ b/addons/website_slides/static/src/scss/website_slides.scss @@ -84,7 +84,7 @@ img.oe_slides_promote_image { border-bottom: 1px solid $nav-tabs-border-color; } -.oe_slide_js_like, .oe_slide_js_unlike{ +.o_wslides_like_up, .o_wslides_like_down { cursor: pointer; color: $link-color; } @@ -153,6 +153,13 @@ textarea.o_slides_comment { padding: 10px; } +// Slide display +div.embed-responsive { + iframe.o_wslides_iframe_viewer { + position: relative; + } +} + // PDF Viewer Share bar .oe_slides_share_bar{ padding: 10px 0; diff --git a/addons/website_slides/views/website_slides_templates.xml b/addons/website_slides/views/website_slides_templates.xml index 393123f9e05..129ce77f965 100644 --- a/addons/website_slides/views/website_slides_templates.xml +++ b/addons/website_slides/views/website_slides_templates.xml @@ -88,7 +88,7 @@ / - + Upload @@ -233,13 +233,13 @@

No presentation published yet.

The is empty. - + Upload PDF presentations, documents, videos or infographic using the button below.

- + Upload

@@ -436,28 +436,22 @@
-
+
- + - +