Class: Effective::Chat

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/effective/chat.rb

Constant Summary collapse

NOTIFY_AFTER =
2.minutes

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#current_userObject

Returns the value of attribute current_user.



9
10
11
# File 'app/models/effective/chat.rb', line 9

def current_user
  @current_user
end

#user_typeObject

Must be set when creating a chat by admin/new form, and passing user_ids



10
11
12
# File 'app/models/effective/chat.rb', line 10

def user_type
  @user_type
end

Instance Method Details

#build_chat_message(user:, body: nil) ⇒ Object

Always build



96
97
98
99
# File 'app/models/effective/chat.rb', line 96

def build_chat_message(user:, body: nil)
  raise('expected an effective_messaging_user') unless user.class.respond_to?(:effective_messaging_user?)
  chat_messages.build(user: user, body: body)
end

#build_chat_user(user:, anonymous_name: nil) ⇒ Object



89
90
91
92
93
# File 'app/models/effective/chat.rb', line 89

def build_chat_user(user:, anonymous_name: nil)
  cu = chat_user(user: user) || chat_users.build(user: user)
  cu.assign_attributes(anonymous_name: anonymous_name) if anonymous_name.present?
  cu
end

#chat_user(user:) ⇒ Object



84
85
86
87
# File 'app/models/effective/chat.rb', line 84

def chat_user(user:)
  raise('expected an effective_messaging_user') unless user.class.respond_to?(:effective_messaging_user?)
  chat_users.find { |cu| cu.user_id == user.id && cu.user_type == user.class.name }
end

#notify!(except: nil, force: false) ⇒ Object

Called by an after_commit on chat message



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'app/models/effective/chat.rb', line 63

def notify!(except: nil, force: false)
  raise('expected a ChatUser') if except.present? && !except.kind_of?(ChatUser)

  # Notify everyone in the chat except the user that created this message
  notified = (chat_users - [except]).map do |chat_user|

    # Only notify once every 5 minutes unless force
    if chat_user.last_notified_at.present? && !force
      next if (Time.zone.now - chat_user.last_notified_at) < NOTIFY_AFTER
    end

    EffectiveMessaging.send_email(:chat_new_message, self, chat_user)
    chat_user
  end

  ChatUser.where(id: notified).update_all(last_notified_at: Time.zone.now) if notified.present?

  # updated_at is when last message was sent
  touch
end

#send_message!(user:, body:) ⇒ Object

This is an API for sending a message.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'app/models/effective/chat.rb', line 47

def send_message!(user:, body:)
  raise('expected an effective_messaging_user') unless user.class.respond_to?(:effective_messaging_user?)

  chat_user = chat_user(user: user)
  raise('expected user to be a chat_user in this chat') unless chat_user.present?

  # Build and send message
  chat_message = chat_messages.build(body: body, user: user, chat_user: chat_user, name: chat_user.name)

  # Creates message, which also calls notify! below
  save!

  chat_message
end

#to_sObject



42
43
44
# File 'app/models/effective/chat.rb', line 42

def to_s
  title.presence || 'New Chat'
end

#user_idsObject



106
107
108
# File 'app/models/effective/chat.rb', line 106

def user_ids
  chat_users.map(&:user_id)
end

#user_ids=(user_ids) ⇒ Object



110
111
112
113
114
115
116
117
118
# File 'app/models/effective/chat.rb', line 110

def user_ids=(user_ids)
  raise('expected a user_type') unless user_type.present?

  # The users in this chat
  self.users = user_type.constantize.where(id: user_ids)

  # Return user_ids
  user_ids
end

#usersObject

Builders for polymorphic users form



102
103
104
# File 'app/models/effective/chat.rb', line 102

def users
  chat_users.map(&:user)
end

#users=(users) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'app/models/effective/chat.rb', line 120

def users=(users)
  users = Array(users)
  raise('expected a effective_messaging_user') unless users.all? { |user| user.class.respond_to?(:effective_messaging_user?) }

  # Mark for destruction
  chat_users.each { |cu| cu.mark_for_destruction unless users.include?(cu.user) }

  # Find or build chat_users
  users.each { |user| build_chat_user(user: user) }

  # Return users
  users
end