# frozen_string_literal: true class PostActionNotifier def self.disable @disabled = true end def self.enable @disabled = false end # For testing purposes def self.reset! @custom_post_revision_notifier_recipients = nil end def self.alerter @alerter ||= PostAlerter.new end def self.refresh_like_notification(post, read) return unless post && post.user_id && post.topic usernames = post.post_actions.where(post_action_type_id: PostActionType.types[:like]) .joins(:user) .order('post_actions.created_at desc') .where('post_actions.created_at > ?', 1.day.ago) .pluck(:username) if usernames.length > 0 data = { topic_title: post.topic.title, username: usernames[0], display_username: usernames[0], username2: usernames[1], count: usernames.length } Notification.create( notification_type: Notification.types[:liked], topic_id: post.topic_id, post_number: post.post_number, user_id: post.user_id, read: read, data: data.to_json ) end end def self.post_action_deleted(post_action) return if @disabled # We only care about deleting post actions for now return if post_action.deleted_at.blank? if post_action.post_action_type_id == PostActionType.types[:like] && post_action.post read = true Notification.where( topic_id: post_action.post.topic_id, user_id: post_action.post.user_id, post_number: post_action.post.post_number, notification_type: Notification.types[:liked] ).each do |notification| read = false unless notification.read notification.destroy end refresh_like_notification(post_action.post, read) else # not using destroy_all cause we want stuff to trigger Notification.where(post_action_id: post_action.id).each(&:destroy) end end def self.post_action_created(post_action) return if @disabled # We only notify on likes for now return unless post_action.is_like? post = post_action.post return if post_action.user.blank? || post.blank? alerter.create_notification( post.user, Notification.types[:liked], post, display_username: post_action.user.username, post_action_id: post_action.id, user_id: post_action.user_id ) end def self.after_create_post_revision(post_revision) return if @disabled post = post_revision.post return unless post return if post_revision.user.blank? return if post.topic.blank? return if post.topic.private_message? return if SiteSetting.disable_system_edit_notifications && post_revision.user_id == Discourse::SYSTEM_USER_ID user_ids = [] if post_revision.user_id != post.user_id user_ids << post.user_id end # Notify all users watching the topic when the OP of a wiki topic is edited # or if the topic category allows unlimited owner edits on the OP. if post.is_first_post? && (post.wiki? || post.topic.category_allows_unlimited_owner_edits_on_first_post?) user_ids.concat( TopicUser.watching(post.topic_id) .where.not(user_id: post_revision.user_id) .where(topic: post.topic) .pluck(:user_id) ) end custom_post_revision_notifier_recipients.each do |block| user_ids.concat(Array(block.call(post_revision))) end if user_ids.present? DB.after_commit do Jobs.enqueue(:notify_post_revision, user_ids: user_ids, post_revision_id: post_revision.id ) end end end def self.after_post_unhide(post, flaggers) return if @disabled || post.last_editor.blank? || flaggers.blank? flaggers.each do |flagger| alerter.create_notification( flagger, Notification.types[:edited], post, display_username: post.last_editor.username, acting_user_id: post.last_editor.id ) end end def self.custom_post_revision_notifier_recipients @custom_post_revision_notifier_recipients ||= Set.new end def self.add_post_revision_notifier_recipients(&block) custom_post_revision_notifier_recipients << block end end