diff --git a/app/assets/javascripts/discourse/models/topic-list.js.es6 b/app/assets/javascripts/discourse/models/topic-list.js.es6 index 6c90b31ab3c..5346fd977ea 100644 --- a/app/assets/javascripts/discourse/models/topic-list.js.es6 +++ b/app/assets/javascripts/discourse/models/topic-list.js.es6 @@ -98,13 +98,22 @@ TopicList.reopenClass({ if (!result) { return; } // Stitch together our side loaded data + const categories = Discourse.Category.list(), - users = Model.extractByKey(result.users, Discourse.User); + users = Model.extractByKey(result.users, Discourse.User), + groups = Model.extractByKey(result.primary_groups, Ember.Object); return result.topic_list.topics.map(function (t) { t.category = categories.findBy('id', t.category_id); t.posters.forEach(function(p) { p.user = users[p.user_id]; + p.extraClasses = p.extras; + if (p.primary_group_id) { + p.primary_group = groups[p.primary_group_id]; + if (p.primary_group) { + p.extraClasses += ` group-${p.primary_group.name}`; + } + } }); if (t.participants) { t.participants.forEach(function(p) { diff --git a/app/assets/javascripts/discourse/templates/list/posters-column.raw.hbs b/app/assets/javascripts/discourse/templates/list/posters-column.raw.hbs index 71317223b4b..8a76f021914 100644 --- a/app/assets/javascripts/discourse/templates/list/posters-column.raw.hbs +++ b/app/assets/javascripts/discourse/templates/list/posters-column.raw.hbs @@ -1,5 +1,5 @@ {{#each posters as |poster|}} -{{avatar poster avatarTemplatePath="user.avatar_template" usernamePath="user.username" imageSize="small"}} +{{avatar poster avatarTemplatePath="user.avatar_template" usernamePath="user.username" imageSize="small"}} {{/each}} diff --git a/app/models/topic.rb b/app/models/topic.rb index 90517540f78..be414d6b59d 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -816,7 +816,7 @@ SQL update_column(:like_count, Post.where(topic_id: id).sum(:like_count)) end - def posters_summary(options = {}) + def posters_summary(options = {}) # avatar lookup in options @posters_summary ||= TopicPostersSummary.new(self, options).summary end diff --git a/app/models/topic_list.rb b/app/models/topic_list.rb index b26db3cff2c..16dc5ea6e27 100644 --- a/app/models/topic_list.rb +++ b/app/models/topic_list.rb @@ -1,4 +1,5 @@ require_dependency 'avatar_lookup' +require_dependency 'primary_group_lookup' class TopicList include ActiveModel::Serialization @@ -108,7 +109,11 @@ class TopicList ft.user_data.post_action_data = {post_action_type => actions} end - ft.posters = ft.posters_summary(avatar_lookup: avatar_lookup) + ft.posters = ft.posters_summary( + avatar_lookup: avatar_lookup, + primary_group_lookup: PrimaryGroupLookup.new(user_ids) + ) + ft.participants = ft.participants_summary(avatar_lookup: avatar_lookup, user: @current_user) ft.topic_list = self end diff --git a/app/models/topic_participants_summary.rb b/app/models/topic_participants_summary.rb index f72a5fb6cdd..424e203c482 100644 --- a/app/models/topic_participants_summary.rb +++ b/app/models/topic_participants_summary.rb @@ -1,3 +1,4 @@ +# This is used on a topic page class TopicParticipantsSummary attr_reader :topic, :options diff --git a/app/models/topic_poster.rb b/app/models/topic_poster.rb index 7e32aa83db4..ec3a88e2a26 100644 --- a/app/models/topic_poster.rb +++ b/app/models/topic_poster.rb @@ -1,14 +1,15 @@ class TopicPoster < OpenStruct include ActiveModel::Serialization - attr_accessor :user, :description, :extras, :id + attr_accessor :user, :description, :extras, :id, :primary_group def attributes { 'user' => user, 'description' => description, 'extras' => extras, - 'id' => id + 'id' => id, + 'primary_group' => primary_group } end diff --git a/app/models/topic_posters_summary.rb b/app/models/topic_posters_summary.rb index c000505ead2..7723bf338cd 100644 --- a/app/models/topic_posters_summary.rb +++ b/app/models/topic_posters_summary.rb @@ -1,3 +1,4 @@ +# This is used in topic lists class TopicPostersSummary attr_reader :topic, :options @@ -16,6 +17,7 @@ class TopicPostersSummary TopicPoster.new.tap do |topic_poster| topic_poster.user = user topic_poster.description = descriptions_for(user) + topic_poster.primary_group = primary_group_lookup[user.id] if topic.last_post_user_id == user.id topic_poster.extras = 'latest' topic_poster.extras << ' single' if user_ids.uniq.size == 1 @@ -74,4 +76,8 @@ class TopicPostersSummary def avatar_lookup @avatar_lookup ||= options[:avatar_lookup] || AvatarLookup.new(user_ids) end + + def primary_group_lookup + @primary_group_lookup ||= options[:primary_group_lookup] || PrimaryGroupLookup.new(user_ids) + end end diff --git a/app/serializers/primary_group_serializer.rb b/app/serializers/primary_group_serializer.rb new file mode 100644 index 00000000000..c9f7130e4e0 --- /dev/null +++ b/app/serializers/primary_group_serializer.rb @@ -0,0 +1,3 @@ +class PrimaryGroupSerializer < ApplicationSerializer + attributes :id, :name, :flair_url, :flair_bg_color, :flair_color +end diff --git a/app/serializers/topic_poster_serializer.rb b/app/serializers/topic_poster_serializer.rb index a3c3f2864e3..9d182b9121d 100644 --- a/app/serializers/topic_poster_serializer.rb +++ b/app/serializers/topic_poster_serializer.rb @@ -1,4 +1,5 @@ class TopicPosterSerializer < ApplicationSerializer attributes :extras, :description has_one :user, serializer: BasicUserSerializer + has_one :primary_group, serializer: PrimaryGroupSerializer end diff --git a/lib/primary_group_lookup.rb b/lib/primary_group_lookup.rb new file mode 100644 index 00000000000..c61bb1b7e5e --- /dev/null +++ b/lib/primary_group_lookup.rb @@ -0,0 +1,37 @@ +class PrimaryGroupLookup + def initialize(user_ids=[]) + @user_ids = user_ids.tap(&:compact!).tap(&:uniq!).tap(&:flatten!) + end + + # Lookup primary group for a given user id + def [](user_id) + users[user_id] + end + + private + + def self.lookup_columns + @lookup_columns ||= %i{id name flair_url flair_bg_color flair_color} + end + + def users + @users ||= user_lookup_hash + end + + def user_lookup_hash + users_with_primary_group = User.where(id: @user_ids) + .where.not(primary_group_id: nil) + .select(:id, :primary_group_id) + + group_lookup = {} + group_ids = users_with_primary_group.map(&:primary_group_id).compact + Group.where(id: group_ids).select(self.class.lookup_columns) + .each { |g| group_lookup[g.id] = g } + + hash = {} + users_with_primary_group.each do |u| + hash[u.id] = group_lookup[u.primary_group_id] + end + hash + end +end