FEATURE: Don't display muted/ignored users under "who liked" (#10084)

FEATURE: Don’t display muted/ignored users under “who liked” (#10084)

  • FEATURE: Don’t display muted/ignored users under “who liked”

Previously, if you clicked on the heart icon below a post it would show you the avatar for a user even if you ignored or muted them.

This commit will instead display a (?) icon. The count of likes will remain correct, but you needn’t be reminded of the person you preferred not to see.

  • Use a circle instead of (?) for unknown user
diff --git a/app/assets/javascripts/discourse/app/widgets/actions-summary.js b/app/assets/javascripts/discourse/app/widgets/actions-summary.js
index 9e15f6d..7ca85f0 100644
--- a/app/assets/javascripts/discourse/app/widgets/actions-summary.js
+++ b/app/assets/javascripts/discourse/app/widgets/actions-summary.js
@@ -6,17 +6,18 @@ import { h } from "virtual-dom";
 import { userPath } from "discourse/lib/url";
 import hbs from "discourse/widgets/hbs-compiler";
 
-export function avatarAtts(user) {
+export function smallUserAtts(user) {
   return {
     template: user.avatar_template,
     username: user.username,
     post_url: user.post_url,
-    url: userPath(user.username_lower)
+    url: userPath(user.username_lower),
+    unknown: user.unknown
   };
 }
 
 createWidget("small-user-list", {
-  tagName: "div.clearfix",
+  tagName: "div.clearfix.small-user-list",
 
   buildClasses(atts) {
     return atts.listClassName;
@@ -30,7 +31,7 @@ createWidget("small-user-list", {
         atts.addSelf &&
         !users.some(u => u.username === currentUser.username)
       ) {
-        users = users.concat(avatarAtts(currentUser));
+        users = users.concat(smallUserAtts(currentUser));
       }
 
       let description = null;
@@ -43,7 +44,13 @@ createWidget("small-user-list", {
       let postUrl;
       const icons = users.map(u => {
         postUrl = postUrl || u.post_url;
-        return avatarFor.call(this, "small", u);
+        if (u.unknown) {
+          return h("div.unknown", {
+            attributes: { title: I18n.t("post.unknown_user") }
+          });
+        } else {
+          return avatarFor.call(this, "small", u);
+        }
       });
 
       if (postUrl) {
diff --git a/app/assets/javascripts/discourse/app/widgets/emoji.js b/app/assets/javascripts/discourse/app/widgets/emoji.js
index 2fe6322..a3f302c 100644
--- a/app/assets/javascripts/discourse/app/widgets/emoji.js
+++ b/app/assets/javascripts/discourse/app/widgets/emoji.js
@@ -12,8 +12,13 @@ export default createWidget("emoji", {
   tagName: "img.emoji",
 
   buildAttributes(attrs) {
-    let result = { src: emojiUrlFor(attrs.name), alt: `:${attrs.name}:` };
-    if (attrs.title) result.title = attrs.name;
+    let result = {
+      src: emojiUrlFor(attrs.name),
+      alt: `:${attrs.alt || attrs.name}:`
+    };
+    if (attrs.title) {
+      result.title = typeof attrs.title === "string" ? attrs.title : attrs.name;
+    }
     return result;
   }
 });
diff --git a/app/assets/javascripts/discourse/app/widgets/post-menu.js b/app/assets/javascripts/discourse/app/widgets/post-menu.js
index fa18b45..d014a67 100644
--- a/app/assets/javascripts/discourse/app/widgets/post-menu.js
+++ b/app/assets/javascripts/discourse/app/widgets/post-menu.js
@@ -1,6 +1,6 @@
 import { next, run } from "@ember/runloop";
 import { applyDecorators, createWidget } from "discourse/widgets/widget";
-import { avatarAtts } from "discourse/widgets/actions-summary";
+import { smallUserAtts } from "discourse/widgets/actions-summary";
 import { h } from "virtual-dom";
 import showModal from "discourse/lib/show-modal";
 import { Promise } from "rsvp";
@@ -696,7 +696,7 @@ export default createWidget("post-menu", {
         post_action_type_id: LIKE_ACTION
       })
       .then(users => {
-        state.likedUsers = users.map(avatarAtts);
+        state.likedUsers = users.map(smallUserAtts);
         state.total = users.totalRows;
       });
   },
@@ -705,7 +705,7 @@ export default createWidget("post-menu", {
     const { attrs, state } = this;
 
     return this.store.find("post-reader", { id: attrs.id }).then(users => {
-      state.readers = users.map(avatarAtts);
+      state.readers = users.map(smallUserAtts);
       state.totalReaders = users.totalRows;
     });
   },
diff --git a/app/assets/stylesheets/common/base/topic-post.scss b/app/assets/stylesheets/common/base/topic-post.scss
index 5f56f61..3b2424c 100644
--- a/app/assets/stylesheets/common/base/topic-post.scss
+++ b/app/assets/stylesheets/common/base/topic-post.scss
@@ -264,6 +264,16 @@ blockquote {
   }
 }
 
+.small-user-list .unknown {
+  display: inline-block;
+  background-color: $primary-low;
+  width: 25px;
+  height: 25px;
+  border-radius: 50%;
+  vertical-align: middle;
+  margin-right: 0.25em;
+}
+
 .post-hidden {
   .topic-avatar,
   .cooked,
diff --git a/app/controllers/post_action_users_controller.rb b/app/controllers/post_action_users_controller.rb
index fe42fd3..0c59b76 100644
--- a/app/controllers/post_action_users_controller.rb
+++ b/app/controllers/post_action_users_controller.rb
@@ -15,6 +15,16 @@ class PostActionUsersController < ApplicationController
     post = finder.first
     guardian.ensure_can_see!(post)
 
+    unknown_user_ids = Set.new
+    if current_user.present?
+      result = DB.query_single(<<~SQL, user_id: current_user.id)
+        SELECT mu.muted_user_id AS id FROM muted_users AS mu WHERE mu.user_id = :user_id
+        UNION
+        SELECT iu.ignored_user_id AS id FROM ignored_users AS iu WHERE iu.user_id = :user_id
+      SQL
+      unknown_user_ids.merge(result)
+    end
+
     post_actions = post.post_actions.where(post_action_type_id: post_action_type_id)
       .includes(:user)
       .offset(page * page_size)
@@ -29,7 +39,13 @@ class PostActionUsersController < ApplicationController
     action_type = PostActionType.types.key(post_action_type_id)
     total_count = post["#{action_type}_count"].to_i
 
-    data = { post_action_users: serialize_data(post_actions.to_a, PostActionUserSerializer) }
+    data = {
+      post_action_users: serialize_data(
+        post_actions.to_a,
+        PostActionUserSerializer,
+        unknown_user_ids: unknown_user_ids
+      )
+    }
 
     if total_count > page_size
       data[:total_rows_post_action_users] = total_count
diff --git a/app/serializers/post_action_user_serializer.rb b/app/serializers/post_action_user_serializer.rb
index c1413c4..40d8145 100644
--- a/app/serializers/post_action_user_serializer.rb
+++ b/app/serializers/post_action_user_serializer.rb
@@ -2,7 +2,8 @@
 
 class PostActionUserSerializer < BasicUserSerializer
   attributes :post_url,
-             :username_lower
+             :username_lower,
+             :unknown
 
   def id
     object.user.id
@@ -24,4 +25,12 @@ class PostActionUserSerializer < BasicUserSerializer
     object.related_post.url if object.related_post_id && object.related_post
   end
 
+  def unknown
+    true
+  end
+
+  def include_unknown?
+    (@options[:unknown_user_ids] || []).include?(object.user.id)
+  end
+
 end
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index aacd7c2..301e9d5 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -2603,6 +2603,7 @@ en:
         one: "%{count} Reply"
         other: "%{count} Replies"
 
+      unknown_user: "(unknown/deleted user)"
       has_likes_title:
         one: "%{count} person liked this post"
         other: "%{count} people liked this post"
diff --git a/spec/requests/post_action_users_controller_spec.rb b/spec/requests/post_action_users_controller_spec.rb
index bc05352..ec6bc28 100644
--- a/spec/requests/post_action_users_controller_spec.rb
+++ b/spec/requests/post_action_users_controller_spec.rb
@@ -59,6 +59,22 @@ describe PostActionUsersController do
     expect(response.status).to eq(200)
   end
 
+  it 'will return an unknown attribute for muted users' do
+    ignored_user = Fabricate(:user)
+    PostActionCreator.like(ignored_user, post)
+    regular_user = Fabricate(:user)
+    PostActionCreator.like(regular_user, post)
+    IgnoredUser.create(user: user, ignored_user: ignored_user)
+
+    get "/post_action_users.json", params: {
+      id: post.id, post_action_type_id: PostActionType.types[:like]
+    }
+    expect(response.status).to eq(200)
+    json_users = response.parsed_body['post_action_users']
+    expect(json_users.find { |u| u['id'] == regular_user.id }['unknown']).to be_blank

[... diff too long, it was truncated ...]

GitHub sha: 4a2871f7

1 Like

This commit appears in #10084 which was merged by eviltrout.