From 9f65909f42c14d1e56c5f916eb76b156709ac147 Mon Sep 17 00:00:00 2001 From: Eugen Rochko 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) }