Add polls (#10111)
* Add polls Fix #1629 * Add tests * Fixes * Change API for creating polls * Use name instead of content for votes * Remove poll validation for remote polls * Add polls to public pages * When updating the poll, update options just in case they were changed * Fix public pages showing both poll and other media
This commit is contained in:
parent
99dc212ae5
commit
230a012f00
47 changed files with 1038 additions and 19 deletions
|
@ -4,7 +4,7 @@ class ActivityPub::Activity
|
|||
include JsonLdHelper
|
||||
include Redisable
|
||||
|
||||
SUPPORTED_TYPES = %w(Note).freeze
|
||||
SUPPORTED_TYPES = %w(Note Question).freeze
|
||||
CONVERTED_TYPES = %w(Image Video Article Page).freeze
|
||||
|
||||
def initialize(json, account, **options)
|
||||
|
|
|
@ -6,7 +6,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
|
||||
RedisLock.acquire(lock_options) do |lock|
|
||||
if lock.acquired?
|
||||
return if delete_arrived_first?(object_uri)
|
||||
return if delete_arrived_first?(object_uri) || poll_vote?
|
||||
|
||||
@status = find_existing_status
|
||||
|
||||
|
@ -68,6 +68,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
thread: replied_to_status,
|
||||
conversation: conversation_from_uri(@object['conversation']),
|
||||
media_attachment_ids: process_attachments.take(4).map(&:id),
|
||||
owned_poll: process_poll,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -209,6 +210,41 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
media_attachments
|
||||
end
|
||||
|
||||
def process_poll
|
||||
return unless @object['type'] == 'Question' && (@object['anyOf'].is_a?(Array) || @object['oneOf'].is_a?(Array))
|
||||
|
||||
expires_at = begin
|
||||
if @object['closed'].is_a?(String)
|
||||
@object['closed']
|
||||
elsif !@object['closed'].is_a?(FalseClass)
|
||||
Time.now.utc
|
||||
else
|
||||
@object['endTime']
|
||||
end
|
||||
end
|
||||
|
||||
if @object['anyOf'].is_a?(Array)
|
||||
multiple = true
|
||||
items = @object['anyOf']
|
||||
else
|
||||
multiple = false
|
||||
items = @object['oneOf']
|
||||
end
|
||||
|
||||
Poll.new(
|
||||
account: @account,
|
||||
multiple: multiple,
|
||||
expires_at: expires_at,
|
||||
options: items.map { |item| item['name'].presence || item['content'] },
|
||||
cached_tallies: items.map { |item| item.dig('replies', 'totalItems') || 0 }
|
||||
)
|
||||
end
|
||||
|
||||
def poll_vote?
|
||||
return false if replied_to_status.nil? || replied_to_status.poll.nil? || !replied_to_status.local? || !replied_to_status.poll.options.include?(@object['name'])
|
||||
replied_to_status.poll.votes.create!(account: @account, choice: replied_to_status.poll.options.index(@object['name']))
|
||||
end
|
||||
|
||||
def resolve_thread(status)
|
||||
return unless status.reply? && status.thread.nil? && Request.valid_url?(in_reply_to_uri)
|
||||
ThreadResolveWorker.perform_async(status.id, in_reply_to_uri)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue