FEATURE: Like button should act like a toggle and stay there once you've

clicked it.
This commit is contained in:
Robin Ward 2014-07-18 17:01:27 -04:00
parent 3aa8d8efa1
commit da717c55d7
7 changed files with 43 additions and 30 deletions

View file

@ -1,11 +1,3 @@
/**
This controller supports all actions related to a topic
@class TopicController
@extends Discourse.ObjectController
@namespace Discourse
@module Discourse
**/
Discourse.TopicController = Discourse.ObjectController.extend(Discourse.SelectedPostsCount, {
multiSelect: false,
needs: ['header', 'modal', 'composer', 'quote-button', 'search', 'topic-progress'],
@ -84,10 +76,10 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
return false;
},
likePost: function(post) {
toggleLike: function(post) {
var likeAction = post.get('actionByName.like');
if (likeAction && likeAction.get('can_act')) {
likeAction.act();
if (likeAction && likeAction.get('canToggle')) {
likeAction.toggle();
}
},

View file

@ -20,7 +20,7 @@ Discourse.KeyboardShortcuts = Ember.Object.createWithMixins({
'b': 'toggleBookmark',
'd': 'deletePost',
'e': 'editPost',
'l': 'likePost',
'l': 'toggleLike',
'r': 'replyToPost',
'!': 'showFlags'
},

View file

@ -119,7 +119,7 @@ Discourse.Post = Discourse.Model.extend({
flagsAvailable: function() {
var post = this;
return Discourse.Site.currentProp('flagTypes').filter(function(item) {
return post.get("actionByName." + (item.get('name_key')) + ".can_act");
return post.get("actionByName." + item.get('name_key') + ".can_act");
});
}.property('actions_summary.@each.can_act'),

View file

@ -26,6 +26,10 @@ Discourse.ActionSummary = Discourse.Model.extend({
usersCollapsed: Em.computed.not('usersExpanded'),
usersExpanded: Em.computed.gt('users.length', 0),
canToggle: function() {
return this.get('can_undo') || this.get('can_act');
}.property('can_undo', 'can_act'),
// Remove it
removeAction: function() {
this.setProperties({
@ -40,6 +44,14 @@ Discourse.ActionSummary = Discourse.Model.extend({
}
},
toggle: function() {
if (!this.get('acted')) {
this.act();
} else {
this.undo();
}
},
// Perform this action
act: function(opts) {
if (!opts) opts = {};

View file

@ -1,12 +1,3 @@
/**
This view renders a menu below a post. It uses buffered rendering for performance.
@class PostMenuView
@extends Discourse.View
@namespace Discourse
@module Discourse
**/
// Helper class for rendering a button
var Button = function(action, label, icon, opts) {
this.action = action;
@ -21,14 +12,17 @@ var Button = function(action, label, icon, opts) {
};
Button.prototype.render = function(buffer) {
var opts = this.opts;
buffer.push("<button title=\"" + I18n.t(this.label) + "\"");
if (this.opts.className) { buffer.push(" class=\"" + this.opts.className + "\""); }
if (this.opts.shareUrl) { buffer.push(" data-share-url=\"" + this.opts.shareUrl + "\""); }
if (this.opts.postNumber) { buffer.push(" data-post-number=\"" + this.opts.postNumber + "\""); }
if (opts.disabled) { buffer.push(" disabled"); }
if (opts.className) { buffer.push(" class=\"" + opts.className + "\""); }
if (opts.shareUrl) { buffer.push(" data-share-url=\"" + opts.shareUrl + "\""); }
if (opts.postNumber) { buffer.push(" data-post-number=\"" + opts.postNumber + "\""); }
buffer.push(" data-action=\"" + this.action + "\">");
if (this.icon) { buffer.push("<i class=\"fa fa-" + this.icon + "\"></i>"); }
if (this.opts.textLabel) { buffer.push(I18n.t(this.opts.textLabel)); }
if (this.opts.innerHTML) { buffer.push(this.opts.innerHTML); }
if (opts.textLabel) { buffer.push(I18n.t(opts.textLabel)); }
if (opts.innerHTML) { buffer.push(opts.innerHTML); }
buffer.push("</button>");
};
@ -188,12 +182,20 @@ export default Discourse.View.extend({
// Like button
buttonForLike: function(post) {
if (!post.get('actionByName.like.can_act')) return;
return new Button('like', 'post.controls.like', 'heart', {className: 'like'});
var likeAction = post.get('actionByName.like');
if (!likeAction) { return; }
var className = likeAction.get('acted') ? 'has-like' : 'like';
if (likeAction.get('canToggle')) {
var descKey = likeAction.get('acted') ? 'post.controls.undo_like' : 'post.controls.like';
return new Button('like', descKey, 'heart', {className: className});
} else if (likeAction.get('acted')) {
return new Button('like', 'post.controls.has_liked', 'heart', {className: className, disabled: true});
}
},
clickLike: function(post) {
this.get('controller').send('likePost', post);
this.get('controller').send('toggleLike', post);
},
// Flag button

View file

@ -169,6 +169,11 @@ nav.post-controls {
background: scale-color($love, $lightness: 75%);
}
&.has-like {color: $love;}
&.has-like[disabled]:hover {
background: transparent;
}
&.bookmark {padding: 8px 11px; }
.read-icon {

View file

@ -1022,6 +1022,8 @@ en:
controls:
reply: "begin composing a reply to this post"
like: "like this post"
has_liked: "you've liked this post"
undo_like: "undo like"
edit: "edit this post"
flag: "privately flag this post for attention or send a private notification about it"
delete: "delete this post"