diff --git a/web/src/message_events.js b/web/src/message_events.js index 21c83ec49c..2c7b7e9e2d 100644 --- a/web/src/message_events.js +++ b/web/src/message_events.js @@ -47,6 +47,34 @@ function filter_has_term_type(filter, term_type) { ); } +export function discard_cached_lists_with_term_type(term_type) { + // Discards cached MessageList and MessageListData which have + // `term_type` and `not-term_type`. + assert(!term_type.includes("not-")); + + // We loop over rendered message lists and cached message data separately since + // they are separately maintained and can have different items. + for (const msg_list of message_lists.all_rendered_message_lists()) { + // We never want to discard the current message list. + if (msg_list === message_lists.current) { + continue; + } + + const filter = msg_list.data.filter; + if (filter_has_term_type(filter, term_type)) { + message_lists.delete_message_list(msg_list); + message_list_data_cache.remove(filter); + } + } + + for (const msg_list_data of message_lists.non_rendered_data()) { + const filter = msg_list_data.filter; + if (filter_has_term_type(filter, term_type)) { + message_list_data_cache.remove(filter); + } + } +} + export function update_current_view_for_topic_visibility() { // If we have rendered message list / cached data based on topic // visibility policy, we need to rerender it to reflect the changes. It diff --git a/web/src/message_lists.ts b/web/src/message_lists.ts index 6e06ea5bd5..a8c8f8c69e 100644 --- a/web/src/message_lists.ts +++ b/web/src/message_lists.ts @@ -15,7 +15,7 @@ export function set_current(msg_list: MessageList | undefined): void { current = msg_list; } -function delete_message_list(message_list: MessageList): void { +export function delete_message_list(message_list: MessageList): void { message_list.view.$list.remove(); rendered_message_lists.delete(message_list.id); message_list.data.set_rendered_message_list_id(undefined); diff --git a/web/src/server_events_dispatch.js b/web/src/server_events_dispatch.js index 920581967d..7f99f99a1d 100644 --- a/web/src/server_events_dispatch.js +++ b/web/src/server_events_dispatch.js @@ -90,6 +90,7 @@ import * as user_group_edit from "./user_group_edit"; import * as user_groups from "./user_groups"; import {user_settings} from "./user_settings"; import * as user_status from "./user_status"; +import * as user_topics from "./user_topics"; import * as user_topics_ui from "./user_topics_ui"; export function dispatch_normal_event(event) { @@ -1017,11 +1018,23 @@ export function dispatch_normal_event(event) { } break; - case "user_topic": + case "user_topic": { + const previous_topic_visibility = user_topics.get_topic_visibility_policy( + event.stream_id, + event.topic_name, + ); user_topics_ui.handle_topic_updates( event, message_events.update_current_view_for_topic_visibility(), ); + // Discard cached message lists if `event` topic was / is followed. + if ( + event.visibility_policy === user_topics.all_visibility_policies.FOLLOWED || + previous_topic_visibility === user_topics.all_visibility_policies.FOLLOWED + ) { + message_events.discard_cached_lists_with_term_type("is-followed"); + } break; + } } } diff --git a/web/tests/dispatch.test.js b/web/tests/dispatch.test.js index e22dd1f73a..3b2d8b9cc0 100644 --- a/web/tests/dispatch.test.js +++ b/web/tests/dispatch.test.js @@ -379,6 +379,20 @@ run_test("muted_topics", ({override}) => { assert_same(args.user_topic, event); }); +run_test("followed_topic", ({override}) => { + const event = event_fixtures.user_topic_with_followed_policy_change; + + const stub = make_stub(); + const discard_msg_list_stub = make_stub(); + override(user_topics_ui, "handle_topic_updates", stub.f); + override(message_events, "discard_cached_lists_with_term_type", discard_msg_list_stub.f); + dispatch(event); + assert.equal(stub.num_calls, 1); + assert.equal(discard_msg_list_stub.num_calls, 1); + const args = stub.get_args("user_topic"); + assert_same(args.user_topic, event); +}); + run_test("muted_users", ({override}) => { const event = event_fixtures.muted_users; diff --git a/web/tests/lib/events.js b/web/tests/lib/events.js index a395dc89ab..2b47162242 100644 --- a/web/tests/lib/events.js +++ b/web/tests/lib/events.js @@ -1164,6 +1164,14 @@ exports.fixtures = { visibility_policy: 1, }, + user_topic_with_followed_policy_change: { + type: "user_topic", + stream_id: 101, + topic_name: "js", + last_updated: fake_now, + visibility_policy: 3, + }, + web_reload_client: { type: "web_reload_client", immediate: true,