about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--app/lib/feed_manager.rb2
-rw-r--r--app/lib/status_filter.rb11
-rw-r--r--app/models/status.rb4
3 files changed, 17 insertions, 0 deletions
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index 2b7b018c6..9e8f85fee 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -171,6 +171,7 @@ class FeedManager
     if status.reply? && !status.in_reply_to_account_id.nil?                                                                      # Filter out if it's a reply
       should_filter   = !Follow.where(account_id: receiver_id, target_account_id: status.in_reply_to_account_id).exists?         # and I'm not following the person it's a reply to
       should_filter &&= receiver_id != status.in_reply_to_account_id                                                             # and it's not a reply to me
+      should_filter ||= Status.find(status.in_reply_to_id)&.marked_no_replies?                                                   # or the parent has no-replies set
       should_filter &&= status.account_id != status.in_reply_to_account_id                                                       # and it's not a self-reply
       return should_filter
     elsif status.reblog?                                                                                                         # Filter out a reblog
@@ -185,6 +186,7 @@ class FeedManager
 
   def filter_from_mentions?(status, receiver_id)
     return true if receiver_id == status.account_id
+    return true if status.reply? && !status.in_reply_to_id.nil? && Status.find(status.in_reply_to_id)&.marked_no_replies?
     return true if phrase_filtered?(status, receiver_id, :notifications)
 
     # This filter is called from NotifyService, but already after the sender of
diff --git a/app/lib/status_filter.rb b/app/lib/status_filter.rb
index 0f8841885..4253f6502 100644
--- a/app/lib/status_filter.rb
+++ b/app/lib/status_filter.rb
@@ -30,6 +30,9 @@ class StatusFilter
     # I don't think this should happen, but just in case...
     return filtered_reply if status&.mentions.nil?
 
+    # filter non-op posts replying to something marked no replies
+    return true if reply_to_no_replies?
+
     # Grab a list of account IDs mentioned in the status.
     mentioned_account_ids = status.mentions.pluck(:account_id)
 
@@ -63,6 +66,14 @@ class StatusFilter
     @preloaded_relations[:muting] ? @preloaded_relations[:muting][status.in_reply_to_account_id] : account.muting?(status.in_reply_to_account_id)
   end
 
+  def reply_to_no_replies?
+    status.reply? &&
+      !status.in_reply_to_account_id.nil? &&
+      !status.in_reply_to_id.nil? &&
+      status.account_id != status.in_reply_to_account_id &&
+      Status.find(status.in_reply_to_id)&.marked_no_replies?
+  end
+
   def blocking_account?
     @preloaded_relations[:blocking] ? @preloaded_relations[:blocking][status.account_id] : account.blocking?(status.account_id)
   end
diff --git a/app/models/status.rb b/app/models/status.rb
index 29e8c7374..ce642f9bf 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -511,6 +511,10 @@ class Status < ApplicationRecord
     '👁'
   end
 
+  def marked_no_replies?
+    /(:ms_dont_at_me:|(don't|do not|no) ((at|@|mention) me)|reply|replies)/.match?(spoiler_text)
+  end
+
   private
 
   def update_status_stat!(attrs)