PluginProbe
WpStream – Live Streaming, Video on Demand, Pay Per View / 4.8
WpStream – Live Streaming, Video on Demand, Pay Per View v4.8
4.14.1 4.14.0 4.13.2 4.13.1 4.13 4.12.5 4.12.4 4.12.3 4.12.2 4.12.1 4.12 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5 4.5.1 4.5.11 4.5.11.1 4.5.11.2 4.5.11.4 4.5.11.5 4.5.11.6 All 181 releases
wpstream / public / chat_lib / chat.js

chat.js in WpStream – Live Streaming, Video on Demand, Pay Per View 4.8, at public/chat_lib/chat.js

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