diff --git a/app/models/account.rb b/app/models/account.rb index 1abd49b1e..0d4749587 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -52,6 +52,7 @@ class Account < ApplicationRecord include AccountFinderConcern include AccountHeader include AccountInteractions + include Glitch::AccountInteractions include Attachmentable include Remotable include Paginable diff --git a/app/models/concerns/glitch/account_interactions.rb b/app/models/concerns/glitch/account_interactions.rb new file mode 100644 index 000000000..e3a5f21ab --- /dev/null +++ b/app/models/concerns/glitch/account_interactions.rb @@ -0,0 +1,25 @@ +# frozen_string_literals: true + +module Glitch::AccountInteractions + extend ActiveSupport::Concern + + class_methods do + def mute_note_map(target_account_ids, account_id) + notes_from_relationship(Mute, target_account_ids, account_id).each_with_object({}) do |mute, mapping| + mapping[mute.target_account_id] = mute.note&.text + end + end + + def block_note_map(target_account_ids, account_id) + notes_from_relationship(Block, target_account_ids, account_id).each_with_object({}) do |block, mapping| + mapping[block.target_account_id] = block.note&.text + end + end + + private + + def notes_from_relationship(klass, target_account_ids, account_id) + klass.where(target_account_id: target_account_ids, account_id: account_id).includes(:note) + end + end +end diff --git a/app/presenters/account_relationships_presenter.rb b/app/presenters/account_relationships_presenter.rb index bf1ba3716..8958410d6 100644 --- a/app/presenters/account_relationships_presenter.rb +++ b/app/presenters/account_relationships_presenter.rb @@ -2,7 +2,8 @@ class AccountRelationshipsPresenter attr_reader :following, :followed_by, :blocking, - :muting, :requested, :domain_blocking + :muting, :requested, :domain_blocking, + :mute_notes, :block_notes def initialize(account_ids, current_account_id, **options) @following = Account.following_map(account_ids, current_account_id).merge(options[:following_map] || {}) @@ -11,5 +12,7 @@ class AccountRelationshipsPresenter @muting = Account.muting_map(account_ids, current_account_id).merge(options[:muting_map] || {}) @requested = Account.requested_map(account_ids, current_account_id).merge(options[:requested_map] || {}) @domain_blocking = Account.domain_blocking_map(account_ids, current_account_id).merge(options[:domain_blocking_map] || {}) + @mute_notes = Account.mute_note_map(account_ids, current_account_id).merge(options[:mute_note_map] || {}) + @block_notes = Account.block_note_map(account_ids, current_account_id).merge(options[:block_note_map] || {}) end end diff --git a/app/serializers/rest/relationship_serializer.rb b/app/serializers/rest/relationship_serializer.rb index 45bfd4d6e..0cbf25d2e 100644 --- a/app/serializers/rest/relationship_serializer.rb +++ b/app/serializers/rest/relationship_serializer.rb @@ -2,7 +2,8 @@ class REST::RelationshipSerializer < ActiveModel::Serializer attributes :id, :following, :showing_reblogs, :followed_by, :blocking, - :muting, :muting_notifications, :requested, :domain_blocking + :muting, :muting_notifications, :requested, :domain_blocking, + :mute_notes, :block_notes def id object.id.to_s @@ -34,6 +35,14 @@ class REST::RelationshipSerializer < ActiveModel::Serializer (instance_options[:relationships].muting[object.id] || {})[:notifications] || false end + def mute_notes + instance_options[:relationships].mute_notes[object.id] || '' + end + + def block_notes + instance_options[:relationships].block_notes[object.id] || '' + end + def requested instance_options[:relationships].requested[object.id] ? true : false end diff --git a/spec/models/concerns/glitch/account_interactions_spec.rb b/spec/models/concerns/glitch/account_interactions_spec.rb new file mode 100644 index 000000000..86e73b306 --- /dev/null +++ b/spec/models/concerns/glitch/account_interactions_spec.rb @@ -0,0 +1,78 @@ +require 'rails_helper' + +describe Glitch::AccountInteractions do + let(:account) { Fabricate(:account, username: 'account') } + let(:account_id) { account.id } + let(:account_ids) { [account_id] } + let(:target_account) { Fabricate(:account, username: 'target') } + let(:target_account_id) { target_account.id } + let(:target_account_ids) { [target_account_id] } + + describe '.mute_note_map' do + subject { Account.mute_note_map(target_account_ids, account_id) } + + context 'account with Mute' do + before do + Fabricate(:mute, target_account: target_account, account: account).tap do |m| + m.create_note!(note: note) if note + end + end + + context 'with a note' do + let(:note) { 'Too many jorts' } + + it 'returns { target_account_id => "(a note)" }' do + is_expected.to eq(target_account_id => 'Too many jorts') + end + end + + context 'with no associated note' do + let(:note) { nil } + + it 'returns { target_account_id => nil }' do + is_expected.to eq(target_account_id => nil) + end + end + end + + context 'account without Mute' do + it 'returns {}' do + is_expected.to eq({}) + end + end + end + + describe '.block_note_map' do + subject { Account.block_note_map(target_account_ids, account_id) } + + context 'account with Block' do + before do + Fabricate(:block, target_account: target_account, account: account).tap do |m| + m.create_note!(note: note) if note + end + end + + context 'with a note' do + let(:note) { 'Too many oats' } + + it 'returns { target_account_id => "(a note)" }' do + is_expected.to eq(target_account_id => 'Too many oats') + end + end + + context 'with no associated note' do + let(:note) { nil } + + it 'returns { target_account_id => nil }' do + is_expected.to eq(target_account_id => nil) + end + end + end + + context 'account without Block' do + it 'returns {}' do + is_expected.to eq({}) + end + end + end +end