diff --git a/app/assets/javascripts/app/controllers/chat.coffee b/app/assets/javascripts/app/controllers/chat.coffee
index 772ce86cf..20ddf59bb 100644
--- a/app/assets/javascripts/app/controllers/chat.coffee
+++ b/app/assets/javascripts/app/controllers/chat.coffee
@@ -36,7 +36,6 @@ class App.CustomerChat extends App.Controller
@bind(
'chat_session_start'
(data) =>
- App.WebSocket.send(event:'chat_status_agent')
if data.session
@addChat(data.session)
)
@@ -45,7 +44,6 @@ class App.CustomerChat extends App.Controller
->
App.WebSocket.send(event:'chat_status_agent')
)
-
App.WebSocket.send(event:'chat_status_agent')
pushState: =>
@@ -101,7 +99,7 @@ class App.CustomerChat extends App.Controller
@delay(delay, 200, 'updateNavMenu')
updateMeta: =>
- if @meta.waiting_chat_count && @maxChats > @currentChatCount()
+ if @meta.waiting_chat_count && @maxChats > @windowCount()
@$('.js-acceptChat').addClass('is-clickable is-blinking')
else
@$('.js-acceptChat').removeClass('is-clickable is-blinking')
@@ -134,11 +132,9 @@ class App.CustomerChat extends App.Controller
windowCount: =>
count = 0
-
for chat of @chatWindows
- count++
-
- return count
+ count++
+ count
removeChat: (session_id) =>
delete @chatWindows[session_id]
@@ -149,15 +145,8 @@ class App.CustomerChat extends App.Controller
for session_id, chat of @chatWindows
chat.trigger 'layout-changed'
- currentChatCount: =>
- currentChats = 0
- for key, value of @chatWindows
- if @chatWindows[key]
- currentChats += 1
- currentChats
-
acceptChat: =>
- return if @currentChatCount() >= @maxChats
+ return if @windowCount() >= @maxChats
App.WebSocket.send(event:'chat_session_start')
class CustomerChatRouter extends App.ControllerPermanent
diff --git a/app/models/chat.rb b/app/models/chat.rb
index d730e2927..bd1a4a64a 100644
--- a/app/models/chat.rb
+++ b/app/models/chat.rb
@@ -10,43 +10,56 @@ class Chat < ApplicationModel
# reconnect
if session_id
chat_session = Chat::Session.find_by(session_id: session_id, state: %w(waiting running))
- user = nil
- if chat_session && chat_session.user_id
- chat_user = User.find(chat_session.user_id)
- url = nil
- if chat_user.image && chat_user.image != 'none'
- url = "/api/v1/users/image/#{chat_user.image}"
- end
- user = {
- name: chat_user.fullname,
- avatar: url,
- }
- end
if chat_session
- session = Chat.session_state(session_id)
- if session && !session.empty?
+ if chat_session.state == 'running'
+ user = nil
+ if chat_session.user_id
+ chat_user = User.find(chat_session.user_id)
+ url = nil
+ if chat_user.image && chat_user.image != 'none'
+ url = "/api/v1/users/image/#{chat_user.image}"
+ end
+ user = {
+ name: chat_user.fullname,
+ avatar: url,
+ }
+
+ # get queue postion if needed
+ session = Chat.session_state(session_id)
+ if session
+ return {
+ state: 'reconnect',
+ session: session,
+ agent: user,
+ }
+ end
+ end
+ elsif chat_session.state == 'waiting'
return {
state: 'reconnect',
- session: session,
- agent: user,
+ position: chat_session.position,
}
end
end
end
- if Chat::Agent.where(active: true).where('updated_at > ?', Time.zone.now - 2.minutes).count > 0
- if active_chat_count >= max_queue
- return {
- state: 'no_seats_available',
- queue: seads_available,
- }
- else
- return { state: 'online' }
- end
+ # check if agents are available
+ available_agents = Chat::Agent.where(active: true).where('updated_at > ?', Time.zone.now - 2.minutes).count
+ if available_agents == 0
+ return { state: 'offline' }
end
- { state: 'offline' }
+ # if all seads are used
+ if active_chat_count >= max_queue
+ return {
+ state: 'no_seats_available',
+ queue: seads_available,
+ }
+ end
+
+ # seads are available
+ { state: 'online' }
end
def self.session_state(session_id)
@@ -111,81 +124,3 @@ class Chat < ApplicationModel
seads_total(diff) - active_chat_count
end
end
-
-class Chat::Topic < ApplicationModel
-end
-
-class Chat::Agent < ApplicationModel
-
- def seads_available
- concurrent - active_chat_count
- end
-
- def active_chat_count
- Chat::Session.where(state: %w(waiting running), user_id: updated_by_id).count
- end
-
- def self.state(user_id, state = nil)
- chat_agent = Chat::Agent.find_by(
- updated_by_id: user_id
- )
- if state.nil?
- return false if !chat_agent
- return chat_agent.active
- end
- if chat_agent
- chat_agent.active = state
- chat_agent.updated_at = Time.zone.now
- chat_agent.save
- else
- Chat::Agent.create(
- active: state,
- updated_by_id: user_id,
- created_by_id: user_id,
- )
- end
- end
-
- def self.create_or_update(params)
- chat_agent = Chat::Agent.find_by(
- updated_by_id: params[:updated_by_id]
- )
- if chat_agent
- chat_agent.update_attributes(params)
- else
- Chat::Agent.create(params)
- end
- end
-end
-
-class Chat::Session < ApplicationModel
- before_create :generate_session_id
- store :preferences
-
- def generate_session_id
- self.session_id = Digest::MD5.hexdigest(Time.zone.now.to_s + rand(99_999_999_999_999).to_s)
- end
-
- def add_recipient(client_id, store = false)
- if !preferences[:participants]
- preferences[:participants] = []
- end
- return preferences[:participants] if preferences[:participants].include?(client_id)
- preferences[:participants].push client_id
- if store
- save
- end
- preferences[:participants]
- end
-
- def send_to_recipients(message, ignore_client_id = nil)
- preferences[:participants].each {|local_client_id|
- next if local_client_id == ignore_client_id
- Sessions.send(local_client_id, message)
- }
- true
- end
-end
-
-class Chat::Message < ApplicationModel
-end
diff --git a/app/models/chat/agent.rb b/app/models/chat/agent.rb
new file mode 100644
index 000000000..fe3002bcb
--- /dev/null
+++ b/app/models/chat/agent.rb
@@ -0,0 +1,42 @@
+class Chat::Agent < ApplicationModel
+
+ def seads_available
+ concurrent - active_chat_count
+ end
+
+ def active_chat_count
+ Chat::Session.where(state: %w(waiting running), user_id: updated_by_id).count
+ end
+
+ def self.state(user_id, state = nil)
+ chat_agent = Chat::Agent.find_by(
+ updated_by_id: user_id
+ )
+ if state.nil?
+ return false if !chat_agent
+ return chat_agent.active
+ end
+ if chat_agent
+ chat_agent.active = state
+ chat_agent.updated_at = Time.zone.now
+ chat_agent.save
+ else
+ Chat::Agent.create(
+ active: state,
+ updated_by_id: user_id,
+ created_by_id: user_id,
+ )
+ end
+ end
+
+ def self.create_or_update(params)
+ chat_agent = Chat::Agent.find_by(
+ updated_by_id: params[:updated_by_id]
+ )
+ if chat_agent
+ chat_agent.update_attributes(params)
+ else
+ Chat::Agent.create(params)
+ end
+ end
+end
diff --git a/app/models/chat/message.rb b/app/models/chat/message.rb
new file mode 100644
index 000000000..5076f0951
--- /dev/null
+++ b/app/models/chat/message.rb
@@ -0,0 +1,2 @@
+class Chat::Message < ApplicationModel
+end
diff --git a/app/models/chat/session.rb b/app/models/chat/session.rb
new file mode 100644
index 000000000..4932fc1e1
--- /dev/null
+++ b/app/models/chat/session.rb
@@ -0,0 +1,38 @@
+class Chat::Session < ApplicationModel
+ before_create :generate_session_id
+ store :preferences
+
+ def generate_session_id
+ self.session_id = Digest::MD5.hexdigest(Time.zone.now.to_s + rand(99_999_999_999_999).to_s)
+ end
+
+ def add_recipient(client_id, store = false)
+ if !preferences[:participants]
+ preferences[:participants] = []
+ end
+ return preferences[:participants] if preferences[:participants].include?(client_id)
+ preferences[:participants].push client_id
+ if store
+ save
+ end
+ preferences[:participants]
+ end
+
+ def send_to_recipients(message, ignore_client_id = nil)
+ preferences[:participants].each {|local_client_id|
+ next if local_client_id == ignore_client_id
+ Sessions.send(local_client_id, message)
+ }
+ true
+ end
+
+ def position
+ return if state != 'waiting'
+ position = 0
+ Chat::Session.where(state: 'waiting').order('created_at ASC').each {|chat_session|
+ position += 1
+ break if chat_session.id == id
+ }
+ position
+ end
+end
diff --git a/app/models/chat/topic.rb b/app/models/chat/topic.rb
new file mode 100644
index 000000000..413576f67
--- /dev/null
+++ b/app/models/chat/topic.rb
@@ -0,0 +1,2 @@
+class Chat::Topic < ApplicationModel
+end
diff --git a/lib/sessions/event/chat_session_init.rb b/lib/sessions/event/chat_session_init.rb
index 6efb8d64a..853173fbb 100644
--- a/lib/sessions/event/chat_session_init.rb
+++ b/lib/sessions/event/chat_session_init.rb
@@ -24,13 +24,7 @@ class Sessions::Event::ChatSessionInit < Sessions::Event::ChatBase
)
# send broadcast to agents
- Chat::Agent.where(active: true).each {|item|
- data = {
- event: 'chat_status_agent',
- data: Chat.agent_state(item.updated_by_id),
- }
- Sessions.send_to(item.updated_by_id, data)
- }
+ broadcast_agent_state_update
# return new session
{
diff --git a/public/assets/chat/chat.coffee b/public/assets/chat/chat.coffee
index 65cd4adb7..ac57c6f6a 100644
--- a/public/assets/chat/chat.coffee
+++ b/public/assets/chat/chat.coffee
@@ -10,13 +10,14 @@ do($ = window.jQuery, window) ->
defaults:
invitationPhrase: 'Chat with us!'
agentPhrase: ' is helping you'
- show: false
+ show: true
target: $('body')
host: ''
port: 6042
+ debug: false
_messageCount: 0
- isOpen: false
+ isOpen: true
blinkOnlineInterval: null
stopBlinOnlineStateTimeout: null
showTimeEveryXMinutes: 1
@@ -26,7 +27,6 @@ do($ = window.jQuery, window) ->
isTyping: false
isOnline: true
initialQueueDelay: 10000
- debug: true
wsReconnectEnable: true
strings:
'Online': 'Online'
@@ -54,7 +54,7 @@ do($ = window.jQuery, window) ->
translation
log: (level, string...) =>
- return if !@debug && level is 'debug'
+ return if !@options.debug && level is 'debug'
string.unshift(level)
console.log.apply console, string
@@ -67,6 +67,12 @@ do($ = window.jQuery, window) ->
return window.zammadChatTemplates[name](options)
constructor: (options) ->
+
+ # check prerequisites
+ if !window.WebSocket or !sessionStorage
+ @log 'notice', 'Chat: Browser not supported!'
+ return
+
@options = $.extend {}, @defaults, options
@el = $(@view('chat')(@options))
@options.target.append @el
@@ -80,14 +86,8 @@ do($ = window.jQuery, window) ->
keydown: @checkForEnter
input: @onInput
- if !window.WebSocket or !sessionStorage
- @log 'notice', 'Chat: Browser not supported!'
- return
-
@wsConnect()
- #@onReady()
-
checkForEnter: (event) =>
if not event.shiftKey and event.keyCode is 13
event.preventDefault()
@@ -146,16 +146,22 @@ do($ = window.jQuery, window) ->
reopenSession: (data) =>
unfinishedMessage = sessionStorage.getItem 'unfinished_message'
- @onConnectionEstablished(data)
+ # rerender chat history
+ if data.agent
+ @onConnectionEstablished(data)
- for message in data.session
- @renderMessage
- message: message.content
- id: message.id
- from: if message.created_by_id then 'agent' else 'customer'
+ for message in data.session
+ @renderMessage
+ message: message.content
+ id: message.id
+ from: if message.created_by_id then 'agent' else 'customer'
- if unfinishedMessage
- @input.val unfinishedMessage
+ if unfinishedMessage
+ @input.val unfinishedMessage
+
+ # show wait list
+ if data.position
+ @onQueue data
@show()
@open()
@@ -276,7 +282,6 @@ do($ = window.jQuery, window) ->
# stop delay of initial queue position
if @onInitialQueueDelayId
clearTimeout(@onInitialQueueDelayId)
- #@ws.close()
sessionStorage.removeItem 'sessionId'
sessionStorage.removeItem 'unfinished_message'
diff --git a/public/assets/chat/index.html b/public/assets/chat/index.html
index 4098318cf..0fcb3460b 100644
--- a/public/assets/chat/index.html
+++ b/public/assets/chat/index.html
@@ -134,8 +134,11 @@
}
-->