Show chat per default.
This commit is contained in:
parent
6c0e4ba9f3
commit
0d692cb7ed
9 changed files with 157 additions and 147 deletions
|
@ -36,7 +36,6 @@ class App.CustomerChat extends App.Controller
|
||||||
@bind(
|
@bind(
|
||||||
'chat_session_start'
|
'chat_session_start'
|
||||||
(data) =>
|
(data) =>
|
||||||
App.WebSocket.send(event:'chat_status_agent')
|
|
||||||
if data.session
|
if data.session
|
||||||
@addChat(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')
|
||||||
)
|
)
|
||||||
|
|
||||||
App.WebSocket.send(event:'chat_status_agent')
|
App.WebSocket.send(event:'chat_status_agent')
|
||||||
|
|
||||||
pushState: =>
|
pushState: =>
|
||||||
|
@ -101,7 +99,7 @@ class App.CustomerChat extends App.Controller
|
||||||
@delay(delay, 200, 'updateNavMenu')
|
@delay(delay, 200, 'updateNavMenu')
|
||||||
|
|
||||||
updateMeta: =>
|
updateMeta: =>
|
||||||
if @meta.waiting_chat_count && @maxChats > @currentChatCount()
|
if @meta.waiting_chat_count && @maxChats > @windowCount()
|
||||||
@$('.js-acceptChat').addClass('is-clickable is-blinking')
|
@$('.js-acceptChat').addClass('is-clickable is-blinking')
|
||||||
else
|
else
|
||||||
@$('.js-acceptChat').removeClass('is-clickable is-blinking')
|
@$('.js-acceptChat').removeClass('is-clickable is-blinking')
|
||||||
|
@ -134,11 +132,9 @@ class App.CustomerChat extends App.Controller
|
||||||
|
|
||||||
windowCount: =>
|
windowCount: =>
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
for chat of @chatWindows
|
for chat of @chatWindows
|
||||||
count++
|
count++
|
||||||
|
count
|
||||||
return count
|
|
||||||
|
|
||||||
removeChat: (session_id) =>
|
removeChat: (session_id) =>
|
||||||
delete @chatWindows[session_id]
|
delete @chatWindows[session_id]
|
||||||
|
@ -149,15 +145,8 @@ class App.CustomerChat extends App.Controller
|
||||||
for session_id, chat of @chatWindows
|
for session_id, chat of @chatWindows
|
||||||
chat.trigger 'layout-changed'
|
chat.trigger 'layout-changed'
|
||||||
|
|
||||||
currentChatCount: =>
|
|
||||||
currentChats = 0
|
|
||||||
for key, value of @chatWindows
|
|
||||||
if @chatWindows[key]
|
|
||||||
currentChats += 1
|
|
||||||
currentChats
|
|
||||||
|
|
||||||
acceptChat: =>
|
acceptChat: =>
|
||||||
return if @currentChatCount() >= @maxChats
|
return if @windowCount() >= @maxChats
|
||||||
App.WebSocket.send(event:'chat_session_start')
|
App.WebSocket.send(event:'chat_session_start')
|
||||||
|
|
||||||
class CustomerChatRouter extends App.ControllerPermanent
|
class CustomerChatRouter extends App.ControllerPermanent
|
||||||
|
|
|
@ -10,8 +10,11 @@ class Chat < ApplicationModel
|
||||||
# reconnect
|
# reconnect
|
||||||
if session_id
|
if session_id
|
||||||
chat_session = Chat::Session.find_by(session_id: session_id, state: %w(waiting running))
|
chat_session = Chat::Session.find_by(session_id: session_id, state: %w(waiting running))
|
||||||
|
|
||||||
|
if chat_session
|
||||||
|
if chat_session.state == 'running'
|
||||||
user = nil
|
user = nil
|
||||||
if chat_session && chat_session.user_id
|
if chat_session.user_id
|
||||||
chat_user = User.find(chat_session.user_id)
|
chat_user = User.find(chat_session.user_id)
|
||||||
url = nil
|
url = nil
|
||||||
if chat_user.image && chat_user.image != 'none'
|
if chat_user.image && chat_user.image != 'none'
|
||||||
|
@ -21,11 +24,10 @@ class Chat < ApplicationModel
|
||||||
name: chat_user.fullname,
|
name: chat_user.fullname,
|
||||||
avatar: url,
|
avatar: url,
|
||||||
}
|
}
|
||||||
end
|
|
||||||
|
|
||||||
if chat_session
|
# get queue postion if needed
|
||||||
session = Chat.session_state(session_id)
|
session = Chat.session_state(session_id)
|
||||||
if session && !session.empty?
|
if session
|
||||||
return {
|
return {
|
||||||
state: 'reconnect',
|
state: 'reconnect',
|
||||||
session: session,
|
session: session,
|
||||||
|
@ -33,20 +35,31 @@ class Chat < ApplicationModel
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
elsif chat_session.state == 'waiting'
|
||||||
|
return {
|
||||||
|
state: 'reconnect',
|
||||||
|
position: chat_session.position,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if Chat::Agent.where(active: true).where('updated_at > ?', Time.zone.now - 2.minutes).count > 0
|
# 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
|
||||||
|
|
||||||
|
# if all seads are used
|
||||||
if active_chat_count >= max_queue
|
if active_chat_count >= max_queue
|
||||||
return {
|
return {
|
||||||
state: 'no_seats_available',
|
state: 'no_seats_available',
|
||||||
queue: seads_available,
|
queue: seads_available,
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return { state: 'online' }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
{ state: 'offline' }
|
# seads are available
|
||||||
|
{ state: 'online' }
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.session_state(session_id)
|
def self.session_state(session_id)
|
||||||
|
@ -111,81 +124,3 @@ class Chat < ApplicationModel
|
||||||
seads_total(diff) - active_chat_count
|
seads_total(diff) - active_chat_count
|
||||||
end
|
end
|
||||||
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
|
|
||||||
|
|
42
app/models/chat/agent.rb
Normal file
42
app/models/chat/agent.rb
Normal file
|
@ -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
|
2
app/models/chat/message.rb
Normal file
2
app/models/chat/message.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
class Chat::Message < ApplicationModel
|
||||||
|
end
|
38
app/models/chat/session.rb
Normal file
38
app/models/chat/session.rb
Normal file
|
@ -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
|
2
app/models/chat/topic.rb
Normal file
2
app/models/chat/topic.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
class Chat::Topic < ApplicationModel
|
||||||
|
end
|
|
@ -24,13 +24,7 @@ class Sessions::Event::ChatSessionInit < Sessions::Event::ChatBase
|
||||||
)
|
)
|
||||||
|
|
||||||
# send broadcast to agents
|
# send broadcast to agents
|
||||||
Chat::Agent.where(active: true).each {|item|
|
broadcast_agent_state_update
|
||||||
data = {
|
|
||||||
event: 'chat_status_agent',
|
|
||||||
data: Chat.agent_state(item.updated_by_id),
|
|
||||||
}
|
|
||||||
Sessions.send_to(item.updated_by_id, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
# return new session
|
# return new session
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,13 +10,14 @@ do($ = window.jQuery, window) ->
|
||||||
defaults:
|
defaults:
|
||||||
invitationPhrase: '<strong>Chat</strong> with us!'
|
invitationPhrase: '<strong>Chat</strong> with us!'
|
||||||
agentPhrase: ' is helping you'
|
agentPhrase: ' is helping you'
|
||||||
show: false
|
show: true
|
||||||
target: $('body')
|
target: $('body')
|
||||||
host: ''
|
host: ''
|
||||||
port: 6042
|
port: 6042
|
||||||
|
debug: false
|
||||||
|
|
||||||
_messageCount: 0
|
_messageCount: 0
|
||||||
isOpen: false
|
isOpen: true
|
||||||
blinkOnlineInterval: null
|
blinkOnlineInterval: null
|
||||||
stopBlinOnlineStateTimeout: null
|
stopBlinOnlineStateTimeout: null
|
||||||
showTimeEveryXMinutes: 1
|
showTimeEveryXMinutes: 1
|
||||||
|
@ -26,7 +27,6 @@ do($ = window.jQuery, window) ->
|
||||||
isTyping: false
|
isTyping: false
|
||||||
isOnline: true
|
isOnline: true
|
||||||
initialQueueDelay: 10000
|
initialQueueDelay: 10000
|
||||||
debug: true
|
|
||||||
wsReconnectEnable: true
|
wsReconnectEnable: true
|
||||||
strings:
|
strings:
|
||||||
'Online': 'Online'
|
'Online': 'Online'
|
||||||
|
@ -54,7 +54,7 @@ do($ = window.jQuery, window) ->
|
||||||
translation
|
translation
|
||||||
|
|
||||||
log: (level, string...) =>
|
log: (level, string...) =>
|
||||||
return if !@debug && level is 'debug'
|
return if !@options.debug && level is 'debug'
|
||||||
string.unshift(level)
|
string.unshift(level)
|
||||||
console.log.apply console, string
|
console.log.apply console, string
|
||||||
|
|
||||||
|
@ -67,6 +67,12 @@ do($ = window.jQuery, window) ->
|
||||||
return window.zammadChatTemplates[name](options)
|
return window.zammadChatTemplates[name](options)
|
||||||
|
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
|
|
||||||
|
# check prerequisites
|
||||||
|
if !window.WebSocket or !sessionStorage
|
||||||
|
@log 'notice', 'Chat: Browser not supported!'
|
||||||
|
return
|
||||||
|
|
||||||
@options = $.extend {}, @defaults, options
|
@options = $.extend {}, @defaults, options
|
||||||
@el = $(@view('chat')(@options))
|
@el = $(@view('chat')(@options))
|
||||||
@options.target.append @el
|
@options.target.append @el
|
||||||
|
@ -80,14 +86,8 @@ do($ = window.jQuery, window) ->
|
||||||
keydown: @checkForEnter
|
keydown: @checkForEnter
|
||||||
input: @onInput
|
input: @onInput
|
||||||
|
|
||||||
if !window.WebSocket or !sessionStorage
|
|
||||||
@log 'notice', 'Chat: Browser not supported!'
|
|
||||||
return
|
|
||||||
|
|
||||||
@wsConnect()
|
@wsConnect()
|
||||||
|
|
||||||
#@onReady()
|
|
||||||
|
|
||||||
checkForEnter: (event) =>
|
checkForEnter: (event) =>
|
||||||
if not event.shiftKey and event.keyCode is 13
|
if not event.shiftKey and event.keyCode is 13
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
@ -146,6 +146,8 @@ do($ = window.jQuery, window) ->
|
||||||
reopenSession: (data) =>
|
reopenSession: (data) =>
|
||||||
unfinishedMessage = sessionStorage.getItem 'unfinished_message'
|
unfinishedMessage = sessionStorage.getItem 'unfinished_message'
|
||||||
|
|
||||||
|
# rerender chat history
|
||||||
|
if data.agent
|
||||||
@onConnectionEstablished(data)
|
@onConnectionEstablished(data)
|
||||||
|
|
||||||
for message in data.session
|
for message in data.session
|
||||||
|
@ -157,6 +159,10 @@ do($ = window.jQuery, window) ->
|
||||||
if unfinishedMessage
|
if unfinishedMessage
|
||||||
@input.val unfinishedMessage
|
@input.val unfinishedMessage
|
||||||
|
|
||||||
|
# show wait list
|
||||||
|
if data.position
|
||||||
|
@onQueue data
|
||||||
|
|
||||||
@show()
|
@show()
|
||||||
@open()
|
@open()
|
||||||
@scrollToBottom()
|
@scrollToBottom()
|
||||||
|
@ -276,7 +282,6 @@ do($ = window.jQuery, window) ->
|
||||||
# stop delay of initial queue position
|
# stop delay of initial queue position
|
||||||
if @onInitialQueueDelayId
|
if @onInitialQueueDelayId
|
||||||
clearTimeout(@onInitialQueueDelayId)
|
clearTimeout(@onInitialQueueDelayId)
|
||||||
#@ws.close()
|
|
||||||
|
|
||||||
sessionStorage.removeItem 'sessionId'
|
sessionStorage.removeItem 'sessionId'
|
||||||
sessionStorage.removeItem 'unfinished_message'
|
sessionStorage.removeItem 'unfinished_message'
|
||||||
|
|
|
@ -134,8 +134,11 @@
|
||||||
}
|
}
|
||||||
-->
|
-->
|
||||||
<script>
|
<script>
|
||||||
var chat = new ZammadChat();
|
var chat = new ZammadChat({
|
||||||
chat.open();
|
host: 'ws://localhost',
|
||||||
|
port: 6042,
|
||||||
|
debug: true
|
||||||
|
});
|
||||||
|
|
||||||
$('.settings :input').on({
|
$('.settings :input').on({
|
||||||
change: function(){
|
change: function(){
|
||||||
|
|
Loading…
Reference in a new issue