recent_topics_ui: Add support to follow topic via recent conversations.

This commit replaces the mute/unmute topic button in the recent
conversations UI with a button that allows the user to set the
visibility_policy of the topic to muted, unmuted, followed or inherit.

The button in the recent conversations UI has an icon corresponding to
the current visibility policy of the topic.

In a muted stream:
A click on the button opens a popover with 'Mute', 'Default', 'Unmute,
and 'Follow' options.

In a not muted stream:
A click on the button opens a popover with 'Mute', 'Default', and
'Follow' option. 'Unmute' option is available only when the
visibility_policy is set to 'Unmute'.

The current visibility_policy of the topic is highlighted
in the popover.

Fixes #25915.
This commit is contained in:
Prakhar Pratyush 2023-07-27 18:27:55 +05:30 committed by Tim Abbott
parent 41697f2663
commit f8f2af5ebe
3 changed files with 52 additions and 5 deletions

View File

@ -405,6 +405,15 @@ function format_conversation(conversation_data) {
context.topic,
);
context.visibility_policy = user_topics.get_topic_visibility_policy(
context.stream_id,
context.topic,
);
// The following two fields are not specific to this context, but this is the
// easiest way we've figured out for passing the data to the template rendering.
context.development = page_params.development_environment;
context.all_visibility_policies = user_topics.all_visibility_policies;
// Since the css for displaying senders in reverse order is much simpler,
// we provide our handlebars with senders in opposite order.
// Display in most recent sender first order.

View File

@ -59,12 +59,30 @@
</div>
<div class="recent_topic_actions">
<div class="recent_topics_focusable hidden-for-spectators">
{{#if stream_muted}}
<i class="zulip-icon zulip-icon-unmute stream_muted {{#if topic_unmuted}}on_hover_topic_mute {{else}}on_hover_topic_unmute {{/if}} recipient_bar_icon tippy-zulip-tooltip" data-stream-id="{{stream_id}}" data-topic-name="{{topic}}" role="button" tabindex="0"
{{#if topic_unmuted}} data-tippy-content="{{t 'Mute topic' }}" aria-label="{{t 'Mute topic' }}" {{else}} data-tippy-content="{{t 'Unmute topic' }}" aria-label="{{t 'Unmute topic' }}" {{/if}} data-tippy-trigger="mouseenter"></i>
{{#if development}}
<span class="change_visibility_policy hidden-for-spectators" data-stream-id="{{stream_id}}" data-topic-name="{{topic}}">
{{#if (eq visibility_policy all_visibility_policies.FOLLOWED)}}
<i class="zulip-icon zulip-icon-follow recipient_bar_icon" data-tippy-content="{{t 'You follow this topic'}}"
role="button" tabindex="0" aria-haspopup="true" aria-label="{{t 'You follow this topic' }}"></i>
{{else if (eq visibility_policy all_visibility_policies.UNMUTED)}}
<i class="zulip-icon zulip-icon-unmute-new recipient_bar_icon" data-tippy-content="{{t 'You have unmuted this topic'}}"
role="button" tabindex="0" aria-haspopup="true" aria-label="{{t 'You have unmuted this topic' }}"></i>
{{else if (eq visibility_policy all_visibility_policies.MUTED)}}
<i class="zulip-icon zulip-icon-mute-new recipient_bar_icon" data-tippy-content="{{t 'You have muted this topic'}}"
role="button" tabindex="0" aria-haspopup="true" aria-label="{{t 'You have muted this topic' }}"></i>
{{else}}
<i class="zulip-icon zulip-icon-inherit recipient_bar_icon" data-tippy-content="{{t 'You will get default notifications for this topic'}}"
role="button" tabindex="0" aria-haspopup="true" aria-label="{{t 'You will get default notifications for this topic' }}"></i>
{{/if}}
</span>
{{else}}
<i class="zulip-icon zulip-icon-mute stream_unmuted {{#if topic_muted}}on_hover_topic_unmute {{else}}on_hover_topic_mute {{/if}} recipient_bar_icon tippy-zulip-tooltip" data-stream-id="{{stream_id}}" data-topic-name="{{topic}}" role="button" tabindex="0"
{{#if topic_muted}} data-tippy-content="{{t 'Unmute topic' }}" aria-label="{{t 'Unmute topic' }}" {{else}} data-tippy-content="{{t 'Mute topic' }}" aria-label="{{t 'Mute topic' }}" {{/if}} data-tippy-trigger="mouseenter"></i>
{{#if stream_muted}}
<i class="zulip-icon zulip-icon-unmute stream_muted {{#if topic_unmuted}}on_hover_topic_mute {{else}}on_hover_topic_unmute {{/if}} recipient_bar_icon tippy-zulip-tooltip" data-stream-id="{{stream_id}}" data-topic-name="{{topic}}" role="button" tabindex="0"
{{#if topic_unmuted}} data-tippy-content="{{t 'Mute topic' }}" aria-label="{{t 'Mute topic' }}" {{else}} data-tippy-content="{{t 'Unmute topic' }}" aria-label="{{t 'Unmute topic' }}" {{/if}} data-tippy-trigger="mouseenter"></i>
{{else}}
<i class="zulip-icon zulip-icon-mute stream_unmuted {{#if topic_muted}}on_hover_topic_unmute {{else}}on_hover_topic_mute {{/if}} recipient_bar_icon tippy-zulip-tooltip" data-stream-id="{{stream_id}}" data-topic-name="{{topic}}" role="button" tabindex="0"
{{#if topic_muted}} data-tippy-content="{{t 'Unmute topic' }}" aria-label="{{t 'Unmute topic' }}" {{else}} data-tippy-content="{{t 'Mute topic' }}" aria-label="{{t 'Mute topic' }}" {{/if}} data-tippy-trigger="mouseenter"></i>
{{/if}}
{{/if}}
</div>
</div>

View File

@ -39,6 +39,13 @@ const topic8 = "topic-8";
const topic9 = "topic-9";
const topic10 = "topic-10";
const all_visibility_policies = {
INHERIT: 0,
MUTED: 1,
UNMUTED: 2,
FOLLOWED: 3,
};
let expected_data_to_replace_in_list_widget;
const ListWidget = mock_esm("../src/list_widget", {
@ -108,6 +115,13 @@ mock_esm("../src/user_topics", {
return false;
},
is_topic_unmuted: () => false,
get_topic_visibility_policy(stream_id, topic) {
if (stream_id === 1 && topic === "topic-7") {
return all_visibility_policies.MUTED;
}
return all_visibility_policies.INHERIT;
},
all_visibility_policies,
});
const narrow = mock_esm("../src/narrow", {
update_narrow_title: noop,
@ -367,6 +381,11 @@ function generate_topic_data(topic_info_array) {
mention_in_unread: false,
topic_muted: muted,
topic_unmuted: false,
visibility_policy: muted
? all_visibility_policies.MUTED
: all_visibility_policies.INHERIT,
development: true,
all_visibility_policies,
});
}
return data;
@ -397,6 +416,7 @@ function stub_out_filter_buttons() {
function test(label, f) {
run_test(label, (helpers) => {
$(".header").css = () => {};
page_params.development_environment = true;
messages = sample_messages.map((message) => ({...message}));
f(helpers);