106 lines
2.9 KiB
Ruby
106 lines
2.9 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 = Person.find_or_fetch_by_identifier(nh)
|
|
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|
|
|
participants << Person.find_or_fetch_by_identifier(handle)
|
|
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
|