class ChatConversation

Schema Information

Table name: chat_conversations

id             :integer          not null, primary key
grouped        :boolean          default(TRUE)
messages_count :integer          default(0)
created_at     :datetime
updated_at     :datetime
university_id     :integer
resource_id    :integer
resource_type  :string(255)

Public Class Methods

create_for_members!(user_ids) click to toggle source

To create new chat conversation for the users.

# File app/models/chat_conversation.rb, line 142
def self.create_for_members!(user_ids)
  conversation = find_conversation(user_ids)
  return conversation if conversation
  conversation = ChatConversation.new(grouped: user_ids.size > 2, resource: User.current)
  conversation.add_members!(user_ids)
end
find_conversation(user_ids) click to toggle source

Find the conversations

# File app/models/chat_conversation.rb, line 171
def self.find_conversation(user_ids)
  conversations = self.joins(:chat_members).where("chat_members.user_id IN (?)", user_ids)
  conversations = conversations.where(grouped: (user_ids.size > 2 ? true : false))
  conversations.group("chat_conversation_id having count(*) = #{user_ids.size}").first
end
find_or_create_conversation_for(user, other_user_ids = [], conversation_id = nil) click to toggle source

Find or create conversation

# File app/models/chat_conversation.rb, line 150
def self.find_or_create_conversation_for(user, other_user_ids = [], conversation_id = nil)
  if conversation_id
    conversation = user.chat_conversations.find(conversation_id)
    if conversation.grouped?
      return conversation if other_user_ids.blank?
      return conversation.add_members!(other_user_ids)
    else
      user_ids = other_user_ids.push(conversation.active_members.map(&:user_id))
      return create_for_members!(user_ids.flatten.uniq)
    end
  else
    user_ids = (other_user_ids | [user.id]).map(&:to_i).uniq
    if user_ids.size > 1
      conversation = find_conversation(user_ids)
      return conversation if conversation
      return create_for_members!(user_ids)
    end
  end
end

Public Instance Methods

add_members!(user_ids) click to toggle source

To add members to chat conversation.

# File app/models/chat_conversation.rb, line 69
def add_members!(user_ids)
  user_ids.each do |user_id|
    self.active_members.build(user_id: user_id) unless self.active_members.exists?(user_id: user_id)
  end
  self.save(validate: false)
  return self
end
chat_data_for(user, remote = false) click to toggle source

Returns chat converstion

# File app/models/chat_conversation.rb, line 78
def chat_data_for(user, remote = false)
  users = members.except_user(user)
  data = {
    conversation_id: self.id,
    grouped: self.grouped,
    image: self.image(user, remote)
  }
  if self.grouped?
    data.merge!(label: self.label(user))
  else
    data.merge!(label: self.label(user), user_id: users.first.id)
    data.merge!(booking_url: Rails.application.routes.url_helpers.personal_calendar_path(user_id: users.first.id)) if users.first.tutor?
  end
  data
end
image(user, remote = false) click to toggle source

Return image url of other user

# File app/models/chat_conversation.rb, line 113
def image(user, remote = false)
  users = members.except_user(user)
  path = if self.grouped?
    'groups/thumb.png'
  else
    users.first.image_url(:thumb)
  end
  remote ? ActionController::Base.helpers.image_path(path) : path
end
init_chat_for(user) click to toggle source

It intialize chat for user(i.e. load previous chat data and assign private channel to chat).

# File app/models/chat_conversation.rb, line 124
def init_chat_for(user)
  ActsAsTenant.current_tenant.pusher_configuration.client.trigger_async("private-user-#{user.id}", 'init-chat', chat_data_for(user, true).to_json)
end
label(user) click to toggle source

Returns group name if resource type is group else return users name and also retunrs count of users if more than one user is present in chat conversation else return user's full name.

# File app/models/chat_conversation.rb, line 95
def label(user)
  users = members.except_user(user)
  if self.grouped?
    if self.resource_type == 'Group'
      "Group: #{resource.name}"
    else
      if users.count > 2
        "#{users.first.name} and #{users.count - 1} others"
      else
        users.map(&:name).join(' and ')
      end
    end
  else
    users.first.full_name
  end
end
members(type: :active) click to toggle source

Returns the active members of group if resource type is group else returns all active users.

# File app/models/chat_conversation.rb, line 43
def members(type: :active)
  if resource_type == 'Group'
    resource.users
  else
    active_users
  end
end
read?(user) click to toggle source

Set unread messages count to 0 if messages are seen by user.

# File app/models/chat_conversation.rb, line 57
def read?(user)
  unread_messages_count(user) == 0
end
reply(message, attachment = nil) click to toggle source

To reply the chat message.

# File app/models/chat_conversation.rb, line 136
def reply(message, attachment = nil)
  message = nil if attachment
  self.messages.create!(message: message, attachment_attributes: {attachment: attachment})
end
reset_unread_messages_count!(user) click to toggle source

To reset unread messages count..

# File app/models/chat_conversation.rb, line 62
def reset_unread_messages_count!(user)
  unread_receipts.where(user: user).update_all(read: true)
  message_count = user.cached_message_count - 1
  user.update_columns(cached_message_count: message_count > 0 ? message_count : 0 )
end
trigger_typing_event_except(current_user, typing) click to toggle source

To display “typing” if other user is typing the chat.

# File app/models/chat_conversation.rb, line 129
def trigger_typing_event_except(current_user, typing)
  members.except_user(current_user).each do |user|
    ActsAsTenant.current_tenant.pusher_configuration.client.trigger_async("private-user-#{user.id}", 'typing-event', {conversation_id: self.id, from{{id: current_user.id, image: current_user.image_url(:thumb), name: current_user.full_name}, typing: typing})
  end
end
unread_messages_count(user) click to toggle source

Returns the count of unread messages.

# File app/models/chat_conversation.rb, line 52
def unread_messages_count(user)
  receipts.where(user: user, read: false).count
end