mirror of
https://github.com/discourse/discourse.git
synced 2024-12-03 05:43:44 +08:00
06ad13b517
`last_message_sent_at` could be equal and as a result the order would be random causing random spec failures in plugins/chat/spec/mailers/user_notifications_spec.rb:182
141 lines
4.8 KiB
Ruby
141 lines
4.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Chat::UserNotificationsExtension
|
|
def chat_summary(user, opts)
|
|
guardian = Guardian.new(user)
|
|
return unless guardian.can_chat?
|
|
|
|
@messages =
|
|
ChatMessage
|
|
.joins(:user, :chat_channel)
|
|
.where.not(user: user)
|
|
.where("chat_messages.created_at > ?", 1.week.ago)
|
|
.joins("LEFT OUTER JOIN chat_mentions cm ON cm.chat_message_id = chat_messages.id")
|
|
.joins(
|
|
"INNER JOIN user_chat_channel_memberships uccm ON uccm.chat_channel_id = chat_channels.id",
|
|
)
|
|
.where(<<~SQL, user_id: user.id)
|
|
uccm.user_id = :user_id AND
|
|
(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 uccm.following IS true AND chat_channels.chatable_type = 'Category') OR
|
|
(chat_channels.chatable_type = 'DirectMessage')
|
|
)
|
|
SQL
|
|
.to_a
|
|
|
|
return if @messages.empty?
|
|
@grouped_messages = @messages.group_by { |message| message.chat_channel }
|
|
@grouped_messages =
|
|
@grouped_messages.select { |channel, _| guardian.can_join_chat_channel?(channel) }
|
|
return if @grouped_messages.empty?
|
|
|
|
@grouped_messages.each do |chat_channel, messages|
|
|
@grouped_messages[chat_channel] = messages.sort_by(&:created_at)
|
|
end
|
|
@user = user
|
|
@user_tz = UserOption.user_tzinfo(user.id)
|
|
@display_usernames = SiteSetting.prioritize_username_in_ux || !SiteSetting.enable_names
|
|
|
|
build_summary_for(user)
|
|
@preferences_path = "#{Discourse.base_url}/my/preferences/chat"
|
|
|
|
# TODO(roman): Remove after the 2.9 release
|
|
add_unsubscribe_link = UnsubscribeKey.respond_to?(:get_unsubscribe_strategy_for)
|
|
|
|
if add_unsubscribe_link
|
|
unsubscribe_key = UnsubscribeKey.create_key_for(@user, "chat_summary")
|
|
@unsubscribe_link = "#{Discourse.base_url}/email/unsubscribe/#{unsubscribe_key}"
|
|
opts[:unsubscribe_url] = @unsubscribe_link
|
|
end
|
|
|
|
opts = {
|
|
from_alias: I18n.t("user_notifications.chat_summary.from", site_name: Email.site_title),
|
|
subject: summary_subject(user, @grouped_messages),
|
|
add_unsubscribe_link: add_unsubscribe_link,
|
|
}
|
|
|
|
build_email(user.email, opts)
|
|
end
|
|
|
|
def summary_subject(user, grouped_messages)
|
|
all_channels = grouped_messages.keys
|
|
grouped_channels = all_channels.partition { |c| !c.direct_message_channel? }
|
|
channels = grouped_channels.first
|
|
|
|
dm_messages = grouped_channels.last.flat_map { |c| grouped_messages[c] }
|
|
dm_users = dm_messages.sort_by(&:created_at).uniq { |m| m.user_id }.map(&:user)
|
|
|
|
# Prioritize messages from regular channels over direct messages
|
|
if channels.any?
|
|
channel_notification_text(
|
|
channels.sort_by { |channel| [channel.last_message_sent_at, channel.created_at] },
|
|
dm_users,
|
|
)
|
|
else
|
|
direct_message_notification_text(dm_users)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def channel_notification_text(channels, dm_users)
|
|
total_count = channels.size + dm_users.size
|
|
|
|
if total_count > 2
|
|
I18n.t(
|
|
"user_notifications.chat_summary.subject.chat_channel_more",
|
|
email_prefix: @email_prefix,
|
|
channel: channels.first.title,
|
|
count: total_count - 1,
|
|
)
|
|
elsif channels.size == 1 && dm_users.size == 0
|
|
I18n.t(
|
|
"user_notifications.chat_summary.subject.chat_channel_1",
|
|
email_prefix: @email_prefix,
|
|
channel: channels.first.title,
|
|
)
|
|
elsif channels.size == 1 && dm_users.size == 1
|
|
I18n.t(
|
|
"user_notifications.chat_summary.subject.chat_channel_and_direct_message",
|
|
email_prefix: @email_prefix,
|
|
channel: channels.first.title,
|
|
username: dm_users.first.username,
|
|
)
|
|
elsif channels.size == 2
|
|
I18n.t(
|
|
"user_notifications.chat_summary.subject.chat_channel_2",
|
|
email_prefix: @email_prefix,
|
|
channel1: channels.first.title,
|
|
channel2: channels.second.title,
|
|
)
|
|
end
|
|
end
|
|
|
|
def direct_message_notification_text(dm_users)
|
|
case dm_users.size
|
|
when 1
|
|
I18n.t(
|
|
"user_notifications.chat_summary.subject.direct_message_from_1",
|
|
email_prefix: @email_prefix,
|
|
username: dm_users.first.username,
|
|
)
|
|
when 2
|
|
I18n.t(
|
|
"user_notifications.chat_summary.subject.direct_message_from_2",
|
|
email_prefix: @email_prefix,
|
|
username1: dm_users.first.username,
|
|
username2: dm_users.second.username,
|
|
)
|
|
else
|
|
I18n.t(
|
|
"user_notifications.chat_summary.subject.direct_message_from_more",
|
|
email_prefix: @email_prefix,
|
|
username: dm_users.first.username,
|
|
count: dm_users.size - 1,
|
|
)
|
|
end
|
|
end
|
|
end
|