mirror of
https://github.com/discourse/discourse.git
synced 2024-11-28 16:56:19 +08:00
DEV: Convert topic-notifications-button to gjs (#29237)
This commit is contained in:
parent
97be676b99
commit
481d0645a9
|
@ -101,10 +101,7 @@
|
|||
/>
|
||||
{{/if}}
|
||||
|
||||
<TopicNotificationsButton
|
||||
@notificationLevel={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
/>
|
||||
<TopicNotificationsButton @topic={{this.topic}} />
|
||||
{{/if}}
|
||||
|
||||
<PluginOutlet
|
||||
|
|
|
@ -175,12 +175,11 @@
|
|||
|
||||
{{#if this.currentUser}}
|
||||
<TopicNotificationsButton
|
||||
@notificationLevel={{@model.details.notification_level}}
|
||||
@topic={{@model}}
|
||||
@showFullTitle={{false}}
|
||||
@appendReason={{false}}
|
||||
@placement="bottom-end"
|
||||
@showCaret={{false}}
|
||||
@placement="bottom-end"
|
||||
/>
|
||||
{{#if @mobileView}}
|
||||
<TopicAdminMenu
|
||||
|
|
|
@ -19,9 +19,9 @@ acceptance("Topic Notifications button", function (needs) {
|
|||
|
||||
await visit("/t/internationalization-localization/280");
|
||||
|
||||
assert.ok(
|
||||
assert.true(
|
||||
notificationOptions.exists(),
|
||||
"it should display the notification options button in the topic's footer"
|
||||
"displays the notification options button in the topic's footer"
|
||||
);
|
||||
|
||||
await notificationOptions.expand();
|
||||
|
@ -30,7 +30,7 @@ acceptance("Topic Notifications button", function (needs) {
|
|||
assert.strictEqual(
|
||||
notificationOptions.header().label(),
|
||||
"Watching",
|
||||
"it should display the right notification level"
|
||||
"displays the right notification level"
|
||||
);
|
||||
|
||||
const timelineNotificationOptions = selectKit(
|
||||
|
@ -40,7 +40,7 @@ acceptance("Topic Notifications button", function (needs) {
|
|||
assert.strictEqual(
|
||||
timelineNotificationOptions.header().value(),
|
||||
"3",
|
||||
"it should display the right notification level"
|
||||
"displays the right notification level"
|
||||
);
|
||||
|
||||
await timelineNotificationOptions.expand();
|
||||
|
@ -49,13 +49,13 @@ acceptance("Topic Notifications button", function (needs) {
|
|||
assert.strictEqual(
|
||||
timelineNotificationOptions.header().value(),
|
||||
"0",
|
||||
"it should display the right notification level"
|
||||
"displays the right notification level"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
notificationOptions.header().label(),
|
||||
"Muted",
|
||||
"it should display the right notification level"
|
||||
"displays the right notification level"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,242 @@
|
|||
import { tracked } from "@glimmer/tracking";
|
||||
import { getOwner } from "@ember/owner";
|
||||
import { render, settled } from "@ember/test-helpers";
|
||||
import { module, test } from "qunit";
|
||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||
import selectKit from "discourse/tests/helpers/select-kit-helper";
|
||||
import I18n from "discourse-i18n";
|
||||
import TopicNotificationsButton from "select-kit/components/topic-notifications-button";
|
||||
|
||||
class TestClass {
|
||||
@tracked topic;
|
||||
}
|
||||
|
||||
function buildTopic(opts) {
|
||||
return this.store.createRecord("topic", {
|
||||
id: 4563,
|
||||
title: "Qunit Test Topic",
|
||||
details: {
|
||||
notification_level: opts.level,
|
||||
notifications_reason_id: opts.reason || null,
|
||||
},
|
||||
archetype: opts.archetype || "regular",
|
||||
category_id: opts.category_id || null,
|
||||
tags: opts.tags || [],
|
||||
});
|
||||
}
|
||||
|
||||
const originalTranslation =
|
||||
I18n.translations.en.js.topic.notifications.tracking_pm.title;
|
||||
|
||||
module(
|
||||
"Integration | Component | select-kit/topic-notifications-button",
|
||||
function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.store = getOwner(this).lookup("service:store");
|
||||
});
|
||||
|
||||
hooks.afterEach(function () {
|
||||
I18n.translations.en.js.topic.notifications.tracking_pm.title =
|
||||
originalTranslation;
|
||||
});
|
||||
|
||||
test("the header has correct labels", async function (assert) {
|
||||
const state = new TestClass();
|
||||
state.topic = buildTopic.call(this, { level: 1 });
|
||||
|
||||
await render(<template>
|
||||
<TopicNotificationsButton @topic={{state.topic}} />
|
||||
</template>);
|
||||
|
||||
assert.strictEqual(
|
||||
selectKit().header().label(),
|
||||
"Normal",
|
||||
"has the correct label"
|
||||
);
|
||||
|
||||
state.topic = buildTopic.call(this, { level: 2 });
|
||||
await settled();
|
||||
|
||||
assert.strictEqual(
|
||||
selectKit().header().label(),
|
||||
"Tracking",
|
||||
"correctly changes the label"
|
||||
);
|
||||
});
|
||||
|
||||
test("the header has a localized title", async function (assert) {
|
||||
I18n.translations.en.js.topic.notifications.tracking_pm.title = `${originalTranslation} PM`;
|
||||
const topic = buildTopic.call(this, {
|
||||
level: 2,
|
||||
archetype: "private_message",
|
||||
});
|
||||
|
||||
await render(<template>
|
||||
<TopicNotificationsButton @topic={{topic}} />
|
||||
</template>);
|
||||
|
||||
assert.strictEqual(
|
||||
selectKit().header().label(),
|
||||
`${originalTranslation} PM`,
|
||||
"has the correct label for PMs"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user mailing list mode", async function (assert) {
|
||||
this.currentUser.set("user_option.mailing_list_mode", true);
|
||||
const topic = buildTopic.call(this, { level: 2 });
|
||||
|
||||
await render(<template>
|
||||
<TopicNotificationsButton @topic={{topic}} />
|
||||
</template>);
|
||||
|
||||
assert
|
||||
.dom(".topic-notifications-button .text")
|
||||
.hasText(
|
||||
I18n.t("topic.notifications.reasons.mailing_list_mode"),
|
||||
"mailing_list_mode enabled for the user shows unique text"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - bad notification reason", async function (assert) {
|
||||
const state = new TestClass();
|
||||
state.topic = buildTopic.call(this, { level: 2 });
|
||||
|
||||
await render(<template>
|
||||
<TopicNotificationsButton @topic={{state.topic}} />
|
||||
</template>);
|
||||
|
||||
state.topic = buildTopic.call(this, { level: 3, reason: 999 });
|
||||
await settled();
|
||||
|
||||
assert
|
||||
.dom(".topic-notifications-button .text")
|
||||
.hasText(
|
||||
I18n.t("topic.notifications.reasons.3"),
|
||||
"fallback to regular level translation if reason does not exist"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user tracking category", async function (assert) {
|
||||
this.currentUser.set("tracked_category_ids", [88]);
|
||||
const topic = buildTopic.call(this, {
|
||||
level: 2,
|
||||
reason: 8,
|
||||
category_id: 88,
|
||||
});
|
||||
|
||||
await render(<template>
|
||||
<TopicNotificationsButton @topic={{topic}} />
|
||||
</template>);
|
||||
|
||||
assert
|
||||
.dom(".topic-notifications-button .text")
|
||||
.hasText(
|
||||
I18n.t("topic.notifications.reasons.2_8"),
|
||||
"use 2_8 notification if user is still tracking category"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user no longer tracking category", async function (assert) {
|
||||
this.currentUser.set("tracked_category_ids", []);
|
||||
const topic = buildTopic.call(this, {
|
||||
level: 2,
|
||||
reason: 8,
|
||||
category_id: 88,
|
||||
});
|
||||
|
||||
await render(<template>
|
||||
<TopicNotificationsButton @topic={{topic}} />
|
||||
</template>);
|
||||
|
||||
assert
|
||||
.dom(".topic-notifications-button .text")
|
||||
.hasText(
|
||||
I18n.t("topic.notifications.reasons.2_8_stale"),
|
||||
"use _stale notification if user is no longer tracking category"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user watching category", async function (assert) {
|
||||
this.currentUser.set("watched_category_ids", [88]);
|
||||
const topic = buildTopic.call(this, {
|
||||
level: 3,
|
||||
reason: 6,
|
||||
category_id: 88,
|
||||
});
|
||||
|
||||
await render(<template>
|
||||
<TopicNotificationsButton @topic={{topic}} />
|
||||
</template>);
|
||||
|
||||
assert
|
||||
.dom(".topic-notifications-button .text")
|
||||
.hasText(
|
||||
I18n.t("topic.notifications.reasons.3_6"),
|
||||
"use 3_6 notification if user is still watching category"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user no longer watching category", async function (assert) {
|
||||
this.currentUser.set("watched_category_ids", []);
|
||||
const topic = buildTopic.call(this, {
|
||||
level: 3,
|
||||
reason: 6,
|
||||
category_id: 88,
|
||||
});
|
||||
|
||||
await render(<template>
|
||||
<TopicNotificationsButton @topic={{topic}} />
|
||||
</template>);
|
||||
|
||||
assert
|
||||
.dom(".topic-notifications-button .text")
|
||||
.hasText(
|
||||
I18n.t("topic.notifications.reasons.3_6_stale"),
|
||||
"use _stale notification if user is no longer watching category"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user watching tag", async function (assert) {
|
||||
this.currentUser.set("watched_tags", ["test"]);
|
||||
const topic = buildTopic.call(this, {
|
||||
level: 3,
|
||||
reason: 10,
|
||||
tags: ["test"],
|
||||
});
|
||||
|
||||
await render(<template>
|
||||
<TopicNotificationsButton @topic={{topic}} />
|
||||
</template>);
|
||||
|
||||
assert
|
||||
.dom(".topic-notifications-button .text")
|
||||
.hasText(
|
||||
I18n.t("topic.notifications.reasons.3_10"),
|
||||
"use 3_10 notification if user is still watching tag"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user no longer watching tag", async function (assert) {
|
||||
this.currentUser.set("watched_tags", []);
|
||||
const topic = buildTopic.call(this, {
|
||||
level: 3,
|
||||
reason: 10,
|
||||
tags: ["test"],
|
||||
});
|
||||
|
||||
await render(<template>
|
||||
<TopicNotificationsButton @topic={{topic}} />
|
||||
</template>);
|
||||
|
||||
assert
|
||||
.dom(".topic-notifications-button .text")
|
||||
.hasText(
|
||||
I18n.t("topic.notifications.reasons.3_10_stale"),
|
||||
"use _stale notification if user is no longer watching tag"
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
|
@ -1,250 +0,0 @@
|
|||
import { getOwner } from "@ember/owner";
|
||||
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 { query } from "discourse/tests/helpers/qunit-helpers";
|
||||
import selectKit from "discourse/tests/helpers/select-kit-helper";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
function buildTopic(opts) {
|
||||
return this.store.createRecord("topic", {
|
||||
id: 4563,
|
||||
title: "Qunit Test Topic",
|
||||
details: {
|
||||
notification_level: opts.level,
|
||||
notifications_reason_id: opts.reason || null,
|
||||
},
|
||||
archetype: opts.archetype || "regular",
|
||||
category_id: opts.category_id || null,
|
||||
tags: opts.tags || [],
|
||||
});
|
||||
}
|
||||
|
||||
const originalTranslation =
|
||||
I18n.translations.en.js.topic.notifications.tracking_pm.title;
|
||||
|
||||
module(
|
||||
"Integration | Component | select-kit/topic-notifications-button",
|
||||
function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
this.store = getOwner(this).lookup("service:store");
|
||||
});
|
||||
|
||||
hooks.afterEach(function () {
|
||||
I18n.translations.en.js.topic.notifications.tracking_pm.title =
|
||||
originalTranslation;
|
||||
});
|
||||
|
||||
test("the header has a localized title", async function (assert) {
|
||||
this.set("topic", buildTopic.call(this, { level: 1 }));
|
||||
|
||||
await render(hbs`
|
||||
<TopicNotificationsButton
|
||||
@notificationLevel={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.strictEqual(
|
||||
selectKit().header().label(),
|
||||
"Normal",
|
||||
"it has the correct label"
|
||||
);
|
||||
|
||||
this.set("topic", buildTopic.call(this, { level: 2 }));
|
||||
|
||||
assert.strictEqual(
|
||||
selectKit().header().label(),
|
||||
"Tracking",
|
||||
"it correctly changes the label"
|
||||
);
|
||||
});
|
||||
|
||||
test("the header has a localized title", async function (assert) {
|
||||
I18n.translations.en.js.topic.notifications.tracking_pm.title = `${originalTranslation} PM`;
|
||||
this.set(
|
||||
"topic",
|
||||
buildTopic.call(this, { level: 2, archetype: "private_message" })
|
||||
);
|
||||
|
||||
await render(hbs`
|
||||
<TopicNotificationsButton
|
||||
@notificationLevel={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.strictEqual(
|
||||
selectKit().header().label(),
|
||||
`${originalTranslation} PM`,
|
||||
"it has the correct label for PMs"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user mailing list mode", async function (assert) {
|
||||
this.currentUser.set("user_option.mailing_list_mode", true);
|
||||
this.set("topic", buildTopic.call(this, { level: 2 }));
|
||||
|
||||
await render(hbs`
|
||||
<TopicNotificationsButton
|
||||
@notificationLevel={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.strictEqual(
|
||||
query(".topic-notifications-button .text").innerText,
|
||||
I18n.t("topic.notifications.reasons.mailing_list_mode"),
|
||||
"mailing_list_mode enabled for the user shows unique text"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - bad notification reason", async function (assert) {
|
||||
this.set("topic", buildTopic.call(this, { level: 2 }));
|
||||
|
||||
await render(hbs`
|
||||
<TopicNotificationsButton
|
||||
@notificationLevel={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
/>
|
||||
`);
|
||||
|
||||
this.set("topic", buildTopic.call(this, { level: 3, reason: 999 }));
|
||||
|
||||
assert.strictEqual(
|
||||
query(".topic-notifications-button .text").innerText,
|
||||
I18n.t("topic.notifications.reasons.3"),
|
||||
"fallback to regular level translation if reason does not exist"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user tracking category", async function (assert) {
|
||||
this.currentUser.set("tracked_category_ids", [88]);
|
||||
this.set(
|
||||
"topic",
|
||||
buildTopic.call(this, { level: 2, reason: 8, category_id: 88 })
|
||||
);
|
||||
|
||||
await render(hbs`
|
||||
<TopicNotificationsButton
|
||||
@notificationLevel={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.strictEqual(
|
||||
query(".topic-notifications-button .text").innerText,
|
||||
I18n.t("topic.notifications.reasons.2_8"),
|
||||
"use 2_8 notification if user is still tracking category"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user no longer tracking category", async function (assert) {
|
||||
this.currentUser.set("tracked_category_ids", []);
|
||||
this.set(
|
||||
"topic",
|
||||
buildTopic.call(this, { level: 2, reason: 8, category_id: 88 })
|
||||
);
|
||||
|
||||
await render(hbs`
|
||||
<TopicNotificationsButton
|
||||
@notificationLevel={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.strictEqual(
|
||||
query(".topic-notifications-button .text").innerText,
|
||||
I18n.t("topic.notifications.reasons.2_8_stale"),
|
||||
"use _stale notification if user is no longer tracking category"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user watching category", async function (assert) {
|
||||
this.currentUser.set("watched_category_ids", [88]);
|
||||
this.set(
|
||||
"topic",
|
||||
buildTopic.call(this, { level: 3, reason: 6, category_id: 88 })
|
||||
);
|
||||
|
||||
await render(hbs`
|
||||
<TopicNotificationsButton
|
||||
@notificationLevel={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.strictEqual(
|
||||
query(".topic-notifications-button .text").innerText,
|
||||
I18n.t("topic.notifications.reasons.3_6"),
|
||||
"use 3_6 notification if user is still watching category"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user no longer watching category", async function (assert) {
|
||||
this.currentUser.set("watched_category_ids", []);
|
||||
this.set(
|
||||
"topic",
|
||||
buildTopic.call(this, { level: 3, reason: 6, category_id: 88 })
|
||||
);
|
||||
|
||||
await render(hbs`
|
||||
<TopicNotificationsButton
|
||||
@notificationLevel={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.strictEqual(
|
||||
query(".topic-notifications-button .text").innerText,
|
||||
I18n.t("topic.notifications.reasons.3_6_stale"),
|
||||
"use _stale notification if user is no longer watching category"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user watching tag", async function (assert) {
|
||||
this.currentUser.set("watched_tags", ["test"]);
|
||||
this.set(
|
||||
"topic",
|
||||
buildTopic.call(this, { level: 3, reason: 10, tags: ["test"] })
|
||||
);
|
||||
|
||||
await render(hbs`
|
||||
<TopicNotificationsButton
|
||||
@notificationLevel={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.strictEqual(
|
||||
query(".topic-notifications-button .text").innerText,
|
||||
I18n.t("topic.notifications.reasons.3_10"),
|
||||
"use 3_10 notification if user is still watching tag"
|
||||
);
|
||||
});
|
||||
|
||||
test("notification reason text - user no longer watching tag", async function (assert) {
|
||||
this.currentUser.set("watched_tags", []);
|
||||
this.set(
|
||||
"topic",
|
||||
buildTopic.call(this, { level: 3, reason: 10, tags: ["test"] })
|
||||
);
|
||||
|
||||
await render(hbs`
|
||||
<TopicNotificationsButton
|
||||
@notificationLevel={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
/>
|
||||
`);
|
||||
|
||||
assert.strictEqual(
|
||||
query(".topic-notifications-button .text").innerText,
|
||||
I18n.t("topic.notifications.reasons.3_10_stale"),
|
||||
"use _stale notification if user is no longer watching tag"
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
|
@ -1,10 +1,10 @@
|
|||
import { getOwner } from "@ember/owner";
|
||||
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 selectKit from "discourse/tests/helpers/select-kit-helper";
|
||||
import I18n from "discourse-i18n";
|
||||
import TopicNotificationsOptions from "select-kit/components/topic-notifications-options";
|
||||
|
||||
function extractDescriptions(rows) {
|
||||
return [...rows].map((el) => el.querySelector(".desc").textContent.trim());
|
||||
|
@ -23,24 +23,21 @@ module(
|
|||
|
||||
test("regular topic notification level descriptions", async function (assert) {
|
||||
const store = getOwner(this).lookup("service:store");
|
||||
this.set(
|
||||
"topic",
|
||||
store.createRecord("topic", {
|
||||
id: 4563,
|
||||
title: "Qunit Test Topic",
|
||||
archetype: "regular",
|
||||
details: {
|
||||
notification_level: 1,
|
||||
},
|
||||
})
|
||||
);
|
||||
const topic = store.createRecord("topic", {
|
||||
id: 4563,
|
||||
title: "Qunit Test Topic",
|
||||
archetype: "regular",
|
||||
details: {
|
||||
notification_level: 1,
|
||||
},
|
||||
});
|
||||
|
||||
await render(hbs`
|
||||
await render(<template>
|
||||
<TopicNotificationsOptions
|
||||
@value={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
@value={{topic.details.notification_level}}
|
||||
@topic={{topic}}
|
||||
/>
|
||||
`);
|
||||
</template>);
|
||||
|
||||
await selectKit().expand();
|
||||
|
||||
|
@ -50,38 +47,35 @@ module(
|
|||
assert.strictEqual(
|
||||
uiTexts.length,
|
||||
descriptions.length,
|
||||
"it has the correct copy"
|
||||
"has the correct copy"
|
||||
);
|
||||
|
||||
uiTexts.forEach((text, index) => {
|
||||
assert.strictEqual(
|
||||
text.trim(),
|
||||
descriptions[index].trim(),
|
||||
"it has the correct copy"
|
||||
"has the correct copy"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test("PM topic notification level descriptions", async function (assert) {
|
||||
const store = getOwner(this).lookup("service:store");
|
||||
this.set(
|
||||
"topic",
|
||||
store.createRecord("topic", {
|
||||
id: 4563,
|
||||
title: "Qunit Test Topic",
|
||||
archetype: "private_message",
|
||||
details: {
|
||||
notification_level: 1,
|
||||
},
|
||||
})
|
||||
);
|
||||
const topic = store.createRecord("topic", {
|
||||
id: 4563,
|
||||
title: "Qunit Test Topic",
|
||||
archetype: "private_message",
|
||||
details: {
|
||||
notification_level: 1,
|
||||
},
|
||||
});
|
||||
|
||||
await render(hbs`
|
||||
await render(<template>
|
||||
<TopicNotificationsOptions
|
||||
@value={{this.topic.details.notification_level}}
|
||||
@topic={{this.topic}}
|
||||
@value={{topic.details.notification_level}}
|
||||
@topic={{topic}}
|
||||
/>
|
||||
`);
|
||||
</template>);
|
||||
|
||||
await selectKit().expand();
|
||||
|
||||
|
@ -91,14 +85,14 @@ module(
|
|||
assert.strictEqual(
|
||||
uiTexts.length,
|
||||
descriptions.length,
|
||||
"it has the correct copy"
|
||||
"has the correct copy"
|
||||
);
|
||||
|
||||
uiTexts.forEach((text, index) => {
|
||||
assert.strictEqual(
|
||||
text.trim(),
|
||||
descriptions[index].trim(),
|
||||
"it has the correct copy"
|
||||
"has the correct copy"
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,147 @@
|
|||
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 appendReason() {
|
||||
return this.args.appendReason ?? true;
|
||||
}
|
||||
|
||||
get showFullTitle() {
|
||||
return this.args.showFullTitle ?? true;
|
||||
}
|
||||
|
||||
get showCaret() {
|
||||
return this.args.showCaret ?? true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@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>
|
||||
<div class="topic-notifications-button">
|
||||
{{#if this.appendReason}}
|
||||
<p class="reason">
|
||||
<TopicNotificationsOptions
|
||||
@value={{this.notificationLevel}}
|
||||
@topic={{@topic}}
|
||||
@onChange={{this.changeTopicNotificationLevel}}
|
||||
@options={{hash
|
||||
icon=(if this.isLoading "spinner")
|
||||
showFullTitle=this.showFullTitle
|
||||
showCaret=this.showCaret
|
||||
headerAriaLabel=(i18n "topic.notifications.title")
|
||||
}}
|
||||
/>
|
||||
<span class="text">{{htmlSafe this.reasonText}}</span>
|
||||
</p>
|
||||
{{else}}
|
||||
<TopicNotificationsOptions
|
||||
@value={{this.notificationLevel}}
|
||||
@topic={{@topic}}
|
||||
@onChange={{this.changeTopicNotificationLevel}}
|
||||
@options={{hash
|
||||
icon=(if this.isLoading "spinner")
|
||||
showFullTitle=this.showFullTitle
|
||||
showCaret=this.showCaret
|
||||
headerAriaLabel=(i18n "topic.notifications.title")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
||||
</div>
|
||||
</template>
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
{{#if this.appendReason}}
|
||||
<p class="reason">
|
||||
<TopicNotificationsOptions
|
||||
@value={{this.notificationLevel}}
|
||||
@topic={{this.topic}}
|
||||
@onChange={{action "changeTopicNotificationLevel"}}
|
||||
@options={{hash
|
||||
icon=this.icon
|
||||
showFullTitle=this.showFullTitle
|
||||
showCaret=this.showCaret
|
||||
headerAriaLabel=(i18n "topic.notifications.title")
|
||||
}}
|
||||
/>
|
||||
<span class="text">{{html-safe this.notificationReasonText}}</span>
|
||||
</p>
|
||||
{{else}}
|
||||
<TopicNotificationsOptions
|
||||
@value={{this.notificationLevel}}
|
||||
@topic={{this.topic}}
|
||||
@onChange={{action "changeTopicNotificationLevel"}}
|
||||
@options={{hash
|
||||
icon=this.icon
|
||||
showFullTitle=this.showFullTitle
|
||||
showCaret=this.showCaret
|
||||
headerAriaLabel=(i18n "topic.notifications.title")
|
||||
}}
|
||||
/>
|
||||
{{/if}}
|
|
@ -1,118 +0,0 @@
|
|||
import Component from "@ember/component";
|
||||
import { action, computed } from "@ember/object";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { classNameBindings, classNames } from "@ember-decorators/component";
|
||||
import { NotificationLevels } from "discourse/lib/notification-levels";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
@classNames("topic-notifications-button")
|
||||
@classNameBindings("isLoading")
|
||||
export default class TopicNotificationsButton extends Component {
|
||||
appendReason = true;
|
||||
showFullTitle = true;
|
||||
notificationLevel = null;
|
||||
topic = null;
|
||||
showCaret = true;
|
||||
isLoading = false;
|
||||
|
||||
@computed("isLoading")
|
||||
get icon() {
|
||||
return this.isLoading ? "spinner" : null;
|
||||
}
|
||||
|
||||
@action
|
||||
changeTopicNotificationLevel(levelId) {
|
||||
if (levelId !== this.notificationLevel) {
|
||||
this.set("isLoading", true);
|
||||
this.topic.details
|
||||
.updateNotifications(levelId)
|
||||
.finally(() => this.set("isLoading", false));
|
||||
}
|
||||
}
|
||||
|
||||
@discourseComputed(
|
||||
"topic",
|
||||
"topic.details.{notification_level,notifications_reason_id}"
|
||||
)
|
||||
notificationReasonText(topic, topicDetails) {
|
||||
let level = topicDetails.notification_level;
|
||||
let reason = topicDetails.notifications_reason_id;
|
||||
|
||||
if (typeof level !== "number") {
|
||||
level = 1;
|
||||
}
|
||||
|
||||
let localeString = `topic.notifications.reasons.${level}`;
|
||||
if (typeof reason === "number") {
|
||||
let localeStringWithReason = localeString + "_" + reason;
|
||||
|
||||
if (
|
||||
this._notificationReasonStale(level, reason, topic, this.currentUser)
|
||||
) {
|
||||
localeStringWithReason += "_stale";
|
||||
}
|
||||
|
||||
// some sane protection for missing translations of edge cases
|
||||
if (I18n.lookup(localeStringWithReason, { locale: "en" })) {
|
||||
localeString = localeStringWithReason;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
this.currentUser &&
|
||||
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 && 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.
|
||||
_notificationReasonStale(level, reason, topic, currentUser) {
|
||||
if (!currentUser) {
|
||||
return;
|
||||
}
|
||||
|
||||
let categoryId = topic.category_id;
|
||||
let tags = topic.tags;
|
||||
let watchedCategoryIds = currentUser.watched_category_ids || [];
|
||||
let trackedCategoryIds = currentUser.tracked_category_ids || [];
|
||||
let watchedTags = currentUser.watched_tags || [];
|
||||
|
||||
// 2_8 tracking category
|
||||
if (categoryId) {
|
||||
if (level === 2 && reason === 8) {
|
||||
if (!trackedCategoryIds.includes(categoryId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 3_6 watching category
|
||||
} else if (level === 3 && reason === 6) {
|
||||
if (!watchedCategoryIds.includes(categoryId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (!isEmpty(tags)) {
|
||||
// 3_10 watching tag
|
||||
if (level === 3 && reason === 10) {
|
||||
if (!tags.some((tag) => watchedTags.includes(tag))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user