Show Gaps in the post stream when filters are active

Conflicts:
	app/assets/javascripts/discourse/templates/topic.js.handlebars
This commit is contained in:
Robin Ward
2013-12-05 16:46:59 -05:00
parent 0fe5ecbb24
commit 79427732b2
14 changed files with 364 additions and 49 deletions
+54
View File
@@ -0,0 +1,54 @@
#
# This is used for finding the gaps between a subset of elements in an array
# and the original layout. We use this in Discourse to find gaps between posts.
#
# Note that we will only return a gap as 'before' or 'after', not both. We only
# want to display the gap once.
#
class Gaps
attr_reader :before, :after
def initialize(subset, original)
@before = {}
@after = {}
@subset = subset
@original = original
find_gaps
end
def empty?
@before.size == 0 && @after.size == 0
end
def find_gaps
return if @subset.nil? or @original.nil?
i = j = 0
gaps = {}
current_gap = []
while
e1 = @subset[i]
e2 = @original[j]
if (e1 == e2)
if current_gap.size > 0
@before[e1] = current_gap.dup
current_gap = []
end
i = i + 1
else
current_gap << e2
end
j = j + 1
break if (i == @subset.size) || (j == @original.size)
end
@after[@subset[i-1]] = @original[j..-1] if j < @original.size
end
end
+38 -8
View File
@@ -2,6 +2,7 @@ require_dependency 'guardian'
require_dependency 'topic_query'
require_dependency 'filter_best_posts'
require_dependency 'summarize'
require_dependency 'gaps'
class TopicView
@@ -44,6 +45,15 @@ class TopicView
path
end
def contains_gaps?
@contains_gaps
end
def gaps
return unless @contains_gaps
Gaps.new(filtered_post_ids, unfiltered_posts.order(:sort_order).pluck(:id))
end
def last_post
return nil if @posts.blank?
@last_post ||= @posts.last
@@ -113,9 +123,7 @@ class TopicView
# Filter to all posts near a particular post number
def filter_posts_near(post_number)
min_idx, max_idx = get_minmax_ids(post_number)
filter_posts_in_range(min_idx, max_idx)
end
@@ -255,14 +263,36 @@ class TopicView
finder.first
end
def unfiltered_posts
result = @topic.posts.where(hidden: false)
result = result.with_deleted if @user.try(:staff?)
result
end
def setup_filtered_posts
@filtered_posts = @topic.posts.where(hidden: false)
# Certain filters might leave gaps between posts. If that's true, we can return a gap structure
@contains_gaps = false
@filtered_posts = unfiltered_posts
@filtered_posts = @filtered_posts.with_deleted if @user.try(:staff?)
@filtered_posts = @filtered_posts.summary if @filter == 'summary'
@filtered_posts = @filtered_posts.where('posts.post_type <> ?', Post.types[:moderator_action]) if @best.present?
return unless @username_filters.present?
usernames = @username_filters.map{|u| u.downcase}
@filtered_posts = @filtered_posts.where('post_number = 1 or user_id in (select u.id from users u where username_lower in (?))', usernames)
# Filters
if @filter == 'summary'
@filtered_posts = @filtered_posts.summary
@contains_gaps = true
end
if @best.present?
@filtered_posts = @filtered_posts.where('posts.post_type <> ?', Post.types[:moderator_action])
@contains_gaps = true
end
if @username_filters.present?
usernames = @username_filters.map{|u| u.downcase}
@filtered_posts = @filtered_posts.where('post_number = 1 or user_id in (select u.id from users u where username_lower in (?))', usernames)
@contains_gaps = true
end
end
def check_and_raise_exceptions