Show chat per default.

This commit is contained in:
Martin Edenhofer 2015-11-13 15:15:44 +01:00
parent 6c0e4ba9f3
commit 0d692cb7ed
9 changed files with 157 additions and 147 deletions

View file

@ -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

View file

@ -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
View 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

View file

@ -0,0 +1,2 @@
class Chat::Message < ApplicationModel
end

View 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
View file

@ -0,0 +1,2 @@
class Chat::Topic < ApplicationModel
end

View file

@ -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
{ {

View file

@ -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'

View file

@ -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(){