From f0dfe56870caf983ced94f592b600e1f30f5ab34 Mon Sep 17 00:00:00 2001 From: Andrei Prigorshnev Date: Thu, 25 May 2023 15:41:22 +0400 Subject: [PATCH] DEV: extract more logic into ParsedMentions class (#21729) This doesn't change any behavior, only moves code around. --- plugins/chat/lib/chat/notifier.rb | 57 +++++++++--------------- plugins/chat/lib/chat/parsed_mentions.rb | 19 ++++++-- 2 files changed, 37 insertions(+), 39 deletions(-) diff --git a/plugins/chat/lib/chat/notifier.rb b/plugins/chat/lib/chat/notifier.rb index e0d0c0abd00..26d961af0a8 100644 --- a/plugins/chat/lib/chat/notifier.rb +++ b/plugins/chat/lib/chat/notifier.rb @@ -58,6 +58,7 @@ module Chat def initialize(chat_message, timestamp) @chat_message = chat_message + @parsed_mentions = @chat_message.parsed_mentions @timestamp = timestamp @chat_channel = @chat_message.chat_channel @user = @chat_message.user @@ -102,8 +103,7 @@ module Chat private def list_users_to_notify - skip_notifications = - @chat_message.parsed_mentions.count > SiteSetting.max_mentions_per_chat_message + skip_notifications = @parsed_mentions.count > SiteSetting.max_mentions_per_chat_message {}.tap do |to_notify| # The order of these methods is the precedence @@ -125,11 +125,10 @@ module Chat end def expand_global_mention(to_notify, already_covered_ids) - has_all_mention = @chat_message.parsed_mentions.has_global_mention + has_all_mention = @parsed_mentions.has_global_mention if has_all_mention && @chat_channel.allow_channel_wide_mentions - to_notify[:global_mentions] = @chat_message - .parsed_mentions + to_notify[:global_mentions] = @parsed_mentions .global_mentions .not_suspended .where(user_options: { ignore_channel_wide_mention: [false, nil] }) @@ -144,11 +143,10 @@ module Chat end def expand_here_mention(to_notify, already_covered_ids) - has_here_mention = @chat_message.parsed_mentions.has_here_mention + has_here_mention = @parsed_mentions.has_here_mention if has_here_mention && @chat_channel.allow_channel_wide_mentions - to_notify[:here_mentions] = @chat_message - .parsed_mentions + to_notify[:here_mentions] = @parsed_mentions .here_mentions .not_suspended .where(user_options: { ignore_channel_wide_mention: [false, nil] }) @@ -190,8 +188,7 @@ module Chat direct_mentions = [] else direct_mentions = - @chat_message - .parsed_mentions + @parsed_mentions .direct_mentions .not_suspended .where.not(username_lower: @user.username_lower) @@ -207,36 +204,25 @@ module Chat end def expand_group_mentions(to_notify, already_covered_ids) - return if @chat_message.parsed_mentions.visible_groups.empty? + return if @parsed_mentions.visible_groups.empty? reached_by_group = - @chat_message - .parsed_mentions + @parsed_mentions .group_mentions .not_suspended .where("user_count <= ?", SiteSetting.max_users_notified_per_group_mention) .where.not(username_lower: @user.username_lower) .where.not(id: already_covered_ids) - too_many_members, mentionable = - @chat_message.parsed_mentions.mentionable_groups.partition do |group| - group.user_count > SiteSetting.max_users_notified_per_group_mention - end - - mentions_disabled = - @chat_message.parsed_mentions.visible_groups - - @chat_message.parsed_mentions.mentionable_groups - to_notify[:group_mentions_disabled] = mentions_disabled - to_notify[:too_many_members] = too_many_members - mentionable.each { |g| to_notify[g.name.downcase] = [] } + @parsed_mentions.groups_to_mention.each { |g| to_notify[g.name.downcase] = [] } grouped = group_users_to_notify(reached_by_group) grouped[:already_participating].each do |user| # When a user is a member of multiple mentioned groups, # the most far to the left should take precedence. ordered_group_names = - @chat_message.parsed_mentions.parsed_group_mentions & - mentionable.map { |mg| mg.name.downcase } + @parsed_mentions.parsed_group_mentions & + @parsed_mentions.groups_to_mention.map { |mg| mg.name.downcase } user_group_names = user.groups.map { |ug| ug.name.downcase } group_name = ordered_group_names.detect { |gn| user_group_names.include?(gn) } @@ -249,22 +235,21 @@ module Chat end def notify_creator_of_inaccessible_mentions(to_notify) - inaccessible = - to_notify.extract!( - :unreachable, - :welcome_to_join, - :too_many_members, - :group_mentions_disabled, - ) - return if inaccessible.values.all?(&:blank?) + inaccessible = to_notify.extract!(:unreachable, :welcome_to_join) + group_mentions_disabled = @parsed_mentions.groups_with_disabled_mentions.to_a + too_many_members = @parsed_mentions.groups_with_too_many_members.to_a + if inaccessible.values.all?(&:blank?) && group_mentions_disabled.empty? && + too_many_members.empty? + return + end Chat::Publisher.publish_inaccessible_mentions( @user.id, @chat_message, inaccessible[:unreachable].to_a, inaccessible[:welcome_to_join].to_a, - inaccessible[:too_many_members].to_a, - inaccessible[:group_mentions_disabled].to_a, + too_many_members, + group_mentions_disabled, ) end diff --git a/plugins/chat/lib/chat/parsed_mentions.rb b/plugins/chat/lib/chat/parsed_mentions.rb index d6add90f626..3b0bd69649e 100644 --- a/plugins/chat/lib/chat/parsed_mentions.rb +++ b/plugins/chat/lib/chat/parsed_mentions.rb @@ -62,9 +62,17 @@ module Chat .where.not(username_lower: @parsed_direct_mentions) end - def mentionable_groups - @mentionable_groups ||= - Group.mentionable(@message.user, include_public: false).where(id: visible_groups.map(&:id)) + def groups_to_mention + @groups_to_mention = mentionable_groups - groups_with_too_many_members + end + + def groups_with_disabled_mentions + @groups_with_disabled_mentions ||= visible_groups - mentionable_groups + end + + def groups_with_too_many_members + @groups_with_too_many_members ||= + mentionable_groups.where("user_count > ?", SiteSetting.max_users_notified_per_group_mention) end def visible_groups @@ -93,6 +101,11 @@ module Chat .where(user_options: { chat_enabled: true }) end + def mentionable_groups + @mentionable_groups ||= + Group.mentionable(@message.user, include_public: false).where(id: visible_groups.map(&:id)) + end + def parse_mentions(message) Nokogiri::HTML5.fragment(message.cooked).css(".mention").map(&:text) end