mirror of
https://github.com/mastodon/mastodon.git
synced 2024-12-29 03:53:52 +00:00
6793bec4c6
Same URI passed between follow request and follow, since they are the same thing in ActivityPub. Local URIs are generated during creation using UUIDs and are passed to serializers.
187 lines
6.8 KiB
Ruby
187 lines
6.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module AccountInteractions
|
|
extend ActiveSupport::Concern
|
|
|
|
class_methods do
|
|
def following_map(target_account_ids, account_id)
|
|
Follow.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |follow, mapping|
|
|
mapping[follow.target_account_id] = {
|
|
reblogs: follow.show_reblogs?,
|
|
}
|
|
end
|
|
end
|
|
|
|
def followed_by_map(target_account_ids, account_id)
|
|
follow_mapping(Follow.where(account_id: target_account_ids, target_account_id: account_id), :account_id)
|
|
end
|
|
|
|
def blocking_map(target_account_ids, account_id)
|
|
follow_mapping(Block.where(target_account_id: target_account_ids, account_id: account_id), :target_account_id)
|
|
end
|
|
|
|
def blocked_by_map(target_account_ids, account_id)
|
|
follow_mapping(Block.where(account_id: target_account_ids, target_account_id: account_id), :account_id)
|
|
end
|
|
|
|
def muting_map(target_account_ids, account_id)
|
|
Mute.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |mute, mapping|
|
|
mapping[mute.target_account_id] = {
|
|
notifications: mute.hide_notifications?,
|
|
}
|
|
end
|
|
end
|
|
|
|
def requested_map(target_account_ids, account_id)
|
|
FollowRequest.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |follow_request, mapping|
|
|
mapping[follow_request.target_account_id] = {
|
|
reblogs: follow_request.show_reblogs?,
|
|
}
|
|
end
|
|
end
|
|
|
|
def domain_blocking_map(target_account_ids, account_id)
|
|
accounts_map = Account.where(id: target_account_ids).select('id, domain').map { |a| [a.id, a.domain] }.to_h
|
|
blocked_domains = domain_blocking_map_by_domain(accounts_map.values.compact, account_id)
|
|
accounts_map.map { |id, domain| [id, blocked_domains[domain]] }.to_h
|
|
end
|
|
|
|
def domain_blocking_map_by_domain(target_domains, account_id)
|
|
follow_mapping(AccountDomainBlock.where(account_id: account_id, domain: target_domains), :domain)
|
|
end
|
|
|
|
private
|
|
|
|
def follow_mapping(query, field)
|
|
query.pluck(field).each_with_object({}) { |id, mapping| mapping[id] = true }
|
|
end
|
|
end
|
|
|
|
included do
|
|
# Follow relations
|
|
has_many :follow_requests, dependent: :destroy
|
|
|
|
has_many :active_relationships, class_name: 'Follow', foreign_key: 'account_id', dependent: :destroy
|
|
has_many :passive_relationships, class_name: 'Follow', foreign_key: 'target_account_id', dependent: :destroy
|
|
|
|
has_many :following, -> { order('follows.id desc') }, through: :active_relationships, source: :target_account
|
|
has_many :followers, -> { order('follows.id desc') }, through: :passive_relationships, source: :account
|
|
|
|
# Block relationships
|
|
has_many :block_relationships, class_name: 'Block', foreign_key: 'account_id', dependent: :destroy
|
|
has_many :blocking, -> { order('blocks.id desc') }, through: :block_relationships, source: :target_account
|
|
has_many :blocked_by_relationships, class_name: 'Block', foreign_key: :target_account_id, dependent: :destroy
|
|
has_many :blocked_by, -> { order('blocks.id desc') }, through: :blocked_by_relationships, source: :account
|
|
|
|
# Mute relationships
|
|
has_many :mute_relationships, class_name: 'Mute', foreign_key: 'account_id', dependent: :destroy
|
|
has_many :muting, -> { order('mutes.id desc') }, through: :mute_relationships, source: :target_account
|
|
has_many :muted_by_relationships, class_name: 'Mute', foreign_key: :target_account_id, dependent: :destroy
|
|
has_many :muted_by, -> { order('mutes.id desc') }, through: :muted_by_relationships, source: :account
|
|
has_many :conversation_mutes, dependent: :destroy
|
|
has_many :domain_blocks, class_name: 'AccountDomainBlock', dependent: :destroy
|
|
end
|
|
|
|
def follow!(other_account, reblogs: nil, uri: nil)
|
|
reblogs = true if reblogs.nil?
|
|
|
|
rel = active_relationships.create_with(show_reblogs: reblogs, uri: uri)
|
|
.find_or_create_by!(target_account: other_account)
|
|
|
|
rel.update!(show_reblogs: reblogs)
|
|
rel
|
|
end
|
|
|
|
def block!(other_account, uri: nil)
|
|
block_relationships.create_with(uri: uri)
|
|
.find_or_create_by!(target_account: other_account)
|
|
end
|
|
|
|
def mute!(other_account, notifications: nil)
|
|
notifications = true if notifications.nil?
|
|
mute = mute_relationships.create_with(hide_notifications: notifications).find_or_create_by!(target_account: other_account)
|
|
# When toggling a mute between hiding and allowing notifications, the mute will already exist, so the find_or_create_by! call will return the existing Mute without updating the hide_notifications attribute. Therefore, we check that hide_notifications? is what we want and set it if it isn't.
|
|
if mute.hide_notifications? != notifications
|
|
mute.update!(hide_notifications: notifications)
|
|
end
|
|
mute
|
|
end
|
|
|
|
def mute_conversation!(conversation)
|
|
conversation_mutes.find_or_create_by!(conversation: conversation)
|
|
end
|
|
|
|
def block_domain!(other_domain)
|
|
domain_blocks.find_or_create_by!(domain: other_domain)
|
|
end
|
|
|
|
def unfollow!(other_account)
|
|
follow = active_relationships.find_by(target_account: other_account)
|
|
follow&.destroy
|
|
end
|
|
|
|
def unblock!(other_account)
|
|
block = block_relationships.find_by(target_account: other_account)
|
|
block&.destroy
|
|
end
|
|
|
|
def unmute!(other_account)
|
|
mute = mute_relationships.find_by(target_account: other_account)
|
|
mute&.destroy
|
|
end
|
|
|
|
def unmute_conversation!(conversation)
|
|
mute = conversation_mutes.find_by(conversation: conversation)
|
|
mute&.destroy!
|
|
end
|
|
|
|
def unblock_domain!(other_domain)
|
|
block = domain_blocks.find_by(domain: other_domain)
|
|
block&.destroy
|
|
end
|
|
|
|
def following?(other_account)
|
|
active_relationships.where(target_account: other_account).exists?
|
|
end
|
|
|
|
def blocking?(other_account)
|
|
block_relationships.where(target_account: other_account).exists?
|
|
end
|
|
|
|
def domain_blocking?(other_domain)
|
|
domain_blocks.where(domain: other_domain).exists?
|
|
end
|
|
|
|
def muting?(other_account)
|
|
mute_relationships.where(target_account: other_account).exists?
|
|
end
|
|
|
|
def muting_conversation?(conversation)
|
|
conversation_mutes.where(conversation: conversation).exists?
|
|
end
|
|
|
|
def muting_notifications?(other_account)
|
|
mute_relationships.where(target_account: other_account, hide_notifications: true).exists?
|
|
end
|
|
|
|
def muting_reblogs?(other_account)
|
|
active_relationships.where(target_account: other_account, show_reblogs: false).exists?
|
|
end
|
|
|
|
def requested?(other_account)
|
|
follow_requests.where(target_account: other_account).exists?
|
|
end
|
|
|
|
def favourited?(status)
|
|
status.proper.favourites.where(account: self).exists?
|
|
end
|
|
|
|
def reblogged?(status)
|
|
status.proper.reblogs.where(account: self).exists?
|
|
end
|
|
|
|
def pinned?(status)
|
|
status_pins.where(status: status).exists?
|
|
end
|
|
end
|