From e7fb4be23ec609546d83950faecdf00b9fcbfb04 Mon Sep 17 00:00:00 2001 From: Roman Rizzi Date: Mon, 31 Jul 2023 18:33:21 -0300 Subject: [PATCH] UX: Topic recommendations tweaks. (#22880) This PR updates how we display related and suggested topics on mobile and desktop. It adds a new `PluginOutlet` specifically designed for adding new topic lists, which automatically work if following the same conventions as the ones inside ``. While we display lists side by side on desktop, we only display one in mobile. You can switch to another one by clicking on the nav pills, and we'll automatically save your preference for next time. --- .../discourse/app/components/more-topics.hbs | 40 ++ .../discourse/app/components/more-topics.js | 64 ++ .../app/components/related-messages.hbs | 6 +- .../app/components/related-messages.js | 8 + .../app/components/suggested-topics.hbs | 16 +- .../app/components/suggested-topics.js | 8 + .../discourse/app/lib/keyboard-shortcuts.js | 2 +- .../more-topics-preference-tracking.js | 20 + .../discourse/app/templates/topic.hbs | 16 +- .../tests/acceptance/personal-message-test.js | 2 +- .../discourse/tests/acceptance/topic-test.js | 2 +- .../acceptance/user-private-messages-test.js | 590 +++++++++--------- app/assets/stylesheets/common/base/topic.scss | 37 +- .../stylesheets/desktop/topic-post.scss | 8 +- app/assets/stylesheets/desktop/topic.scss | 18 + app/assets/stylesheets/mobile/topic-post.scss | 19 +- config/locales/client.en.yml | 4 +- 17 files changed, 511 insertions(+), 349 deletions(-) create mode 100644 app/assets/javascripts/discourse/app/components/more-topics.hbs create mode 100644 app/assets/javascripts/discourse/app/components/more-topics.js create mode 100644 app/assets/javascripts/discourse/app/services/more-topics-preference-tracking.js diff --git a/app/assets/javascripts/discourse/app/components/more-topics.hbs b/app/assets/javascripts/discourse/app/components/more-topics.hbs new file mode 100644 index 00000000000..3c9f3ffcf23 --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/more-topics.hbs @@ -0,0 +1,40 @@ +
+ {{#if this.showTopicListsNav}} +
+ +
+ {{/if}} + + {{#if @topic.relatedMessages.length}} + + {{/if}} + + {{#if @topic.suggestedTopics.length}} + + + + + + {{/if}} + + +
\ No newline at end of file diff --git a/app/assets/javascripts/discourse/app/components/more-topics.js b/app/assets/javascripts/discourse/app/components/more-topics.js new file mode 100644 index 00000000000..58d3dd6c796 --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/more-topics.js @@ -0,0 +1,64 @@ +import Component from "@glimmer/component"; +import { inject as service } from "@ember/service"; +import { next } from "@ember/runloop"; +import { action } from "@ember/object"; +import { tracked } from "@glimmer/tracking"; + +export default class MoreTopics extends Component { + @service site; + @service moreTopicsPreferenceTracking; + + @tracked availablePills = []; + @tracked singleList = false; + + get showTopicListsNav() { + return this.site.mobileView && !this.singleList; + } + + get showTitleOnMobile() { + return this.site.mobileView && this.singleList; + } + + @action + rememberTopicListPreference(value) { + this.moreTopicsPreferenceTracking.updatePreference(value); + + this.buildListPills(); + } + + @action + buildListPills() { + if (!this.site.mobileView) { + return; + } + + next(() => { + const pills = Array.from( + document.querySelectorAll(".more-content-topics") + ).map((topicList) => { + return { + name: topicList.dataset.mobileTitle, + id: topicList.dataset.listId, + }; + }); + + if (pills.length <= 1) { + this.singleList = true; + return; + } + + let preference = this.moreTopicsPreferenceTracking.preference; + + if (!preference) { + this.moreTopicsPreferenceTracking.updatePreference(pills[0].id); + preference = pills[0].id; + } + + pills.forEach((pill) => { + pill.selected = pill.id === preference; + }); + + this.availablePills = pills; + }); + } +} diff --git a/app/assets/javascripts/discourse/app/components/related-messages.hbs b/app/assets/javascripts/discourse/app/components/related-messages.hbs index 32cdb231862..6767440cc14 100644 --- a/app/assets/javascripts/discourse/app/components/related-messages.hbs +++ b/app/assets/javascripts/discourse/app/components/related-messages.hbs @@ -1,10 +1,12 @@ \ No newline at end of file diff --git a/app/assets/javascripts/discourse/app/components/suggested-topics.js b/app/assets/javascripts/discourse/app/components/suggested-topics.js index ad0c6671706..3a46a0670ec 100644 --- a/app/assets/javascripts/discourse/app/components/suggested-topics.js +++ b/app/assets/javascripts/discourse/app/components/suggested-topics.js @@ -5,9 +5,12 @@ import { categoryBadgeHTML } from "discourse/helpers/category-link"; import discourseComputed from "discourse-common/utils/decorators"; import getURL from "discourse-common/lib/get-url"; import { iconHTML } from "discourse-common/lib/icon-library"; +import { inject as service } from "@ember/service"; export default Component.extend({ tagName: "", + moreTopicsPreferenceTracking: service(), + listId: "suggested-topics", suggestedTitleLabel: computed("topic", function () { const href = this.currentUser && this.currentUser.pmPath(this.topic); @@ -18,6 +21,11 @@ export default Component.extend({ } }), + @discourseComputed("moreTopicsPreferenceTracking.preference") + hidden(preference) { + return this.site.mobileView && preference !== this.listId; + }, + @discourseComputed( "topic", "pmTopicTrackingState.isTracking", diff --git a/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js b/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js index 3316daad88d..5eb93bec091 100644 --- a/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js +++ b/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js @@ -360,7 +360,7 @@ export default { }, goToFirstSuggestedTopic() { - const el = document.querySelector(".suggested-topics a.raw-topic-link"); + const el = document.querySelector("#suggested-topics a.raw-topic-link"); if (el) { el.click(); } else { 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 new file mode 100644 index 00000000000..6267ef94d17 --- /dev/null +++ b/app/assets/javascripts/discourse/app/services/more-topics-preference-tracking.js @@ -0,0 +1,20 @@ +import Service, { inject as service } from "@ember/service"; +import { tracked } from "@glimmer/tracking"; + +const TOPIC_LIST_PREFERENCE_KEY = "more-topics-list-preference"; + +export default class MoreTopicsPreferenceTracking extends Service { + @service keyValueStore; + + @tracked preference; + + init() { + super.init(...arguments); + this.preference = this.keyValueStore.get(TOPIC_LIST_PREFERENCE_KEY); + } + + updatePreference(value) { + this.keyValueStore.set({ key: TOPIC_LIST_PREFERENCE_KEY, value }); + this.preference = value; + } +} diff --git a/app/assets/javascripts/discourse/app/templates/topic.hbs b/app/assets/javascripts/discourse/app/templates/topic.hbs index a830830a10e..aa269fe16bb 100644 --- a/app/assets/javascripts/discourse/app/templates/topic.hbs +++ b/app/assets/javascripts/discourse/app/templates/topic.hbs @@ -543,20 +543,8 @@ @outletArgs={{hash model=this.model}} /> -
- {{#if this.model.relatedMessages.length}} - - {{/if}} - {{#if this.model.suggestedTopics.length}} - - {{/if}} -
+ + {{/if}} {{else}}
diff --git a/app/assets/javascripts/discourse/tests/acceptance/personal-message-test.js b/app/assets/javascripts/discourse/tests/acceptance/personal-message-test.js index e4d2f430f4c..a5f9802fe2c 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/personal-message-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/personal-message-test.js @@ -21,7 +21,7 @@ acceptance("Personal Message", function (needs) { await visit("/t/pm-for-testing/12"); assert.strictEqual( - query("#suggested-topics .suggested-topics-title").innerText.trim(), + query("#suggested-topics-title").innerText.trim(), I18n.t("suggested_topics.pm_title") ); }); diff --git a/app/assets/javascripts/discourse/tests/acceptance/topic-test.js b/app/assets/javascripts/discourse/tests/acceptance/topic-test.js index 318460d635b..df3aa629f10 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/topic-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/topic-test.js @@ -204,7 +204,7 @@ acceptance("Topic", function (needs) { await visit("/t/internationalization-localization/280"); assert.strictEqual( - query("#suggested-topics .suggested-topics-title").innerText.trim(), + query("#suggested-topics-title").innerText.trim(), I18n.t("suggested_topics.title") ); }); 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 3fdd3aadf35..ae50319aebd 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 @@ -83,242 +83,246 @@ acceptance( } ); -acceptance( - "User Private Messages - user with group messages", - function (needs) { - let fetchedNew; - let fetchUserNew; - let fetchedGroupNew; +let fetchedNew; +let fetchUserNew; +let fetchedGroupNew; - needs.user({ - id: 5, - username: "charlie", - groups: [{ id: 14, name: "awesome_group", has_messages: true }], +function withGroupMessagesSetup(needs) { + needs.user({ + id: 5, + username: "charlie", + groups: [{ id: 14, name: "awesome_group", has_messages: true }], + }); + + needs.site({ + can_tag_pms: true, + }); + + needs.hooks.afterEach(() => { + fetchedNew = false; + fetchedGroupNew = false; + fetchUserNew = false; + }); + + needs.pretender((server, helper) => { + server.get("/tags/personal_messages/:username.json", () => { + return helper.response({ tags: [{ id: "tag1" }] }); }); - needs.site({ - can_tag_pms: true, + server.get("/t/13.json", () => { + const response = cloneJSON(fixturesByUrl["/t/12/1.json"]); + response.suggested_group_name = "awesome_group"; + return helper.response(response); }); - needs.hooks.afterEach(() => { - fetchedNew = false; - fetchedGroupNew = false; - fetchUserNew = false; - }); - - needs.pretender((server, helper) => { - server.get("/tags/personal_messages/:username.json", () => { - return helper.response({ tags: [{ id: "tag1" }] }); + server.get("/topics/private-messages/:username.json", () => { + return helper.response({ + topic_list: { + topics: [ + { + id: 1, + posters: [], + notification_level: NotificationLevels.TRACKING, + unread_posts: 1, + last_read_post_number: 1, + highest_post_number: 2, + }, + { + id: 2, + posters: [], + }, + { + id: 3, + posters: [], + }, + ], + }, }); + }); - server.get("/t/13.json", () => { - const response = cloneJSON(fixturesByUrl["/t/12/1.json"]); - response.suggested_group_name = "awesome_group"; - return helper.response(response); + [ + "/topics/private-messages-new/:username.json", + "/topics/private-messages-unread/:username.json", + "/topics/private-messages-archive/:username.json", + "/topics/private-messages-group/:username/:group_name/new.json", + "/topics/private-messages-group/:username/:group_name/unread.json", + "/topics/private-messages-group/:username/:group_name/archive.json", + "/topics/private-messages-tags/:username/:tag_name", + ].forEach((url) => { + server.get(url, () => { + let topics; + + if (fetchedNew || fetchedGroupNew || fetchUserNew) { + topics = []; + } else { + topics = [ + { id: 1, posters: [] }, + { id: 2, posters: [] }, + { id: 3, posters: [] }, + ]; + } + + return helper.response({ + topic_list: { + topics, + }, + }); }); + }); - server.get("/topics/private-messages/:username.json", () => { + server.get( + "/topics/private-messages-group/:username/:group_name.json", + () => { return helper.response({ topic_list: { topics: [ - { - id: 1, - posters: [], - notification_level: NotificationLevels.TRACKING, - unread_posts: 1, - last_read_post_number: 1, - highest_post_number: 2, - }, - { - id: 2, - posters: [], - }, - { - id: 3, - posters: [], - }, + { id: 1, posters: [] }, + { id: 2, posters: [] }, ], }, }); - }); + } + ); - [ - "/topics/private-messages-new/:username.json", - "/topics/private-messages-unread/:username.json", - "/topics/private-messages-archive/:username.json", - "/topics/private-messages-group/:username/:group_name/new.json", - "/topics/private-messages-group/:username/:group_name/unread.json", - "/topics/private-messages-group/:username/:group_name/archive.json", - "/topics/private-messages-tags/:username/:tag_name", - ].forEach((url) => { - server.get(url, () => { - let topics; + server.put("/topics/pm-reset-new", (request) => { + const requestBody = request.requestBody; + // No easy way to do this https://github.com/pretenderjs/pretender/issues/159 + if (requestBody === "inbox=group&group_name=awesome_group") { + fetchedGroupNew = true; + } - if (fetchedNew || fetchedGroupNew || fetchUserNew) { - topics = []; - } else { - topics = [ - { id: 1, posters: [] }, - { id: 2, posters: [] }, - { id: 3, posters: [] }, - ]; - } + if (requestBody === "inbox=user") { + fetchUserNew = true; + } - return helper.response({ - topic_list: { - topics, - }, - }); - }); - }); + if (requestBody === "inbox=all") { + fetchedNew = true; + } - server.get( - "/topics/private-messages-group/:username/:group_name.json", - () => { - return helper.response({ - topic_list: { - topics: [ - { id: 1, posters: [] }, - { id: 2, posters: [] }, - ], - }, - }); - } - ); - - server.put("/topics/pm-reset-new", (request) => { - const requestBody = request.requestBody; - // No easy way to do this https://github.com/pretenderjs/pretender/issues/159 - if (requestBody === "inbox=group&group_name=awesome_group") { - fetchedGroupNew = true; - } - - if (requestBody === "inbox=user") { - fetchUserNew = true; - } - - if (requestBody === "inbox=all") { - fetchedNew = true; - } - - return helper.response({ topic_ids: [1, 2, 3] }); - }); - - server.put("/topics/bulk", (request) => { - const requestBody = request.requestBody; - - if (requestBody.includes("private_message_inbox=all")) { - fetchedNew = true; - } - - if ( - requestBody.includes( - "private_message_inbox=group&group_name=awesome_group" - ) - ) { - fetchedGroupNew = true; - } - - if (requestBody.includes("private_message_inbox=user")) { - fetchUserNew = true; - } - - return helper.response({ - topic_ids: [1, 2, 3], - }); - }); + return helper.response({ topic_ids: [1, 2, 3] }); }); - const publishReadToMessageBus = function (opts = {}) { - return publishToMessageBus( - `/private-message-topic-tracking-state/user/${opts.userId || 5}`, - { - topic_id: opts.topicId, - message_type: "read", - payload: { - last_read_post_number: 2, - highest_post_number: 2, - notification_level: 2, - }, - } - ); - }; + server.put("/topics/bulk", (request) => { + const requestBody = request.requestBody; - const publishUnreadToMessageBus = function (opts = {}) { - return publishToMessageBus( - `/private-message-topic-tracking-state/user/${opts.userId || 5}`, - { - topic_id: opts.topicId, - message_type: "unread", - payload: { - last_read_post_number: 1, - highest_post_number: 2, - notification_level: 2, - group_ids: opts.groupIds || [], - }, - } - ); - }; + if (requestBody.includes("private_message_inbox=all")) { + fetchedNew = true; + } - const publishNewToMessageBus = function (opts = {}) { - return publishToMessageBus( - `/private-message-topic-tracking-state/user/${opts.userId || 5}`, - { - topic_id: opts.topicId, - message_type: "new_topic", - payload: { - last_read_post_number: null, - highest_post_number: 1, - group_ids: opts.groupIds || [], - }, - } - ); - }; + if ( + requestBody.includes( + "private_message_inbox=group&group_name=awesome_group" + ) + ) { + fetchedGroupNew = true; + } - const publishGroupArchiveToMessageBus = function (opts) { - return publishToMessageBus( - `/private-message-topic-tracking-state/group/${opts.groupIds[0]}`, - { - topic_id: opts.topicId, - message_type: "group_archive", - payload: { - group_ids: opts.groupIds, - acting_user_id: opts.actingUserId, - }, - } - ); - }; + if (requestBody.includes("private_message_inbox=user")) { + fetchUserNew = true; + } - const publishGroupUnreadToMessageBus = function (opts) { - return publishToMessageBus( - `/private-message-topic-tracking-state/group/${opts.groupIds[0]}`, - { - topic_id: opts.topicId, - message_type: "unread", - payload: { - last_read_post_number: 1, - highest_post_number: 2, - notification_level: 2, - group_ids: opts.groupIds || [], - }, - } - ); - }; + return helper.response({ + topic_ids: [1, 2, 3], + }); + }); + }); +} - const publishGroupNewToMessageBus = function (opts) { - return publishToMessageBus( - `/private-message-topic-tracking-state/group/${opts.groupIds[0]}`, - { - topic_id: opts.topicId, - message_type: "new_topic", - payload: { - last_read_post_number: null, - highest_post_number: 1, - group_ids: opts.groupIds || [], - }, - } - ); - }; +const publishReadToMessageBus = function (opts = {}) { + return publishToMessageBus( + `/private-message-topic-tracking-state/user/${opts.userId || 5}`, + { + topic_id: opts.topicId, + message_type: "read", + payload: { + last_read_post_number: 2, + highest_post_number: 2, + notification_level: 2, + }, + } + ); +}; + +const publishUnreadToMessageBus = function (opts = {}) { + return publishToMessageBus( + `/private-message-topic-tracking-state/user/${opts.userId || 5}`, + { + topic_id: opts.topicId, + message_type: "unread", + payload: { + last_read_post_number: 1, + highest_post_number: 2, + notification_level: 2, + group_ids: opts.groupIds || [], + }, + } + ); +}; + +const publishNewToMessageBus = function (opts = {}) { + return publishToMessageBus( + `/private-message-topic-tracking-state/user/${opts.userId || 5}`, + { + topic_id: opts.topicId, + message_type: "new_topic", + payload: { + last_read_post_number: null, + highest_post_number: 1, + group_ids: opts.groupIds || [], + }, + } + ); +}; + +const publishGroupArchiveToMessageBus = function (opts) { + return publishToMessageBus( + `/private-message-topic-tracking-state/group/${opts.groupIds[0]}`, + { + topic_id: opts.topicId, + message_type: "group_archive", + payload: { + group_ids: opts.groupIds, + acting_user_id: opts.actingUserId, + }, + } + ); +}; + +const publishGroupUnreadToMessageBus = function (opts) { + return publishToMessageBus( + `/private-message-topic-tracking-state/group/${opts.groupIds[0]}`, + { + topic_id: opts.topicId, + message_type: "unread", + payload: { + last_read_post_number: 1, + highest_post_number: 2, + notification_level: 2, + group_ids: opts.groupIds || [], + }, + } + ); +}; + +const publishGroupNewToMessageBus = function (opts) { + return publishToMessageBus( + `/private-message-topic-tracking-state/group/${opts.groupIds[0]}`, + { + topic_id: opts.topicId, + message_type: "new_topic", + payload: { + last_read_post_number: null, + highest_post_number: 1, + group_ids: opts.groupIds || [], + }, + } + ); +}; + +acceptance( + "User Private Messages - user with group messages", + function (needs) { + withGroupMessagesSetup(needs); test("incoming group archive message acted by current user", async function (assert) { await visit("/u/charlie/messages"); @@ -639,83 +643,6 @@ acceptance( ); }); - test("suggested messages without new or unread", async function (assert) { - await visit("/t/12"); - - assert.strictEqual( - query(".suggested-topics-message").innerText.trim(), - "Want to read more? Browse other messages in personal messages.", - "displays the right browse more message" - ); - }); - - test("suggested messages with new and unread", async function (assert) { - await visit("/t/12"); - - await publishNewToMessageBus({ userId: 5, topicId: 1 }); - - assert.strictEqual( - query(".suggested-topics-message").innerText.trim(), - "There is 1 new message remaining, or browse other personal messages", - "displays the right browse more message" - ); - - await publishUnreadToMessageBus({ userId: 5, topicId: 2 }); - - assert.strictEqual( - query(".suggested-topics-message").innerText.trim(), - "There is 1 unread and 1 new message remaining, or browse other personal messages", - "displays the right browse more message" - ); - - await publishReadToMessageBus({ userId: 5, topicId: 2 }); - - assert.strictEqual( - query(".suggested-topics-message").innerText.trim(), - "There is 1 new message remaining, or browse other personal messages", - "displays the right browse more message" - ); - }); - - test("suggested messages for group messages without new or unread", async function (assert) { - await visit("/t/13"); - - assert.ok( - query(".suggested-topics-message") - .innerText.trim() - .match( - /Want to read more\? Browse other messages in\s+awesome_group\./ - ), - "displays the right browse more message" - ); - }); - - test("suggested messages for group messages with new and unread", async function (assert) { - await visit("/t/13"); - - await publishGroupNewToMessageBus({ groupIds: [14], topicId: 1 }); - - assert.ok( - query(".suggested-topics-message") - .innerText.trim() - .match( - /There is 1 new message remaining, or browse other messages in\s+awesome_group/ - ), - "displays the right browse more message" - ); - - await publishGroupUnreadToMessageBus({ groupIds: [14], topicId: 2 }); - - assert.ok( - query(".suggested-topics-message") - .innerText.trim() - .match( - /There is 1 unread and 1 new message remaining, or browse other messages in\s+awesome_group/ - ), - "displays the right browse more message" - ); - }); - test("navigating between user messages route with dropdown", async function (assert) { await visit("/u/Charlie/messages"); @@ -808,6 +735,95 @@ acceptance( } ); +acceptance( + "User Private Messages - user with group messages - Mobile", + function (needs) { + withGroupMessagesSetup(needs); + needs.mobileView(); + + test("suggested messages without new or unread", async function (assert) { + await visit("/t/12"); + + assert.strictEqual( + query(".suggested-topics-message").innerText.trim(), + "Want to read more? Browse other messages in personal messages.", + "displays the right browse more message" + ); + }); + + test("suggested messages with new and unread", async function (assert) { + await visit("/t/12"); + + await publishNewToMessageBus({ userId: 5, topicId: 1 }); + + assert.strictEqual( + query(".suggested-topics-message").innerText.trim(), + "There is 1 new message remaining, or browse other personal messages", + "displays the right browse more message" + ); + + await publishUnreadToMessageBus({ userId: 5, topicId: 2 }); + + assert.ok( + query(".suggested-topics-message") + .innerText.trim() + .match( + /There is 1 unread\s+ and 1 new message remaining, or browse other personal messages/ + ), + "displays the right browse more message" + ); + + await publishReadToMessageBus({ userId: 5, topicId: 2 }); + + assert.strictEqual( + query(".suggested-topics-message").innerText.trim(), + "There is 1 new message remaining, or browse other personal messages", + "displays the right browse more message" + ); + }); + + test("suggested messages for group messages without new or unread", async function (assert) { + await visit("/t/13"); + + assert.ok( + query(".suggested-topics-message") + .innerText.trim() + .match( + /Want to read more\? Browse other messages in\s+awesome_group\./ + ), + "displays the right browse more message" + ); + }); + + test("suggested messages for group messages with new and unread", async function (assert) { + needs.mobileView(); + await visit("/t/13"); + + await publishGroupNewToMessageBus({ groupIds: [14], topicId: 1 }); + + assert.ok( + query(".suggested-topics-message") + .innerText.trim() + .match( + /There is 1 new message remaining, or browse other messages in\s+awesome_group/ + ), + "displays the right browse more message" + ); + + await publishGroupUnreadToMessageBus({ groupIds: [14], topicId: 2 }); + + assert.ok( + query(".suggested-topics-message") + .innerText.trim() + .match( + /There is 1 unread\s+ and 1 new message remaining, or browse other messages in\s+awesome_group/ + ), + "displays the right browse more message" + ); + }); + } +); + acceptance("User Private Messages - user with no messages", function (needs) { needs.user(); diff --git a/app/assets/stylesheets/common/base/topic.scss b/app/assets/stylesheets/common/base/topic.scss index 46dbe81f9b2..a6d1225fe0f 100644 --- a/app/assets/stylesheets/common/base/topic.scss +++ b/app/assets/stylesheets/common/base/topic.scss @@ -368,42 +368,43 @@ a.badge-category { max-width: 757px; } -.suggested-topics-wrapper.related-messages-wrapper { - .suggested-topics:nth-of-type(n + 2) { - thead { - display: none; - } - } +.more-content-wrapper .topic-list-body .topic-list-data:first-of-type { + padding-left: 0; } // Target the .badge-category text, the bullet icon needs to maintain `display: block` -.suggested-topics h3 .badge-wrapper.bullet span.badge-category, -.suggested-topics h3 .badge-wrapper.box span, -.suggested-topics h3 .badge-wrapper.bar span { +.more-content-topics h3 .badge-wrapper.bullet span.badge-category, +.more-content-topics h3 .badge-wrapper.box span, +.more-content-topics h3 .badge-wrapper.bar span { display: inline; } -.suggested-topics h3 .badge-wrapper.bullet span.badge-category { +.more-content-topicss h3 .badge-wrapper.bullet span.badge-category { // Override vertical-align: text-top from `badges.css.scss` vertical-align: baseline; line-height: var(--line-height-medium); } -.suggested-topics h3 .badge-wrapper.bullet, -.suggested-topics h3 .badge-wrapper.bullet span.badge-category-parent-bg, -.suggested-topics h3 .badge-wrapper.bullet span.badge-category-bg { +.more-content-topics h3 .badge-wrapper.bullet, +.more-content-topics h3 .badge-wrapper.bullet span.badge-category-parent-bg, +.more-content-topics h3 .badge-wrapper.bullet span.badge-category-bg { // Top of bullet aligns with top of line - adjust line height to vertically align bullet. line-height: 0.8; } -.suggested-topics .badge-wrapper.bullet span.badge-category, -.suggested-topics .badge-wrapper.bar span.badge-category { +.more-content-topics .badge-wrapper.bullet span.badge-category, +.more-content-topics .badge-wrapper.bar span.badge-category { max-width: 150px; } -.suggested-topics .suggested-topics-title { - display: flex; - align-items: center; +.more-content-topics { + .topic-list-body { + border-top: none; + + .topic-list-item:last-of-type { + border-bottom: none; + } + } } .post-links-container { diff --git a/app/assets/stylesheets/desktop/topic-post.scss b/app/assets/stylesheets/desktop/topic-post.scss index 16ec5f82095..250be807fcc 100644 --- a/app/assets/stylesheets/desktop/topic-post.scss +++ b/app/assets/stylesheets/desktop/topic-post.scss @@ -362,11 +362,11 @@ pre.codeblock-buttons:hover { } } -.suggested-topics { - margin: 4.5em 0 1em; +.more-content-topics { + margin-top: 2em; - table { - margin-top: 10px; + .suggested-topics-message { + display: none; } } diff --git a/app/assets/stylesheets/desktop/topic.scss b/app/assets/stylesheets/desktop/topic.scss index 9dd4ea77319..181f82c1f6c 100644 --- a/app/assets/stylesheets/desktop/topic.scss +++ b/app/assets/stylesheets/desktop/topic.scss @@ -135,3 +135,21 @@ max-width: 100%; } } + +.more-content-wrapper { + display: flex; + + .topic-list-header, + .posts-map, + .views { + display: none; + } + + .topic-list-body { + border-top: none; + + .topic-list-item:last-of-type { + border-bottom: none; + } + } +} diff --git a/app/assets/stylesheets/mobile/topic-post.scss b/app/assets/stylesheets/mobile/topic-post.scss index 2d6db363904..f09fb33bd24 100644 --- a/app/assets/stylesheets/mobile/topic-post.scss +++ b/app/assets/stylesheets/mobile/topic-post.scss @@ -252,17 +252,18 @@ a.reply-to-tab { } } -.suggested-topics { +.more-content-wrapper { + &:not(.mobile-single-list) { + .more-topics-title { + display: none; + } + } +} + +.more-content-topics { clear: left; padding: 20px 0 15px 0; - th.views, - td.views, - td.activity, - th.activity, - th.likes, - td.likes { - display: none; - } + a.badge-category, a.badge-category-parent { font-size: var(--font-down-1); diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index da297da8fa7..0a3cb03adcc 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -301,10 +301,12 @@ en: related_messages: title: "Related Messages" + pill: "Related Messages" see_all: 'See all messages from @%{username}...' suggested_topics: - title: "Suggested Topics" + title: "New & Unread Topics" + pill: "Suggested" pm_title: "Suggested Messages" about: