mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
DEV: refactor topic-map participants into glimmer component (#25350)
* DEV: refactor topic-map participants into glimmer components
This commit is contained in:
parent
04d2ec45b4
commit
8b44270929
@ -0,0 +1,70 @@
|
||||
import Component from "@glimmer/component";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import UserAvatarFlair from "discourse/components/user-avatar-flair";
|
||||
import { userPath } from "discourse/lib/url";
|
||||
import { avatarImg } from "discourse-common/lib/avatar-utils";
|
||||
import gt from "truth-helpers/helpers/gt";
|
||||
|
||||
const addTopicParticipantClassesCallbacks = [];
|
||||
|
||||
export function addTopicParticipantClassesCallback(callback) {
|
||||
addTopicParticipantClassesCallbacks.push(callback);
|
||||
}
|
||||
|
||||
export default class TopicParticipant extends Component {
|
||||
get avatarImage() {
|
||||
return htmlSafe(
|
||||
avatarImg({
|
||||
avatarTemplate: this.args.participant.avatar_template,
|
||||
size: "medium",
|
||||
title: this.args.participant.name || this.args.participant.username,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
get participantClasses() {
|
||||
const { primary_group_name } = this.args.participant;
|
||||
return [
|
||||
primary_group_name ? `group-${primary_group_name}` : null,
|
||||
addTopicParticipantClassesCallbacks.map((callback) =>
|
||||
callback(this.args.participant)
|
||||
),
|
||||
]
|
||||
.filter(Boolean)
|
||||
.flat(3)
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
get linkClasses() {
|
||||
return [
|
||||
"poster",
|
||||
"trigger-user-card",
|
||||
this.args.toggledUsers?.has(this.args.participant.username)
|
||||
? "toggled"
|
||||
: null,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
}
|
||||
|
||||
get userUrl() {
|
||||
userPath(this.args.participant);
|
||||
}
|
||||
|
||||
<template>
|
||||
<div class={{this.participantClasses}}>
|
||||
<a
|
||||
class={{this.linkClasses}}
|
||||
data-user-card={{@participant.username}}
|
||||
title={{@participant.username}}
|
||||
href={{this.userUrl}}
|
||||
>
|
||||
{{this.avatarImage}}
|
||||
{{#if (gt @participant.post_count 1)}}
|
||||
<span class="post-count">{{@participant.post_count}}</span>
|
||||
{{/if}}
|
||||
<UserAvatarFlair @user={{@participant}} />
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
import Component from "@glimmer/component";
|
||||
import TopicParticipant from "discourse/components/topic-map/topic-participant";
|
||||
|
||||
export default class TopicParticipants extends Component {
|
||||
// prettier-ignore
|
||||
toggledUsers = new Set(this.args.userFilters);
|
||||
|
||||
<template>
|
||||
{{@title}}
|
||||
{{#each @participants as |participant|}}
|
||||
<TopicParticipant
|
||||
@participant={{participant}}
|
||||
@toggledUsers={{this.toggledUsers}}
|
||||
/>
|
||||
{{/each}}
|
||||
</template>
|
||||
}
|
@ -26,6 +26,7 @@ import {
|
||||
import { addOnKeyUpCallback } from "discourse/components/search-menu/search-term";
|
||||
import { REFRESH_COUNTS_APP_EVENT_NAME as REFRESH_USER_SIDEBAR_CATEGORIES_SECTION_COUNTS_APP_EVENT_NAME } from "discourse/components/sidebar/user/categories-section";
|
||||
import { forceDropdownForMenuPanels } from "discourse/components/site-header";
|
||||
import { addTopicParticipantClassesCallback } from "discourse/components/topic-map/topic-participant";
|
||||
import { setDesktopScrollAreaHeight } from "discourse/components/topic-timeline/container";
|
||||
import { addTopicTitleDecorator } from "discourse/components/topic-title";
|
||||
import { setNotificationsLimit as setUserMenuNotificationsLimit } from "discourse/components/user-menu/notifications-list";
|
||||
@ -122,7 +123,6 @@ import {
|
||||
addSearchSuggestion,
|
||||
removeDefaultQuickSearchRandomTips as removeWidgetDefaultQuickSearchRandomTips,
|
||||
} from "discourse/widgets/search-menu-results";
|
||||
import { addTopicParticipantClassesCallback } from "discourse/widgets/topic-map";
|
||||
import {
|
||||
changeSetting,
|
||||
createWidget,
|
||||
|
@ -1,27 +1,30 @@
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import { hbs } from "ember-cli-htmlbars";
|
||||
import { h } from "virtual-dom";
|
||||
import { dateNode, numberNode } from "discourse/helpers/node";
|
||||
import autoGroupFlairForUser from "discourse/lib/avatar-flair";
|
||||
import { userPath } from "discourse/lib/url";
|
||||
import { replaceEmoji } from "discourse/widgets/emoji";
|
||||
import { avatarFor, avatarImg } from "discourse/widgets/post";
|
||||
import { avatarFor } from "discourse/widgets/post";
|
||||
import RenderGlimmer from "discourse/widgets/render-glimmer";
|
||||
import { createWidget } from "discourse/widgets/widget";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
const LINKS_SHOWN = 5;
|
||||
|
||||
function renderParticipants(userFilters, participants) {
|
||||
if (!participants) {
|
||||
return;
|
||||
}
|
||||
|
||||
userFilters = userFilters || [];
|
||||
return participants.map((p) => {
|
||||
return this.attach("topic-participant", p, {
|
||||
state: { toggled: userFilters.includes(p.username) },
|
||||
});
|
||||
});
|
||||
function renderParticipants(wrapperElement, title, userFilters, participants) {
|
||||
return new RenderGlimmer(
|
||||
this,
|
||||
wrapperElement,
|
||||
hbs`<TopicMap::TopicParticipants
|
||||
@title={{@data.title}}
|
||||
@participants={{@data.participants}}
|
||||
@userFilters={{@data.userFilters}}
|
||||
/>`,
|
||||
{
|
||||
title,
|
||||
userFilters,
|
||||
participants,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
createWidget("topic-map-show-links", {
|
||||
@ -43,70 +46,6 @@ createWidget("topic-map-show-links", {
|
||||
},
|
||||
});
|
||||
|
||||
let addTopicParticipantClassesCallbacks = null;
|
||||
export function addTopicParticipantClassesCallback(callback) {
|
||||
addTopicParticipantClassesCallbacks =
|
||||
addTopicParticipantClassesCallbacks || [];
|
||||
addTopicParticipantClassesCallbacks.push(callback);
|
||||
}
|
||||
createWidget("topic-participant", {
|
||||
buildClasses(attrs) {
|
||||
const classNames = [];
|
||||
if (attrs.primary_group_name) {
|
||||
classNames.push(`group-${attrs.primary_group_name}`);
|
||||
}
|
||||
if (addTopicParticipantClassesCallbacks) {
|
||||
for (let i = 0; i < addTopicParticipantClassesCallbacks.length; i++) {
|
||||
let pluginClasses = addTopicParticipantClassesCallbacks[i].call(
|
||||
this,
|
||||
attrs
|
||||
);
|
||||
if (pluginClasses) {
|
||||
classNames.push.apply(classNames, pluginClasses);
|
||||
}
|
||||
}
|
||||
}
|
||||
return classNames;
|
||||
},
|
||||
|
||||
html(attrs, state) {
|
||||
const linkContents = [
|
||||
avatarImg("medium", {
|
||||
username: attrs.username,
|
||||
template: attrs.avatar_template,
|
||||
name: attrs.name,
|
||||
}),
|
||||
];
|
||||
|
||||
if (attrs.post_count > 1) {
|
||||
linkContents.push(h("span.post-count", attrs.post_count.toString()));
|
||||
}
|
||||
|
||||
if (attrs.flair_group_id) {
|
||||
if (attrs.flair_url || attrs.flair_bg_color) {
|
||||
linkContents.push(this.attach("avatar-flair", attrs));
|
||||
} else {
|
||||
const autoFlairAttrs = autoGroupFlairForUser(this.site, attrs);
|
||||
if (autoFlairAttrs) {
|
||||
linkContents.push(this.attach("avatar-flair", autoFlairAttrs));
|
||||
}
|
||||
}
|
||||
}
|
||||
return h(
|
||||
"a.poster.trigger-user-card",
|
||||
{
|
||||
className: state.toggled ? "toggled" : null,
|
||||
attributes: {
|
||||
title: attrs.username,
|
||||
"data-user-card": attrs.username,
|
||||
href: userPath(attrs.username),
|
||||
},
|
||||
},
|
||||
linkContents
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
createWidget("topic-map-summary", {
|
||||
tagName: "section.map",
|
||||
|
||||
@ -245,10 +184,12 @@ createWidget("topic-map-summary", {
|
||||
) {
|
||||
const participants = renderParticipants.call(
|
||||
this,
|
||||
"li.avatars",
|
||||
"",
|
||||
attrs.userFilters,
|
||||
attrs.participants.slice(0, 3)
|
||||
);
|
||||
contents.push(h("li.avatars", participants));
|
||||
contents.push(participants);
|
||||
}
|
||||
|
||||
const nav = h(
|
||||
@ -313,10 +254,13 @@ createWidget("topic-map-expanded", {
|
||||
let avatars;
|
||||
|
||||
if (attrs.participants && attrs.participants.length > 0) {
|
||||
avatars = h("section.avatars", [
|
||||
h("h3", I18n.t("topic_map.participants_title")),
|
||||
renderParticipants.call(this, attrs.userFilters, attrs.participants),
|
||||
]);
|
||||
avatars = renderParticipants.call(
|
||||
this,
|
||||
"section.avatars",
|
||||
htmlSafe(`<h3>${I18n.t("topic_map.participants_title")}</h3>`),
|
||||
attrs.userFilters,
|
||||
attrs.participants
|
||||
);
|
||||
}
|
||||
|
||||
const result = [avatars];
|
||||
@ -408,7 +352,7 @@ export default createWidget("topic-map", {
|
||||
"section.information.toggle-summary",
|
||||
hbs`<SummaryBox
|
||||
@postAttrs={{@data.postAttrs}}
|
||||
@actionDispatchFunc={{@data.actionDispatchFunc}}
|
||||
@actionDispatchFunc={{@data.actionDispatchFunc}}
|
||||
/>`,
|
||||
{
|
||||
postAttrs: attrs,
|
||||
|
@ -0,0 +1,42 @@
|
||||
import { render } from "@ember/test-helpers";
|
||||
import { hbs } from "ember-cli-htmlbars";
|
||||
import { module, test } from "qunit";
|
||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||
|
||||
module("Integration | Component | topic-participant", function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test("one post", async function (assert) {
|
||||
this.set("args", {
|
||||
username: "test",
|
||||
avatar_template: "/images/avatar.png",
|
||||
post_count: 1,
|
||||
});
|
||||
|
||||
await render(hbs`<TopicMap::TopicParticipant @participant={{this.args}}/>`);
|
||||
|
||||
assert.dom("a.poster.trigger-user-card").exists();
|
||||
assert.dom("span.post-count").doesNotExist();
|
||||
assert.dom(".avatar-flair").doesNotExist();
|
||||
});
|
||||
|
||||
test("many posts, a primary group with flair", async function (assert) {
|
||||
this.set("args", {
|
||||
username: "test",
|
||||
avatar_template: "/images/avatar.png",
|
||||
post_count: 2,
|
||||
primary_group_name: "devs",
|
||||
flair_name: "devs",
|
||||
flair_url: "/images/d-logo-sketch-small.png",
|
||||
flair_bg_color: "222",
|
||||
flair_group_id: "41",
|
||||
});
|
||||
|
||||
await render(hbs`<TopicMap::TopicParticipant @participant={{this.args}}/>`);
|
||||
|
||||
assert.dom("a.poster.trigger-user-card").exists();
|
||||
assert.dom("span.post-count").exists();
|
||||
assert.dom(".group-devs a.poster").exists();
|
||||
assert.dom(".avatar-flair.avatar-flair-devs").exists();
|
||||
});
|
||||
});
|
@ -1,56 +0,0 @@
|
||||
import { render } from "@ember/test-helpers";
|
||||
import { hbs } from "ember-cli-htmlbars";
|
||||
import { module, test } from "qunit";
|
||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||
import { exists } from "discourse/tests/helpers/qunit-helpers";
|
||||
|
||||
module(
|
||||
"Integration | Component | Widget | topic-participant",
|
||||
function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test("one post", async function (assert) {
|
||||
this.set("args", {
|
||||
username: "test",
|
||||
avatar_template: "/images/avatar.png",
|
||||
post_count: 1,
|
||||
});
|
||||
|
||||
await render(
|
||||
hbs`<MountWidget @widget="topic-participant" @args={{this.args}} />`
|
||||
);
|
||||
|
||||
assert.ok(exists("a.poster.trigger-user-card"));
|
||||
assert.ok(!exists("span.post-count"), "don't show count for only 1 post");
|
||||
assert.ok(!exists(".avatar-flair"), "no avatar flair");
|
||||
});
|
||||
|
||||
test("many posts, a primary group with flair", async function (assert) {
|
||||
this.set("args", {
|
||||
username: "test",
|
||||
avatar_template: "/images/avatar.png",
|
||||
post_count: 2,
|
||||
primary_group_name: "devs",
|
||||
flair_name: "devs",
|
||||
flair_url: "/images/d-logo-sketch-small.png",
|
||||
flair_bg_color: "222",
|
||||
flair_group_id: "41",
|
||||
});
|
||||
|
||||
await render(
|
||||
hbs`<MountWidget @widget="topic-participant" @args={{this.args}} />`
|
||||
);
|
||||
|
||||
assert.ok(exists("a.poster.trigger-user-card"));
|
||||
assert.ok(exists("span.post-count"), "show count for many posts");
|
||||
assert.ok(
|
||||
exists(".group-devs a.poster"),
|
||||
"add class for the group outside the link"
|
||||
);
|
||||
assert.ok(
|
||||
exists(".avatar-flair.avatar-flair-devs"),
|
||||
"show flair with group class"
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
Loading…
Reference in New Issue
Block a user