[IMP] website_slides: improve like / dislike

Like / dislike of slides is fixed and improved to make a tri-state like
behavior. Future commit will change this implementation in order to use
a relationship table between users and slides as we are moving towards
the eLearning platform. Let us have this simple implementation currently
and rewrite it in a near future.

This commit is linked to task ID 1933820 and PR #30553.
This commit is contained in:
Thibault Delavallée
2019-01-28 15:37:13 +00:00
parent 2db50e5796
commit c5da7b8aeb
4 changed files with 81 additions and 56 deletions
+39 -9
View File
@@ -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)
@@ -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):
@@ -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 <a href="/web?redirect=%s">login</a> 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 <a href="/web?redirect=%s">login</a> 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);
},
});
@@ -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;
}
@@ -436,28 +436,22 @@
</div>
<!-- LikeButton widget -->
<div class="text-muted mt4">
<div class="float-right mb16 text-right">
<div class="float-right mb16 text-right o_wslides_like">
<span
class="oe_slide_js_like"
data-href="/slides/slide/like"
t-att-data-user-id="user.id"
t-att-data-public-user="is_public_user"
class="o_wslides_like_up"
t-att-data-slide-id="slide.id"
tabindex="0"
data-toggle="popover">
<i class="fa fa-thumbs-up fa-1x" role="img" aria-label="Likes" title="Likes"/>
<span class="o_wslides_like_dislike_count" t-esc="slide.likes"/>
<span t-esc="slide.likes"/>
</span>
<span
class="oe_slide_js_unlike"
data-href="/slides/slide/dislike"
t-att-data-user-id="user.id"
t-att-data-public-user="is_public_user"
class="o_wslides_like_down"
t-att-data-slide-id="slide.id"
tabindex="0"
data-toggle="popover">
<i class="fa fa-thumbs-down fa-1x" role="img" aria-label="Dislikes" title="Dislikes"/>
<span class="o_wslides_like_dislike_count" t-esc="slide.dislikes"/>
<span t-esc="slide.dislikes"/>
</span>
</div>
</div>