88 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # frozen_string_literal: true
 | |
| 
 | |
| module StatusControllerConcern
 | |
|   extend ActiveSupport::Concern
 | |
| 
 | |
|   ANCESTORS_LIMIT         = 40
 | |
|   DESCENDANTS_LIMIT       = 60
 | |
|   DESCENDANTS_DEPTH_LIMIT = 20
 | |
| 
 | |
|   def create_descendant_thread(starting_depth, statuses)
 | |
|     depth = starting_depth + statuses.size
 | |
| 
 | |
|     if depth < DESCENDANTS_DEPTH_LIMIT
 | |
|       {
 | |
|         statuses: statuses,
 | |
|         starting_depth: starting_depth,
 | |
|       }
 | |
|     else
 | |
|       next_status = statuses.pop
 | |
| 
 | |
|       {
 | |
|         statuses: statuses,
 | |
|         starting_depth: starting_depth,
 | |
|         next_status: next_status,
 | |
|       }
 | |
|     end
 | |
|   end
 | |
| 
 | |
|   def set_ancestors
 | |
|     @ancestors     = @status.reply? ? cache_collection(@status.ancestors(ANCESTORS_LIMIT, current_account), Status) : []
 | |
|     @next_ancestor = @ancestors.size < ANCESTORS_LIMIT ? nil : @ancestors.shift
 | |
|   end
 | |
| 
 | |
|   def set_descendants
 | |
|     @max_descendant_thread_id   = params[:max_descendant_thread_id]&.to_i
 | |
|     @since_descendant_thread_id = params[:since_descendant_thread_id]&.to_i
 | |
| 
 | |
|     descendants = cache_collection(
 | |
|       @status.descendants(
 | |
|         DESCENDANTS_LIMIT,
 | |
|         current_account,
 | |
|         @max_descendant_thread_id,
 | |
|         @since_descendant_thread_id,
 | |
|         DESCENDANTS_DEPTH_LIMIT
 | |
|       ),
 | |
|       Status
 | |
|     )
 | |
| 
 | |
|     @descendant_threads = []
 | |
| 
 | |
|     if descendants.present?
 | |
|       statuses       = [descendants.first]
 | |
|       starting_depth = 0
 | |
| 
 | |
|       descendants.drop(1).each_with_index do |descendant, index|
 | |
|         if descendants[index].id == descendant.in_reply_to_id
 | |
|           statuses << descendant
 | |
|         else
 | |
|           @descendant_threads << create_descendant_thread(starting_depth, statuses)
 | |
| 
 | |
|           # The thread is broken, assume it's a reply to the root status
 | |
|           starting_depth = 0
 | |
| 
 | |
|           # ... unless we can find its ancestor in one of the already-processed threads
 | |
|           @descendant_threads.reverse_each do |descendant_thread|
 | |
|             statuses = descendant_thread[:statuses]
 | |
| 
 | |
|             index = statuses.find_index do |thread_status|
 | |
|               thread_status.id == descendant.in_reply_to_id
 | |
|             end
 | |
| 
 | |
|             if index.present?
 | |
|               starting_depth = descendant_thread[:starting_depth] + index + 1
 | |
|               break
 | |
|             end
 | |
|           end
 | |
| 
 | |
|           statuses = [descendant]
 | |
|         end
 | |
|       end
 | |
| 
 | |
|       @descendant_threads << create_descendant_thread(starting_depth, statuses)
 | |
|     end
 | |
| 
 | |
|     @max_descendant_thread_id = @descendant_threads.pop[:statuses].first.id if descendants.size >= DESCENDANTS_LIMIT
 | |
|   end
 | |
| end
 |