left_sidebar: Prioritize unmuted topics in non-zoomed topic list.

Created a new function choose_topics that loops through the topics
and push filtered topics using should_show_topic function to items
array if not zoomed else just push all topics directly to array.

If stream is muted and not zoomed call the choose_topics function
twice, first with passing unmuted_topics and second time with passing
remaining topics. else, call it only once with topic_names.

Fixes part of #24243
This commit is contained in:
Hardik Dharmani
2023-04-20 01:29:46 +05:30
committed by Tim Abbott
parent ace3ca80a8
commit 1e1e18d28c
2 changed files with 58 additions and 32 deletions

View File

@@ -3,6 +3,7 @@ import * as resolved_topic from "../shared/src/resolved_topic";
import * as hash_util from "./hash_util"; import * as hash_util from "./hash_util";
import * as narrow_state from "./narrow_state"; import * as narrow_state from "./narrow_state";
import * as stream_topic_history from "./stream_topic_history"; import * as stream_topic_history from "./stream_topic_history";
import * as sub_store from "./sub_store";
import * as unread from "./unread"; import * as unread from "./unread";
import * as user_topics from "./user_topics"; import * as user_topics from "./user_topics";
import * as util from "./util"; import * as util from "./util";
@@ -10,34 +11,17 @@ import * as util from "./util";
const max_topics = 8; const max_topics = 8;
const max_topics_with_unread = 12; const max_topics_with_unread = 12;
export function get_list_info(stream_id, zoomed, search_term) { function choose_topics(stream_id, topic_names, zoomed, topic_choice_state) {
let topics_selected = 0;
let more_topics_unreads = 0;
let more_topics_have_unread_mention_messages = false;
let active_topic = narrow_state.topic();
if (active_topic) {
active_topic = active_topic.toLowerCase();
}
let topic_names = stream_topic_history.get_recent_topic_names(stream_id);
if (zoomed) {
topic_names = util.filter_by_word_prefix_match(topic_names, search_term, (item) => item);
}
const items = [];
const topics_with_unread_mentions = unread.get_topics_with_unread_mentions(stream_id);
for (const [idx, topic_name] of topic_names.entries()) { for (const [idx, topic_name] of topic_names.entries()) {
const num_unread = unread.num_unread_for_topic(stream_id, topic_name); const num_unread = unread.num_unread_for_topic(stream_id, topic_name);
const is_active_topic = active_topic === topic_name.toLowerCase(); const is_active_topic = topic_choice_state.active_topic === topic_name.toLowerCase();
const is_topic_muted = user_topics.is_topic_muted(stream_id, topic_name); const is_topic_muted = user_topics.is_topic_muted(stream_id, topic_name);
const [topic_resolved_prefix, topic_display_name] = const [topic_resolved_prefix, topic_display_name] =
resolved_topic.display_parts(topic_name); resolved_topic.display_parts(topic_name);
// Important: Topics are lower-case in this set. // Important: Topics are lower-case in this set.
const contains_unread_mention = topics_with_unread_mentions.has(topic_name.toLowerCase()); const contains_unread_mention = topic_choice_state.topics_with_unread_mentions.has(
topic_name.toLowerCase(),
);
if (!zoomed) { if (!zoomed) {
function should_show_topic(topics_selected) { function should_show_topic(topics_selected) {
@@ -64,7 +48,7 @@ export function get_list_info(stream_id, zoomed, search_term) {
// We include the most recent max_topics topics, // We include the most recent max_topics topics,
// even if there are no unread messages. // even if there are no unread messages.
if (idx < max_topics) { if (idx < max_topics && topics_selected < max_topics) {
return true; return true;
} }
@@ -81,20 +65,20 @@ export function get_list_info(stream_id, zoomed, search_term) {
return false; return false;
} }
const show_topic = should_show_topic(topics_selected); const show_topic = should_show_topic(topic_choice_state.topics_selected);
if (!show_topic) { if (!show_topic) {
if (!is_topic_muted) { if (!is_topic_muted) {
// The "more topics" unread count, like // The "more topics" unread count, like
// stream-level counts, only counts messages // stream-level counts, only counts messages
// on unmuted topics. // on unmuted topics.
more_topics_unreads += num_unread; topic_choice_state.more_topics_unreads += num_unread;
if (contains_unread_mention) { if (contains_unread_mention) {
more_topics_have_unread_mention_messages = true; topic_choice_state.more_topics_have_unread_mention_messages = true;
} }
} }
continue; continue;
} }
topics_selected += 1; topic_choice_state.topics_selected += 1;
// We fall through to rendering the topic, using the // We fall through to rendering the topic, using the
// same code we do when zoomed. // same code we do when zoomed.
} }
@@ -111,13 +95,46 @@ export function get_list_info(stream_id, zoomed, search_term) {
contains_unread_mention, contains_unread_mention,
}; };
items.push(topic_info); topic_choice_state.items.push(topic_info);
}
}
export function get_list_info(stream_id, zoomed, search_term) {
const topic_choice_state = {
items: [],
topics_selected: 0,
more_topics_unreads: 0,
more_topics_have_unread_mention_messages: false,
active_topic: narrow_state.topic()?.toLowerCase(),
topics_with_unread_mentions: unread.get_topics_with_unread_mentions(stream_id),
};
const stream_muted = sub_store.get(stream_id).is_muted;
let topic_names = stream_topic_history.get_recent_topic_names(stream_id);
if (zoomed) {
topic_names = util.filter_by_word_prefix_match(topic_names, search_term, (item) => item);
}
if (stream_muted && !zoomed) {
const unmuted_topics = topic_names.filter((topic) =>
user_topics.is_topic_unmuted(stream_id, topic),
);
choose_topics(stream_id, unmuted_topics, zoomed, topic_choice_state);
const other_topics = topic_names.filter(
(topic) => !user_topics.is_topic_unmuted(stream_id, topic),
);
choose_topics(stream_id, other_topics, zoomed, topic_choice_state);
} else {
choose_topics(stream_id, topic_names, zoomed, topic_choice_state);
} }
return { return {
items, items: topic_choice_state.items,
num_possible_topics: topic_names.length, num_possible_topics: topic_names.length,
more_topics_unreads, more_topics_unreads: topic_choice_state.more_topics_unreads,
more_topics_have_unread_mention_messages, more_topics_have_unread_mention_messages:
topic_choice_state.more_topics_have_unread_mention_messages,
}; };
} }

View File

@@ -250,6 +250,15 @@ test("get_list_info unreads", ({override}) => {
return topic_name === "topic 4"; return topic_name === "topic 4";
}); });
// muting the stream and unmuting the topic 5
// this should make topic 5 at top in items array
general.is_muted = true;
add_unreads("topic 5", 1);
override(user_topics, "is_topic_unmuted", (stream_id, topic_name) => {
assert.equal(stream_id, general.stream_id);
return topic_name === "topic 5";
});
list_info = get_list_info(); list_info = get_list_info();
assert.equal(list_info.items.length, 12); assert.equal(list_info.items.length, 12);
assert.equal(list_info.more_topics_unreads, 3); assert.equal(list_info.more_topics_unreads, 3);
@@ -259,11 +268,11 @@ test("get_list_info unreads", ({override}) => {
assert.deepEqual( assert.deepEqual(
list_info.items.map((li) => li.topic_name), list_info.items.map((li) => li.topic_name),
[ [
"topic 5",
"topic 0", "topic 0",
"topic 1", "topic 1",
"topic 2", "topic 2",
"topic 3", "topic 3",
"topic 5",
"topic 6", "topic 6",
"topic 7", "topic 7",
"topic 8", "topic 8",