Add the ability to make status reference notifications followee-only
This commit is contained in:
parent
91910d7d2d
commit
ccafeaf32f
11 changed files with 116 additions and 4 deletions
|
@ -96,7 +96,7 @@ class Settings::PreferencesController < Settings::BaseController
|
|||
:setting_default_search_searchability,
|
||||
:setting_show_reload_button,
|
||||
notification_emails: %i(follow follow_request reblog favourite emoji_reaction status_reference mention digest report pending_account trending_tag),
|
||||
interactions: %i(must_be_follower must_be_following must_be_following_dm must_be_dm_to_send_email)
|
||||
interactions: %i(must_be_follower must_be_following must_be_following_dm must_be_dm_to_send_email must_be_following_reference)
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ const initialState = ImmutableMap({
|
|||
poll: true,
|
||||
status: true,
|
||||
emoji_reaction: true,
|
||||
status_reference: false,
|
||||
status_reference: true,
|
||||
}),
|
||||
|
||||
sounds: ImmutableMap({
|
||||
|
@ -87,7 +87,7 @@ const initialState = ImmutableMap({
|
|||
poll: true,
|
||||
status: true,
|
||||
emoji_reaction: true,
|
||||
status_reference: false,
|
||||
status_reference: true,
|
||||
}),
|
||||
}),
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ class StatusPolicy < ApplicationPolicy
|
|||
def subscribe?
|
||||
return false unless show?
|
||||
|
||||
!unlisted? || owned? || following_author? || mention_exists?
|
||||
public? || owned? || following_author? || mention_exists?
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -69,6 +69,10 @@ class StatusPolicy < ApplicationPolicy
|
|||
author.id == current_account&.id
|
||||
end
|
||||
|
||||
def public?
|
||||
record.public_visibility?
|
||||
end
|
||||
|
||||
def unlisted?
|
||||
record.unlisted_visibility?
|
||||
end
|
||||
|
|
|
@ -67,6 +67,10 @@ class NotifyService < BaseService
|
|||
@recipient.user.settings.interactions['must_be_following'] && !following_sender?
|
||||
end
|
||||
|
||||
def optional_non_following_and_reference?
|
||||
status_reference? && @recipient.user.settings.interactions['must_be_following_reference'] && !following_sender?
|
||||
end
|
||||
|
||||
def optional_non_direct_message?
|
||||
message? && @recipient.user.settings.interactions['must_be_dm_to_send_email'] && !@notification.target_status.direct_visibility?
|
||||
end
|
||||
|
@ -75,6 +79,10 @@ class NotifyService < BaseService
|
|||
@notification.type == :mention
|
||||
end
|
||||
|
||||
def status_reference?
|
||||
@notification.type == :status_reference
|
||||
end
|
||||
|
||||
def direct_message?
|
||||
message? && @notification.target_status.direct_visibility?
|
||||
end
|
||||
|
@ -162,6 +170,7 @@ class NotifyService < BaseService
|
|||
blocked ||= hellbanned? # Hellban
|
||||
blocked ||= optional_non_follower? # Options
|
||||
blocked ||= optional_non_following? # Options
|
||||
blocked ||= optional_non_following_and_reference? # Options
|
||||
blocked ||= optional_non_following_and_direct? # Options
|
||||
blocked ||= conversation_muted?
|
||||
blocked ||= send("blocked_#{@notification.type}?") # Type-dependent filters
|
||||
|
|
|
@ -38,3 +38,4 @@
|
|||
= ff.input :must_be_following, as: :boolean, wrapper: :with_label
|
||||
= ff.input :must_be_following_dm, as: :boolean, wrapper: :with_label
|
||||
= ff.input :must_be_dm_to_send_email, as: :boolean, wrapper: :with_label, fedibird_features: true
|
||||
= ff.input :must_be_following_reference, as: :boolean, wrapper: :with_label, fedibird_features: true
|
||||
|
|
|
@ -307,6 +307,7 @@ en:
|
|||
must_be_follower: Block notifications from non-followers
|
||||
must_be_following: Block notifications from people you don't follow
|
||||
must_be_following_dm: Block direct messages from people you don't follow
|
||||
must_be_following_reference: Block reference notifications from people you don't follow
|
||||
invite:
|
||||
comment: Comment
|
||||
invite_request:
|
||||
|
|
|
@ -311,6 +311,7 @@ ja:
|
|||
must_be_follower: フォロワー以外からの通知をブロック
|
||||
must_be_following: フォローしていないユーザーからの通知をブロック
|
||||
must_be_following_dm: フォローしていないユーザーからのダイレクトメッセージをブロック
|
||||
must_be_following_reference: フォローしていないユーザーからの参照通知をブロック
|
||||
invite:
|
||||
comment: コメント
|
||||
invite_request:
|
||||
|
|
|
@ -82,6 +82,7 @@ defaults: &defaults
|
|||
must_be_follower: false
|
||||
must_be_following: false
|
||||
must_be_following_dm: false
|
||||
must_be_following_reference: true
|
||||
reserved_usernames:
|
||||
- admin
|
||||
- support
|
||||
|
|
4
spec/fabricators/status_reference_fabricator.rb
Normal file
4
spec/fabricators/status_reference_fabricator.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
Fabricator(:status_reference) do
|
||||
status_id nil
|
||||
target_status_id nil
|
||||
end
|
|
@ -25,6 +25,37 @@ RSpec.describe StatusPolicy, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
permissions :subscribe? do
|
||||
it 'grants access when public and account is viewer' do
|
||||
viewer = Fabricate(:account)
|
||||
status.visibility = :public
|
||||
|
||||
expect(subject).to permit(viewer, status)
|
||||
end
|
||||
|
||||
it 'grants access when direct and viewer is mentioned' do
|
||||
status.visibility = :unlisted
|
||||
status.mentions = [Fabricate(:mention, account: alice)]
|
||||
|
||||
expect(subject).to permit(alice, status)
|
||||
end
|
||||
|
||||
it 'grants access when unlisted and account is following viewer' do
|
||||
follow = Fabricate(:follow)
|
||||
status.visibility = :unlisted
|
||||
status.account = follow.target_account
|
||||
|
||||
expect(subject).to permit(follow.account, status)
|
||||
end
|
||||
|
||||
it 'denies access when unlisted and account is not mentioned or following viewer' do
|
||||
viewer = Fabricate(:account)
|
||||
status.visibility = :unlisted
|
||||
|
||||
expect(subject).to_not permit(viewer, status)
|
||||
end
|
||||
end
|
||||
|
||||
permissions :show? do
|
||||
it 'grants access when direct and account is viewer' do
|
||||
status.visibility = :direct
|
||||
|
|
|
@ -126,6 +126,66 @@ RSpec.describe NotifyService, type: :service do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'status references' do
|
||||
let(:target_status) { Fabricate(:status, account: recipient, visibility: :public) }
|
||||
let(:activity) { Fabricate(:status_reference, status: status, target_status: target_status) }
|
||||
let(:type) { :status_reference }
|
||||
|
||||
before do
|
||||
user.settings.interactions = user.settings.interactions.merge('must_be_following_reference' => enabled)
|
||||
end
|
||||
|
||||
context 'if must_be_following_reference is true' do
|
||||
let(:enabled) { true }
|
||||
|
||||
describe 'with public' do
|
||||
let(:status) { Fabricate(:status, account: sender, visibility: :public) }
|
||||
|
||||
it 'does notify' do
|
||||
is_expected.to_not change(Notification, :count)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with unlisted' do
|
||||
let(:status) { Fabricate(:status, account: sender, visibility: :unlisted) }
|
||||
|
||||
it 'does notify when sender is followed' do
|
||||
recipient.follow!(sender)
|
||||
is_expected.to change(Notification, :count)
|
||||
end
|
||||
|
||||
it 'does not notify when sender is not followed' do
|
||||
is_expected.to_not change(Notification, :count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'if must_be_following_reference is false' do
|
||||
let(:enabled) { false }
|
||||
|
||||
describe 'with public' do
|
||||
let(:status) { Fabricate(:status, account: sender, visibility: :public) }
|
||||
|
||||
it 'does notify' do
|
||||
is_expected.to change(Notification, :count)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'with unlisted' do
|
||||
let(:status) { Fabricate(:status, account: sender, visibility: :unlisted) }
|
||||
|
||||
it 'does notify when sender is followed' do
|
||||
recipient.follow!(sender)
|
||||
is_expected.to change(Notification, :count)
|
||||
end
|
||||
|
||||
it 'does not notify when sender is not followed' do
|
||||
is_expected.to_not change(Notification, :count)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context do
|
||||
let(:asshole) { Fabricate(:account, username: 'asshole') }
|
||||
let(:reply_to) { Fabricate(:status, account: asshole) }
|
||||
|
|
Loading…
Reference in a new issue