diff --git a/app/assets/javascripts/discourse/app/controllers/user-private-messages.js b/app/assets/javascripts/discourse/app/controllers/user-private-messages.js index 2ca079d6a6e..45c37747bd2 100644 --- a/app/assets/javascripts/discourse/app/controllers/user-private-messages.js +++ b/app/assets/javascripts/discourse/app/controllers/user-private-messages.js @@ -2,11 +2,27 @@ import Controller, { inject as controller } from "@ember/controller"; import { action, computed } from "@ember/object"; import { inject as service } from "@ember/service"; import { alias, and, equal, readOnly } from "@ember/object/computed"; -import { tracked } from "@glimmer/tracking"; +import { cached, tracked } from "@glimmer/tracking"; import I18n from "I18n"; import DiscourseURL from "discourse/lib/url"; -export const PERSONAL_INBOX = "__personal_inbox__"; +const customUserNavMessagesDropdownRows = []; + +export function registerCustomUserNavMessagesDropdownRow( + routeName, + name, + icon +) { + customUserNavMessagesDropdownRows.push({ + routeName, + name, + icon, + }); +} + +export function resetCustomUserNavMessagesDropdownRows() { + customUserNavMessagesDropdownRows.length = 0; +} export default class extends Controller { @service router; @@ -25,19 +41,21 @@ export default class extends Controller { @readOnly("site.can_tag_pms") pmTaggingEnabled; get messagesDropdownValue() { - const parentRoute = this.router.currentRoute.parent; + let value; - if (Object.keys(parentRoute.params).length > 0) { - return this.router.urlFor( - parentRoute.name, - this.model.username, - parentRoute.params - ); - } else { - return this.router.urlFor(parentRoute.name, this.model.username); + for (let i = this.messagesDropdownContent.length - 1; i >= 0; i--) { + const row = this.messagesDropdownContent[i]; + + if (this.router.currentURL.includes(row.id)) { + value = row.id; + break; + } } + + return value; } + @cached get messagesDropdownContent() { const content = [ { @@ -66,6 +84,14 @@ export default class extends Controller { }); } + customUserNavMessagesDropdownRows.forEach((row) => { + content.push({ + id: this.router.urlFor(row.routeName, this.model.username), + name: row.name, + icon: row.icon, + }); + }); + return content; } diff --git a/app/assets/javascripts/discourse/app/lib/plugin-api.js b/app/assets/javascripts/discourse/app/lib/plugin-api.js index b55155b5b87..91e666becb6 100644 --- a/app/assets/javascripts/discourse/app/lib/plugin-api.js +++ b/app/assets/javascripts/discourse/app/lib/plugin-api.js @@ -107,6 +107,7 @@ import DiscourseURL from "discourse/lib/url"; import { registerNotificationTypeRenderer } from "discourse/lib/notification-types-manager"; import { registerUserMenuTab } from "discourse/lib/user-menu/tab"; import { registerModelTransformer } from "discourse/lib/model-transformers"; +import { registerCustomUserNavMessagesDropdownRow } from "discourse/controllers/user-private-messages"; // If you add any methods to the API ensure you bump up the version number // based on Semantic Versioning 2.0.0. Please update the changelog at @@ -2018,6 +2019,19 @@ class PluginApi { registerModelTransformer(modelName, transformer) { registerModelTransformer(modelName, transformer); } + + /** + * EXPERIMENTAL. Do not use. + * Adds a row to the dropdown used on the `userPrivateMessages` route used to navigate between the different user + * messages pages. + * + * @param {string} routeName The Ember route name to transition to when the row is selected in the dropdown + * @param {string} name The text displayed to represent the row in the dropdown + * @param {string} [icon] The name of the icon that will be used when displaying the row in the dropdown + */ + addUserMessagesNavigationDropdownRow(routeName, name, icon) { + registerCustomUserNavMessagesDropdownRow(routeName, name, icon); + } } // from http://stackoverflow.com/questions/6832596/how-to-compare-software-version-number-using-js-only-number diff --git a/app/assets/javascripts/discourse/app/templates/user-private-messages-user.hbs b/app/assets/javascripts/discourse/app/templates/user-private-messages-user.hbs index bc25f24dabb..125404af45f 100644 --- a/app/assets/javascripts/discourse/app/templates/user-private-messages-user.hbs +++ b/app/assets/javascripts/discourse/app/templates/user-private-messages-user.hbs @@ -39,8 +39,6 @@ {{i18n "user.messages.archive"}} - - {{outlet}} diff --git a/app/assets/javascripts/discourse/tests/acceptance/user-private-messages-test.js b/app/assets/javascripts/discourse/tests/acceptance/user-private-messages-test.js index 8dc4313df4d..9ac356da93e 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/user-private-messages-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/user-private-messages-test.js @@ -17,6 +17,8 @@ import { resetHighestReadCache, setHighestReadCache, } from "discourse/lib/topic-list-tracker"; +import { withPluginApi } from "discourse/lib/plugin-api"; +import { resetCustomUserNavMessagesDropdownRows } from "discourse/controllers/user-private-messages"; acceptance( "User Private Messages - user with no group messages", @@ -753,6 +755,30 @@ function testUserPrivateMessagesWithGroupMessages(needs, customUserProps) { "All tags is still selected in dropdown" ); }); + + test("addUserMessagesNavigationDropdownRow plugin api", async function (assert) { + try { + withPluginApi("1.5.0", (api) => { + api.addUserMessagesNavigationDropdownRow( + "preferences", + "test nav", + "arrow-left" + ); + }); + + await visit("/u/eviltrout/messages"); + + const messagesDropdown = selectKit(".user-nav-messages-dropdown"); + await messagesDropdown.expand(); + + const row = messagesDropdown.rowByName("test nav"); + + assert.strictEqual(row.value(), "/u/eviltrout/preferences"); + assert.ok(row.icon().classList.contains("d-icon-arrow-left")); + } finally { + resetCustomUserNavMessagesDropdownRows(); + } + }); } }