catstodon/app/services/notify_service.rb
Eugen Rochko f1ab70649b Add buttons to block and unblock domain (#3127)
* Add buttons to block and unblock domain

* Relationship API now returns "domain_blocking" status for accounts,
rename "block entire domain" to "hide entire domain", fix unblocking domain,
do not block notifications from domain-blocked-but-followed people, do
not send Salmons to domain blocked users

* Add test

* Personal domain blocks shouldn't affect Salmon after all, since in this
direction of communication the control is very thin when it comes to
public stuff. Best stay consistent and not affect federation in this way

* Ignore followers and follow request from domain blocked folks,
ensure account domain blocks are not created for empty domain,
and avoid duplicates in validation

* Purge followers when blocking domain (without soft-blocks, since they
are useless here)

* Add tests, fix local timeline being empty when having any domain blocks
2017-05-19 21:05:32 +02:00

73 lines
2.6 KiB
Ruby

# frozen_string_literal: true
class NotifyService < BaseService
def call(recipient, activity)
@recipient = recipient
@activity = activity
@notification = Notification.new(account: @recipient, activity: @activity)
return if recipient.user.nil? || blocked?
create_notification
send_email if email_enabled?
rescue ActiveRecord::RecordInvalid
return
end
private
def blocked_mention?
FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient.id)
end
def blocked_favourite?
false
end
def blocked_follow?
false
end
def blocked_reblog?
false
end
def blocked_follow_request?
false
end
def blocked?
blocked = @recipient.suspended? # Skip if the recipient account is suspended anyway
blocked ||= @recipient.id == @notification.from_account.id # Skip for interactions with self
blocked ||= @recipient.domain_blocking?(@notification.from_account.domain) && !@recipient.following?(@notification.from_account) # Skip for domain blocked accounts
blocked ||= @recipient.blocking?(@notification.from_account) # Skip for blocked accounts
blocked ||= (@notification.from_account.silenced? && !@recipient.following?(@notification.from_account)) # Hellban
blocked ||= (@recipient.user.settings.interactions['must_be_follower'] && !@notification.from_account.following?(@recipient)) # Options
blocked ||= (@recipient.user.settings.interactions['must_be_following'] && !@recipient.following?(@notification.from_account)) # Options
blocked ||= conversation_muted?
blocked ||= send("blocked_#{@notification.type}?") # Type-dependent filters
blocked
end
def conversation_muted?
if @notification.target_status
@recipient.muting_conversation?(@notification.target_status.conversation)
else
false
end
end
def create_notification
@notification.save!
return unless @notification.browserable?
Redis.current.publish("timeline:#{@recipient.id}", Oj.dump(event: :notification, payload: InlineRenderer.render(@notification, @recipient, 'api/v1/notifications/show')))
end
def send_email
NotificationMailer.public_send(@notification.type, @recipient, @notification).deliver_later
end
def email_enabled?
@recipient.user.settings.notification_emails[@notification.type.to_s]
end
end