mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
DEV: Redesign chat mentions (#24752)
At the moment, when someone is mentioning a group, or using here or
all mention, we create a chat_mention record per user. What we want
instead is to have special kinds of mentions, so we can create only one
chat_mention record in such cases. This PR implements that.
Note, that such mentions will still have N related notifications, one
notification per a user. We don't expect we'll have performance
problems on the notifications side, but if at some point we do, we
should be able to solve them on the side of notifications
(notifications are handled in jobs, also some little delays with
the notifications are acceptable, so we can make sure notifications
are properly queued, and that processing of every notification is
fast enough to make delays small enough).
The preparation work for this PR was done in fbd24fa, where we make
it possible for one mention to have several related notifications.
A pretty tricky part of this PR is schema and data migration, I've explained
related details inline on the migration files.
This commit is contained in:
committed by
GitHub
parent
6876c52857
commit
62f423da15
11
plugins/chat/lib/chat/group_extension.rb
Normal file
11
plugins/chat/lib/chat/group_extension.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Chat
|
||||
module GroupExtension
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
prepended do
|
||||
has_many :chat_mentions, class_name: "Chat::GroupMention", foreign_key: "target_id"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -52,13 +52,17 @@ module Chat
|
||||
.joins("INNER JOIN chat_channels cc ON cc.id = uccm.chat_channel_id")
|
||||
.joins("INNER JOIN chat_messages c_msg ON c_msg.chat_channel_id = uccm.chat_channel_id")
|
||||
.joins("LEFT OUTER JOIN chat_mentions c_mentions ON c_mentions.chat_message_id = c_msg.id")
|
||||
.joins(
|
||||
"LEFT OUTER JOIN chat_mention_notifications cmn ON cmn.chat_mention_id = c_mentions.id",
|
||||
)
|
||||
.joins("LEFT OUTER JOIN notifications n ON cmn.notification_id = n.id")
|
||||
.where("c_msg.deleted_at IS NULL AND c_msg.user_id <> users.id")
|
||||
.where("c_msg.created_at > ?", 1.week.ago)
|
||||
.where(<<~SQL)
|
||||
(uccm.last_read_message_id IS NULL OR c_msg.id > uccm.last_read_message_id) AND
|
||||
(uccm.last_unread_mention_when_emailed_id IS NULL OR c_msg.id > uccm.last_unread_mention_when_emailed_id) AND
|
||||
(
|
||||
(uccm.user_id = c_mentions.user_id AND uccm.following IS true AND cc.chatable_type = 'Category') OR
|
||||
(uccm.user_id = n.user_id AND uccm.following IS true AND cc.chatable_type = 'Category') OR
|
||||
(cc.chatable_type = 'DirectMessage')
|
||||
)
|
||||
SQL
|
||||
|
||||
@@ -83,10 +83,15 @@ module Chat
|
||||
|
||||
def notify_edit
|
||||
already_notified_user_ids =
|
||||
Chat::Mention
|
||||
.where(chat_message: @chat_message)
|
||||
.left_outer_joins(:notifications)
|
||||
.where.not(notifications: { id: nil })
|
||||
Notification
|
||||
.where(notification_type: Notification.types[:chat_mention])
|
||||
.joins(
|
||||
"INNER JOIN chat_mention_notifications ON chat_mention_notifications.notification_id = notifications.id",
|
||||
)
|
||||
.joins(
|
||||
"INNER JOIN chat_mentions ON chat_mentions.id = chat_mention_notifications.chat_mention_id",
|
||||
)
|
||||
.where("chat_mentions.chat_message_id = ?", @chat_message.id)
|
||||
.pluck(:user_id)
|
||||
|
||||
to_notify, inaccessible, all_mentioned_user_ids = list_users_to_notify
|
||||
|
||||
@@ -19,18 +19,6 @@ module Chat
|
||||
:parsed_direct_mentions,
|
||||
:parsed_group_mentions
|
||||
|
||||
def all_mentioned_users_ids
|
||||
@all_mentioned_users_ids ||=
|
||||
begin
|
||||
user_ids = global_mentions.pluck(:id)
|
||||
user_ids.concat(direct_mentions.pluck(:id))
|
||||
user_ids.concat(group_mentions.pluck(:id))
|
||||
user_ids.concat(here_mentions.pluck(:id))
|
||||
user_ids.uniq!
|
||||
user_ids
|
||||
end
|
||||
end
|
||||
|
||||
def count
|
||||
@count ||=
|
||||
begin
|
||||
|
||||
@@ -12,7 +12,7 @@ module Chat
|
||||
class_name: "Chat::UserChatThreadMembership",
|
||||
dependent: :destroy
|
||||
has_many :chat_message_reactions, class_name: "Chat::MessageReaction", dependent: :destroy
|
||||
has_many :chat_mentions, class_name: "Chat::Mention"
|
||||
has_many :chat_mentions, class_name: "Chat::UserMention", foreign_key: "target_id"
|
||||
has_many :direct_message_users, class_name: "Chat::DirectMessageUser"
|
||||
has_many :direct_messages, through: :direct_message_users, class_name: "Chat::DirectMessage"
|
||||
end
|
||||
|
||||
@@ -13,6 +13,7 @@ module Chat
|
||||
.where("chat_messages.created_at > ?", 1.week.ago)
|
||||
.joins("LEFT OUTER JOIN chat_mentions cm ON cm.chat_message_id = chat_messages.id")
|
||||
.joins("LEFT OUTER JOIN chat_mention_notifications cmn ON cmn.chat_mention_id = cm.id")
|
||||
.joins("LEFT OUTER JOIN notifications n ON cmn.notification_id = n.id")
|
||||
.joins(
|
||||
"INNER JOIN user_chat_channel_memberships uccm ON uccm.chat_channel_id = chat_channels.id",
|
||||
)
|
||||
@@ -21,7 +22,7 @@ module Chat
|
||||
(uccm.last_read_message_id IS NULL OR chat_messages.id > uccm.last_read_message_id) AND
|
||||
(uccm.last_unread_mention_when_emailed_id IS NULL OR chat_messages.id > uccm.last_unread_mention_when_emailed_id) AND
|
||||
(
|
||||
(cm.user_id = :user_id AND cmn.notification_id IS NOT NULL AND uccm.following IS true AND chat_channels.chatable_type = 'Category') OR
|
||||
(n.user_id = :user_id AND cmn.notification_id IS NOT NULL AND uccm.following IS true AND chat_channels.chatable_type = 'Category') OR
|
||||
(chat_channels.chatable_type = 'DirectMessage')
|
||||
)
|
||||
SQL
|
||||
|
||||
Reference in New Issue
Block a user