@@ -18,6 +18,7 @@ class StatusesController < ApplicationController
1818 before_action :redirect_to_original , only : [ :show ]
1919 before_action :set_referrer_policy_header , only : [ :show ]
2020 before_action :set_cache_headers
21+ before_action :set_replies , only : [ :replies ]
2122
2223 content_security_policy only : :embed do |p |
2324 p . frame_ancestors ( false )
@@ -63,8 +64,37 @@ def embed
6364 render 'stream_entries/embed' , layout : 'embedded'
6465 end
6566
67+ def replies
68+ skip_session!
69+
70+ render json : replies_collection_presenter ,
71+ serializer : ActivityPub ::CollectionSerializer ,
72+ adapter : ActivityPub ::Adapter ,
73+ content_type : 'application/activity+json' ,
74+ skip_activities : true
75+ end
76+
6677 private
6778
79+ def replies_collection_presenter
80+ page = ActivityPub ::CollectionPresenter . new (
81+ id : replies_account_status_url ( @account , @status , page_params ) ,
82+ type : :unordered ,
83+ part_of : replies_account_status_url ( @account , @status ) ,
84+ next : next_page ,
85+ items : @replies . map { |status | status . local ? status : status . id }
86+ )
87+ if page_requested?
88+ page
89+ else
90+ ActivityPub ::CollectionPresenter . new (
91+ id : replies_account_status_url ( @account , @status ) ,
92+ type : :unordered ,
93+ first : page
94+ )
95+ end
96+ end
97+
6898 def create_descendant_thread ( starting_depth , statuses )
6999 depth = starting_depth + statuses . size
70100 if depth < DESCENDANTS_DEPTH_LIMIT
@@ -174,4 +204,27 @@ def set_referrer_policy_header
174204 return if @status . public_visibility? || @status . unlisted_visibility?
175205 response . headers [ 'Referrer-Policy' ] = 'origin'
176206 end
207+
208+ def page_requested?
209+ params [ :page ] == 'true'
210+ end
211+
212+ def set_replies
213+ @replies = page_params [ :other_accounts ] ? Status . where . not ( account_id : @account . id ) : @account . statuses
214+ @replies = @replies . where ( in_reply_to_id : @status . id , visibility : [ :public , :unlisted ] )
215+ @replies = @replies . paginate_by_min_id ( DESCENDANTS_LIMIT , params [ :min_id ] )
216+ end
217+
218+ def next_page
219+ last_reply = @replies . last
220+ return if last_reply . nil?
221+ same_account = last_reply . account_id == @account . id
222+ return unless same_account || @replies . size == DESCENDANTS_LIMIT
223+ same_account = false unless @replies . size == DESCENDANTS_LIMIT
224+ replies_account_status_url ( @account , @status , page : true , min_id : last_reply . id , other_accounts : !same_account )
225+ end
226+
227+ def page_params
228+ { page : true , other_accounts : params [ :other_accounts ] , min_id : params [ :min_id ] } . compact
229+ end
177230end
0 commit comments