mirror of
https://github.com/mastodon/mastodon.git
synced 2024-10-20 01:31:38 +09:00
8f6c67bfde
* Fix performance of account timelines * Various fixes and improvements * Fix duplicate results being returned Co-authored-by: Claire <claire.github-309c@sitedethib.com> * Fix grouping for pinned statuses scope Co-authored-by: Claire <claire.github-309c@sitedethib.com>
135 lines
2.9 KiB
Ruby
135 lines
2.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class AccountStatusesFilter
|
|
KEYS = %i(
|
|
pinned
|
|
tagged
|
|
only_media
|
|
exclude_replies
|
|
exclude_reblogs
|
|
).freeze
|
|
|
|
attr_reader :params, :account, :current_account
|
|
|
|
def initialize(account, current_account, params = {})
|
|
@account = account
|
|
@current_account = current_account
|
|
@params = params
|
|
end
|
|
|
|
def results
|
|
scope = initial_scope
|
|
|
|
scope.merge!(pinned_scope) if pinned?
|
|
scope.merge!(only_media_scope) if only_media?
|
|
scope.merge!(no_replies_scope) if exclude_replies?
|
|
scope.merge!(no_reblogs_scope) if exclude_reblogs?
|
|
scope.merge!(hashtag_scope) if tagged?
|
|
|
|
scope
|
|
end
|
|
|
|
private
|
|
|
|
def initial_scope
|
|
if suspended?
|
|
Status.none
|
|
elsif anonymous?
|
|
account.statuses.where(visibility: %i(public unlisted))
|
|
elsif author?
|
|
account.statuses.all # NOTE: #merge! does not work without the #all
|
|
elsif blocked?
|
|
Status.none
|
|
else
|
|
filtered_scope
|
|
end
|
|
end
|
|
|
|
def filtered_scope
|
|
scope = account.statuses.left_outer_joins(:mentions)
|
|
|
|
scope.merge!(scope.where(visibility: follower? ? %i(public unlisted private) : %i(public unlisted)).or(scope.where(mentions: { account_id: current_account.id })).group(Status.arel_table[:id]))
|
|
scope.merge!(filtered_reblogs_scope) if reblogs_may_occur?
|
|
|
|
scope
|
|
end
|
|
|
|
def filtered_reblogs_scope
|
|
Status.left_outer_joins(:reblog).where(reblog_of_id: nil).or(Status.where.not(reblogs_statuses: { account_id: current_account.excluded_from_timeline_account_ids }))
|
|
end
|
|
|
|
def only_media_scope
|
|
Status.joins(:media_attachments).merge(account.media_attachments.reorder(nil)).group(Status.arel_table[:id])
|
|
end
|
|
|
|
def no_replies_scope
|
|
Status.without_replies
|
|
end
|
|
|
|
def no_reblogs_scope
|
|
Status.without_reblogs
|
|
end
|
|
|
|
def pinned_scope
|
|
account.pinned_statuses.group(Status.arel_table[:id], StatusPin.arel_table[:created_at])
|
|
end
|
|
|
|
def hashtag_scope
|
|
tag = Tag.find_normalized(params[:tagged])
|
|
|
|
if tag
|
|
Status.tagged_with(tag.id)
|
|
else
|
|
Status.none
|
|
end
|
|
end
|
|
|
|
def suspended?
|
|
account.suspended?
|
|
end
|
|
|
|
def anonymous?
|
|
current_account.nil?
|
|
end
|
|
|
|
def author?
|
|
current_account.id == account.id
|
|
end
|
|
|
|
def blocked?
|
|
account.blocking?(current_account) || (current_account.domain.present? && account.domain_blocking?(current_account.domain))
|
|
end
|
|
|
|
def follower?
|
|
current_account.following?(account)
|
|
end
|
|
|
|
def reblogs_may_occur?
|
|
!exclude_reblogs? && !only_media? && !tagged?
|
|
end
|
|
|
|
def pinned?
|
|
truthy_param?(:pinned)
|
|
end
|
|
|
|
def only_media?
|
|
truthy_param?(:only_media)
|
|
end
|
|
|
|
def exclude_replies?
|
|
truthy_param?(:exclude_replies)
|
|
end
|
|
|
|
def exclude_reblogs?
|
|
truthy_param?(:exclude_reblogs)
|
|
end
|
|
|
|
def tagged?
|
|
params[:tagged].present?
|
|
end
|
|
|
|
def truthy_param?(key)
|
|
ActiveModel::Type::Boolean.new.cast(params[key])
|
|
end
|
|
end
|