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