```shell ❯ rg "@notifications_index" ``` The above shell command exits status code 1, which means there are no results found. This relates to exploratory work for forem/forem#16821
96 lines
3.5 KiB
Ruby
96 lines
3.5 KiB
Ruby
class NotificationsController < ApplicationController
|
|
# rubocop:disable Metrics/CyclomaticComplexity
|
|
# rubocop:disable Metrics/PerceivedComplexity
|
|
# No authorization required because we provide authentication on notifications page
|
|
def index
|
|
return unless user_signed_in?
|
|
|
|
@user = user_to_view
|
|
|
|
@initial_page_size = 8
|
|
|
|
# NOTE: this controller is using offset based pagination by assuming that
|
|
# the id of the last notification also corresponds to the newest `notified_at`
|
|
# this might not be forever true but it's good enough for now
|
|
if params[:offset]
|
|
num = 30
|
|
notified_at_offset = Notification.find(params[:offset])&.notified_at
|
|
else
|
|
num = @initial_page_size
|
|
end
|
|
|
|
@notifications = if (params[:org_id].present? || params[:filter] == "org") && allowed_user?
|
|
organization_notifications
|
|
elsif params[:org_id].blank? && params[:filter].present?
|
|
filtered_notifications
|
|
else
|
|
@user.notifications
|
|
end
|
|
|
|
@notifications = @notifications.order(notified_at: :desc)
|
|
|
|
# if offset based pagination is invoked by the frontend code, we filter out all earlier ones
|
|
@notifications = @notifications.where("notified_at < ?", notified_at_offset) if notified_at_offset
|
|
|
|
@notifications = @notifications.limit(num)
|
|
|
|
@notifications = NotificationDecorator.decorate_collection(@notifications)
|
|
|
|
@last_user_reaction = @user.reactions.last&.id
|
|
@last_user_comment = @user.comments.last&.id
|
|
|
|
@organizations = @user.member_organizations if @user.organizations
|
|
@selected_organization = Organization.find(params[:org_id]) if params[:org_id].present?
|
|
|
|
# The first call, the one coming from the browser URL bar will render the "index" view, which renders
|
|
# the first few notifications. After that the JS frontend code (see `initNotification.js`)
|
|
# will call this action again by sending the offset id for the last known notifications, the result
|
|
# will be the partial rendering of only the list of notifications that will be attached to the DOM by JS
|
|
if notified_at_offset
|
|
render partial: "notifications_list"
|
|
else
|
|
# [@jeremyf] I added an explicit render. Before adding the explicit render, we relied on the
|
|
# implicit render cycle of Rails. Which is fine, but it's very disarming to read `render
|
|
# partial: "notifications_list" if notified_at_offset` as the last line of the method.
|
|
#
|
|
# My hope is that this explicit render removes at least one future head scratch.
|
|
render "index"
|
|
end
|
|
end
|
|
# rubocop:enable Metrics/CyclomaticComplexity
|
|
# rubocop:enable Metrics/PerceivedComplexity
|
|
|
|
private
|
|
|
|
def user_to_view
|
|
if params[:username] && current_user.super_admin?
|
|
User.find_by(username: params[:username])
|
|
else
|
|
current_user
|
|
end
|
|
end
|
|
|
|
def filtered_notifications
|
|
if params[:filter].to_s.casecmp("posts").zero?
|
|
@user.notifications.for_published_articles
|
|
elsif params[:filter].to_s.casecmp("comments").zero?
|
|
@user.notifications.for_comments.or(@user.notifications.for_mentions)
|
|
else
|
|
@user.notifications
|
|
end
|
|
end
|
|
|
|
def organization_notifications
|
|
org_id = params[:org_id]
|
|
|
|
if params[:filter].to_s.casecmp("comments").zero?
|
|
Notification.for_organization_comments(org_id).or(Notification.for_organization_mentions(org_id))
|
|
else
|
|
Notification.for_organization(org_id)
|
|
end
|
|
end
|
|
|
|
def allowed_user?
|
|
@user.org_member?(params[:org_id]) || @user.super_admin?
|
|
end
|
|
end
|