forked from treehouse/mastodon
Give the `replies` collection an identifier and enable pagination (#10128)
parent
9d3c6f1849
commit
d8498b3983
|
@ -18,6 +18,7 @@ class StatusesController < ApplicationController
|
||||||
before_action :redirect_to_original, only: [:show]
|
before_action :redirect_to_original, only: [:show]
|
||||||
before_action :set_referrer_policy_header, only: [:show]
|
before_action :set_referrer_policy_header, only: [:show]
|
||||||
before_action :set_cache_headers
|
before_action :set_cache_headers
|
||||||
|
before_action :set_replies, only: [:replies]
|
||||||
|
|
||||||
content_security_policy only: :embed do |p|
|
content_security_policy only: :embed do |p|
|
||||||
p.frame_ancestors(false)
|
p.frame_ancestors(false)
|
||||||
|
@ -63,8 +64,37 @@ class StatusesController < ApplicationController
|
||||||
render 'stream_entries/embed', layout: 'embedded'
|
render 'stream_entries/embed', layout: 'embedded'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def replies
|
||||||
|
skip_session!
|
||||||
|
|
||||||
|
render json: replies_collection_presenter,
|
||||||
|
serializer: ActivityPub::CollectionSerializer,
|
||||||
|
adapter: ActivityPub::Adapter,
|
||||||
|
content_type: 'application/activity+json',
|
||||||
|
skip_activities: true
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def replies_collection_presenter
|
||||||
|
page = ActivityPub::CollectionPresenter.new(
|
||||||
|
id: replies_account_status_url(@account, @status, page_params),
|
||||||
|
type: :unordered,
|
||||||
|
part_of: replies_account_status_url(@account, @status),
|
||||||
|
next: next_page,
|
||||||
|
items: @replies.map { |status| status.local ? status : status.id }
|
||||||
|
)
|
||||||
|
if page_requested?
|
||||||
|
page
|
||||||
|
else
|
||||||
|
ActivityPub::CollectionPresenter.new(
|
||||||
|
id: replies_account_status_url(@account, @status),
|
||||||
|
type: :unordered,
|
||||||
|
first: page
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def create_descendant_thread(starting_depth, statuses)
|
def create_descendant_thread(starting_depth, statuses)
|
||||||
depth = starting_depth + statuses.size
|
depth = starting_depth + statuses.size
|
||||||
if depth < DESCENDANTS_DEPTH_LIMIT
|
if depth < DESCENDANTS_DEPTH_LIMIT
|
||||||
|
@ -174,4 +204,27 @@ class StatusesController < ApplicationController
|
||||||
return if @status.public_visibility? || @status.unlisted_visibility?
|
return if @status.public_visibility? || @status.unlisted_visibility?
|
||||||
response.headers['Referrer-Policy'] = 'origin'
|
response.headers['Referrer-Policy'] = 'origin'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def page_requested?
|
||||||
|
params[:page] == 'true'
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_replies
|
||||||
|
@replies = page_params[:other_accounts] ? Status.where.not(account_id: @account.id) : @account.statuses
|
||||||
|
@replies = @replies.where(in_reply_to_id: @status.id, visibility: [:public, :unlisted])
|
||||||
|
@replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def next_page
|
||||||
|
last_reply = @replies.last
|
||||||
|
return if last_reply.nil?
|
||||||
|
same_account = last_reply.account_id == @account.id
|
||||||
|
return unless same_account || @replies.size == DESCENDANTS_LIMIT
|
||||||
|
same_account = false unless @replies.size == DESCENDANTS_LIMIT
|
||||||
|
replies_account_status_url(@account, @status, page: true, min_id: last_reply.id, other_accounts: !same_account)
|
||||||
|
end
|
||||||
|
|
||||||
|
def page_params
|
||||||
|
{ page: true, other_accounts: params[:other_accounts], min_id: params[:min_id] }.compact
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,6 +48,12 @@ class ActivityPub::TagManager
|
||||||
activity_account_status_url(target.account, target)
|
activity_account_status_url(target.account, target)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def replies_uri_for(target, page_params = nil)
|
||||||
|
raise ArgumentError, 'target must be a local activity' unless %i(note comment activity).include?(target.object_type) && target.local?
|
||||||
|
|
||||||
|
replies_account_status_url(target.account, target, page_params)
|
||||||
|
end
|
||||||
|
|
||||||
# Primary audience of a status
|
# Primary audience of a status
|
||||||
# Public statuses go out to primarily the public collection
|
# Public statuses go out to primarily the public collection
|
||||||
# Unlisted and private statuses go out primarily to the followers collection
|
# Unlisted and private statuses go out primarily to the followers collection
|
||||||
|
|
|
@ -13,7 +13,7 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
|
||||||
has_many :media_attachments, key: :attachment
|
has_many :media_attachments, key: :attachment
|
||||||
has_many :virtual_tags, key: :tag
|
has_many :virtual_tags, key: :tag
|
||||||
|
|
||||||
has_one :replies, serializer: ActivityPub::CollectionSerializer
|
has_one :replies, serializer: ActivityPub::CollectionSerializer, if: :local?
|
||||||
|
|
||||||
def id
|
def id
|
||||||
ActivityPub::TagManager.instance.uri_for(object)
|
ActivityPub::TagManager.instance.uri_for(object)
|
||||||
|
@ -36,12 +36,16 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def replies
|
def replies
|
||||||
|
replies = object.self_replies(5).pluck(:id, :uri)
|
||||||
|
last_id = replies.last&.first
|
||||||
ActivityPub::CollectionPresenter.new(
|
ActivityPub::CollectionPresenter.new(
|
||||||
type: :unordered,
|
type: :unordered,
|
||||||
|
id: ActivityPub::TagManager.instance.replies_uri_for(object),
|
||||||
first: ActivityPub::CollectionPresenter.new(
|
first: ActivityPub::CollectionPresenter.new(
|
||||||
type: :unordered,
|
type: :unordered,
|
||||||
page: true,
|
part_of: ActivityPub::TagManager.instance.replies_uri_for(object),
|
||||||
items: object.self_replies(5).pluck(:uri)
|
items: replies.map(&:second),
|
||||||
|
next: last_id ? ActivityPub::TagManager.instance.replies_uri_for(object, page: true, min_id: last_id) : nil
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -56,6 +56,7 @@ Rails.application.routes.draw do
|
||||||
member do
|
member do
|
||||||
get :activity
|
get :activity
|
||||||
get :embed
|
get :embed
|
||||||
|
get :replies
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue