tilde.news/app/models/message.rb

140 lines
3.1 KiB
Ruby

# typed: false
class Message < ApplicationRecord
belongs_to :recipient,
class_name: "User",
foreign_key: "recipient_user_id",
inverse_of: :received_messages
belongs_to :author,
class_name: "User",
foreign_key: "author_user_id",
inverse_of: :sent_messages,
optional: true
belongs_to :hat,
optional: true
attribute :mod_note, :boolean
attr_reader :recipient_username
validates :subject, length: {in: 1..100}
validates :body, length: {maximum: (64 * 1024)}
validates :short_id, length: {maximum: 30}
validate :hat do
next if hat.blank?
if author.blank? || author.wearable_hats.exclude?(hat)
errors.add(:hat, "not wearable by author")
end
end
scope :inbox, ->(user) {
where(
recipient: user,
deleted_by_recipient: false
).preload(:author, :hat, :recipient).order("id asc")
}
scope :outbox, ->(user) {
where(
author: user,
deleted_by_author: false
).preload(:author, :hat, :recipient).order("id asc")
}
scope :unread, -> { where(has_been_read: false, deleted_by_recipient: false) }
before_validation :assign_short_id, on: :create
after_create :deliver_email_notifications
after_save :update_unread_counts
after_save :check_for_both_deleted
def as_json(_options = {})
attrs = [
:short_id,
:created_at,
:has_been_read,
:subject,
:body,
:deleted_by_author,
:deleted_by_recipient
]
h = super(only: attrs)
h[:author_username] = author.try(:username)
h[:recipient_username] = recipient.try(:username)
h
end
def assign_short_id
self.short_id = ShortId.new(self.class).generate
end
def author_username
if author
author.username
else
"System"
end
end
def check_for_both_deleted
if deleted_by_author? && deleted_by_recipient?
destroy!
end
end
def update_unread_counts
recipient.update_unread_message_count!
end
def deliver_email_notifications
return if Rails.env.development?
if recipient.email_messages?
begin
EmailMessageMailer.notify(self, recipient).deliver_now
rescue => e
Rails.logger.error "error e-mailing #{recipient.email}: #{e}"
end
end
if recipient.pushover_messages?
recipient.pushover!(
title: "#{Rails.application.name} message from " \
"#{author_username}: #{subject}",
message: plaintext_body,
url: url,
url_title: (author ? "Reply to #{author_username}" :
"View message")
)
end
end
def recipient_username=(username)
self.recipient_user_id = nil
if (u = User.find_by(username: username))
self.recipient_user_id = u.id
@recipient_username = username
else
errors.add(:recipient_username, "is not a valid user")
end
end
def linkified_body
Markdowner.to_html(body)
end
def plaintext_body
# TODO: linkify then strip tags and convert entities back
body.to_s
end
def to_param
short_id
end
def url
Rails.application.root_url + "messages/#{short_id}"
end
end