Use domain of users email address for preview. Added css auto load and css Url support. Added possibility to translation chat widget.

This commit is contained in:
Martin Edenhofer 2015-11-25 17:36:06 +01:00
parent 7a231a0121
commit 069063b2c7
8 changed files with 284 additions and 187 deletions

View file

@ -30,10 +30,10 @@ class App.ChannelChat extends App.Controller
apiOptions: [ apiOptions: [
{ {
name: 'channel' name: 'chatId'
default: "'default'" default: '1'
type: 'String' type: 'Integer'
description: 'Name of the chat-channel.' description: 'Identifier of the chat-topic.'
} }
{ {
name: 'show' name: 'show'
@ -54,18 +54,18 @@ class App.ChannelChat extends App.Controller
description: "If left empty, the host gets auto-detected - in this case %s. The auto-detection reads out the host from the <script> tag. If you don't include it via a <script> tag you need to specify the host." description: "If left empty, the host gets auto-detected - in this case %s. The auto-detection reads out the host from the <script> tag. If you don't include it via a <script> tag you need to specify the host."
descriptionSubstitute: window.location.origin descriptionSubstitute: window.location.origin
} }
{
name: 'port'
default: 6042
type: 'Int'
description: ''
}
{ {
name: 'debug' name: 'debug'
default: false default: false
type: 'Boolean' type: 'Boolean'
description: 'Enables console logging.' description: 'Enables console logging.'
} }
{
name: 'title'
default: "'<strong>Chat</strong> with us!'"
type: 'String'
description: 'Welcome Title shown on the closed chat. Can contain HTML.'
}
{ {
name: 'fontSize' name: 'fontSize'
default: 'undefined' default: 'undefined'
@ -91,18 +91,29 @@ class App.ChannelChat extends App.Controller
description: 'This class gets added to the button on initialization and gets removed once the chat connection got established.' description: 'This class gets added to the button on initialization and gets removed once the chat connection got established.'
} }
{ {
name: 'title' name: 'cssAutoload'
default: "'<strong>Chat</strong> with us!'" default: 'true'
type: 'boolean'
description: 'Automatically loads the chat.css file. If you want to use your own css, just set it to false.'
}
{
name: 'cssUrl'
default: 'undefined'
type: 'String' type: 'String'
description: 'Welcome Title shown on the closed chat. Can contain HTML.' description: 'Location of an external chat.css file.'
} }
] ]
isOpen: true isOpen: true
browserWidth: 1280 browserWidth: 1280
previewUrl: ''
constructor: -> constructor: ->
super super
if @Session.get('email')
@previewUrl = "www.#{@Session.get('email').replace(/^.+?\@/, '')}"
@load() @load()
@widgetDesignerPermanentParams = @widgetDesignerPermanentParams =
@ -133,6 +144,7 @@ class App.ChannelChat extends App.Controller
baseurl: window.location.origin baseurl: window.location.origin
chats: chats chats: chats
apiOptions: @apiOptions apiOptions: @apiOptions
previewUrl: @previewUrl
) )
@code.each (i, block) -> @code.each (i, block) ->
@ -222,7 +234,7 @@ class App.ChannelChat extends App.Controller
renderDemoWebsite: (data) => renderDemoWebsite: (data) =>
imageSource = data['data_url'] imageSource = data['data_url']
if imageSource if imageSource
@screenshot.attr 'src', imageSource @screenshot.attr 'src', imageSource
@iframe.attr('src', '') @iframe.attr('src', '')
@website.attr('data-mode', 'screenshot') @website.attr('data-mode', 'screenshot')
@ -236,7 +248,7 @@ class App.ChannelChat extends App.Controller
palette = _.map palette, tinycolor palette = _.map palette, tinycolor
# filter white # filter white
palette = _.filter palette, (color) => palette = _.filter palette, (color) ->
color.getLuminance() < 0.85 color.getLuminance() < 0.85
htmlString = '' htmlString = ''
@ -347,4 +359,4 @@ class App.ChannelChat extends App.Controller
@paramsBlock.each (i, block) -> @paramsBlock.each (i, block) ->
hljs.highlightBlock block hljs.highlightBlock block
App.Config.set( 'Chat Widget', { prio: 4000, name: 'Chat Widget', parent: '#channels', target: '#channels/chat', controller: App.ChannelChat, role: ['Admin'] }, 'NavBarAdmin' ) App.Config.set( 'Chat', { prio: 4000, name: 'Chat', parent: '#channels', target: '#channels/chat', controller: App.ChannelChat, role: ['Admin'] }, 'NavBarAdmin' )

View file

@ -11,6 +11,7 @@
<table class="settings-list"> <table class="settings-list">
<thead> <thead>
<tr> <tr>
<th style="white-space: nowrap;"><%- @T('chatId') %></th>
<th style="white-space: nowrap;"><%- @T('Name') %></th> <th style="white-space: nowrap;"><%- @T('Name') %></th>
<th style="white-space: nowrap;"><%- @T('Note') %></th> <th style="white-space: nowrap;"><%- @T('Note') %></th>
<th style="white-space: nowrap;"><%- @T('Max. clients in waitlist') %></th> <th style="white-space: nowrap;"><%- @T('Max. clients in waitlist') %></th>
@ -20,6 +21,10 @@
<tbody> <tbody>
<% for chat in @chats: %> <% for chat in @chats: %>
<tr data-id="<%= chat.id %>"> <tr data-id="<%= chat.id %>">
<td>
<label class="inline-label">
<%= chat.id %>
</label>
<td> <td>
<label class="inline-label"> <label class="inline-label">
<a class="js-edit is-clickable"><%= chat.name %></a> <a class="js-edit is-clickable"><%= chat.name %></a>
@ -40,7 +45,7 @@
</div> </div>
<% end %> <% end %>
<tr> <tr>
<td colspan="4" class="settings-list-action-cell js-add"> <td colspan="5" class="settings-list-action-cell js-add">
<%- @Icon('plus-small') %> <%- @T('Add') %> <%- @Icon('plus-small') %> <%- @T('Add') %>
</tbody> </tbody>
</table> </table>
@ -62,7 +67,7 @@
<div class="browser chat-demo js-browser"> <div class="browser chat-demo js-browser">
<form class="browser-head js-demo-head" novalidate> <form class="browser-head js-demo-head" novalidate>
<div class="browser-input"> <div class="browser-input">
<input type="url" class="js-testurl-input" id="preview-iframe" placeholder="zammad.org"> <input type="url" class="js-testurl-input" id="preview-iframe" value="<%= @previewUrl %>" placeholder="www.zammad.org">
<div class="loading icon small muted"></div> <div class="loading icon small muted"></div>
</div> </div>
<input type="submit" class="btn" value="<%- @T('Load') %>"> <input type="submit" class="btn" value="<%- @T('Load') %>">

View file

@ -14,6 +14,9 @@ do($ = window.jQuery, window) ->
host: '' host: ''
debug: false debug: false
flat: false flat: false
lang: undefined,
cssAutoload: true,
cssUrl: undefined,
fontSize: undefined fontSize: undefined
buttonClass: 'open-zammad-chat' buttonClass: 'open-zammad-chat'
inactiveClass: 'is-inactive' inactiveClass: 'is-inactive'
@ -31,30 +34,37 @@ do($ = window.jQuery, window) ->
state: 'offline' state: 'offline'
initialQueueDelay: 10000 initialQueueDelay: 10000
wsReconnectEnable: true wsReconnectEnable: true
strings: translations:
'Online': 'Online' de:
'Offline': 'Offline' '<strong>Chat</strong> with us!': '<strong>Chat</strong> mit uns!'
'Connecting': 'Verbinden' 'Online': 'Online'
'Connection re-established': 'Verbindung wiederhergestellt' 'Online': 'Online'
'Today': 'Heute' 'Offline': 'Offline'
'Send': 'Senden' 'Connecting': 'Verbinden'
'Compose your message...': 'Ihre Nachricht...' 'Connection re-established': 'Verbindung wiederhergestellt'
'All colleges are busy.': 'Alle Kollegen sind belegt.' 'Today': 'Heute'
'You are on waiting list position <strong>%s</strong>.': 'Sie sind in der Warteliste an der Position <strong>%s</strong>.' 'Send': 'Senden'
'Start new conversation': 'Neue Konversation starten' 'Compose your message...': 'Ihre Nachricht...'
'Since you didn\'t respond in the last %s your conversation with <strong>%s</strong> got closed.': 'Da sie in den letzten %s nichts geschrieben haben wurde ihre Konversation mit <strong>%s</strong> geschlossen.' 'All colleges are busy.': 'Alle Kollegen sind belegt.'
'minutes': 'Minuten' 'You are on waiting list position <strong>%s</strong>.': 'Sie sind in der Warteliste an der Position <strong>%s</strong>.'
'Start new conversation': 'Neue Konversation starten'
'Since you didn\'t respond in the last %s your conversation with <strong>%s</strong> got closed.': 'Da sie in den letzten %s nichts geschrieben haben wurde ihre Konversation mit <strong>%s</strong> geschlossen.'
'minutes': 'Minuten'
sessionId: undefined sessionId: undefined
T: (string, items...) => T: (string, items...) =>
if !@strings[string] if @options.lang && @options.lang isnt 'en'
@log 'notice', "Translation needed for '#{string}'" if !@translations[@options.lang]
translation = @strings[string] || string @log 'notice', "Translation '#{@options.lang}' needed!"
else
translations = @translations[@options.lang]
if !translations[string]
@log 'notice', "Translation needed for '#{string}'"
string = translations[string] || string
if items if items
for item in items for item in items
translation = translation.replace(/%s/, item) string = string.replace(/%s/, item)
string
translation
log: (level, string...) => log: (level, string...) =>
return if !@options.debug && level is 'debug' return if !@options.debug && level is 'debug'
@ -80,12 +90,18 @@ do($ = window.jQuery, window) ->
@state = 'unsupported' @state = 'unsupported'
@log 'notice', 'Chat: Browser not supported!' @log 'notice', 'Chat: Browser not supported!'
return return
if !@options.chatId if !@options.chatId
@state = 'unsupported' @state = 'unsupported'
@log 'error', 'Chat: need chatId as option!' @log 'error', 'Chat: need chatId as option!'
return return
# detect language
if !@options.lang
@options.lang = $('html').attr('lang')
if @options.lang
@options.lang = @options.lang.replace(/-.+?$/, '') # replace "-xx" of xx-xx
@log 'debug', "lang: #{@options.lang}"
@el = $(@view('chat')( @el = $(@view('chat')(
title: @options.title title: @options.title
)) ))
@ -105,6 +121,8 @@ do($ = window.jQuery, window) ->
@wsConnect() @wsConnect()
@loadCss()
checkForEnter: (event) => checkForEnter: (event) =>
if not event.shiftKey and event.keyCode is 13 if not event.shiftKey and event.keyCode is 13
event.preventDefault() event.preventDefault()
@ -548,4 +566,21 @@ do($ = window.jQuery, window) ->
.attr('data-status', state) .attr('data-status', state)
.text @T(capitalizedState) .text @T(capitalizedState)
loadCss: ->
return if !@options.cssAutoload
url = @options.cssUrl
if !url
url = @options.host
.replace(/^wss/i, 'https')
.replace(/^ws/i, 'http')
.replace(/\/ws/i, '')
url += '/assets/chat/chat.css'
@log 'debug', "load css from '#{url}'"
styles = "@import url('#{url}');"
newSS = document.createElement('link')
newSS.rel = 'stylesheet'
newSS.href = 'data:text/css,' + escape(styles)
document.getElementsByTagName('head')[0].appendChild(newSS)
window.ZammadChat = ZammadChat window.ZammadChat = ZammadChat

View file

@ -1,64 +1,3 @@
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, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
};
}
(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;
@ -75,6 +14,9 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
host: '', host: '',
debug: false, debug: false,
flat: false, flat: false,
lang: void 0,
cssAutoload: true,
cssUrl: void 0,
fontSize: void 0, fontSize: void 0,
buttonClass: 'open-zammad-chat', buttonClass: 'open-zammad-chat',
inactiveClass: 'is-inactive', inactiveClass: 'is-inactive',
@ -105,37 +47,48 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
ZammadChat.prototype.wsReconnectEnable = true; ZammadChat.prototype.wsReconnectEnable = true;
ZammadChat.prototype.strings = { ZammadChat.prototype.translations = {
'Online': 'Online', de: {
'Offline': 'Offline', '<strong>Chat</strong> with us!': '<strong>Chat</strong> mit uns!',
'Connecting': 'Verbinden', 'Online': 'Online',
'Connection re-established': 'Verbindung wiederhergestellt', 'Online': 'Online',
'Today': 'Heute', 'Offline': 'Offline',
'Send': 'Senden', 'Connecting': 'Verbinden',
'Compose your message...': 'Ihre Nachricht...', 'Connection re-established': 'Verbindung wiederhergestellt',
'All colleges are busy.': 'Alle Kollegen sind belegt.', 'Today': 'Heute',
'You are on waiting list position <strong>%s</strong>.': 'Sie sind in der Warteliste an der Position <strong>%s</strong>.', 'Send': 'Senden',
'Start new conversation': 'Neue Konversation starten', 'Compose your message...': 'Ihre Nachricht...',
'Since you didn\'t respond in the last %s your conversation with <strong>%s</strong> got closed.': 'Da sie in den letzten %s nichts geschrieben haben wurde ihre Konversation mit <strong>%s</strong> geschlossen.', 'All colleges are busy.': 'Alle Kollegen sind belegt.',
'minutes': 'Minuten' 'You are on waiting list position <strong>%s</strong>.': 'Sie sind in der Warteliste an der Position <strong>%s</strong>.',
'Start new conversation': 'Neue Konversation starten',
'Since you didn\'t respond in the last %s your conversation with <strong>%s</strong> got closed.': 'Da sie in den letzten %s nichts geschrieben haben wurde ihre Konversation mit <strong>%s</strong> geschlossen.',
'minutes': 'Minuten'
}
}; };
ZammadChat.prototype.sessionId = void 0; ZammadChat.prototype.sessionId = void 0;
ZammadChat.prototype.T = function() { ZammadChat.prototype.T = function() {
var i, item, items, len, string, translation; var i, item, items, len, string, translations;
string = arguments[0], items = 2 <= arguments.length ? slice.call(arguments, 1) : []; string = arguments[0], items = 2 <= arguments.length ? slice.call(arguments, 1) : [];
if (!this.strings[string]) { if (this.options.lang && this.options.lang !== 'en') {
this.log('notice', "Translation needed for '" + string + "'"); if (!this.translations[this.options.lang]) {
this.log('notice', "Translation '" + this.options.lang + "' needed!");
} else {
translations = this.translations[this.options.lang];
if (!translations[string]) {
this.log('notice', "Translation needed for '" + string + "'");
}
string = translations[string] || string;
}
} }
translation = this.strings[string] || string;
if (items) { if (items) {
for (i = 0, len = items.length; i < len; i++) { for (i = 0, len = items.length; i < len; i++) {
item = items[i]; item = items[i];
translation = translation.replace(/%s/, item); string = string.replace(/%s/, item);
} }
} }
return translation; return string;
}; };
ZammadChat.prototype.log = function() { ZammadChat.prototype.log = function() {
@ -205,6 +158,13 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
this.log('error', 'Chat: need chatId as option!'); this.log('error', 'Chat: need chatId as option!');
return; return;
} }
if (!this.options.lang) {
this.options.lang = $('html').attr('lang');
}
if (this.options.lang) {
this.options.lang = this.options.lang.replace(/-.+?$/, '');
this.log('debug', "lang: " + this.options.lang);
}
this.el = $(this.view('chat')({ this.el = $(this.view('chat')({
title: this.options.title title: this.options.title
})); }));
@ -219,6 +179,7 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
input: this.onInput input: this.onInput
}); });
this.wsConnect(); this.wsConnect();
this.loadCss();
} }
ZammadChat.prototype.checkForEnter = function(event) { ZammadChat.prototype.checkForEnter = function(event) {
@ -730,12 +691,91 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
return this.el.find('.zammad-chat-agent-status').attr('data-status', state).text(this.T(capitalizedState)); return this.el.find('.zammad-chat-agent-status').attr('data-status', state).text(this.T(capitalizedState));
}; };
ZammadChat.prototype.loadCss = function() {
var newSS, styles, url;
if (!this.options.cssAutoload) {
return;
}
url = this.options.cssUrl;
if (!url) {
url = this.options.host.replace(/^wss/i, 'https').replace(/^ws/i, 'http').replace(/\/ws/i, '');
url += '/assets/chat/chat.css';
}
this.log('debug', "load css from '" + url + "'");
styles = "@import url('" + url + "');";
newSS = document.createElement('link');
newSS.rel = 'stylesheet';
newSS.href = 'data:text/css,' + escape(styles);
return document.getElementsByTagName('head')[0].appendChild(newSS);
};
return ZammadChat; return ZammadChat;
})(); })();
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, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
};
}
(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('');
};
/*! /*!
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42): * "THE BEER-WARE LICENSE" (Revision 42):
@ -875,7 +915,7 @@ window.zammadChatTemplates["chat"] = function (__obj) {
__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('>\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.title); __out.push(this.T(this.title));
__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="');

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,6 @@
<!doctype html> <!doctype html>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Zammad Chat</title> <title>Zammad Chat</title>
<link rel="stylesheet" href="chat.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>
@ -140,6 +139,7 @@
var chat = new ZammadChat({ var chat = new ZammadChat({
chatId: 1, chatId: 1,
host: 'ws://localhost:6042', host: 'ws://localhost:6042',
cssUrl: 'http://localhost:3000/assets/chat/chat.css',
debug: true debug: true
}); });

View file

@ -11,7 +11,7 @@
</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"><%- @title %></span> <span class="zammad-chat-welcome-text"><%- @T(@title) %></span>
</div> </div>
</div> </div>
<div class="zammad-chat-body"></div> <div class="zammad-chat-body"></div>

View file

@ -1,71 +1,73 @@
<!doctype html> <!doctype html>
<meta charset="utf-8"> <html lang="de-de">
<title>Zammad Chat</title> <head>
<link rel="stylesheet" href="chat.css"> <meta charset="utf-8">
<link rel="stylesheet" href="znuny.css"> <title>Zammad Chat</title>
<meta name="viewport" content="width=device-width"> <link rel="stylesheet" href="znuny.css">
<script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35738/livereload.js?snipver=1"></' + 'script>')</script> <meta name="viewport" content="width=device-width">
<style> <script>document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + ':35738/livereload.js?snipver=1"></' + 'script>')</script>
body { <style>
margin: 0; body {
font-family: sans-serif; margin: 0;
} font-family: sans-serif;
.mockup {
vertical-align: bottom;
}
.settings {
position: fixed;
left: 20px;
top: 20px;
background: white;
font-size: 14px;
padding: 10px;
border-radius: 5px;
box-shadow: 0 3px 10px rgba(0,0,0,.3);
}
.settings input {
vertical-align: middle;
}
.settings input + input {
margin-right: 3px;
}
table td:first-child {
text-align: right;
padding-right: 0;
}
td {
padding: 5px;
}
h2 {
font-size: 1em;
margin: 0;
}
@media only screen and (max-width: 768px) {
.settings {
display: none;
} }
}
.Box { .mockup {
background: hsl(0,0%,91%); vertical-align: bottom;
width: 26px; }
height: 24px;
color: hsl(0,0%,47%);
float: left;
}
.Box.Active {
background: hsl(0,0%,36%);
color: white;
}
</style>
.settings {
position: fixed;
left: 20px;
top: 20px;
background: white;
font-size: 14px;
padding: 10px;
border-radius: 5px;
box-shadow: 0 3px 10px rgba(0,0,0,.3);
}
.settings input {
vertical-align: middle;
}
.settings input + input {
margin-right: 3px;
}
table td:first-child {
text-align: right;
padding-right: 0;
}
td {
padding: 5px;
}
h2 {
font-size: 1em;
margin: 0;
}
@media only screen and (max-width: 768px) {
.settings {
display: none;
}
}
.Box {
background: hsl(0,0%,91%);
width: 26px;
height: 24px;
color: hsl(0,0%,47%);
float: left;
}
.Box.Active {
background: hsl(0,0%,36%);
color: white;
}
</style>
</head>
<body>
<img class="mockup" width="100%" src="znuny.png"> <img class="mockup" width="100%" src="znuny.png">
<div class="settings"> <div class="settings">
@ -107,6 +109,7 @@
var chat = new ZammadChat({ var chat = new ZammadChat({
chatId: 1, chatId: 1,
host: 'ws://localhost:6042', host: 'ws://localhost:6042',
cssUrl: 'http://localhost:3000/assets/chat/chat.css',
debug: true, debug: true,
background: '#494d52', background: '#494d52',
flat: true, flat: true,
@ -144,4 +147,6 @@
} }
} }
}); });
</script> </script>
</body>
</html>