about summary refs log tree commit diff
path: root/app/lib
diff options
context:
space:
mode:
authorFire Demon <firedemon@creature.cafe>2020-06-30 17:33:55 -0500
committerFire Demon <firedemon@creature.cafe>2020-08-30 05:41:03 -0500
commiteaf9bc1a428b338ee666f1da1e32eed7e3b6b25e (patch)
treeaeec5fdde79d6e4fa354da326a540811b5576907 /app/lib
parent5d5d88e4f65df4c190afeb407167c153584be108 (diff)
[Feature] Add in-place post editing
Diffstat (limited to 'app/lib')
-rw-r--r--app/lib/activitypub/activity/create.rb42
-rw-r--r--app/lib/activitypub/activity/update.rb4
-rw-r--r--app/lib/activitypub/adapter.rb1
-rw-r--r--app/lib/formatter.rb4
4 files changed, 47 insertions, 4 deletions
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index f09caaae4..d2bbd26d5 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -51,7 +51,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
 
         @status = find_existing_status
 
-        if @status.nil?
+        if @status.nil? || @options[:update]
           process_status
         elsif @options[:delivered_to_account_id].present?
           postprocess_audience_and_deliver
@@ -77,6 +77,17 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     @mentions = []
     @params   = {}
 
+    unless @status.nil?
+      process_status_update_params
+      process_tags
+      process_audience
+
+      @status = UpdateStatusService.new.call(@status, @params, @mentions, @tags)
+      resolve_thread(@status)
+      fetch_replies(@status)
+      return @status
+    end
+
     process_status_params
     process_tags
     process_audience
@@ -121,6 +132,19 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     end
   end
 
+  def process_status_update_params
+    @params = begin
+      {
+        text: text_from_content || '',
+        language: detected_language,
+        spoiler_text: converted_object_type? ? '' : (text_from_summary || ''),
+        sensitive: @object['sensitive'] || false,
+        visibility: visibility_from_audience,
+        media_attachment_ids: process_attachments.take(4).map(&:id),
+      }
+    end
+  end
+
   def process_audience
     (as_array(audience_to) + as_array(audience_cc)).uniq.each do |audience|
       next if audience == ActivityPub::TagManager::COLLECTIONS[:public]
@@ -240,7 +264,21 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
 
       begin
         href             = Addressable::URI.parse(attachment['url']).normalize.to_s
-        media_attachment = MediaAttachment.create(account: @account, remote_url: href, thumbnail_remote_url: icon_url_from_attachment(attachment), description: attachment['summary'].presence || attachment['name'].presence, focus: attachment['focalPoint'], blurhash: supported_blurhash?(attachment['blurhash']) ? attachment['blurhash'] : nil)
+        media_attachment = MediaAttachment.find_by(account: @account, remote_url: href)
+
+        if media_attachment.nil?
+          media_attachment = MediaAttachment.create(account: @account, remote_url: href, thumbnail_remote_url: icon_url_from_attachment(attachment), description: attachment['summary'].presence || attachment['name'].presence, focus: attachment['focalPoint'], blurhash: supported_blurhash?(attachment['blurhash']) ? attachment['blurhash'] : nil)
+        else
+          updated_description = attachment['summary'].presence || media_attachment[:description].presence || attachment['name'].presence || media_attachment[:name].presence
+          updated_focus = attachment['focalPoint'].presence || media_attachment['focalPoint'].presence
+          updated_blurhash = supported_blurhash?(attachment['blurhash']) ? attachment['blurhash'] : media_attachment[:blurhash]
+
+          media_attachment.update(description: updated_description, focus: updated_focus, blurhash: updated_blurhash)
+
+          media_attachments << media_attachment
+          next
+        end
+
         media_attachments << media_attachment
 
         next if unsupported_media_type?(attachment['mediaType']) || skip_download?
diff --git a/app/lib/activitypub/activity/update.rb b/app/lib/activitypub/activity/update.rb
index 018e2df54..d1dba5196 100644
--- a/app/lib/activitypub/activity/update.rb
+++ b/app/lib/activitypub/activity/update.rb
@@ -2,6 +2,7 @@
 
 class ActivityPub::Activity::Update < ActivityPub::Activity
   SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze
+  SUPPORTED_OBJECT_TYPES = (ActivityPub::Activity::SUPPORTED_TYPES + ActivityPub::Activity::CONVERTED_TYPES).freeze
 
   def perform
     dereference_object!
@@ -10,6 +11,9 @@ class ActivityPub::Activity::Update < ActivityPub::Activity
       update_account
     elsif equals_or_includes_any?(@object['type'], %w(Question))
       update_poll
+    elsif equals_or_includes_any?(@object['type'], SUPPORTED_OBJECT_TYPES)
+      @options[:update] = true
+      ActivityPub::Activity::Create.new(@json, @account, @options).perform
     end
   end
 
diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb
index 712c48823..309b84c37 100644
--- a/app/lib/activitypub/adapter.rb
+++ b/app/lib/activitypub/adapter.rb
@@ -8,6 +8,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
 
   CONTEXT_EXTENSION_MAP = {
     direct_message: { 'litepub': 'http://litepub.social/ns#', 'directMessage': 'litepub:directMessage' },
+    edited: { 'mp' => 'http://the.monsterpit.net/ns#', 'edited' => 'mp:edited' },
     manually_approves_followers: { 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers' },
     sensitive: { 'sensitive' => 'as:sensitive' },
     hashtag: { 'Hashtag' => 'as:Hashtag' },
diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb
index 051f27408..d5408a30b 100644
--- a/app/lib/formatter.rb
+++ b/app/lib/formatter.rb
@@ -122,8 +122,8 @@ class Formatter
     html.html_safe # rubocop:disable Rails/OutputSafety
   end
 
-  def linkify(text)
-    html = encode_and_link_urls(text)
+  def linkify(text, accounts = nil, options = {})
+    html = encode_and_link_urls(text, accounts, options)
     html = simple_format(html, {}, sanitize: false)
     html = html.delete("\n")