2019-07-02 08:10:25 +01:00
# 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
2020-12-19 06:33:33 +00:00
def chat_blocking_map ( target_account_ids , account_id )
follow_mapping ( ChatBlock . where ( target_account_id : target_account_ids , account_id : account_id ) , :target_account_id )
end
def chat_blocked_by_map ( target_account_ids , account_id )
follow_mapping ( ChatBlock . where ( account_id : target_account_ids , target_account_id : account_id ) , :account_id )
end
2019-07-02 08:10:25 +01:00
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
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
2019-08-20 00:25:10 +01:00
has_many :group_accounts , inverse_of : :account , dependent : :destroy , source : :account
has_many :groups , through : :group_accounts
2021-01-19 06:26:28 +00:00
has_many :group_removed_accounts , inverse_of : :account , dependent : :destroy , source : :account
2019-08-20 00:25:10 +01:00
2019-07-02 08:10:25 +01:00
# 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
2020-12-10 16:51:45 +00:00
# Chat block relationships
has_many :chat_block_relationships , class_name : 'ChatBlock' , foreign_key : 'account_id' , dependent : :destroy
has_many :chat_blocking , - > { order ( 'chat_blocks.id desc' ) } , through : :chat_block_relationships , source : :target_account
has_many :chat_blocked_by_relationships , class_name : 'ChatBlock' , foreign_key : :target_account_id , dependent : :destroy
has_many :chat_blocked_by , - > { order ( 'chat_blocks.id desc' ) } , through : :chat_blocked_by_relationships , source : :account
2019-07-02 08:10:25 +01:00
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 )
remove_potential_friendship ( other_account )
rel
end
def block! ( other_account , uri : nil )
remove_potential_friendship ( other_account )
block_relationships . create_with ( uri : uri )
. find_or_create_by! ( target_account : other_account )
end
2020-12-19 06:33:33 +00:00
def chat_block! ( other_account )
chat_block_relationships . find_or_create_by! ( target_account : other_account )
end
2019-07-02 08:10:25 +01:00
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 )
remove_potential_friendship ( 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 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
2020-12-19 06:33:33 +00:00
def chat_unblock! ( other_account )
block = chat_block_relationships . find_by ( target_account : other_account )
block & . destroy
end
2019-07-02 08:10:25 +01:00
def unmute! ( other_account )
mute = mute_relationships . find_by ( target_account : other_account )
mute & . 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
2020-12-19 06:33:33 +00:00
def chat_blocking? ( other_account )
chat_block_relationships . where ( target_account : other_account ) . exists?
end
def chat_blocked_by ( target_account_id , account_id )
ChatBlock . where ( account_id : target_account_id , target_account_id : account_id ) . exists?
end
2019-07-02 08:10:25 +01:00
def muting? ( other_account )
mute_relationships . where ( target_account : other_account ) . 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
2020-07-25 00:48:31 +01:00
def bookmarked? ( status )
2020-11-25 21:22:37 +00:00
status_bookmarks . where ( account : self , status : status ) . exists?
2020-07-25 00:48:31 +01:00
end
2019-07-02 08:10:25 +01:00
def reblogged? ( status )
status . proper . reblogs . where ( account : self ) . exists?
end
def pinned? ( status )
status_pins . where ( status : status ) . exists?
end
def followers_for_local_distribution
followers . local
. joins ( :user )
. where ( 'users.current_sign_in_at > ?' , User :: ACTIVE_DURATION . ago )
end
def lists_for_local_distribution
lists . joins ( account : :user )
. where ( 'users.current_sign_in_at > ?' , User :: ACTIVE_DURATION . ago )
end
private
def remove_potential_friendship ( other_account , mutual = false )
PotentialFriendshipTracker . remove ( id , other_account . id )
PotentialFriendshipTracker . remove ( other_account . id , id ) if mutual
end
end