user_topics: Update user_topics.js to include all visibility policies.

Updated user_topics.js to include all visibility policies
rather than just mute/inherit visibility policies.

Replaced muted_topics Map with `all_user_topics` Map which has
structure: {stream_id:{topic_name:{date_updated,visibility_policy}}}.

Removed add_muted_topic, remove_muted_topic functions which were
adding/removing topics in muted_topics Map. Added new function
update_user_topics which take parameter stream_id, topic,
visibility_policy, and date_updated(optional) which adds a topic
to all_user_topics with date_updated and visibility_policy,
if visibility_policy is not equal to inherit.
else, removes topic from all_user_topics.

Added get_topic_visibility_policy which returns visibility_policy
if stream_id is not undefined else return false.

Added 2 helper functions is_topic_muted and is_topic_unmuted which
uses get_topic_visibility_policy and return true if topic is
muted and unmuted respectively else return false.

Replaced switch case statement which was using add_muted_topic
and remove_muted_topic functions in set_user_topic with new function
update_user_topics.

Fixes #24244
This commit is contained in:
Hardik Dharmani
2023-04-11 11:18:13 +05:30
committed by Tim Abbott
parent 46cabdd59e
commit aab252f657
6 changed files with 98 additions and 50 deletions

View File

@@ -10,7 +10,7 @@ import * as stream_data from "./stream_data";
import * as timerender from "./timerender"; import * as timerender from "./timerender";
import {get_time_from_date_muted} from "./util"; import {get_time_from_date_muted} from "./util";
const muted_topics = new Map(); const all_user_topics = new Map();
export const all_visibility_policies = { export const all_visibility_policies = {
INHERIT: 0, INHERIT: 0,
@@ -19,45 +19,56 @@ export const all_visibility_policies = {
FOLLOWED: 3, FOLLOWED: 3,
}; };
export function add_muted_topic(stream_id, topic, date_muted) { export function update_user_topics(stream_id, topic, visibility_policy, date_updated) {
let sub_dict = muted_topics.get(stream_id); let sub_dict = all_user_topics.get(stream_id);
if (!sub_dict) { if (visibility_policy === all_visibility_policies.INHERIT && sub_dict) {
sub_dict = new FoldDict();
muted_topics.set(stream_id, sub_dict);
}
const time = get_time_from_date_muted(date_muted);
sub_dict.set(topic, time);
}
export function remove_muted_topic(stream_id, topic) {
const sub_dict = muted_topics.get(stream_id);
if (sub_dict) {
sub_dict.delete(topic); sub_dict.delete(topic);
} else {
if (!sub_dict) {
sub_dict = new FoldDict();
all_user_topics.set(stream_id, sub_dict);
}
const time = get_time_from_date_muted(date_updated);
sub_dict.set(topic, {date_updated: time, visibility_policy});
} }
} }
export function is_topic_muted(stream_id, topic) { export function get_topic_visibility_policy(stream_id, topic) {
if (stream_id === undefined) { if (stream_id === undefined) {
return false; return false;
} }
const sub_dict = muted_topics.get(stream_id); const sub_dict = all_user_topics.get(stream_id);
return (sub_dict && sub_dict.get(topic)) || false; if (sub_dict && sub_dict.get(topic)) {
return sub_dict.get(topic).visibility_policy;
}
return all_visibility_policies.INHERIT;
}
export function is_topic_unmuted(stream_id, topic) {
return get_topic_visibility_policy(stream_id, topic) === all_visibility_policies.UNMUTED;
}
export function is_topic_muted(stream_id, topic) {
return get_topic_visibility_policy(stream_id, topic) === all_visibility_policies.MUTED;
} }
export function get_muted_topics() { export function get_muted_topics() {
const topics = []; const topics = [];
for (const [stream_id, sub_dict] of muted_topics) { for (const [stream_id, sub_dict] of all_user_topics) {
const stream = stream_data.maybe_get_stream_name(stream_id); const stream = stream_data.maybe_get_stream_name(stream_id);
for (const topic of sub_dict.keys()) { for (const topic of sub_dict.keys()) {
const date_muted = sub_dict.get(topic); if (sub_dict.get(topic).visibility_policy === all_visibility_policies.MUTED) {
const date_muted_str = timerender.render_now(new Date(date_muted)).time_str; const date_muted = sub_dict.get(topic).date_updated;
topics.push({ const date_muted_str = timerender.render_now(new Date(date_muted)).time_str;
stream_id, topics.push({
stream, stream_id,
topic, stream,
date_muted, topic,
date_muted_str, date_muted,
}); date_muted_str,
});
}
} }
} }
return topics; return topics;
@@ -114,7 +125,7 @@ export function set_user_topic_visibility_policy(stream_id, topic, visibility_po
export function set_user_topic(user_topic) { export function set_user_topic(user_topic) {
const stream_id = user_topic.stream_id; const stream_id = user_topic.stream_id;
const topic = user_topic.topic_name; const topic = user_topic.topic_name;
const date_muted = user_topic.last_updated; const date_updated = user_topic.last_updated;
const stream_name = stream_data.maybe_get_stream_name(stream_id); const stream_name = stream_data.maybe_get_stream_name(stream_id);
@@ -123,18 +134,11 @@ export function set_user_topic(user_topic) {
return; return;
} }
switch (user_topic.visibility_policy) { update_user_topics(stream_id, topic, user_topic.visibility_policy, date_updated);
case visibility_policy.MUTED:
add_muted_topic(stream_id, topic, date_muted);
break;
case visibility_policy.INHERIT:
remove_muted_topic(stream_id, topic);
break;
}
} }
export function set_user_topics(user_topics) { export function set_user_topics(user_topics) {
muted_topics.clear(); all_user_topics.clear();
for (const user_topic of user_topics) { for (const user_topic of user_topics) {
set_user_topic(user_topic); set_user_topic(user_topic);

View File

@@ -143,7 +143,7 @@ run_test("muting", () => {
{id: 9, type: "private", to_user_ids: "9", sender_id: 11}, // 1:1 PM to non-muted {id: 9, type: "private", to_user_ids: "9", sender_id: 11}, // 1:1 PM to non-muted
]; ];
user_topics.add_muted_topic(1, "muted"); user_topics.update_user_topics(1, "muted", user_topics.all_visibility_policies.MUTED);
muted_users.add_muted_user(10); muted_users.add_muted_user(10);
// `messages_filtered_for_topic_mutes` should skip filtering // `messages_filtered_for_topic_mutes` should skip filtering

View File

@@ -47,7 +47,11 @@ const muted = {
stream_data.add_sub(general); stream_data.add_sub(general);
stream_data.add_sub(muted); stream_data.add_sub(muted);
user_topics.add_muted_topic(general.stream_id, "muted topic"); user_topics.update_user_topics(
general.stream_id,
"muted topic",
user_topics.all_visibility_policies.MUTED,
);
function test(label, f) { function test(label, f) {
run_test(label, (helpers) => { run_test(label, (helpers) => {

View File

@@ -21,7 +21,12 @@ const frontend = {
stream_data.add_sub(frontend); stream_data.add_sub(frontend);
run_test("settings", ({override}) => { run_test("settings", ({override}) => {
user_topics.add_muted_topic(frontend.stream_id, "js", 1577836800); user_topics.update_user_topics(
frontend.stream_id,
"js",
user_topics.all_visibility_policies.MUTED,
1577836800,
);
let populate_list_called = false; let populate_list_called = false;
override(list_widget, "create", ($container, list) => { override(list_widget, "create", ($container, list) => {
assert.deepEqual(list, [ assert.deepEqual(list, [

View File

@@ -233,7 +233,11 @@ test("muting", () => {
assert.deepEqual(unread.get_msg_ids_for_stream(stream_id), [message.id]); assert.deepEqual(unread.get_msg_ids_for_stream(stream_id), [message.id]);
test_notifiable_count(counts.home_unread_messages, 0); test_notifiable_count(counts.home_unread_messages, 0);
user_topics.add_muted_topic(social.stream_id, "test_muting"); user_topics.update_user_topics(
social.stream_id,
"test_muting",
user_topics.all_visibility_policies.MUTED,
);
counts = unread.get_counts(); counts = unread.get_counts();
assert.equal(counts.stream_count.get(stream_id), 0); assert.equal(counts.stream_count.get(stream_id), 0);
assert.equal(counts.home_unread_messages, 0); assert.equal(counts.home_unread_messages, 0);
@@ -470,7 +474,7 @@ test("mentions", () => {
const muted_stream_id = 401; const muted_stream_id = 401;
user_topics.add_muted_topic(401, "lunch"); user_topics.update_user_topics(401, "lunch", user_topics.all_visibility_policies.MUTED);
const already_read_message = { const already_read_message = {
id: 14, id: 14,
@@ -593,7 +597,7 @@ test("mention updates", () => {
test("stream_has_any_unread_mentions", () => { test("stream_has_any_unread_mentions", () => {
const muted_stream_id = 401; const muted_stream_id = 401;
user_topics.add_muted_topic(401, "lunch"); user_topics.update_user_topics(401, "lunch", user_topics.all_visibility_policies.MUTED);
const mention_me_message = { const mention_me_message = {
id: 15, id: 15,

View File

@@ -56,29 +56,60 @@ test("edge_cases", () => {
test("add_and_remove_mutes", () => { test("add_and_remove_mutes", () => {
assert.ok(!user_topics.is_topic_muted(devel.stream_id, "java")); assert.ok(!user_topics.is_topic_muted(devel.stream_id, "java"));
user_topics.add_muted_topic(devel.stream_id, "java"); user_topics.update_user_topics(devel.stream_id, "java", all_visibility_policies.MUTED);
assert.ok(user_topics.is_topic_muted(devel.stream_id, "java")); assert.ok(user_topics.is_topic_muted(devel.stream_id, "java"));
// test idempotency // test idempotency
user_topics.add_muted_topic(devel.stream_id, "java"); user_topics.update_user_topics(devel.stream_id, "java", all_visibility_policies.MUTED);
assert.ok(user_topics.is_topic_muted(devel.stream_id, "java")); assert.ok(user_topics.is_topic_muted(devel.stream_id, "java"));
user_topics.remove_muted_topic(devel.stream_id, "java"); user_topics.update_user_topics(devel.stream_id, "java", all_visibility_policies.INHERIT);
assert.ok(!user_topics.is_topic_muted(devel.stream_id, "java")); assert.ok(!user_topics.is_topic_muted(devel.stream_id, "java"));
// test idempotency // test idempotency
user_topics.remove_muted_topic(devel.stream_id, "java"); user_topics.update_user_topics(devel.stream_id, "java", all_visibility_policies.INHERIT);
assert.ok(!user_topics.is_topic_muted(devel.stream_id, "java")); assert.ok(!user_topics.is_topic_muted(devel.stream_id, "java"));
// test unknown stream is harmless too // test unknown stream is harmless too
user_topics.remove_muted_topic(unknown.stream_id, "java"); user_topics.update_user_topics(unknown.stream_id, "java", all_visibility_policies.INHERIT);
assert.ok(!user_topics.is_topic_muted(unknown.stream_id, "java")); assert.ok(!user_topics.is_topic_muted(unknown.stream_id, "java"));
}); });
test("add_and_remove_unmutes", () => {
assert.ok(!user_topics.is_topic_unmuted(devel.stream_id, "java"));
user_topics.update_user_topics(devel.stream_id, "java", all_visibility_policies.UNMUTED);
assert.ok(user_topics.is_topic_unmuted(devel.stream_id, "java"));
// test idempotency
user_topics.update_user_topics(devel.stream_id, "java", all_visibility_policies.UNMUTED);
assert.ok(user_topics.is_topic_unmuted(devel.stream_id, "java"));
user_topics.update_user_topics(devel.stream_id, "java", all_visibility_policies.INHERIT);
assert.ok(!user_topics.is_topic_unmuted(devel.stream_id, "java"));
// test idempotency
user_topics.update_user_topics(devel.stream_id, "java", all_visibility_policies.INHERIT);
assert.ok(!user_topics.is_topic_unmuted(devel.stream_id, "java"));
// test unknown stream is harmless too
user_topics.update_user_topics(unknown.stream_id, "java", all_visibility_policies.INHERIT);
assert.ok(!user_topics.is_topic_unmuted(unknown.stream_id, "java"));
});
test("get_mutes", () => { test("get_mutes", () => {
assert.deepEqual(user_topics.get_muted_topics(), []); assert.deepEqual(user_topics.get_muted_topics(), []);
user_topics.add_muted_topic(office.stream_id, "gossip", 1577836800); user_topics.update_user_topics(
user_topics.add_muted_topic(devel.stream_id, "java", 1577836700); office.stream_id,
"gossip",
all_visibility_policies.MUTED,
1577836800,
);
user_topics.update_user_topics(
devel.stream_id,
"java",
all_visibility_policies.MUTED,
1577836700,
);
const all_muted_topics = user_topics const all_muted_topics = user_topics
.get_muted_topics() .get_muted_topics()
.sort((a, b) => a.date_muted - b.date_muted); .sort((a, b) => a.date_muted - b.date_muted);