From 9f65909f42c14d1e56c5f916eb76b156709ac147 Mon Sep 17 00:00:00 2001
From: Eugen Rochko <eugen@zeonfederated.com>
Date: Wed, 5 Oct 2022 03:48:06 +0200
Subject: [PATCH] Change public timelines to be filtered by current locale by
default (#19291)
In the absence of an opt-in to multiple specific languages in the
preferences, it makes more sense to filter by the user's presumed
language only (interface language or `lang` override)
---
.../api/v1/timelines/public_controller.rb | 1 +
.../api/v1/timelines/tag_controller.rb | 1 +
app/models/public_feed.rb | 13 ++++++++++++-
app/models/status.rb | 1 -
app/models/tag_feed.rb | 2 ++
spec/models/status_spec.rb | 16 ----------------
6 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb
index d253b744f9..15b91d63ea 100644
--- a/app/controllers/api/v1/timelines/public_controller.rb
+++ b/app/controllers/api/v1/timelines/public_controller.rb
@@ -35,6 +35,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
def public_feed
PublicFeed.new(
current_account,
+ locale: content_locale,
local: truthy_param?(:local),
remote: truthy_param?(:remote),
only_media: truthy_param?(:only_media)
diff --git a/app/controllers/api/v1/timelines/tag_controller.rb b/app/controllers/api/v1/timelines/tag_controller.rb
index 64a1db58df..9f3a5b3f12 100644
--- a/app/controllers/api/v1/timelines/tag_controller.rb
+++ b/app/controllers/api/v1/timelines/tag_controller.rb
@@ -36,6 +36,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
TagFeed.new(
@tag,
current_account,
+ locale: content_locale,
any: params[:any],
all: params[:all],
none: params[:none],
diff --git a/app/models/public_feed.rb b/app/models/public_feed.rb
index 5e4c3e1cee..2cf9206d2b 100644
--- a/app/models/public_feed.rb
+++ b/app/models/public_feed.rb
@@ -8,6 +8,7 @@ class PublicFeed
# @option [Boolean] :local
# @option [Boolean] :remote
# @option [Boolean] :only_media
+ # @option [String] :locale
def initialize(account, options = {})
@account = account
@options = options
@@ -27,6 +28,7 @@ class PublicFeed
scope.merge!(remote_only_scope) if remote_only?
scope.merge!(account_filters_scope) if account?
scope.merge!(media_only_scope) if media_only?
+ scope.merge!(language_scope)
scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id)
end
@@ -83,10 +85,19 @@ class PublicFeed
Status.joins(:media_attachments).group(:id)
end
+ def language_scope
+ if account&.chosen_languages.present?
+ Status.where(language: account.chosen_languages)
+ elsif @options[:locale].present?
+ Status.where(language: @options[:locale])
+ else
+ Status.all
+ end
+ end
+
def account_filters_scope
Status.not_excluded_by_account(account).tap do |scope|
scope.merge!(Status.not_domain_blocked_by_account(account)) unless local_only?
- scope.merge!(Status.in_chosen_languages(account)) if account.chosen_languages.present?
end
end
end
diff --git a/app/models/status.rb b/app/models/status.rb
index 7eff990aab..de958aaf33 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -95,7 +95,6 @@ class Status < ApplicationRecord
scope :without_reblogs, -> { where('statuses.reblog_of_id IS NULL') }
scope :with_public_visibility, -> { where(visibility: :public) }
scope :tagged_with, ->(tag_ids) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag_ids }) }
- scope :in_chosen_languages, ->(account) { where(language: nil).or where(language: account.chosen_languages) }
scope :excluding_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced_at: nil }) }
scope :including_silenced_accounts, -> { left_outer_joins(:account).where.not(accounts: { silenced_at: nil }) }
scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) }
diff --git a/app/models/tag_feed.rb b/app/models/tag_feed.rb
index b8cd63557e..58216bddcb 100644
--- a/app/models/tag_feed.rb
+++ b/app/models/tag_feed.rb
@@ -12,6 +12,7 @@ class TagFeed < PublicFeed
# @option [Boolean] :local
# @option [Boolean] :remote
# @option [Boolean] :only_media
+ # @option [String] :locale
def initialize(tag, account, options = {})
@tag = tag
super(account, options)
@@ -32,6 +33,7 @@ class TagFeed < PublicFeed
scope.merge!(remote_only_scope) if remote_only?
scope.merge!(account_filters_scope) if account?
scope.merge!(media_only_scope) if media_only?
+ scope.merge!(language_scope)
scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id)
end
diff --git a/spec/models/status_spec.rb b/spec/models/status_spec.rb
index 130f4d03fa..78cc059596 100644
--- a/spec/models/status_spec.rb
+++ b/spec/models/status_spec.rb
@@ -251,22 +251,6 @@ RSpec.describe Status, type: :model do
end
end
- describe '.in_chosen_languages' do
- context 'for accounts with language filters' do
- let(:user) { Fabricate(:user, chosen_languages: ['en']) }
-
- it 'does not include statuses in not in chosen languages' do
- status = Fabricate(:status, language: 'de')
- expect(Status.in_chosen_languages(user.account)).not_to include status
- end
-
- it 'includes status with unknown language' do
- status = Fabricate(:status, language: nil)
- expect(Status.in_chosen_languages(user.account)).to include status
- end
- end
- end
-
describe '.tagged_with' do
let(:tag1) { Fabricate(:tag) }
let(:tag2) { Fabricate(:tag) }
--
GitLab