diff --git a/README.md b/README.md
index ee79efa..69cd5ed 100644
--- a/README.md
+++ b/README.md
@@ -50,6 +50,8 @@ To configure the chat, just use the object passed on IASChat instantiation. *Bol
- defaultSupportPic: String Default support picture (if no supporter assigned)
- uploadFiles: Boolean Enable or disable the option to upload and send files (Default: true)
- onlyPictures: Boolean Allow only pictures, or all file types (Default: true)
+ - onMessage: Function Execute a function on message recieved. Params message (all object) and key are passed to the function
+ - onSend: Function Execute a function when a message is sent. Params message (all object) and key are passed to the function
In IASChatProvider, there are some extra features:
- container: String Container for support panel (*#identifier* or *.className*. Default: *body*)
diff --git a/demo/index.html b/demo/index.html
index 0edf122..4954338 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -61,8 +61,22 @@
User side support
mainColor: '#ff9800',
textColor: '#fff',
defaultSupportName: 'John Doe',
- defaultSupportPic: 'http://lorempixel.com/100/100/people'
+ defaultSupportPic: 'http://lorempixel.com/100/100/people',
+ onMessage: myFunction,
+ onSend: function(msg, key) {
+ console.log('#################');
+ console.log('- Message sent! Key: ' + key);
+ console.log(msg)
+ console.log('#################');
+ }
});
+
+ function myFunction(message, key) {
+ console.log('--------------------');
+ console.log('- We got a message! key: ' + key);
+ console.log(message);
+ console.log('--------------------');
+ }
};
diff --git a/dist/chat.js b/dist/chat.js
index 371fa41..03504ea 100644
--- a/dist/chat.js
+++ b/dist/chat.js
@@ -21,12 +21,15 @@ function IASChat(config) {
var hashSign = config.hashSign || '?';
var uploadFiles = config.uploadFiles || true;
var onlyPictures = config.onlyPictures || true;
+ var onSend = config.onSend || null;
+ var onMessage = config.onMessage || null;
// Prepare interface
printInterface(container);
// Prepare listeners
var show = document.getElementById('ias-show');
+ var showNotifications = document.getElementById('ias-show-notifications');
var ias = document.getElementById('ias');
var topbar = document.getElementById('ias_topbar');
var close = document.getElementById('ias_topbar-close');
@@ -47,6 +50,10 @@ function IASChat(config) {
var lastHash = '';
var lastPage = '';
+ var user = null;
+ var lastMessage = {};
+
+
// Listen event submit
if(show) {
show.addEventListener('click', showIAS.bind(this));
@@ -83,7 +90,19 @@ function IASChat(config) {
name = config.name || '';
pic = config.pic || '';
- setChatData();
+ // Get chat info
+ userRef = firebase.database().ref('users/' + cid);
+ userRef.on('value', function(data) {
+
+ user = data.val();
+
+ lastMessage = user.lastMessage;
+ // console.log(lastMessage);
+
+ setChatData();
+ setNotifications();
+ });
+
clearMessages();
@@ -96,10 +115,7 @@ function IASChat(config) {
function setChatData() {
- userRef = firebase.database().ref('users/' + cid);
- userRef.on('value', function(data) {
- var key = data.key;
- var user = data.val();
+ if(user) {
var printData = {
name: defaultSupportName,
@@ -118,8 +134,9 @@ function IASChat(config) {
document.getElementById('ias_topbar-text').innerHTML = printData.name;
document.getElementById('ias_topbar-pic').firstChild.setAttribute('src', printData.pic);
- });
-
+ } else {
+ setTimeout(setChatData, 100);
+ }
}
@@ -131,11 +148,11 @@ function IASChat(config) {
// If shall show button, add it to interface (from html/show-button.html)
if(button) {
- ias += ''
+ ias += ''
}
// Also add the styles from css/style.css
- ias += '';
+ ias += '';
var printplace = null;
@@ -219,7 +236,7 @@ function IASChat(config) {
var text = e.srcElement.children[1].value
if(text === '' && attatchment === null) {
- console.log('tried to send empty form. Rejected.');
+ console.warn('tried to send empty form. Rejected.');
return false;
}
@@ -278,6 +295,10 @@ function IASChat(config) {
firebase.database().ref('messages/' + cid).push(msg);
firebase.database().ref('users/' + cid).once('value').then(function(snapshot) {
+
+ var userLastMsg = msg;
+ userLastMsg.read = false;
+
if(!snapshot.val()) {
// Add user
firebase.database().ref('users/' + cid).set({
@@ -285,10 +306,10 @@ function IASChat(config) {
pic: pic,
isSupporter: false,
supporter: -1,
- lastMessage: msg
+ lastMessage: userLastMsg
});
} else {
- firebase.database().ref('users/' + cid).update({lastMessage: msg});
+ firebase.database().ref('users/' + cid).update({lastMessage: userLastMsg});
if(!snapshot.val().profile) {
generateUserData(cid)
}
@@ -312,8 +333,44 @@ function IASChat(config) {
if(message.uid == uid) {
printMessage(text);
+ if(typeof onSend === 'function' && message.timestamp > lastMessage.timestamp) {
+ onSend(message, key);
+ }
} else {
printMessage(text, true);
+
+ // If chat is open, set the message as read
+ if(!isHidden()) {
+ readLastMessage();
+ }
+
+ if(typeof onMessage === 'function' && message.timestamp > lastMessage.timestamp) {
+ onMessage(message, key);
+ }
+ }
+ }
+
+ function readLastMessage() {
+ firebase.database().ref('users/' + cid + '/lastMessage').update({read: true});
+ }
+
+ function setNotifications() {
+
+ // Only set notifications if button are enabled
+ if(button) {
+ if(lastMessage.uid !== uid && !lastMessage.read) {
+ if (showNotifications.classList) {
+ showNotifications.classList.remove('hidden');
+ } else {
+ showNotifications.className = showNotifications.className.replace(new RegExp('(^|\\b)' + 'hidden'.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
+ }
+ } else {
+ if (showNotifications.classList) {
+ showNotifications.classList.add('hidden');
+ } else {
+ showNotifications.className += ' ' + 'hidden';
+ }
+ }
}
}
@@ -338,6 +395,9 @@ function IASChat(config) {
// Also set url hash to true;
addUrlHash();
+
+ // And read last message
+ readLastMessage();
}
function hideIAS(e) {
@@ -355,6 +415,20 @@ function IASChat(config) {
remUrlHash();
}
+ function isHidden(e) {
+ if(typeof(e) !== 'undefined') {
+ e.preventDefault();
+ }
+
+ var className = 'hidden';
+
+ if (ias.classList) {
+ return ias.classList.contains(className);
+ } else {
+ return new RegExp('(^| )' + className + '( |$)', 'gi').test(ias.className);
+ }
+ }
+
/* ### URL Hash ### */
function visibilityUrlHash() {
diff --git a/dist/provider.js b/dist/provider.js
index d60947e..ec7e684 100644
--- a/dist/provider.js
+++ b/dist/provider.js
@@ -49,7 +49,7 @@ function IASChatProvider(config) {
function printInterface(container) {
// Compressed version of html/chat.html turned to string
- var ias = ''
+ var ias = ''
// Also add the provider styles from css/provider-style.css
// ias += '';
@@ -101,10 +101,25 @@ function IASChatProvider(config) {
var supporter = data.supporter.uid || data.supporter;
+ var read = true;
+
+ if(typeof data.lastMessage !== 'undefined' && typeof data.lastMessage.read !== 'undefined' && !data.lastMessage.read) {
+ read = false;
+ }
+
var user = document.createElement('li');
user.setAttribute("data-cid", data.uid);
user.setAttribute("data-supporter", supporter);
+
+ if(read) {
user.innerHTML = '' + data.name + '
';
+ } else {
+ var message = data.lastMessage.text;
+ if(data.lastMessage.text.length > 20)
+ message = data.lastMessage.text.slice(0, 20) + '...';
+
+ user.innerHTML = '' + data.name + '
' + message + '
';
+ }
user.addEventListener('click', usersChatManagement, false);
diff --git a/js/chat.js b/js/chat.js
index ac0a7e1..a7f7c75 100644
--- a/js/chat.js
+++ b/js/chat.js
@@ -21,12 +21,15 @@ function IASChat(config) {
var hashSign = config.hashSign || '?';
var uploadFiles = config.uploadFiles || true;
var onlyPictures = config.onlyPictures || true;
+ var onSend = config.onSend || null;
+ var onMessage = config.onMessage || null;
// Prepare interface
printInterface(container);
// Prepare listeners
var show = document.getElementById('ias-show');
+ var showNotifications = document.getElementById('ias-show-notifications');
var ias = document.getElementById('ias');
var topbar = document.getElementById('ias_topbar');
var close = document.getElementById('ias_topbar-close');
@@ -47,6 +50,10 @@ function IASChat(config) {
var lastHash = '';
var lastPage = '';
+ var user = null;
+ var lastMessage = {};
+
+
// Listen event submit
if(show) {
show.addEventListener('click', showIAS.bind(this));
@@ -83,7 +90,19 @@ function IASChat(config) {
name = config.name || '';
pic = config.pic || '';
- setChatData();
+ // Get chat info
+ userRef = firebase.database().ref('users/' + cid);
+ userRef.on('value', function(data) {
+
+ user = data.val();
+
+ lastMessage = user.lastMessage;
+ // console.log(lastMessage);
+
+ setChatData();
+ setNotifications();
+ });
+
clearMessages();
@@ -96,10 +115,7 @@ function IASChat(config) {
function setChatData() {
- userRef = firebase.database().ref('users/' + cid);
- userRef.on('value', function(data) {
- var key = data.key;
- var user = data.val();
+ if(user) {
var printData = {
name: defaultSupportName,
@@ -118,8 +134,9 @@ function IASChat(config) {
document.getElementById('ias_topbar-text').innerHTML = printData.name;
document.getElementById('ias_topbar-pic').firstChild.setAttribute('src', printData.pic);
- });
-
+ } else {
+ setTimeout(setChatData, 100);
+ }
}
@@ -219,7 +236,7 @@ function IASChat(config) {
var text = e.srcElement.children[1].value
if(text === '' && attatchment === null) {
- console.log('tried to send empty form. Rejected.');
+ console.warn('tried to send empty form. Rejected.');
return false;
}
@@ -278,6 +295,10 @@ function IASChat(config) {
firebase.database().ref('messages/' + cid).push(msg);
firebase.database().ref('users/' + cid).once('value').then(function(snapshot) {
+
+ var userLastMsg = msg;
+ userLastMsg.read = false;
+
if(!snapshot.val()) {
// Add user
firebase.database().ref('users/' + cid).set({
@@ -285,10 +306,10 @@ function IASChat(config) {
pic: pic,
isSupporter: false,
supporter: -1,
- lastMessage: msg
+ lastMessage: userLastMsg
});
} else {
- firebase.database().ref('users/' + cid).update({lastMessage: msg});
+ firebase.database().ref('users/' + cid).update({lastMessage: userLastMsg});
if(!snapshot.val().profile) {
generateUserData(cid)
}
@@ -312,8 +333,44 @@ function IASChat(config) {
if(message.uid == uid) {
printMessage(text);
+ if(typeof onSend === 'function' && message.timestamp > lastMessage.timestamp) {
+ onSend(message, key);
+ }
} else {
printMessage(text, true);
+
+ // If chat is open, set the message as read
+ if(!isHidden()) {
+ readLastMessage();
+ }
+
+ if(typeof onMessage === 'function' && message.timestamp > lastMessage.timestamp) {
+ onMessage(message, key);
+ }
+ }
+ }
+
+ function readLastMessage() {
+ firebase.database().ref('users/' + cid + '/lastMessage').update({read: true});
+ }
+
+ function setNotifications() {
+
+ // Only set notifications if button are enabled
+ if(button) {
+ if(lastMessage.uid !== uid && !lastMessage.read) {
+ if (showNotifications.classList) {
+ showNotifications.classList.remove('hidden');
+ } else {
+ showNotifications.className = showNotifications.className.replace(new RegExp('(^|\\b)' + 'hidden'.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
+ }
+ } else {
+ if (showNotifications.classList) {
+ showNotifications.classList.add('hidden');
+ } else {
+ showNotifications.className += ' ' + 'hidden';
+ }
+ }
}
}
@@ -338,6 +395,9 @@ function IASChat(config) {
// Also set url hash to true;
addUrlHash();
+
+ // And read last message
+ readLastMessage();
}
function hideIAS(e) {
@@ -355,6 +415,20 @@ function IASChat(config) {
remUrlHash();
}
+ function isHidden(e) {
+ if(typeof(e) !== 'undefined') {
+ e.preventDefault();
+ }
+
+ var className = 'hidden';
+
+ if (ias.classList) {
+ return ias.classList.contains(className);
+ } else {
+ return new RegExp('(^| )' + className + '( |$)', 'gi').test(ias.className);
+ }
+ }
+
/* ### URL Hash ### */
function visibilityUrlHash() {
diff --git a/js/provider.js b/js/provider.js
index 297e5ee..2012049 100644
--- a/js/provider.js
+++ b/js/provider.js
@@ -101,10 +101,25 @@ function IASChatProvider(config) {
var supporter = data.supporter.uid || data.supporter;
+ var read = true;
+
+ if(typeof data.lastMessage !== 'undefined' && typeof data.lastMessage.read !== 'undefined' && !data.lastMessage.read) {
+ read = false;
+ }
+
var user = document.createElement('li');
user.setAttribute("data-cid", data.uid);
user.setAttribute("data-supporter", supporter);
+
+ if(read) {
user.innerHTML = '' + data.name + '
';
+ } else {
+ var message = data.lastMessage.text;
+ if(data.lastMessage.text.length > 20)
+ message = data.lastMessage.text.slice(0, 20) + '...';
+
+ user.innerHTML = '' + data.name + '
' + message + '
';
+ }
user.addEventListener('click', usersChatManagement, false);
diff --git a/template/ias_provider.html b/template/ias_provider.html
index 78a12e9..3153c4c 100644
--- a/template/ias_provider.html
+++ b/template/ias_provider.html
@@ -21,6 +21,15 @@ Your Users:
padding: 0;
}
+ .iasProvider_users-chat-unread {
+ font-weight: bold;
+ }
+
+ .iasProvider_users-chat-message {
+ font-weight: lighter;
+ font-family: .8em;
+ }
+
.iasProvider_users-chat li div {
display: inline-block;
vertical-align: middle;
diff --git a/template/ias_segment.html b/template/ias_segment.html
index 631c940..02a2f06 100644
--- a/template/ias_segment.html
+++ b/template/ias_segment.html
@@ -3,4 +3,5 @@
+
\ No newline at end of file
diff --git a/template/ias_style.html b/template/ias_style.html
index f46eb6a..71b99ea 100644
--- a/template/ias_style.html
+++ b/template/ias_style.html
@@ -151,6 +151,18 @@
right: 16px;
width: 56px;
}
+ #ias-show-notifications {
+ height: 16px;
+ width: 16px;
+ background: red;
+ position: absolute;
+ left: 1px;
+ top: 1px;
+ border-radius: 50%;
+ }
+ #ias-show-notifications.hidden {
+ display: none;
+ }
@media screen and (min-width: 842px) {
#ias {