mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 04:52:12 +00:00
mentions: Warn on non-silent group mentions with unsubscribed members.
Add a warning banner when a user mentions a group (non-silent) where none of the members are subscribed to the current stream. The banner informs the user that the mention won't notify anyone. Fixes #33545.
This commit is contained in:
@@ -42,6 +42,7 @@ export const CLASSNAMES = {
|
||||
// warnings
|
||||
topic_resolved: "topic_resolved",
|
||||
recipient_not_subscribed: "recipient_not_subscribed",
|
||||
group_entirely_not_subscribed: "group_entirely_not_subscribed",
|
||||
wildcard_warning: "wildcard_warning",
|
||||
private_stream_warning: "private_stream_warning",
|
||||
guest_in_dm_recipient_warning: "guest_in_dm_recipient_warning",
|
||||
|
@@ -3,6 +3,7 @@ import _ from "lodash";
|
||||
|
||||
import * as resolved_topic from "../shared/src/resolved_topic.ts";
|
||||
import render_compose_banner from "../templates/compose_banner/compose_banner.hbs";
|
||||
import render_compose_mention_group_warning from "../templates/compose_banner/compose_mention_group_warning.hbs";
|
||||
import render_guest_in_dm_recipient_warning from "../templates/compose_banner/guest_in_dm_recipient_warning.hbs";
|
||||
import render_not_subscribed_warning from "../templates/compose_banner/not_subscribed_warning.hbs";
|
||||
import render_private_stream_warning from "../templates/compose_banner/private_stream_warning.hbs";
|
||||
@@ -28,7 +29,9 @@ import * as stream_data from "./stream_data.ts";
|
||||
import * as sub_store from "./sub_store.ts";
|
||||
import type {StreamSubscription} from "./sub_store.ts";
|
||||
import type {UserOrMention} from "./typeahead_helper.ts";
|
||||
import {toggle_user_group_info_popover} from "./user_group_popover.ts";
|
||||
import * as user_groups from "./user_groups.ts";
|
||||
import type {UserGroup} from "./user_groups.ts";
|
||||
import * as util from "./util.ts";
|
||||
|
||||
let user_acknowledged_stream_wildcard = false;
|
||||
@@ -341,7 +344,59 @@ export function warn_if_mentioning_unsubscribed_user(
|
||||
}
|
||||
}
|
||||
}
|
||||
export function warn_if_mentioning_unsubscribed_group(
|
||||
mentioned_group: UserGroup,
|
||||
$textarea: JQuery<HTMLTextAreaElement>,
|
||||
is_silent: boolean,
|
||||
): void {
|
||||
if (is_silent) {
|
||||
return;
|
||||
}
|
||||
|
||||
const stream_id = get_stream_id_for_textarea($textarea);
|
||||
if (!stream_id) {
|
||||
// One could imagine doing something with DMs here, but given
|
||||
// all DMs are given the same notification prevalence as
|
||||
// mentions, it doesn't seem useful.
|
||||
return;
|
||||
}
|
||||
|
||||
const group_members = user_groups.get_recursive_group_members(mentioned_group);
|
||||
let any_member_subscribed = false;
|
||||
for (const user_id of group_members) {
|
||||
if (
|
||||
stream_data.is_user_subscribed(stream_id, user_id) &&
|
||||
people.is_person_active(user_id)
|
||||
) {
|
||||
any_member_subscribed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (any_member_subscribed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const $banner_container = compose_banner.get_compose_banner_container($textarea);
|
||||
if (
|
||||
$banner_container.find(
|
||||
`.${CSS.escape(compose_banner.CLASSNAMES.group_entirely_not_subscribed)}`,
|
||||
).length > 0
|
||||
) {
|
||||
// Don't add a second banner if one is already present.
|
||||
// TODO: This should work like warn_if_mentioning_unsubscribed_user,
|
||||
// where we actually check if it's the same group.
|
||||
return;
|
||||
}
|
||||
|
||||
const context = {
|
||||
group_id: mentioned_group.id,
|
||||
group_name: mentioned_group.name,
|
||||
banner_type: compose_banner.WARNING,
|
||||
classname: compose_banner.CLASSNAMES.group_entirely_not_subscribed,
|
||||
};
|
||||
const new_row_html = render_compose_mention_group_warning(context);
|
||||
compose_banner.append_compose_banner_to_banner_list($(new_row_html), $banner_container);
|
||||
}
|
||||
// Called when clearing the compose box and similar contexts to clear
|
||||
// the warning for composing to a resolved topic, if present. Also clears
|
||||
// the state for whether this warning has already been shown in the
|
||||
@@ -983,3 +1038,15 @@ export function convert_mentions_to_silent_in_direct_messages(
|
||||
const silent_mention_text = people.get_mention_syntax(full_name, user_id, true);
|
||||
return silent_mention_text;
|
||||
}
|
||||
|
||||
export function initialize(): void {
|
||||
$("body").on(
|
||||
"click",
|
||||
".view_user_group_mention",
|
||||
function (this: HTMLElement, e: JQuery.ClickEvent) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
toggle_user_group_info_popover(this, undefined);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@@ -1181,6 +1181,11 @@ export function content_typeahead_selected(
|
||||
let user_group_mention_text = is_silent ? "@_*" : "@*";
|
||||
user_group_mention_text += item.name + "* ";
|
||||
beginning += user_group_mention_text;
|
||||
compose_validate.warn_if_mentioning_unsubscribed_group(
|
||||
item,
|
||||
$textbox,
|
||||
is_silent ?? false,
|
||||
);
|
||||
// We could theoretically warn folks if they are
|
||||
// mentioning a user group that literally has zero
|
||||
// members where we are posting to, but we don't have
|
||||
|
@@ -34,6 +34,7 @@ import * as compose_send_menu_popover from "./compose_send_menu_popover.js";
|
||||
import * as compose_setup from "./compose_setup.js";
|
||||
import * as compose_textarea from "./compose_textarea.ts";
|
||||
import * as compose_tooltips from "./compose_tooltips.ts";
|
||||
import * as compose_validate from "./compose_validate.ts";
|
||||
import * as composebox_typeahead from "./composebox_typeahead.ts";
|
||||
import * as condense from "./condense.ts";
|
||||
import * as desktop_integration from "./desktop_integration.ts";
|
||||
@@ -603,6 +604,7 @@ export function initialize_everything(state_data) {
|
||||
composebox_typeahead.initialize({
|
||||
on_enter_send: compose.finish,
|
||||
});
|
||||
compose_validate.initialize();
|
||||
compose_textarea.initialize();
|
||||
upload.initialize();
|
||||
search.initialize({
|
||||
|
@@ -0,0 +1,16 @@
|
||||
{{#> compose_banner . }}
|
||||
<p class="banner_message">
|
||||
{{#tr}}
|
||||
None of the members of <z-group-pill></z-group-pill> are subscribed to this channel.
|
||||
{{#*inline "z-group-pill"}}
|
||||
<span class="display_only_group_pill">
|
||||
<a data-user-group-id="{{group_id}}" class="view_user_group_mention" tabindex="0">
|
||||
<span class="pill-label">
|
||||
<span>{{group_name}}</span>
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
{{/inline}}
|
||||
{{/tr}}
|
||||
</p>
|
||||
{{/compose_banner}}
|
@@ -26,6 +26,8 @@ const compose_validate = mock_esm("../src/compose_validate", {
|
||||
validate_message_length: () => true,
|
||||
warn_if_topic_resolved: noop,
|
||||
stream_wildcard_mention_allowed: () => true,
|
||||
warn_if_mentioning_unsubscribed_group: noop,
|
||||
initialize: noop,
|
||||
});
|
||||
const input_pill = mock_esm("../src/input_pill");
|
||||
const message_user_ids = mock_esm("../src/message_user_ids", {
|
||||
|
Reference in New Issue
Block a user