Add conversation-based forwarding for limited visibility statuses through bearcaps
This commit is contained in:
parent
52157fdcba
commit
7cd4ed7d42
26 changed files with 430 additions and 78 deletions
|
@ -90,6 +90,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
fetch_replies(@status)
|
||||
check_for_spam
|
||||
distribute(@status)
|
||||
forward_for_conversation
|
||||
forward_for_reply
|
||||
end
|
||||
|
||||
|
@ -114,7 +115,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
sensitive: @object['sensitive'] || false,
|
||||
visibility: visibility_from_audience,
|
||||
thread: replied_to_status,
|
||||
conversation: conversation_from_uri(@object['conversation']),
|
||||
conversation: conversation_from_context,
|
||||
media_attachment_ids: process_attachments.take(4).map(&:id),
|
||||
poll: process_poll,
|
||||
}
|
||||
|
@ -122,8 +123,10 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
end
|
||||
|
||||
def process_audience
|
||||
conversation_uri = value_or_id(@object['context'])
|
||||
|
||||
(audience_to + audience_cc).uniq.each do |audience|
|
||||
next if audience == ActivityPub::TagManager::COLLECTIONS[:public]
|
||||
next if audience == ActivityPub::TagManager::COLLECTIONS[:public] || audience == conversation_uri
|
||||
|
||||
# Unlike with tags, there is no point in resolving accounts we don't already
|
||||
# know here, because silent mentions would only be used for local access
|
||||
|
@ -340,15 +343,45 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
ActivityPub::FetchRepliesWorker.perform_async(status.id, uri) unless uri.nil?
|
||||
end
|
||||
|
||||
def conversation_from_uri(uri)
|
||||
return nil if uri.nil?
|
||||
return Conversation.find_by(id: OStatus::TagManager.instance.unique_tag_to_local_id(uri, 'Conversation')) if OStatus::TagManager.instance.local_id?(uri)
|
||||
def conversation_from_context
|
||||
atom_uri = @object['conversation']
|
||||
|
||||
begin
|
||||
Conversation.find_or_create_by!(uri: uri)
|
||||
rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique
|
||||
retry
|
||||
conversation = begin
|
||||
if atom_uri.present? && OStatus::TagManager.instance.local_id?(atom_uri)
|
||||
Conversation.find_by(id: OStatus::TagManager.instance.unique_tag_to_local_id(atom_uri, 'Conversation'))
|
||||
elsif atom_uri.present? && @object['context'].present?
|
||||
Conversation.find_by(uri: atom_uri)
|
||||
elsif atom_uri.present?
|
||||
begin
|
||||
Conversation.find_or_create_by!(uri: atom_uri)
|
||||
rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique
|
||||
retry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return conversation if @object['context'].nil?
|
||||
|
||||
uri = value_or_id(@object['context'])
|
||||
conversation ||= ActivityPub::TagManager.instance.uri_to_resource(uri, Conversation)
|
||||
|
||||
return conversation if (conversation.present? && conversation.uri == uri) || !uri.start_with?('https://')
|
||||
|
||||
conversation_json = begin
|
||||
if @object['context'].is_a?(Hash) && !invalid_origin?(uri)
|
||||
@object['context']
|
||||
else
|
||||
fetch_resource(uri, true)
|
||||
end
|
||||
end
|
||||
|
||||
return conversation if conversation_json.blank?
|
||||
|
||||
conversation ||= Conversation.new
|
||||
conversation.uri = uri
|
||||
conversation.inbox_url = conversation_json['inbox']
|
||||
conversation.save! if conversation.changed?
|
||||
conversation
|
||||
end
|
||||
|
||||
def visibility_from_audience
|
||||
|
@ -492,6 +525,12 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
SpamCheck.perform(@status)
|
||||
end
|
||||
|
||||
def forward_for_conversation
|
||||
return unless audience_to.include?(value_or_id(@object['context'])) && @json['signature'].present? && @status.conversation.local?
|
||||
|
||||
ActivityPub::ForwardDistributionWorker.perform_async(@status.conversation_id, Oj.dump(@json))
|
||||
end
|
||||
|
||||
def forward_for_reply
|
||||
return unless @status.distributable? && @json['signature'].present? && reply_to_local?
|
||||
|
||||
|
|
|
@ -21,8 +21,11 @@ class ActivityPub::TagManager
|
|||
when :person
|
||||
target.instance_actor? ? about_more_url(instance_actor: true) : short_account_url(target)
|
||||
when :note, :comment, :activity
|
||||
return activity_account_status_url(target.account, target) if target.reblog?
|
||||
short_account_status_url(target.account, target)
|
||||
if target.reblog?
|
||||
activity_account_status_url(target.account, target)
|
||||
else
|
||||
short_account_status_url(target.account, target)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -33,10 +36,15 @@ class ActivityPub::TagManager
|
|||
when :person
|
||||
target.instance_actor? ? instance_actor_url : account_url(target)
|
||||
when :note, :comment, :activity
|
||||
return activity_account_status_url(target.account, target) if target.reblog?
|
||||
account_status_url(target.account, target)
|
||||
if target.reblog?
|
||||
activity_account_status_url(target.account, target)
|
||||
else
|
||||
account_status_url(target.account, target)
|
||||
end
|
||||
when :emoji
|
||||
emoji_url(target)
|
||||
when :conversation
|
||||
context_url(target)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -66,7 +74,9 @@ class ActivityPub::TagManager
|
|||
[COLLECTIONS[:public]]
|
||||
when 'unlisted', 'private'
|
||||
[account_followers_url(status.account)]
|
||||
when 'direct', 'limited'
|
||||
when 'limited'
|
||||
status.conversation_id.present? ? [uri_for(status.conversation)] : []
|
||||
when 'direct'
|
||||
if status.account.silenced?
|
||||
# Only notify followers if the account is locally silenced
|
||||
account_ids = status.active_mentions.pluck(:account_id)
|
||||
|
@ -104,7 +114,7 @@ class ActivityPub::TagManager
|
|||
cc << COLLECTIONS[:public]
|
||||
end
|
||||
|
||||
unless status.direct_visibility? || status.limited_visibility?
|
||||
unless status.direct_visibility?
|
||||
if status.account.silenced?
|
||||
# Only notify followers if the account is locally silenced
|
||||
account_ids = status.active_mentions.pluck(:account_id)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue