about summary refs log tree commit diff
path: root/app/lib/feed_manager.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/lib/feed_manager.rb')
-rw-r--r--app/lib/feed_manager.rb39
1 files changed, 30 insertions, 9 deletions
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index 0ec341e3f..88fa592a7 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -2,6 +2,7 @@
 
 require 'singleton'
 
+# rubocop:disable Metrics/ClassLength
 class FeedManager
   include Singleton
   include Redisable
@@ -23,7 +24,7 @@ class FeedManager
 
   def filter?(timeline_type, status, receiver_id)
     if [:home, :list].include?(timeline_type)
-      filter_from_home?(status, receiver_id, build_crutches(receiver_id, [status]))
+      filter_from_home?(status, receiver_id, build_crutches(receiver_id, [status]), filter_options_for(receiver_id))
     elsif timeline_type == :mentions
       filter_from_mentions?(status, receiver_id)
     elsif timeline_type == :direct
@@ -142,9 +143,10 @@ class FeedManager
 
     statuses = query.to_a
     crutches = build_crutches(into_account.id, statuses)
+    filter_options = filter_options_for(receiver_id)
 
     statuses.each do |status|
-      next if filter_from_home?(status, into_account.id, crutches)
+      next if filter_from_home?(status, into_account.id, crutches, filter_options)
 
       add_to_feed(:home, into_account.id, status, aggregate)
     end
@@ -242,9 +244,9 @@ class FeedManager
       (context == :home ? Mute.where(account_id: receiver_id, target_account_id: account_ids).any? : Mute.where(account_id: receiver_id, target_account_id: account_ids, hide_notifications: true).any?)
   end
 
-  def filter_from_home?(status, receiver_id, crutches)
+  def filter_from_home?(status, receiver_id, crutches, filter_options)
     return false if receiver_id == status.account_id
-    return true  unless status.published? && (status.conversation&.public? || crutches[:following][status.conversation&.account_id])
+    return true  unless status.published? && (status.conversation&.public? || status.conversation&.account_id == receiver_id || crutches[:following][status.conversation&.account_id])
     return true  if status.reply? && (status.in_reply_to_id.nil? || status.in_reply_to_account_id.nil?)
     return true  if phrase_filtered?(status, receiver_id, :home)
 
@@ -264,18 +266,25 @@ class FeedManager
 
     if status.reply? && !status.in_reply_to_account_id.nil?
       should_filter   = receiver_id != status.in_reply_to_account_id
+      should_filter &&= receiver_id != status.conversation&.account_id
       should_filter &&= status.account_id != status.in_reply_to_account_id
-      should_filter &&= !(crutches[:following][status.in_reply_to_account_id] && crutches[:following][status.conversation&.account_id])
+      should_filter &&= if filter_options[:to_unknown]
+                          !(crutches[:following][status.in_reply_to_account_id] && crutches[:following][status.conversation&.account_id])
+                        else
+                          !crutches[:following][status.in_reply_to_account_id]
+                        end
 
       return !!should_filter
     elsif status.reblog?
       should_filter   = status.reblog.reply?
       should_filter &&= status.reblog.account_id != status.reblog.in_reply_to_account_id
-      should_filter &&= !(crutches[:following][status.reblog.in_reply_to_account_id] && crutches[:following][status.reblog.conversation&.account_id])
-
-      should_filter ||= !crutches[:following][status.reblog.account_id] if status.reblog.account.silenced?
-      should_filter ||= !crutches[:following][status.reblog.conversation&.account_id] if status.reblog.conversation&.account&.silenced?
+      should_filter &&= if filter_options[:to_unknown]
+                          !(crutches[:following][status.reblog.in_reply_to_account_id] && crutches[:following][status.reblog.conversation&.account_id])
+                        else
+                          !crutches[:following][status.reblog.in_reply_to_account_id]
+                        end
 
+      should_filter ||= !crutches[:following][status.reblog.account_id] if filter_options[:from_account] || status.reblog.account.silenced?
       should_filter ||= crutches[:hiding_reblogs][status.account_id]
       should_filter ||= crutches[:blocked_by][status.reblog.account_id]
       should_filter ||= crutches[:domain_blocking][status.reblog.account.domain]
@@ -423,6 +432,17 @@ class FeedManager
     redis.zrem(timeline_key, status.id)
   end
 
+  def filter_options_for(receiver_id)
+    Rails.cache.fetch("filter_settings:#{receiver_id}", expires_in: 1.month) do
+      return {} if (settings = User.find_by(account_id: receiver_id)&.settings).blank?
+
+      {
+        to_unknown: settings.filter_to_unknown,
+        from_unknown: settings.filter_from_unknown,
+      }
+    end
+  end
+
   def build_crutches(receiver_id, statuses)
     crutches = {}
 
@@ -450,3 +470,4 @@ class FeedManager
     crutches
   end
 end
+# rubocop:enable Metrics/ClassLength