The code powering m.abunchtell.com https://m.abunchtell.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

146 lines
5.1 KiB

  1. # frozen_string_literal: true
  2. module AccountInteractions
  3. extend ActiveSupport::Concern
  4. class_methods do
  5. def following_map(target_account_ids, account_id)
  6. follow_mapping(Follow.where(target_account_id: target_account_ids, account_id: account_id), :target_account_id)
  7. end
  8. def followed_by_map(target_account_ids, account_id)
  9. follow_mapping(Follow.where(account_id: target_account_ids, target_account_id: account_id), :account_id)
  10. end
  11. def blocking_map(target_account_ids, account_id)
  12. follow_mapping(Block.where(target_account_id: target_account_ids, account_id: account_id), :target_account_id)
  13. end
  14. def muting_map(target_account_ids, account_id)
  15. follow_mapping(Mute.where(target_account_id: target_account_ids, account_id: account_id), :target_account_id)
  16. end
  17. def requested_map(target_account_ids, account_id)
  18. follow_mapping(FollowRequest.where(target_account_id: target_account_ids, account_id: account_id), :target_account_id)
  19. end
  20. def domain_blocking_map(target_account_ids, account_id)
  21. accounts_map = Account.where(id: target_account_ids).select('id, domain').map { |a| [a.id, a.domain] }.to_h
  22. blocked_domains = AccountDomainBlock.where(account_id: account_id, domain: accounts_map.values).pluck(:domain)
  23. accounts_map.map { |id, domain| [id, blocked_domains.include?(domain)] }.to_h
  24. end
  25. private
  26. def follow_mapping(query, field)
  27. query.pluck(field).each_with_object({}) { |id, mapping| mapping[id] = true }
  28. end
  29. end
  30. included do
  31. # Follow relations
  32. has_many :follow_requests, dependent: :destroy
  33. has_many :active_relationships, class_name: 'Follow', foreign_key: 'account_id', dependent: :destroy
  34. has_many :passive_relationships, class_name: 'Follow', foreign_key: 'target_account_id', dependent: :destroy
  35. has_many :following, -> { order('follows.id desc') }, through: :active_relationships, source: :target_account
  36. has_many :followers, -> { order('follows.id desc') }, through: :passive_relationships, source: :account
  37. # Block relationships
  38. has_many :block_relationships, class_name: 'Block', foreign_key: 'account_id', dependent: :destroy
  39. has_many :blocking, -> { order('blocks.id desc') }, through: :block_relationships, source: :target_account
  40. has_many :blocked_by_relationships, class_name: 'Block', foreign_key: :target_account_id, dependent: :destroy
  41. has_many :blocked_by, -> { order('blocks.id desc') }, through: :blocked_by_relationships, source: :account
  42. # Mute relationships
  43. has_many :mute_relationships, class_name: 'Mute', foreign_key: 'account_id', dependent: :destroy
  44. has_many :muting, -> { order('mutes.id desc') }, through: :mute_relationships, source: :target_account
  45. has_many :muted_by_relationships, class_name: 'Mute', foreign_key: :target_account_id, dependent: :destroy
  46. has_many :muted_by, -> { order('mutes.id desc') }, through: :muted_by_relationships, source: :account
  47. has_many :conversation_mutes, dependent: :destroy
  48. has_many :domain_blocks, class_name: 'AccountDomainBlock', dependent: :destroy
  49. end
  50. def follow!(other_account)
  51. active_relationships.find_or_create_by!(target_account: other_account)
  52. end
  53. def block!(other_account)
  54. block_relationships.find_or_create_by!(target_account: other_account)
  55. end
  56. def mute!(other_account)
  57. mute_relationships.find_or_create_by!(target_account: other_account)
  58. end
  59. def mute_conversation!(conversation)
  60. conversation_mutes.find_or_create_by!(conversation: conversation)
  61. end
  62. def block_domain!(other_domain)
  63. domain_blocks.find_or_create_by!(domain: other_domain)
  64. end
  65. def unfollow!(other_account)
  66. follow = active_relationships.find_by(target_account: other_account)
  67. follow&.destroy
  68. end
  69. def unblock!(other_account)
  70. block = block_relationships.find_by(target_account: other_account)
  71. block&.destroy
  72. end
  73. def unmute!(other_account)
  74. mute = mute_relationships.find_by(target_account: other_account)
  75. mute&.destroy
  76. end
  77. def unmute_conversation!(conversation)
  78. mute = conversation_mutes.find_by(conversation: conversation)
  79. mute&.destroy!
  80. end
  81. def unblock_domain!(other_domain)
  82. block = domain_blocks.find_by(domain: other_domain)
  83. block&.destroy
  84. end
  85. def following?(other_account)
  86. active_relationships.where(target_account: other_account).exists?
  87. end
  88. def blocking?(other_account)
  89. block_relationships.where(target_account: other_account).exists?
  90. end
  91. def domain_blocking?(other_domain)
  92. domain_blocks.where(domain: other_domain).exists?
  93. end
  94. def muting?(other_account)
  95. mute_relationships.where(target_account: other_account).exists?
  96. end
  97. def muting_conversation?(conversation)
  98. conversation_mutes.where(conversation: conversation).exists?
  99. end
  100. def requested?(other_account)
  101. follow_requests.where(target_account: other_account).exists?
  102. end
  103. def favourited?(status)
  104. status.proper.favourites.where(account: self).exists?
  105. end
  106. def reblogged?(status)
  107. status.proper.reblogs.where(account: self).exists?
  108. end
  109. def pinned?(status)
  110. status_pins.where(status: status).exists?
  111. end
  112. end