From 4eb17c5a5fde6fc26be87579d2bf5b50e660063b Mon Sep 17 00:00:00 2001 From: Pablo Brasero Date: Mon, 20 Apr 2026 15:26:48 +0100 Subject: [PATCH] Skeleton to implement each type of web notification --- .rubocop_todo.yml | 2 +- app/controllers/notifications_controller.rb | 4 ++ app/models/user.rb | 2 + app/models/user_notifications.rb | 52 +++++++++++++++++++++ app/views/notifications/index.html.erb | 11 ++++- test/factories/notifications.rb | 31 ++++++++++++ 6 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 app/models/user_notifications.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f7565912e..892e927c0 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -56,7 +56,7 @@ Metrics/BlockNesting: # Offense count: 23 # Configuration parameters: CountComments, CountAsOne. Metrics/ClassLength: - Max: 342 + Max: 343 # Offense count: 72 # Configuration parameters: AllowedMethods, AllowedPatterns. diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index a6a6fd4a7..602841383 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -9,4 +9,8 @@ class NotificationsController < ApplicationController authorize_resource :class => false before_action :check_database_readable + + def index + @notifications = UserNotifications.new(current_user) + end end diff --git a/app/models/user.rb b/app/models/user.rb index ceee49b55..15f7f9fa6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -91,6 +91,8 @@ class User < ApplicationRecord has_many :reports + has_many :notifications, :as => :recipient, :class_name => "Noticed::Notification" + has_many :social_links accepts_nested_attributes_for :social_links, :allow_destroy => true diff --git a/app/models/user_notifications.rb b/app/models/user_notifications.rb new file mode 100644 index 000000000..b1ef8881e --- /dev/null +++ b/app/models/user_notifications.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +class UserNotifications + class Notification + def self.from(notification) + event_type_name = event_type_name_of(notification) + klass = "UserNotifications::#{event_type_name}Notification".constantize + klass.new(notification) + end + + # Takes "ChangesetCommentNotifier::Notification", returns "ChangesetComment" + def self.event_type_name_of(notification) + notification.class.name.sub("Notifier::Notification", "") + end + + def initialize(notification) + @notification = notification + end + + delegate :record, :to => :@notification + + def to_partial_path + event_type_name = self.class.event_type_name_of(@notification) + "notifications/#{event_type_name.underscore}" + end + + def timestamp + record.created_at + end + end + + include Enumerable + + LISTABLE_NOTIFICATIONS = [].freeze + + def initialize(user) + @user = user + end + + def each(&) + @user + .notifications + .where(:type => LISTABLE_NOTIFICATIONS) + .newest_first + .map { |instance| Notification.from(instance) } + .each(&) + end + + def empty? + none? + end +end diff --git a/app/views/notifications/index.html.erb b/app/views/notifications/index.html.erb index 7de863324..1240a1b62 100644 --- a/app/views/notifications/index.html.erb +++ b/app/views/notifications/index.html.erb @@ -8,4 +8,13 @@

<% end %> -

<%= t(".no_notifications") %>

+<% if @notifications.empty? %> +

<%= t(".no_notifications") %>

+<% else %> +
+ <% @notifications.each do |notification| %> + <%= render :partial => notification.to_partial_path, :object => notification, :as => :notification %> +
+ <% end %> +
+<% end %> diff --git a/test/factories/notifications.rb b/test/factories/notifications.rb index cb582fccb..aa1d4d343 100644 --- a/test/factories/notifications.rb +++ b/test/factories/notifications.rb @@ -1,6 +1,37 @@ # frozen_string_literal: true FactoryBot.define do + factory :notification, :class => "ApplicationNotifier::Notification" do + initialize_with do + notifier_class = self.notifier_class || "#{record.class.name}Notifier".constantize + notification_class = notifier_class::Notification + notification_class.new + end + + recipient :factory => :user + + event do + association :notifier, :record => record, :notifier_class => notifier_class, :params => notifier_params + end + + transient do + record { nil } + notifier_class { nil } + notifier_params { nil } + end + end + + factory :notifier, :class => "ApplicationNotifier" do + initialize_with do + notifier_class = self.notifier_class || "#{record.class.name}Notifier".constantize + notifier_class.new(:record => record) + end + + transient do + notifier_class { nil } + end + end + factory :changeset_comment_notification, :class => "ChangesetCommentNotifier::Notification" do event :factory => :changeset_comment_notifier recipient :factory => :user -- 2.47.3