mirror of https://github.com/zulip/zulip.git
mentions: Add "channel" as a wildcard mention.
Adds "channel" to the `stream_wildcards` frozenset for stream wildcard notifications on the backend/server. Updates frontend/web-app to handle "channel" as the other stream wildcards are handled in the typeahead and composebox modules. Updates the API version and documentation for the addition of "channel" as a wildcard mention. But does not change any of the functionailty of (or deprecate) the "stream" wildcard at this point. Part of project to rename "stream" to "channel".
This commit is contained in:
parent
88fd9d947b
commit
e700e818e5
|
@ -20,6 +20,12 @@ format used by the Zulip server that they are interacting with.
|
||||||
|
|
||||||
## Changes in Zulip 9.0
|
## Changes in Zulip 9.0
|
||||||
|
|
||||||
|
**Feature level 247**
|
||||||
|
|
||||||
|
* [Markdown message formatting](/api/message-formatting#mentions):
|
||||||
|
Added `channel` to the supported options for [wildcard
|
||||||
|
mentions](/help/mention-a-user-or-group#mention-everyone-on-a-stream).
|
||||||
|
|
||||||
**Feature level 246**
|
**Feature level 246**
|
||||||
|
|
||||||
* [`POST /register`](/api/register-queue), [`POST
|
* [`POST /register`](/api/register-queue), [`POST
|
||||||
|
|
|
@ -23,6 +23,12 @@ for syntax highlighting. This field is used in the
|
||||||
mentions][help-global-time] to supported Markdown message formatting
|
mentions][help-global-time] to supported Markdown message formatting
|
||||||
features.
|
features.
|
||||||
|
|
||||||
|
## Mentions
|
||||||
|
|
||||||
|
**Changes**: In Zulip 9.0 (feature level 247), `channel` was added
|
||||||
|
to the supported [wildcard][help-mention-all] options used in the
|
||||||
|
[mentions][help-mentions] Markdown message formatting feature.
|
||||||
|
|
||||||
## Spoilers
|
## Spoilers
|
||||||
|
|
||||||
**Changes**: In Zulip 3.0 (feature level 15), added
|
**Changes**: In Zulip 3.0 (feature level 15), added
|
||||||
|
@ -45,3 +51,5 @@ inconsistent syntax, were removed.
|
||||||
[help-playgrounds]: /help/code-blocks#code-playgrounds
|
[help-playgrounds]: /help/code-blocks#code-playgrounds
|
||||||
[help-spoilers]: /help/spoilers
|
[help-spoilers]: /help/spoilers
|
||||||
[help-global-time]: /help/global-times
|
[help-global-time]: /help/global-times
|
||||||
|
[help-mentions]: /help/mention-a-user-or-group
|
||||||
|
[help-mention-all]: /help/mention-a-user-or-group#mention-everyone-on-a-stream
|
||||||
|
|
|
@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.9.3"
|
||||||
# Changes should be accompanied by documentation explaining what the
|
# Changes should be accompanied by documentation explaining what the
|
||||||
# new level means in api_docs/changelog.md, as well as "**Changes**"
|
# new level means in api_docs/changelog.md, as well as "**Changes**"
|
||||||
# entries in the endpoint's documentation in `zulip.yaml`.
|
# entries in the endpoint's documentation in `zulip.yaml`.
|
||||||
API_FEATURE_LEVEL = 246
|
API_FEATURE_LEVEL = 247
|
||||||
|
|
||||||
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
||||||
# only when going from an old version of the code to a newer version. Bump
|
# only when going from an old version of the code to a newer version. Bump
|
||||||
|
|
|
@ -411,7 +411,7 @@ export function broadcast_mentions() {
|
||||||
if (compose_state.get_message_type() === "private") {
|
if (compose_state.get_message_type() === "private") {
|
||||||
wildcard_mention_array = ["all", "everyone"];
|
wildcard_mention_array = ["all", "everyone"];
|
||||||
} else if (compose_validate.stream_wildcard_mention_allowed()) {
|
} else if (compose_validate.stream_wildcard_mention_allowed()) {
|
||||||
wildcard_mention_array = ["all", "everyone", "stream", "topic"];
|
wildcard_mention_array = ["all", "everyone", "stream", "channel", "topic"];
|
||||||
} else if (compose_validate.topic_wildcard_mention_allowed()) {
|
} else if (compose_validate.topic_wildcard_mention_allowed()) {
|
||||||
wildcard_mention_array = ["topic"];
|
wildcard_mention_array = ["topic"];
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,12 @@ function parse_with_options(
|
||||||
const marked_options = {
|
const marked_options = {
|
||||||
...options,
|
...options,
|
||||||
userMentionHandler(mention: string, silently: boolean): string | undefined {
|
userMentionHandler(mention: string, silently: boolean): string | undefined {
|
||||||
if (mention === "all" || mention === "everyone" || mention === "stream") {
|
if (
|
||||||
|
mention === "all" ||
|
||||||
|
mention === "everyone" ||
|
||||||
|
mention === "stream" ||
|
||||||
|
mention === "channel"
|
||||||
|
) {
|
||||||
let classes;
|
let classes;
|
||||||
let display_text;
|
let display_text;
|
||||||
if (silently) {
|
if (silently) {
|
||||||
|
|
|
@ -1373,7 +1373,7 @@ export function get_mention_syntax(full_name: string, user_id?: number, silent =
|
||||||
}
|
}
|
||||||
|
|
||||||
function full_name_matches_wildcard_mention(full_name: string): boolean {
|
function full_name_matches_wildcard_mention(full_name: string): boolean {
|
||||||
return ["all", "everyone", "stream", "topic"].includes(full_name);
|
return ["all", "everyone", "stream", "channel", "topic"].includes(full_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _add_user(person: User): void {
|
export function _add_user(person: User): void {
|
||||||
|
|
|
@ -195,10 +195,12 @@ export class CachedValue<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function find_stream_wildcard_mentions(message_content: string): string | null {
|
export function find_stream_wildcard_mentions(message_content: string): string | null {
|
||||||
// We cannot use the exact same regex as the server side users (in zerver/lib/mention.py)
|
// We cannot use the exact same regex as the server side uses (in zerver/lib/mention.py)
|
||||||
// because Safari < 16.4 does not support look-behind assertions. Reframe the lookbehind of a
|
// because Safari < 16.4 does not support look-behind assertions. Reframe the lookbehind of a
|
||||||
// negative character class as a start-of-string or positive character class.
|
// negative character class as a start-of-string or positive character class.
|
||||||
const mention = message_content.match(/(?:^|[\s"'(/<[{])(@\*{2}(all|everyone|stream)\*{2})/);
|
const mention = message_content.match(
|
||||||
|
/(?:^|[\s"'(/<[{])(@\*{2}(all|everyone|stream|channel)\*{2})/,
|
||||||
|
);
|
||||||
if (mention === null) {
|
if (mention === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,19 +65,23 @@ run_test("verify wildcard mentions typeahead for stream message", () => {
|
||||||
const mention_all = ct.broadcast_mentions()[0];
|
const mention_all = ct.broadcast_mentions()[0];
|
||||||
const mention_everyone = ct.broadcast_mentions()[1];
|
const mention_everyone = ct.broadcast_mentions()[1];
|
||||||
const mention_stream = ct.broadcast_mentions()[2];
|
const mention_stream = ct.broadcast_mentions()[2];
|
||||||
const mention_topic = ct.broadcast_mentions()[3];
|
const mention_channel = ct.broadcast_mentions()[3];
|
||||||
|
const mention_topic = ct.broadcast_mentions()[4];
|
||||||
assert.equal(mention_all.email, "all");
|
assert.equal(mention_all.email, "all");
|
||||||
assert.equal(mention_all.full_name, "all");
|
assert.equal(mention_all.full_name, "all");
|
||||||
assert.equal(mention_everyone.email, "everyone");
|
assert.equal(mention_everyone.email, "everyone");
|
||||||
assert.equal(mention_everyone.full_name, "everyone");
|
assert.equal(mention_everyone.full_name, "everyone");
|
||||||
assert.equal(mention_stream.email, "stream");
|
assert.equal(mention_stream.email, "stream");
|
||||||
assert.equal(mention_stream.full_name, "stream");
|
assert.equal(mention_stream.full_name, "stream");
|
||||||
|
assert.equal(mention_channel.email, "channel");
|
||||||
|
assert.equal(mention_channel.full_name, "channel");
|
||||||
assert.equal(mention_topic.email, "topic");
|
assert.equal(mention_topic.email, "topic");
|
||||||
assert.equal(mention_topic.full_name, "topic");
|
assert.equal(mention_topic.full_name, "topic");
|
||||||
|
|
||||||
assert.equal(mention_all.special_item_text, "all (translated: Notify stream)");
|
assert.equal(mention_all.special_item_text, "all (translated: Notify stream)");
|
||||||
assert.equal(mention_everyone.special_item_text, "everyone (translated: Notify stream)");
|
assert.equal(mention_everyone.special_item_text, "everyone (translated: Notify stream)");
|
||||||
assert.equal(mention_stream.special_item_text, "stream (translated: Notify stream)");
|
assert.equal(mention_stream.special_item_text, "stream (translated: Notify stream)");
|
||||||
|
assert.equal(mention_channel.special_item_text, "channel (translated: Notify stream)");
|
||||||
assert.equal(mention_topic.special_item_text, "topic (translated: Notify topic)");
|
assert.equal(mention_topic.special_item_text, "topic (translated: Notify topic)");
|
||||||
|
|
||||||
compose_validate.stream_wildcard_mention_allowed = () => false;
|
compose_validate.stream_wildcard_mention_allowed = () => false;
|
||||||
|
@ -1788,7 +1792,7 @@ test("typeahead_results", () => {
|
||||||
|
|
||||||
// Verify we suggest both 'the first matching stream wildcard' and
|
// Verify we suggest both 'the first matching stream wildcard' and
|
||||||
// 'topic wildcard' mentions. Not only one matching wildcard mention.
|
// 'topic wildcard' mentions. Not only one matching wildcard mention.
|
||||||
const mention_topic = ct.broadcast_mentions()[3];
|
const mention_topic = ct.broadcast_mentions()[4];
|
||||||
// Here, we suggest both "everyone" and "topic".
|
// Here, we suggest both "everyone" and "topic".
|
||||||
assert_mentions_matches("o", [othello, mention_everyone, mention_topic, cordelia]);
|
assert_mentions_matches("o", [othello, mention_everyone, mention_topic, cordelia]);
|
||||||
|
|
||||||
|
|
|
@ -781,6 +781,17 @@ test("message_flags", () => {
|
||||||
assert.equal(message.flags.includes("topic_wildcard_mentioned"), false);
|
assert.equal(message.flags.includes("topic_wildcard_mentioned"), false);
|
||||||
assert.equal(message.flags.includes("mentioned"), false);
|
assert.equal(message.flags.includes("mentioned"), false);
|
||||||
|
|
||||||
|
input = "test @**channel**";
|
||||||
|
message = {topic: "No links here", raw_content: input};
|
||||||
|
message = {
|
||||||
|
...message,
|
||||||
|
...markdown.render(message.raw_content),
|
||||||
|
};
|
||||||
|
assert.equal(message.is_me_message, false);
|
||||||
|
assert.equal(message.flags.includes("stream_wildcard_mentioned"), true);
|
||||||
|
assert.equal(message.flags.includes("topic_wildcard_mentioned"), false);
|
||||||
|
assert.equal(message.flags.includes("mentioned"), false);
|
||||||
|
|
||||||
input = "test @**topic**";
|
input = "test @**topic**";
|
||||||
message = {topic: "No links here", raw_content: input};
|
message = {topic: "No links here", raw_content: input};
|
||||||
message = {
|
message = {
|
||||||
|
|
|
@ -602,7 +602,7 @@ test("sort broadcast mentions for stream message type", () => {
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
results.map((r) => r.email),
|
results.map((r) => r.email),
|
||||||
["all", "everyone", "stream", "topic"],
|
["all", "everyone", "stream", "channel", "topic"],
|
||||||
);
|
);
|
||||||
|
|
||||||
// Reverse the list to test actual sorting
|
// Reverse the list to test actual sorting
|
||||||
|
@ -616,7 +616,7 @@ test("sort broadcast mentions for stream message type", () => {
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
results2.map((r) => r.email),
|
results2.map((r) => r.email),
|
||||||
["all", "everyone", "stream", "topic", a_user.email, zman.email],
|
["all", "everyone", "stream", "channel", "topic", a_user.email, zman.email],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -184,6 +184,13 @@ run_test("wildcard_mentions_regexp", () => {
|
||||||
"some text before only @**stream**",
|
"some text before only @**stream**",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const messages_with_channel_mentions = [
|
||||||
|
"@**channel**",
|
||||||
|
"some text before @**channel** some text after",
|
||||||
|
"@**channel** some text after only",
|
||||||
|
"some text before only @**channel**",
|
||||||
|
];
|
||||||
|
|
||||||
const messages_with_topic_mentions = [
|
const messages_with_topic_mentions = [
|
||||||
"@**topic**",
|
"@**topic**",
|
||||||
"some text before @**topic** some text after",
|
"some text before @**topic** some text after",
|
||||||
|
@ -218,6 +225,15 @@ run_test("wildcard_mentions_regexp", () => {
|
||||||
"some_email@**stream**.com",
|
"some_email@**stream**.com",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const messages_without_channel_mentions = [
|
||||||
|
"some text before @channel some text after",
|
||||||
|
"@channel",
|
||||||
|
"`@channel`",
|
||||||
|
"some_email@channel.com",
|
||||||
|
"`@**channel**`",
|
||||||
|
"some_email@**channel**.com",
|
||||||
|
];
|
||||||
|
|
||||||
let i;
|
let i;
|
||||||
for (i = 0; i < messages_with_all_mentions.length; i += 1) {
|
for (i = 0; i < messages_with_all_mentions.length; i += 1) {
|
||||||
assert.ok(util.find_stream_wildcard_mentions(messages_with_all_mentions[i]));
|
assert.ok(util.find_stream_wildcard_mentions(messages_with_all_mentions[i]));
|
||||||
|
@ -231,6 +247,10 @@ run_test("wildcard_mentions_regexp", () => {
|
||||||
assert.ok(util.find_stream_wildcard_mentions(messages_with_stream_mentions[i]));
|
assert.ok(util.find_stream_wildcard_mentions(messages_with_stream_mentions[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < messages_with_channel_mentions.length; i += 1) {
|
||||||
|
assert.ok(util.find_stream_wildcard_mentions(messages_with_channel_mentions[i]));
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < messages_with_topic_mentions.length; i += 1) {
|
for (i = 0; i < messages_with_topic_mentions.length; i += 1) {
|
||||||
assert.ok(!util.find_stream_wildcard_mentions(messages_with_topic_mentions[i]));
|
assert.ok(!util.find_stream_wildcard_mentions(messages_with_topic_mentions[i]));
|
||||||
}
|
}
|
||||||
|
@ -246,6 +266,10 @@ run_test("wildcard_mentions_regexp", () => {
|
||||||
for (i = 0; i < messages_without_stream_mentions.length; i += 1) {
|
for (i = 0; i < messages_without_stream_mentions.length; i += 1) {
|
||||||
assert.ok(!util.find_stream_wildcard_mentions(messages_without_stream_mentions[i]));
|
assert.ok(!util.find_stream_wildcard_mentions(messages_without_stream_mentions[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < messages_without_channel_mentions.length; i += 1) {
|
||||||
|
assert.ok(!util.find_stream_wildcard_mentions(messages_without_channel_mentions[i]));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
run_test("move_array_elements_to_front", () => {
|
run_test("move_array_elements_to_front", () => {
|
||||||
|
|
|
@ -22,7 +22,7 @@ USER_GROUP_MENTIONS_RE = re.compile(
|
||||||
)
|
)
|
||||||
|
|
||||||
topic_wildcards = frozenset(["topic"])
|
topic_wildcards = frozenset(["topic"])
|
||||||
stream_wildcards = frozenset(["all", "everyone", "stream"])
|
stream_wildcards = frozenset(["all", "everyone", "stream", "channel"])
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|
Loading…
Reference in New Issue