diff --git a/app/assets/javascripts/discourse/app/components/more-topics.hbs b/app/assets/javascripts/discourse/app/components/more-topics.hbs index 015f2de71ab..0df708cce4e 100644 --- a/app/assets/javascripts/discourse/app/components/more-topics.hbs +++ b/app/assets/javascripts/discourse/app/components/more-topics.hbs @@ -1,14 +1,15 @@ -<div class="more-topics__container" {{did-insert this.buildListPills}}> +<div class="more-topics__container"> {{#unless this.singleList}} <div class="row"> <ul class="nav nav-pills"> - {{#each this.availablePills as |pill|}} + {{#each this.availableTabs as |tab|}} <li> <DButton - @translatedTitle={{pill.name}} - @translatedLabel={{pill.name}} - @class={{if pill.selected "active"}} - @action={{action "rememberTopicListPreference" pill.id}} + @translatedTitle={{tab.name}} + @translatedLabel={{tab.name}} + @class={{if (eq tab.id this.selectedTab) "active"}} + @action={{action "rememberTopicListPreference" tab.id}} + @icon={{tab.icon}} /> </li> {{/each}} diff --git a/app/assets/javascripts/discourse/app/components/more-topics.js b/app/assets/javascripts/discourse/app/components/more-topics.js index 40e37fcb0f5..9ea4bf2062a 100644 --- a/app/assets/javascripts/discourse/app/components/more-topics.js +++ b/app/assets/javascripts/discourse/app/components/more-topics.js @@ -1,8 +1,6 @@ import Component from "@glimmer/component"; import { inject as service } from "@ember/service"; -import { next } from "@ember/runloop"; import { action, computed } from "@ember/object"; -import { tracked } from "@glimmer/tracking"; import I18n from "I18n"; import { categoryBadgeHTML } from "discourse/helpers/category-link"; import getURL from "discourse-common/lib/get-url"; @@ -15,59 +13,24 @@ export default class MoreTopics extends Component { @service topicTrackingState; @service currentUser; - @tracked availablePills = []; - @tracked singleList = false; - @action rememberTopicListPreference(value) { - // Don't change the preference when selecting related PMs. - // It messes with the topics pref. - const rememberPref = value !== "related-messages"; - - this.moreTopicsPreferenceTracking.updatePreference(value, rememberPref); - - this.buildListPills(); + this.moreTopicsPreferenceTracking.updatePreference(value); } - @action - buildListPills() { - next(() => { - const pills = Array.from( - document.querySelectorAll(".more-topics__list") - ).map((topicList) => { - return { - name: topicList.dataset.mobileTitle, - id: topicList.dataset.listId, - }; - }); + @computed("moreTopicsPreferenceTracking.topicLists") + get singleList() { + return this.availableTabs.length === 1; + } - if (pills.length === 0) { - return; - } else if (pills.length === 1) { - this.singleList = true; - } + @computed("moreTopicsPreferenceTracking.selectedTab") + get selectedTab() { + return this.moreTopicsPreferenceTracking.selectedTab; + } - let preference = this.moreTopicsPreferenceTracking.preference; - // Scenario where we have a preference, but there - // are no more elements in it. - const listPresent = pills.find((pill) => pill.id === preference); - - if (!listPresent) { - const rememberPref = false; - - this.moreTopicsPreferenceTracking.updatePreference( - pills[0].id, - rememberPref - ); - preference = pills[0].id; - } - - pills.forEach((pill) => { - pill.selected = pill.id === preference; - }); - - this.availablePills = pills; - }); + @computed("moreTopicsPreferenceTracking.topicLists") + get availableTabs() { + return this.moreTopicsPreferenceTracking.topicLists; } @computed( diff --git a/app/assets/javascripts/discourse/app/components/related-messages.hbs b/app/assets/javascripts/discourse/app/components/related-messages.hbs index 18d7862cb35..23145a55a93 100644 --- a/app/assets/javascripts/discourse/app/components/related-messages.hbs +++ b/app/assets/javascripts/discourse/app/components/related-messages.hbs @@ -3,8 +3,8 @@ class="more-topics__list {{if this.hidden 'hidden'}}" role="complementary" aria-labelledby="related-messages-title" - data-mobile-title={{i18n "related_messages.pill"}} - data-list-id={{this.listId}} + {{did-insert this.registerList}} + {{will-destroy this.removeList}} > <h3 id="related-messages-title" class="more-topics__list-title"> {{i18n "related_messages.title"}} diff --git a/app/assets/javascripts/discourse/app/components/related-messages.js b/app/assets/javascripts/discourse/app/components/related-messages.js index 51a3adbff0f..688b3bda3da 100644 --- a/app/assets/javascripts/discourse/app/components/related-messages.js +++ b/app/assets/javascripts/discourse/app/components/related-messages.js @@ -1,7 +1,8 @@ import Component from "@glimmer/component"; -import { computed } from "@ember/object"; +import { action, computed } from "@ember/object"; import getURL from "discourse-common/lib/get-url"; import { inject as service } from "@ember/service"; +import I18n from "I18n"; export default class RelatedMessages extends Component { @service moreTopicsPreferenceTracking; @@ -9,9 +10,22 @@ export default class RelatedMessages extends Component { listId = "related-Messages"; - @computed("moreTopicsPreferenceTracking.preference") + @computed("moreTopicsPreferenceTracking.selectedTab") get hidden() { - return this.moreTopicsPreferenceTracking.preference !== this.listId; + return this.moreTopicsPreferenceTracking.selectedTab !== this.listId; + } + + @action + registerList() { + this.moreTopicsPreferenceTracking.registerTopicList({ + name: I18n.t("related_messages.pill"), + id: this.listId, + }); + } + + @action + removeList() { + this.moreTopicsPreferenceTracking.removeTopicList(this.listId); } get targetUser() { diff --git a/app/assets/javascripts/discourse/app/components/suggested-topics.hbs b/app/assets/javascripts/discourse/app/components/suggested-topics.hbs index 215a9d1de3f..60c9cc00579 100644 --- a/app/assets/javascripts/discourse/app/components/suggested-topics.hbs +++ b/app/assets/javascripts/discourse/app/components/suggested-topics.hbs @@ -3,8 +3,8 @@ class="more-topics__list {{if this.hidden 'hidden'}}" role="complementary" aria-labelledby="suggested-topics-title" - data-mobile-title={{i18n "suggested_topics.pill"}} - data-list-id={{this.listId}} + {{did-insert this.registerList}} + {{will-destroy this.removeList}} > <UserTip @id="suggested_topics" @selector=".user-tip-reference" /> diff --git a/app/assets/javascripts/discourse/app/components/suggested-topics.js b/app/assets/javascripts/discourse/app/components/suggested-topics.js index 4b6ead15b29..fb563e1e180 100644 --- a/app/assets/javascripts/discourse/app/components/suggested-topics.js +++ b/app/assets/javascripts/discourse/app/components/suggested-topics.js @@ -1,6 +1,7 @@ import Component from "@glimmer/component"; -import { computed } from "@ember/object"; +import { action, computed } from "@ember/object"; import { inject as service } from "@ember/service"; +import I18n from "I18n"; export default class SuggestedTopics extends Component { @service moreTopicsPreferenceTracking; @@ -17,8 +18,21 @@ export default class SuggestedTopics extends Component { } } - @computed("moreTopicsPreferenceTracking.preference") + @computed("moreTopicsPreferenceTracking.selectedTab") get hidden() { - return this.moreTopicsPreferenceTracking.preference !== this.listId; + return this.moreTopicsPreferenceTracking.selectedTab !== this.listId; + } + + @action + registerList() { + this.moreTopicsPreferenceTracking.registerTopicList({ + name: I18n.t("suggested_topics.pill"), + id: this.listId, + }); + } + + @action + removeList() { + this.moreTopicsPreferenceTracking.removeTopicList(this.listId); } } diff --git a/app/assets/javascripts/discourse/app/services/more-topics-preference-tracking.js b/app/assets/javascripts/discourse/app/services/more-topics-preference-tracking.js index 091285f2cdf..4359f927f09 100644 --- a/app/assets/javascripts/discourse/app/services/more-topics-preference-tracking.js +++ b/app/assets/javascripts/discourse/app/services/more-topics-preference-tracking.js @@ -6,18 +6,49 @@ const TOPIC_LIST_PREFERENCE_KEY = "more-topics-list-preference"; export default class MoreTopicsPreferenceTracking extends Service { @service keyValueStore; - @tracked preference; + @tracked selectedTab = null; + @tracked topicLists = []; + + memoryTab = null; init() { super.init(...arguments); - this.preference = this.keyValueStore.get(TOPIC_LIST_PREFERENCE_KEY); + this.memoryTab = this.keyValueStore.get(TOPIC_LIST_PREFERENCE_KEY); } - updatePreference(value, rememberPref = true) { + updatePreference(value) { + // Don't change the preference when selecting related PMs. + // It messes with the topics pref. + const rememberPref = value !== "related-messages"; + if (rememberPref) { this.keyValueStore.set({ key: TOPIC_LIST_PREFERENCE_KEY, value }); + this.memoryTab = value; } - this.preference = value; + this.selectedTab = value; + } + + registerTopicList(item) { + // We have a preference stored and the list exists. + if (this.memoryTab && this.memoryTab === item.id) { + this.selectedTab = item.id; + } + + // Use the first list as a default. Future lists may override this + // if they match the stored preference. + if (!this.selectedTab) { + this.selectedTab = item.id; + } + + this.topicLists = [...this.topicLists, item]; + } + + removeTopicList(itemId) { + this.topicLists = this.topicLists.filter((item) => item.id !== itemId); + + if (this.selectedTab === itemId) { + this.selectedTab = this.topicLists[0]?.id; + } } } diff --git a/app/assets/stylesheets/common/components/more-topics.scss b/app/assets/stylesheets/common/components/more-topics.scss index b7d449350e0..fb8b8092e9e 100644 --- a/app/assets/stylesheets/common/components/more-topics.scss +++ b/app/assets/stylesheets/common/components/more-topics.scss @@ -9,6 +9,10 @@ .btn { padding: 0.5em 0.65em; } + + .btn.active .d-icon { + color: var(--primary-low); + } } }