0
0
Fork 0

Add notifications of severed relationships (#27511)

This commit is contained in:
Claire 2024-03-20 16:37:21 +01:00 committed by GitHub
parent 8a1423a474
commit 44bf7b8128
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 781 additions and 54 deletions

View file

@ -0,0 +1,27 @@
# frozen_string_literal: true
#
# == Schema Information
#
# Table name: account_relationship_severance_events
#
# id :bigint(8) not null, primary key
# account_id :bigint(8) not null
# relationship_severance_event_id :bigint(8) not null
# created_at :datetime not null
# updated_at :datetime not null
#
class AccountRelationshipSeveranceEvent < ApplicationRecord
belongs_to :account
belongs_to :relationship_severance_event
delegate :severed_relationships, :type, :target_name, :purged, to: :relationship_severance_event, prefix: false
before_create :set_relationships_count!
private
def set_relationships_count!
self.relationships_count = severed_relationships.where(local_account: account).count
end
end

View file

@ -83,6 +83,11 @@ module Account::Interactions
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
with_options class_name: 'SeveredRelationship', dependent: :destroy do
has_many :severed_relationships, foreign_key: 'local_account_id', inverse_of: :local_account
has_many :remote_severed_relationships, foreign_key: 'remote_account_id', inverse_of: :remote_account
end
# Account notes
has_many :account_notes, dependent: :destroy

View file

@ -48,6 +48,18 @@ module Account::Merging
record.update_attribute(:account_warning_id, id)
end
SeveredRelationship.where(local_account_id: other_account.id).reorder(nil).find_each do |record|
record.update_attribute(:local_account_id, id)
rescue ActiveRecord::RecordNotUnique
next
end
SeveredRelationship.where(remote_account_id: other_account.id).reorder(nil).find_each do |record|
record.update_attribute(:remote_account_id, id)
rescue ActiveRecord::RecordNotUnique
next
end
# Some follow relationships have moved, so the cache is stale
Rails.cache.delete_matched("followers_hash:#{id}:*")
Rails.cache.delete_matched("relationships:#{id}:*")

View file

@ -54,6 +54,9 @@ class Notification < ApplicationRecord
update: {
filterable: false,
}.freeze,
severed_relationships: {
filterable: false,
}.freeze,
'admin.sign_up': {
filterable: false,
}.freeze,
@ -86,6 +89,7 @@ class Notification < ApplicationRecord
belongs_to :favourite, inverse_of: :notification
belongs_to :poll, inverse_of: false
belongs_to :report, inverse_of: false
belongs_to :relationship_severance_event, inverse_of: false
end
validates :type, inclusion: { in: TYPES }
@ -182,6 +186,11 @@ class Notification < ApplicationRecord
self.from_account_id = activity&.status&.account_id
when 'Account'
self.from_account_id = activity&.id
when 'AccountRelationshipSeveranceEvent'
# These do not really have an originating account, but this is mandatory
# in the data model, and the recipient's account will by definition
# always exist
self.from_account_id = account_id
end
end

View file

@ -0,0 +1,56 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: relationship_severance_events
#
# id :bigint(8) not null, primary key
# type :integer not null
# target_name :string not null
# purged :boolean default(FALSE), not null
# created_at :datetime not null
# updated_at :datetime not null
#
class RelationshipSeveranceEvent < ApplicationRecord
self.inheritance_column = nil
has_many :severed_relationships, inverse_of: :relationship_severance_event, dependent: :delete_all
enum type: {
domain_block: 0,
user_domain_block: 1,
account_suspension: 2,
}
scope :about_local_account, ->(account) { where(id: SeveredRelationship.about_local_account(account).select(:relationship_severance_event_id)) }
def import_from_active_follows!(follows)
import_from_follows!(follows, true)
end
def import_from_passive_follows!(follows)
import_from_follows!(follows, false)
end
def affected_local_accounts
Account.where(id: severed_relationships.select(:local_account_id))
end
private
def import_from_follows!(follows, active)
SeveredRelationship.insert_all(
follows.pluck(:account_id, :target_account_id, :show_reblogs, :notify, :languages).map do |account_id, target_account_id, show_reblogs, notify, languages|
{
local_account_id: active ? account_id : target_account_id,
remote_account_id: active ? target_account_id : account_id,
show_reblogs: show_reblogs,
notify: notify,
languages: languages,
relationship_severance_event_id: id,
direction: active ? :active : :passive,
}
end
)
end
end

View file

@ -0,0 +1,40 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: severed_relationships
#
# id :bigint(8) not null, primary key
# relationship_severance_event_id :bigint(8) not null
# local_account_id :bigint(8) not null
# remote_account_id :bigint(8) not null
# direction :integer not null
# show_reblogs :boolean
# notify :boolean
# languages :string is an Array
# created_at :datetime not null
# updated_at :datetime not null
#
class SeveredRelationship < ApplicationRecord
belongs_to :relationship_severance_event
belongs_to :local_account, class_name: 'Account'
belongs_to :remote_account, class_name: 'Account'
enum direction: {
passive: 0, # analogous to `local_account.passive_relationships`
active: 1, # analogous to `local_account.active_relationships`
}
scope :about_local_account, ->(account) { where(local_account: account) }
scope :active, -> { where(direction: :active) }
scope :passive, -> { where(direction: :passive) }
def account
active? ? local_account : remote_account
end
def target_account
active? ? remote_account : local_account
end
end