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)
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 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
# 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
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
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
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
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
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
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
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
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
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
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
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