FIX: Add plugin event to topic list user lookup (#14116)

FIX: Add plugin event to topic list user lookup (#14116)

This can be used to change the list of topic posters. For example, discourse-solved can use this to move the user who posted the solution after the original poster.

diff --git a/app/models/topic_list.rb b/app/models/topic_list.rb
index 4308d88..2c56408 100644
--- a/app/models/topic_list.rb
+++ b/app/models/topic_list.rb
@@ -25,6 +25,19 @@ class TopicList
     end
   end
 
+  def self.on_preload_user_ids(&blk)
+    (@preload_user_ids ||= Set.new) << blk
+  end
+
+  def self.preload_user_ids(topics, user_ids, object)
+    if @preload_user_ids
+      @preload_user_ids.each do |preload_user_ids|
+        user_ids = preload_user_ids.call(topics, user_ids, object)
+      end
+    end
+    user_ids
+  end
+
   attr_accessor(
     :more_topics_url,
     :prev_topics_url,
@@ -113,6 +126,7 @@ class TopicList
       user_ids << ft.user_id << ft.last_post_user_id << ft.featured_user_ids << ft.allowed_user_ids
     end
 
+    user_ids = TopicList.preload_user_ids(@topics, user_ids, self)
     user_lookup = UserLookup.new(user_ids)
 
     @topics.each do |ft|
diff --git a/app/models/topic_posters_summary.rb b/app/models/topic_posters_summary.rb
index e21dd42..cded3eb 100644
--- a/app/models/topic_posters_summary.rb
+++ b/app/models/topic_posters_summary.rb
@@ -41,10 +41,10 @@ class TopicPostersSummary
     topic_poster
   end
 
-  def descriptions_by_id
+  def descriptions_by_id(ids: nil)
     @descriptions_by_id ||= begin
       result = {}
-      ids = user_ids
+      ids = ids || user_ids
 
       if id = ids.shift
         result[id] ||= []
diff --git a/lib/plugin/instance.rb b/lib/plugin/instance.rb
index c342324..471f5c3 100644
--- a/lib/plugin/instance.rb
+++ b/lib/plugin/instance.rb
@@ -210,6 +210,16 @@ class Plugin::Instance
     TopicView.add_custom_filter(trigger, &block)
   end
 
+  # Allows to add more user IDs to the list of preloaded users. This can be
+  # useful to efficiently change the list of posters or participants.
+  # Example usage:
+  #   register_topic_list_preload_user_ids do |topics, user_ids, topic_list|
+  #     user_ids << Discourse::SYSTEM_USER_ID
+  #   end
+  def register_topic_list_preload_user_ids(&block)
+    TopicList.on_preload_user_ids(&block)
+  end
+
   # Allow to eager load additional tables in Search. Useful to avoid N+1 performance problems.
   # Example usage:
   #   register_search_topic_eager_load do |opts|

GitHub sha: 197532dc31b8d6e61d71eed5eb4a6bd1a7010f00

This commit appears in #14116 which was approved by eviltrout and tgxworld. It was merged by nbianca.