forked from cybrespace/mastodon
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)
This commit is contained in:
parent
d2528b26b6
commit
9f65909f42
|
@ -35,6 +35,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
|
||||||
def public_feed
|
def public_feed
|
||||||
PublicFeed.new(
|
PublicFeed.new(
|
||||||
current_account,
|
current_account,
|
||||||
|
locale: content_locale,
|
||||||
local: truthy_param?(:local),
|
local: truthy_param?(:local),
|
||||||
remote: truthy_param?(:remote),
|
remote: truthy_param?(:remote),
|
||||||
only_media: truthy_param?(:only_media)
|
only_media: truthy_param?(:only_media)
|
||||||
|
|
|
@ -36,6 +36,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
|
||||||
TagFeed.new(
|
TagFeed.new(
|
||||||
@tag,
|
@tag,
|
||||||
current_account,
|
current_account,
|
||||||
|
locale: content_locale,
|
||||||
any: params[:any],
|
any: params[:any],
|
||||||
all: params[:all],
|
all: params[:all],
|
||||||
none: params[:none],
|
none: params[:none],
|
||||||
|
|
|
@ -8,6 +8,7 @@ class PublicFeed
|
||||||
# @option [Boolean] :local
|
# @option [Boolean] :local
|
||||||
# @option [Boolean] :remote
|
# @option [Boolean] :remote
|
||||||
# @option [Boolean] :only_media
|
# @option [Boolean] :only_media
|
||||||
|
# @option [String] :locale
|
||||||
def initialize(account, options = {})
|
def initialize(account, options = {})
|
||||||
@account = account
|
@account = account
|
||||||
@options = options
|
@options = options
|
||||||
|
@ -27,6 +28,7 @@ class PublicFeed
|
||||||
scope.merge!(remote_only_scope) if remote_only?
|
scope.merge!(remote_only_scope) if remote_only?
|
||||||
scope.merge!(account_filters_scope) if account?
|
scope.merge!(account_filters_scope) if account?
|
||||||
scope.merge!(media_only_scope) if media_only?
|
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)
|
scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id)
|
||||||
end
|
end
|
||||||
|
@ -83,10 +85,19 @@ class PublicFeed
|
||||||
Status.joins(:media_attachments).group(:id)
|
Status.joins(:media_attachments).group(:id)
|
||||||
end
|
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
|
def account_filters_scope
|
||||||
Status.not_excluded_by_account(account).tap do |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.not_domain_blocked_by_account(account)) unless local_only?
|
||||||
scope.merge!(Status.in_chosen_languages(account)) if account.chosen_languages.present?
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -95,7 +95,6 @@ class Status < ApplicationRecord
|
||||||
scope :without_reblogs, -> { where('statuses.reblog_of_id IS NULL') }
|
scope :without_reblogs, -> { where('statuses.reblog_of_id IS NULL') }
|
||||||
scope :with_public_visibility, -> { where(visibility: :public) }
|
scope :with_public_visibility, -> { where(visibility: :public) }
|
||||||
scope :tagged_with, ->(tag_ids) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag_ids }) }
|
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 :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 :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) }
|
scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) }
|
||||||
|
|
|
@ -12,6 +12,7 @@ class TagFeed < PublicFeed
|
||||||
# @option [Boolean] :local
|
# @option [Boolean] :local
|
||||||
# @option [Boolean] :remote
|
# @option [Boolean] :remote
|
||||||
# @option [Boolean] :only_media
|
# @option [Boolean] :only_media
|
||||||
|
# @option [String] :locale
|
||||||
def initialize(tag, account, options = {})
|
def initialize(tag, account, options = {})
|
||||||
@tag = tag
|
@tag = tag
|
||||||
super(account, options)
|
super(account, options)
|
||||||
|
@ -32,6 +33,7 @@ class TagFeed < PublicFeed
|
||||||
scope.merge!(remote_only_scope) if remote_only?
|
scope.merge!(remote_only_scope) if remote_only?
|
||||||
scope.merge!(account_filters_scope) if account?
|
scope.merge!(account_filters_scope) if account?
|
||||||
scope.merge!(media_only_scope) if media_only?
|
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)
|
scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id)
|
||||||
end
|
end
|
||||||
|
|
|
@ -251,22 +251,6 @@ RSpec.describe Status, type: :model do
|
||||||
end
|
end
|
||||||
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
|
describe '.tagged_with' do
|
||||||
let(:tag1) { Fabricate(:tag) }
|
let(:tag1) { Fabricate(:tag) }
|
||||||
let(:tag2) { Fabricate(:tag) }
|
let(:tag2) { Fabricate(:tag) }
|
||||||
|
|
Loading…
Reference in New Issue