mirror of
https://github.com/glitch-soc/mastodon.git
synced 2024-11-23 08:34:13 -05:00
Add notification policies and notification requests (#29366)
This commit is contained in:
parent
653ce43abe
commit
50b17f7e10
37
app/controllers/api/v1/notifications/policies_controller.rb
Normal file
37
app/controllers/api/v1/notifications/policies_controller.rb
Normal file
@ -0,0 +1,37 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Notifications::PoliciesController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, only: :show
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, only: :update
|
||||
|
||||
before_action :require_user!
|
||||
before_action :set_policy
|
||||
|
||||
def show
|
||||
render json: @policy, serializer: REST::NotificationPolicySerializer
|
||||
end
|
||||
|
||||
def update
|
||||
@policy.update!(resource_params)
|
||||
render json: @policy, serializer: REST::NotificationPolicySerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_policy
|
||||
@policy = NotificationPolicy.find_or_initialize_by(account: current_account)
|
||||
|
||||
with_read_replica do
|
||||
@policy.summarize!
|
||||
end
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.permit(
|
||||
:filter_not_following,
|
||||
:filter_not_followers,
|
||||
:filter_new_accounts,
|
||||
:filter_private_mentions
|
||||
)
|
||||
end
|
||||
end
|
75
app/controllers/api/v1/notifications/requests_controller.rb
Normal file
75
app/controllers/api/v1/notifications/requests_controller.rb
Normal file
@ -0,0 +1,75 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Notifications::RequestsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, only: :index
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, except: :index
|
||||
|
||||
before_action :require_user!
|
||||
before_action :set_request, except: :index
|
||||
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
def index
|
||||
with_read_replica do
|
||||
@requests = load_requests
|
||||
@relationships = relationships
|
||||
end
|
||||
|
||||
render json: @requests, each_serializer: REST::NotificationRequestSerializer, relationships: @relationships
|
||||
end
|
||||
|
||||
def accept
|
||||
AcceptNotificationRequestService.new.call(@request)
|
||||
render_empty
|
||||
end
|
||||
|
||||
def dismiss
|
||||
@request.update!(dismissed: true)
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_requests
|
||||
requests = NotificationRequest.where(account: current_account).where(dismissed: truthy_param?(:dismissed)).includes(:last_status, from_account: [:account_stat, :user]).to_a_paginated_by_id(
|
||||
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
||||
params_slice(:max_id, :since_id, :min_id)
|
||||
)
|
||||
|
||||
NotificationRequest.preload_cache_collection(requests) do |statuses|
|
||||
cache_collection(statuses, Status)
|
||||
end
|
||||
end
|
||||
|
||||
def relationships
|
||||
StatusRelationshipsPresenter.new(@requests.map(&:last_status), current_user&.account_id)
|
||||
end
|
||||
|
||||
def set_request
|
||||
@request = NotificationRequest.where(account: current_account).find(params[:id])
|
||||
end
|
||||
|
||||
def insert_pagination_headers
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
|
||||
def next_path
|
||||
api_v1_notifications_requests_url pagination_params(max_id: pagination_max_id) unless @requests.empty?
|
||||
end
|
||||
|
||||
def prev_path
|
||||
api_v1_notifications_requests_url pagination_params(min_id: pagination_since_id) unless @requests.empty?
|
||||
end
|
||||
|
||||
def pagination_max_id
|
||||
@requests.last.id
|
||||
end
|
||||
|
||||
def pagination_since_id
|
||||
@requests.first.id
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:dismissed).permit(:dismissed).merge(core_params)
|
||||
end
|
||||
end
|
@ -49,7 +49,8 @@ class Api::V1::NotificationsController < Api::BaseController
|
||||
current_account.notifications.without_suspended.browserable(
|
||||
types: Array(browserable_params[:types]),
|
||||
exclude_types: Array(browserable_params[:exclude_types]),
|
||||
from_account_id: browserable_params[:account_id]
|
||||
from_account_id: browserable_params[:account_id],
|
||||
include_filtered: truthy_param?(:include_filtered)
|
||||
)
|
||||
end
|
||||
|
||||
@ -78,10 +79,10 @@ class Api::V1::NotificationsController < Api::BaseController
|
||||
end
|
||||
|
||||
def browserable_params
|
||||
params.permit(:account_id, types: [], exclude_types: [])
|
||||
params.permit(:account_id, :include_filtered, types: [], exclude_types: [])
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit, :account_id, :types, :exclude_types).permit(:limit, :account_id, types: [], exclude_types: []).merge(core_params)
|
||||
params.slice(:limit, :account_id, :types, :exclude_types, :include_filtered).permit(:limit, :account_id, :include_filtered, types: [], exclude_types: []).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
@ -15,10 +15,15 @@ module Account::Associations
|
||||
has_many :favourites, inverse_of: :account, dependent: :destroy
|
||||
has_many :bookmarks, inverse_of: :account, dependent: :destroy
|
||||
has_many :mentions, inverse_of: :account, dependent: :destroy
|
||||
has_many :notifications, inverse_of: :account, dependent: :destroy
|
||||
has_many :conversations, class_name: 'AccountConversation', dependent: :destroy, inverse_of: :account
|
||||
has_many :scheduled_statuses, inverse_of: :account, dependent: :destroy
|
||||
|
||||
# Notifications
|
||||
has_many :notifications, inverse_of: :account, dependent: :destroy
|
||||
has_one :notification_policy, inverse_of: :account, dependent: :destroy
|
||||
has_many :notification_permissions, inverse_of: :account, dependent: :destroy
|
||||
has_many :notification_requests, inverse_of: :account, dependent: :destroy
|
||||
|
||||
# Pinned statuses
|
||||
has_many :status_pins, inverse_of: :account, dependent: :destroy
|
||||
has_many :pinned_statuses, -> { reorder('status_pins.created_at DESC') }, through: :status_pins, class_name: 'Status', source: :status
|
||||
|
@ -12,6 +12,7 @@
|
||||
# account_id :bigint(8) not null
|
||||
# from_account_id :bigint(8) not null
|
||||
# type :string
|
||||
# filtered :boolean default(FALSE), not null
|
||||
#
|
||||
|
||||
class Notification < ApplicationRecord
|
||||
@ -89,7 +90,7 @@ class Notification < ApplicationRecord
|
||||
end
|
||||
|
||||
class << self
|
||||
def browserable(types: [], exclude_types: [], from_account_id: nil)
|
||||
def browserable(types: [], exclude_types: [], from_account_id: nil, include_filtered: false)
|
||||
requested_types = if types.empty?
|
||||
TYPES
|
||||
else
|
||||
@ -99,6 +100,7 @@ class Notification < ApplicationRecord
|
||||
requested_types -= exclude_types.map(&:to_sym)
|
||||
|
||||
all.tap do |scope|
|
||||
scope.merge!(where(filtered: false)) unless include_filtered || from_account_id.present?
|
||||
scope.merge!(where(from_account_id: from_account_id)) if from_account_id.present?
|
||||
scope.merge!(where(type: requested_types)) unless requested_types.size == TYPES.size
|
||||
end
|
||||
@ -144,6 +146,8 @@ class Notification < ApplicationRecord
|
||||
after_initialize :set_from_account
|
||||
before_validation :set_from_account
|
||||
|
||||
after_destroy :remove_from_notification_request
|
||||
|
||||
private
|
||||
|
||||
def set_from_account
|
||||
@ -158,4 +162,9 @@ class Notification < ApplicationRecord
|
||||
self.from_account_id = activity&.id
|
||||
end
|
||||
end
|
||||
|
||||
def remove_from_notification_request
|
||||
notification_request = NotificationRequest.find_by(account_id: account_id, from_account_id: from_account_id)
|
||||
notification_request&.reconsider_existence!
|
||||
end
|
||||
end
|
||||
|
16
app/models/notification_permission.rb
Normal file
16
app/models/notification_permission.rb
Normal file
@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: notification_permissions
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# account_id :bigint(8) not null
|
||||
# from_account_id :bigint(8) not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
class NotificationPermission < ApplicationRecord
|
||||
belongs_to :account
|
||||
belongs_to :from_account, class_name: 'Account'
|
||||
end
|
36
app/models/notification_policy.rb
Normal file
36
app/models/notification_policy.rb
Normal file
@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: notification_policies
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# account_id :bigint(8) not null
|
||||
# filter_not_following :boolean default(FALSE), not null
|
||||
# filter_not_followers :boolean default(FALSE), not null
|
||||
# filter_new_accounts :boolean default(FALSE), not null
|
||||
# filter_private_mentions :boolean default(TRUE), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
class NotificationPolicy < ApplicationRecord
|
||||
belongs_to :account
|
||||
|
||||
has_many :notification_requests, primary_key: :account_id, foreign_key: :account_id, dependent: nil, inverse_of: false
|
||||
|
||||
attr_reader :pending_requests_count, :pending_notifications_count
|
||||
|
||||
MAX_MEANINGFUL_COUNT = 100
|
||||
|
||||
def summarize!
|
||||
@pending_requests_count = pending_notification_requests.first
|
||||
@pending_notifications_count = pending_notification_requests.last
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pending_notification_requests
|
||||
@pending_notification_requests ||= notification_requests.where(dismissed: false).limit(MAX_MEANINGFUL_COUNT).pick(Arel.sql('count(*), coalesce(sum(notifications_count), 0)::bigint'))
|
||||
end
|
||||
end
|
53
app/models/notification_request.rb
Normal file
53
app/models/notification_request.rb
Normal file
@ -0,0 +1,53 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: notification_requests
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# account_id :bigint(8) not null
|
||||
# from_account_id :bigint(8) not null
|
||||
# last_status_id :bigint(8) not null
|
||||
# notifications_count :bigint(8) default(0), not null
|
||||
# dismissed :boolean default(FALSE), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
class NotificationRequest < ApplicationRecord
|
||||
include Paginable
|
||||
|
||||
MAX_MEANINGFUL_COUNT = 100
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :from_account, class_name: 'Account'
|
||||
belongs_to :last_status, class_name: 'Status'
|
||||
|
||||
before_save :prepare_notifications_count
|
||||
|
||||
def self.preload_cache_collection(requests)
|
||||
cached_statuses_by_id = yield(requests.filter_map(&:last_status)).index_by(&:id) # Call cache_collection in block
|
||||
|
||||
requests.each do |request|
|
||||
request.last_status = cached_statuses_by_id[request.last_status_id] unless request.last_status_id.nil?
|
||||
end
|
||||
end
|
||||
|
||||
def reconsider_existence!
|
||||
return if dismissed?
|
||||
|
||||
prepare_notifications_count
|
||||
|
||||
if notifications_count.positive?
|
||||
save
|
||||
else
|
||||
destroy
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prepare_notifications_count
|
||||
self.notifications_count = Notification.where(account: account, from_account: from_account).limit(MAX_MEANINGFUL_COUNT).count
|
||||
end
|
||||
end
|
16
app/serializers/rest/notification_policy_serializer.rb
Normal file
16
app/serializers/rest/notification_policy_serializer.rb
Normal file
@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class REST::NotificationPolicySerializer < ActiveModel::Serializer
|
||||
attributes :filter_not_following,
|
||||
:filter_not_followers,
|
||||
:filter_new_accounts,
|
||||
:filter_private_mentions,
|
||||
:summary
|
||||
|
||||
def summary
|
||||
{
|
||||
pending_requests_count: object.pending_requests_count.to_s,
|
||||
pending_notifications_count: object.pending_notifications_count.to_s,
|
||||
}
|
||||
end
|
||||
end
|
16
app/serializers/rest/notification_request_serializer.rb
Normal file
16
app/serializers/rest/notification_request_serializer.rb
Normal file
@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class REST::NotificationRequestSerializer < ActiveModel::Serializer
|
||||
attributes :id, :created_at, :updated_at, :notifications_count
|
||||
|
||||
belongs_to :from_account, key: :account, serializer: REST::AccountSerializer
|
||||
belongs_to :last_status, serializer: REST::StatusSerializer
|
||||
|
||||
def id
|
||||
object.id.to_s
|
||||
end
|
||||
|
||||
def notifications_count
|
||||
object.notifications_count.to_s
|
||||
end
|
||||
end
|
8
app/services/accept_notification_request_service.rb
Normal file
8
app/services/accept_notification_request_service.rb
Normal file
@ -0,0 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AcceptNotificationRequestService < BaseService
|
||||
def call(request)
|
||||
NotificationPermission.create!(account: request.account, from_account: request.from_account)
|
||||
UnfilterNotificationsWorker.perform_async(request.id)
|
||||
end
|
||||
end
|
@ -11,60 +11,131 @@ class NotifyService < BaseService
|
||||
status
|
||||
).freeze
|
||||
|
||||
def call(recipient, type, activity)
|
||||
@recipient = recipient
|
||||
@activity = activity
|
||||
@notification = Notification.new(account: @recipient, type: type, activity: @activity)
|
||||
class DismissCondition
|
||||
def initialize(notification)
|
||||
@recipient = notification.account
|
||||
@sender = notification.from_account
|
||||
@notification = notification
|
||||
end
|
||||
|
||||
return if recipient.user.nil? || blocked?
|
||||
def dismiss?
|
||||
blocked = @recipient.unavailable?
|
||||
blocked ||= from_self? && @notification.type != :poll
|
||||
|
||||
@notification.save!
|
||||
return blocked if message? && from_staff?
|
||||
|
||||
# It's possible the underlying activity has been deleted
|
||||
# between the save call and now
|
||||
return if @notification.activity.nil?
|
||||
|
||||
push_notification!
|
||||
push_to_conversation! if direct_message?
|
||||
send_email! if email_needed?
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
nil
|
||||
blocked ||= domain_blocking?
|
||||
blocked ||= @recipient.blocking?(@sender)
|
||||
blocked ||= @recipient.muting_notifications?(@sender)
|
||||
blocked ||= conversation_muted?
|
||||
blocked ||= blocked_mention? if message?
|
||||
blocked
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def blocked_mention?
|
||||
FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient)
|
||||
end
|
||||
|
||||
def following_sender?
|
||||
return @following_sender if defined?(@following_sender)
|
||||
|
||||
@following_sender = @recipient.following?(@notification.from_account) || @recipient.requested?(@notification.from_account)
|
||||
end
|
||||
|
||||
def optional_non_follower?
|
||||
@recipient.user.settings['interactions.must_be_follower'] && !@notification.from_account.following?(@recipient)
|
||||
end
|
||||
|
||||
def optional_non_following?
|
||||
@recipient.user.settings['interactions.must_be_following'] && !following_sender?
|
||||
FeedManager.instance.filter?(:mentions, @notification.target_status, @recipient)
|
||||
end
|
||||
|
||||
def message?
|
||||
@notification.type == :mention
|
||||
end
|
||||
|
||||
def direct_message?
|
||||
message? && @notification.target_status.direct_visibility?
|
||||
def from_staff?
|
||||
@sender.local? && @sender.user.present? && @sender.user_role&.overrides?(@recipient.user_role)
|
||||
end
|
||||
|
||||
def from_self?
|
||||
@recipient.id == @sender.id
|
||||
end
|
||||
|
||||
def domain_blocking?
|
||||
@recipient.domain_blocking?(@sender.domain) && !following_sender?
|
||||
end
|
||||
|
||||
def conversation_muted?
|
||||
@notification.target_status && @recipient.muting_conversation?(@notification.target_status.conversation)
|
||||
end
|
||||
|
||||
def following_sender?
|
||||
@recipient.following?(@sender)
|
||||
end
|
||||
end
|
||||
|
||||
class FilterCondition
|
||||
NEW_ACCOUNT_THRESHOLD = 30.days.freeze
|
||||
|
||||
NEW_FOLLOWER_THRESHOLD = 3.days.freeze
|
||||
|
||||
def initialize(notification)
|
||||
@notification = notification
|
||||
@recipient = notification.account
|
||||
@sender = notification.from_account
|
||||
@policy = NotificationPolicy.find_or_initialize_by(account: @recipient)
|
||||
end
|
||||
|
||||
def filter?
|
||||
return false if override_for_sender?
|
||||
|
||||
from_limited? ||
|
||||
filtered_by_not_following_policy? ||
|
||||
filtered_by_not_followers_policy? ||
|
||||
filtered_by_new_accounts_policy? ||
|
||||
filtered_by_private_mentions_policy?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filtered_by_not_following_policy?
|
||||
@policy.filter_not_following? && not_following?
|
||||
end
|
||||
|
||||
def filtered_by_not_followers_policy?
|
||||
@policy.filter_not_followers? && not_follower?
|
||||
end
|
||||
|
||||
def filtered_by_new_accounts_policy?
|
||||
@policy.filter_new_accounts? && new_account?
|
||||
end
|
||||
|
||||
def filtered_by_private_mentions_policy?
|
||||
@policy.filter_private_mentions? && not_following? && private_mention_not_in_response?
|
||||
end
|
||||
|
||||
def not_following?
|
||||
!@recipient.following?(@sender)
|
||||
end
|
||||
|
||||
def not_follower?
|
||||
follow = Follow.find_by(account: @sender, target_account: @recipient)
|
||||
follow.nil? || follow.created_at > NEW_FOLLOWER_THRESHOLD.ago
|
||||
end
|
||||
|
||||
def new_account?
|
||||
@sender.created_at > NEW_ACCOUNT_THRESHOLD.ago
|
||||
end
|
||||
|
||||
def override_for_sender?
|
||||
NotificationPermission.exists?(account: @recipient, from_account: @sender)
|
||||
end
|
||||
|
||||
def from_limited?
|
||||
@sender.silenced? && not_following?
|
||||
end
|
||||
|
||||
def private_mention_not_in_response?
|
||||
@notification.type == :mention && @notification.target_status.direct_visibility? && !response_to_recipient?
|
||||
end
|
||||
|
||||
# Returns true if the sender has been mentioned by the recipient up the thread
|
||||
def response_to_recipient?
|
||||
return false if @notification.target_status.in_reply_to_id.nil?
|
||||
|
||||
# Using an SQL CTE to avoid unneeded back-and-forth with SQL server in case of long threads
|
||||
!Status.count_by_sql([<<-SQL.squish, id: @notification.target_status.in_reply_to_id, recipient_id: @recipient.id, sender_id: @notification.from_account.id, depth_limit: 100]).zero?
|
||||
statuses_that_mention_sender.positive?
|
||||
end
|
||||
|
||||
def statuses_that_mention_sender
|
||||
Status.count_by_sql([<<-SQL.squish, id: @notification.target_status.in_reply_to_id, recipient_id: @recipient.id, sender_id: @sender.id, depth_limit: 100])
|
||||
WITH RECURSIVE ancestors(id, in_reply_to_id, mention_id, path, depth) AS (
|
||||
SELECT s.id, s.in_reply_to_id, m.id, ARRAY[s.id], 0
|
||||
FROM statuses s
|
||||
@ -83,54 +154,52 @@ class NotifyService < BaseService
|
||||
WHERE st.mention_id IS NOT NULL AND s.visibility = 3
|
||||
SQL
|
||||
end
|
||||
|
||||
def from_staff?
|
||||
@notification.from_account.local? && @notification.from_account.user.present? && @notification.from_account.user_role&.overrides?(@recipient.user_role)
|
||||
end
|
||||
|
||||
def optional_non_following_and_direct?
|
||||
direct_message? &&
|
||||
@recipient.user.settings['interactions.must_be_following_dm'] &&
|
||||
!following_sender? &&
|
||||
!response_to_recipient?
|
||||
end
|
||||
def call(recipient, type, activity)
|
||||
return if recipient.user.nil?
|
||||
|
||||
def hellbanned?
|
||||
@notification.from_account.silenced? && !following_sender?
|
||||
end
|
||||
@recipient = recipient
|
||||
@activity = activity
|
||||
@notification = Notification.new(account: @recipient, type: type, activity: @activity)
|
||||
|
||||
def from_self?
|
||||
@recipient.id == @notification.from_account.id
|
||||
end
|
||||
# For certain conditions we don't need to create a notification at all
|
||||
return if dismiss?
|
||||
|
||||
def domain_blocking?
|
||||
@recipient.domain_blocking?(@notification.from_account.domain) && !following_sender?
|
||||
end
|
||||
@notification.filtered = filter?
|
||||
@notification.save!
|
||||
|
||||
def blocked?
|
||||
blocked = @recipient.unavailable?
|
||||
blocked ||= from_self? && @notification.type != :poll
|
||||
# It's possible the underlying activity has been deleted
|
||||
# between the save call and now
|
||||
return if @notification.activity.nil?
|
||||
|
||||
return blocked if message? && from_staff?
|
||||
|
||||
blocked ||= domain_blocking?
|
||||
blocked ||= @recipient.blocking?(@notification.from_account)
|
||||
blocked ||= @recipient.muting_notifications?(@notification.from_account)
|
||||
blocked ||= hellbanned?
|
||||
blocked ||= optional_non_follower?
|
||||
blocked ||= optional_non_following?
|
||||
blocked ||= optional_non_following_and_direct?
|
||||
blocked ||= conversation_muted?
|
||||
blocked ||= blocked_mention? if @notification.type == :mention
|
||||
blocked
|
||||
end
|
||||
|
||||
def conversation_muted?
|
||||
if @notification.target_status
|
||||
@recipient.muting_conversation?(@notification.target_status.conversation)
|
||||
if @notification.filtered?
|
||||
update_notification_request!
|
||||
else
|
||||
false
|
||||
push_notification!
|
||||
push_to_conversation! if direct_message?
|
||||
send_email! if email_needed?
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def dismiss?
|
||||
DismissCondition.new(@notification).dismiss?
|
||||
end
|
||||
|
||||
def filter?
|
||||
FilterCondition.new(@notification).filter?
|
||||
end
|
||||
|
||||
def update_notification_request!
|
||||
return unless @notification.type == :mention
|
||||
|
||||
notification_request = NotificationRequest.find_or_initialize_by(account_id: @recipient.id, from_account_id: @notification.from_account_id)
|
||||
notification_request.last_status_id = @notification.target_status.id
|
||||
notification_request.save
|
||||
end
|
||||
|
||||
def push_notification!
|
||||
@ -150,6 +219,10 @@ class NotifyService < BaseService
|
||||
AccountConversation.add_status(@recipient, @notification.target_status)
|
||||
end
|
||||
|
||||
def direct_message?
|
||||
@notification.type == :mention && @notification.target_status.direct_visibility?
|
||||
end
|
||||
|
||||
def push_to_web_push_subscriptions!
|
||||
::Web::PushNotificationWorker.push_bulk(web_push_subscriptions.select { |subscription| subscription.pushable?(@notification) }) { |subscription| [subscription.id, @notification.id] }
|
||||
end
|
||||
|
@ -40,11 +40,3 @@
|
||||
label_method: ->(setting) { I18n.t("simple_form.labels.notification_emails.software_updates.#{setting}") },
|
||||
label: I18n.t('simple_form.labels.notification_emails.software_updates.label'),
|
||||
wrapper: :with_label
|
||||
|
||||
%h4= t 'notifications.other_settings'
|
||||
|
||||
.fields-group
|
||||
= f.simple_fields_for :settings, current_user.settings do |ff|
|
||||
= ff.input :'interactions.must_be_follower', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_follower')
|
||||
= ff.input :'interactions.must_be_following', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_following')
|
||||
= ff.input :'interactions.must_be_following_dm', wrapper: :with_label, label: I18n.t('simple_form.labels.interactions.must_be_following_dm')
|
||||
|
37
app/workers/unfilter_notifications_worker.rb
Normal file
37
app/workers/unfilter_notifications_worker.rb
Normal file
@ -0,0 +1,37 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class UnfilterNotificationsWorker
|
||||
include Sidekiq::Worker
|
||||
|
||||
def perform(notification_request_id)
|
||||
@notification_request = NotificationRequest.find(notification_request_id)
|
||||
|
||||
push_to_conversations!
|
||||
unfilter_notifications!
|
||||
remove_request!
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def push_to_conversations!
|
||||
notifications_with_private_mentions.find_each { |notification| AccountConversation.add_status(@notification_request.account, notification.target_status) }
|
||||
end
|
||||
|
||||
def unfilter_notifications!
|
||||
filtered_notifications.in_batches.update_all(filtered: false)
|
||||
end
|
||||
|
||||
def remove_request!
|
||||
@notification_request.destroy!
|
||||
end
|
||||
|
||||
def filtered_notifications
|
||||
Notification.where(account: @notification_request.account, from_account: @notification_request.from_account, filtered: true)
|
||||
end
|
||||
|
||||
def notifications_with_private_mentions
|
||||
filtered_notifications.joins(mention: :status).merge(Status.where(visibility: :direct)).includes(mention: :status)
|
||||
end
|
||||
end
|
@ -1288,7 +1288,6 @@ an:
|
||||
notifications:
|
||||
email_events: Eventos pa notificacions per correu electronico
|
||||
email_events_hint: 'Tría los eventos pa los quals deseyas recibir notificacions:'
|
||||
other_settings: Atros achustes de notificacions
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1594,7 +1594,6 @@ ar:
|
||||
administration_emails: إشعارات البريد الإلكتروني الإدارية
|
||||
email_events: الأحداث للإشعارات عبر البريد الإلكتروني
|
||||
email_events_hint: 'اختر الأحداث التي تريد أن تصِلَك اشعارات عنها:'
|
||||
other_settings: إعدادات أخرى للإشعارات
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -695,7 +695,6 @@ ast:
|
||||
notifications:
|
||||
email_events: Unviu d'avisos per corréu electrónicu
|
||||
email_events_hint: 'Seleiciona los eventos de los que quies recibir avisos:'
|
||||
other_settings: Configuración d'otros avisos
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1547,7 +1547,6 @@ be:
|
||||
administration_emails: Апавяшчэнні эл. пошты для адміністратара
|
||||
email_events: Падзеі для апавяшчэнняў эл. пошты
|
||||
email_events_hint: 'Выберыце падзеі, аб якіх вы хочаце атрымліваць апавяшчэнні:'
|
||||
other_settings: Іншыя налады апавяшчэнняў
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1490,7 +1490,6 @@ bg:
|
||||
administration_emails: Администраторски известия по имейла
|
||||
email_events: Събития за известия по имейл
|
||||
email_events_hint: 'Изберете събития, за които искате да получавате известия:'
|
||||
other_settings: Настройки за други известия
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ ca:
|
||||
administration_emails: Notificacions per correu-e de l'Admin
|
||||
email_events: Esdeveniments per a notificacions de correu electrònic
|
||||
email_events_hint: 'Selecciona els esdeveniments per als quals vols rebre notificacions:'
|
||||
other_settings: Altres opcions de notificació
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -840,7 +840,6 @@ ckb:
|
||||
notifications:
|
||||
email_events: رووداوەکان بۆ ئاگاداری ئیمەیلی
|
||||
email_events_hint: 'ئەو ڕووداوانە دیاریبکە کە دەتەوێت ئاگانامەکان وەربگری بۆ:'
|
||||
other_settings: ڕێکبەندەکانی ئاگانامەکانی تر
|
||||
otp_authentication:
|
||||
code_hint: کۆدێک داخڵ بکە کە دروست کراوە لەلایەن ئەپی ڕەسەنایەتیەوە بۆ دڵنیابوون
|
||||
description_html: ئەگەر تۆ <strong> هاتنەژوورەوەی دوو قۆناغی</strong> بە یارمەتی ئەپێکی پەسەندکردن چالاک بکەن، پێویستە بۆ چوونەژوورەوە ، بە تەلەفۆنەکەتان کە کۆدیکتان بۆ دروستدەکات دەستپێگەیشتنتان هەبێت.
|
||||
|
@ -809,7 +809,6 @@ co:
|
||||
notifications:
|
||||
email_events: Avvenimenti da nutificà cù l'e-mail
|
||||
email_events_hint: 'Selezziunate l''avvenimenti per quelli vulete riceve nutificazione:'
|
||||
other_settings: Altri parametri di nutificazione
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1547,7 +1547,6 @@ cs:
|
||||
administration_emails: E-mailová oznámení administrátora
|
||||
email_events: Události pro e-mailová oznámení
|
||||
email_events_hint: 'Vyberte události, pro které chcete dostávat oznámení:'
|
||||
other_settings: Další nastavení oznámení
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1599,7 +1599,6 @@ cy:
|
||||
administration_emails: Hysbysiadau e-bost gweinyddol
|
||||
email_events: Digwyddiadau ar gyfer hysbysiadau e-bost
|
||||
email_events_hint: 'Dewiswch ddigwyddiadau yr ydych am dderbyn hysbysiadau ar eu cyfer:'
|
||||
other_settings: Gosodiadau hysbysiadau arall
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ da:
|
||||
administration_emails: Admin e-mailnotifikationer
|
||||
email_events: Begivenheder for e-mailnotifikationer
|
||||
email_events_hint: 'Vælg begivenheder, for hvilke notifikationer skal modtages:'
|
||||
other_settings: Andre notifikationsindstillinger
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ de:
|
||||
administration_emails: Admin-E-Mail-Benachrichtigungen
|
||||
email_events: Benachrichtigungen per E-Mail
|
||||
email_events_hint: 'Bitte die Ereignisse auswählen, für die du Benachrichtigungen per E-Mail erhalten möchtest:'
|
||||
other_settings: Weitere Benachrichtigungseinstellungen
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1383,7 +1383,6 @@ el:
|
||||
notifications:
|
||||
email_events: Συμβάντα για ειδοποιήσεις μέσω email
|
||||
email_events_hint: 'Επέλεξε συμβάντα για τα οποία θέλεις να λαμβάνεις ειδοποιήσεις μέσω email:'
|
||||
other_settings: Άλλες ρυθμίσεις ειδοποιήσεων
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1490,7 +1490,6 @@ en-GB:
|
||||
administration_emails: Admin e-mail notifications
|
||||
email_events: Events for e-mail notifications
|
||||
email_events_hint: 'Select events that you want to receive notifications for:'
|
||||
other_settings: Other notifications settings
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ en:
|
||||
administration_emails: Admin e-mail notifications
|
||||
email_events: Events for e-mail notifications
|
||||
email_events_hint: 'Select events that you want to receive notifications for:'
|
||||
other_settings: Other notifications settings
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1425,7 +1425,6 @@ eo:
|
||||
administration_emails: Admin retpoŝtaj sciigoj
|
||||
email_events: Eventoj por retpoŝtaj sciigoj
|
||||
email_events_hint: 'Elekti la eventojn pri kioj vi volas ricevi sciigojn:'
|
||||
other_settings: Aliaj agordoj de sciigoj
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ es-AR:
|
||||
administration_emails: Notificaciones de administración por correo electrónico
|
||||
email_events: Eventos para notificaciones por correo electrónico
|
||||
email_events_hint: 'Seleccioná los eventos para los que querés recibir notificaciones:'
|
||||
other_settings: Configuración de otras notificaciones
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ es-MX:
|
||||
administration_emails: Notificaciones de administración por correo electrónico
|
||||
email_events: Eventos para notificaciones por correo electrónico
|
||||
email_events_hint: 'Selecciona los eventos para los que deseas recibir notificaciones:'
|
||||
other_settings: Otros ajustes de notificaciones
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ es:
|
||||
administration_emails: Notificaciones de administración por correo electrónico
|
||||
email_events: Eventos para notificaciones por correo electrónico
|
||||
email_events_hint: 'Selecciona los eventos para los que deseas recibir notificaciones:'
|
||||
other_settings: Otros ajustes de notificaciones
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1490,7 +1490,6 @@ et:
|
||||
administration_emails: Admini e-postiteavitused
|
||||
email_events: E-posti teadete sündmused
|
||||
email_events_hint: 'Vali sündmused, mille kohta soovid teavitusi:'
|
||||
other_settings: Muud teadete sätted
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1496,7 +1496,6 @@ eu:
|
||||
administration_emails: Administratzailearen posta elektroniko bidezko jakinarazpenak
|
||||
email_events: E-mail jakinarazpenentzako gertaerak
|
||||
email_events_hint: 'Hautatu jaso nahi dituzun gertaeren jakinarazpenak:'
|
||||
other_settings: Bezte jakinarazpen konfigurazioak
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1271,7 +1271,6 @@ fa:
|
||||
notifications:
|
||||
email_events: رویدادها برای آگاهیهای رایانامهای
|
||||
email_events_hint: 'گزینش رویدادهایی که میخواهید برایشان آگاهی دریافت کنید:'
|
||||
other_settings: سایر تنظیمات آگاهیها
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ fi:
|
||||
administration_emails: Ylläpitäjän sähköposti-ilmoitukset
|
||||
email_events: Sähköposti-ilmoitusten tapahtumat
|
||||
email_events_hint: 'Valitse tapahtumat, joista haluat saada ilmoituksia:'
|
||||
other_settings: Muut ilmoitusasetukset
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ fo:
|
||||
administration_emails: Fráboðanir um teldupost til umsitarar
|
||||
email_events: Hendingar fyri teldupostfráboðanir
|
||||
email_events_hint: 'Vel hendingar, sum tú vil hava fráboðanir um:'
|
||||
other_settings: Aðrar fráboðanarstillingar
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1490,7 +1490,6 @@ fr-CA:
|
||||
administration_emails: Notifications par e-mail de l’admin
|
||||
email_events: Événements pour les notifications par courriel
|
||||
email_events_hint: 'Sélectionnez les événements pour lesquels vous souhaitez recevoir des notifications :'
|
||||
other_settings: Autres paramètres de notifications
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1490,7 +1490,6 @@ fr:
|
||||
administration_emails: Notifications par e-mail de l’admin
|
||||
email_events: Événements pour les notifications par courriel
|
||||
email_events_hint: 'Sélectionnez les événements pour lesquels vous souhaitez recevoir des notifications :'
|
||||
other_settings: Autres paramètres de notifications
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1490,7 +1490,6 @@ fy:
|
||||
administration_emails: E-mailmeldingen behearder
|
||||
email_events: E-mailmeldingen foar eveneminten
|
||||
email_events_hint: 'Selektearje eveneminten wêrfoar’t jo meldingen ûntfange wolle:'
|
||||
other_settings: Oare meldingsynstellingen
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1532,7 +1532,6 @@ gd:
|
||||
administration_emails: Brathan puist-d na rianachd
|
||||
email_events: Tachartasan nam brathan puist-d
|
||||
email_events_hint: 'Tagh na tachartasan dhan a bheil thu airson brathan fhaighinn:'
|
||||
other_settings: Roghainnean eile nam brathan
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ gl:
|
||||
administration_emails: Notificacións de Admin por correo electrónico
|
||||
email_events: Eventos para os correos de notificación
|
||||
email_events_hint: 'Escolle os eventos sobre os que queres recibir notificacións:'
|
||||
other_settings: Outros axustes das notificacións
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1547,7 +1547,6 @@ he:
|
||||
administration_emails: התראות לדוא"ל חשבון מנהל
|
||||
email_events: ארועים להתראות דוא"ל
|
||||
email_events_hint: 'בחר/י ארועים עבורים תרצה/י לקבל התראות:'
|
||||
other_settings: הגדרות התראות אחרות
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ hu:
|
||||
administration_emails: Adminisztrátori e-mail-értesítések
|
||||
email_events: Események email értesítésekhez
|
||||
email_events_hint: 'Válaszd ki azokat az eseményeket, melyekről értesítést szeretnél:'
|
||||
other_settings: Értesítések egyéb beállításai
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -672,7 +672,6 @@ hy:
|
||||
subject: "%{name}-ը փոխել է գրառումը"
|
||||
notifications:
|
||||
email_events_hint: Ընտրիր իրադարձութիւնները, որոնց վերաբերեալ ցանկանում ես ստանալ ծանուցումներ․
|
||||
other_settings: Ծանուցումների այլ կարգաւորումներ
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1257,7 +1257,6 @@ id:
|
||||
notifications:
|
||||
email_events: Event untuk notifikasi email
|
||||
email_events_hint: 'Pilih event yang ingin Anda terima notifikasinya:'
|
||||
other_settings: Pengaturan notifikasi lain
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ ie:
|
||||
administration_emails: Email-notificationes pri administration
|
||||
email_events: Evenimentes por email-notificationes
|
||||
email_events_hint: 'Selecte li evenimentes pri queles tu vole reciver notificationes:'
|
||||
other_settings: Parametres pri altri notificationes
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1472,7 +1472,6 @@ io:
|
||||
administration_emails: Jerala retpostonotifiki
|
||||
email_events: Eventi por retpostoavizi
|
||||
email_events_hint: 'Selektez eventi quon vu volas ganar avizi:'
|
||||
other_settings: Altra avizopcioni
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1499,7 +1499,6 @@ is:
|
||||
administration_emails: Kerfisstjórnunartilkynningar í tölvupósti
|
||||
email_events: Atburðir fyrir tilkynningar í tölvupósti
|
||||
email_events_hint: 'Veldu þá atburði sem þú vilt fá tilkynningar í tölvupósti þegar þeir koma upp:'
|
||||
other_settings: Aðrar stillingar varðandi tilkynningar
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1497,7 +1497,6 @@ it:
|
||||
administration_emails: Notifiche email amministratore
|
||||
email_events: Eventi per notifiche via email
|
||||
email_events_hint: 'Seleziona gli eventi per i quali vuoi ricevere le notifiche:'
|
||||
other_settings: Altre impostazioni delle notifiche
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1469,7 +1469,6 @@ ja:
|
||||
administration_emails: 管理にかかわるメール通知
|
||||
email_events: メールによる通知
|
||||
email_events_hint: '受信する通知を選択:'
|
||||
other_settings: その他の通知設定
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -626,8 +626,6 @@ kab:
|
||||
subject: Yuder-ik·ikem-id %{name}
|
||||
reblog:
|
||||
subject: "%{name} yesselha addad-ik·im"
|
||||
notifications:
|
||||
other_settings: Iɣewwaṛen nniḍen n yilɣa
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -539,7 +539,6 @@ kk:
|
||||
notifications:
|
||||
email_events: E-mail ескертпелеріне шаралар
|
||||
email_events_hint: 'Ескертпе болып келетін шараларды таңда:'
|
||||
other_settings: Ескертпелердің басқа баптаулары
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1471,7 +1471,6 @@ ko:
|
||||
administration_emails: 관리자 이메일 알림
|
||||
email_events: 이메일 알림에 대한 이벤트
|
||||
email_events_hint: '알림 받을 이벤트를 선택해주세요:'
|
||||
other_settings: 기타 알림 설정
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1285,7 +1285,6 @@ ku:
|
||||
notifications:
|
||||
email_events: Bûyer bo agahdariyên e-nameyê
|
||||
email_events_hint: 'Bûyera ku tu dixwazî agahdariyan jê wergerî hilbijêre:'
|
||||
other_settings: Sazkariya agahdariyên din
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ lad:
|
||||
administration_emails: Avizos de administrasyon por posta
|
||||
email_events: Evenimyentos para avizos por posta
|
||||
email_events_hint: 'Eskoje los evenimientos para los kualos keres risivir avizos:'
|
||||
other_settings: Otras preferensyas de avizos
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1513,7 +1513,6 @@ lv:
|
||||
administration_emails: Administrators e-pasta paziņojumi
|
||||
email_events: E-pasta paziņojumu notikumi
|
||||
email_events_hint: 'Atlasi notikumus, par kuriem vēlies saņemt paziņojumus:'
|
||||
other_settings: Citu paziņojumu iestatījumi
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1442,7 +1442,6 @@ ms:
|
||||
administration_emails: Notifikasi e-mel pentadbir
|
||||
email_events: Acara untuk pemberitahuan e-mel
|
||||
email_events_hint: 'Pilih acara yang ingin anda terima pemberitahuan:'
|
||||
other_settings: Tetapan notifikasi lain
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1445,7 +1445,6 @@ my:
|
||||
administration_emails: စီမံခန့်ခွဲသူ အီးမေးလ် အသိပေးချက်များ
|
||||
email_events: အီးမေးလ်သတိပေးချက်များအတွက်အကြောင်းအရာများ
|
||||
email_events_hint: အသိပေးချက်များရယူမည့် အစီအစဉ်များကို ရွေးပါ -
|
||||
other_settings: အခြားအသိပေးချက်များ၏ သတ်မှတ်ချက်များ
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ nl:
|
||||
administration_emails: E-mailmeldingen beheerder
|
||||
email_events: E-mailmeldingen voor gebeurtenissen
|
||||
email_events_hint: 'Selecteer gebeurtenissen waarvoor je meldingen wilt ontvangen:'
|
||||
other_settings: Andere meldingsinstellingen
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ nn:
|
||||
administration_emails: Administrator sine epost-varsler
|
||||
email_events: E-postvarslinger for hendelser
|
||||
email_events_hint: 'Velg hendelser som du vil motta varslinger for:'
|
||||
other_settings: Andre varslingsinnstillinger
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1490,7 +1490,6 @@
|
||||
administration_emails: Administrators e-postvarslinger
|
||||
email_events: E-postvarslinger for hendelser
|
||||
email_events_hint: 'Velg hendelser som du vil motta varslinger for:'
|
||||
other_settings: Andre varslingsinnstillinger
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -724,7 +724,6 @@ oc:
|
||||
notifications:
|
||||
email_events: Eveniments per las notificacions per corrièl
|
||||
email_events_hint: 'Seleccionatz los eveniments que volètz recebre :'
|
||||
other_settings: Autres paramètres de notificacion
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1547,7 +1547,6 @@ pl:
|
||||
administration_emails: Administracyjne powiadomienia e-mail
|
||||
email_events: 'Powiadamiaj e-mailem o:'
|
||||
email_events_hint: 'Wybierz wydarzenia, o których chcesz otrzymywać powiadomienia:'
|
||||
other_settings: Inne ustawienia powiadomień
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1491,7 +1491,6 @@ pt-BR:
|
||||
administration_emails: Notificações por e-mail sobre administração
|
||||
email_events: Eventos para notificações por e-mail
|
||||
email_events_hint: 'Selecione os eventos que deseja receber notificações:'
|
||||
other_settings: Outras opções para notificações
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ pt-PT:
|
||||
administration_emails: Notificções administrativas por e-mail
|
||||
email_events: Eventos para notificações por e-mail
|
||||
email_events_hint: 'Selecione os casos para os quais deseja receber notificações:'
|
||||
other_settings: Outras opções de notificações
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1542,7 +1542,6 @@ ru:
|
||||
administration_emails: Уведомления администратора по электронной почте
|
||||
email_events: События для e-mail уведомлений
|
||||
email_events_hint: 'Выберите события, для которых вы хотели бы получать уведомления:'
|
||||
other_settings: Остальные настройки уведомлений
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -865,7 +865,6 @@ sc:
|
||||
notifications:
|
||||
email_events: Eventos pro notìficas cun posta eletrònica
|
||||
email_events_hint: 'Seletziona eventos pro is chi boles retzire notìficas:'
|
||||
other_settings: Àteras configuratziones de notìficas
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1275,7 +1275,6 @@ sco:
|
||||
notifications:
|
||||
email_events: Events fir email notes
|
||||
email_events_hint: 'Pick events thit ye''r wantin tae get notes fir:'
|
||||
other_settings: Ither notes settins
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1144,7 +1144,6 @@ si:
|
||||
notifications:
|
||||
email_events: ඊමේල් දැනුම්දීම් සඳහා සිදුවීම්
|
||||
email_events_hint: 'ඔබට දැනුම්දීම් ලැබීමට අවශ්ය සිදුවීම් තෝරන්න:'
|
||||
other_settings: වෙනත් දැනුම්දීම් සැකසුම්
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1085,7 +1085,6 @@ sk:
|
||||
notifications:
|
||||
email_events: Udalosti oznamované emailom
|
||||
email_events_hint: 'Vyber si udalosti, pre ktoré chceš dostávať oboznámenia:'
|
||||
other_settings: Ostatné oboznamovacie nastavenia
|
||||
otp_authentication:
|
||||
enable: Povoľ
|
||||
pagination:
|
||||
|
@ -1547,7 +1547,6 @@ sl:
|
||||
administration_emails: E-poštna obvestila skrbnika
|
||||
email_events: Dogodki za e-obvestila
|
||||
email_events_hint: 'Izberite dogodke, za katere želite prejmati obvestila:'
|
||||
other_settings: Druge nastavitve obvestil
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1491,7 +1491,6 @@ sq:
|
||||
administration_emails: Njoftime email për përgjegjësin
|
||||
email_events: Akte për njoftim me email
|
||||
email_events_hint: 'Përzgjidhni akte për të cilët doni të merrni njoftime:'
|
||||
other_settings: Rregullimet të tjera njoftimesh
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1516,7 +1516,6 @@ sr-Latn:
|
||||
administration_emails: Obaveštenja e-poštom od administratora
|
||||
email_events: Događaji za obaveštenja e-poštom
|
||||
email_events_hint: 'Izaberite dešavanja za koja želite da primate obaveštenja:'
|
||||
other_settings: Ostala podešavanja obaveštenja
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1516,7 +1516,6 @@ sr:
|
||||
administration_emails: Обавештења е-поштом од администратора
|
||||
email_events: Догађаји за обавештења е-поштом
|
||||
email_events_hint: 'Изаберите дешавања за која желите да примате обавештења:'
|
||||
other_settings: Остала подешавања обавештења
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1489,7 +1489,6 @@ sv:
|
||||
administration_emails: Admin e-postaviseringar
|
||||
email_events: Händelser för e-postnotiser
|
||||
email_events_hint: 'Välj händelser som du vill ta emot aviseringar för:'
|
||||
other_settings: Andra aviseringsinställningar
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -212,7 +212,6 @@ ta:
|
||||
notifications:
|
||||
email_events: மின்னஞ்சல் அறிவிப்புகளுக்கான நிகழ்வுகள்
|
||||
email_events_hint: 'எந்த நிகழ்வுகளுக்கு அறிவிப்புகளைப் பெற வேண்டும் என்று தேர்வு செய்க:'
|
||||
other_settings: அறிவிப்புகள் குறித்த பிற அமைப்புகள்
|
||||
polls:
|
||||
errors:
|
||||
invalid_choice: நீங்கள் தேர்வு செய்த விருப்பம் கிடைக்கவில்லை
|
||||
|
@ -1469,7 +1469,6 @@ th:
|
||||
administration_emails: การแจ้งเตือนอีเมลผู้ดูแล
|
||||
email_events: เหตุการณ์สำหรับการแจ้งเตือนอีเมล
|
||||
email_events_hint: 'เลือกเหตุการณ์ที่คุณต้องการรับการแจ้งเตือน:'
|
||||
other_settings: การตั้งค่าการแจ้งเตือนอื่น ๆ
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1495,7 +1495,6 @@ tr:
|
||||
administration_emails: Yönetici e-posta bildirimleri
|
||||
email_events: E-posta bildirimi gönderilecek etkinlikler
|
||||
email_events_hint: 'Bildirim almak istediğiniz olayları seçin:'
|
||||
other_settings: Diğer bildirim ayarları
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1547,7 +1547,6 @@ uk:
|
||||
administration_emails: Сповіщення е-пошти адміністратора
|
||||
email_events: Події, про які сповіщати електронною поштою
|
||||
email_events_hint: 'Оберіть події, про які ви хочете отримувати сповіщення:'
|
||||
other_settings: Інші налаштування сповіщень
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1467,7 +1467,6 @@ vi:
|
||||
administration_emails: Email thông báo admin
|
||||
email_events: Email
|
||||
email_events_hint: 'Chọn những hoạt động sẽ gửi thông báo qua email:'
|
||||
other_settings: Chặn thông báo từ
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1469,7 +1469,6 @@ zh-CN:
|
||||
administration_emails: 管理员电子邮件通知
|
||||
email_events: 电子邮件通知事件
|
||||
email_events_hint: 选择你想要收到通知的事件:
|
||||
other_settings: 其它通知设置
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1464,7 +1464,6 @@ zh-HK:
|
||||
administration_emails: 管理員電郵通知
|
||||
email_events: 電郵通知活動
|
||||
email_events_hint: 選擇你想接收通知的活動:
|
||||
other_settings: 其他通知設定
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -1471,7 +1471,6 @@ zh-TW:
|
||||
administration_emails: 管理員電子郵件通知
|
||||
email_events: 電子郵件通知設定
|
||||
email_events_hint: 選取您想接收通知的事件:
|
||||
other_settings: 其他通知設定
|
||||
number:
|
||||
human:
|
||||
decimal_units:
|
||||
|
@ -150,6 +150,17 @@ namespace :api, format: false do
|
||||
end
|
||||
end
|
||||
|
||||
namespace :notifications do
|
||||
resources :requests, only: :index do
|
||||
member do
|
||||
post :accept
|
||||
post :dismiss
|
||||
end
|
||||
end
|
||||
|
||||
resource :policy, only: [:show, :update]
|
||||
end
|
||||
|
||||
resources :notifications, only: [:index, :show] do
|
||||
collection do
|
||||
post :clear
|
||||
|
@ -0,0 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AddFilteredToNotifications < ActiveRecord::Migration[7.1]
|
||||
def change
|
||||
add_column :notifications, :filtered, :boolean, default: false, null: false
|
||||
end
|
||||
end
|
18
db/migrate/20240221195828_create_notification_requests.rb
Normal file
18
db/migrate/20240221195828_create_notification_requests.rb
Normal file
@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class CreateNotificationRequests < ActiveRecord::Migration[7.1]
|
||||
def change
|
||||
create_table :notification_requests do |t|
|
||||
t.references :account, null: false, foreign_key: { on_delete: :cascade }, index: false
|
||||
t.references :from_account, null: false, foreign_key: { to_table: :accounts, on_delete: :cascade }
|
||||
t.references :last_status, null: false, foreign_key: { to_table: :statuses, on_delete: :nullify }
|
||||
t.bigint :notifications_count, null: false, default: 0
|
||||
t.boolean :dismissed, null: false, default: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :notification_requests, [:account_id, :from_account_id], unique: true
|
||||
add_index :notification_requests, [:account_id, :id], where: 'dismissed = false', order: { id: :desc }
|
||||
end
|
||||
end
|
@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class NotificationRequestIdsToTimestampIds < ActiveRecord::Migration[7.1]
|
||||
def up
|
||||
safety_assured do
|
||||
execute("ALTER TABLE notification_requests ALTER COLUMN id SET DEFAULT timestamp_id('notification_requests')")
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
execute('LOCK notification_requests')
|
||||
execute("SELECT setval('notification_requests_id_seq', (SELECT MAX(id) FROM notification_requests))")
|
||||
execute("ALTER TABLE notification_requests ALTER COLUMN id SET DEFAULT nextval('notification_requests_id_seq')")
|
||||
end
|
||||
end
|
12
db/migrate/20240222193403_create_notification_permissions.rb
Normal file
12
db/migrate/20240222193403_create_notification_permissions.rb
Normal file
@ -0,0 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class CreateNotificationPermissions < ActiveRecord::Migration[7.1]
|
||||
def change
|
||||
create_table :notification_permissions do |t|
|
||||
t.references :account, null: false, foreign_key: true
|
||||
t.references :from_account, null: false, foreign_key: { to_table: :accounts }
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
15
db/migrate/20240222203722_create_notification_policies.rb
Normal file
15
db/migrate/20240222203722_create_notification_policies.rb
Normal file
@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class CreateNotificationPolicies < ActiveRecord::Migration[7.1]
|
||||
def change
|
||||
create_table :notification_policies do |t|
|
||||
t.references :account, null: false, foreign_key: true, index: { unique: true }
|
||||
t.boolean :filter_not_following, null: false, default: false
|
||||
t.boolean :filter_not_followers, null: false, default: false
|
||||
t.boolean :filter_new_accounts, null: false, default: false
|
||||
t.boolean :filter_private_mentions, null: false, default: true
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AddFilteredIndexOnNotifications < ActiveRecord::Migration[7.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def change
|
||||
add_index :notifications, [:account_id, :id, :type], where: 'filtered = false', order: { id: :desc }, name: 'index_notifications_on_filtered', algorithm: :concurrently
|
||||
end
|
||||
end
|
@ -0,0 +1,46 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class MigrateInteractionSettingsToPolicy < ActiveRecord::Migration[7.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
# Dummy classes, to make migration possible across version changes
|
||||
class Account < ApplicationRecord
|
||||
has_one :user, inverse_of: :account
|
||||
has_one :notification_policy, inverse_of: :account
|
||||
end
|
||||
|
||||
class User < ApplicationRecord
|
||||
belongs_to :account
|
||||
end
|
||||
|
||||
class NotificationPolicy < ApplicationRecord
|
||||
belongs_to :account
|
||||
end
|
||||
|
||||
def up
|
||||
User.includes(account: :notification_policy).find_each do |user|
|
||||
deserialized_settings = Oj.load(user.attributes_before_type_cast['settings'])
|
||||
policy = user.account.notification_policy || user.account.build_notification_policy
|
||||
requires_new_policy = false
|
||||
|
||||
if deserialized_settings['interactions.must_be_follower']
|
||||
policy.filter_not_followers = true
|
||||
requires_new_policy = true
|
||||
end
|
||||
|
||||
if deserialized_settings['interactions.must_be_following']
|
||||
policy.filter_not_following = true
|
||||
requires_new_policy = true
|
||||
end
|
||||
|
||||
if deserialized_settings['interactions.must_be_following_dm']
|
||||
policy.filter_private_mentions = true
|
||||
requires_new_policy = true
|
||||
end
|
||||
|
||||
policy.save if requires_new_policy && policy.changed?
|
||||
end
|
||||
end
|
||||
|
||||
def down; end
|
||||
end
|
44
db/schema.rb
44
db/schema.rb
@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.1].define(version: 2024_01_11_033014) do
|
||||
ActiveRecord::Schema[7.1].define(version: 2024_03_04_090449) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
@ -666,6 +666,40 @@ ActiveRecord::Schema[7.1].define(version: 2024_01_11_033014) do
|
||||
t.index ["target_account_id"], name: "index_mutes_on_target_account_id"
|
||||
end
|
||||
|
||||
create_table "notification_permissions", force: :cascade do |t|
|
||||
t.bigint "account_id", null: false
|
||||
t.bigint "from_account_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id"], name: "index_notification_permissions_on_account_id"
|
||||
t.index ["from_account_id"], name: "index_notification_permissions_on_from_account_id"
|
||||
end
|
||||
|
||||
create_table "notification_policies", force: :cascade do |t|
|
||||
t.bigint "account_id", null: false
|
||||
t.boolean "filter_not_following", default: false, null: false
|
||||
t.boolean "filter_not_followers", default: false, null: false
|
||||
t.boolean "filter_new_accounts", default: false, null: false
|
||||
t.boolean "filter_private_mentions", default: true, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id"], name: "index_notification_policies_on_account_id", unique: true
|
||||
end
|
||||
|
||||
create_table "notification_requests", id: :bigint, default: -> { "timestamp_id('notification_requests'::text)" }, force: :cascade do |t|
|
||||
t.bigint "account_id", null: false
|
||||
t.bigint "from_account_id", null: false
|
||||
t.bigint "last_status_id", null: false
|
||||
t.bigint "notifications_count", default: 0, null: false
|
||||
t.boolean "dismissed", default: false, null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["account_id", "from_account_id"], name: "index_notification_requests_on_account_id_and_from_account_id", unique: true
|
||||
t.index ["account_id", "id"], name: "index_notification_requests_on_account_id_and_id", order: { id: :desc }, where: "(dismissed = false)"
|
||||
t.index ["from_account_id"], name: "index_notification_requests_on_from_account_id"
|
||||
t.index ["last_status_id"], name: "index_notification_requests_on_last_status_id"
|
||||
end
|
||||
|
||||
create_table "notifications", force: :cascade do |t|
|
||||
t.bigint "activity_id", null: false
|
||||
t.string "activity_type", null: false
|
||||
@ -674,7 +708,9 @@ ActiveRecord::Schema[7.1].define(version: 2024_01_11_033014) do
|
||||
t.bigint "account_id", null: false
|
||||
t.bigint "from_account_id", null: false
|
||||
t.string "type"
|
||||
t.boolean "filtered", default: false, null: false
|
||||
t.index ["account_id", "id", "type"], name: "index_notifications_on_account_id_and_id_and_type", order: { id: :desc }
|
||||
t.index ["account_id", "id", "type"], name: "index_notifications_on_filtered", order: { id: :desc }, where: "(filtered = false)"
|
||||
t.index ["activity_id", "activity_type"], name: "index_notifications_on_activity_id_and_activity_type"
|
||||
t.index ["from_account_id"], name: "index_notifications_on_from_account_id"
|
||||
end
|
||||
@ -1255,6 +1291,12 @@ ActiveRecord::Schema[7.1].define(version: 2024_01_11_033014) do
|
||||
add_foreign_key "mentions", "statuses", on_delete: :cascade
|
||||
add_foreign_key "mutes", "accounts", column: "target_account_id", name: "fk_eecff219ea", on_delete: :cascade
|
||||
add_foreign_key "mutes", "accounts", name: "fk_b8d8daf315", on_delete: :cascade
|
||||
add_foreign_key "notification_permissions", "accounts"
|
||||
add_foreign_key "notification_permissions", "accounts", column: "from_account_id"
|
||||
add_foreign_key "notification_policies", "accounts"
|
||||
add_foreign_key "notification_requests", "accounts", column: "from_account_id", on_delete: :cascade
|
||||
add_foreign_key "notification_requests", "accounts", on_delete: :cascade
|
||||
add_foreign_key "notification_requests", "statuses", column: "last_status_id", on_delete: :nullify
|
||||
add_foreign_key "notifications", "accounts", column: "from_account_id", name: "fk_fbd6b0bf9e", on_delete: :cascade
|
||||
add_foreign_key "notifications", "accounts", name: "fk_c141c8ee55", on_delete: :cascade
|
||||
add_foreign_key "oauth_access_grants", "oauth_applications", column: "application_id", name: "fk_34d54b0a33", on_delete: :cascade
|
||||
|
@ -24,14 +24,13 @@ describe Settings::Preferences::NotificationsController do
|
||||
|
||||
describe 'PUT #update' do
|
||||
it 'updates notifications settings' do
|
||||
user.settings.update('notification_emails.follow': false, 'interactions.must_be_follower': true)
|
||||
user.settings.update('notification_emails.follow': false)
|
||||
user.save
|
||||
|
||||
put :update, params: {
|
||||
user: {
|
||||
settings_attributes: {
|
||||
'notification_emails.follow': '1',
|
||||
'interactions.must_be_follower': '0',
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -39,7 +38,6 @@ describe Settings::Preferences::NotificationsController do
|
||||
expect(response).to redirect_to(settings_preferences_notifications_path)
|
||||
user.reload
|
||||
expect(user.settings['notification_emails.follow']).to be true
|
||||
expect(user.settings['interactions.must_be_follower']).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
6
spec/fabricators/notification_permission_fabricator.rb
Normal file
6
spec/fabricators/notification_permission_fabricator.rb
Normal file
@ -0,0 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:notification_permission) do
|
||||
account
|
||||
from_account { Fabricate.build(:account) }
|
||||
end
|
9
spec/fabricators/notification_policy_fabricator.rb
Normal file
9
spec/fabricators/notification_policy_fabricator.rb
Normal file
@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:notification_policy) do
|
||||
account
|
||||
filter_not_following false
|
||||
filter_not_followers false
|
||||
filter_new_accounts false
|
||||
filter_private_mentions true
|
||||
end
|
8
spec/fabricators/notification_request_fabricator.rb
Normal file
8
spec/fabricators/notification_request_fabricator.rb
Normal file
@ -0,0 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
Fabricator(:notification_request) do
|
||||
account
|
||||
from_account { Fabricate.build(:account) }
|
||||
last_status { Fabricate.build(:status) }
|
||||
dismissed false
|
||||
end
|
25
spec/models/notification_policy_spec.rb
Normal file
25
spec/models/notification_policy_spec.rb
Normal file
@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe NotificationPolicy do
|
||||
describe '#summarize!' do
|
||||
subject { Fabricate(:notification_policy) }
|
||||
|
||||
let(:sender) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
Fabricate.times(2, :notification, account: subject.account, activity: Fabricate(:status, account: sender))
|
||||
Fabricate(:notification_request, account: subject.account, from_account: sender)
|
||||
subject.summarize!
|
||||
end
|
||||
|
||||
it 'sets pending_requests_count' do
|
||||
expect(subject.pending_requests_count).to eq 1
|
||||
end
|
||||
|
||||
it 'sets pending_notifications_count' do
|
||||
expect(subject.pending_notifications_count).to eq 2
|
||||
end
|
||||
end
|
||||
end
|
44
spec/models/notification_request_spec.rb
Normal file
44
spec/models/notification_request_spec.rb
Normal file
@ -0,0 +1,44 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe NotificationRequest do
|
||||
describe '#reconsider_existence!' do
|
||||
subject { Fabricate(:notification_request, dismissed: dismissed) }
|
||||
|
||||
let(:dismissed) { false }
|
||||
|
||||
context 'when there are remaining notifications' do
|
||||
before do
|
||||
Fabricate(:notification, account: subject.account, activity: Fabricate(:status, account: subject.from_account))
|
||||
subject.reconsider_existence!
|
||||
end
|
||||
|
||||
it 'leaves request intact' do
|
||||
expect(subject.destroyed?).to be false
|
||||
end
|
||||
|
||||
it 'updates notifications_count' do
|
||||
expect(subject.notifications_count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no notifications' do
|
||||
before do
|
||||
subject.reconsider_existence!
|
||||
end
|
||||
|
||||
context 'when dismissed' do
|
||||
let(:dismissed) { true }
|
||||
|
||||
it 'leaves request intact' do
|
||||
expect(subject.destroyed?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
it 'removes the request' do
|
||||
expect(subject.destroyed?).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user