/** * @licstart The following is the entire license notice for the * JavaScript code in this page. * * Copyright (C) 2015 Alicia ( https://ion.nu/ ) * * The JavaScript code in this page is free software: you can * redistribute it and/or modify it under the terms of the GNU * Affero General Public License (GNU AGPL) as published by the Free Software * Foundation, version 3 of the License. * The code is distributed WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU AGPL for more details. * * As additional permission under GNU AGPL version 3 section 7, you * may distribute non-source (e.g., minimized or compacted) forms of * that code without the copy of the GNU AGPL normally required by * section 4, provided you include this license notice and a URL * through which recipients can access the Corresponding Source. * * @licend The above is the entire license notice * for the JavaScript code in this page. */ var userlist=new Array(); var nickname=''; // Will be set with 'startnick:' var me; function User(name) { this.nickname=name; this.listlabel=document.createElement("span"); this.listlabel.textContent=this.nickname; this.listlabel.style.display='block'; var user=this; this.listlabel.oncontextmenu=function(e) // this.listlabel.onclick=function(e) { usermenu(user, e.pageX, e.pageY); return false; }; this.color='000000'; this.modprivileges=0; this.broadcasting=false; document.getElementById('userlist').appendChild(this.listlabel); } function finduser(name) { var i=0; while(i<userlist.length) { if(userlist[i].nickname==name){return userlist[i];} ++i; } return false; } function chatnoteon(msg, tab) { var scroll=(!tab.chat.scrollTopMax || tab.chat.scrollTop==tab.chat.scrollTopMax); var text=document.createElement("div"); text.textContent=msg; tab.chat.appendChild(text); if(scroll){text.scrollIntoView();} } function chatnote(msg) { chatnoteon(msg, tabs[0]); } function twodigits(num) { num=num.toString(); while(num.length<2){num='0'+num;} return num; } var unseenmessages=0; function chatmsgon(name, msg, color, tab) { if(msg.substring(0,6)=='video:') // TODO: Proper command, and mod privileges to play them { document.getElementById('videoplayer').style.display='inline-block'; document.getElementById('videoplayerframe').src='https://www.youtube-nocookie.com/embed/'+msg.substring(6,msg.length)+'?rel=0&controls=0&showinfo=0&autoplay=1'; showcams(); chatnote(name+' started a video'); return; } if(document.hasFocus && !document.hasFocus()) { ++unseenmessages; document.title='('+unseenmessages+' unseen messages) Chat (work in progress)'; } var scroll=(!tab.chat.scrollTopMax || tab.chat.scrollTop==tab.chat.scrollTopMax); var line=document.createElement("div"); var timestamp=document.createElement("pre"); var date=new Date(); timestamp.textContent='['+twodigits(date.getHours())+':'+twodigits(date.getMinutes())+']'; var text=document.createElement("span"); if(msg.substring(0,4)=='/me ') { text.textContent='* '+name+' '+msg.substring(4,msg.length); }else{ text.textContent=name+': '+msg; } text.style.color='#'+color; line.appendChild(timestamp); line.appendChild(text); tab.chat.appendChild(line); if(scroll){text.scrollIntoView();} if(tab!=currenttab){tab.tab.className='tab tabactivity';} } function chatmsg(name, msg, color) { chatmsgon(name, msg, color, tabs[0]); } var connection; function connect(channel, password) { if(password===undefined) { connection=new WebSocket(chatdprotocol+chatd+'/chat/'+channel, 'chat-0.1'); }else{ connection=new WebSocket(chatdprotocol+chatd+'/chat/'+channel+'?password='+encodeURIComponent(password), 'chat-0.1'); } connection.onmessage=handlecommands; connection.onclose=function(){chatnote('-'); chatnote('The connection to the server was lost. Reload the page to reconnect');}; } function sendmsg() { if(currenttab.dead){return;} // Don't send to dead tabs var msg=document.getElementById('message').value; document.getElementById('message').value=''; if(msg==''){return;} if(msg.substring(0,6)=='/nick '){connection.send('nick:'+msg.substring(6,msg.length)); return;} if(currenttab==tabs[0]) { chatmsg(nickname, msg, me.color); connection.send('msg:'+msg); }else{ // PMs chatmsgon(nickname, msg, me.color, currenttab); connection.send('pm:'+currenttab.name+':'+msg); } } function setcolor(color) { if(color.substring(0,1)=='#'){color=color.substring(1,color.length);} connection.send('color:'+color); me.color=color; me.listlabel.style.color='#'+color; } var channelname; function init(channel) { channelname=channel; tabs.push(new Tab('Main')); document.getElementById('color').value='#000000'; // The color defaults to black, but sometimes input values are retained when reloading the page connect(channel); } function setheightcalc(element, calc) { element.style.height='calc('+calc+')'; element.style.height='-webkit-calc('+calc+')'; element.style.height='-moz-calc('+calc+')'; element.style.height='-o-calc('+calc+')'; element.style.height='-ms-calc('+calc+')'; } function closevideo() { document.getElementById('videoplayer').style.display='none'; document.getElementById('videoplayerframe').src='about:blank'; // Close the cam pane if no one is on cam if(cams.length==0){hidecams();} } function handleclick() { document.getElementById('usermenu').style.display='none'; } function changenick() { var newnick=prompt('New nickname?', nickname); if(newnick){connection.send('nick:'+newnick);} } function usermenu(user, x, y) { if(document.body.clientWidth && x>document.body.clientWidth/2) { document.getElementById('usermenu').style.right=(document.body.clientWidth-x)+'px'; document.getElementById('usermenu').style.left='auto'; }else{ document.getElementById('usermenu').style.left=x+'px'; document.getElementById('usermenu').style.right='auto'; } document.getElementById('usermenu').style.top=y+'px'; document.getElementById('usermenu').style.display='block'; // Send private message document.getElementById('usermenu').children.pm.onclick=function() { var tab=findtab(user.nickname); if(!tab){tabs.push(tab=new Tab(user.nickname));} tab.focus(); document.getElementById('usermenu').style.display='none'; }; // Account/profile document.getElementById('usermenu').children.whois.onclick=function() { connection.send('whois:'+user.nickname); document.getElementById('usermenu').style.display='none'; } // Show/hide media streams if(user.broadcasting) { if(user.cam) { document.getElementById('usermenu').children.showmedia.style.display='none'; document.getElementById('usermenu').children.hidemedia.style.display='block'; document.getElementById('usermenu').children.hidemedia.onclick=function() { closecam(user); document.getElementById('usermenu').style.display='none'; } }else{ document.getElementById('usermenu').children.hidemedia.style.display='none'; document.getElementById('usermenu').children.showmedia.style.display='block'; document.getElementById('usermenu').children.showmedia.onclick=function() { opencam(user); document.getElementById('usermenu').style.display='none'; } } }else{ document.getElementById('usermenu').children.showmedia.style.display='none'; document.getElementById('usermenu').children.hidemedia.style.display='none'; } // Close media stream if(me.modprivileges&PRIV_CLOSECAM && user.broadcasting) { document.getElementById('usermenu').children.closemedia.style.display='block'; document.getElementById('usermenu').children.closemedia.onclick=function() { connection.send('closemedia:'+user.nickname); document.getElementById('usermenu').style.display='none'; } }else{ document.getElementById('usermenu').children.closemedia.style.display='none'; } // Ban if(me.modprivileges&PRIV_KICK) { document.getElementById('usermenu').children.ban.style.display='block'; document.getElementById('usermenu').children.ban.onclick=function() { connection.send('ban:'+user.nickname); document.getElementById('usermenu').style.display='none'; } }else{ document.getElementById('usermenu').children.ban.style.display='none'; } } function login(form) { document.getElementById('login').style.display='none'; connection.send('login:'+form.user.value+':'+form.pass.value); form.pass.value=''; } function createaccount(form) { // TODO: Check username availability upon onchange if(form.user.value.indexOf(':')>-1) { alert('Error: Usernames may not contain :'); } if(form.pass.value!=form.pass2.value) { alert('Error: Passwords don\'t match!'); return; } connection.send('createaccount:'+form.user.value+':'+form.pass.value); form.pass.value=''; form.pass2.value=''; document.getElementById('createaccount').style.display='none'; } function showfullscreen(name, focus) { document.getElementById(name).style.display='block'; if(focus) { document.getElementById(focus).focus(); document.getElementById(focus).select(); } } function setupmodmanager() { var list=document.getElementById('modmanagerlist'); while(list.children.length>0) { list.removeChild(list.children[0]); } connection.send('listmods'); } function addmoderator() { connection.send('addmod:'+document.getElementById('addmod_account').value+':'+PRIV_NONOWNER); document.getElementById('addmod_account').value=''; } function setupbanlist() { document.getElementById('banlist_placeholder').style.display='inline-block'; var list=document.getElementById('banlist_list'); while(list.children.length>0) { list.removeChild(list.children[0]); } connection.send('listbans'); }