1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-11-28 09:24:24 +01:00

(feat) backend for notifications preference system

This commit is contained in:
Karen 2023-01-27 16:21:16 +01:00 committed by Sylvain
parent 54dbd5ef4d
commit 9b69aad9df
8 changed files with 58 additions and 7 deletions

View File

@ -15,14 +15,16 @@ class API::NotificationsController < API::ApiController
def index
loop do
@notifications = current_user.notifications
.delivered_in_system(current_user)
.includes(:attached_object)
.page(params[:page])
.per(NOTIFICATIONS_PER_PAGE).order('created_at DESC')
.per(NOTIFICATIONS_PER_PAGE)
.order('created_at DESC')
# we delete obsolete notifications on first access
break unless delete_obsoletes(@notifications)
end
@totals = {
total: current_user.notifications.count,
total: current_user.notifications.delivered_in_system(current_user).count,
unread: current_user.notifications.where(is_read: false).count
}
render :index
@ -39,7 +41,7 @@ class API::NotificationsController < API::ApiController
break unless delete_obsoletes(@notifications)
end
@totals = {
total: current_user.notifications.count,
total: current_user.notifications.delivered_in_system(current_user).count,
unread: current_user.notifications.where(is_read: false).count
}
render :index
@ -50,7 +52,7 @@ class API::NotificationsController < API::ApiController
.where('is_read = false AND created_at >= :date', date: params[:last_poll])
.order('created_at DESC')
@totals = {
total: current_user.notifications.count,
total: current_user.notifications.delivered_in_system(current_user).count,
unread: current_user.notifications.where(is_read: false).count
}
render :index

View File

@ -6,6 +6,17 @@ class Notification < ApplicationRecord
belongs_to :receiver, polymorphic: true
belongs_to :attached_object, polymorphic: true
# This scope filter a user's in system (push) notifications :
# It fetch his notifications where no notification preference is made,
# or if this preference specify that the user accepts in system notification
scope :delivered_in_system, lambda { |user|
left_outer_joins(notification_type: :notification_preferences)
.where(<<-SQL.squish, user.id)
(notification_preferences.user_id = ? AND notification_preferences.in_system IS TRUE)
OR notification_preferences.id IS NULL
SQL
}
validates :receiver_id,
:receiver_type,
:attached_object_id,
@ -33,6 +44,16 @@ class Notification < ApplicationRecord
NotificationsMailer.send_mail_by(self).deliver_later if save
end
def deliver_with_preferences(user, notification_type)
preference = NotificationPreference.find_by(notification_type: notification_type, user: user)
# Set as read if user do not want push notifications
self.is_read = true if preference && preference.in_system == false
# Save notification if user do not want email notifications ; else, deliver.
preference && preference.email == false ? save : deliver_later
end
def get_meta_data(key)
meta_data.try(:[], key.to_s)
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
# Allow user to set their preferences for notifications (push and email)
class NotificationPreference < ApplicationRecord
belongs_to :user
belongs_to :notification_type
end

View File

@ -3,5 +3,7 @@
# NotificationType defines the different types of Notification.
class NotificationType < ApplicationRecord
has_many :notifications, dependent: :destroy
has_many :notification_preferences, dependent: :destroy
validates :name, uniqueness: true, presence: true
end

View File

@ -51,6 +51,7 @@ class User < ApplicationRecord
has_many :proof_of_identity_refusals, dependent: :destroy
has_many :notifications, as: :receiver, dependent: :destroy
has_many :notification_preferences, dependent: :destroy
# fix for create admin user
before_save do

View File

@ -4,14 +4,16 @@
class NotificationCenter
def self.call(type: nil, receiver: nil, attached_object: nil, meta_data: {})
receiver = [receiver] unless receiver.respond_to?(:each)
notification_type = NotificationType.find_by(name: type)
receiver.each do |user|
Notification.new(
meta_data: meta_data,
attached_object: attached_object,
receiver: user,
notification_type: NotificationType.find_by(name: type)
notification_type: notification_type
)
.deliver_later
.deliver_with_preferences(user, notification_type)
end
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
# Create notification preferences : allow user to decide which type of notifications
# they want to receive via push ('in system') or via email.
class CreateNotificationPreferences < ActiveRecord::Migration[5.2]
def change
create_table :notification_preferences do |t|
t.references :user, index: true, foreign_key: true, null: false
t.references :notification_type, index: true, foreign_key: true, null: false
t.boolean :in_system, default: true
t.boolean :email, default: true
t.timestamps
end
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2023_01_26_160900) do
ActiveRecord::Schema.define(version: 2023_01_27_100506) do
# These are extensions that must be enabled in order to support this database
enable_extension "fuzzystrmatch"