discourse/app/models/topic_posters_summary.rb

99 lines
2.3 KiB
Ruby

# frozen_string_literal: true
# This is used in topic lists
class TopicPostersSummary
# localization is fast, but this allows us to avoid
# calling it in a loop which adds up
def self.translations
{
original_poster: I18n.t(:original_poster),
most_recent_poster: I18n.t(:most_recent_poster),
frequent_poster: I18n.t(:frequent_poster),
joiner: I18n.t(:poster_description_joiner)
}
end
attr_reader :topic, :options
def initialize(topic, options = {})
@topic = topic
@options = options
@translations = options[:translations] || TopicPostersSummary.translations
end
def summary
sorted_top_posters.compact.map(&method(:new_topic_poster_for))
end
private
def new_topic_poster_for(user)
topic_poster = TopicPoster.new
topic_poster.user = user
topic_poster.description = descriptions_for(user)
topic_poster.primary_group = user_lookup.primary_groups[user.id]
if topic.last_post_user_id == user.id
topic_poster.extras = +'latest'
topic_poster.extras << ' single' if user_ids.uniq.size == 1
end
topic_poster
end
def descriptions_by_id
@descriptions_by_id ||= begin
result = {}
ids = user_ids
if id = ids.shift
result[id] ||= []
result[id] << @translations[:original_poster]
end
if id = ids.shift
result[id] ||= []
result[id] << @translations[:most_recent_poster]
end
while id = ids.shift
result[id] ||= []
result[id] << @translations[:frequent_poster]
end
result
end
end
def descriptions_for(user)
descriptions_by_id[user.id].join(@translations[:joiner])
end
def shuffle_last_poster_to_back_in(summary)
unless last_poster_is_topic_creator?
summary.reject! { |u| u.id == topic.last_post_user_id }
summary << user_lookup[topic.last_post_user_id]
end
summary
end
def last_poster_is_topic_creator?
topic.user_id == topic.last_post_user_id
end
def sorted_top_posters
shuffle_last_poster_to_back_in top_posters
end
def top_posters
user_ids.map { |id| user_lookup[id] }.compact.uniq.take(5)
end
def user_ids
[ topic.user_id, topic.last_post_user_id, *topic.featured_user_ids ]
end
def user_lookup
@user_lookup ||= options[:user_lookup] || UserLookup.new(user_ids)
end
end