chat client: fix reconnect ui, simpler theming
This commit is contained in:
parent
0d692cb7ed
commit
543c27a0bc
12 changed files with 227 additions and 202 deletions
|
@ -8,13 +8,12 @@ do($ = window.jQuery, window) ->
|
||||||
class ZammadChat
|
class ZammadChat
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
invitationPhrase: '<strong>Chat</strong> with us!'
|
|
||||||
agentPhrase: ' is helping you'
|
|
||||||
show: true
|
show: true
|
||||||
target: $('body')
|
target: $('body')
|
||||||
host: ''
|
host: ''
|
||||||
port: 6042
|
port: 6042
|
||||||
debug: false
|
debug: false
|
||||||
|
buttonSelector: '.open-zammad-chat'
|
||||||
|
|
||||||
_messageCount: 0
|
_messageCount: 0
|
||||||
isOpen: true
|
isOpen: true
|
||||||
|
@ -25,14 +24,15 @@ do($ = window.jQuery, window) ->
|
||||||
lastAddedType: null
|
lastAddedType: null
|
||||||
inputTimeout: null
|
inputTimeout: null
|
||||||
isTyping: false
|
isTyping: false
|
||||||
isOnline: true
|
state: 'offline'
|
||||||
initialQueueDelay: 10000
|
initialQueueDelay: 10000
|
||||||
wsReconnectEnable: true
|
wsReconnectEnable: true
|
||||||
strings:
|
strings:
|
||||||
|
'<strong>Chat</strong> with us!': '<strong>Chatten</strong> sie mit uns!'
|
||||||
'Online': 'Online'
|
'Online': 'Online'
|
||||||
'Offline': 'Offline'
|
'Offline': 'Offline'
|
||||||
'Connecting': 'Verbinden'
|
'Connecting': 'Verbinden'
|
||||||
'Connection re-established': 'Connection re-established'
|
'Connection re-established': 'Verbindung wiederhergestellt'
|
||||||
'Today': 'Heute'
|
'Today': 'Heute'
|
||||||
'Send': 'Senden'
|
'Send': 'Senden'
|
||||||
'Compose your message...': 'Ihre Nachricht...'
|
'Compose your message...': 'Ihre Nachricht...'
|
||||||
|
@ -64,6 +64,8 @@ do($ = window.jQuery, window) ->
|
||||||
options = {}
|
options = {}
|
||||||
|
|
||||||
options.T = @T
|
options.T = @T
|
||||||
|
options.background = @options.background
|
||||||
|
options.flat = @options.flat
|
||||||
return window.zammadChatTemplates[name](options)
|
return window.zammadChatTemplates[name](options)
|
||||||
|
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
|
@ -74,18 +76,20 @@ do($ = window.jQuery, window) ->
|
||||||
return
|
return
|
||||||
|
|
||||||
@options = $.extend {}, @defaults, options
|
@options = $.extend {}, @defaults, options
|
||||||
@el = $(@view('chat')(@options))
|
@el = $(@view('chat')())
|
||||||
@options.target.append @el
|
@options.target.append @el
|
||||||
|
|
||||||
@input = @el.find('.zammad-chat-input')
|
@input = @el.find('.zammad-chat-input')
|
||||||
|
|
||||||
@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
|
||||||
@input.on
|
@input.on
|
||||||
keydown: @checkForEnter
|
keydown: @checkForEnter
|
||||||
input: @onInput
|
input: @onInput
|
||||||
|
|
||||||
|
$(@options.buttonSelector).click @open
|
||||||
|
|
||||||
@wsConnect()
|
@wsConnect()
|
||||||
|
|
||||||
checkForEnter: (event) =>
|
checkForEnter: (event) =>
|
||||||
|
@ -127,13 +131,13 @@ do($ = window.jQuery, window) ->
|
||||||
@onReady()
|
@onReady()
|
||||||
@log 'debug', 'Zammad Chat: ready'
|
@log 'debug', 'Zammad Chat: ready'
|
||||||
when 'offline'
|
when 'offline'
|
||||||
@log 'debug', 'Zammad Chat: No agent online'
|
@onError 'Zammad Chat: No agent online'
|
||||||
@wsClose()
|
@wsClose()
|
||||||
when 'chat_disabled'
|
when 'chat_disabled'
|
||||||
@log 'debug', 'Zammad Chat: Chat is disabled'
|
@onError 'Zammad Chat: Chat is disabled'
|
||||||
@wsClose()
|
@wsClose()
|
||||||
when 'no_seats_available'
|
when 'no_seats_available'
|
||||||
@log 'debug', 'Zammad Chat: Too many clients in queue. Clients in queue: ', pipe.data.queue
|
@onError 'Zammad Chat: Too many clients in queue. Clients in queue: ', pipe.data.queue
|
||||||
@wsClose()
|
@wsClose()
|
||||||
when 'reconnect'
|
when 'reconnect'
|
||||||
@log 'debug', 'old messages', pipe.data.session
|
@log 'debug', 'old messages', pipe.data.session
|
||||||
|
@ -143,6 +147,10 @@ do($ = window.jQuery, window) ->
|
||||||
if @options.show
|
if @options.show
|
||||||
@show()
|
@show()
|
||||||
|
|
||||||
|
onError: (message) =>
|
||||||
|
@log 'debug', message
|
||||||
|
$(@options.buttonSelector).hide()
|
||||||
|
|
||||||
reopenSession: (data) =>
|
reopenSession: (data) =>
|
||||||
unfinishedMessage = sessionStorage.getItem 'unfinished_message'
|
unfinishedMessage = sessionStorage.getItem 'unfinished_message'
|
||||||
|
|
||||||
|
@ -421,7 +429,6 @@ do($ = window.jQuery, window) ->
|
||||||
@log 'debug', 'close websocket connection'
|
@log 'debug', 'close websocket connection'
|
||||||
if @wsReconnectEnable
|
if @wsReconnectEnable
|
||||||
@reconnect()
|
@reconnect()
|
||||||
@setAgentOnlineState(false)
|
|
||||||
|
|
||||||
@ws.onerror = (e) =>
|
@ws.onerror = (e) =>
|
||||||
@log 'debug', 'ws:onerror', e
|
@log 'debug', 'ws:onerror', e
|
||||||
|
@ -442,21 +449,21 @@ do($ = window.jQuery, window) ->
|
||||||
@send 'chat_status_customer',
|
@send 'chat_status_customer',
|
||||||
session_id: @sessionId
|
session_id: @sessionId
|
||||||
|
|
||||||
@setAgentOnlineState(true)
|
@setAgentOnlineState 'online'
|
||||||
|
|
||||||
reconnect: =>
|
reconnect: =>
|
||||||
# set status to connecting
|
# set status to connecting
|
||||||
@log 'notice', 'reconnecting'
|
@log 'notice', 'reconnecting'
|
||||||
@disableInput()
|
@disableInput()
|
||||||
@lastAddedType = 'status'
|
@lastAddedType = 'status'
|
||||||
@el.find('.zammad-chat-agent-status').attr('data-status', 'connecting').text @T('Reconnecting')
|
@setAgentOnlineState 'connecting'
|
||||||
@addStatus @T('Connection lost')
|
@addStatus @T('Connection lost')
|
||||||
@wsReconnect()
|
@wsReconnect()
|
||||||
|
|
||||||
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')
|
@setAgentOnlineState 'online'
|
||||||
@addStatus @T('Connection re-established')
|
@addStatus @T('Connection re-established')
|
||||||
|
|
||||||
onSessionClosed: (data) ->
|
onSessionClosed: (data) ->
|
||||||
|
@ -508,10 +515,11 @@ do($ = window.jQuery, window) ->
|
||||||
@el.find('.zammad-chat-body').html @view('loader')()
|
@el.find('.zammad-chat-body').html @view('loader')()
|
||||||
|
|
||||||
setAgentOnlineState: (state) =>
|
setAgentOnlineState: (state) =>
|
||||||
@isOnline = state
|
@state = state
|
||||||
|
capitalizedState = state.charAt(0).toUpperCase() + state.slice(1)
|
||||||
@el
|
@el
|
||||||
.find('.zammad-chat-agent-status')
|
.find('.zammad-chat-agent-status')
|
||||||
.toggleClass('zammad-chat-is-online', state)
|
.attr('data-status', state)
|
||||||
.text if state then @T('Online') else @T('Offline')
|
.text @T(capitalizedState)
|
||||||
|
|
||||||
window.ZammadChat = ZammadChat
|
window.ZammadChat = ZammadChat
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
background: #379ad7;
|
background: #379ad7;
|
||||||
color: white;
|
color: white;
|
||||||
line-height: 2.5em;
|
line-height: 2.5em;
|
||||||
box-shadow: 0 -1px #247fb7, 0 1px rgba(255, 255, 255, 0.3) inset, 0 -1px #247fb7 inset, 0 1px 1px rgba(0, 0, 0, 0.13);
|
box-shadow: 0 -1px rgba(0, 0, 0, 0.1), 0 1px rgba(255, 255, 255, 0.3) inset, 0 -1px rgba(0, 0, 0, 0.1) inset, 0 1px 1px rgba(0, 0, 0, 0.13);
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 5px 5px 0 0;
|
border-radius: 5px 5px 0 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -89,8 +89,8 @@
|
||||||
line-height: 2em;
|
line-height: 2em;
|
||||||
padding: 0 0.7em;
|
padding: 0 0.7em;
|
||||||
border-radius: 1em;
|
border-radius: 1em;
|
||||||
background: #288ecc;
|
background: rgba(0, 0, 0, 0.1);
|
||||||
box-shadow: 0 0 0 1px #2582bb; }
|
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.04); }
|
||||||
|
|
||||||
.zammad-chat-agent-status:before {
|
.zammad-chat-agent-status:before {
|
||||||
content: "";
|
content: "";
|
||||||
|
@ -101,7 +101,8 @@
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-right: 0.3em;
|
margin-right: 0.3em;
|
||||||
box-shadow: 0 0 0 1px #2582bb; }
|
vertical-align: middle;
|
||||||
|
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.04); }
|
||||||
|
|
||||||
.zammad-chat-agent-status[data-status="online"]:before {
|
.zammad-chat-agent-status[data-status="online"]:before {
|
||||||
background: #52c782; }
|
background: #52c782; }
|
||||||
|
@ -185,7 +186,7 @@
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
border-radius: 1em;
|
border-radius: 1em;
|
||||||
background: #f6f8f9;
|
background: #ededed;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
max-width: 70%;
|
max-width: 70%;
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
|
@ -223,7 +224,7 @@
|
||||||
display: inline-block; }
|
display: inline-block; }
|
||||||
|
|
||||||
.zammad-chat-loading-circle {
|
.zammad-chat-loading-circle {
|
||||||
background: #c5dded;
|
background: #d9d9d9;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
height: 0.72em;
|
height: 0.72em;
|
||||||
width: 0.72em;
|
width: 0.72em;
|
||||||
|
@ -267,7 +268,7 @@
|
||||||
-webkit-align-items: flex-start;
|
-webkit-align-items: flex-start;
|
||||||
-ms-flex-align: start;
|
-ms-flex-align: start;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
border-top: 1px solid #e3f0f7;
|
border-top: 1px solid #ededed;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 1.4em;
|
line-height: 1.4em;
|
||||||
box-shadow: 0 1px rgba(0, 0, 0, 0.01), 0 -1px rgba(0, 0, 0, 0.02);
|
box-shadow: 0 1px rgba(0, 0, 0, 0.01), 0 -1px rgba(0, 0, 0, 0.02);
|
||||||
|
@ -294,7 +295,7 @@
|
||||||
max-height: 6em; }
|
max-height: 6em; }
|
||||||
|
|
||||||
.zammad-chat-input::-webkit-input-placeholder {
|
.zammad-chat-input::-webkit-input-placeholder {
|
||||||
color: #bdc9d0; }
|
color: #d9d9d9; }
|
||||||
|
|
||||||
.zammad-chat-button {
|
.zammad-chat-button {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
|
@ -309,7 +310,7 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 1.5em;
|
border-radius: 1.5em;
|
||||||
box-shadow: 0 2px rgba(255, 255, 255, 0.25) inset, 0 0 0 1px #247fb7 inset, 0 1px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px rgba(255, 255, 255, 0.25) inset, 0 0 0 1px rgba(0, 0, 0, 0.1) inset, 0 1px rgba(0, 0, 0, 0.1);
|
||||||
outline: none;
|
outline: none;
|
||||||
display: inline-block; }
|
display: inline-block; }
|
||||||
|
|
||||||
|
@ -332,10 +333,10 @@
|
||||||
border: none; }
|
border: none; }
|
||||||
|
|
||||||
.zammad-chat--flat .zammad-chat-header {
|
.zammad-chat--flat .zammad-chat-header {
|
||||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.13); }
|
box-shadow: none; }
|
||||||
|
|
||||||
.zammad-chat--flat .zammad-chat-message-body {
|
.zammad-chat--flat .zammad-chat-message-body {
|
||||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08) inset; }
|
box-shadow: none; }
|
||||||
|
|
||||||
.zammad-chat--flat .zammad-chat-agent-status,
|
.zammad-chat--flat .zammad-chat-agent-status,
|
||||||
.zammad-chat--flat .zammad-chat-button,
|
.zammad-chat--flat .zammad-chat-button,
|
||||||
|
|
|
@ -1,3 +1,64 @@
|
||||||
|
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>\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); }; },
|
var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
||||||
slice = [].slice;
|
slice = [].slice;
|
||||||
|
|
||||||
|
@ -8,17 +69,17 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
scriptHost = myScript.src.match(".*://([^:/]*).*")[1];
|
scriptHost = myScript.src.match(".*://([^:/]*).*")[1];
|
||||||
ZammadChat = (function() {
|
ZammadChat = (function() {
|
||||||
ZammadChat.prototype.defaults = {
|
ZammadChat.prototype.defaults = {
|
||||||
invitationPhrase: '<strong>Chat</strong> with us!',
|
show: true,
|
||||||
agentPhrase: ' is helping you',
|
|
||||||
show: false,
|
|
||||||
target: $('body'),
|
target: $('body'),
|
||||||
host: '',
|
host: '',
|
||||||
port: 6042
|
port: 6042,
|
||||||
|
debug: false,
|
||||||
|
buttonSelector: '.open-zammad-chat'
|
||||||
};
|
};
|
||||||
|
|
||||||
ZammadChat.prototype._messageCount = 0;
|
ZammadChat.prototype._messageCount = 0;
|
||||||
|
|
||||||
ZammadChat.prototype.isOpen = false;
|
ZammadChat.prototype.isOpen = true;
|
||||||
|
|
||||||
ZammadChat.prototype.blinkOnlineInterval = null;
|
ZammadChat.prototype.blinkOnlineInterval = null;
|
||||||
|
|
||||||
|
@ -34,19 +95,18 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
|
|
||||||
ZammadChat.prototype.isTyping = false;
|
ZammadChat.prototype.isTyping = false;
|
||||||
|
|
||||||
ZammadChat.prototype.isOnline = true;
|
ZammadChat.prototype.state = 'offline';
|
||||||
|
|
||||||
ZammadChat.prototype.initialQueueDelay = 10000;
|
ZammadChat.prototype.initialQueueDelay = 10000;
|
||||||
|
|
||||||
ZammadChat.prototype.debug = true;
|
|
||||||
|
|
||||||
ZammadChat.prototype.wsReconnectEnable = true;
|
ZammadChat.prototype.wsReconnectEnable = true;
|
||||||
|
|
||||||
ZammadChat.prototype.strings = {
|
ZammadChat.prototype.strings = {
|
||||||
|
'<strong>Chat</strong> with us!': '<strong>Chatten</strong> sie mit uns!',
|
||||||
'Online': 'Online',
|
'Online': 'Online',
|
||||||
'Offline': 'Offline',
|
'Offline': 'Offline',
|
||||||
'Connecting': 'Verbinden',
|
'Connecting': 'Verbinden',
|
||||||
'Connection re-established': 'Connection re-established',
|
'Connection re-established': 'Verbindung wiederhergestellt',
|
||||||
'Today': 'Heute',
|
'Today': 'Heute',
|
||||||
'Send': 'Senden',
|
'Send': 'Senden',
|
||||||
'Compose your message...': 'Ihre Nachricht...',
|
'Compose your message...': 'Ihre Nachricht...',
|
||||||
|
@ -78,7 +138,7 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
ZammadChat.prototype.log = function() {
|
ZammadChat.prototype.log = function() {
|
||||||
var level, string;
|
var level, string;
|
||||||
level = arguments[0], string = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
level = arguments[0], string = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
||||||
if (!this.debug && level === 'debug') {
|
if (!this.options.debug && level === 'debug') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
string.unshift(level);
|
string.unshift(level);
|
||||||
|
@ -92,6 +152,8 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
options.T = _this.T;
|
options.T = _this.T;
|
||||||
|
options.background = _this.options.background;
|
||||||
|
options.flat = _this.options.flat;
|
||||||
return window.zammadChatTemplates[name](options);
|
return window.zammadChatTemplates[name](options);
|
||||||
};
|
};
|
||||||
})(this);
|
})(this);
|
||||||
|
@ -122,6 +184,7 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
this.onTypingEnd = bind(this.onTypingEnd, this);
|
this.onTypingEnd = bind(this.onTypingEnd, this);
|
||||||
this.onInput = bind(this.onInput, this);
|
this.onInput = bind(this.onInput, this);
|
||||||
this.reopenSession = bind(this.reopenSession, this);
|
this.reopenSession = bind(this.reopenSession, this);
|
||||||
|
this.onError = bind(this.onError, this);
|
||||||
this.onReady = bind(this.onReady, this);
|
this.onReady = bind(this.onReady, this);
|
||||||
this.onWebSocketMessage = bind(this.onWebSocketMessage, this);
|
this.onWebSocketMessage = bind(this.onWebSocketMessage, this);
|
||||||
this.send = bind(this.send, this);
|
this.send = bind(this.send, this);
|
||||||
|
@ -129,25 +192,22 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
this.view = bind(this.view, this);
|
this.view = bind(this.view, this);
|
||||||
this.log = bind(this.log, this);
|
this.log = bind(this.log, this);
|
||||||
this.T = bind(this.T, this);
|
this.T = bind(this.T, this);
|
||||||
|
if (!window.WebSocket || !sessionStorage) {
|
||||||
|
this.log('notice', 'Chat: Browser not supported!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
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.target.append(this.el);
|
this.options.target.append(this.el);
|
||||||
this.input = this.el.find('.zammad-chat-input');
|
this.input = this.el.find('.zammad-chat-input');
|
||||||
this.el.find('.js-chat-open').click((function(_this) {
|
this.el.find('.js-chat-open').click(this.open);
|
||||||
return function() {
|
|
||||||
return _this.open();
|
|
||||||
};
|
|
||||||
})(this));
|
|
||||||
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);
|
||||||
this.input.on({
|
this.input.on({
|
||||||
keydown: this.checkForEnter,
|
keydown: this.checkForEnter,
|
||||||
input: this.onInput
|
input: this.onInput
|
||||||
});
|
});
|
||||||
if (!window.WebSocket || !sessionStorage) {
|
$(this.options.buttonSelector).click(this.open);
|
||||||
this.log('notice', 'Chat: Browser not supported!');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.wsConnect();
|
this.wsConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,15 +267,15 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
this.log('debug', 'Zammad Chat: ready');
|
this.log('debug', 'Zammad Chat: ready');
|
||||||
break;
|
break;
|
||||||
case 'offline':
|
case 'offline':
|
||||||
this.log('debug', 'Zammad Chat: No agent online');
|
this.onError('Zammad Chat: No agent online');
|
||||||
this.wsClose();
|
this.wsClose();
|
||||||
break;
|
break;
|
||||||
case 'chat_disabled':
|
case 'chat_disabled':
|
||||||
this.log('debug', 'Zammad Chat: Chat is disabled');
|
this.onError('Zammad Chat: Chat is disabled');
|
||||||
this.wsClose();
|
this.wsClose();
|
||||||
break;
|
break;
|
||||||
case 'no_seats_available':
|
case 'no_seats_available':
|
||||||
this.log('debug', 'Zammad Chat: Too many clients in queue. Clients in queue: ', pipe.data.queue);
|
this.onError('Zammad Chat: Too many clients in queue. Clients in queue: ', pipe.data.queue);
|
||||||
this.wsClose();
|
this.wsClose();
|
||||||
break;
|
break;
|
||||||
case 'reconnect':
|
case 'reconnect':
|
||||||
|
@ -232,9 +292,15 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ZammadChat.prototype.onError = function(message) {
|
||||||
|
this.log('debug', message);
|
||||||
|
return $(this.options.buttonSelector).hide();
|
||||||
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.reopenSession = function(data) {
|
ZammadChat.prototype.reopenSession = function(data) {
|
||||||
var i, len, message, ref, unfinishedMessage;
|
var i, len, message, ref, unfinishedMessage;
|
||||||
unfinishedMessage = sessionStorage.getItem('unfinished_message');
|
unfinishedMessage = sessionStorage.getItem('unfinished_message');
|
||||||
|
if (data.agent) {
|
||||||
this.onConnectionEstablished(data);
|
this.onConnectionEstablished(data);
|
||||||
ref = data.session;
|
ref = data.session;
|
||||||
for (i = 0, len = ref.length; i < len; i++) {
|
for (i = 0, len = ref.length; i < len; i++) {
|
||||||
|
@ -248,6 +314,10 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
if (unfinishedMessage) {
|
if (unfinishedMessage) {
|
||||||
this.input.val(unfinishedMessage);
|
this.input.val(unfinishedMessage);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (data.position) {
|
||||||
|
this.onQueue(data);
|
||||||
|
}
|
||||||
this.show();
|
this.show();
|
||||||
this.open();
|
this.open();
|
||||||
this.scrollToBottom();
|
this.scrollToBottom();
|
||||||
|
@ -518,9 +588,8 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
return function(e) {
|
return function(e) {
|
||||||
_this.log('debug', 'close websocket connection');
|
_this.log('debug', 'close websocket connection');
|
||||||
if (_this.wsReconnectEnable) {
|
if (_this.wsReconnectEnable) {
|
||||||
_this.reconnect();
|
return _this.reconnect();
|
||||||
}
|
}
|
||||||
return _this.setAgentOnlineState(false);
|
|
||||||
};
|
};
|
||||||
})(this);
|
})(this);
|
||||||
return this.ws.onerror = (function(_this) {
|
return this.ws.onerror = (function(_this) {
|
||||||
|
@ -548,21 +617,21 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
this.send('chat_status_customer', {
|
this.send('chat_status_customer', {
|
||||||
session_id: this.sessionId
|
session_id: this.sessionId
|
||||||
});
|
});
|
||||||
return this.setAgentOnlineState(true);
|
return this.setAgentOnlineState('online');
|
||||||
};
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.reconnect = function() {
|
ZammadChat.prototype.reconnect = function() {
|
||||||
this.log('notice', 'reconnecting');
|
this.log('notice', 'reconnecting');
|
||||||
this.disableInput();
|
this.disableInput();
|
||||||
this.lastAddedType = 'status';
|
this.lastAddedType = 'status';
|
||||||
this.el.find('.zammad-chat-agent-status').attr('data-status', 'connecting').text(this.T('Reconnecting'));
|
this.setAgentOnlineState('connecting');
|
||||||
this.addStatus(this.T('Connection lost'));
|
this.addStatus(this.T('Connection lost'));
|
||||||
return this.wsReconnect();
|
return this.wsReconnect();
|
||||||
};
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.onConnectionReestablished = function() {
|
ZammadChat.prototype.onConnectionReestablished = function() {
|
||||||
this.lastAddedType = 'status';
|
this.lastAddedType = 'status';
|
||||||
this.el.find('.zammad-chat-agent-status').attr('data-status', 'online').text(this.T('Online'));
|
this.setAgentOnlineState('online');
|
||||||
return this.addStatus(this.T('Connection re-established'));
|
return this.addStatus(this.T('Connection re-established'));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -622,8 +691,10 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
ZammadChat.prototype.setAgentOnlineState = function(state) {
|
ZammadChat.prototype.setAgentOnlineState = function(state) {
|
||||||
this.isOnline = state;
|
var capitalizedState;
|
||||||
return this.el.find('.zammad-chat-agent-status').toggleClass('zammad-chat-is-online', state).text(state ? this.T('Online') : this.T('Offline'));
|
this.state = state;
|
||||||
|
capitalizedState = state.charAt(0).toUpperCase() + state.slice(1);
|
||||||
|
return this.el.find('.zammad-chat-agent-status').attr('data-status', state).text(this.T(capitalizedState));
|
||||||
};
|
};
|
||||||
|
|
||||||
return ZammadChat;
|
return ZammadChat;
|
||||||
|
@ -632,71 +703,6 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||||
return window.ZammadChat = ZammadChat;
|
return window.ZammadChat = ZammadChat;
|
||||||
})(window.jQuery, window);
|
})(window.jQuery, window);
|
||||||
|
|
||||||
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('');
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||||
|
@ -816,15 +822,33 @@ 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 </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');
|
||||||
|
|
||||||
__out.push(this.invitationPhrase);
|
if (this.flat) {
|
||||||
|
__out.push(__sanitize(' zammad-chat--flat'));
|
||||||
|
}
|
||||||
|
|
||||||
|
__out.push('">\n <div class="zammad-chat-header js-chat-open"');
|
||||||
|
|
||||||
|
if (this.background) {
|
||||||
|
__out.push(__sanitize(" style='background: " + this.background + "'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
__out.push('>\n <div class="zammad-chat-header-controls">\n <span class="zammad-chat-agent-status zammad-chat-is-hidden" data-status="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.T('<strong>Chat</strong> with us!'));
|
||||||
|
|
||||||
__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('</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(this.T('Compose your message...'));
|
||||||
|
|
||||||
__out.push('"></textarea>\n <button type="submit" class="zammad-chat-button zammad-chat-send">');
|
__out.push('"></textarea>\n <button type="submit" class="zammad-chat-button zammad-chat-send"');
|
||||||
|
|
||||||
|
if (this.background) {
|
||||||
|
__out.push(__sanitize(" style='background: " + this.background + "'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
__out.push('>');
|
||||||
|
|
||||||
__out.push(this.T('Send'));
|
__out.push(this.T('Send'));
|
||||||
|
|
||||||
|
@ -938,7 +962,13 @@ window.zammadChatTemplates["message"] = function (__obj) {
|
||||||
|
|
||||||
__out.push(__sanitize(this.from));
|
__out.push(__sanitize(this.from));
|
||||||
|
|
||||||
__out.push('">\n <span class="zammad-chat-message-body">');
|
__out.push('">\n <span class="zammad-chat-message-body"');
|
||||||
|
|
||||||
|
if (this.background && this.from === 'customer') {
|
||||||
|
__out.push(__sanitize(" style='background: " + this.background + "'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
__out.push('>');
|
||||||
|
|
||||||
__out.push(this.message);
|
__out.push(this.message);
|
||||||
|
|
||||||
|
@ -1052,7 +1082,13 @@ window.zammadChatTemplates["timeout"] = function (__obj) {
|
||||||
|
|
||||||
__out.push(this.T('Since you didn\'t respond in the last %s your conversation with <strong>%s</strong> got closed.', this.delay + " " + this.unit, this.agent));
|
__out.push(this.T('Since you didn\'t respond in the last %s your conversation with <strong>%s</strong> got closed.', this.delay + " " + this.unit, this.agent));
|
||||||
|
|
||||||
__out.push('<br>\n <div class="zammad-chat-button">');
|
__out.push('<br>\n <div class="zammad-chat-button"');
|
||||||
|
|
||||||
|
if (this.background) {
|
||||||
|
__out.push(__sanitize(" style='background: " + this.background + "'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
__out.push('>');
|
||||||
|
|
||||||
__out.push(__sanitize(this.T('Start new conversation')));
|
__out.push(__sanitize(this.T('Start new conversation')));
|
||||||
|
|
||||||
|
|
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
|
@ -1,43 +1,12 @@
|
||||||
/// Returns the luminance of `$color` as a float (between 0 and 1)
|
|
||||||
/// 1 is pure white, 0 is pure black
|
|
||||||
/// @param {Color} $color - Color
|
|
||||||
/// @return {Number}
|
|
||||||
/// @link http://stackoverflow.com/a/596241/731172
|
|
||||||
@function luminance($color) {
|
|
||||||
@return (0.375 * red($color) + 0.5 * green($color) + 0.125 * blue($color)) / 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Limits the lighten function to a maximum value
|
|
||||||
/// @param {Color} $color - Color
|
|
||||||
/// @param {Number} $amount - The amount to increase the lightness by, between 0% and 100%
|
|
||||||
/// @param {Number} $max - The maximal lightness amount
|
|
||||||
/// @return {Color}
|
|
||||||
@function lightenMax($color, $amount, $max) {
|
|
||||||
$enlightedColor: lighten($color, $amount);
|
|
||||||
@if lightness($enlightedColor) > $max {
|
|
||||||
@return change-color($color, $lightness: $max);
|
|
||||||
} @else {
|
|
||||||
@return $enlightedColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$themeColor: hsl(203,67,53);
|
|
||||||
$fontSize: 12px;
|
|
||||||
$borderRadius: 5px;
|
|
||||||
|
|
||||||
$luminance: luminance($themeColor);
|
|
||||||
$contrastTextColor: if($luminance > 0.5, inherit, white);
|
|
||||||
$baseTextColor: if($luminance < 0.2, white, black);
|
|
||||||
|
|
||||||
.zammad-chat {
|
.zammad-chat {
|
||||||
color: $baseTextColor;
|
color: black;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 30px;
|
right: 30px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
font-size: $fontSize;
|
font-size: 12px;
|
||||||
width: 33em;
|
width: 33em;
|
||||||
box-shadow: 0 3px 10px rgba(0,0,0,.3);
|
box-shadow: 0 3px 10px rgba(0,0,0,.3);
|
||||||
border-radius: $borderRadius $borderRadius 0 0;
|
border-radius: 5px 5px 0 0;
|
||||||
will-change: bottom;
|
will-change: bottom;
|
||||||
display: none;
|
display: none;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -56,16 +25,16 @@ $baseTextColor: if($luminance < 0.2, white, black);
|
||||||
|
|
||||||
.zammad-chat-header {
|
.zammad-chat-header {
|
||||||
padding: 0.5em 2.5em 0.5em 1em;
|
padding: 0.5em 2.5em 0.5em 1em;
|
||||||
background: $themeColor;
|
background: hsl(203,67%,53%);
|
||||||
color: $contrastTextColor;
|
color: white;
|
||||||
line-height: 2.5em;
|
line-height: 2.5em;
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 -1px darken($themeColor, 10%),
|
0 -1px rgba(0,0,0,.1),
|
||||||
0 1px rgba(255,255,255,.3) inset,
|
0 1px rgba(255,255,255,.3) inset,
|
||||||
0 -1px darken($themeColor, 10%) inset,
|
0 -1px rgba(0,0,0,.1) inset,
|
||||||
0 1px 1px rgba(0,0,0,.13);
|
0 1px 1px rgba(0,0,0,.13);
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: $borderRadius $borderRadius 0 0;
|
border-radius: 5px 5px 0 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
@ -134,8 +103,8 @@ $baseTextColor: if($luminance < 0.2, white, black);
|
||||||
line-height: 2em;
|
line-height: 2em;
|
||||||
padding: 0 .7em;
|
padding: 0 .7em;
|
||||||
border-radius: 1em;
|
border-radius: 1em;
|
||||||
background: darken($themeColor, 5%);
|
background: rgba(0,0,0,.1);
|
||||||
box-shadow: 0 0 0 1px darken($themeColor, 9%);
|
box-shadow: 0 0 0 1px rgba(0,0,0,.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
.zammad-chat-agent-status:before {
|
.zammad-chat-agent-status:before {
|
||||||
|
@ -147,7 +116,8 @@ $baseTextColor: if($luminance < 0.2, white, black);
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-right: 0.3em;
|
margin-right: 0.3em;
|
||||||
box-shadow: 0 0 0 1px darken($themeColor, 9%);
|
vertical-align: middle;
|
||||||
|
box-shadow: 0 0 0 1px rgba(0,0,0,.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
.zammad-chat-agent-status[data-status="online"]:before {
|
.zammad-chat-agent-status[data-status="online"]:before {
|
||||||
|
@ -222,7 +192,7 @@ $baseTextColor: if($luminance < 0.2, white, black);
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
border-radius: 1em;
|
border-radius: 1em;
|
||||||
background: desaturate(lightenMax($themeColor, 50%, 97%), 50%);
|
background: hsl(0,0%,93%);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
max-width: 70%;
|
max-width: 70%;
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
|
@ -252,8 +222,8 @@ $baseTextColor: if($luminance < 0.2, white, black);
|
||||||
}
|
}
|
||||||
|
|
||||||
.zammad-chat-message--customer .zammad-chat-message-body {
|
.zammad-chat-message--customer .zammad-chat-message-body {
|
||||||
background: $themeColor;
|
background: hsl(203,67%,53%);
|
||||||
color: $contrastTextColor;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zammad-chat-message--unread {
|
.zammad-chat-message--unread {
|
||||||
|
@ -269,7 +239,7 @@ $baseTextColor: if($luminance < 0.2, white, black);
|
||||||
}
|
}
|
||||||
|
|
||||||
.zammad-chat-loading-circle {
|
.zammad-chat-loading-circle {
|
||||||
background: desaturate(lightenMax($themeColor, 50%, 85%), 15%);
|
background: hsl(0,0%, 85%);
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
height: 0.72em;
|
height: 0.72em;
|
||||||
width: 0.72em;
|
width: 0.72em;
|
||||||
|
@ -294,7 +264,7 @@ $baseTextColor: if($luminance < 0.2, white, black);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
border-top: 1px solid desaturate(lightenMax($themeColor, 80%, 93%), 10%);
|
border-top: 1px solid hsl(0,0%,93%);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 1.4em;
|
line-height: 1.4em;
|
||||||
box-shadow:
|
box-shadow:
|
||||||
|
@ -321,15 +291,15 @@ $baseTextColor: if($luminance < 0.2, white, black);
|
||||||
}
|
}
|
||||||
|
|
||||||
.zammad-chat-input::-webkit-input-placeholder {
|
.zammad-chat-input::-webkit-input-placeholder {
|
||||||
color: desaturate(lightenMax($themeColor, 25%, 85%), 50%);
|
color: hsl(0,0%,85%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.zammad-chat-button {
|
.zammad-chat-button {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
background: $themeColor;
|
background: hsl(203,67%,53%);
|
||||||
color: $contrastTextColor;
|
color: white;
|
||||||
padding: 0.6em 1.2em;
|
padding: 0.6em 1.2em;
|
||||||
margin: 0.5em 1em 0.5em;
|
margin: 0.5em 1em 0.5em;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -337,7 +307,7 @@ $baseTextColor: if($luminance < 0.2, white, black);
|
||||||
border-radius: 1.5em;
|
border-radius: 1.5em;
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 2px rgba(255,255,255,.25) inset,
|
0 2px rgba(255,255,255,.25) inset,
|
||||||
0 0 0 1px darken($themeColor, 10%) inset,
|
0 0 0 1px rgba(0,0,0,.1) inset,
|
||||||
0 1px rgba(0,0,0,.1);
|
0 1px rgba(0,0,0,.1);
|
||||||
outline: none;
|
outline: none;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -366,10 +336,10 @@ $baseTextColor: if($luminance < 0.2, white, black);
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
.zammad-chat--flat .zammad-chat-header {
|
.zammad-chat--flat .zammad-chat-header {
|
||||||
box-shadow: 0 1px 1px rgba(0,0,0,.13);
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
.zammad-chat--flat .zammad-chat-message-body {
|
.zammad-chat--flat .zammad-chat-message-body {
|
||||||
box-shadow: 0 0 0 1px rgba(0,0,0,.08) inset;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
.zammad-chat--flat .zammad-chat-agent-status,
|
.zammad-chat--flat .zammad-chat-agent-status,
|
||||||
.zammad-chat--flat .zammad-chat-button,
|
.zammad-chat--flat .zammad-chat-button,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Zammad Chat</title>
|
<title>Zammad Chat</title>
|
||||||
<link rel="stylesheet" href="chat.css">
|
<link rel="stylesheet" href="chat.css">
|
||||||
|
<link rel="stylesheet" href="znuny.css">
|
||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width">
|
||||||
<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35738/livereload.js?snipver=1"></' + 'script>')</script>
|
<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35738/livereload.js?snipver=1"></' + 'script>')</script>
|
||||||
<style>
|
<style>
|
||||||
|
@ -65,7 +66,7 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<img class="mockup" width="100%" src="website.png">
|
<img class="mockup" width="100%" src="znuny.png">
|
||||||
|
|
||||||
<div class="settings">
|
<div class="settings">
|
||||||
<table>
|
<table>
|
||||||
|
@ -94,6 +95,9 @@
|
||||||
<input type="number" value="12" min="11" max="18" data-option="fontSize">px
|
<input type="number" value="12" min="11" max="18" data-option="fontSize">px
|
||||||
<td>
|
<td>
|
||||||
<label for="fontSize">Font Size</label>
|
<label for="fontSize">Font Size</label>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<td><button class="open-zammad-chat">Open Chat</button>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -137,7 +141,10 @@
|
||||||
var chat = new ZammadChat({
|
var chat = new ZammadChat({
|
||||||
host: 'ws://localhost',
|
host: 'ws://localhost',
|
||||||
port: 6042,
|
port: 6042,
|
||||||
debug: true
|
debug: true,
|
||||||
|
background: '#494d52',
|
||||||
|
flat: true,
|
||||||
|
show: false
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.settings :input').on({
|
$('.settings :input').on({
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
<img class="zammad-chat-agent-avatar" src="<%= @agent.avatar %>">
|
<img class="zammad-chat-agent-avatar" src="<%= @agent.avatar %>">
|
||||||
<% end %>
|
<% end %>
|
||||||
<span class="zammad-chat-agent-sentence">
|
<span class="zammad-chat-agent-sentence">
|
||||||
<span class="zammad-chat-agent-name"><%= @agent.name %></span> <%- @agentPhrase %>
|
<span class="zammad-chat-agent-name"><%= @agent.name %></span>
|
||||||
</span>
|
</span>
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="zammad-chat">
|
<div class="zammad-chat<%= ' zammad-chat--flat' if @flat %>">
|
||||||
<div class="zammad-chat-header js-chat-open">
|
<div class="zammad-chat-header js-chat-open"<%= " style='background: #{ @background }'" if @background %>>
|
||||||
<div class="zammad-chat-header-controls">
|
<div class="zammad-chat-header-controls">
|
||||||
<span class="zammad-chat-agent-status zammad-chat-is-hidden" data-status="online">Online</span>
|
<span class="zammad-chat-agent-status zammad-chat-is-hidden" data-status="online"></span>
|
||||||
<span class="zammad-chat-header-icon">
|
<span class="zammad-chat-header-icon">
|
||||||
<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>
|
<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>
|
||||||
<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>
|
<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>
|
||||||
|
@ -11,12 +11,12 @@
|
||||||
</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>
|
||||||
<span class="zammad-chat-welcome-text"><%- @invitationPhrase %></span>
|
<span class="zammad-chat-welcome-text"><%- @T('<strong>Chat</strong> with us!') %></span>
|
||||||
</div>
|
</div>
|
||||||
</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="<%- @T('Compose your message...') %>"></textarea>
|
<textarea class="zammad-chat-input" rows="1" placeholder="<%- @T('Compose your message...') %>"></textarea>
|
||||||
<button type="submit" class="zammad-chat-button zammad-chat-send"><%- @T('Send') %></button>
|
<button type="submit" class="zammad-chat-button zammad-chat-send"<%= " style='background: #{ @background }'" if @background %>><%- @T('Send') %></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
|
@ -1,3 +1,3 @@
|
||||||
<div class="zammad-chat-message zammad-chat-message--<%= @from %>">
|
<div class="zammad-chat-message zammad-chat-message--<%= @from %>">
|
||||||
<span class="zammad-chat-message-body"><%- @message %></span>
|
<span class="zammad-chat-message-body"<%= " style='background: #{ @background }'" if @background and @from is 'customer' %>><%- @message %></span>
|
||||||
</div>
|
</div>
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="zammad-chat-modal">
|
<div class="zammad-chat-modal">
|
||||||
<div class="zammad-chat-modal-text">
|
<div class="zammad-chat-modal-text">
|
||||||
<%- @T('Since you didn\'t respond in the last %s your conversation with <strong>%s</strong> got closed.', "#{ @delay } #{ @unit }", @agent) %><br>
|
<%- @T('Since you didn\'t respond in the last %s your conversation with <strong>%s</strong> got closed.', "#{ @delay } #{ @unit }", @agent) %><br>
|
||||||
<div class="zammad-chat-button"><%= @T('Start new conversation') %></div>
|
<div class="zammad-chat-button"<%= " style='background: #{ @background }'" if @background %>><%= @T('Start new conversation') %></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
3
public/assets/chat/znuny.css
Normal file
3
public/assets/chat/znuny.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.help {
|
||||||
|
background: hsl(213,6%,30%);
|
||||||
|
}
|
BIN
public/assets/chat/znuny.png
Normal file
BIN
public/assets/chat/znuny.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 453 KiB |
Loading…
Reference in a new issue