From 9415fecfd05af41fa953f6d3eea98415e4ac77b4 Mon Sep 17 00:00:00 2001 From: Andrei Prigorshnev Date: Thu, 26 Aug 2021 21:38:34 +0400 Subject: [PATCH] UX: improve blank page syndrome on the user messages page (#14165) The user-topic-list template is also in use in other places when we want to improve blank page syndrome, so this PR is a preparation for that changes as well. --- .../app/controllers/user-topics-list.js | 8 ++- .../routes/build-private-messages-route.js | 12 ++++ .../app/templates/user-topics-list.hbs | 65 +++++++++++-------- .../acceptance/user-private-messages-test.js | 43 ++++++++++++ 4 files changed, 98 insertions(+), 30 deletions(-) diff --git a/app/assets/javascripts/discourse/app/controllers/user-topics-list.js b/app/assets/javascripts/discourse/app/controllers/user-topics-list.js index 195adb4fb00407..6800f060d3c036 100644 --- a/app/assets/javascripts/discourse/app/controllers/user-topics-list.js +++ b/app/assets/javascripts/discourse/app/controllers/user-topics-list.js @@ -19,6 +19,12 @@ export default Controller.extend(BulkTopicSelection, { channel: null, tagsForUser: null, pmTopicTrackingState: null, + incomingCount: reads("pmTopicTrackingState.newIncoming.length"), + + @discourseComputed("emptyState", "model.topics.length", "incomingCount") + showEmptyStatePlaceholder(emptyState, topicsLength, incomingCount) { + return emptyState && topicsLength === 0 && incomingCount === 0; + }, saveScrollPosition() { this.session.set("topicListScrollPosition", $(window).scrollTop()); @@ -29,8 +35,6 @@ export default Controller.extend(BulkTopicSelection, { this.set("application.showFooter", !this.get("model.canLoadMore")); }, - incomingCount: reads("pmTopicTrackingState.newIncoming.length"), - @discourseComputed("filter", "model.topics.length") showResetNew(filter, hasTopics) { return filter === NEW_FILTER && hasTopics; diff --git a/app/assets/javascripts/discourse/app/routes/build-private-messages-route.js b/app/assets/javascripts/discourse/app/routes/build-private-messages-route.js index c2608d7606c385..846408a7cc728a 100644 --- a/app/assets/javascripts/discourse/app/routes/build-private-messages-route.js +++ b/app/assets/javascripts/discourse/app/routes/build-private-messages-route.js @@ -3,6 +3,8 @@ import UserAction from "discourse/models/user-action"; import UserTopicListRoute from "discourse/routes/user-topic-list"; import { findOrResetCachedTopicList } from "discourse/lib/cached-topic-list"; import { action } from "@ember/object"; +import { iconHTML } from "discourse-common/lib/icon-library"; +import getURL from "discourse-common/lib/get-url"; export const NEW_FILTER = "new"; export const UNREAD_FILTER = "unread"; @@ -61,6 +63,7 @@ export default (inboxType, path, filter) => { inbox: inboxType, pmTopicTrackingState: userPrivateMessagesController.pmTopicTrackingState, + emptyState: this.emptyState(), }); userTopicsListController.subscribe(); @@ -74,6 +77,15 @@ export default (inboxType, path, filter) => { this.searchService.set("contextType", "private_messages"); }, + emptyState() { + const title = I18n.t("user.no_messages_title"); + const body = I18n.t("user.no_messages_body", { + aboutUrl: getURL("/about"), + icon: iconHTML("envelope"), + }).htmlSafe(); + return { title, body }; + }, + deactivate() { this.controllerFor("user-topics-list").unsubscribe(); diff --git a/app/assets/javascripts/discourse/app/templates/user-topics-list.hbs b/app/assets/javascripts/discourse/app/templates/user-topics-list.hbs index 4e9d4d138e3837..7096fec48c64ad 100644 --- a/app/assets/javascripts/discourse/app/templates/user-topics-list.hbs +++ b/app/assets/javascripts/discourse/app/templates/user-topics-list.hbs @@ -1,11 +1,19 @@ -{{#unless site.mobileView}} - {{#if showToggleBulkSelect}} - {{bulk-select-button canDoBulkActions=true selected=selected action=(route-action "refresh")}} - {{/if}} -{{/unless}} +{{#if showEmptyStatePlaceholder}} +
+ {{emptyState.title}} +
+

{{emptyState.body}}

+
+
+{{else}} + {{#unless site.mobileView}} + {{#if showToggleBulkSelect}} + {{bulk-select-button canDoBulkActions=true selected=selected action=(route-action "refresh")}} + {{/if}} + {{/unless}} -{{#load-more class="paginated-topics-list" selector=".paginated-topics-list .topic-list tr" action=(action "loadMore")}} - {{topic-dismiss-buttons + {{#load-more class="paginated-topics-list" selector=".paginated-topics-list .topic-list tr" action=(action "loadMore")}} + {{topic-dismiss-buttons position="top" selectedTopics=selected model=model @@ -13,27 +21,27 @@ showDismissRead=showDismissRead resetNew=(action "resetNew")}} - {{#if (gt incomingCount 0)}} -
- - {{count-i18n key="topic_count_" suffix="latest" count=incomingCount}} - -
- {{/if}} + {{#if (gt incomingCount 0)}} +
+ + {{count-i18n key="topic_count_" suffix="latest" count=incomingCount}} + +
+ {{/if}} - {{basic-topic-list topicList=model - hideCategory=hideCategory - showPosters=showPosters - bulkSelectEnabled=bulkSelectEnabled - selected=selected - tagsForUser=tagsForUser - onScroll=saveScrollPosition - canBulkSelect=canBulkSelect - scrollOnLoad=true - toggleBulkSelect=(action "toggleBulkSelect") - updateAutoAddTopicsToBulkSelect=(action "updateAutoAddTopicsToBulkSelect")}} + {{basic-topic-list topicList=model + hideCategory=hideCategory + showPosters=showPosters + bulkSelectEnabled=bulkSelectEnabled + selected=selected + tagsForUser=tagsForUser + onScroll=saveScrollPosition + canBulkSelect=canBulkSelect + scrollOnLoad=true + toggleBulkSelect=(action "toggleBulkSelect") + updateAutoAddTopicsToBulkSelect=(action "updateAutoAddTopicsToBulkSelect")}} - {{topic-dismiss-buttons + {{topic-dismiss-buttons position="bottom" selectedTopics=selected model=model @@ -41,5 +49,6 @@ showDismissRead=showDismissRead resetNew=(action "resetNew")}} - {{conditional-loading-spinner condition=model.loadingMore}} -{{/load-more}} + {{conditional-loading-spinner condition=model.loadingMore}} + {{/load-more}} +{{/if}} 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 dac9e7d27bef00..d1891a8dead2bd 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 @@ -546,3 +546,46 @@ acceptance( }); } ); + +acceptance("User Private Messages - user with no messages", function (needs) { + needs.user(); + + needs.pretender((server, helper) => { + const emptyResponse = { + topic_list: { + topics: [], + }, + }; + + const apiUrls = [ + "/topics/private-messages-all/:username.json", + "/topics/private-messages-all-sent/:username.json", + "/topics/private-messages-all-new/:username.json", + "/topics/private-messages-all-unread/:username.json", + "/topics/private-messages-all-archive/:username.json", + ]; + + apiUrls.forEach((url) => { + server.get(url, () => { + return helper.response(emptyResponse); + }); + }); + }); + + test("It renders the empty state panel", async function (assert) { + await visit("/u/charlie/messages"); + assert.ok(exists("div.empty-state")); + + await visit("/u/charlie/messages/sent"); + assert.ok(exists("div.empty-state")); + + await visit("/u/charlie/messages/new"); + assert.ok(exists("div.empty-state")); + + await visit("/u/charlie/messages/unread"); + assert.ok(exists("div.empty-state")); + + await visit("/u/charlie/messages/archive"); + assert.ok(exists("div.empty-state")); + }); +});