mirror of
https://github.com/discourse/discourse.git
synced 2025-03-03 02:37:24 +08:00

Instead of passing `user` to `guardian.can_chat?`, we can just use the inner `@user` that is part of the guardian instance already to determine whether that user can chat, since this is how it works for all other usages of guardian even within chat.
136 lines
4.6 KiB
Ruby
136 lines
4.6 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_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)
|
|
all_channels = grouped_messages.keys
|
|
grouped_channels = all_channels.partition { |c| !c.direct_message_channel? }
|
|
channels = grouped_channels.first
|
|
dm_users = grouped_channels.last.flat_map { |c| grouped_messages[c].map(&:user) }.uniq
|
|
|
|
# Prioritize messages from regular channels over direct messages
|
|
if channels.any?
|
|
channel_notification_text(channels, 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
|