message_view: Add support for unmuting of topic from its recipient bar.

Earlier, a user can only mute a topic from its recipient bar but can't
unmute it from there (and in fact we displayed an option to mute even
if the topic was already muted!). This commit fixes that bug and
allows a user also to unmute the topic from its recipient bar.

There are two core issues here;
* We did not have code, an icon, etc. for the "already muted" case in
  the recipient bar logic at all.
* We did not rerender messages in !excludes_muted_topics views when
  muting state changed.

See: 660475bd0c for background on when
we started only rerendering the streams with excludes_muted_topics
after muting changes.  Rerendering of newly muted topics are important
for live rendering if a user is narrowed to that topic itself, which
are essentially all excludes_muted_topics narrows anyway.

Hence, now, we rerender by calling the `rerender` function for muted
topics (which is done just before we update the items for muting via
the function: `update_items_for_topic_muting`).

Tweaked by tabbott to add comments explaining the reasoning and
long-term plans.

Fixes #15223.
This commit is contained in:
akshatdalton
2021-04-30 05:44:43 +00:00
committed by Tim Abbott
parent dd0e7bcb2e
commit bf41f455cd
7 changed files with 48 additions and 8 deletions

View File

@@ -382,6 +382,11 @@ export function initialize() {
mute_or_unmute_topic($(e.target), true);
});
$("body").on("click", ".message_header .on_hover_topic_unmute", (e) => {
e.stopPropagation();
mute_or_unmute_topic($(e.target), false);
});
// RECENT TOPICS
$("body").on("keydown", ".on_hover_topic_mute", ui_util.convert_enter_to_click);

View File

@@ -414,6 +414,13 @@ export function update_messages(events) {
message_lists.home.update_topic_muting_and_rerender();
// However, we don't need to rerender message_list.narrowed if
// we just changed the narrow earlier in this function.
//
// TODO: We can potentially optimize this logic to avoid
// calling `update_topic_muting_and_rerender` if the muted
// messages would not match the view before or after this
// edit. Doing so could save significant work, since most
// topic edits will not match the current topic narrow in
// large organizations.
if (!changed_narrow && message_lists.current === message_list.narrowed) {
message_list.narrowed.update_topic_muting_and_rerender();
}

View File

@@ -385,9 +385,17 @@ export class MessageList {
update_topic_muting_and_rerender() {
this.data.update_items_for_topic_muting();
if (this.data.excludes_muted_topics) {
this.rerender();
}
// We need to rerender whether or not the narrow hides muted
// topics, because we need to update recipient bars for topics
// we've muted when we are displaying those topics.
//
// We could avoid a rerender if we can provide that this
// narrow cannot have contained messages to muted topics
// either before or after the state change. The right place
// to do this is in the message_events.js code path for
// processing topic edits, since that's the only place we'll
// call this frequently anyway.
this.rerender();
}
all_messages() {

View File

@@ -19,6 +19,7 @@ import * as message_edit from "./message_edit";
import * as message_lists from "./message_lists";
import * as message_store from "./message_store";
import * as message_viewport from "./message_viewport";
import * as muting from "./muting";
import * as narrow_state from "./narrow_state";
import {page_params} from "./page_params";
import * as people from "./people";
@@ -158,6 +159,7 @@ function populate_group_from_message_container(group, message_container) {
} else {
group.stream_id = sub.stream_id;
}
group.topic_muted = muting.is_topic_muted(group.stream_id, group.topic);
} else if (group.is_private) {
group.pm_with_url = message_container.pm_with_url;
group.display_reply_to = message_store.get_pm_full_names(message_container.msg);

View File

@@ -36,7 +36,7 @@ export function is_topic_muted(stream_id, topic) {
return false;
}
const sub_dict = muted_topics.get(stream_id);
return sub_dict && sub_dict.get(topic);
return (sub_dict && sub_dict.get(topic)) || false;
}
export function get_muted_topics() {

View File

@@ -1311,7 +1311,6 @@ td.pointer {
}
.on_hover_topic_edit,
.on_hover_topic_mute,
.on_hover_topic_read {
opacity: 0.2;
}
@@ -1320,10 +1319,25 @@ td.pointer {
opacity: 0.7;
}
.on_hover_topic_unmute {
opacity: 0.7;
&:hover {
cursor: pointer;
opacity: 1;
}
}
.on_hover_topic_mute {
opacity: 0.2;
&:hover {
cursor: pointer;
opacity: 0.7;
}
}
.on_hover_topic_edit,
.always_visible_topic_edit,
.on_hover_topic_mute,
.on_hover_topic_unmute,
.on_hover_topic_read {
&:hover {
cursor: pointer;

View File

@@ -50,7 +50,11 @@
<span class="topic_edit_form" id="{{id}}"></span>
</span>
<i class="fa fa-bell-slash on_hover_topic_mute recipient_bar_icon" data-stream-id="{{stream_id}}" data-topic-name="{{topic}}" title="{{t 'Mute topic' }} (M)" role="button" tabindex="0" aria-label="{{t 'Mute topic' }} (M)"></i>
{{#if topic_muted}}
<i class="fa fa-bell-slash on_hover_topic_unmute recipient_bar_icon" data-stream-id="{{stream_id}}" data-topic-name="{{topic}}" title="{{t 'Unmute topic' }} (M)" role="button" tabindex="0" aria-label="{{t 'Unmute topic' }}"></i>
{{else}}
<i class="fa fa-bell-slash on_hover_topic_mute recipient_bar_icon" data-stream-id="{{stream_id}}" data-topic-name="{{topic}}" title="{{t 'Mute topic' }} (M)" role="button" tabindex="0" aria-label="{{t 'Mute topic' }}"></i>
{{/if}}
</span>
<span class="recipient_row_date {{#if group_date_divider_html}}{{else}}hide-date{{/if}}">{{{date}}}</span>
</div>