diaspora/app/models/conversation.rb

106 lines
2.8 KiB
Ruby

class Conversation < ActiveRecord::Base
include Diaspora::Federated::Base
include Diaspora::Guid
xml_attr :subject
xml_attr :created_at
xml_attr :messages, :as => [Message]
xml_reader :diaspora_handle
xml_reader :participant_handles
has_many :conversation_visibilities, :dependent => :destroy
has_many :participants, :class_name => 'Person', :through => :conversation_visibilities, :source => :person
has_many :messages, -> { order('created_at ASC') }
belongs_to :author, :class_name => 'Person'
validate :max_participants
validate :local_recipients
def max_participants
errors.add(:max_participants, "too many participants") if participants.count > 20
end
def local_recipients
recipients.each do |recipient|
if recipient.local?
unless recipient.owner.contacts.where(person_id: author.id).any? ||
(author.owner && author.owner.podmin_account?)
errors.add(:all_recipients, "recipient not allowed")
end
end
end
end
accepts_nested_attributes_for :messages
def recipients
self.participants - [self.author]
end
def diaspora_handle
self.author.diaspora_handle
end
def diaspora_handle= nh
self.author = Webfinger.new(nh).fetch
end
def first_unread_message(user)
if visibility = self.conversation_visibilities.where(:person_id => user.person.id).where('unread > 0').first
self.messages.to_a[-visibility.unread]
end
end
def set_read(user)
if visibility = self.conversation_visibilities.where(:person_id => user.person.id).first
visibility.unread = 0
visibility.save
end
end
def public?
false
end
def participant_handles
self.participants.map{|p| p.diaspora_handle}.join(";")
end
def participant_handles= handles
handles.split(';').each do |handle|
self.participants << Webfinger.new(handle).fetch
end
end
def last_author
return unless @last_author.present? || messages.size > 0
@last_author_id ||= messages.pluck(:author_id).last
@last_author ||= Person.includes(:profile).where(id: @last_author_id).first
end
def ordered_participants
@ordered_participants ||= (messages.map(&:author).reverse + participants).uniq
end
def subject
self[:subject].blank? ? I18n.t("conversations.new.subject_default") : self[:subject]
end
def subscribers(user)
self.recipients
end
def receive(user, person)
cnv = Conversation.create_with(self.attributes).find_or_create_by!(guid: guid)
self.participants.each do |participant|
ConversationVisibility.find_or_create_by(conversation_id: cnv.id, person_id: participant.id)
end
self.messages.each do |msg|
msg.conversation_id = cnv.id
received_msg = msg.receive(user, person)
Notification.notify(user, received_msg, person) if msg.respond_to?(:notification_type)
end
end
end