FEATURE: reorder participants in topic so always chronological
FEATURE: tie breaker for same number of posts is last post date UX: highlight for latest poster when it is OP
This commit is contained in:
parent
0fcb98c80a
commit
c6a5081763
|
@ -108,7 +108,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.posters a:first-child .avatar.latest:not(.single) {
|
||||||
|
box-shadow: 0 0 3px 1px desaturate(scale-color($tertiary, $lightness: 65%), 35%);
|
||||||
|
border: 2px solid desaturate(scale-color($tertiary, $lightness: 50%), 40%);
|
||||||
|
position: relative;
|
||||||
|
top: -2px;
|
||||||
|
left: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.sortable {
|
.sortable {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|
|
@ -43,6 +43,7 @@ class PostMover
|
||||||
update_user_actions
|
update_user_actions
|
||||||
set_last_post_user_id(destination_topic)
|
set_last_post_user_id(destination_topic)
|
||||||
|
|
||||||
|
destination_topic.reload
|
||||||
destination_topic
|
destination_topic
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,8 @@ class TopicFeaturedUsers
|
||||||
|
|
||||||
# Chooses which topic users to feature
|
# Chooses which topic users to feature
|
||||||
def choose(args={})
|
def choose(args={})
|
||||||
clear
|
self.class.ensure_consistency!(topic.id.to_i)
|
||||||
update keys(args)
|
|
||||||
update_participant_count
|
update_participant_count
|
||||||
topic.save
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_ids
|
def user_ids
|
||||||
|
@ -24,19 +22,29 @@ class TopicFeaturedUsers
|
||||||
topic.featured_user4_id].uniq.compact
|
topic.featured_user4_id].uniq.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.ensure_consistency!
|
def self.ensure_consistency!(topic_id=nil)
|
||||||
|
|
||||||
sql = <<SQL
|
sql = <<SQL
|
||||||
|
|
||||||
WITH cte as (
|
WITH cte as (
|
||||||
SELECT
|
SELECT
|
||||||
t.id, p.user_id,
|
t.id,
|
||||||
ROW_NUMBER() OVER(PARTITION BY t.id ORDER BY COUNT(*) DESC) as rank
|
p.user_id,
|
||||||
|
MAX(p.created_at) last_post_date,
|
||||||
|
ROW_NUMBER() OVER(PARTITION BY t.id ORDER BY COUNT(*) DESC, MAX(p.created_at) DESC) as rank
|
||||||
FROM topics t
|
FROM topics t
|
||||||
JOIN posts p ON p.topic_id = t.id
|
JOIN posts p ON p.topic_id = t.id
|
||||||
WHERE p.deleted_at IS NULL AND NOT p.hidden AND p.user_id <> t.user_id AND
|
WHERE p.deleted_at IS NULL AND
|
||||||
|
NOT p.hidden AND
|
||||||
|
p.user_id <> t.user_id AND
|
||||||
p.user_id <> t.last_post_user_id
|
p.user_id <> t.last_post_user_id
|
||||||
GROUP BY t.id, p.user_id
|
GROUP BY t.id, p.user_id
|
||||||
|
),
|
||||||
|
|
||||||
|
cte2 as (
|
||||||
|
SELECT id, user_id, ROW_NUMBER() OVER(PARTITION BY id ORDER BY last_post_date ASC) as rank
|
||||||
|
FROM cte
|
||||||
|
WHERE rank <= #{count}
|
||||||
)
|
)
|
||||||
|
|
||||||
UPDATE topics tt
|
UPDATE topics tt
|
||||||
|
@ -52,8 +60,7 @@ FROM (
|
||||||
MAX(case when c.rank = 2 then c.user_id end) featured_user2,
|
MAX(case when c.rank = 2 then c.user_id end) featured_user2,
|
||||||
MAX(case when c.rank = 3 then c.user_id end) featured_user3,
|
MAX(case when c.rank = 3 then c.user_id end) featured_user3,
|
||||||
MAX(case when c.rank = 4 then c.user_id end) featured_user4
|
MAX(case when c.rank = 4 then c.user_id end) featured_user4
|
||||||
FROM cte as c
|
FROM cte2 as c
|
||||||
WHERE c.rank <= 4
|
|
||||||
GROUP BY c.id
|
GROUP BY c.id
|
||||||
) x
|
) x
|
||||||
WHERE x.id = tt.id AND
|
WHERE x.id = tt.id AND
|
||||||
|
@ -62,7 +69,7 @@ WHERE x.id = tt.id AND
|
||||||
COALESCE(featured_user2_id,-99) <> COALESCE(featured_user2,-99) OR
|
COALESCE(featured_user2_id,-99) <> COALESCE(featured_user2,-99) OR
|
||||||
COALESCE(featured_user3_id,-99) <> COALESCE(featured_user3,-99) OR
|
COALESCE(featured_user3_id,-99) <> COALESCE(featured_user3,-99) OR
|
||||||
COALESCE(featured_user4_id,-99) <> COALESCE(featured_user4,-99)
|
COALESCE(featured_user4_id,-99) <> COALESCE(featured_user4,-99)
|
||||||
)
|
) #{"AND x.id = #{topic_id.to_i}" if topic_id}
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
Topic.exec_sql(sql)
|
Topic.exec_sql(sql)
|
||||||
|
@ -70,30 +77,7 @@ SQL
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def keys(args)
|
|
||||||
# Don't include the OP or the last poster
|
|
||||||
to_feature = topic.posts.where('user_id NOT IN (?, ?)', topic.user_id, topic.last_post_user_id)
|
|
||||||
|
|
||||||
# Exclude a given post if supplied (in the case of deletes)
|
|
||||||
to_feature = to_feature.where("id <> ?", args[:except_post_id]) if args[:except_post_id].present?
|
|
||||||
|
|
||||||
# Assign the featured_user{x} columns
|
|
||||||
to_feature.group(:user_id).order('count_all desc').limit(TopicFeaturedUsers.count).count.keys
|
|
||||||
end
|
|
||||||
|
|
||||||
def clear
|
|
||||||
TopicFeaturedUsers.count.times do |i|
|
|
||||||
topic.send("featured_user#{i+1}_id=", nil)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def update(user_keys)
|
|
||||||
user_keys.each_with_index do |user_id, i|
|
|
||||||
topic.send("featured_user#{i+1}_id=", user_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_participant_count
|
def update_participant_count
|
||||||
topic.participant_count = topic.posts.count('distinct user_id')
|
topic.update_columns(participant_count: topic.posts.count('distinct user_id'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,6 +19,7 @@ class PostOwnerChanger
|
||||||
|
|
||||||
@topic.update_statistics
|
@topic.update_statistics
|
||||||
@new_owner.user_stat.update(first_post_created_at: @new_owner.posts(true).order('created_at ASC').first.try(:created_at))
|
@new_owner.user_stat.update(first_post_created_at: @new_owner.posts(true).order('created_at ASC').first.try(:created_at))
|
||||||
|
@topic.save!
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -72,7 +72,6 @@ class PostDestroyer
|
||||||
if @post.topic
|
if @post.topic
|
||||||
make_previous_post_the_last_one
|
make_previous_post_the_last_one
|
||||||
clear_user_posted_flag
|
clear_user_posted_flag
|
||||||
feature_users_in_the_topic
|
|
||||||
Topic.reset_highest(@post.topic_id)
|
Topic.reset_highest(@post.topic_id)
|
||||||
end
|
end
|
||||||
trash_public_post_actions
|
trash_public_post_actions
|
||||||
|
@ -92,6 +91,7 @@ class PostDestroyer
|
||||||
TopicUser.update_post_action_cache(topic_id: @post.topic_id)
|
TopicUser.update_post_action_cache(topic_id: @post.topic_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature_users_in_the_topic if @post.topic
|
||||||
@post.publish_change_to_clients! :deleted if @post.topic
|
@post.publish_change_to_clients! :deleted if @post.topic
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ class PostDestroyer
|
||||||
end
|
end
|
||||||
|
|
||||||
def feature_users_in_the_topic
|
def feature_users_in_the_topic
|
||||||
Jobs.enqueue(:feature_topic_users, topic_id: @post.topic_id, except_post_id: @post.id)
|
Jobs.enqueue(:feature_topic_users, topic_id: @post.topic_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def trash_public_post_actions
|
def trash_public_post_actions
|
||||||
|
|
|
@ -291,7 +291,7 @@ describe PostDestroyer do
|
||||||
let!(:post) { Fabricate(:post, raw: "Hello @CodingHorror") }
|
let!(:post) { Fabricate(:post, raw: "Hello @CodingHorror") }
|
||||||
|
|
||||||
it "should feature the users again (in case they've changed)" do
|
it "should feature the users again (in case they've changed)" do
|
||||||
Jobs.expects(:enqueue).with(:feature_topic_users, has_entries(topic_id: post.topic_id, except_post_id: post.id))
|
Jobs.expects(:enqueue).with(:feature_topic_users, has_entries(topic_id: post.topic_id))
|
||||||
PostDestroyer.new(moderator, post).destroy
|
PostDestroyer.new(moderator, post).destroy
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,6 @@ describe Jobs::FeatureTopicUsers do
|
||||||
expect(topic.reload.featured_user_ids.include?(coding_horror.id)).to eq(true)
|
expect(topic.reload.featured_user_ids.include?(coding_horror.id)).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "will not feature the second poster if we supply their post to be ignored" do
|
|
||||||
Jobs::FeatureTopicUsers.new.execute(topic_id: topic.id, except_post_id: second_post.id)
|
|
||||||
expect(topic.reload.featured_user_ids.include?(coding_horror.id)).to eq(false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "won't feature the last poster" do
|
it "won't feature the last poster" do
|
||||||
Jobs::FeatureTopicUsers.new.execute(topic_id: topic.id)
|
Jobs::FeatureTopicUsers.new.execute(topic_id: topic.id)
|
||||||
expect(topic.reload.featured_user_ids.include?(evil_trout.id)).to eq(false)
|
expect(topic.reload.featured_user_ids.include?(evil_trout.id)).to eq(false)
|
||||||
|
|
Loading…
Reference in New Issue