mirror of
https://github.com/discourse/discourse.git
synced 2025-05-22 02:41:13 +08:00
DEV: Add backend support for unread and new topics list (#20293)
This commit adds backend support for a new topics list that combines both the current unread and new topics lists. We're going to experiment with this new list (name TBD) internally and decide if this feature is something that we want to fully build. Internal topic: t/77234.
This commit is contained in:
@ -507,21 +507,7 @@ class TopicQuery
|
||||
whisperer: @user&.whisperer?,
|
||||
).order("CASE WHEN topics.user_id = tu.user_id THEN 1 ELSE 2 END")
|
||||
|
||||
if @user
|
||||
# micro optimisation so we don't load up all of user stats which we do not need
|
||||
unread_at =
|
||||
DB.query_single("select first_unread_at from user_stats where user_id = ?", @user.id).first
|
||||
|
||||
if max_age = options[:max_age]
|
||||
max_age_date = max_age.days.ago
|
||||
unread_at ||= max_age_date
|
||||
unread_at = unread_at > max_age_date ? unread_at : max_age_date
|
||||
end
|
||||
|
||||
# perf note, in the past we tried doing this in a subquery but performance was
|
||||
# terrible, also tried with a join and it was bad
|
||||
result = result.where("topics.updated_at >= ?", unread_at)
|
||||
end
|
||||
result = apply_max_age_limit(result, options)
|
||||
|
||||
self.class.results_filter_callbacks.each do |filter_callback|
|
||||
result = filter_callback.call(:unread, result, @user, options)
|
||||
@ -548,6 +534,28 @@ class TopicQuery
|
||||
suggested_ordering(result, options)
|
||||
end
|
||||
|
||||
def new_and_unread_results(options = {})
|
||||
base = default_results(options.reverse_merge(unordered: true))
|
||||
|
||||
new_results =
|
||||
TopicQuery.new_filter(
|
||||
base,
|
||||
treat_as_new_topic_start_date: @user.user_option.treat_as_new_topic_start_date,
|
||||
)
|
||||
new_results = remove_muted(new_results, @user, options)
|
||||
new_results = remove_dismissed(new_results, @user)
|
||||
|
||||
unread_results =
|
||||
apply_max_age_limit(TopicQuery.unread_filter(base, whisperer: @user&.whisperer?), options)
|
||||
|
||||
base.joins_values.concat(new_results.joins_values, unread_results.joins_values)
|
||||
base.joins_values.uniq!
|
||||
results = base.merge(new_results.or(unread_results))
|
||||
|
||||
results = results.order("CASE WHEN topics.user_id = tu.user_id THEN 1 ELSE 2 END")
|
||||
suggested_ordering(results, options)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def per_page_setting
|
||||
@ -1167,4 +1175,23 @@ class TopicQuery
|
||||
col_name = whisperer ? "highest_staff_post_number" : "highest_post_number"
|
||||
list.where("tu.last_read_post_number IS NULL OR tu.last_read_post_number < topics.#{col_name}")
|
||||
end
|
||||
|
||||
def apply_max_age_limit(results, options)
|
||||
if @user
|
||||
# micro optimisation so we don't load up all of user stats which we do not need
|
||||
unread_at =
|
||||
DB.query_single("select first_unread_at from user_stats where user_id = ?", @user.id).first
|
||||
|
||||
if max_age = options[:max_age]
|
||||
max_age_date = max_age.days.ago
|
||||
unread_at ||= max_age_date
|
||||
unread_at = unread_at > max_age_date ? unread_at : max_age_date
|
||||
end
|
||||
|
||||
# perf note, in the past we tried doing this in a subquery but performance was
|
||||
# terrible, also tried with a join and it was bad
|
||||
results = results.where("topics.updated_at >= ?", unread_at)
|
||||
end
|
||||
results
|
||||
end
|
||||
end
|
||||
|
Reference in New Issue
Block a user