about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/api/v1/statuses_controller.rb3
-rw-r--r--app/lib/activitypub/activity/create.rb13
-rw-r--r--app/lib/command_tag/commands/status_tools.rb28
-rw-r--r--app/models/status.rb2
-rw-r--r--app/serializers/activitypub/note_serializer.rb5
-rw-r--r--app/serializers/rest/status_serializer.rb2
-rw-r--r--app/services/post_status_service.rb2
-rw-r--r--app/services/update_status_service.rb1
8 files changed, 55 insertions, 1 deletions
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index b64bf3fa0..a02a496ba 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -41,6 +41,7 @@ class Api::V1::StatusesController < Api::BaseController
                                          media_ids: status_params[:media_ids],
                                          sensitive: status_params[:sensitive],
                                          spoiler_text: status_params[:spoiler_text],
+                                         title: status_params[:title],
                                          visibility: status_params[:visibility],
                                          local_only: status_params[:local_only],
                                          scheduled_at: status_params[:scheduled_at],
@@ -67,6 +68,7 @@ class Api::V1::StatusesController < Api::BaseController
                                          media_ids: status_params[:media_ids],
                                          sensitive: status_params[:sensitive],
                                          spoiler_text: status_params[:spoiler_text],
+                                         title: status_params[:title],
                                          visibility: status_params[:visibility],
                                          local_only: status_params[:local_only],
                                          scheduled_at: status_params[:scheduled_at],
@@ -116,6 +118,7 @@ class Api::V1::StatusesController < Api::BaseController
       :in_reply_to_id,
       :sensitive,
       :spoiler_text,
+      :title,
       :visibility,
       :local_only,
       :scheduled_at,
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index 10a0a9498..12c3b0d19 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -122,6 +122,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
         text: text_from_content || '',
         language: detected_language,
         spoiler_text: converted_object_type? ? '' : (text_from_summary || ''),
+        title: text_from_title,
         created_at: @object['published'],
         override_timestamps: @options[:override_timestamps],
         reply: @object['inReplyTo'].present?,
@@ -451,6 +452,14 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     end
   end
 
+  def text_from_title
+    if @object['title'].present?
+      @object['title']
+    elsif title_language_map?
+      @object['titleMap'].values.first
+    end
+  end
+
   def text_from_name
     if @object['name'].present?
       @object['name']
@@ -487,6 +496,10 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     @object['summaryMap'].is_a?(Hash) && !@object['summaryMap'].empty?
   end
 
+  def title_language_map?
+    @object['titleMap'].is_a?(Hash) && !@object['titleMap'].empty?
+  end
+
   def content_language_map?
     @object['contentMap'].is_a?(Hash) && !@object['contentMap'].empty?
   end
diff --git a/app/lib/command_tag/commands/status_tools.rb b/app/lib/command_tag/commands/status_tools.rb
new file mode 100644
index 000000000..f8b8f8ae0
--- /dev/null
+++ b/app/lib/command_tag/commands/status_tools.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+# rubocop:disable Layout/ExtraSpacing
+module CommandTag::Commands::StatusTools
+  def handle_title_before_save(args)
+    return unless author_of_status? && !@status.published?
+
+    @status.title = args[0]
+  end
+
+  def handle_visibility_before_save(args)
+    return unless author_of_status? && !@status.published? && args[0].present?
+
+    args[0] = 'public' if %w(p pu all world).include?(args[0])
+    args[0] = 'unlisted' if %w(u ul).include?(args[0])
+    args[0] = 'private' if %w(f followers followers-only packmates packmates-only).include?(args[0])
+    args[0] = 'limited' if %w(l limit).include?(args[0])
+    args[0] = 'direct' if %w(d dm pm directmessage).include?(args[0])
+
+    return unless %w(public unlisted private limited direct).include?(args[0])
+
+    @status.visibility = args[0].to_sym
+  end
+
+  alias handle_v_before_save                      handle_visibility_before_save
+  alias handle_privacy_before_save                handle_visibility_before_save
+end
+# rubocop:enable Layout/ExtraSpacing
diff --git a/app/models/status.rb b/app/models/status.rb
index 46361280d..69d3a0ff8 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -28,6 +28,7 @@
 #  edited                 :integer          default(0), not null
 #  nest_level             :integer          default(0), not null
 #  published              :boolean          default(TRUE), not null
+#  title                  :text
 #
 
 # rubocop:disable Metrics/ClassLength
@@ -527,6 +528,7 @@ class Status < ApplicationRecord
   def prepare_contents
     text&.strip!
     spoiler_text&.strip!
+    title&.strip!
   end
 
   def set_reblog
diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb
index 87d7f9db0..75a38e9b5 100644
--- a/app/serializers/activitypub/note_serializer.rb
+++ b/app/serializers/activitypub/note_serializer.rb
@@ -12,6 +12,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
              :conversation
 
   attribute :updated
+  attribute :title, if: :title_present?
 
   attribute :content
   attribute :content_map, if: :language?
@@ -184,6 +185,10 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
     object.preloadable_poll&.voters_count
   end
 
+  def title_present?
+    object.title.present?
+  end
+
   class MediaAttachmentSerializer < ActivityPub::Serializer
     context_extensions :blurhash, :focal_point
 
diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb
index 1db3d50f1..1c4b86c21 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, :title
 
   attribute :favourited, if: :current_user?
   attribute :reblogged, if: :current_user?
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index aef630f71..33440a5a4 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -15,6 +15,7 @@ class PostStatusService < BaseService
   # @option [String] :visibility
   # @option [Boolean] :local_only
   # @option [String] :spoiler_text
+  # @option [String] :title
   # @option [String] :language
   # @option [String] :scheduled_at
   # @option [Hash] :poll Optional poll to attach
@@ -200,6 +201,7 @@ class PostStatusService < BaseService
       poll_attributes: poll_attributes,
       sensitive: @sensitive,
       spoiler_text: @options[:spoiler_text] || '',
+      title: @options[:title],
       visibility: @visibility,
       local_only: @options[:local_only],
       language: language_from_option(@options[:language]) || @account.user&.setting_default_language&.presence || LanguageDetector.instance.detect(@text, @account),
diff --git a/app/services/update_status_service.rb b/app/services/update_status_service.rb
index f59f26a25..18fee3e17 100644
--- a/app/services/update_status_service.rb
+++ b/app/services/update_status_service.rb
@@ -6,6 +6,7 @@ class UpdateStatusService < BaseService
 
   ALLOWED_ATTRIBUTES = %i(
     spoiler_text
+    title
     text
     content_type
     language