mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
DEV: Extract TopicCell component (#28947)
This commit is contained in:
parent
e926a07c83
commit
d1feb67f35
@ -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~}}
|
||||
|
||||
{{~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>
|
||||
}
|
@ -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~}}
|
||||
|
||||
{{~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"
|
||||
|
Loading…
Reference in New Issue
Block a user