96 lines
2.3 KiB
Ruby
96 lines
2.3 KiB
Ruby
class Notification < ActiveRecord::Base
|
|
|
|
belongs_to :user
|
|
belongs_to :topic
|
|
|
|
validates_presence_of :data
|
|
validates_presence_of :notification_type
|
|
|
|
def self.Types
|
|
{:mentioned => 1,
|
|
:replied => 2,
|
|
:quoted => 3,
|
|
:edited => 4,
|
|
:liked => 5,
|
|
:private_message => 6,
|
|
:invited_to_private_message => 7,
|
|
:invitee_accepted => 8,
|
|
:posted => 9,
|
|
:moved_post => 10}
|
|
end
|
|
|
|
def self.InvertedTypes
|
|
@inverted_types ||= Notification.Types.invert
|
|
end
|
|
|
|
def self.unread
|
|
where(read: false)
|
|
end
|
|
|
|
def self.mark_post_read(user, topic_id, post_number)
|
|
Notification.update_all "read = true", ["user_id = ? and topic_id = ? and post_number = ?", user.id, topic_id, post_number]
|
|
end
|
|
|
|
def self.recent
|
|
order('created_at desc').limit(10)
|
|
end
|
|
|
|
def self.interesting_after(min_date)
|
|
result = where("created_at > ?", min_date)
|
|
.includes(:topic)
|
|
.unread
|
|
.limit(20)
|
|
.order("CASE WHEN notification_type = #{Notification.Types[:replied]} THEN 1
|
|
WHEN notification_type = #{Notification.Types[:mentioned]} THEN 2
|
|
ELSE 3
|
|
END, created_at DESC").to_a
|
|
|
|
# Remove any duplicates by type and topic
|
|
if result.present?
|
|
seen = {}
|
|
to_remove = Set.new
|
|
|
|
result.each do |r|
|
|
seen[r.notification_type] ||= Set.new
|
|
if seen[r.notification_type].include?(r.topic_id)
|
|
to_remove << r.id
|
|
else
|
|
seen[r.notification_type] << r.topic_id
|
|
end
|
|
end
|
|
result.reject! {|r| to_remove.include?(r.id) }
|
|
end
|
|
|
|
result
|
|
end
|
|
|
|
# Be wary of calling this frequently. O(n) JSON parsing can suck.
|
|
def data_hash
|
|
@data_hash ||= begin
|
|
return nil if data.blank?
|
|
::JSON.parse(data).with_indifferent_access
|
|
end
|
|
end
|
|
|
|
def text_description
|
|
link = block_given? ? yield : ""
|
|
I18n.t("notification_types.#{Notification.InvertedTypes[notification_type]}", data_hash.merge(link: link))
|
|
end
|
|
|
|
def url
|
|
if topic.present?
|
|
return topic.relative_url(post_number)
|
|
end
|
|
nil
|
|
end
|
|
|
|
def post
|
|
return nil unless topic_id.present?
|
|
return nil unless post_number.present?
|
|
|
|
Post.where(topic_id: topic_id, post_number: post_number).first
|
|
end
|
|
|
|
end
|
|
|