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/timelines/public_controller.rb3
-rw-r--r--app/models/status.rb12
-rw-r--r--app/services/fan_out_on_write_service.rb15
3 files changed, 19 insertions, 11 deletions
diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb
index b449bcadf..968aa8cf5 100644
--- a/app/controllers/api/v1/timelines/public_controller.rb
+++ b/app/controllers/api/v1/timelines/public_controller.rb
@@ -41,7 +41,8 @@ class Api::V1::Timelines::PublicController < Api::BaseController
   end
 
   def public_timeline_statuses
-    Status.as_public_timeline(current_account, truthy_param?(:remote) ? :remote : truthy_param?(:local))
+    local = truthy_param?(:local) ? true : :local_reblogs
+    Status.as_public_timeline(current_account, truthy_param?(:remote) ? :remote : local)
   end
 
   def insert_pagination_headers
diff --git a/app/models/status.rb b/app/models/status.rb
index fab3644a4..ade8b4c85 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -133,6 +133,8 @@ class Status < ApplicationRecord
   scope :unpublished, -> { rewhere(published: false) }
   scope :published, -> { where(published: true) }
   scope :without_semiprivate, -> { where(semiprivate: false) }
+  scope :reblogs, -> { where('statuses.reblog_of_id IS NOT NULL') }
+  scope :locally_reblogged, -> { where(id: Status.unscoped.local.reblogs.select(:reblog_of_id)) }
 
   scope :not_hidden_by_account, ->(account) do
     left_outer_joins(:mutes, :conversation_mute).where('(status_mutes.account_id IS NULL OR status_mutes.account_id != ?) AND (conversation_mutes.account_id IS NULL OR (conversation_mutes.account_id != ? AND conversation_mutes.hidden = TRUE))', account.id, account.id)
@@ -535,15 +537,13 @@ class Status < ApplicationRecord
                          Status.local
                        when :remote
                          Status.remote
+                       when :local_reblogs
+                         Status.locally_reblogged
                        else
                          Status
                        end
-      starting_scope = starting_scope.with_public_visibility
-      if Setting.show_reblogs_in_public_timelines
-        starting_scope
-      else
-        starting_scope.without_reblogs
-      end
+      starting_scope = starting_scope.with_public_visibility.published
+      scope != :local_reblogs ? starting_scope.without_reblogs : starting_scope
     end
 
     def apply_timeline_filters(query, account, local_only)
diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb
index 3f845ecd4..08963cf5e 100644
--- a/app/services/fan_out_on_write_service.rb
+++ b/app/services/fan_out_on_write_service.rb
@@ -23,14 +23,16 @@ class FanOutOnWriteService < BaseService
       deliver_to_lists(status)
     end
 
-    return if status.account.silenced? || !status.public_visibility?
-    return if status.reblog? && !Setting.show_reblogs_in_public_timelines
+    return if status.account.silenced?
+
+    deliver_to_public(status.reblog) if status.local? && status.reblog? && status.reblog.public_visibility? && !status.reblog.account.silenced?
+
+    return if status.reblog? || !status.public_visibility?
 
     deliver_to_hashtags(status)
 
     return if status.reply? && status.in_reply_to_account_id != status.account_id && !Setting.show_replies_in_public_timelines
 
-    deliver_to_public(status)
     deliver_to_media(status) if status.media_attachments.any?
   end
 
@@ -85,8 +87,13 @@ class FanOutOnWriteService < BaseService
   end
 
   def deliver_to_public(status)
+    key = "timeline:public:#{status.id}"
+    return if Redis.current.get(key)
+
     Rails.logger.debug "Delivering status #{status.id} to public timeline"
 
+    Redis.current.set(key, true, ex: 6.hours)
+
     Redis.current.publish('timeline:public', @payload)
     if status.local?
       Redis.current.publish('timeline:public:local', @payload)
@@ -109,7 +116,7 @@ class FanOutOnWriteService < BaseService
   def deliver_to_direct_timelines(status)
     Rails.logger.debug "Delivering status #{status.id} to direct timelines"
 
-    FeedInsertWorker.push_bulk(status.mentions.includes(:account).map(&:account).select { |mentioned_account| mentioned_account.local? }) do |account|
+    FeedInsertWorker.push_bulk(status.mentions.includes(:account).map(&:account).select(&:local?)) do |account|
       [status.id, account.id, :direct]
     end
   end