From da717c55d77de5565292c42019e9f33ff61b537b Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Fri, 18 Jul 2014 17:01:27 -0400 Subject: [PATCH] FEATURE: Like button should act like a toggle and stay there once you've clicked it. --- .../discourse/controllers/topic_controller.js | 14 ++------ .../discourse/lib/keyboard_shortcuts.js | 2 +- .../javascripts/discourse/models/_post.js | 2 +- .../discourse/models/action_summary.js | 12 +++++++ .../discourse/views/post-menu.js.es6 | 36 ++++++++++--------- .../stylesheets/desktop/topic-post.scss | 5 +++ config/locales/client.en.yml | 2 ++ 7 files changed, 43 insertions(+), 30 deletions(-) diff --git a/app/assets/javascripts/discourse/controllers/topic_controller.js b/app/assets/javascripts/discourse/controllers/topic_controller.js index a6d2b29903b..17fd59b5ad6 100644 --- a/app/assets/javascripts/discourse/controllers/topic_controller.js +++ b/app/assets/javascripts/discourse/controllers/topic_controller.js @@ -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(); } }, diff --git a/app/assets/javascripts/discourse/lib/keyboard_shortcuts.js b/app/assets/javascripts/discourse/lib/keyboard_shortcuts.js index 4033fa635d2..3e2df6a1728 100644 --- a/app/assets/javascripts/discourse/lib/keyboard_shortcuts.js +++ b/app/assets/javascripts/discourse/lib/keyboard_shortcuts.js @@ -20,7 +20,7 @@ Discourse.KeyboardShortcuts = Ember.Object.createWithMixins({ 'b': 'toggleBookmark', 'd': 'deletePost', 'e': 'editPost', - 'l': 'likePost', + 'l': 'toggleLike', 'r': 'replyToPost', '!': 'showFlags' }, diff --git a/app/assets/javascripts/discourse/models/_post.js b/app/assets/javascripts/discourse/models/_post.js index db73e811161..f81e3bbb21c 100644 --- a/app/assets/javascripts/discourse/models/_post.js +++ b/app/assets/javascripts/discourse/models/_post.js @@ -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'), diff --git a/app/assets/javascripts/discourse/models/action_summary.js b/app/assets/javascripts/discourse/models/action_summary.js index 4fbb7a7d10e..47ddddeccd9 100644 --- a/app/assets/javascripts/discourse/models/action_summary.js +++ b/app/assets/javascripts/discourse/models/action_summary.js @@ -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 = {}; diff --git a/app/assets/javascripts/discourse/views/post-menu.js.es6 b/app/assets/javascripts/discourse/views/post-menu.js.es6 index 1538a75055f..d2359f96d55 100644 --- a/app/assets/javascripts/discourse/views/post-menu.js.es6 +++ b/app/assets/javascripts/discourse/views/post-menu.js.es6 @@ -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(""); }; @@ -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 diff --git a/app/assets/stylesheets/desktop/topic-post.scss b/app/assets/stylesheets/desktop/topic-post.scss index edc70c16857..5a6fdd9beb6 100644 --- a/app/assets/stylesheets/desktop/topic-post.scss +++ b/app/assets/stylesheets/desktop/topic-post.scss @@ -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 { diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 3dc547b1eeb..32a42406334 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -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"