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, { Discourse.TopicController = Discourse.ObjectController.extend(Discourse.SelectedPostsCount, {
multiSelect: false, multiSelect: false,
needs: ['header', 'modal', 'composer', 'quote-button', 'search', 'topic-progress'], needs: ['header', 'modal', 'composer', 'quote-button', 'search', 'topic-progress'],
@ -84,10 +76,10 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
return false; return false;
}, },
likePost: function(post) { toggleLike: function(post) {
var likeAction = post.get('actionByName.like'); var likeAction = post.get('actionByName.like');
if (likeAction && likeAction.get('can_act')) { if (likeAction && likeAction.get('canToggle')) {
likeAction.act(); likeAction.toggle();
} }
}, },

View File

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

View File

@ -119,7 +119,7 @@ Discourse.Post = Discourse.Model.extend({
flagsAvailable: function() { flagsAvailable: function() {
var post = this; var post = this;
return Discourse.Site.currentProp('flagTypes').filter(function(item) { 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'), }.property('actions_summary.@each.can_act'),

View File

@ -26,6 +26,10 @@ Discourse.ActionSummary = Discourse.Model.extend({
usersCollapsed: Em.computed.not('usersExpanded'), usersCollapsed: Em.computed.not('usersExpanded'),
usersExpanded: Em.computed.gt('users.length', 0), 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 // Remove it
removeAction: function() { removeAction: function() {
this.setProperties({ 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 // Perform this action
act: function(opts) { act: function(opts) {
if (!opts) 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 // Helper class for rendering a button
var Button = function(action, label, icon, opts) { var Button = function(action, label, icon, opts) {
this.action = action; this.action = action;
@ -21,14 +12,17 @@ var Button = function(action, label, icon, opts) {
}; };
Button.prototype.render = function(buffer) { Button.prototype.render = function(buffer) {
var opts = this.opts;
buffer.push("<button title=\"" + I18n.t(this.label) + "\""); buffer.push("<button title=\"" + I18n.t(this.label) + "\"");
if (this.opts.className) { buffer.push(" class=\"" + this.opts.className + "\""); } if (opts.disabled) { buffer.push(" disabled"); }
if (this.opts.shareUrl) { buffer.push(" data-share-url=\"" + this.opts.shareUrl + "\""); } if (opts.className) { buffer.push(" class=\"" + opts.className + "\""); }
if (this.opts.postNumber) { buffer.push(" data-post-number=\"" + this.opts.postNumber + "\""); } 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 + "\">"); buffer.push(" data-action=\"" + this.action + "\">");
if (this.icon) { buffer.push("<i class=\"fa fa-" + this.icon + "\"></i>"); } if (this.icon) { buffer.push("<i class=\"fa fa-" + this.icon + "\"></i>"); }
if (this.opts.textLabel) { buffer.push(I18n.t(this.opts.textLabel)); } if (opts.textLabel) { buffer.push(I18n.t(opts.textLabel)); }
if (this.opts.innerHTML) { buffer.push(this.opts.innerHTML); } if (opts.innerHTML) { buffer.push(opts.innerHTML); }
buffer.push("</button>"); buffer.push("</button>");
}; };
@ -188,12 +182,20 @@ export default Discourse.View.extend({
// Like button // Like button
buttonForLike: function(post) { buttonForLike: function(post) {
if (!post.get('actionByName.like.can_act')) return; var likeAction = post.get('actionByName.like');
return new Button('like', 'post.controls.like', 'heart', {className: '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) { clickLike: function(post) {
this.get('controller').send('likePost', post); this.get('controller').send('toggleLike', post);
}, },
// Flag button // Flag button

View File

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

View File

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