status_controller_concern.rb 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. # frozen_string_literal: true
  2. module StatusControllerConcern
  3. extend ActiveSupport::Concern
  4. ANCESTORS_LIMIT = 40
  5. DESCENDANTS_LIMIT = 60
  6. DESCENDANTS_DEPTH_LIMIT = 20
  7. def create_descendant_thread(starting_depth, statuses)
  8. depth = starting_depth + statuses.size
  9. if depth < DESCENDANTS_DEPTH_LIMIT
  10. {
  11. statuses: statuses,
  12. starting_depth: starting_depth,
  13. }
  14. else
  15. next_status = statuses.pop
  16. {
  17. statuses: statuses,
  18. starting_depth: starting_depth,
  19. next_status: next_status,
  20. }
  21. end
  22. end
  23. def set_ancestors
  24. @ancestors = @status.reply? ? cache_collection(@status.ancestors(ANCESTORS_LIMIT, current_account), Status) : []
  25. @next_ancestor = @ancestors.size < ANCESTORS_LIMIT ? nil : @ancestors.shift
  26. end
  27. def set_descendants
  28. @max_descendant_thread_id = params[:max_descendant_thread_id]&.to_i
  29. @since_descendant_thread_id = params[:since_descendant_thread_id]&.to_i
  30. descendants = cache_collection(
  31. @status.descendants(
  32. DESCENDANTS_LIMIT,
  33. current_account,
  34. @max_descendant_thread_id,
  35. @since_descendant_thread_id,
  36. DESCENDANTS_DEPTH_LIMIT
  37. ),
  38. Status
  39. )
  40. @descendant_threads = []
  41. if descendants.present?
  42. statuses = [descendants.first]
  43. starting_depth = 0
  44. descendants.drop(1).each_with_index do |descendant, index|
  45. if descendants[index].id == descendant.in_reply_to_id
  46. statuses << descendant
  47. else
  48. @descendant_threads << create_descendant_thread(starting_depth, statuses)
  49. # The thread is broken, assume it's a reply to the root status
  50. starting_depth = 0
  51. # ... unless we can find its ancestor in one of the already-processed threads
  52. @descendant_threads.reverse_each do |descendant_thread|
  53. statuses = descendant_thread[:statuses]
  54. index = statuses.find_index do |thread_status|
  55. thread_status.id == descendant.in_reply_to_id
  56. end
  57. if index.present?
  58. starting_depth = descendant_thread[:starting_depth] + index + 1
  59. break
  60. end
  61. end
  62. statuses = [descendant]
  63. end
  64. end
  65. @descendant_threads << create_descendant_thread(starting_depth, statuses)
  66. end
  67. @max_descendant_thread_id = @descendant_threads.pop[:statuses].first.id if descendants.size >= DESCENDANTS_LIMIT
  68. end
  69. end