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
This commit is contained in:
parent
8a86705e51
commit
4a2871f7f6
|
@ -6,17 +6,18 @@ import { h } from "virtual-dom";
|
||||||
import { userPath } from "discourse/lib/url";
|
import { userPath } from "discourse/lib/url";
|
||||||
import hbs from "discourse/widgets/hbs-compiler";
|
import hbs from "discourse/widgets/hbs-compiler";
|
||||||
|
|
||||||
export function avatarAtts(user) {
|
export function smallUserAtts(user) {
|
||||||
return {
|
return {
|
||||||
template: user.avatar_template,
|
template: user.avatar_template,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
post_url: user.post_url,
|
post_url: user.post_url,
|
||||||
url: userPath(user.username_lower)
|
url: userPath(user.username_lower),
|
||||||
|
unknown: user.unknown
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
createWidget("small-user-list", {
|
createWidget("small-user-list", {
|
||||||
tagName: "div.clearfix",
|
tagName: "div.clearfix.small-user-list",
|
||||||
|
|
||||||
buildClasses(atts) {
|
buildClasses(atts) {
|
||||||
return atts.listClassName;
|
return atts.listClassName;
|
||||||
|
@ -30,7 +31,7 @@ createWidget("small-user-list", {
|
||||||
atts.addSelf &&
|
atts.addSelf &&
|
||||||
!users.some(u => u.username === currentUser.username)
|
!users.some(u => u.username === currentUser.username)
|
||||||
) {
|
) {
|
||||||
users = users.concat(avatarAtts(currentUser));
|
users = users.concat(smallUserAtts(currentUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
let description = null;
|
let description = null;
|
||||||
|
@ -43,7 +44,13 @@ createWidget("small-user-list", {
|
||||||
let postUrl;
|
let postUrl;
|
||||||
const icons = users.map(u => {
|
const icons = users.map(u => {
|
||||||
postUrl = postUrl || u.post_url;
|
postUrl = postUrl || u.post_url;
|
||||||
|
if (u.unknown) {
|
||||||
|
return h("div.unknown", {
|
||||||
|
attributes: { title: I18n.t("post.unknown_user") }
|
||||||
|
});
|
||||||
|
} else {
|
||||||
return avatarFor.call(this, "small", u);
|
return avatarFor.call(this, "small", u);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (postUrl) {
|
if (postUrl) {
|
||||||
|
|
|
@ -12,8 +12,13 @@ export default createWidget("emoji", {
|
||||||
tagName: "img.emoji",
|
tagName: "img.emoji",
|
||||||
|
|
||||||
buildAttributes(attrs) {
|
buildAttributes(attrs) {
|
||||||
let result = { src: emojiUrlFor(attrs.name), alt: `:${attrs.name}:` };
|
let result = {
|
||||||
if (attrs.title) result.title = attrs.name;
|
src: emojiUrlFor(attrs.name),
|
||||||
|
alt: `:${attrs.alt || attrs.name}:`
|
||||||
|
};
|
||||||
|
if (attrs.title) {
|
||||||
|
result.title = typeof attrs.title === "string" ? attrs.title : attrs.name;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { next, run } from "@ember/runloop";
|
import { next, run } from "@ember/runloop";
|
||||||
import { applyDecorators, createWidget } from "discourse/widgets/widget";
|
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 { h } from "virtual-dom";
|
||||||
import showModal from "discourse/lib/show-modal";
|
import showModal from "discourse/lib/show-modal";
|
||||||
import { Promise } from "rsvp";
|
import { Promise } from "rsvp";
|
||||||
|
@ -696,7 +696,7 @@ export default createWidget("post-menu", {
|
||||||
post_action_type_id: LIKE_ACTION
|
post_action_type_id: LIKE_ACTION
|
||||||
})
|
})
|
||||||
.then(users => {
|
.then(users => {
|
||||||
state.likedUsers = users.map(avatarAtts);
|
state.likedUsers = users.map(smallUserAtts);
|
||||||
state.total = users.totalRows;
|
state.total = users.totalRows;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -705,7 +705,7 @@ export default createWidget("post-menu", {
|
||||||
const { attrs, state } = this;
|
const { attrs, state } = this;
|
||||||
|
|
||||||
return this.store.find("post-reader", { id: attrs.id }).then(users => {
|
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;
|
state.totalReaders = users.totalRows;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -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 {
|
.post-hidden {
|
||||||
.topic-avatar,
|
.topic-avatar,
|
||||||
.cooked,
|
.cooked,
|
||||||
|
|
|
@ -15,6 +15,16 @@ class PostActionUsersController < ApplicationController
|
||||||
post = finder.first
|
post = finder.first
|
||||||
guardian.ensure_can_see!(post)
|
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)
|
post_actions = post.post_actions.where(post_action_type_id: post_action_type_id)
|
||||||
.includes(:user)
|
.includes(:user)
|
||||||
.offset(page * page_size)
|
.offset(page * page_size)
|
||||||
|
@ -29,7 +39,13 @@ class PostActionUsersController < ApplicationController
|
||||||
action_type = PostActionType.types.key(post_action_type_id)
|
action_type = PostActionType.types.key(post_action_type_id)
|
||||||
total_count = post["#{action_type}_count"].to_i
|
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
|
if total_count > page_size
|
||||||
data[:total_rows_post_action_users] = total_count
|
data[:total_rows_post_action_users] = total_count
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
class PostActionUserSerializer < BasicUserSerializer
|
class PostActionUserSerializer < BasicUserSerializer
|
||||||
attributes :post_url,
|
attributes :post_url,
|
||||||
:username_lower
|
:username_lower,
|
||||||
|
:unknown
|
||||||
|
|
||||||
def id
|
def id
|
||||||
object.user.id
|
object.user.id
|
||||||
|
@ -24,4 +25,12 @@ class PostActionUserSerializer < BasicUserSerializer
|
||||||
object.related_post.url if object.related_post_id && object.related_post
|
object.related_post.url if object.related_post_id && object.related_post
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def unknown
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_unknown?
|
||||||
|
(@options[:unknown_user_ids] || []).include?(object.user.id)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2603,6 +2603,7 @@ en:
|
||||||
one: "%{count} Reply"
|
one: "%{count} Reply"
|
||||||
other: "%{count} Replies"
|
other: "%{count} Replies"
|
||||||
|
|
||||||
|
unknown_user: "(unknown/deleted user)"
|
||||||
has_likes_title:
|
has_likes_title:
|
||||||
one: "%{count} person liked this post"
|
one: "%{count} person liked this post"
|
||||||
other: "%{count} people liked this post"
|
other: "%{count} people liked this post"
|
||||||
|
|
|
@ -59,6 +59,22 @@ describe PostActionUsersController do
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
end
|
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
|
it "paginates post actions" do
|
||||||
user_ids = []
|
user_ids = []
|
||||||
5.times do
|
5.times do
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
||||||
|
});
|
Loading…
Reference in New Issue