2024-10-21 23:34:56 +08:00
|
|
|
import Component from "@glimmer/component";
|
|
|
|
import { tracked } from "@glimmer/tracking";
|
|
|
|
import { hash } from "@ember/helper";
|
|
|
|
import { action } from "@ember/object";
|
|
|
|
import { service } from "@ember/service";
|
|
|
|
import { htmlSafe } from "@ember/template";
|
|
|
|
import { isEmpty } from "@ember/utils";
|
|
|
|
import { NotificationLevels } from "discourse/lib/notification-levels";
|
|
|
|
import i18n from "discourse-common/helpers/i18n";
|
|
|
|
import getURL from "discourse-common/lib/get-url";
|
|
|
|
import I18n from "discourse-i18n";
|
|
|
|
import TopicNotificationsOptions from "select-kit/components/topic-notifications-options";
|
|
|
|
|
|
|
|
export default class TopicNotificationsButton extends Component {
|
|
|
|
@service currentUser;
|
|
|
|
|
|
|
|
@tracked isLoading = false;
|
|
|
|
|
|
|
|
get notificationLevel() {
|
|
|
|
return this.args.topic.get("details.notification_level");
|
|
|
|
}
|
|
|
|
|
|
|
|
get reasonText() {
|
|
|
|
const topic = this.args.topic;
|
|
|
|
const level = topic.get("details.notification_level") ?? 1;
|
|
|
|
const reason = topic.get("details.notifications_reason_id");
|
|
|
|
let localeString = `topic.notifications.reasons.${level}`;
|
|
|
|
|
|
|
|
if (typeof reason === "number") {
|
|
|
|
let localeStringWithReason = `${localeString}_${reason}`;
|
|
|
|
|
|
|
|
if (this._reasonStale(level, reason)) {
|
|
|
|
localeStringWithReason += "_stale";
|
|
|
|
}
|
|
|
|
|
|
|
|
// some sane protection for missing translations of edge cases
|
|
|
|
if (I18n.lookup(localeStringWithReason, { locale: "en" })) {
|
|
|
|
localeString = localeStringWithReason;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
this.currentUser?.user_option.mailing_list_mode &&
|
|
|
|
level > NotificationLevels.MUTED
|
|
|
|
) {
|
|
|
|
return I18n.t("topic.notifications.reasons.mailing_list_mode");
|
|
|
|
} else {
|
|
|
|
return I18n.t(localeString, {
|
|
|
|
username: this.currentUser?.username_lower,
|
|
|
|
basePath: getURL(""),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The user may have changed their category or tag tracking settings
|
|
|
|
// since this topic was tracked/watched based on those settings in the
|
|
|
|
// past. In that case we need to alter the reason message we show them
|
|
|
|
// otherwise it is very confusing for the end user to be told they are
|
|
|
|
// tracking a topic because of a category, when they are no longer tracking
|
|
|
|
// that category.
|
|
|
|
_reasonStale(level, reason) {
|
|
|
|
if (!this.currentUser) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const watchedCategoryIds = this.currentUser.watched_category_ids || [];
|
|
|
|
const trackedCategoryIds = this.currentUser.tracked_category_ids || [];
|
|
|
|
const watchedTags = this.currentUser.watched_tags || [];
|
|
|
|
|
|
|
|
if (this.args.topic.category_id) {
|
|
|
|
if (level === 2 && reason === 8) {
|
|
|
|
// 2_8 tracking category
|
|
|
|
return !trackedCategoryIds.includes(this.args.topic.category_id);
|
|
|
|
} else if (level === 3 && reason === 6) {
|
|
|
|
// 3_6 watching category
|
|
|
|
return !watchedCategoryIds.includes(this.args.topic.category_id);
|
|
|
|
}
|
|
|
|
} else if (!isEmpty(this.args.topic.tags)) {
|
|
|
|
if (level === 3 && reason === 10) {
|
|
|
|
// 3_10 watching tag
|
|
|
|
return !this.args.topic.tags.some((tag) => watchedTags.includes(tag));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2024-10-29 23:27:23 +08:00
|
|
|
get conditionalWrapper() {
|
|
|
|
if (this.args.expanded) {
|
|
|
|
return <template><p class="reason">{{yield}}</p></template>;
|
|
|
|
} else {
|
|
|
|
return <template>
|
|
|
|
{{! template-lint-disable no-yield-only}}{{yield}}
|
|
|
|
</template>;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-21 23:34:56 +08:00
|
|
|
@action
|
|
|
|
async changeTopicNotificationLevel(levelId) {
|
|
|
|
if (levelId === this.notificationLevel) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.isLoading = true;
|
|
|
|
|
|
|
|
try {
|
|
|
|
await this.args.topic.details.updateNotifications(levelId);
|
|
|
|
} finally {
|
|
|
|
this.isLoading = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
<template>
|
2024-10-23 00:54:18 +08:00
|
|
|
<div class="topic-notifications-button" ...attributes>
|
2024-10-29 23:27:23 +08:00
|
|
|
<this.conditionalWrapper>
|
2024-10-21 23:34:56 +08:00
|
|
|
<TopicNotificationsOptions
|
|
|
|
@value={{this.notificationLevel}}
|
|
|
|
@topic={{@topic}}
|
|
|
|
@onChange={{this.changeTopicNotificationLevel}}
|
|
|
|
@options={{hash
|
|
|
|
icon=(if this.isLoading "spinner")
|
2024-10-29 23:27:23 +08:00
|
|
|
showFullTitle=@expanded
|
|
|
|
showCaret=@expanded
|
2024-10-21 23:34:56 +08:00
|
|
|
headerAriaLabel=(i18n "topic.notifications.title")
|
|
|
|
}}
|
|
|
|
/>
|
2024-10-29 23:27:23 +08:00
|
|
|
{{#if @expanded}}
|
|
|
|
<span class="text">{{htmlSafe this.reasonText}}</span>
|
|
|
|
{{/if}}
|
|
|
|
</this.conditionalWrapper>
|
2024-10-21 23:34:56 +08:00
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
}
|