| 1 |
/* Variables */ |
| 2 |
var user; |
| 3 |
var timer; |
| 4 |
var socket; |
| 5 |
var oldname; |
| 6 |
var username; |
| 7 |
var typeTimer; |
| 8 |
var clients = []; |
| 9 |
var usersTyping = []; |
| 10 |
var nmr = 0; |
| 11 |
var dev = true; |
| 12 |
var key=null; |
| 13 |
var unread = 0; |
| 14 |
var focus = true; |
| 15 |
var typing = false; |
| 16 |
var connected = false; |
| 17 |
var version = '1.0.6'; |
| 18 |
|
| 19 |
var blop = ''; |
| 20 |
var regex = /(‍| )/g; |
| 21 |
|
| 22 |
var settings = { |
| 23 |
'name': null, |
| 24 |
'emoji': true, |
| 25 |
'greentext': true, |
| 26 |
'inline': true, |
| 27 |
'sound': true, |
| 28 |
'desktop': false, |
| 29 |
'synthesis': false, |
| 30 |
'recognition': false |
| 31 |
}; |
| 32 |
|
| 33 |
|
| 34 |
/* Config */ |
| 35 |
emojione.ascii = true; |
| 36 |
emojione.imageType = 'png'; |
| 37 |
emojione.unicodeAlt = false; |
| 38 |
|
| 39 |
var wpstream_close_socket=function(){ |
| 40 |
socket.close(); |
| 41 |
}; |
| 42 |
/* Connection */ |
| 43 |
var connect = function(chat_uri) { |
| 44 |
var reject=false; |
| 45 |
|
| 46 |
if(chat_uri==='' || chat_uri==='undefined'){ |
| 47 |
message="We are not live at this moment.Please check back later."; |
| 48 |
//showChat('light', null, message); |
| 49 |
reject=true; |
| 50 |
} |
| 51 |
|
| 52 |
if(username===''){ |
| 53 |
message="Please login if you want to use the chat."; |
| 54 |
showChat('light', null, message); |
| 55 |
reject=true; |
| 56 |
} |
| 57 |
|
| 58 |
var protocol; |
| 59 |
protocol = 'wss://'; |
| 60 |
if(chat_uri!==''){ |
| 61 |
socket = new WebSocket(chat_uri); |
| 62 |
socket.addEventListener('error', function (event) { |
| 63 |
message="We are not live at this moment.Please check back later."; |
| 64 |
showChat('light', null, message); |
| 65 |
reject=true; |
| 66 |
}); |
| 67 |
} |
| 68 |
|
| 69 |
|
| 70 |
if(reject===true){ |
| 71 |
return; |
| 72 |
} |
| 73 |
|
| 74 |
|
| 75 |
|
| 76 |
socket.error =function(){ |
| 77 |
console.log('socket error'); |
| 78 |
}; |
| 79 |
|
| 80 |
socket.onopen = function() { |
| 81 |
var ping = setInterval(function(){ |
| 82 |
socket.send(JSON.stringify({type: 'ping'})); |
| 83 |
}, 50 * 1000); |
| 84 |
|
| 85 |
updateInfo(); |
| 86 |
}; |
| 87 |
|
| 88 |
socket.onclose = function() { |
| 89 |
clearTimeout(typeTimer); |
| 90 |
jQuery('#admin').hide(); |
| 91 |
typing = false; |
| 92 |
clients = []; |
| 93 |
|
| 94 |
if(connected) { |
| 95 |
updateBar('mdi-action-autorenew spin', 'Connection lost, reconnecting...', true); |
| 96 |
|
| 97 |
timer = setTimeout(function() { |
| 98 |
console.warn('Connection lost, reconnecting...'); |
| 99 |
connect(); |
| 100 |
}, 1500); |
| 101 |
} |
| 102 |
}; |
| 103 |
|
| 104 |
socket.onmessage = function(e) { |
| 105 |
var data = JSON.parse(e.data); |
| 106 |
|
| 107 |
|
| 108 |
if(data.type == 'delete') { |
| 109 |
return jQuery('div[data-mid="' + data.message + '"]').remove(); |
| 110 |
} |
| 111 |
|
| 112 |
if(data.type == 'typing') { |
| 113 |
var string; |
| 114 |
if(data.user != username) { |
| 115 |
if(data.typing) { |
| 116 |
usersTyping.push(data.user); |
| 117 |
} else { |
| 118 |
usersTyping.splice(usersTyping.indexOf(data.user), 1); |
| 119 |
} |
| 120 |
} |
| 121 |
|
| 122 |
|
| 123 |
if(usersTyping.length == 1) { |
| 124 |
string = usersTyping + ' is writing...'; |
| 125 |
} else if(usersTyping.length > 4) { |
| 126 |
string = 'Several people are writing...'; |
| 127 |
} else if(usersTyping.length > 1) { |
| 128 |
var lastUser = usersTyping.pop(); |
| 129 |
string = usersTyping.join(', ') + ' and ' + lastUser + ' are writing...'; |
| 130 |
usersTyping.push(lastUser); |
| 131 |
} else { |
| 132 |
string = '<br>'; |
| 133 |
} |
| 134 |
|
| 135 |
return document.getElementById('typing').innerHTML = string; |
| 136 |
} |
| 137 |
|
| 138 |
if(data.type == 'server') { |
| 139 |
switch(data.info) { |
| 140 |
case 'rejected': |
| 141 |
var message; |
| 142 |
|
| 143 |
if(data.reason == 'length') { |
| 144 |
message = 'Your username must have at least 3 characters and no more than 16 characters'; |
| 145 |
} |
| 146 |
|
| 147 |
if(data.reason == 'format') { |
| 148 |
message = 'Your username must only contain alphanumeric characters (numbers, letters and underscores)'; |
| 149 |
} |
| 150 |
|
| 151 |
if(data.reason == 'taken') { |
| 152 |
message = 'This username is already taken'; |
| 153 |
} |
| 154 |
|
| 155 |
if(data.reason == 'banned') { |
| 156 |
message = 'You have been banned from the server for ' + data.time / 60 / 1000 + ' minutes. You have to wait until you get unbanned to be able to connect again'; |
| 157 |
} |
| 158 |
|
| 159 |
showChat('light', null, message); |
| 160 |
|
| 161 |
if(!data.keep) { |
| 162 |
username = undefined; |
| 163 |
connected = false; |
| 164 |
} else { |
| 165 |
username = oldname; |
| 166 |
} |
| 167 |
break; |
| 168 |
|
| 169 |
case 'success': |
| 170 |
document.getElementById('send').childNodes[0].nodeValue = 'Send'; |
| 171 |
updateBar('mdi-content-send', 'Enter your message here', false); |
| 172 |
connected = true; |
| 173 |
settings.name = username; |
| 174 |
localStorage.settings = JSON.stringify(settings); |
| 175 |
break; |
| 176 |
|
| 177 |
case 'update': |
| 178 |
showChat('info', null, data.user.oldun + ' changed its name to ' + data.user.un); |
| 179 |
clients[data.user.id] = data.user; |
| 180 |
break; |
| 181 |
|
| 182 |
case 'connection': |
| 183 |
var userip = data.user.ip ? ' [' + data.user.ip + ']' : ''; |
| 184 |
showChat('info', null, data.user.un + userip + ' connected to the server'); |
| 185 |
|
| 186 |
clients[data.user.id] = data.user; |
| 187 |
document.getElementById('users').innerHTML = Object.keys(clients).length + ' USERS'; |
| 188 |
break; |
| 189 |
|
| 190 |
case 'disconnection': |
| 191 |
var userip = data.user.ip ? ' [' + data.user.ip + ']' : ''; |
| 192 |
|
| 193 |
if(data.user.un != null) { |
| 194 |
showChat('info', null, data.user.un + userip + ' disconnected from the server'); |
| 195 |
} |
| 196 |
|
| 197 |
delete clients[data.user.id]; |
| 198 |
document.getElementById('users').innerHTML = Object.keys(clients).length + ' USERS'; |
| 199 |
break; |
| 200 |
|
| 201 |
case 'spam': |
| 202 |
showChat('global', null, 'You have to wait 1 second between messages. Continuing on spamming the servers may get you banned. Warning ' + data.warn + ' of 5'); |
| 203 |
break; |
| 204 |
|
| 205 |
case 'clients': |
| 206 |
clients = data.clients; |
| 207 |
document.getElementById('users').innerHTML = Object.keys(clients).length + ' USERS'; |
| 208 |
break; |
| 209 |
|
| 210 |
case 'user': |
| 211 |
user = data.client.id; |
| 212 |
break; |
| 213 |
} |
| 214 |
} else if((data.type == 'kick' || data.type == 'ban') && data.extra == username) { |
| 215 |
location.reload(); |
| 216 |
} else { |
| 217 |
if(data.message.indexOf('@' + username) > -1) { |
| 218 |
data.type = 'mention'; |
| 219 |
} |
| 220 |
|
| 221 |
if(settings.synthesis) { |
| 222 |
textToSpeech.text = data.message; |
| 223 |
speechSynthesis.speak(textToSpeech); |
| 224 |
} |
| 225 |
|
| 226 |
showChat(data.type, data.user, data.message, data.subtxt, data.mid); |
| 227 |
} |
| 228 |
|
| 229 |
if(data.type == 'role') { |
| 230 |
if(getUserByName(data.extra) != undefined) { |
| 231 |
if(data.extra == username && data.role > 0) { |
| 232 |
jQuery('#admin').show(); |
| 233 |
jQuery('#menu-admin').show(); |
| 234 |
} |
| 235 |
|
| 236 |
if(data.extra == username && data.role == 0) { |
| 237 |
jQuery('#admin').hide(); |
| 238 |
jQuery('#menu-admin').hide(); |
| 239 |
} |
| 240 |
|
| 241 |
clients[getUserByName(data.extra).id].role = data.role; |
| 242 |
} |
| 243 |
} |
| 244 |
|
| 245 |
if(data.type == 'global' || data.type == 'pm' || data.type == 'mention') { |
| 246 |
if(!focus) { |
| 247 |
unread++; |
| 248 |
if(settings.sound) { |
| 249 |
blop.play(); |
| 250 |
} |
| 251 |
|
| 252 |
if(settings.desktop) { |
| 253 |
desktopNotif(data.user + ': ' + data.message); |
| 254 |
} |
| 255 |
} |
| 256 |
} |
| 257 |
} |
| 258 |
}; |
| 259 |
|
| 260 |
|
| 261 |
/* Functions */ |
| 262 |
function sendSocket(value, method, other, txt) { |
| 263 |
socket.send(JSON.stringify({ |
| 264 |
type: method, |
| 265 |
message: value, |
| 266 |
subtxt: txt, |
| 267 |
extra: other |
| 268 |
})); |
| 269 |
|
| 270 |
jQuery('#message').focus(); |
| 271 |
} |
| 272 |
|
| 273 |
function updateInfo() { |
| 274 |
socket.send(JSON.stringify({ |
| 275 |
user: username, |
| 276 |
type: 'update', |
| 277 |
key:key |
| 278 |
})); |
| 279 |
} |
| 280 |
|
| 281 |
function getUserByName(name) { |
| 282 |
for(client in clients) { |
| 283 |
if(clients[client].un == name) { |
| 284 |
return clients[client]; |
| 285 |
} |
| 286 |
} |
| 287 |
} |
| 288 |
|
| 289 |
|
| 290 |
|
| 291 |
|
| 292 |
|
| 293 |
|
| 294 |
function updateBar(icon, placeholder, disable) { |
| 295 |
// document.getElementById('icon').className = 'mdi ' + icon; |
| 296 |
jQuery('#message').attr('placeholder', placeholder); |
| 297 |
jQuery('#message').prop('disabled', disable); |
| 298 |
jQuery('#send').prop('disabled', disable); |
| 299 |
} |
| 300 |
|
| 301 |
function showChat(type, user, message, subtxt, mid) { |
| 302 |
var nameclass = ''; |
| 303 |
|
| 304 |
if(type == 'global' || type == 'kick' || type == 'ban' || type == 'info' || type == 'light' || type == 'help' || type == 'role') { |
| 305 |
user = 'System'; |
| 306 |
} |
| 307 |
|
| 308 |
if(type == 'me' || type == 'em') { |
| 309 |
type = 'emote'; |
| 310 |
} |
| 311 |
|
| 312 |
if(!mid) { |
| 313 |
mid == 'system'; |
| 314 |
} |
| 315 |
|
| 316 |
if(type == 'emote' || type == 'message') { |
| 317 |
if(user == username && getUserByName(user).role == 0) { |
| 318 |
nameclass = 'self'; |
| 319 |
} else { |
| 320 |
if(getUserByName(user).role == 1) nameclass = 'helper'; |
| 321 |
if(getUserByName(user).role == 2) nameclass = 'moderator'; |
| 322 |
if(getUserByName(user).role == 3) nameclass = 'administrator'; |
| 323 |
} |
| 324 |
} |
| 325 |
|
| 326 |
if(!subtxt) { |
| 327 |
jQuery('#panel').append('<div data-mid="' + mid + '" class="' + type + '""><span class="name ' + nameclass + '"><b><a class="namelink" href="javascript:void(0)">' + user + ':</a></b></span><span class="delete"><a href="javascript:void(0)">DELETE</a></span><span class="timestamp">' + getTime() + '</span><span class="msg">' + message + '</span></div>'); |
| 328 |
} else { |
| 329 |
jQuery('#panel').append('<div data-mid="' + mid + '" class="' + type + '""><span class="name ' + nameclass + '"><b><a class="namelink" href="javascript:void(0)">' + user + ':</a></b></span><span class="timestamp">(' + subtxt + ') ' + getTime() + '</span><span class="msg">' + message + '</span></div>'); |
| 330 |
} |
| 331 |
|
| 332 |
jQuery('#panel').animate({scrollTop: jQuery('#panel').prop('scrollHeight')}, 500); |
| 333 |
updateStyle(); |
| 334 |
jQuery('#message').focus(); |
| 335 |
|
| 336 |
nmr++; |
| 337 |
|
| 338 |
if(settings.inline) { |
| 339 |
var m = message.match(/(https?|ftp):\/\/[^\s/jQuery.?#].[^\s]*/gmi); |
| 340 |
|
| 341 |
if(m) { |
| 342 |
m.forEach(function(e, i, a) { |
| 343 |
// Gfycat Support |
| 344 |
if(e.indexOf('//gfycat') !== -1) { |
| 345 |
var oldUrl = e; |
| 346 |
e = e.replace('//gfycat.com', '//gfycat.com/cajax/get').replace('http://', 'https://'); |
| 347 |
|
| 348 |
jQuery.getJSON(e, function(data) { |
| 349 |
testImage(data.gfyItem.gifUrl.replace('http://', 'https://'), mid, oldUrl); |
| 350 |
}); |
| 351 |
} else { |
| 352 |
testImage(e, mid, e); |
| 353 |
} |
| 354 |
}); |
| 355 |
} |
| 356 |
} |
| 357 |
} |
| 358 |
|
| 359 |
function testImage(url, mid, oldUrl) { |
| 360 |
var img = new Image(); |
| 361 |
|
| 362 |
img.onload = function() { |
| 363 |
jQuery('div[data-mid=' + mid + '] .msg a[href="' + oldUrl.replace('https://', 'http://') + '"]').html(img); |
| 364 |
jQuery('#panel').animate({scrollTop: jQuery('#panel').prop('scrollHeight')}, 500); |
| 365 |
}; |
| 366 |
|
| 367 |
img.src = url; |
| 368 |
} |
| 369 |
|
| 370 |
|
| 371 |
function handleInput() { |
| 372 |
var value = jQuery('#message').val().replace(regex, ' ').trim(); |
| 373 |
jQuery('#message').focus(); |
| 374 |
if(value.length > 0) { |
| 375 |
|
| 376 |
if(username === undefined) { |
| 377 |
// username = value; |
| 378 |
// connect(); |
| 379 |
} else if(value.charAt(0) == '/') { |
| 380 |
var command = value.substring(1).split(' '); |
| 381 |
|
| 382 |
switch(command[0].toLowerCase()) { |
| 383 |
case 'pm': case 'msg': case 'role': case 'kick': case 'ban': case 'name': case 'alert': case 'me': case 'em': |
| 384 |
if(value.substring(command[0].length).length > 1) { |
| 385 |
if((command[0] == 'pm' || command[0] == 'msg') && value.substring(command[0].concat(command[1]).length).length > 2) { |
| 386 |
sendSocket(value.substring(command[0].concat(command[1]).length + 2), 'pm', command[1], 'PM'); |
| 387 |
} else if(command[0] == 'pm' || command[0] == 'msg') { |
| 388 |
showChat('light', 'Error', 'Use /' + command[0] + ' [user] [message]'); |
| 389 |
} |
| 390 |
|
| 391 |
if(command[0] == 'ban' && value.substring(command[0].concat(command[1]).length).length > 2) { |
| 392 |
sendSocket(command[1], 'ban', command[2]); |
| 393 |
} else if(command[0] == 'ban') { |
| 394 |
showChat('light', 'Error', 'Use /ban [user] [minutes]'); |
| 395 |
} |
| 396 |
|
| 397 |
if(command[0] == 'alert') { |
| 398 |
sendSocket(value.substring(command[0].length + 2), 'global', null, username); |
| 399 |
} |
| 400 |
|
| 401 |
if((command[0] == 'role') && value.substring(command[0].concat(command[1]).length).length > 3) { |
| 402 |
sendSocket(command[1], 'role', value.substring(command[0].concat(command[1]).length + 3)); |
| 403 |
} else if(command[0] == 'role') { |
| 404 |
showChat('light', 'Error', 'Use /' + command[0] + ' [user] [0-3]'); |
| 405 |
} |
| 406 |
|
| 407 |
if(command[0] == 'kick' || command[0] == 'me' || command[0] == 'em') { |
| 408 |
sendSocket(value.substring(command[0].length + 2), command[0]); |
| 409 |
} |
| 410 |
|
| 411 |
if(command[0] == 'name') { |
| 412 |
oldname = username; |
| 413 |
username = value.substring(command[0].length + 2); |
| 414 |
updateInfo(); |
| 415 |
} |
| 416 |
} else { |
| 417 |
var variables; |
| 418 |
if(command[0] == 'alert' || command[0] == 'me' || command[0] == 'em') { |
| 419 |
variables = ' [message]'; |
| 420 |
} |
| 421 |
|
| 422 |
if(command[0] == 'role') { |
| 423 |
variables = ' [user] [0-3]'; |
| 424 |
} |
| 425 |
|
| 426 |
if(command[0] == 'ban') { |
| 427 |
variables = ' [user] [minutes]'; |
| 428 |
} |
| 429 |
|
| 430 |
if(command[0] == 'pm') { |
| 431 |
variables = ' [user] [message]'; |
| 432 |
} |
| 433 |
|
| 434 |
if(command[0] == 'kick') { |
| 435 |
variables = ' [user]'; |
| 436 |
} |
| 437 |
|
| 438 |
if(command[0] == 'name') { |
| 439 |
variables = ' [name]'; |
| 440 |
} |
| 441 |
|
| 442 |
showChat('light', 'Error', 'Use /' + command[0] + variables); |
| 443 |
} |
| 444 |
break; |
| 445 |
|
| 446 |
case 'clear': |
| 447 |
nmr = 0; |
| 448 |
document.getElementById('panel').innerHTML = ''; |
| 449 |
showChat('light', 'System', 'Messages cleared'); |
| 450 |
break; |
| 451 |
|
| 452 |
case 'shrug': |
| 453 |
sendSocket(value.substring(6) + ' ¯\\_(ツ)_/¯', 'message'); |
| 454 |
break; |
| 455 |
|
| 456 |
case 'help': |
| 457 |
jQuery('#help-dialog').modal('show'); |
| 458 |
break; |
| 459 |
|
| 460 |
case 'users': |
| 461 |
jQuery('#user').click(); |
| 462 |
break; |
| 463 |
|
| 464 |
case 'reconnect': |
| 465 |
socket.close(); |
| 466 |
break; |
| 467 |
|
| 468 |
default: |
| 469 |
showChat('light', 'Error', 'Unknown command, use /help to get a list of the available commands'); |
| 470 |
break; |
| 471 |
} |
| 472 |
} else { |
| 473 |
sendSocket(value, 'message'); |
| 474 |
} |
| 475 |
|
| 476 |
jQuery('#message').val(''); |
| 477 |
jQuery('#message').focus(); |
| 478 |
|
| 479 |
} |
| 480 |
} |
| 481 |
|
| 482 |
function getTime() { |
| 483 |
var now = new Date(); |
| 484 |
var time = [now.getHours(), now.getMinutes(), now.getSeconds()]; |
| 485 |
|
| 486 |
for(var i = 0; i < 3; i++) { |
| 487 |
if(time[i] < 10) { |
| 488 |
time[i] = '0' + time[i]; |
| 489 |
} |
| 490 |
} |
| 491 |
|
| 492 |
return time.join(':'); |
| 493 |
} |
| 494 |
|
| 495 |
function updateStyle() { |
| 496 |
jQuery('#panel').linkify(); |
| 497 |
var element = document.getElementsByClassName('msg')[nmr]; |
| 498 |
|
| 499 |
if(element.innerHTML != undefined) { |
| 500 |
if(settings.greentext && element.innerHTML.indexOf('>') == 0) { |
| 501 |
element.style.color = '#689f38'; |
| 502 |
} |
| 503 |
|
| 504 |
if(settings.emoji) { |
| 505 |
var input = element.innerHTML; |
| 506 |
var output = emojione.shortnameToImage(element.innerHTML); |
| 507 |
element.innerHTML = output; |
| 508 |
} |
| 509 |
} |
| 510 |
} |
| 511 |
|
| 512 |
|
| 513 |
/* Binds */ |
| 514 |
jQuery(document).ready(function() { |
| 515 |
jQuery('#close-users-dialog').on('click',function(){ |
| 516 |
jQuery('#users-dialog').hide(); |
| 517 |
}); |
| 518 |
|
| 519 |
jQuery('#user').bind('click', function() { |
| 520 |
var content = ''; |
| 521 |
var userip = ''; |
| 522 |
var admin; |
| 523 |
|
| 524 |
for(var i in clients) { |
| 525 |
if(clients[i] != undefined) { |
| 526 |
if(clients[i].ip) { |
| 527 |
userip = '(' + clients[i].ip + ')'; |
| 528 |
} |
| 529 |
|
| 530 |
if(clients[i].role === 0) { |
| 531 |
admin = '</li>'; |
| 532 |
} |
| 533 |
|
| 534 |
if(clients[i].role === 1) { |
| 535 |
admin = ' - <b>Helper</b></li>'; |
| 536 |
} |
| 537 |
|
| 538 |
if(clients[i].role === 2) { |
| 539 |
admin = ' - <b>Moderator</b></li>'; |
| 540 |
} |
| 541 |
|
| 542 |
if(clients[i].role === 3) { |
| 543 |
admin = ' - <b>Administrator</b></li>'; |
| 544 |
} |
| 545 |
|
| 546 |
content += '<li>' + '<b>#' + clients[i].id + '</b> ' + userip + ' - ' + clients[i].un + admin; |
| 547 |
} |
| 548 |
} |
| 549 |
|
| 550 |
document.getElementById('users-content').innerHTML = content; |
| 551 |
jQuery('#users-dialog').show(); |
| 552 |
}); |
| 553 |
|
| 554 |
jQuery('#panel').on('mouseenter', '.message', function() { |
| 555 |
if(clients[user].role > 0) { |
| 556 |
jQuery(this).find('span:eq(1)').show(); |
| 557 |
jQuery(this).find('span:eq(2)').hide(); |
| 558 |
} |
| 559 |
}); |
| 560 |
|
| 561 |
jQuery('#panel').on('mouseleave', '.message',function() { |
| 562 |
if(clients[user].role > 0) { |
| 563 |
jQuery(this).find('span:eq(1)').hide(); |
| 564 |
jQuery(this).find('span:eq(2)').show(); |
| 565 |
} |
| 566 |
}); |
| 567 |
|
| 568 |
jQuery('#panel').on('mouseenter', '.emote', function() { |
| 569 |
if(clients[user].role > 0) { |
| 570 |
jQuery(this).find('span:eq(1)').show(); |
| 571 |
jQuery(this).find('span:eq(2)').hide(); |
| 572 |
} |
| 573 |
}); |
| 574 |
|
| 575 |
jQuery('#panel').on('mouseleave', '.emote', function() { |
| 576 |
if(clients[user].role > 0) { |
| 577 |
jQuery(this).find('span:eq(1)').hide(); |
| 578 |
jQuery(this).find('span:eq(2)').show(); |
| 579 |
} |
| 580 |
}); |
| 581 |
|
| 582 |
jQuery('#panel').on('click', '.delete', function(e) { |
| 583 |
var value = jQuery(this)[0].parentElement.attributes[0].value; |
| 584 |
sendSocket(value, 'delete'); |
| 585 |
}); |
| 586 |
|
| 587 |
jQuery('#panel').on('click', '.name', function(e) { |
| 588 |
jQuery('#message').val('@' + jQuery(this)[0].children[0].children[0].innerHTML + ' '); |
| 589 |
jQuery('#message').focus(); |
| 590 |
}); |
| 591 |
|
| 592 |
jQuery('#send').bind('click', function() { |
| 593 |
handleInput(); |
| 594 |
}); |
| 595 |
|
| 596 |
jQuery('#menu-admin').bind('click', function() { |
| 597 |
jQuery('#admin-help-dialog').modal('show'); |
| 598 |
}); |
| 599 |
|
| 600 |
jQuery('#help').bind('click', function() { |
| 601 |
jQuery('#help-dialog').modal('show'); |
| 602 |
}); |
| 603 |
|
| 604 |
jQuery('#options').bind('click', function() { |
| 605 |
jQuery('#options-dialog').modal('show'); |
| 606 |
}); |
| 607 |
|
| 608 |
jQuery('#menu-options').bind('click', function() { |
| 609 |
jQuery('#options-dialog').modal('show'); |
| 610 |
}); |
| 611 |
|
| 612 |
jQuery('#audio').bind('click', function() { |
| 613 |
speechToText.start(); |
| 614 |
updateBar('mdi-av-mic', 'Start speaking', true); |
| 615 |
}); |
| 616 |
|
| 617 |
jQuery('#emoji').bind('change', function() { |
| 618 |
settings.emoji = document.getElementById('emoji').checked; |
| 619 |
localStorage.settings = JSON.stringify(settings); |
| 620 |
}); |
| 621 |
|
| 622 |
jQuery('#greentext').bind('change', function() { |
| 623 |
settings.greentext = document.getElementById('greentext').checked; |
| 624 |
localStorage.settings = JSON.stringify(settings); |
| 625 |
}); |
| 626 |
|
| 627 |
jQuery('#sound').bind('change', function() { |
| 628 |
settings.sound = document.getElementById('sound').checked; |
| 629 |
localStorage.settings = JSON.stringify(settings); |
| 630 |
}); |
| 631 |
|
| 632 |
jQuery('#synthesis').bind('change', function() { |
| 633 |
settings.synthesis = document.getElementById('synthesis').checked; |
| 634 |
localStorage.settings = JSON.stringify(settings); |
| 635 |
}); |
| 636 |
|
| 637 |
jQuery('#inline').bind('change', function() { |
| 638 |
settings.inline = document.getElementById('inline').checked; |
| 639 |
localStorage.settings = JSON.stringify(settings); |
| 640 |
}); |
| 641 |
|
| 642 |
jQuery('#desktop').bind('change', function() { |
| 643 |
settings.desktop = document.getElementById('desktop').checked; |
| 644 |
localStorage.settings = JSON.stringify(settings); |
| 645 |
|
| 646 |
if(Notification.permission !== 'granted') { |
| 647 |
Notification.requestPermission(); |
| 648 |
} |
| 649 |
}); |
| 650 |
|
| 651 |
jQuery('#recognition').bind('change', function() { |
| 652 |
settings.recognition = document.getElementById('recognition').checked; |
| 653 |
localStorage.settings = JSON.stringify(settings); |
| 654 |
|
| 655 |
if(settings.recognition) |
| 656 |
jQuery('#audio').show(); |
| 657 |
else { |
| 658 |
jQuery('#audio').hide(); |
| 659 |
} |
| 660 |
}); |
| 661 |
|
| 662 |
jQuery('#message').keypress(function(e) { |
| 663 |
if(e.which == 13) { |
| 664 |
if(connected && typing) { |
| 665 |
typing = false; |
| 666 |
clearTimeout(typeTimer); |
| 667 |
socket.send(JSON.stringify({type:'typing', typing:false})); |
| 668 |
} |
| 669 |
|
| 670 |
handleInput(); |
| 671 |
} else if(connected) { |
| 672 |
if(!typing) { |
| 673 |
typing = true; |
| 674 |
socket.send(JSON.stringify({type:'typing', typing:true})); |
| 675 |
} |
| 676 |
|
| 677 |
clearTimeout(typeTimer); |
| 678 |
typeTimer = setTimeout(function() { |
| 679 |
typing = false; |
| 680 |
socket.send(JSON.stringify({type:'typing', typing:false})); |
| 681 |
}, 2000); |
| 682 |
} |
| 683 |
}); |
| 684 |
|
| 685 |
//addition keypress binding for handling autocompletion |
| 686 |
jQuery("#message").keypress( function(event) { |
| 687 |
// don't navigate away from the field on tab when selecting an item |
| 688 |
if (event.keyCode === jQuery.ui.keyCode.TAB ) |
| 689 |
event.preventDefault(); |
| 690 |
}) |
| 691 |
.autocomplete({ |
| 692 |
minLength: 0, |
| 693 |
source: function(request, response) { |
| 694 |
var term = request.term; |
| 695 |
var results = []; |
| 696 |
term = term.split(/ \s*/).pop(); |
| 697 |
|
| 698 |
if (term.length > 0 && term[0] === '@') { |
| 699 |
var names = jQuery.map( clients, function( val ) { return val.un; }); |
| 700 |
results = jQuery.ui.autocomplete.filter(names, term.substr(1)); |
| 701 |
} |
| 702 |
response(results); |
| 703 |
}, |
| 704 |
focus: function() { |
| 705 |
return false; // prevent value inserted on focus |
| 706 |
}, |
| 707 |
select: function(event, ui) { |
| 708 |
var terms = this.value.split(/ \s*/); |
| 709 |
var old = terms.pop(); //get old word |
| 710 |
var ins = "@" + ui.item.value + " "; //new word to insert |
| 711 |
var ind = this.value.lastIndexOf(old); //location to insert at |
| 712 |
this.value = this.value.slice(0,ind) + ins; |
| 713 |
return false; |
| 714 |
} |
| 715 |
}); |
| 716 |
}); |
| 717 |
|
| 718 |
/* Internal */ |
| 719 |
if(Notification) { |
| 720 |
jQuery('#toggle-desktop').show(); |
| 721 |
} |
| 722 |
|
| 723 |
if('speechSynthesis' in window) { |
| 724 |
jQuery('#toggle-synthesis').show(); |
| 725 |
textToSpeech = new SpeechSynthesisUtterance(); |
| 726 |
textToSpeech.lang = 'en'; |
| 727 |
} |
| 728 |
|
| 729 |
if('SpeechRecognition' in window || 'webkitSpeechRecognition' in window) { |
| 730 |
jQuery('#toggle-recognition').show(); |
| 731 |
var speechToText = new webkitSpeechRecognition(); |
| 732 |
speechToText.interimResults = true; |
| 733 |
speechToText.continuous = true; |
| 734 |
speechToText.lang = 'en-US'; |
| 735 |
} |
| 736 |
|
| 737 |
if(speechToText) { |
| 738 |
speechToText.onresult = function(event) { |
| 739 |
jQuery('#message').val(''); |
| 740 |
|
| 741 |
for (var i = event.resultIndex; i < event.results.length; ++i) { |
| 742 |
if (event.results[i].isFinal) { |
| 743 |
jQuery('#message').val(event.results[i][0].transcript); |
| 744 |
updateBar('mdi-content-send', 'Enter your message here', false); |
| 745 |
speechToText.stop(); |
| 746 |
handleInput(); |
| 747 |
} else { |
| 748 |
var oldval = jQuery('#message').val(); |
| 749 |
jQuery('#message').val(oldval + event.results[i][0].transcript); |
| 750 |
} |
| 751 |
} |
| 752 |
} |
| 753 |
|
| 754 |
speechToText.onerror = function(event) { |
| 755 |
updateBar('mdi-content-send', 'Enter your message here', false); |
| 756 |
} |
| 757 |
|
| 758 |
} |
| 759 |
|
| 760 |
function desktopNotif(message) { |
| 761 |
if(!Notification) { |
| 762 |
return; |
| 763 |
} |
| 764 |
|
| 765 |
var notification = new Notification('You\'ve got a new message', { |
| 766 |
icon: 'http://i.imgur.com/ehB0QcM.png', |
| 767 |
body: message |
| 768 |
}); |
| 769 |
} |
| 770 |
|
| 771 |
if(typeof(Storage) !== 'undefined') { |
| 772 |
if(!localStorage.settings) { |
| 773 |
localStorage.settings = JSON.stringify(settings); |
| 774 |
} else { |
| 775 |
settings = JSON.parse(localStorage.settings); |
| 776 |
if(settings.recognition) { |
| 777 |
jQuery('#audio').show(); |
| 778 |
} |
| 779 |
} |
| 780 |
} |
| 781 |
|
| 782 |
window.onfocus = function() { |
| 783 |
// document.title = 'Node.JS Chat'; |
| 784 |
focus = true; |
| 785 |
unread = 0; |
| 786 |
}; |
| 787 |
|
| 788 |
|
| 789 |
window.onblur = function() { |
| 790 |
focus = false; |
| 791 |
}; |