about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/lib/activitypub/activity/create.rb19
-rw-r--r--app/lib/activitypub/adapter.rb1
-rw-r--r--app/models/conversation.rb3
-rw-r--r--app/models/status.rb10
-rw-r--r--app/models/status_mute.rb2
-rw-r--r--app/serializers/activitypub/note_serializer.rb8
-rw-r--r--app/serializers/rest/status_serializer.rb6
7 files changed, 41 insertions, 8 deletions
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index 12c3b0d19..91f0ab146 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -373,6 +373,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
   end
 
   def fetch_replies(status)
+    FetchReplyWorker.perform_async(@object['root']) unless @object['root'].blank? || [@object['id'], @object['url']].include?(@object['root']) || status_from_uri(@object['root'])
+
     collection = @object['replies']
     return if collection.nil?
 
@@ -385,11 +387,22 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
 
   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)
+    conversation = OStatus::TagManager.instance.local_id?(uri) ? Conversation.find_by(id: OStatus::TagManager.instance.unique_tag_to_local_id(uri, 'Conversation')) : nil
 
     begin
-      conversation = Conversation.find_by(uri: uri)
-      Conversation.create!(uri: uri, account: @account, public: %i(public unlisted).include?(visibility_from_audience)) if conversation.nil?
+      conversation = Conversation.find_by(uri: uri) if conversation.blank?
+
+      if @object['inReplyTo'].blank? && replied_to_status.blank?
+        if conversation.blank?
+          conversation = Conversation.create!(uri: uri, root: @object['id'], account: @account, public: %i(public unlisted).include?(visibility_from_audience))
+        elsif conversation.root.blank?
+          conversation.update!(root: @object['id'], account: @account, public: %i(public unlisted).include?(visibility_from_audience))
+        end
+      elsif conversation.blank?
+        conversation = Conversation.create!(uri: uri, account_id: nil, public: false)
+      end
+
+      conversation
     rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique
       retry
     end
diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb
index b02059430..107b93b44 100644
--- a/app/lib/activitypub/adapter.rb
+++ b/app/lib/activitypub/adapter.rb
@@ -16,6 +16,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
     require_auth: { 'mp' => 'http://the.monsterpit.net/ns#', 'requireAuth' => 'mp:requireAuth' },
     metadata: { 'mp' => 'https://the.monsterpit.net/ns#', 'metadata' => { '@id' => 'mp:metadata', '@type' => '@id' } },
     server_metadata: { 'mp' => 'https://the.monsterpit.net/ns#', 'serverMetadata' => { '@id' => 'mp:serverMetadata', '@type' => '@id' } },
+    root: { 'mp' => 'https://the.monsterpit.net/ns#', 'root' => { '@id' => 'mp:root', '@type' => '@id' } },
     manually_approves_followers: { 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers' },
     sensitive: { 'sensitive' => 'as:sensitive' },
     hashtag: { 'Hashtag' => 'as:Hashtag' },
diff --git a/app/models/conversation.rb b/app/models/conversation.rb
index d1674fe4e..e065c34c8 100644
--- a/app/models/conversation.rb
+++ b/app/models/conversation.rb
@@ -9,6 +9,7 @@
 #  updated_at :datetime         not null
 #  account_id :bigint(8)
 #  public     :boolean          default(FALSE), not null
+#  root       :string
 #
 
 class Conversation < ApplicationRecord
@@ -16,7 +17,7 @@ class Conversation < ApplicationRecord
 
   has_many :statuses
   has_many :mutes, class_name: 'ConversationMute', inverse_of: :conversation, dependent: :destroy
-  belongs_to :account, inverse_of: :threads
+  belongs_to :account, inverse_of: :threads, optional: true
 
   def local?
     uri.nil?
diff --git a/app/models/status.rb b/app/models/status.rb
index 9067f44df..9c061bf85 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -376,6 +376,7 @@ class Status < ApplicationRecord
   after_destroy_commit :decrement_counter_caches
 
   after_create_commit :store_uri, if: :local?
+  after_create_commit :store_url, if: :local?
   after_create_commit :update_statistics, if: :local?
 
   around_create Mastodon::Snowflake::Callbacks
@@ -392,6 +393,7 @@ class Status < ApplicationRecord
 
   after_save :set_domain_permissions, if: :local?
   after_save :set_semiprivate, if: :local?
+  after_save :set_conversation_root
 
   class << self
     def selectable_visibilities
@@ -676,6 +678,10 @@ class Status < ApplicationRecord
     update_column(:uri, ActivityPub::TagManager.instance.uri_for(self)) if uri.nil?
   end
 
+  def store_url
+    update_column(:url, ActivityPub::TagManager.instance.url_for(self)) if url.nil?
+  end
+
   def prepare_contents
     text&.strip!
     spoiler_text&.strip!
@@ -717,6 +723,10 @@ class Status < ApplicationRecord
     end
   end
 
+  def set_conversation_root
+    conversation.update!(root: uri, account_id: account_id, public: distributable?) if !reply && conversation.root.blank?
+  end
+
   def carried_over_reply_to_account_id
     if thread.account_id == account_id && thread.reply?
       thread.in_reply_to_account_id
diff --git a/app/models/status_mute.rb b/app/models/status_mute.rb
index 223893604..1e01f0278 100644
--- a/app/models/status_mute.rb
+++ b/app/models/status_mute.rb
@@ -4,7 +4,7 @@
 # Table name: status_mutes
 #
 #  id         :bigint(8)        not null, primary key
-#  account_id :integer          not null
+#  account_id :bigint(8)        not null
 #  status_id  :bigint(8)        not null
 #
 
diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb
index 163f25560..b86ab932e 100644
--- a/app/serializers/activitypub/note_serializer.rb
+++ b/app/serializers/activitypub/note_serializer.rb
@@ -3,7 +3,7 @@
 class ActivityPub::NoteSerializer < ActivityPub::Serializer
   context_extensions :atom_uri, :conversation, :sensitive, :voters_count, :direct_message
 
-  context_extensions :edited, :server_metadata
+  context_extensions :edited, :server_metadata, :root
 
   attributes :id, :type, :summary,
              :in_reply_to, :published, :url,
@@ -11,7 +11,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
              :atom_uri, :in_reply_to_atom_uri,
              :conversation
 
-  attribute :updated
+  attributes :updated, :root
   attribute :title, key: :name, if: :title_present?
 
   attribute :content
@@ -50,6 +50,10 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
     end
   end
 
+  def root
+    object.conversation&.root
+  end
+
   def summary
     return Formatter.instance.format(object) if title_present?
 
diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb
index dec39ec24..1182d8e80 100644
--- a/app/serializers/rest/status_serializer.rb
+++ b/app/serializers/rest/status_serializer.rb
@@ -7,7 +7,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
              :favourites_count
 
   # Monsterfork additions
-  attributes :updated_at, :edited, :nest_level
+  attributes :updated_at, :edited, :nest_level, :root
 
   attribute :favourited, if: :current_user?
   attribute :reblogged, if: :current_user?
@@ -110,6 +110,10 @@ class REST::StatusSerializer < ActiveModel::Serializer
     ActivityPub::TagManager.instance.url_for(object)
   end
 
+  def root
+    object.conversation&.root
+  end
+
   def favourited
     if instance_options && instance_options[:relationships]
       instance_options[:relationships].favourites_map[object.id] || false