DEV: Extract TopicCell component (#28947)

This commit is contained in:
Jarek Radosz 2024-09-17 20:03:51 +02:00 committed by GitHub
parent e926a07c83
commit d1feb67f35
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 177 additions and 150 deletions

View File

@ -0,0 +1,168 @@
import Component from "@glimmer/component";
import { hash } from "@ember/helper";
import { on } from "@ember/modifier";
import { action } from "@ember/object";
import { service } from "@ember/service";
import PluginOutlet from "discourse/components/plugin-outlet";
import ActionList from "discourse/components/topic-list/action-list";
import ParticipantGroups from "discourse/components/topic-list/participant-groups";
import TopicExcerpt from "discourse/components/topic-list/topic-excerpt";
import TopicLink from "discourse/components/topic-list/topic-link";
import UnreadIndicator from "discourse/components/topic-list/unread-indicator";
import TopicPostBadges from "discourse/components/topic-post-badges";
import TopicStatus from "discourse/components/topic-status";
import categoryLink from "discourse/helpers/category-link";
import discourseTags from "discourse/helpers/discourse-tags";
import topicFeaturedLink from "discourse/helpers/topic-featured-link";
import { groupPath } from "discourse/lib/url";
import { bind } from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
export default class TopicCell extends Component {
@service currentUser;
@service messageBus;
constructor() {
super(...arguments);
if (this.includeUnreadIndicator) {
this.messageBus.subscribe(this.unreadIndicatorChannel, this.onMessage);
}
}
willDestroy() {
super.willDestroy(...arguments);
this.messageBus.unsubscribe(this.unreadIndicatorChannel, this.onMessage);
}
@bind
onMessage(data) {
const nodeClassList = document.querySelector(
`.indicator-topic-${data.topic_id}`
).classList;
nodeClassList.toggle("read", !data.show_indicator);
}
get unreadIndicatorChannel() {
return `/private-messages/unread-indicator/${this.args.topic.id}`;
}
get includeUnreadIndicator() {
return typeof this.args.topic.unread_by_group_member !== "undefined";
}
get unreadClass() {
return this.args.topic.unread_by_group_member ? "" : "read";
}
get newDotText() {
return this.currentUser?.trust_level > 0
? ""
: I18n.t("filters.new.lower_title");
}
get participantGroups() {
if (!this.args.topic.participant_groups) {
return [];
}
return this.args.topic.participant_groups.map((name) => ({
name,
url: groupPath(name),
}));
}
@action
onTitleFocus(event) {
event.target.classList.add("selected");
}
@action
onTitleBlur(event) {
event.target.classList.remove("selected");
}
<template>
<td class="main-link clearfix topic-list-data" colspan="1">
<PluginOutlet
@name="topic-list-before-link"
@outletArgs={{hash topic=@topic}}
/>
<span class="link-top-line">
{{~! no whitespace ~}}
<PluginOutlet
@name="topic-list-before-status"
@outletArgs={{hash topic=@topic}}
/>
{{~! no whitespace ~}}
<TopicStatus @topic={{@topic}} />
{{~! no whitespace ~}}
<TopicLink
{{on "focus" this.onTitleFocus}}
{{on "blur" this.onTitleBlur}}
@topic={{@topic}}
class="raw-link raw-topic-link"
/>
{{~#if @topic.featured_link~}}
&nbsp;
{{~topicFeaturedLink @topic}}
{{~/if~}}
<PluginOutlet
@name="topic-list-after-title"
@outletArgs={{hash topic=@topic}}
/>
{{~! no whitespace ~}}
<UnreadIndicator
@includeUnreadIndicator={{this.includeUnreadIndicator}}
@topicId={{@topic.id}}
class={{this.unreadClass}}
/>
{{~#if @showTopicPostBadges~}}
<TopicPostBadges
@unreadPosts={{@topic.unread_posts}}
@unseen={{@topic.unseen}}
@newDotText={{this.newDotText}}
@url={{@topic.lastUnreadUrl}}
/>
{{~/if~}}
</span>
<div class="link-bottom-line">
{{#unless @hideCategory}}
{{#unless @topic.isPinnedUncategorized}}
<PluginOutlet
@name="topic-list-before-category"
@outletArgs={{hash topic=@topic}}
/>
{{categoryLink @topic.category}}
{{/unless}}
{{/unless}}
{{discourseTags @topic mode="list" tagsForUser=@tagsForUser}}
{{#if this.participantGroups}}
<ParticipantGroups @groups={{this.participantGroups}} />
{{/if}}
<ActionList
@topic={{@topic}}
@postNumbers={{@topic.liked_post_numbers}}
@icon="heart"
class="likes"
/>
</div>
{{#if @expandPinned}}
<TopicExcerpt @topic={{@topic}} />
{{/if}}
<PluginOutlet
@name="topic-list-main-link-bottom"
@outletArgs={{hash topic=@topic}}
/>
</td>
</template>
}

View File

@ -8,16 +8,13 @@ import { service } from "@ember/service";
import { modifier } from "ember-modifier";
import { eq, gt } from "truth-helpers";
import PluginOutlet from "discourse/components/plugin-outlet";
import ActionList from "discourse/components/topic-list/action-list";
import ActivityColumn from "discourse/components/topic-list/activity-column";
import ParticipantGroups from "discourse/components/topic-list/participant-groups";
import PostCountOrBadges from "discourse/components/topic-list/post-count-or-badges";
import PostersColumn from "discourse/components/topic-list/posters-column";
import PostsCountColumn from "discourse/components/topic-list/posts-count-column";
import TopicCell from "discourse/components/topic-list/topic-cell";
import TopicExcerpt from "discourse/components/topic-list/topic-excerpt";
import TopicLink from "discourse/components/topic-list/topic-link";
import UnreadIndicator from "discourse/components/topic-list/unread-indicator";
import TopicPostBadges from "discourse/components/topic-post-badges";
import TopicStatus from "discourse/components/topic-status";
import { topicTitleDecorators } from "discourse/components/topic-title";
import avatar from "discourse/helpers/avatar";
@ -28,16 +25,12 @@ import formatDate from "discourse/helpers/format-date";
import number from "discourse/helpers/number";
import topicFeaturedLink from "discourse/helpers/topic-featured-link";
import { wantsNewWindow } from "discourse/lib/intercept-click";
import DiscourseURL, { groupPath } from "discourse/lib/url";
import DiscourseURL from "discourse/lib/url";
import icon from "discourse-common/helpers/d-icon";
import i18n from "discourse-common/helpers/i18n";
import { bind } from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
export default class TopicListItem extends Component {
@service currentUser;
@service historyStore;
@service messageBus;
@service site;
@service siteSettings;
@ -58,58 +51,10 @@ export default class TopicListItem extends Component {
}
});
constructor() {
super(...arguments);
if (this.includeUnreadIndicator) {
this.messageBus.subscribe(this.unreadIndicatorChannel, this.onMessage);
}
}
willDestroy() {
super.willDestroy(...arguments);
this.messageBus.unsubscribe(this.unreadIndicatorChannel, this.onMessage);
}
@bind
onMessage(data) {
const nodeClassList = document.querySelector(
`.indicator-topic-${data.topic_id}`
).classList;
nodeClassList.toggle("read", !data.show_indicator);
}
get unreadIndicatorChannel() {
return `/private-messages/unread-indicator/${this.args.topic.id}`;
}
get includeUnreadIndicator() {
return typeof this.args.topic.unread_by_group_member !== "undefined";
}
get isSelected() {
return this.args.selected?.includes(this.args.topic);
}
get participantGroups() {
if (!this.args.topic.participant_groups) {
return [];
}
return this.args.topic.participant_groups.map((name) => ({
name,
url: groupPath(name),
}));
}
get newDotText() {
return this.currentUser?.trust_level > 0
? ""
: I18n.t("filters.new.lower_title");
}
get tagClassNames() {
return this.args.topic.tags?.map((tagName) => `tag-${tagName}`);
}
@ -133,10 +78,6 @@ export default class TopicListItem extends Component {
return this.site.desktopView && this.args.focusLastVisitedTopic;
}
get unreadClass() {
return this.args.topic.unread_by_group_member ? "" : "read";
}
navigateToTopic(topic, href) {
this.historyStore.set("lastTopicIdViewed", topic.id);
DiscourseURL.routeTo(href || topic.url);
@ -152,16 +93,6 @@ export default class TopicListItem extends Component {
element.classList.add("highlighted");
}
@action
onTitleFocus(event) {
event.target.classList.add("selected");
}
@action
onTitleBlur(event) {
event.target.classList.remove("selected");
}
@action
applyTitleDecorators(element) {
const rawTopicLink = element.querySelector(".raw-topic-link");
@ -298,85 +229,13 @@ export default class TopicListItem extends Component {
</td>
{{/if}}
<td class="main-link clearfix topic-list-data" colspan="1">
<PluginOutlet
@name="topic-list-before-link"
@outletArgs={{hash topic=@topic}}
/>
<span class="link-top-line">
{{~! no whitespace ~}}
<PluginOutlet
@name="topic-list-before-status"
@outletArgs={{hash topic=@topic}}
/>
{{~! no whitespace ~}}
<TopicStatus @topic={{@topic}} />
{{~! no whitespace ~}}
<TopicLink
{{on "focus" this.onTitleFocus}}
{{on "blur" this.onTitleBlur}}
@topic={{@topic}}
class="raw-link raw-topic-link"
/>
{{~#if @topic.featured_link~}}
&nbsp;
{{~topicFeaturedLink @topic}}
{{~/if~}}
<PluginOutlet
@name="topic-list-after-title"
@outletArgs={{hash topic=@topic}}
/>
{{~! no whitespace ~}}
<UnreadIndicator
@includeUnreadIndicator={{this.includeUnreadIndicator}}
@topicId={{@topic.id}}
class={{this.unreadClass}}
/>
{{~#if @showTopicPostBadges~}}
<TopicPostBadges
@unreadPosts={{@topic.unread_posts}}
@unseen={{@topic.unseen}}
@newDotText={{this.newDotText}}
@url={{@topic.lastUnreadUrl}}
/>
{{~/if~}}
</span>
<div class="link-bottom-line">
{{#unless @hideCategory}}
{{#unless @topic.isPinnedUncategorized}}
<PluginOutlet
@name="topic-list-before-category"
@outletArgs={{hash topic=@topic}}
/>
{{categoryLink @topic.category}}
{{/unless}}
{{/unless}}
{{discourseTags @topic mode="list" tagsForUser=@tagsForUser}}
{{#if this.participantGroups}}
<ParticipantGroups @groups={{this.participantGroups}} />
{{/if}}
<ActionList
@topic={{@topic}}
@postNumbers={{@topic.liked_post_numbers}}
@icon="heart"
class="likes"
/>
</div>
{{#if this.expandPinned}}
<TopicExcerpt @topic={{@topic}} />
{{/if}}
<PluginOutlet
@name="topic-list-main-link-bottom"
@outletArgs={{hash topic=@topic}}
/>
</td>
<TopicCell
@topic={{@topic}}
@showTopicPostBadges={{@showTopicPostBadges}}
@hideCategory={{@hideCategory}}
@tagsForUser={{@tagsForUser}}
@expandPinned={{this.expandPinned}}
/>
<PluginOutlet
@name="topic-list-after-main-link"