Added reconnecting of chat app. Improved logging of chat app.
This commit is contained in:
parent
74de560844
commit
ba68349789
11 changed files with 346 additions and 172 deletions
|
@ -27,20 +27,25 @@ class App.CustomerChat extends App.Controller
|
||||||
|
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
App.Event.bind(
|
@bind(
|
||||||
'chat_status_agent'
|
'chat_status_agent'
|
||||||
(data) =>
|
(data) =>
|
||||||
@meta = data
|
@meta = data
|
||||||
@updateMeta()
|
@updateMeta()
|
||||||
@interval(@pushState, 20000, 'pushState')
|
@interval(@pushState, 20000, 'pushState')
|
||||||
)
|
)
|
||||||
App.Event.bind(
|
@bind(
|
||||||
'chat_session_start'
|
'chat_session_start'
|
||||||
(data) =>
|
(data) =>
|
||||||
App.WebSocket.send(event:'chat_status_agent')
|
App.WebSocket.send(event:'chat_status_agent')
|
||||||
if data.session
|
if data.session
|
||||||
@addChat(data.session)
|
@addChat(data.session)
|
||||||
)
|
)
|
||||||
|
@bind(
|
||||||
|
'ws:login'
|
||||||
|
->
|
||||||
|
App.WebSocket.send(event:'chat_status_agent')
|
||||||
|
)
|
||||||
|
|
||||||
App.WebSocket.send(event:'chat_status_agent')
|
App.WebSocket.send(event:'chat_status_agent')
|
||||||
|
|
||||||
|
@ -190,20 +195,28 @@ class chatWindow extends App.Controller
|
||||||
|
|
||||||
@on 'layout-change', @scrollToBottom
|
@on 'layout-change', @scrollToBottom
|
||||||
|
|
||||||
App.Event.bind(
|
@bind(
|
||||||
'chat_session_typing'
|
'chat_session_typing'
|
||||||
(data) =>
|
(data) =>
|
||||||
return if data.session_id isnt @session.session_id
|
return if data.session_id isnt @session.session_id
|
||||||
return if data.self_written
|
return if data.self_written
|
||||||
@showWritingLoader()
|
@showWritingLoader()
|
||||||
)
|
)
|
||||||
App.Event.bind(
|
@bind(
|
||||||
'chat_session_message'
|
'chat_session_message'
|
||||||
(data) =>
|
(data) =>
|
||||||
return if data.session_id isnt @session.session_id
|
return if data.session_id isnt @session.session_id
|
||||||
return if data.self_written
|
return if data.self_written
|
||||||
@receiveMessage(data.message.content)
|
@receiveMessage(data.message.content)
|
||||||
)
|
)
|
||||||
|
@bind(
|
||||||
|
'chat_session_left chat_session_closed'
|
||||||
|
(data) =>
|
||||||
|
return if data.session_id isnt @session.session_id
|
||||||
|
return if data.self_written
|
||||||
|
@addStatusMessage("#{data.realname} was leaving the conversation")
|
||||||
|
@goOffline()
|
||||||
|
)
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
@html App.view('layout_ref/customer_chat_window')
|
@html App.view('layout_ref/customer_chat_window')
|
||||||
|
@ -223,7 +236,7 @@ class chatWindow extends App.Controller
|
||||||
@addMessage message.content, 'customer'
|
@addMessage message.content, 'customer'
|
||||||
|
|
||||||
# set focus
|
# set focus
|
||||||
@input.get(0).focus()
|
#@input.get(0).focus()
|
||||||
|
|
||||||
onTransitionend: (event) =>
|
onTransitionend: (event) =>
|
||||||
# chat window is done with animation - adjust scroll-bars
|
# chat window is done with animation - adjust scroll-bars
|
||||||
|
@ -246,6 +259,7 @@ class chatWindow extends App.Controller
|
||||||
|
|
||||||
release: =>
|
release: =>
|
||||||
@trigger 'closed'
|
@trigger 'closed'
|
||||||
|
@el.remove()
|
||||||
super
|
super
|
||||||
|
|
||||||
clearUnread: =>
|
clearUnread: =>
|
||||||
|
@ -360,7 +374,7 @@ class chatWindow extends App.Controller
|
||||||
@$('.js-loader').remove()
|
@$('.js-loader').remove()
|
||||||
|
|
||||||
goOffline: =>
|
goOffline: =>
|
||||||
@addStatusMessage("<strong>#{ @options.name }</strong>'s connection got closed")
|
#@addStatusMessage("<strong>#{ @options.name }</strong>'s connection got closed")
|
||||||
@status.attr('data-status', 'offline')
|
@status.attr('data-status', 'offline')
|
||||||
@el.addClass('is-offline')
|
@el.addClass('is-offline')
|
||||||
@input.attr('disabled', true)
|
@input.attr('disabled', true)
|
||||||
|
|
|
@ -46,7 +46,7 @@ class Chat < ApplicationModel
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.running_chat_count
|
def self.running_chat_count
|
||||||
Chat::Session.where(state: ['waiting']).count
|
Chat::Session.where(state: ['running']).count
|
||||||
end
|
end
|
||||||
|
|
||||||
def active_chat_count
|
def active_chat_count
|
||||||
|
@ -129,19 +129,19 @@ class Chat::Session < ApplicationModel
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_recipient(client_id, store = false)
|
def add_recipient(client_id, store = false)
|
||||||
if !self.preferences[:participants]
|
if !preferences[:participants]
|
||||||
self.preferences[:participants] = []
|
preferences[:participants] = []
|
||||||
end
|
end
|
||||||
return self.preferences[:participants] if self.preferences[:participants].include?(client_id)
|
return preferences[:participants] if preferences[:participants].include?(client_id)
|
||||||
self.preferences[:participants].push client_id
|
preferences[:participants].push client_id
|
||||||
if store
|
if store
|
||||||
self.save
|
save
|
||||||
end
|
end
|
||||||
self.preferences[:participants]
|
preferences[:participants]
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_to_recipients(message, ignore_client_id)
|
def send_to_recipients(message, ignore_client_id)
|
||||||
self.preferences[:participants].each {|local_client_id|
|
preferences[:participants].each {|local_client_id|
|
||||||
next if local_client_id == ignore_client_id
|
next if local_client_id == ignore_client_id
|
||||||
Sessions.send(local_client_id, message)
|
Sessions.send(local_client_id, message)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ class Sessions::Event::ChatBase
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def pre_check
|
def pre
|
||||||
|
|
||||||
# check if feature is enabled
|
# check if feature is enabled
|
||||||
if !Setting.get('chat')
|
if !Setting.get('chat')
|
||||||
|
@ -22,4 +22,8 @@ class Sessions::Event::ChatBase
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def post
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,15 +16,41 @@ class Sessions::Event::ChatSessionClose < Sessions::Event::ChatBase
|
||||||
return {
|
return {
|
||||||
event: 'chat_status_close',
|
event: 'chat_status_close',
|
||||||
data: {
|
data: {
|
||||||
state: "No such session id #{data['data']['session_id']}",
|
state: "No such session id #{@data['data']['session_id']}",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
chat_session.state = 'closed'
|
realname = 'anonymous'
|
||||||
chat_session.save
|
if @session && @session['id']
|
||||||
|
realname = User.find(@session['id']).fullname
|
||||||
|
end
|
||||||
|
|
||||||
# return new session
|
# notify about "leaving"
|
||||||
|
if @session && chat_session.user_id == @session['id']
|
||||||
|
message = {
|
||||||
|
event: 'chat_session_closed',
|
||||||
|
data: {
|
||||||
|
session_id: chat_session.session_id,
|
||||||
|
realname: realname,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# close session if host is closing it
|
||||||
|
chat_session.state = 'closed'
|
||||||
|
chat_session.save
|
||||||
|
else
|
||||||
|
message = {
|
||||||
|
event: 'chat_session_left',
|
||||||
|
data: {
|
||||||
|
session_id: chat_session.session_id,
|
||||||
|
realname: realname,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
chat_session.send_to_recipients(message, @client_id)
|
||||||
|
|
||||||
|
# notifiy participients
|
||||||
{
|
{
|
||||||
event: 'chat_status_close',
|
event: 'chat_status_close',
|
||||||
data: {
|
data: {
|
||||||
|
|
|
@ -20,9 +20,13 @@ class Sessions::Event::ChatSessionStart < Sessions::Event::ChatBase
|
||||||
|
|
||||||
# send chat_session_init to client
|
# send chat_session_init to client
|
||||||
chat_user = User.find(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 = {
|
user = {
|
||||||
name: chat_user.fullname,
|
name: chat_user.fullname,
|
||||||
avatar: chat_user.image,
|
avatar: url,
|
||||||
}
|
}
|
||||||
data = {
|
data = {
|
||||||
event: 'chat_session_start',
|
event: 'chat_session_start',
|
||||||
|
|
|
@ -4,12 +4,10 @@ class Sessions::Event::ChatStatusAgent < Sessions::Event::ChatBase
|
||||||
|
|
||||||
# check if user has permissions
|
# check if user has permissions
|
||||||
|
|
||||||
|
|
||||||
# renew timestamps
|
# renew timestamps
|
||||||
state = Chat::Agent.state(@session['id'])
|
state = Chat::Agent.state(@session['id'])
|
||||||
Chat::Agent.state(@session['id'], state)
|
Chat::Agent.state(@session['id'], state)
|
||||||
|
|
||||||
|
|
||||||
# update recipients of existing sessions
|
# update recipients of existing sessions
|
||||||
Chat::Session.where(state: 'running', user_id: @session['id']).order('created_at ASC').each {|chat_session|
|
Chat::Session.where(state: 'running', user_id: @session['id']).order('created_at ASC').each {|chat_session|
|
||||||
chat_session.add_recipient(@client_id, true)
|
chat_session.add_recipient(@client_id, true)
|
||||||
|
|
|
@ -19,15 +19,35 @@ do($ = window.jQuery, window) ->
|
||||||
inputTimeout: null
|
inputTimeout: null
|
||||||
isTyping: false
|
isTyping: false
|
||||||
isOnline: true
|
isOnline: true
|
||||||
|
debug: true
|
||||||
|
host: 'ws://localhost:6042'
|
||||||
strings:
|
strings:
|
||||||
'Online': 'Online'
|
'Online': 'Online'
|
||||||
'Offline': 'Offline'
|
'Offline': 'Offline'
|
||||||
'Connecting': 'Connecting'
|
'Connecting': 'Verbinden'
|
||||||
'Connection re-established': 'Connection re-established'
|
'Connection re-established': 'Connection re-established'
|
||||||
'Today': 'Today'
|
'Today': 'Heute'
|
||||||
|
'Send': 'Senden'
|
||||||
|
'Compose your message...': 'Ihre Nachricht...'
|
||||||
|
'All colleges are busy.': 'Alle Kollegen sind belegt.'
|
||||||
|
'You are on waiting list position <strong>%s</strong>.': 'Sie sind in der Warteliste an der Position <strong>%s</strong>.'
|
||||||
|
'': ''
|
||||||
|
'': ''
|
||||||
|
'': ''
|
||||||
|
|
||||||
T: (string) =>
|
T: (string, items...) =>
|
||||||
return @strings[string]
|
if !@strings[string]
|
||||||
|
@log 'notice', "Translation needed for '#{string}'"
|
||||||
|
translation = @strings[string] || string
|
||||||
|
if items
|
||||||
|
for item in items
|
||||||
|
translation = translation.replace(/%s/, item)
|
||||||
|
|
||||||
|
translation
|
||||||
|
|
||||||
|
log: (level, string...) =>
|
||||||
|
return if !@debug && level is 'debug'
|
||||||
|
console.log level, string
|
||||||
|
|
||||||
view: (name) =>
|
view: (name) =>
|
||||||
return (options) =>
|
return (options) =>
|
||||||
|
@ -42,8 +62,6 @@ do($ = window.jQuery, window) ->
|
||||||
@el = $(@view('chat')(@options))
|
@el = $(@view('chat')(@options))
|
||||||
@options.target.append @el
|
@options.target.append @el
|
||||||
|
|
||||||
@setAgentOnlineState @isOnline
|
|
||||||
|
|
||||||
@el.find('.js-chat-open').click @open
|
@el.find('.js-chat-open').click @open
|
||||||
@el.find('.js-chat-close').click @close
|
@el.find('.js-chat-close').click @close
|
||||||
@el.find('.zammad-chat-controls').on 'submit', @onSubmit
|
@el.find('.zammad-chat-controls').on 'submit', @onSubmit
|
||||||
|
@ -54,24 +72,10 @@ do($ = window.jQuery, window) ->
|
||||||
@session_id = undefined
|
@session_id = undefined
|
||||||
|
|
||||||
if !window.WebSocket
|
if !window.WebSocket
|
||||||
console.log('Zammad Chat: Browser not supported')
|
@log 'notice', 'Chat: Browser not supported!'
|
||||||
return
|
return
|
||||||
|
|
||||||
zammad_host = 'ws://localhost:6042'
|
@connect()
|
||||||
@ws = new window.WebSocket(zammad_host)
|
|
||||||
console.log("Connecting to #{zammad_host}")
|
|
||||||
|
|
||||||
@ws.onopen = =>
|
|
||||||
console.log('ws connected')
|
|
||||||
@send 'chat_status_customer'
|
|
||||||
|
|
||||||
@ws.onmessage = @onWebSocketMessage
|
|
||||||
|
|
||||||
@ws.onclose = (e) =>
|
|
||||||
console.log 'debug', 'close websocket connection'
|
|
||||||
|
|
||||||
@ws.onerror = (e) =>
|
|
||||||
console.log 'debug', 'ws:onerror', e
|
|
||||||
|
|
||||||
@onReady()
|
@onReady()
|
||||||
|
|
||||||
|
@ -81,7 +85,7 @@ do($ = window.jQuery, window) ->
|
||||||
@sendMessage()
|
@sendMessage()
|
||||||
|
|
||||||
send: (event, data) =>
|
send: (event, data) =>
|
||||||
console.log 'debug', 'ws:send', event, data
|
@log 'debug', 'ws:send', event, data
|
||||||
pipe = JSON.stringify
|
pipe = JSON.stringify
|
||||||
event: event
|
event: event
|
||||||
data: data
|
data: data
|
||||||
|
@ -89,7 +93,7 @@ do($ = window.jQuery, window) ->
|
||||||
|
|
||||||
onWebSocketMessage: (e) =>
|
onWebSocketMessage: (e) =>
|
||||||
pipes = JSON.parse( e.data )
|
pipes = JSON.parse( e.data )
|
||||||
console.log 'debug', 'ws:onmessage', pipes
|
@log 'debug', 'ws:onmessage', pipes
|
||||||
|
|
||||||
for pipe in pipes
|
for pipe in pipes
|
||||||
switch pipe.event
|
switch pipe.event
|
||||||
|
@ -110,17 +114,21 @@ do($ = window.jQuery, window) ->
|
||||||
when 'queue'
|
when 'queue'
|
||||||
@onQueue pipe.data.position
|
@onQueue pipe.data.position
|
||||||
@session_id = pipe.data.session_id
|
@session_id = pipe.data.session_id
|
||||||
|
when 'chat_session_closed'
|
||||||
|
@onSessionClosed pipe.data
|
||||||
|
when 'chat_session_left'
|
||||||
|
@onSessionClosed pipe.data
|
||||||
when 'chat_status_customer'
|
when 'chat_status_customer'
|
||||||
switch pipe.data.state
|
switch pipe.data.state
|
||||||
when 'online'
|
when 'online'
|
||||||
@onReady()
|
@onReady()
|
||||||
console.log 'Zammad Chat: ready'
|
@log 'debug', 'Zammad Chat: ready'
|
||||||
when 'offline'
|
when 'offline'
|
||||||
console.log 'Zammad Chat: No agent online'
|
@log 'debug', 'Zammad Chat: No agent online'
|
||||||
when 'chat_disabled'
|
when 'chat_disabled'
|
||||||
console.log 'Zammad Chat: Chat is disabled'
|
@log 'debug', 'Zammad Chat: Chat is disabled'
|
||||||
when 'no_seats_available'
|
when 'no_seats_available'
|
||||||
console.log 'Zammad Chat: Too many clients in queue. Clients in queue: ', pipe.data.queue
|
@log 'debug', 'Zammad Chat: Too many clients in queue. Clients in queue: ', pipe.data.queue
|
||||||
|
|
||||||
onReady: =>
|
onReady: =>
|
||||||
if @options.show
|
if @options.show
|
||||||
|
@ -157,8 +165,7 @@ do($ = window.jQuery, window) ->
|
||||||
sendMessage: ->
|
sendMessage: ->
|
||||||
message = @el.find('.zammad-chat-input').val()
|
message = @el.find('.zammad-chat-input').val()
|
||||||
|
|
||||||
if !message
|
return if !message
|
||||||
return
|
|
||||||
|
|
||||||
messageElement = @view('message')
|
messageElement = @view('message')
|
||||||
message: message
|
message: message
|
||||||
|
@ -216,7 +223,7 @@ do($ = window.jQuery, window) ->
|
||||||
# setTimeout @onConnectionEstablished, 1180
|
# setTimeout @onConnectionEstablished, 1180
|
||||||
# setTimeout @onAgentTypingStart, 2000
|
# setTimeout @onAgentTypingStart, 2000
|
||||||
# setTimeout @receiveMessage, 5000, "Hello! How can I help you?"
|
# setTimeout @receiveMessage, 5000, "Hello! How can I help you?"
|
||||||
@connect()
|
@session_init()
|
||||||
|
|
||||||
close: (event) =>
|
close: (event) =>
|
||||||
event.stopPropagation() if event
|
event.stopPropagation() if event
|
||||||
|
@ -228,6 +235,8 @@ do($ = window.jQuery, window) ->
|
||||||
@disconnect()
|
@disconnect()
|
||||||
@isOpen = false
|
@isOpen = false
|
||||||
|
|
||||||
|
@send 'chat_session_close', {session_id: @session_id}
|
||||||
|
|
||||||
hide: ->
|
hide: ->
|
||||||
@el.removeClass('zammad-chat-is-visible')
|
@el.removeClass('zammad-chat-is-visible')
|
||||||
|
|
||||||
|
@ -238,8 +247,16 @@ do($ = window.jQuery, window) ->
|
||||||
|
|
||||||
@el.css 'bottom', -remainerHeight
|
@el.css 'bottom', -remainerHeight
|
||||||
|
|
||||||
|
disableInput: ->
|
||||||
|
@el.find('.zammad-chat-input').prop('disabled', true)
|
||||||
|
@el.find('.zammad-chat-send').prop('disabled', true)
|
||||||
|
|
||||||
|
enableInput: ->
|
||||||
|
@el.find('.zammad-chat-input').prop('disabled', false)
|
||||||
|
@el.find('.zammad-chat-send').prop('disabled', false)
|
||||||
|
|
||||||
onQueue: (position) =>
|
onQueue: (position) =>
|
||||||
console.log "onQueue", position
|
@log 'notice', 'onQueue', position
|
||||||
@inQueue = true
|
@inQueue = true
|
||||||
|
|
||||||
@el.find('.zammad-chat-body').html @view('waiting')
|
@el.find('.zammad-chat-body').html @view('waiting')
|
||||||
|
@ -294,21 +311,49 @@ do($ = window.jQuery, window) ->
|
||||||
scrollToBottom: ->
|
scrollToBottom: ->
|
||||||
@el.find('.zammad-chat-body').scrollTop($('.zammad-chat-body').prop('scrollHeight'))
|
@el.find('.zammad-chat-body').scrollTop($('.zammad-chat-body').prop('scrollHeight'))
|
||||||
|
|
||||||
connect: ->
|
session_init: ->
|
||||||
@send('chat_session_init')
|
@send('chat_session_init')
|
||||||
|
|
||||||
|
connect: =>
|
||||||
|
@log 'notice', "Connecting to #{@host}"
|
||||||
|
@ws = new window.WebSocket(@host)
|
||||||
|
@ws.onopen = =>
|
||||||
|
@log 'debug', 'ws connected'
|
||||||
|
@send 'chat_status_customer'
|
||||||
|
@setAgentOnlineState(true)
|
||||||
|
|
||||||
|
@ws.onmessage = @onWebSocketMessage
|
||||||
|
|
||||||
|
@ws.onclose = (e) =>
|
||||||
|
@log 'debug', 'close websocket connection'
|
||||||
|
@reconnect()
|
||||||
|
@setAgentOnlineState(false)
|
||||||
|
|
||||||
|
@ws.onerror = (e) =>
|
||||||
|
@log 'debug', 'ws:onerror', e
|
||||||
|
|
||||||
reconnect: =>
|
reconnect: =>
|
||||||
# set status to connecting
|
# set status to connecting
|
||||||
|
@log 'notice', 'reconnecting'
|
||||||
|
@disableInput()
|
||||||
@lastAddedType = 'status'
|
@lastAddedType = 'status'
|
||||||
@el.find('.zammad-chat-agent-status').attr('data-status', 'connecting').text @T('Connecting')
|
@el.find('.zammad-chat-agent-status').attr('data-status', 'connecting').text @T('Reconnecting')
|
||||||
@addStatus @T('Connection lost')
|
@addStatus @T('Connection lost')
|
||||||
|
|
||||||
|
if @reconnectDelayId
|
||||||
|
clearTimeout(@reconnectDelayId)
|
||||||
|
@reconnectDelayId = setTimeout(@connect, 5000)
|
||||||
|
|
||||||
onConnectionReestablished: =>
|
onConnectionReestablished: =>
|
||||||
# set status back to online
|
# set status back to online
|
||||||
@lastAddedType = 'status'
|
@lastAddedType = 'status'
|
||||||
@el.find('.zammad-chat-agent-status').attr('data-status', 'online').text @T('Online')
|
@el.find('.zammad-chat-agent-status').attr('data-status', 'online').text @T('Online')
|
||||||
@addStatus @T('Connection re-established')
|
@addStatus @T('Connection re-established')
|
||||||
|
|
||||||
|
onSessionClosed: (data) ->
|
||||||
|
@addStatus @T('Chat closed by %s', data.realname)
|
||||||
|
@disableInput()
|
||||||
|
|
||||||
disconnect: ->
|
disconnect: ->
|
||||||
@showLoader()
|
@showLoader()
|
||||||
@el.find('.zammad-chat-welcome').removeClass('zammad-chat-is-hidden')
|
@el.find('.zammad-chat-welcome').removeClass('zammad-chat-is-hidden')
|
||||||
|
@ -322,6 +367,8 @@ do($ = window.jQuery, window) ->
|
||||||
@el.find('.zammad-chat-agent').html @view('agent')
|
@el.find('.zammad-chat-agent').html @view('agent')
|
||||||
agent: agent
|
agent: agent
|
||||||
|
|
||||||
|
@enableInput()
|
||||||
|
|
||||||
@el.find('.zammad-chat-body').empty()
|
@el.find('.zammad-chat-body').empty()
|
||||||
@el.find('.zammad-chat-welcome').addClass('zammad-chat-is-hidden')
|
@el.find('.zammad-chat-welcome').addClass('zammad-chat-is-hidden')
|
||||||
@el.find('.zammad-chat-agent').removeClass('zammad-chat-is-hidden')
|
@el.find('.zammad-chat-agent').removeClass('zammad-chat-is-hidden')
|
||||||
|
|
|
@ -1,4 +1,70 @@
|
||||||
var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
if (!window.zammadChatTemplates) {
|
||||||
|
window.zammadChatTemplates = {};
|
||||||
|
}
|
||||||
|
window.zammadChatTemplates["agent"] = function (__obj) {
|
||||||
|
if (!__obj) __obj = {};
|
||||||
|
var __out = [], __capture = function(callback) {
|
||||||
|
var out = __out, result;
|
||||||
|
__out = [];
|
||||||
|
callback.call(this);
|
||||||
|
result = __out.join('');
|
||||||
|
__out = out;
|
||||||
|
return __safe(result);
|
||||||
|
}, __sanitize = function(value) {
|
||||||
|
if (value && value.ecoSafe) {
|
||||||
|
return value;
|
||||||
|
} else if (typeof value !== 'undefined' && value != null) {
|
||||||
|
return __escape(value);
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
|
||||||
|
__safe = __obj.safe = function(value) {
|
||||||
|
if (value && value.ecoSafe) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
if (!(typeof value !== 'undefined' && value != null)) value = '';
|
||||||
|
var result = new String(value);
|
||||||
|
result.ecoSafe = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (!__escape) {
|
||||||
|
__escape = __obj.escape = function(value) {
|
||||||
|
return ('' + value)
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
(function() {
|
||||||
|
(function() {
|
||||||
|
if (this.agent.avatar) {
|
||||||
|
__out.push('\n<img class="zammad-chat-agent-avatar" src="');
|
||||||
|
__out.push(__sanitize(this.agent.avatar));
|
||||||
|
__out.push('">\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
__out.push('\n<span class="zammad-chat-agent-sentence">\n <span class="zammad-chat-agent-name">');
|
||||||
|
|
||||||
|
__out.push(__sanitize(this.agent.name));
|
||||||
|
|
||||||
|
__out.push('</span> ');
|
||||||
|
|
||||||
|
__out.push(this.agentPhrase);
|
||||||
|
|
||||||
|
__out.push('\n</span>');
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
||||||
|
}).call(__obj);
|
||||||
|
__obj.safe = __objSafe, __obj.escape = __escape;
|
||||||
|
return __out.join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
||||||
|
slice = [].slice;
|
||||||
|
|
||||||
(function($, window) {
|
(function($, window) {
|
||||||
var ZammadChat;
|
var ZammadChat;
|
||||||
|
@ -30,16 +96,48 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
|
|
||||||
ZammadChat.prototype.isOnline = true;
|
ZammadChat.prototype.isOnline = true;
|
||||||
|
|
||||||
|
ZammadChat.prototype.debug = true;
|
||||||
|
|
||||||
|
ZammadChat.prototype.host = 'ws://localhost:6042';
|
||||||
|
|
||||||
ZammadChat.prototype.strings = {
|
ZammadChat.prototype.strings = {
|
||||||
'Online': 'Online',
|
'Online': 'Online',
|
||||||
'Offline': 'Offline',
|
'Offline': 'Offline',
|
||||||
'Connecting': 'Connecting',
|
'Connecting': 'Verbinden',
|
||||||
'Connection re-established': 'Connection re-established',
|
'Connection re-established': 'Connection re-established',
|
||||||
'Today': 'Today'
|
'Today': 'Heute',
|
||||||
|
'Send': 'Senden',
|
||||||
|
'Compose your message...': 'Ihre Nachricht...',
|
||||||
|
'All colleges are busy.': 'Alle Kollegen sind belegt.',
|
||||||
|
'You are on waiting list position <strong>%s</strong>.': 'Sie sind in der Warteliste an der Position <strong>%s</strong>.',
|
||||||
|
'': '',
|
||||||
|
'': '',
|
||||||
|
'': ''
|
||||||
};
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.T = function(string) {
|
ZammadChat.prototype.T = function() {
|
||||||
return this.strings[string];
|
var i, item, items, len, string, translation;
|
||||||
|
string = arguments[0], items = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
||||||
|
if (!this.strings[string]) {
|
||||||
|
this.log('notice', "Translation needed for '" + string + "'");
|
||||||
|
}
|
||||||
|
translation = this.strings[string] || string;
|
||||||
|
if (items) {
|
||||||
|
for (i = 0, len = items.length; i < len; i++) {
|
||||||
|
item = items[i];
|
||||||
|
translation = translation.replace(/%s/, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return translation;
|
||||||
|
};
|
||||||
|
|
||||||
|
ZammadChat.prototype.log = function() {
|
||||||
|
var level, string;
|
||||||
|
level = arguments[0], string = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
||||||
|
if (!this.debug && level === 'debug') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return console.log(level, string);
|
||||||
};
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.view = function(name) {
|
ZammadChat.prototype.view = function(name) {
|
||||||
|
@ -59,6 +157,7 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
this.onConnectionEstablished = bind(this.onConnectionEstablished, this);
|
this.onConnectionEstablished = bind(this.onConnectionEstablished, this);
|
||||||
this.onConnectionReestablished = bind(this.onConnectionReestablished, this);
|
this.onConnectionReestablished = bind(this.onConnectionReestablished, this);
|
||||||
this.reconnect = bind(this.reconnect, this);
|
this.reconnect = bind(this.reconnect, this);
|
||||||
|
this.connect = bind(this.connect, this);
|
||||||
this.onAgentTypingEnd = bind(this.onAgentTypingEnd, this);
|
this.onAgentTypingEnd = bind(this.onAgentTypingEnd, this);
|
||||||
this.onAgentTypingStart = bind(this.onAgentTypingStart, this);
|
this.onAgentTypingStart = bind(this.onAgentTypingStart, this);
|
||||||
this.onQueue = bind(this.onQueue, this);
|
this.onQueue = bind(this.onQueue, this);
|
||||||
|
@ -75,12 +174,11 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
this.send = bind(this.send, this);
|
this.send = bind(this.send, this);
|
||||||
this.checkForEnter = bind(this.checkForEnter, this);
|
this.checkForEnter = bind(this.checkForEnter, this);
|
||||||
this.view = bind(this.view, this);
|
this.view = bind(this.view, this);
|
||||||
|
this.log = bind(this.log, this);
|
||||||
this.T = bind(this.T, this);
|
this.T = bind(this.T, this);
|
||||||
var zammad_host;
|
|
||||||
this.options = $.extend({}, this.defaults, options);
|
this.options = $.extend({}, this.defaults, options);
|
||||||
this.el = $(this.view('chat')(this.options));
|
this.el = $(this.view('chat')(this.options));
|
||||||
this.options.target.append(this.el);
|
this.options.target.append(this.el);
|
||||||
this.setAgentOnlineState(this.isOnline);
|
|
||||||
this.el.find('.js-chat-open').click(this.open);
|
this.el.find('.js-chat-open').click(this.open);
|
||||||
this.el.find('.js-chat-close').click(this.close);
|
this.el.find('.js-chat-close').click(this.close);
|
||||||
this.el.find('.zammad-chat-controls').on('submit', this.onSubmit);
|
this.el.find('.zammad-chat-controls').on('submit', this.onSubmit);
|
||||||
|
@ -90,29 +188,10 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
});
|
});
|
||||||
this.session_id = void 0;
|
this.session_id = void 0;
|
||||||
if (!window.WebSocket) {
|
if (!window.WebSocket) {
|
||||||
console.log('Zammad Chat: Browser not supported');
|
this.log('notice', 'Chat: Browser not supported!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
zammad_host = 'ws://localhost:6042';
|
this.connect();
|
||||||
this.ws = new window.WebSocket(zammad_host);
|
|
||||||
console.log("Connecting to " + zammad_host);
|
|
||||||
this.ws.onopen = (function(_this) {
|
|
||||||
return function() {
|
|
||||||
console.log('ws connected');
|
|
||||||
return _this.send('chat_status_customer');
|
|
||||||
};
|
|
||||||
})(this);
|
|
||||||
this.ws.onmessage = this.onWebSocketMessage;
|
|
||||||
this.ws.onclose = (function(_this) {
|
|
||||||
return function(e) {
|
|
||||||
return console.log('debug', 'close websocket connection');
|
|
||||||
};
|
|
||||||
})(this);
|
|
||||||
this.ws.onerror = (function(_this) {
|
|
||||||
return function(e) {
|
|
||||||
return console.log('debug', 'ws:onerror', e);
|
|
||||||
};
|
|
||||||
})(this);
|
|
||||||
this.onReady();
|
this.onReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +204,7 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
|
|
||||||
ZammadChat.prototype.send = function(event, data) {
|
ZammadChat.prototype.send = function(event, data) {
|
||||||
var pipe;
|
var pipe;
|
||||||
console.log('debug', 'ws:send', event, data);
|
this.log('debug', 'ws:send', event, data);
|
||||||
pipe = JSON.stringify({
|
pipe = JSON.stringify({
|
||||||
event: event,
|
event: event,
|
||||||
data: data
|
data: data
|
||||||
|
@ -136,7 +215,7 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
ZammadChat.prototype.onWebSocketMessage = function(e) {
|
ZammadChat.prototype.onWebSocketMessage = function(e) {
|
||||||
var i, len, pipe, pipes;
|
var i, len, pipe, pipes;
|
||||||
pipes = JSON.parse(e.data);
|
pipes = JSON.parse(e.data);
|
||||||
console.log('debug', 'ws:onmessage', pipes);
|
this.log('debug', 'ws:onmessage', pipes);
|
||||||
for (i = 0, len = pipes.length; i < len; i++) {
|
for (i = 0, len = pipes.length; i < len; i++) {
|
||||||
pipe = pipes[i];
|
pipe = pipes[i];
|
||||||
switch (pipe.event) {
|
switch (pipe.event) {
|
||||||
|
@ -168,20 +247,26 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
this.session_id = pipe.data.session_id;
|
this.session_id = pipe.data.session_id;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'chat_session_closed':
|
||||||
|
this.onSessionClosed(pipe.data);
|
||||||
|
break;
|
||||||
|
case 'chat_session_left':
|
||||||
|
this.onSessionClosed(pipe.data);
|
||||||
|
break;
|
||||||
case 'chat_status_customer':
|
case 'chat_status_customer':
|
||||||
switch (pipe.data.state) {
|
switch (pipe.data.state) {
|
||||||
case 'online':
|
case 'online':
|
||||||
this.onReady();
|
this.onReady();
|
||||||
console.log('Zammad Chat: ready');
|
this.log('debug', 'Zammad Chat: ready');
|
||||||
break;
|
break;
|
||||||
case 'offline':
|
case 'offline':
|
||||||
console.log('Zammad Chat: No agent online');
|
this.log('debug', 'Zammad Chat: No agent online');
|
||||||
break;
|
break;
|
||||||
case 'chat_disabled':
|
case 'chat_disabled':
|
||||||
console.log('Zammad Chat: Chat is disabled');
|
this.log('debug', 'Zammad Chat: Chat is disabled');
|
||||||
break;
|
break;
|
||||||
case 'no_seats_available':
|
case 'no_seats_available':
|
||||||
console.log('Zammad Chat: Too many clients in queue. Clients in queue: ', pipe.data.queue);
|
this.log('debug', 'Zammad Chat: Too many clients in queue. Clients in queue: ', pipe.data.queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,7 +365,7 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.onOpenAnimationEnd = function() {
|
ZammadChat.prototype.onOpenAnimationEnd = function() {
|
||||||
return this.connect();
|
return this.session_init();
|
||||||
};
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.close = function(event) {
|
ZammadChat.prototype.close = function(event) {
|
||||||
|
@ -297,7 +382,10 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
ZammadChat.prototype.onCloseAnimationEnd = function() {
|
ZammadChat.prototype.onCloseAnimationEnd = function() {
|
||||||
this.el.removeClass('zammad-chat-is-open');
|
this.el.removeClass('zammad-chat-is-open');
|
||||||
this.disconnect();
|
this.disconnect();
|
||||||
return this.isOpen = false;
|
this.isOpen = false;
|
||||||
|
return this.send('chat_session_close', {
|
||||||
|
session_id: this.session_id
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.hide = function() {
|
ZammadChat.prototype.hide = function() {
|
||||||
|
@ -311,8 +399,18 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
return this.el.css('bottom', -remainerHeight);
|
return this.el.css('bottom', -remainerHeight);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ZammadChat.prototype.disableInput = function() {
|
||||||
|
this.el.find('.zammad-chat-input').prop('disabled', true);
|
||||||
|
return this.el.find('.zammad-chat-send').prop('disabled', true);
|
||||||
|
};
|
||||||
|
|
||||||
|
ZammadChat.prototype.enableInput = function() {
|
||||||
|
this.el.find('.zammad-chat-input').prop('disabled', false);
|
||||||
|
return this.el.find('.zammad-chat-send').prop('disabled', false);
|
||||||
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.onQueue = function(position) {
|
ZammadChat.prototype.onQueue = function(position) {
|
||||||
console.log("onQueue", position);
|
this.log('notice', 'onQueue', position);
|
||||||
this.inQueue = true;
|
this.inQueue = true;
|
||||||
return this.el.find('.zammad-chat-body').html(this.view('waiting')({
|
return this.el.find('.zammad-chat-body').html(this.view('waiting')({
|
||||||
position: position
|
position: position
|
||||||
|
@ -371,14 +469,45 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
return this.el.find('.zammad-chat-body').scrollTop($('.zammad-chat-body').prop('scrollHeight'));
|
return this.el.find('.zammad-chat-body').scrollTop($('.zammad-chat-body').prop('scrollHeight'));
|
||||||
};
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.connect = function() {
|
ZammadChat.prototype.session_init = function() {
|
||||||
return this.send('chat_session_init');
|
return this.send('chat_session_init');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ZammadChat.prototype.connect = function() {
|
||||||
|
this.log('notice', "Connecting to " + this.host);
|
||||||
|
this.ws = new window.WebSocket(this.host);
|
||||||
|
this.ws.onopen = (function(_this) {
|
||||||
|
return function() {
|
||||||
|
_this.log('debug', 'ws connected');
|
||||||
|
_this.send('chat_status_customer');
|
||||||
|
return _this.setAgentOnlineState(true);
|
||||||
|
};
|
||||||
|
})(this);
|
||||||
|
this.ws.onmessage = this.onWebSocketMessage;
|
||||||
|
this.ws.onclose = (function(_this) {
|
||||||
|
return function(e) {
|
||||||
|
_this.log('debug', 'close websocket connection');
|
||||||
|
_this.reconnect();
|
||||||
|
return _this.setAgentOnlineState(false);
|
||||||
|
};
|
||||||
|
})(this);
|
||||||
|
return this.ws.onerror = (function(_this) {
|
||||||
|
return function(e) {
|
||||||
|
return _this.log('debug', 'ws:onerror', e);
|
||||||
|
};
|
||||||
|
})(this);
|
||||||
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.reconnect = function() {
|
ZammadChat.prototype.reconnect = function() {
|
||||||
|
this.log('notice', 'reconnecting');
|
||||||
|
this.disableInput();
|
||||||
this.lastAddedType = 'status';
|
this.lastAddedType = 'status';
|
||||||
this.el.find('.zammad-chat-agent-status').attr('data-status', 'connecting').text(this.T('Connecting'));
|
this.el.find('.zammad-chat-agent-status').attr('data-status', 'connecting').text(this.T('Reconnecting'));
|
||||||
return this.addStatus(this.T('Connection lost'));
|
this.addStatus(this.T('Connection lost'));
|
||||||
|
if (this.reconnectDelayId) {
|
||||||
|
clearTimeout(this.reconnectDelayId);
|
||||||
|
}
|
||||||
|
return this.reconnectDelayId = setTimeout(this.connect, 5000);
|
||||||
};
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.onConnectionReestablished = function() {
|
ZammadChat.prototype.onConnectionReestablished = function() {
|
||||||
|
@ -387,6 +516,11 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
return this.addStatus(this.T('Connection re-established'));
|
return this.addStatus(this.T('Connection re-established'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ZammadChat.prototype.onSessionClosed = function(data) {
|
||||||
|
this.addStatus(this.T('Chat closed by %s', data.realname));
|
||||||
|
return this.disableInput();
|
||||||
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.disconnect = function() {
|
ZammadChat.prototype.disconnect = function() {
|
||||||
this.showLoader();
|
this.showLoader();
|
||||||
this.el.find('.zammad-chat-welcome').removeClass('zammad-chat-is-hidden');
|
this.el.find('.zammad-chat-welcome').removeClass('zammad-chat-is-hidden');
|
||||||
|
@ -400,6 +534,7 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
this.el.find('.zammad-chat-agent').html(this.view('agent')({
|
this.el.find('.zammad-chat-agent').html(this.view('agent')({
|
||||||
agent: agent
|
agent: agent
|
||||||
}));
|
}));
|
||||||
|
this.enableInput();
|
||||||
this.el.find('.zammad-chat-body').empty();
|
this.el.find('.zammad-chat-body').empty();
|
||||||
this.el.find('.zammad-chat-welcome').addClass('zammad-chat-is-hidden');
|
this.el.find('.zammad-chat-welcome').addClass('zammad-chat-is-hidden');
|
||||||
this.el.find('.zammad-chat-agent').removeClass('zammad-chat-is-hidden');
|
this.el.find('.zammad-chat-agent').removeClass('zammad-chat-is-hidden');
|
||||||
|
@ -501,71 +636,6 @@ jQuery.fn.autoGrow = function(options) {
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
if (!window.zammadChatTemplates) {
|
|
||||||
window.zammadChatTemplates = {};
|
|
||||||
}
|
|
||||||
window.zammadChatTemplates["agent"] = function (__obj) {
|
|
||||||
if (!__obj) __obj = {};
|
|
||||||
var __out = [], __capture = function(callback) {
|
|
||||||
var out = __out, result;
|
|
||||||
__out = [];
|
|
||||||
callback.call(this);
|
|
||||||
result = __out.join('');
|
|
||||||
__out = out;
|
|
||||||
return __safe(result);
|
|
||||||
}, __sanitize = function(value) {
|
|
||||||
if (value && value.ecoSafe) {
|
|
||||||
return value;
|
|
||||||
} else if (typeof value !== 'undefined' && value != null) {
|
|
||||||
return __escape(value);
|
|
||||||
} else {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
|
|
||||||
__safe = __obj.safe = function(value) {
|
|
||||||
if (value && value.ecoSafe) {
|
|
||||||
return value;
|
|
||||||
} else {
|
|
||||||
if (!(typeof value !== 'undefined' && value != null)) value = '';
|
|
||||||
var result = new String(value);
|
|
||||||
result.ecoSafe = true;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (!__escape) {
|
|
||||||
__escape = __obj.escape = function(value) {
|
|
||||||
return ('' + value)
|
|
||||||
.replace(/&/g, '&')
|
|
||||||
.replace(/</g, '<')
|
|
||||||
.replace(/>/g, '>')
|
|
||||||
.replace(/"/g, '"');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
(function() {
|
|
||||||
(function() {
|
|
||||||
if (this.agent.avatar) {
|
|
||||||
__out.push('\n<img class="zammad-chat-agent-avatar" src="');
|
|
||||||
__out.push(__sanitize(this.agent.avatar));
|
|
||||||
__out.push('">\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
__out.push('\n<span class="zammad-chat-agent-sentence">\n <span class="zammad-chat-agent-name">');
|
|
||||||
|
|
||||||
__out.push(__sanitize(this.agent.name));
|
|
||||||
|
|
||||||
__out.push('</span> ');
|
|
||||||
|
|
||||||
__out.push(this.agentPhrase);
|
|
||||||
|
|
||||||
__out.push('\n</span>');
|
|
||||||
|
|
||||||
}).call(this);
|
|
||||||
|
|
||||||
}).call(__obj);
|
|
||||||
__obj.safe = __objSafe, __obj.escape = __escape;
|
|
||||||
return __out.join('');
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!window.zammadChatTemplates) {
|
if (!window.zammadChatTemplates) {
|
||||||
window.zammadChatTemplates = {};
|
window.zammadChatTemplates = {};
|
||||||
}
|
}
|
||||||
|
@ -608,11 +678,19 @@ window.zammadChatTemplates["chat"] = function (__obj) {
|
||||||
}
|
}
|
||||||
(function() {
|
(function() {
|
||||||
(function() {
|
(function() {
|
||||||
__out.push('<div class="zammad-chat">\n <div class="zammad-chat-header js-chat-open">\n <div class="zammad-chat-header-controls">\n <span class="zammad-chat-agent-status zammad-chat-is-hidden" data-status="online">Online</span>\n <span class="zammad-chat-header-icon">\n <svg class="zammad-chat-header-icon-open" viewBox="0 0 13 7"><path d="M10.807 7l1.4-1.428-5-4.9L6.5-.02l-.7.7-4.9 4.9 1.414 1.413L6.5 2.886 10.807 7z" fill-rule="evenodd"/></svg>\n <svg class="zammad-chat-header-icon-close js-chat-close" viewBox="0 0 13 13"><path d="m2.241.12l-2.121 2.121 4.243 4.243-4.243 4.243 2.121 2.121 4.243-4.243 4.243 4.243 2.121-2.121-4.243-4.243 4.243-4.243-2.121-2.121-4.243 4.243-4.243-4.243" fill-rule="evenodd"/></svg>\n </span>\n </div>\n <div class="zammad-chat-agent zammad-chat-is-hidden">\n \n </div>\n <div class="zammad-chat-welcome">\n <svg class="zammad-chat-icon" viewBox="0 0 24 24"><path d="M2 5C2 4 3 3 4 3h16c1 0 2 1 2 2v10C22 16 21 17 20 17H4C3 17 2 16 2 15V5zM12 17l6 4v-4h-6z" fill-rule="evenodd"/></svg>\n <span class="zammad-chat-welcome-text">');
|
__out.push('<div class="zammad-chat">\n <div class="zammad-chat-header js-chat-open">\n <div class="zammad-chat-header-controls">\n <span class="zammad-chat-agent-status zammad-chat-is-hidden" data-status="online">Online</span>\n <span class="zammad-chat-header-icon">\n <svg class="zammad-chat-header-icon-open" viewBox="0 0 13 7"><path d="M10.807 7l1.4-1.428-5-4.9L6.5-.02l-.7.7-4.9 4.9 1.414 1.413L6.5 2.886 10.807 7z" fill-rule="evenodd"/></svg>\n <svg class="zammad-chat-header-icon-close js-chat-close" viewBox="0 0 13 13"><path d="m2.241.12l-2.121 2.121 4.243 4.243-4.243 4.243 2.121 2.121 4.243-4.243 4.243 4.243 2.121-2.121-4.243-4.243 4.243-4.243-2.121-2.121-4.243 4.243-4.243-4.243" fill-rule="evenodd"/></svg>\n </span>\n </div>\n <div class="zammad-chat-agent zammad-chat-is-hidden">\n </div>\n <div class="zammad-chat-welcome">\n <svg class="zammad-chat-icon" viewBox="0 0 24 24"><path d="M2 5C2 4 3 3 4 3h16c1 0 2 1 2 2v10C22 16 21 17 20 17H4C3 17 2 16 2 15V5zM12 17l6 4v-4h-6z" fill-rule="evenodd"/></svg>\n <span class="zammad-chat-welcome-text">');
|
||||||
|
|
||||||
__out.push(this.invitationPhrase);
|
__out.push(this.invitationPhrase);
|
||||||
|
|
||||||
__out.push('</span>\n </div>\n </div>\n <div class="zammad-chat-body"></div>\n <form class="zammad-chat-controls">\n <textarea class="zammad-chat-input" rows="1" placeholder="Compose your message..."></textarea>\n <button type="submit" class="zammad-chat-send">Send</button>\n </form>\n</div>');
|
__out.push('</span>\n </div>\n </div>\n <div class="zammad-chat-body"></div>\n <form class="zammad-chat-controls">\n <textarea class="zammad-chat-input" rows="1" placeholder="');
|
||||||
|
|
||||||
|
__out.push(this.T('Compose your message...'));
|
||||||
|
|
||||||
|
__out.push('"></textarea>\n <button type="submit" class="zammad-chat-send">');
|
||||||
|
|
||||||
|
__out.push(this.T('Send'));
|
||||||
|
|
||||||
|
__out.push('</button>\n </form>\n</div>');
|
||||||
|
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|
||||||
|
@ -887,11 +965,15 @@ window.zammadChatTemplates["waiting"] = function (__obj) {
|
||||||
}
|
}
|
||||||
(function() {
|
(function() {
|
||||||
(function() {
|
(function() {
|
||||||
__out.push('<div class="zammad-chat-modal">\n <div class="zammad-chat-modal-text">\n <span class="zammad-chat-loading-animation">\n <span class="zammad-chat-loading-circle"></span>\n <span class="zammad-chat-loading-circle"></span>\n <span class="zammad-chat-loading-circle"></span>\n </span>\n Leider sind gerade alle Mitarbeiter belegt.<br>\n Warteliste-Position: <strong>');
|
__out.push('<div class="zammad-chat-modal">\n <div class="zammad-chat-modal-text">\n <span class="zammad-chat-loading-animation">\n <span class="zammad-chat-loading-circle"></span>\n <span class="zammad-chat-loading-circle"></span>\n <span class="zammad-chat-loading-circle"></span>\n </span>\n ');
|
||||||
|
|
||||||
__out.push(__sanitize(this.position));
|
__out.push(this.T('All colleges are busy.'));
|
||||||
|
|
||||||
__out.push('</strong>\n </div>\n</div>');
|
__out.push('<br>\n ');
|
||||||
|
|
||||||
|
__out.push(this.T('You are on waiting list position <strong>%s</strong>.', this.position));
|
||||||
|
|
||||||
|
__out.push('\n </div>\n</div>');
|
||||||
|
|
||||||
}).call(this);
|
}).call(this);
|
||||||
|
|
||||||
|
|
2
public/assets/chat/chat.min.js
vendored
2
public/assets/chat/chat.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -8,7 +8,6 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="zammad-chat-agent zammad-chat-is-hidden">
|
<div class="zammad-chat-agent zammad-chat-is-hidden">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="zammad-chat-welcome">
|
<div class="zammad-chat-welcome">
|
||||||
<svg class="zammad-chat-icon" viewBox="0 0 24 24"><path d="M2 5C2 4 3 3 4 3h16c1 0 2 1 2 2v10C22 16 21 17 20 17H4C3 17 2 16 2 15V5zM12 17l6 4v-4h-6z" fill-rule="evenodd"/></svg>
|
<svg class="zammad-chat-icon" viewBox="0 0 24 24"><path d="M2 5C2 4 3 3 4 3h16c1 0 2 1 2 2v10C22 16 21 17 20 17H4C3 17 2 16 2 15V5zM12 17l6 4v-4h-6z" fill-rule="evenodd"/></svg>
|
||||||
|
@ -17,7 +16,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="zammad-chat-body"></div>
|
<div class="zammad-chat-body"></div>
|
||||||
<form class="zammad-chat-controls">
|
<form class="zammad-chat-controls">
|
||||||
<textarea class="zammad-chat-input" rows="1" placeholder="Compose your message..."></textarea>
|
<textarea class="zammad-chat-input" rows="1" placeholder="<%- @T('Compose your message...') %>"></textarea>
|
||||||
<button type="submit" class="zammad-chat-send">Send</button>
|
<button type="submit" class="zammad-chat-send"><%- @T('Send') %></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
|
@ -5,7 +5,7 @@
|
||||||
<span class="zammad-chat-loading-circle"></span>
|
<span class="zammad-chat-loading-circle"></span>
|
||||||
<span class="zammad-chat-loading-circle"></span>
|
<span class="zammad-chat-loading-circle"></span>
|
||||||
</span>
|
</span>
|
||||||
Leider sind gerade alle Mitarbeiter belegt.<br>
|
<%- @T('All colleges are busy.') %><br>
|
||||||
Warteliste-Position: <strong><%= @position %></strong>
|
<%- @T('You are on waiting list position <strong>%s</strong>.', @position) %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
Loading…
Reference in a new issue