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

791 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 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('&gt;') == 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 };