FEATURE: apply pinning to hot topic lists (#25690)

pinned topics should be pinned even on hot lists so it can be used as a
home page
This commit is contained in:
Sam 2024-02-15 18:27:54 +11:00 committed by GitHub
parent 55df52b56d
commit 4346abe260
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 6 deletions

View File

@ -48,7 +48,9 @@ class TopicHotScore < ActiveRecord::Base
AND topics.deleted_at IS NULL AND topics.deleted_at IS NULL
AND topics.archetype <> :private_message AND topics.archetype <> :private_message
AND topics.created_at <= :now AND topics.created_at <= :now
ORDER BY topics.bumped_at desc ORDER BY
CASE WHEN topics.pinned_at IS NOT NULL THEN 0 ELSE 1 END ASC,
topics.bumped_at desc
LIMIT :max LIMIT :max
SQL SQL

View File

@ -339,7 +339,7 @@ class TopicQuery
end end
def list_hot def list_hot
create_list(:hot, unordered: true) do |topics| create_list(:hot, unordered: true, prioritize_pinned: true) do |topics|
topics = remove_muted_topics(topics, user) topics = remove_muted_topics(topics, user)
topics = remove_muted_categories(topics, user, exclude: options[:category]) topics = remove_muted_categories(topics, user, exclude: options[:category])
TopicQuery.remove_muted_tags(topics, user, options) TopicQuery.remove_muted_tags(topics, user, options)
@ -506,10 +506,12 @@ class TopicQuery
DiscoursePluginRegistry.apply_modifier(:topic_query_create_list_topics, topics, options, self) DiscoursePluginRegistry.apply_modifier(:topic_query_create_list_topics, topics, options, self)
options = options.merge(@options) options = options.merge(@options)
if %w[activity default].include?(options[:order] || "activity") && !options[:unordered] &&
filter != :private_messages apply_pinning = filter != :private_messages
topics = prioritize_pinned_topics(topics, options) apply_pinning &&= %w[activity default].include?(options[:order] || "activity")
end apply_pinning &&= !options[:unordered] || options[:prioritize_pinned]
topics = prioritize_pinned_topics(topics, options) if apply_pinning
topics = topics.to_a topics = topics.to_a

View File

@ -76,6 +76,25 @@ RSpec.describe TopicQuery do
end end
describe "#list_hot" do describe "#list_hot" do
it "keeps pinned topics on top" do
pinned_topic =
Fabricate(
:topic,
created_at: 1.hour.ago,
pinned_at: 1.hour.ago,
pinned_globally: true,
like_count: 1,
)
_topic = Fabricate(:topic, created_at: 5.minute.ago, like_count: 100)
topic = Fabricate(:topic, created_at: 1.minute.ago, like_count: 100)
# pinned topic is older so generally it would not hit the batch without
# extra special logic
TopicHotScore.update_scores(2)
expect(TopicQuery.new(nil).list_hot.topics.map(&:id)).to eq([pinned_topic.id, topic.id])
end
it "excludes muted categories and topics" do it "excludes muted categories and topics" do
muted_category = Fabricate(:category) muted_category = Fabricate(:category)
muted_topic = Fabricate(:topic, category: muted_category) muted_topic = Fabricate(:topic, category: muted_category)