conversation.rb 2.83 KB
Newer Older
1
class Conversation < ActiveRecord::Base
2
  include Diaspora::Federated::Base
3 4 5 6
  include Diaspora::Guid

  xml_attr :subject
  xml_attr :created_at
7 8
  xml_attr :messages, :as => [Message]
  xml_reader :diaspora_handle
9 10
  xml_reader :participant_handles

11
  has_many :conversation_visibilities, :dependent => :destroy
12
  has_many :participants, :class_name => 'Person', :through => :conversation_visibilities, :source => :person
13
  has_many :messages, -> { order('created_at ASC') }
14

15 16
  belongs_to :author, :class_name => 'Person'

17
  validate :max_participants
18
  validate :local_recipients
19 20 21 22

  def max_participants
    errors.add(:max_participants, "too many participants") if participants.count > 20
  end
23

24 25 26
  def local_recipients
    recipients.each do |recipient|
      if recipient.local?
27 28
        unless recipient.owner.contacts.where(person_id: author.id).any? ||
            (author.owner && author.owner.podmin_account?)
29 30 31 32 33
          errors.add(:all_recipients, "recipient not allowed")
        end
      end
    end
  end
34

35
  accepts_nested_attributes_for :messages
danielvincent's avatar
danielvincent committed
36

37 38 39 40
  def recipients
    self.participants - [self.author]
  end

41 42 43
  def diaspora_handle
    self.author.diaspora_handle
  end
44

45 46 47
  def diaspora_handle= nh
    self.author = Webfinger.new(nh).fetch
  end
48

49 50
  def first_unread_message(user)
    if visibility = self.conversation_visibilities.where(:person_id => user.person.id).where('unread > 0').first
Jonne Haß's avatar
Jonne Haß committed
51
      self.messages.to_a[-visibility.unread]
52 53
    end
  end
54

55 56 57 58 59 60 61
  def set_read(user)
    if visibility = self.conversation_visibilities.where(:person_id => user.person.id).first
      visibility.unread = 0
      visibility.save
    end
  end

62 63 64 65
  def public?
    false
  end

66 67 68
  def participant_handles
    self.participants.map{|p| p.diaspora_handle}.join(";")
  end
zhitomirskiyi's avatar
zhitomirskiyi committed
69 70 71 72 73
  def participant_handles= handles
    handles.split(';').each do |handle|
      self.participants << Webfinger.new(handle).fetch
    end
  end
danielvincent's avatar
danielvincent committed
74

75
  def last_author
76 77
    return unless @last_author.present? || messages.size > 0
    @last_author_id ||= messages.pluck(:author_id).last
78
    @last_author ||= Person.includes(:profile).where(id: @last_author_id).first
79 80
  end

81 82 83 84
  def ordered_participants
    @ordered_participants ||= (messages.map(&:author).reverse + participants).uniq
  end

85
  def subject
86
    self[:subject].blank? ? I18n.t("conversations.new.subject_default") : self[:subject]
87 88
  end

zhitomirskiyi's avatar
zhitomirskiyi committed
89 90 91
  def subscribers(user)
    self.recipients
  end
danielvincent's avatar
danielvincent committed
92

zhitomirskiyi's avatar
zhitomirskiyi committed
93
  def receive(user, person)
94
    cnv = Conversation.create_with(self.attributes).find_or_create_by!(guid: guid)
95 96

    self.participants.each do |participant|
97
      ConversationVisibility.find_or_create_by(conversation_id: cnv.id, person_id: participant.id)
98
    end
99

zhitomirskiyi's avatar
zhitomirskiyi committed
100 101
    self.messages.each do |msg|
      msg.conversation_id = cnv.id
102 103
      received_msg = msg.receive(user, person)
      Notification.notify(user, received_msg, person) if msg.respond_to?(:notification_type)
zhitomirskiyi's avatar
zhitomirskiyi committed
104 105
    end
  end
106
end