empty-feed: Show special banner if muted topics in channel.

If we're in the feed for a channel and it is visibly empty
because all of the messages are in topics that have been
muted by the user, we now show an empty narrow banner that
informs the user about why the feed is empty, how to view
muted topics and links to the help center article on muting
and unmuting topics.

If the channel feed is empty and there are no messages in
muted topics, then we show the default empty narrow banner.

Fixes #31601.

Co-authored-by: Lauryn Menard <lauryn@zulip.com>
This commit is contained in:
aditya.chaudhary1558@gmail.com
2024-09-24 04:43:47 +05:30
committed by Tim Abbott
parent f2b33fc3ee
commit 2e59bb0768
2 changed files with 61 additions and 4 deletions

View File

@@ -5,6 +5,7 @@ import assert from "minimalistic-assert";
import * as compose_validate from "./compose_validate.ts"; import * as compose_validate from "./compose_validate.ts";
import type {Filter} from "./filter.ts"; import type {Filter} from "./filter.ts";
import {$t, $t_html} from "./i18n.ts"; import {$t, $t_html} from "./i18n.ts";
import * as message_lists from "./message_lists.ts";
import type {NarrowBannerData, SearchData} from "./narrow_error.ts"; import type {NarrowBannerData, SearchData} from "./narrow_error.ts";
import {narrow_error} from "./narrow_error.ts"; import {narrow_error} from "./narrow_error.ts";
import {page_params} from "./page_params.ts"; import {page_params} from "./page_params.ts";
@@ -62,6 +63,22 @@ const STARRED_MESSAGES_VIEW_EMPTY_BANNER = {
), ),
}; };
const MUTED_TOPICS_IN_CHANNEL_EMPTY_BANNER = {
title: $t({
defaultMessage: "You have muted all the topics in this channel.",
}),
html: $t_html(
{
defaultMessage:
"To view a muted topic, click <b>show all topics</b> in the left sidebar, and select one from the list. <z-link>Learn more</z-link>",
},
{
"z-link": (content_html) =>
`<a target="_blank" rel="noopener noreferrer" href="/help/mute-a-topic">${content_html.join("")}</a>`,
},
),
};
function retrieve_search_query_data(current_filter: Filter): SearchData { function retrieve_search_query_data(current_filter: Filter): SearchData {
// when search bar contains multiple filters, only retrieve search queries // when search bar contains multiple filters, only retrieve search queries
const search_query = current_filter.operands("search")[0]; const search_query = current_filter.operands("search")[0];
@@ -316,6 +333,12 @@ export function pick_empty_narrow_banner(current_filter: Filter): NarrowBannerDa
}), }),
}; };
} }
assert(message_lists.current !== undefined);
if (message_lists.current.visibly_empty() && !message_lists.current.empty()) {
// The current message list appears empty, but there are
// messages in muted topics.
return MUTED_TOPICS_IN_CHANNEL_EMPTY_BANNER;
}
// else fallthrough to default case // else fallthrough to default case
break; break;
} }

View File

@@ -2,8 +2,8 @@
const assert = require("node:assert/strict"); const assert = require("node:assert/strict");
const {mock_esm, zrequire} = require("./lib/namespace.cjs"); const {mock_esm, zrequire, set_global} = require("./lib/namespace.cjs");
const {run_test} = require("./lib/test.cjs"); const {run_test, noop} = require("./lib/test.cjs");
const blueslip = require("./lib/zblueslip.cjs"); const blueslip = require("./lib/zblueslip.cjs");
const $ = require("./lib/zjquery.cjs"); const $ = require("./lib/zjquery.cjs");
const {page_params} = require("./lib/zpage_params.cjs"); const {page_params} = require("./lib/zpage_params.cjs");
@@ -21,12 +21,26 @@ const inbox_util = zrequire("inbox_util");
const {set_current_user, set_realm} = zrequire("state_data"); const {set_current_user, set_realm} = zrequire("state_data");
const user_groups = zrequire("user_groups"); const user_groups = zrequire("user_groups");
const {initialize_user_settings} = zrequire("user_settings"); const {initialize_user_settings} = zrequire("user_settings");
const {MessageList} = zrequire("message_list");
const {MessageListData} = zrequire("message_list_data");
set_current_user({}); set_current_user({});
const realm = {}; const realm = {};
set_realm(realm); set_realm(realm);
initialize_user_settings({user_settings: {}}); initialize_user_settings({user_settings: {}});
set_global("document", "document-stub");
const message_lists = mock_esm("../src/message_lists");
function MessageListView() {
return {
maybe_rerender: noop,
append: noop,
prepend: noop,
};
}
mock_esm("../src/message_list_view", {
MessageListView,
});
mock_esm("../src/compose_banner", { mock_esm("../src/compose_banner", {
clear_errors() {}, clear_errors() {},
clear_search_view_banner() {}, clear_search_view_banner() {},
@@ -573,8 +587,28 @@ run_test("show_empty_narrow_message", ({mock_template, override}) => {
}; };
stream_data.add_sub(my_stream); stream_data.add_sub(my_stream);
stream_data.subscribe_myself(my_stream); stream_data.subscribe_myself(my_stream);
current_filter = set_filter([["stream", my_stream_id.toString()]]); current_filter = set_filter([["stream", my_stream_id.toString()]]);
const list = new MessageList({
data: new MessageListData({
excludes_muted_topics: false,
filter: current_filter,
}),
});
message_lists.current = list;
message_lists.current.visibly_empty = () => true;
// There are muted topics in the channel.
message_lists.current.empty = () => false;
narrow_banner.show_empty_narrow_message(current_filter);
assert.equal(
$(".empty_feed_notice_main").html(),
empty_narrow_html(
"translated: You have muted all the topics in this channel.",
'translated HTML: To view a muted topic, click <b>show all topics</b> in the left sidebar, and select one from the list. <a target="_blank" rel="noopener noreferrer" href="/help/mute-a-topic">Learn more</a>',
),
);
// There are no muted topics in the channel.
message_lists.current.empty = () => true;
narrow_banner.show_empty_narrow_message(current_filter); narrow_banner.show_empty_narrow_message(current_filter);
assert.equal( assert.equal(
$(".empty_feed_notice_main").html(), $(".empty_feed_notice_main").html(),
@@ -583,7 +617,7 @@ run_test("show_empty_narrow_message", ({mock_template, override}) => {
'translated HTML: Why not <a href="#" class="empty_feed_compose_stream">start the conversation</a>?', 'translated HTML: Why not <a href="#" class="empty_feed_compose_stream">start the conversation</a>?',
), ),
); );
// The channel does not exist.
current_filter = set_filter([["stream", ""]]); current_filter = set_filter([["stream", ""]]);
narrow_banner.show_empty_narrow_message(current_filter); narrow_banner.show_empty_narrow_message(current_filter);
assert.equal( assert.equal(