You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
2.2 KiB

  1. # frozen_string_literal: true
  2. class ActivityPub::RepliesController < ActivityPub::BaseController
  3. include SignatureVerification
  4. include Authorization
  5. include AccountOwnedConcern
  6. DESCENDANTS_LIMIT = 60
  7. before_action :require_signature!, if: :authorized_fetch_mode?
  8. before_action :set_status
  9. before_action :set_cache_headers
  10. before_action :set_replies
  11. def index
  12. expires_in 0, public: public_fetch_mode?
  13. render json: replies_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', skip_activities: true
  14. end
  15. private
  16. def pundit_user
  17. signed_request_account
  18. end
  19. def set_status
  20. @status = @account.statuses.find(params[:status_id])
  21. authorize @status, :show?
  22. rescue Mastodon::NotPermittedError
  23. not_found
  24. end
  25. def set_replies
  26. @replies = only_other_accounts? ? Status.where.not(account_id: @account.id) : @account.statuses
  27. @replies = @replies.where(in_reply_to_id: @status.id, visibility: [:public, :unlisted])
  28. @replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id])
  29. end
  30. def replies_collection_presenter
  31. page = ActivityPub::CollectionPresenter.new(
  32. id: account_status_replies_url(@account, @status, page_params),
  33. type: :unordered,
  34. part_of: account_status_replies_url(@account, @status),
  35. next: next_page,
  36. items: @replies.map { |status| status.local? ? status : status.uri }
  37. )
  38. return page if page_requested?
  39. ActivityPub::CollectionPresenter.new(
  40. id: account_status_replies_url(@account, @status),
  41. type: :unordered,
  42. first: page
  43. )
  44. end
  45. def page_requested?
  46. truthy_param?(:page)
  47. end
  48. def only_other_accounts?
  49. truthy_param?(:only_other_accounts)
  50. end
  51. def next_page
  52. only_other_accounts = !(@replies&.last&.account_id == @account.id && @replies.size == DESCENDANTS_LIMIT)
  53. account_status_replies_url(
  54. @account,
  55. @status,
  56. page: true,
  57. min_id: only_other_accounts && !only_other_accounts? ? nil : @replies&.last&.id,
  58. only_other_accounts: only_other_accounts
  59. )
  60. end
  61. def page_params
  62. params_slice(:only_other_accounts, :min_id).merge(page: true)
  63. end
  64. end