127 lines
4.3 KiB
Ruby
127 lines
4.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Chat::UserNotificationsExtension
|
|
def chat_summary(user, opts)
|
|
guardian = Guardian.new(user)
|
|
return unless guardian.can_chat?(user)
|
|
|
|
@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_see_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)
|
|
channels = grouped_messages.keys
|
|
grouped_channels = channels.partition { |c| !c.direct_message_channel? }
|
|
non_dm_channels = grouped_channels.first
|
|
dm_users = grouped_channels.last.flat_map { |c| grouped_messages[c].map(&:user) }.uniq
|
|
|
|
total_count_for_subject = non_dm_channels.size + dm_users.size
|
|
|
|
# Prioritize messages from regular channels.
|
|
first_message_from = non_dm_channels.pop
|
|
if first_message_from
|
|
first_message_title = first_message_from.title(user)
|
|
subject_key = "chat_channel"
|
|
else
|
|
subject_key = "direct_message"
|
|
first_message_from = dm_users.pop
|
|
first_message_title = first_message_from.username
|
|
end
|
|
|
|
subject_opts = {
|
|
email_prefix: @email_prefix,
|
|
count: total_count_for_subject,
|
|
message_title: first_message_title,
|
|
others:
|
|
other_channels_text(
|
|
user,
|
|
total_count_for_subject,
|
|
first_message_from,
|
|
non_dm_channels,
|
|
dm_users,
|
|
),
|
|
}
|
|
|
|
I18n.t(with_subject_prefix(subject_key), **subject_opts)
|
|
end
|
|
|
|
def with_subject_prefix(key)
|
|
"user_notifications.chat_summary.subject.#{key}"
|
|
end
|
|
|
|
def other_channels_text(
|
|
user,
|
|
total_count,
|
|
first_message_from,
|
|
other_non_dm_channels,
|
|
other_dm_users
|
|
)
|
|
return if total_count <= 1
|
|
return I18n.t(with_subject_prefix("others"), count: total_count - 1) if total_count > 2
|
|
|
|
# The summary contains exactly two messages.
|
|
if other_non_dm_channels.empty?
|
|
second_message_from = other_dm_users.first
|
|
second_message_title = second_message_from.username
|
|
else
|
|
second_message_from = other_non_dm_channels.first
|
|
second_message_title = second_message_from.title(user)
|
|
end
|
|
|
|
second_message_is_from_channel = first_message_from.class == second_message_from.class
|
|
return second_message_title if second_message_is_from_channel
|
|
|
|
I18n.t(with_subject_prefix("other_direct_message"), dm_title: second_message_title)
|
|
end
|
|
end
|