Skip to content

Commit

Permalink
FEATURE: Don't display muted/ignored users under "who liked" (#10084)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
eviltrout committed Jun 19, 2020
1 parent 8a86705 commit 4a2871f
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 12 deletions.
17 changes: 12 additions & 5 deletions app/assets/javascripts/discourse/app/widgets/actions-summary.js
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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) {
Expand Down
9 changes: 7 additions & 2 deletions app/assets/javascripts/discourse/app/widgets/emoji.js
Expand Up @@ -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;
}
});
6 changes: 3 additions & 3 deletions 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";
Expand Down Expand Up @@ -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;
});
},
Expand All @@ -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;
});
},
Expand Down
10 changes: 10 additions & 0 deletions app/assets/stylesheets/common/base/topic-post.scss
Expand Up @@ -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,
Expand Down
18 changes: 17 additions & 1 deletion app/controllers/post_action_users_controller.rb
Expand Up @@ -15,6 +15,16 @@ def index
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)
Expand All @@ -29,7 +39,13 @@ def index
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
Expand Down
11 changes: 10 additions & 1 deletion app/serializers/post_action_user_serializer.rb
Expand Up @@ -2,7 +2,8 @@

class PostActionUserSerializer < BasicUserSerializer
attributes :post_url,
:username_lower
:username_lower,
:unknown

def id
object.user.id
Expand All @@ -24,4 +25,12 @@ def post_url
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
1 change: 1 addition & 0 deletions config/locales/client.en.yml
Expand Up @@ -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"
Expand Down
16 changes: 16 additions & 0 deletions spec/requests/post_action_users_controller_spec.rb
Expand Up @@ -59,6 +59,22 @@
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
expect(json_users.find { |u| u['id'] == ignored_user.id }['unknown']).to eq(true)
end

it "paginates post actions" do
user_ids = []
5.times do
Expand Down
20 changes: 20 additions & 0 deletions test/javascripts/widgets/small-user-list-test.js
@@ -0,0 +1,20 @@
import { moduleForWidget, widgetTest } from "helpers/widget-test";

moduleForWidget("small-user-list");

widgetTest("renders avatars and support for unknown", {
template: '{{mount-widget widget="small-user-list" args=args}}',
beforeEach() {
this.set("args", {
users: [
{ id: 456, username: "eviltrout" },
{ id: 457, username: "someone", unknown: true }
]
});
},
async test(assert) {
assert.ok(find("[data-user-card=eviltrout]").length === 1);
assert.ok(find("[data-user-card=someone]").length === 0);
assert.ok(find(".unknown").length, "includes unkown user");
}
});

0 comments on commit 4a2871f

Please sign in to comment.