about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/api/v1/statuses_controller.rb3
-rw-r--r--app/javascript/flavours/glitch/styles/monsterfork/components/formatting.scss13
-rw-r--r--app/lib/command_tag/command/footer_tools.rb33
-rw-r--r--app/lib/command_tag/processor.rb2
-rw-r--r--app/lib/formatter.rb17
-rw-r--r--app/lib/sanitize_config.rb2
-rw-r--r--app/models/status.rb1
-rw-r--r--app/services/post_status_service.rb2
-rw-r--r--app/services/update_status_service.rb1
-rw-r--r--db/migrate/20200817225525_add_footer_to_statuses.rb5
-rw-r--r--db/schema.rb3
11 files changed, 76 insertions, 6 deletions
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index 9a77f8ca2..46433853b 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -42,6 +42,7 @@ class Api::V1::StatusesController < Api::BaseController
                                          sensitive: status_params[:sensitive],
                                          spoiler_text: status_params[:spoiler_text],
                                          title: status_params[:title],
+                                         footer: status_params[:footer],
                                          visibility: status_params[:visibility],
                                          local_only: status_params[:local_only],
                                          scheduled_at: status_params[:scheduled_at],
@@ -69,6 +70,7 @@ class Api::V1::StatusesController < Api::BaseController
                                          sensitive: status_params[:sensitive],
                                          spoiler_text: status_params[:spoiler_text],
                                          title: status_params[:title],
+                                         footer: status_params[:footer],
                                          visibility: status_params[:visibility],
                                          local_only: status_params[:local_only],
                                          scheduled_at: status_params[:scheduled_at],
@@ -120,6 +122,7 @@ class Api::V1::StatusesController < Api::BaseController
       :sensitive,
       :spoiler_text,
       :title,
+      :footer,
       :visibility,
       :local_only,
       :scheduled_at,
diff --git a/app/javascript/flavours/glitch/styles/monsterfork/components/formatting.scss b/app/javascript/flavours/glitch/styles/monsterfork/components/formatting.scss
index 02a3d5310..7beebcea4 100644
--- a/app/javascript/flavours/glitch/styles/monsterfork/components/formatting.scss
+++ b/app/javascript/flavours/glitch/styles/monsterfork/components/formatting.scss
@@ -165,4 +165,17 @@
       margin-bottom: 0;
     };
   }
+  p[data-name="footer"] {
+    color: lighten($dark-text-color, 15%);
+    font-style: italic;
+    font-size: 12px;
+    text-align: right;
+    margin-bottom: 4px;
+  }
 }
+
+.status__content {
+  p:nth-last-child(2), pre:nth-last-child(2), blockquote:nth-last-child(2) {
+    margin-bottom: 0px;
+  }
+}
\ No newline at end of file
diff --git a/app/lib/command_tag/command/footer_tools.rb b/app/lib/command_tag/command/footer_tools.rb
new file mode 100644
index 000000000..c0f347303
--- /dev/null
+++ b/app/lib/command_tag/command/footer_tools.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+module CommandTag::Command::FooterTools
+  def handle_footertools_startup
+    @status.footer = var('persist:footer:default')[0]
+  end
+
+  def handle_footer_before_save(args)
+    return if args.blank?
+
+    name = normalize(args.shift)
+    return (@status.footer = nil) if read_falsy_from(name)
+
+    var_name = "persist:footer:#{name}"
+    return @status.footer = var(var_name)[0] if args.blank?
+    return @vars.delete(var_name) if read_falsy_from(normalize(args[0]))
+
+    if name == 'default'
+      @vars['persist:footer:default'] = @vars[var_name].presence || [args.join(' ')]
+    elsif %w(default DEFAULT).include?(args[0])
+      @vars['persist:footer:default'] = var(var_name)
+    else
+      @vars[var_name] = [args.join(' ')]
+    end
+
+    @status.footer = var(var_name)[0]
+  end
+
+  alias handle_signature_before_save    handle_footer_before_save
+  alias handle_sign_before_save         handle_footer_before_save
+  alias handle_sig_before_save          handle_footer_before_save
+  alias handle_am_before_save           handle_footer_before_save
+  alias handle_are_before_save          handle_footer_before_save
+end
\ No newline at end of file
diff --git a/app/lib/command_tag/processor.rb b/app/lib/command_tag/processor.rb
index f96bddca0..01c06faf3 100644
--- a/app/lib/command_tag/processor.rb
+++ b/app/lib/command_tag/processor.rb
@@ -84,7 +84,7 @@ class CommandTag::Processor
 
     execute_statements(:at_end)
     all_handlers!(:shutdown)
-  rescue Failure => e
+  rescue StandardError => e
     @status.update(published: false)
     @status.destroy
     raise
diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb
index 5cc4761e5..5559ddb73 100644
--- a/app/lib/formatter.rb
+++ b/app/lib/formatter.rb
@@ -61,7 +61,7 @@ class Formatter
     html = "📄 #{html}" if summary_mode
     return html if options[:plaintext]
 
-    linkable_accounts = status.active_mentions.map(&:account)
+    linkable_accounts = status.mentions.map(&:account)
     linkable_accounts << status.account
 
     keep_html = !summary_mode && %w(text/markdown text/html).include?(status.content_type)
@@ -73,20 +73,31 @@ class Formatter
 
     unless keep_html
       html = simple_format(html, {}, sanitize: false)
-      html = html.delete("\n")
+      html.delete!("\n")
     end
 
     html = summary_mode ? format_article_summary(html, status) : format_article_content(summary, html) if summary.present?
+    html = format_footer(html, status.footer, linkable_accounts, status.emojis, **options) if status.footer.present?
     html.html_safe # rubocop:disable Rails/OutputSafety
   end
 
   def format_remote_content(html, emojis, **options)
-    html = reformat(html)
+    html = reformat(html, options[:outgoing])
     html = encode_custom_emojis(html, emojis, options[:autoplay]) if options[:custom_emojify]
     html = format_article_content(options[:summary], html) if options[:article_content] && options[:summary].present?
     html.html_safe # rubocop:disable Rails/OutputSafety
   end
 
+  def format_footer(html, footer, linkable_accounts, emojis, **options)
+    footer = encode_and_link_urls(footer, linkable_accounts)
+    footer = encode_custom_emojis(footer, emojis, options[:autoplay]) if options[:custom_emojify]
+    footer = "<span class=\"invisible\">– </span>#{footer}"
+    footer = simple_format(footer, { 'data-name': 'footer' }, sanitize: false)
+    footer.delete!("\n")
+
+    "#{html}#{footer}"
+  end
+
   def format_markdown(html)
     html = markdown_formatter.render(html)
     html.delete("\r").delete("\n")
diff --git a/app/lib/sanitize_config.rb b/app/lib/sanitize_config.rb
index 93260c7dc..adbbd2168 100644
--- a/app/lib/sanitize_config.rb
+++ b/app/lib/sanitize_config.rb
@@ -43,7 +43,7 @@ class Sanitize
       return unless name_list
 
       name_list.keep_if do |name|
-        next true if %w(summary abstract permalink).include?(name)
+        next true if %w(summary abstract permalink footer).include?(name)
       end
 
       node['data-name'] = name_list.join(' ')
diff --git a/app/models/status.rb b/app/models/status.rb
index 9c061bf85..3a7cce14c 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -31,6 +31,7 @@
 #  title                  :text
 #  semiprivate            :boolean          default(FALSE), not null
 #  original_text          :text
+#  footer                 :text
 #
 
 # rubocop:disable Metrics/ClassLength
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index c6a983001..e790a643b 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -16,6 +16,7 @@ class PostStatusService < BaseService
   # @option [Boolean] :local_only
   # @option [String] :spoiler_text
   # @option [String] :title
+  # @option [String] :footer
   # @option [String] :language
   # @option [String] :scheduled_at
   # @option [Hash] :poll Optional poll to attach
@@ -206,6 +207,7 @@ class PostStatusService < BaseService
       sensitive: @sensitive,
       spoiler_text: @options[:spoiler_text] || '',
       title: @options[:title],
+      footer: @options[:footer],
       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 d0e61d153..355e8ca97 100644
--- a/app/services/update_status_service.rb
+++ b/app/services/update_status_service.rb
@@ -9,6 +9,7 @@ class UpdateStatusService < BaseService
     title
     text
     original_text
+    footer
     content_type
     language
     sensitive
diff --git a/db/migrate/20200817225525_add_footer_to_statuses.rb b/db/migrate/20200817225525_add_footer_to_statuses.rb
new file mode 100644
index 000000000..e85d225bc
--- /dev/null
+++ b/db/migrate/20200817225525_add_footer_to_statuses.rb
@@ -0,0 +1,5 @@
+class AddFooterToStatuses < ActiveRecord::Migration[5.2]
+  def change
+    add_column :statuses, :footer, :text
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 5d7bd5262..6607f1bf7 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 2020_08_17_003653) do
+ActiveRecord::Schema.define(version: 2020_08_17_225525) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
@@ -872,6 +872,7 @@ ActiveRecord::Schema.define(version: 2020_08_17_003653) do
     t.text "title"
     t.boolean "semiprivate", default: false, null: false
     t.text "original_text"
+    t.text "footer"
     t.index ["account_id", "id", "visibility", "updated_at"], name: "index_statuses_20190820", order: { id: :desc }, where: "(deleted_at IS NULL)"
     t.index ["account_id", "id"], name: "index_unpublished_statuses", order: { id: :desc }, where: "((deleted_at IS NULL) AND (published = false))"
     t.index ["conversation_id"], name: "index_statuses_on_conversation_id", where: "(deleted_at IS NULL)"