Skip to content

Commit b1bf648

Browse files
authored
Merge pull request #18 from CodingCarlos/dev
Added new message notifications, and message callbacks (both for send and recieve)
2 parents e454370 + 0b774cf commit b1bf648

File tree

9 files changed

+240
-24
lines changed

9 files changed

+240
-24
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ To configure the chat, just use the object passed on IASChat instantiation. *Bol
5050
- defaultSupportPic: String Default support picture (if no supporter assigned)
5151
- uploadFiles: Boolean Enable or disable the option to upload and send files (Default: true)
5252
- onlyPictures: Boolean Allow only pictures, or all file types (Default: true)
53+
- onMessage: Function Execute a function on message recieved. Params message (all object) and key are passed to the function
54+
- onSend: Function Execute a function when a message is sent. Params message (all object) and key are passed to the function
5355

5456
In IASChatProvider, there are some extra features:
5557
- container: String Container for support panel (*#identifier* or *.className*. Default: *body*)

demo/index.html

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,22 @@ <h1>User side support</h1>
6161
mainColor: '#ff9800',
6262
textColor: '#fff',
6363
defaultSupportName: 'John Doe',
64-
defaultSupportPic: 'http://lorempixel.com/100/100/people'
64+
defaultSupportPic: 'http://lorempixel.com/100/100/people',
65+
onMessage: myFunction,
66+
onSend: function(msg, key) {
67+
console.log('#################');
68+
console.log('- Message sent! Key: ' + key);
69+
console.log(msg)
70+
console.log('#################');
71+
}
6572
});
73+
74+
function myFunction(message, key) {
75+
console.log('--------------------');
76+
console.log('- We got a message! key: ' + key);
77+
console.log(message);
78+
console.log('--------------------');
79+
}
6680
};
6781
</script>
6882

dist/chat.js

Lines changed: 86 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@ function IASChat(config) {
2121
var hashSign = config.hashSign || '?';
2222
var uploadFiles = config.uploadFiles || true;
2323
var onlyPictures = config.onlyPictures || true;
24+
var onSend = config.onSend || null;
25+
var onMessage = config.onMessage || null;
2426

2527
// Prepare interface
2628
printInterface(container);
2729

2830
// Prepare listeners
2931
var show = document.getElementById('ias-show');
32+
var showNotifications = document.getElementById('ias-show-notifications');
3033
var ias = document.getElementById('ias');
3134
var topbar = document.getElementById('ias_topbar');
3235
var close = document.getElementById('ias_topbar-close');
@@ -47,6 +50,10 @@ function IASChat(config) {
4750
var lastHash = '';
4851
var lastPage = '';
4952

53+
var user = null;
54+
var lastMessage = {};
55+
56+
5057
// Listen event submit
5158
if(show) {
5259
show.addEventListener('click', showIAS.bind(this));
@@ -83,7 +90,19 @@ function IASChat(config) {
8390
name = config.name || '';
8491
pic = config.pic || '';
8592

86-
setChatData();
93+
// Get chat info
94+
userRef = firebase.database().ref('users/' + cid);
95+
userRef.on('value', function(data) {
96+
97+
user = data.val();
98+
99+
lastMessage = user.lastMessage;
100+
// console.log(lastMessage);
101+
102+
setChatData();
103+
setNotifications();
104+
});
105+
87106

88107
clearMessages();
89108

@@ -96,10 +115,7 @@ function IASChat(config) {
96115

97116
function setChatData() {
98117

99-
userRef = firebase.database().ref('users/' + cid);
100-
userRef.on('value', function(data) {
101-
var key = data.key;
102-
var user = data.val();
118+
if(user) {
103119

104120
var printData = {
105121
name: defaultSupportName,
@@ -118,8 +134,9 @@ function IASChat(config) {
118134

119135
document.getElementById('ias_topbar-text').innerHTML = printData.name;
120136
document.getElementById('ias_topbar-pic').firstChild.setAttribute('src', printData.pic);
121-
});
122-
137+
} else {
138+
setTimeout(setChatData, 100);
139+
}
123140
}
124141

125142

@@ -131,11 +148,11 @@ function IASChat(config) {
131148

132149
// If shall show button, add it to interface (from html/show-button.html)
133150
if(button) {
134-
ias += '<div id=\"ias-show\"><svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\"><path d=\"M0 0h24v24H0z\" fill=\"none\" /><path d=\"M19 2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h4l3 3 3-3h4c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-6 16h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 11.9 13 12.5 13 14h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z\" /></svg></div>'
151+
ias += '<div id=\"ias-show\"><svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\"><path d=\"M0 0h24v24H0z\" fill=\"none\" /><path d=\"M19 2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h4l3 3 3-3h4c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-6 16h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 11.9 13 12.5 13 14h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z\" /></svg><span id=\"ias-show-notifications\" class=\"hidden\"></span></div>'
135152
}
136153

137154
// Also add the styles from css/style.css
138-
ias += '<style>#ias {font-family: \'Roboto\',\'Helvetica\',\'Arial\',sans-serif!important;position: fixed;top: 0;left: 0;height: 100%;width: 100%;z-index: 999;}#ias.hidden {display: none;}#ias_topbar {background-color: #ff9800;color: #fff;fill: #fff;height: 56px;width: 100%;}#ias_topbar #ias_topbar-pic {padding: 8px 16px;width: 40px;height: 40px;float: left;}#ias_topbar #ias_topbar-pic img {height: 100%;border-radius: 50%;}#ias_topbar #ias_topbar-text {float: left;margin-left: 6px;margin-top: 14px;font-size: 24px;}#ias_topbar #ias_topbar-close {color: #fff;float: right;font-size: 24px;margin: 16px 16px 0 0;}#ias_messages {background: #f7f8fb;height: calc(100% - 117px);overflow: auto;padding-top: 12px;}.ias_message {margin: 4px 8px;padding: 4px 12px;}.ias_message-sent {text-align: right;}.ias_message span {background-color: #fff;padding: 4px 12px;border-radius: 5px 5px 0 5px;box-shadow: 1px 1px 5px rgba(0, 0, 0, .1);color: #333;display: inline-block;}.ias_message span img {margin: 8px 0 4px;max-width: 300px;max-height: 264px;}#ias_attachment {position: fixed;bottom: 48px;background: #fff;width: 100%;height: 220px;text-align: center;padding: 8px;box-sizing: border-box;border-top: 1px solid #efefef;}#ias_attachment.hidden {display: none;}#ias_attachment-close {position: absolute;top: 8px;right: 8px;}#ias_attachment #ias_attachment-preview img {max-height: 100%;max-width: 100%;}#ias_write {background-color: #fff;border-top: 1px solid #efefef;height: 48px;position: fixed;bottom: 0;left: 0;width: 100%;}#ias_write input {border: 0;border-bottom: 1px solid #ff9800;height: 31px;left: 0;margin: 0 48px;outline: none;padding: 8px 8px 0px 8px;position: absolute;top: 0;width: 70%;width: calc(100% - 122px);}#ias_write #ias_write-attachment svg {position: absolute;left: 12px;top: 13px;}#ias_write #ias_write-attachment input#ias_write-attachment-uploadFile {width: 24px;margin: 0px 4px;opacity: 0;position: absolute;top: 4px;left: 0px;}#ias_write button {background-color: #fff;border: none;position: fixed;right: 12px;bottom: 5px;border-radius: 50%;font-size: 24px;width: 34px;padding: 0;overflow: hidden;line-height: normal;}#ias-show {background-color: #ff9800;border-radius: 50%;bottom: 16px;box-shadow: 0 1px 1.5px 0 rgba(0, 0, 0, .12), 0 1px 1px 0 rgba(0, 0, 0, .24);box-sizing: border-box;color: #fff;fill: #fff;height: 56px;padding: 16px;position: fixed;right: 16px;width: 56px;}@media screen and (min-width: 842px) {#ias{height: 600px;width: 368px;position: fixed;right: 0;bottom: 0;top: auto;overflow: hidden;left: auto;}#ias_message {height: 483px;}#ias_attachment, #ias_write {position: absolute;}}</style>';
155+
ias += '<style>#ias {font-family: \'Roboto\',\'Helvetica\',\'Arial\',sans-serif!important;position: fixed;top: 0;left: 0;height: 100%;width: 100%;z-index: 999;}#ias.hidden {display: none;}#ias_topbar {background-color: #ff9800;color: #fff;fill: #fff;height: 56px;width: 100%;}#ias_topbar #ias_topbar-pic {padding: 8px 16px;width: 40px;height: 40px;float: left;}#ias_topbar #ias_topbar-pic img {height: 100%;border-radius: 50%;}#ias_topbar #ias_topbar-text {float: left;margin-left: 6px;margin-top: 14px;font-size: 24px;}#ias_topbar #ias_topbar-close {color: #fff;float: right;font-size: 24px;margin: 16px 16px 0 0;}#ias_messages {background: #f7f8fb;height: calc(100% - 117px);overflow: auto;padding-top: 12px;}.ias_message {margin: 4px 8px;padding: 4px 12px;}.ias_message-sent {text-align: right;}.ias_message span {background-color: #fff;padding: 4px 12px;border-radius: 5px 5px 0 5px;box-shadow: 1px 1px 5px rgba(0, 0, 0, .1);color: #333;display: inline-block;}.ias_message span img {margin: 8px 0 4px;max-width: 300px;max-height: 264px;}#ias_attachment {position: fixed;bottom: 48px;background: #fff;width: 100%;height: 220px;text-align: center;padding: 8px;box-sizing: border-box;border-top: 1px solid #efefef;}#ias_attachment.hidden {display: none;}#ias_attachment-close {position: absolute;top: 8px;right: 8px;}#ias_attachment #ias_attachment-preview img {max-height: 100%;max-width: 100%;}#ias_write {background-color: #fff;border-top: 1px solid #efefef;height: 48px;position: fixed;bottom: 0;left: 0;width: 100%;}#ias_write input {border: 0;border-bottom: 1px solid #ff9800;height: 31px;left: 0;margin: 0 48px;outline: none;padding: 8px 8px 0px 8px;position: absolute;top: 0;width: 70%;width: calc(100% - 122px);}#ias_write #ias_write-attachment svg {position: absolute;left: 12px;top: 13px;}#ias_write #ias_write-attachment input#ias_write-attachment-uploadFile {width: 24px;margin: 0px 4px;opacity: 0;position: absolute;top: 4px;left: 0px;}#ias_write button {background-color: #fff;border: none;position: fixed;right: 12px;bottom: 5px;border-radius: 50%;font-size: 24px;width: 34px;padding: 0;overflow: hidden;line-height: normal;}#ias-show {background-color: #ff9800;border-radius: 50%;bottom: 16px;box-shadow: 0 1px 1.5px 0 rgba(0, 0, 0, .12), 0 1px 1px 0 rgba(0, 0, 0, .24);box-sizing: border-box;color: #fff;fill: #fff;height: 56px;padding: 16px;position: fixed;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{height: 600px;width: 368px;position: fixed;right: 0;bottom: 0;top: auto;overflow: hidden;left: auto;}#ias_message {height: 483px;}#ias_attachment, #ias_write {position: absolute;}}</style>';
139156

140157
var printplace = null;
141158

@@ -219,7 +236,7 @@ function IASChat(config) {
219236
var text = e.srcElement.children[1].value
220237

221238
if(text === '' && attatchment === null) {
222-
console.log('tried to send empty form. Rejected.');
239+
console.warn('tried to send empty form. Rejected.');
223240
return false;
224241
}
225242

@@ -278,17 +295,21 @@ function IASChat(config) {
278295
firebase.database().ref('messages/' + cid).push(msg);
279296

280297
firebase.database().ref('users/' + cid).once('value').then(function(snapshot) {
298+
299+
var userLastMsg = msg;
300+
userLastMsg.read = false;
301+
281302
if(!snapshot.val()) {
282303
// Add user
283304
firebase.database().ref('users/' + cid).set({
284305
name: name,
285306
pic: pic,
286307
isSupporter: false,
287308
supporter: -1,
288-
lastMessage: msg
309+
lastMessage: userLastMsg
289310
});
290311
} else {
291-
firebase.database().ref('users/' + cid).update({lastMessage: msg});
312+
firebase.database().ref('users/' + cid).update({lastMessage: userLastMsg});
292313
if(!snapshot.val().profile) {
293314
generateUserData(cid)
294315
}
@@ -312,8 +333,44 @@ function IASChat(config) {
312333

313334
if(message.uid == uid) {
314335
printMessage(text);
336+
if(typeof onSend === 'function' && message.timestamp > lastMessage.timestamp) {
337+
onSend(message, key);
338+
}
315339
} else {
316340
printMessage(text, true);
341+
342+
// If chat is open, set the message as read
343+
if(!isHidden()) {
344+
readLastMessage();
345+
}
346+
347+
if(typeof onMessage === 'function' && message.timestamp > lastMessage.timestamp) {
348+
onMessage(message, key);
349+
}
350+
}
351+
}
352+
353+
function readLastMessage() {
354+
firebase.database().ref('users/' + cid + '/lastMessage').update({read: true});
355+
}
356+
357+
function setNotifications() {
358+
359+
// Only set notifications if button are enabled
360+
if(button) {
361+
if(lastMessage.uid !== uid && !lastMessage.read) {
362+
if (showNotifications.classList) {
363+
showNotifications.classList.remove('hidden');
364+
} else {
365+
showNotifications.className = showNotifications.className.replace(new RegExp('(^|\\b)' + 'hidden'.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
366+
}
367+
} else {
368+
if (showNotifications.classList) {
369+
showNotifications.classList.add('hidden');
370+
} else {
371+
showNotifications.className += ' ' + 'hidden';
372+
}
373+
}
317374
}
318375
}
319376

@@ -338,6 +395,9 @@ function IASChat(config) {
338395

339396
// Also set url hash to true;
340397
addUrlHash();
398+
399+
// And read last message
400+
readLastMessage();
341401
}
342402

343403
function hideIAS(e) {
@@ -355,6 +415,20 @@ function IASChat(config) {
355415
remUrlHash();
356416
}
357417

418+
function isHidden(e) {
419+
if(typeof(e) !== 'undefined') {
420+
e.preventDefault();
421+
}
422+
423+
var className = 'hidden';
424+
425+
if (ias.classList) {
426+
return ias.classList.contains(className);
427+
} else {
428+
return new RegExp('(^| )' + className + '( |$)', 'gi').test(ias.className);
429+
}
430+
}
431+
358432
/* ### URL Hash ### */
359433

360434
function visibilityUrlHash() {

dist/provider.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function IASChatProvider(config) {
4949

5050
function printInterface(container) {
5151
// Compressed version of html/chat.html turned to string
52-
var ias = '<div id=\"iasProvider\"><div id=\"iasProvider_unassigned-chat\"><h3>Unassigned Users:</h3><ul class=\"iasProvider_users-chat\"></ul></div><div id=\"iasProvider_assigned-chat\"><h3>Your Users:</h3><ul class=\"iasProvider_users-chat\"></ul></div></div><style>#iasProvider {font-family: \"Roboto\",\"Helvetica\",\"Arial\",sans-serif!important;}.iasProvider_users-chat {list-style: none;margin: 0;padding: 0;}.iasProvider_users-chat li div {display: inline-block;vertical-align: middle;}.iasProvider_users-chat li div.iasProvider_users-chat-pic {box-sizing: border-box;padding: 8px 16px;width: 72px;}.iasProvider_users-chat li div.iasProvider_users-chat-pic img {border-radius: 50%;height: 40px;width: 40px;}.iasProvider_users-chat li div.iasProvider_users-chat-name {font-size: 16px;}</style>'
52+
var ias = '<div id=\"iasProvider\"><div id=\"iasProvider_unassigned-chat\"><h3>Unassigned Users:</h3><ul class=\"iasProvider_users-chat\"></ul></div><div id=\"iasProvider_assigned-chat\"><h3>Your Users:</h3><ul class=\"iasProvider_users-chat\"></ul></div></div><style>#iasProvider {font-family: \"Roboto\",\"Helvetica\",\"Arial\",sans-serif!important;}.iasProvider_users-chat {list-style: none;margin: 0;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;}.iasProvider_users-chat li div.iasProvider_users-chat-pic {box-sizing: border-box;padding: 8px 16px;width: 72px;}.iasProvider_users-chat li div.iasProvider_users-chat-pic img {border-radius: 50%;height: 40px;width: 40px;}.iasProvider_users-chat li div.iasProvider_users-chat-name {font-size: 16px;}</style>'
5353

5454
// Also add the provider styles from css/provider-style.css
5555
// ias += '';
@@ -101,10 +101,25 @@ function IASChatProvider(config) {
101101

102102
var supporter = data.supporter.uid || data.supporter;
103103

104+
var read = true;
105+
106+
if(typeof data.lastMessage !== 'undefined' && typeof data.lastMessage.read !== 'undefined' && !data.lastMessage.read) {
107+
read = false;
108+
}
109+
104110
var user = document.createElement('li');
105111
user.setAttribute("data-cid", data.uid);
106112
user.setAttribute("data-supporter", supporter);
113+
114+
if(read) {
107115
user.innerHTML = '<div class="iasProvider_users-chat-pic"><img src="' + data.pic + '"></div><div class="iasProvider_users-chat-name">' + data.name + '</div>';
116+
} else {
117+
var message = data.lastMessage.text;
118+
if(data.lastMessage.text.length > 20)
119+
message = data.lastMessage.text.slice(0, 20) + '...';
120+
121+
user.innerHTML = '<div class="iasProvider_users-chat-pic"><img src="' + data.pic + '"></div><div class="iasProvider_users-chat-name iasProvider_users-chat-unread">' + data.name + '<br><span class="iasProvider_users-chat-message">' + message + '</span></div>';
122+
}
108123

109124
user.addEventListener('click', usersChatManagement, false);
110125

0 commit comments

Comments
 (0)