From ec8306835dcadf24a0d0ff83767016bbaefa8fa4 Mon Sep 17 00:00:00 2001 From: Bianca Nenciu Date: Mon, 22 Aug 2022 14:58:02 +0300 Subject: [PATCH] FIX: Improvements to like button for archived topics (#17951) * FIX: Do not allow to remove like if topic is archived * FIX: Always show like button The like button used to be hidden if the topic was archived and it had no likes. This commit changes that to always show the like button, but with a not-allowed cursor if the topic is archived. --- .../discourse/app/lib/transform-post.js | 8 +-- .../discourse/app/widgets/post-menu.js | 72 ++++++++++--------- app/serializers/post_serializer.rb | 3 +- lib/guardian/post_guardian.rb | 2 +- spec/lib/guardian_spec.rb | 6 ++ spec/serializers/post_serializer_spec.rb | 8 +++ 6 files changed, 58 insertions(+), 41 deletions(-) diff --git a/app/assets/javascripts/discourse/app/lib/transform-post.js b/app/assets/javascripts/discourse/app/lib/transform-post.js index 49ffd0e37f3..e7f44c5afc1 100644 --- a/app/assets/javascripts/discourse/app/lib/transform-post.js +++ b/app/assets/javascripts/discourse/app/lib/transform-post.js @@ -255,12 +255,10 @@ export default function transformPost( if (likeAction) { postAtts.liked = likeAction.acted; postAtts.canToggleLike = likeAction.get("canToggle"); - postAtts.showLike = postAtts.liked || postAtts.canToggleLike; + postAtts.showLike = true; postAtts.likeCount = likeAction.count; - } - - if (!currentUser) { - postAtts.showLike = !topic.archived; + } else if (!currentUser) { + postAtts.showLike = true; } if (postAtts.post_number === 1) { diff --git a/app/assets/javascripts/discourse/app/widgets/post-menu.js b/app/assets/javascripts/discourse/app/widgets/post-menu.js index 7389b2b24cb..06765614ce7 100644 --- a/app/assets/javascripts/discourse/app/widgets/post-menu.js +++ b/app/assets/javascripts/discourse/app/widgets/post-menu.js @@ -147,41 +147,45 @@ function likeCount(attrs, state) { registerButton("like-count", likeCount); -registerButton("like", (attrs) => { - if (!attrs.showLike) { - return likeCount(attrs); +registerButton( + "like", + (attrs, _state, _siteSettings, _settings, currentUser) => { + if (!attrs.showLike) { + return likeCount(attrs); + } + + const className = attrs.liked + ? "toggle-like has-like fade-out" + : "toggle-like like"; + + const button = { + action: "like", + icon: attrs.liked ? "d-liked" : "d-unliked", + className, + before: "like-count", + data: { + "post-id": attrs.id, + }, + }; + + // If the user has already liked the post and doesn't have permission + // to undo that operation, then indicate via the title that they've liked it + // and disable the button. Otherwise, set the title even if the user + // is anonymous (meaning they don't currently have permission to like); + // this is important for accessibility. + if (attrs.liked && !attrs.canToggleLike) { + button.title = "post.controls.has_liked"; + } else { + button.title = attrs.liked + ? "post.controls.undo_like" + : "post.controls.like"; + } + if (currentUser && !attrs.canToggleLike) { + button.disabled = true; + } + return button; } - - const className = attrs.liked - ? "toggle-like has-like fade-out" - : "toggle-like like"; - - const button = { - action: "like", - icon: attrs.liked ? "d-liked" : "d-unliked", - className, - before: "like-count", - data: { - "post-id": attrs.id, - }, - }; - - // If the user has already liked the post and doesn't have permission - // to undo that operation, then indicate via the title that they've liked it - // and disable the button. Otherwise, set the title even if the user - // is anonymous (meaning they don't currently have permission to like); - // this is important for accessibility. - if (attrs.liked && !attrs.canToggleLike) { - button.title = "post.controls.has_liked"; - button.disabled = true; - } else { - button.title = attrs.liked - ? "post.controls.undo_like" - : "post.controls.like"; - } - - return button; -}); +); registerButton("flag-count", (attrs) => { let className = "button-count"; diff --git a/app/serializers/post_serializer.rb b/app/serializers/post_serializer.rb index 8f0bebf4c59..338a3f2f9e4 100644 --- a/app/serializers/post_serializer.rb +++ b/app/serializers/post_serializer.rb @@ -315,7 +315,8 @@ class PostSerializer < BasicPostSerializer summary.delete(:count) if summary[:count] == 0 # Only include it if the user can do it or it has a count - if summary[:can_act] || summary[:count] + # If it is a like, we want to show it always (even for archived topic) + if summary[:can_act] || summary[:count] || (sym == :like && object.user_id != scope.user&.id) result << summary end end diff --git a/lib/guardian/post_guardian.rb b/lib/guardian/post_guardian.rb index f20920cf696..ee02e43abd6 100644 --- a/lib/guardian/post_guardian.rb +++ b/lib/guardian/post_guardian.rb @@ -232,7 +232,7 @@ module PostGuardian def can_delete_post_action?(post_action) return false unless is_my_own?(post_action) && !post_action.is_private_message? - post_action.created_at > SiteSetting.post_undo_action_window_mins.minutes.ago + post_action.created_at > SiteSetting.post_undo_action_window_mins.minutes.ago && !post_action.post.topic&.archived? end def can_see_post?(post) diff --git a/spec/lib/guardian_spec.rb b/spec/lib/guardian_spec.rb index b8b0780176e..cdcab4d22cb 100644 --- a/spec/lib/guardian_spec.rb +++ b/spec/lib/guardian_spec.rb @@ -2235,6 +2235,12 @@ RSpec.describe Guardian do expect(Guardian.new(user).can_delete?(post_action)).to be_falsey end + it "returns false if topic is archived" do + post.topic.update!(archived: true) + + expect(Guardian.new(user).can_delete?(post_action)).to be_falsey + end + it "returns true if it's yours" do expect(Guardian.new(user).can_delete?(post_action)).to be_truthy end diff --git a/spec/serializers/post_serializer_spec.rb b/spec/serializers/post_serializer_spec.rb index 23c3123ad7a..50f39b2642d 100644 --- a/spec/serializers/post_serializer_spec.rb +++ b/spec/serializers/post_serializer_spec.rb @@ -55,6 +55,14 @@ RSpec.describe PostSerializer do expect(notify_user_action).to eq(nil) end + + it "shows like for archived topics even if user cannot act" do + post = Fabricate(:post) + post.topic.update!(archived: true) + + serializer = PostSerializer.new(post, scope: Guardian.new(actor), root: false) + expect(serializer.as_json[:actions_summary].map { |a| a[:id] }).to include(PostActionType.types[:like]) + end end context "with a post with reviewable content" do