diff --git a/docs/overview/changelog.md b/docs/overview/changelog.md index 90243d0854..25d894ddc3 100644 --- a/docs/overview/changelog.md +++ b/docs/overview/changelog.md @@ -61,7 +61,7 @@ in bursts. - Added a ReviewBoard integration, and improved numerous existing integrations. - Added support for multi-line messages for the /me feature. - Added markdown rendering of text when displaying custom profile fields. -- Added "silent mentions" syntax (`_@**Tim Abbott**`), which show +- Added "silent mentions" syntax (`@_**Tim Abbott**`), which show visually, but don't trigger a notification to the target user. - Added support for using lightbox in compose preview. - Changes in date no longer force a repeated recipient bar. This diff --git a/frontend_tests/node_tests/markdown.js b/frontend_tests/node_tests/markdown.js index 96156d41bc..ed6783b93b 100644 --- a/frontend_tests/node_tests/markdown.js +++ b/frontend_tests/node_tests/markdown.js @@ -302,7 +302,7 @@ run_test('marked', () => { expected: '

:poop:

'}, {input: '\u{1f6b2}', expected: '

\u{1f6b2}

' }, - {input: 'Silent mention: _@**Cordelia Lear**', + {input: 'Silent mention: @_**Cordelia Lear**', expected: '

Silent mention: @Cordelia Lear

'}, {input: '> Mention in quote: @**Cordelia Lear**\n\nMention outside quote: @**Cordelia Lear**', expected: '
\n

Mention in quote: @Cordelia Lear

\n
\n

Mention outside quote: @Cordelia Lear

'}, diff --git a/static/third/marked/lib/marked.js b/static/third/marked/lib/marked.js index 98f3ad0287..a30d6ce0dc 100644 --- a/static/third/marked/lib/marked.js +++ b/static/third/marked/lib/marked.js @@ -509,7 +509,7 @@ inline.zulip = merge({}, inline.breaks, { '\ud83d[\ude80-\udeff]|\ud83e[\udd00-\uddff]|' + '[\u2000-\u206F]|[\u2300-\u27BF]|[\u2B00-\u2BFF]|' + '[\u3000-\u303F]|[\u3200-\u32FF])'), - usermention: /^((_?)@(?:\*\*([^\*]+)\*\*))/, // Match potentially multi-word string between @** ** + usermention: /^(@(_?)(?:\*\*([^\*]+)\*\*))/, // Match potentially multi-word string between @** ** groupmention: /^@\*([^\*]+)\*/, // Match multi-word string between @* * stream: /^#\*\*([^\*]+)\*\*/, avatar: /^!avatar\(([^)]+)\)/, diff --git a/zerver/lib/actions.py b/zerver/lib/actions.py index 55b90134f2..2b9f9eaf03 100644 --- a/zerver/lib/actions.py +++ b/zerver/lib/actions.py @@ -254,7 +254,7 @@ def send_signup_message(sender: UserProfile, admin_realm_signup_notifications_st "stream", signup_notifications_stream.name, "signups", - "_@**%s|%s** just signed up for Zulip. (total: %i)" % ( + "@_**%s|%s** just signed up for Zulip. (total: %i)" % ( user_profile.full_name, user_profile.id, user_count ) ) @@ -3491,7 +3491,7 @@ def do_rename_stream(stream: Stream, sender, stream, "welcome", - "_@**%s|%d** renamed stream **%s** to **%s**" % (user_profile.full_name, + "@_**%s|%d** renamed stream **%s** to **%s**" % (user_profile.full_name, user_profile.id, old_name, new_name) ) diff --git a/zerver/lib/bugdown/__init__.py b/zerver/lib/bugdown/__init__.py index c76e41d7c2..61aa272ca7 100644 --- a/zerver/lib/bugdown/__init__.py +++ b/zerver/lib/bugdown/__init__.py @@ -1358,7 +1358,7 @@ class BlockQuoteProcessor(markdown.blockprocessors.BlockQuoteProcessor): def clean(self, line: str) -> str: # Silence all the mentions inside blockquotes - line = re.sub(self.mention_re, lambda m: "_@{}".format(m.group('match')), line) + line = re.sub(self.mention_re, lambda m: "@_{}".format(m.group('match')), line) # And then run the upstream processor's code for removing the '>' return super().clean(line) diff --git a/zerver/lib/mention.py b/zerver/lib/mention.py index 858db3d94b..4ccc18c2a4 100644 --- a/zerver/lib/mention.py +++ b/zerver/lib/mention.py @@ -5,7 +5,7 @@ import re # Match multi-word string between @** ** or match any one-word # sequences after @ -find_mentions = r'(?_?)@(?P\*\*[^\*]+\*\*|all|everyone|stream)' +find_mentions = r'(?_?)(?P\*\*[^\*]+\*\*|all|everyone|stream)' user_group_mentions = r'(?' @@ -1052,10 +1052,10 @@ class BugdownTest(ZulipTestCase): content = "> @**King Hamlet**" self.assertEqual(render_markdown(msg, content), expected) self.assertEqual(msg.mentions_user_ids, set()) - content = "```quote\n_@**King Hamlet**\n```" + content = "```quote\n@_**King Hamlet**\n```" self.assertEqual(render_markdown(msg, content), expected) self.assertEqual(msg.mentions_user_ids, set()) - content = "> _@**King Hamlet**" + content = "> @_**King Hamlet**" self.assertEqual(render_markdown(msg, content), expected) self.assertEqual(msg.mentions_user_ids, set()) diff --git a/zerver/tests/test_new_users.py b/zerver/tests/test_new_users.py index 241761a497..72a78ff3e2 100644 --- a/zerver/tests/test_new_users.py +++ b/zerver/tests/test_new_users.py @@ -193,4 +193,4 @@ class TestNotifyNewUser(ZulipTestCase): self.assertEqual(message.recipient.type, Recipient.STREAM) actual_stream = Stream.objects.get(id=message.recipient.type_id) self.assertEqual(actual_stream.name, Realm.INITIAL_PRIVATE_STREAM_NAME) - self.assertIn('_@**Cordelia Lear|%d** just signed up for Zulip.' % (new_user.id), message.content) + self.assertIn('@_**Cordelia Lear|%d** just signed up for Zulip.' % (new_user.id), message.content) diff --git a/zerver/tests/test_subs.py b/zerver/tests/test_subs.py index 34b8e7084c..7184ac7e9f 100644 --- a/zerver/tests/test_subs.py +++ b/zerver/tests/test_subs.py @@ -617,7 +617,7 @@ class StreamAdminTest(ZulipTestCase): # Inspect the notification message sent message = self.get_last_message() actual_stream = Stream.objects.get(id=message.recipient.type_id) - message_content = '_@**King Hamlet|{}** renamed stream **stream_name1** to **stream_name2**'.format(user_profile.id) + message_content = '@_**King Hamlet|{}** renamed stream **stream_name1** to **stream_name2**'.format(user_profile.id) self.assertEqual(message.sender.realm, user_profile.realm) self.assertEqual(actual_stream.name, 'stream_name2') self.assertEqual(message.recipient.type, Recipient.STREAM) @@ -1962,7 +1962,7 @@ class SubscriptionAPITest(ZulipTestCase): msg = self.get_second_to_last_message() self.assertEqual(msg.recipient.type, Recipient.STREAM) self.assertEqual(msg.sender_id, self.notification_bot().id) - expected_msg = "_@**%s|%d** just created a new stream #**%s**." % (invitee_full_name, invitee_user.id, invite_streams[0]) + expected_msg = "@_**%s|%d** just created a new stream #**%s**." % (invitee_full_name, invitee_user.id, invite_streams[0]) self.assertEqual(msg.content, expected_msg) def test_successful_cross_realm_notification(self) -> None: @@ -2030,7 +2030,7 @@ class SubscriptionAPITest(ZulipTestCase): msg = self.get_second_to_last_message() self.assertEqual(msg.sender_id, self.notification_bot().id) - expected_msg = "_@**%s|%d** just created a new stream #**%s**." % (invitee_full_name, invitee_user.id, invite_streams[0]) + expected_msg = "@_**%s|%d** just created a new stream #**%s**." % (invitee_full_name, invitee_user.id, invite_streams[0]) self.assertEqual(msg.content, expected_msg) def test_non_ascii_stream_subscription(self) -> None: diff --git a/zerver/views/streams.py b/zerver/views/streams.py index 2716c87bb0..e46962cc94 100644 --- a/zerver/views/streams.py +++ b/zerver/views/streams.py @@ -389,7 +389,7 @@ def add_subscriptions_backend( stream_msg = "the following streams: %s" % (stream_strs,) else: stream_msg = "a new stream #**%s**." % created_streams[0].name - msg = ("_@**%s|%d** just created %s" % (user_profile.full_name, user_profile.id, stream_msg)) + msg = ("@_**%s|%d** just created %s" % (user_profile.full_name, user_profile.id, stream_msg)) sender = get_system_bot(settings.NOTIFICATION_BOT) topic = 'Streams'