PluginProbe
WpStream – Live Streaming, Video on Demand, Pay Per View / 3.3
WpStream – Live Streaming, Video on Demand, Pay Per View v3.3
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 3.3, at public/chat_lib/chat.js

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