From 1de9444242950d0f54e1e554aeb6e400ef8ad474 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Bodas Date: Sat, 27 Mar 2021 17:12:16 +0530 Subject: [PATCH] mute user: Add frontend functions to maintain data. Muted users are stored in a map with key as user ID and the value as the timestamp of muting. Names can be easily fetched from existing functions in `people.js` and hence not stored. --- frontend_tests/node_tests/dispatch.js | 11 +++++ frontend_tests/node_tests/lib/events.js | 14 +++++++ frontend_tests/node_tests/muting.js | 56 ++++++++++++++++++++++++- static/js/muting.js | 46 ++++++++++++++++++++ static/js/muting_ui.js | 4 ++ static/js/server_events_dispatch.js | 4 ++ 6 files changed, 133 insertions(+), 2 deletions(-) diff --git a/frontend_tests/node_tests/dispatch.js b/frontend_tests/node_tests/dispatch.js index f4c02ff127..9a9bcded80 100644 --- a/frontend_tests/node_tests/dispatch.js +++ b/frontend_tests/node_tests/dispatch.js @@ -239,6 +239,17 @@ run_test("muted_topics", (override) => { assert_same(args.muted_topics, event.muted_topics); }); +run_test("muted_users", (override) => { + const event = event_fixtures.muted_users; + + const stub = make_stub(); + override(muting_ui, "handle_user_updates", stub.f); + dispatch(event); + assert.equal(stub.num_calls, 1); + const args = stub.get_args("muted_users"); + assert_same(args.muted_users, event.muted_users); +}); + run_test("presence", (override) => { const event = event_fixtures.presence; diff --git a/frontend_tests/node_tests/lib/events.js b/frontend_tests/node_tests/lib/events.js index cbde31bdd0..0343efe04d 100644 --- a/frontend_tests/node_tests/lib/events.js +++ b/frontend_tests/node_tests/lib/events.js @@ -167,6 +167,20 @@ exports.fixtures = { ], }, + muted_users: { + type: "muted_users", + muted_users: [ + { + id: 5, + timestamp: fake_then, + }, + { + id: 23, + timestamp: fake_now, + }, + ], + }, + presence: { type: "presence", email: "alice@example.com", diff --git a/frontend_tests/node_tests/muting.js b/frontend_tests/node_tests/muting.js index c43889dce1..2cd389ae09 100644 --- a/frontend_tests/node_tests/muting.js +++ b/frontend_tests/node_tests/muting.js @@ -50,9 +50,12 @@ function test(label, f) { test("edge_cases", () => { // private messages assert(!muting.is_topic_muted(undefined, undefined)); + + // invalid user + assert(!muting.is_user_muted(undefined)); }); -test("basics", () => { +test("add_and_remove_mutes", () => { assert(!muting.is_topic_muted(devel.stream_id, "java")); muting.add_muted_topic(devel.stream_id, "java"); assert(muting.is_topic_muted(devel.stream_id, "java")); @@ -71,9 +74,24 @@ test("basics", () => { // test unknown stream is harmless too muting.remove_muted_topic(unknown.stream_id, "java"); assert(!muting.is_topic_muted(unknown.stream_id, "java")); + + assert(!muting.is_user_muted(1)); + muting.add_muted_user(1); + assert(muting.is_user_muted(1)); + + // test idempotentcy + muting.add_muted_user(1); + assert(muting.is_user_muted(1)); + + muting.remove_muted_user(1); + assert(!muting.is_user_muted(1)); + + // test idempotentcy + muting.remove_muted_user(1); + assert(!muting.is_user_muted(1)); }); -test("basics", () => { +test("get_mutes", () => { assert.deepEqual(muting.get_muted_topics(), []); muting.add_muted_topic(office.stream_id, "gossip", 1577836800); muting.add_muted_topic(devel.stream_id, "java", 1577836700); @@ -95,6 +113,23 @@ test("basics", () => { topic: "gossip", }, ]); + + assert.deepEqual(muting.get_muted_users(), []); + muting.add_muted_user(6, 1577836800); + muting.add_muted_user(4, 1577836800); + const muted_users = muting.get_muted_users().sort((a, b) => a.date_muted - b.date_muted); + assert.deepEqual(muted_users, [ + { + date_muted: 1577836800000, + date_muted_str: "Jan\u00A001,\u00A02020", + id: 6, + }, + { + date_muted: 1577836800000, + date_muted_str: "Jan\u00A001,\u00A02020", + id: 4, + }, + ]); }); test("unknown streams", () => { @@ -105,6 +140,10 @@ test("unknown streams", () => { ["design", "typography", 1577836800], ["BOGUS STREAM", "whatever", 1577836800], ]; + page_params.muted_users = [ + {id: 3, timestamp: 1577836800}, + {id: 2, timestamp: 1577836800}, + ]; muting.initialize(); assert.deepEqual(muting.get_muted_topics().sort(), [ @@ -123,6 +162,19 @@ test("unknown streams", () => { topic: "typography", }, ]); + + assert.deepEqual(muting.get_muted_users().sort(), [ + { + date_muted: 1577836800000, + date_muted_str: "Jan\u00A001,\u00A02020", + id: 3, + }, + { + date_muted: 1577836800000, + date_muted_str: "Jan\u00A001,\u00A02020", + id: 2, + }, + ]); }); test("case_insensitivity", () => { diff --git a/static/js/muting.js b/static/js/muting.js index a5e3eb03b6..334e6f0942 100644 --- a/static/js/muting.js +++ b/static/js/muting.js @@ -5,6 +5,7 @@ import * as stream_data from "./stream_data"; import * as timerender from "./timerender"; const muted_topics = new Map(); +const muted_users = new Map(); function get_time_from_date_muted(date_muted) { if (date_muted === undefined) { @@ -76,6 +77,51 @@ export function set_muted_topics(tuples) { } } +export function add_muted_user(user_id, date_muted) { + const time = get_time_from_date_muted(date_muted); + if (user_id) { + muted_users.set(user_id, time); + } +} + +export function remove_muted_user(user_id) { + if (user_id) { + muted_users.delete(user_id); + } +} + +export function is_user_muted(user_id) { + if (user_id === undefined) { + return false; + } + + return muted_users.has(user_id); +} + +export function get_muted_users() { + const users = []; + for (const [id, date_muted] of muted_users) { + const date_muted_str = timerender.render_now(new Date(date_muted)).time_str; + users.push({ + id, + date_muted, + date_muted_str, + }); + } + return users; +} + +export function set_muted_users(list) { + muted_users.clear(); + + for (const user of list) { + if (user !== undefined && user.id !== undefined) { + add_muted_user(user.id, user.timestamp); + } + } +} + export function initialize() { set_muted_topics(page_params.muted_topics); + set_muted_users(page_params.muted_users); } diff --git a/static/js/muting_ui.js b/static/js/muting_ui.js index b5d88967c1..97ca8cab11 100644 --- a/static/js/muting_ui.js +++ b/static/js/muting_ui.js @@ -157,3 +157,7 @@ export function toggle_topic_mute(message) { mute_topic(stream_id, topic); } } + +export function handle_user_updates(muted_user_ids) { + muting.set_muted_users(muted_user_ids); +} diff --git a/static/js/server_events_dispatch.js b/static/js/server_events_dispatch.js index 9548a3875c..73d7441b94 100644 --- a/static/js/server_events_dispatch.js +++ b/static/js/server_events_dispatch.js @@ -133,6 +133,10 @@ export function dispatch_normal_event(event) { muting_ui.handle_topic_updates(event.muted_topics); break; + case "muted_users": + muting_ui.handle_user_updates(event.muted_users); + break; + case "presence": activity.update_presence_info(event.user_id, event.presence, event.server_timestamp); break;