diff options
-rw-r--r-- | webclient/client.html | 178 |
1 files changed, 150 insertions, 28 deletions
diff --git a/webclient/client.html b/webclient/client.html index 3472cb8..2305c17 100644 --- a/webclient/client.html +++ b/webclient/client.html @@ -7,13 +7,13 @@ var sock=null,username=null; var roomlist=[":console"]; var currentroom=":console"; -var roomlogs={":console":[]}; +var roomlogs=new Map([[":console",[]]]); -(function(){ +var uniqid=(function(){ var id=1; - function uniqid(){ + return function uniqid(){ return id++; - } + }; })(); var net_callbacks={}; @@ -24,6 +24,32 @@ function net_send(msg,cb){ net_callbacks[id]=cb; } +function fancysplit(text,freespace){ + var obj={ + word: [], + rest: [], + }; + var cursor=0,idx; + if(freespace){ + while(cursor<text.length&&text[cursor]==" ")cursor++; + } + while(cursor<text.length){ + idx=text.indexOf(" ",cursor); + if(idx==-1)idx=text.length; + obj.word.push(text.slice(cursor,idx)); + obj.rest.push(text.slice(cursor)); + if(idx==text.length)break; + cursor=idx+1; + if(freespace){ + while(cursor<text.length&&text[cursor]==" ")cursor++; + } else if(cursor==text.length){ + obj.word.push(""); + obj.rest.push(""); + } + } + return obj; +} + function reconnect(){ if(sock)sock.close(); @@ -34,14 +60,13 @@ function reconnect(){ updateStatus(); updateRoomList(); sock.addEventListener("message",function(msg){ - var spl=msg.split(" ",2); - var id=spl[0],type=spl[1]; - var rest=msg.slice(id.length+type.length+2); + var spl=fancysplit(msg.data,false); + console.log(msg.data); + var id=spl.word[0],type=spl.word[1]; if(id=="_push"){ if(type=="message"){ - spl=rest.split(" ",2); - var r=spl[0],u=spl[1]; - addRoomEntry(r,"message",[u,rest.slice(r.length+u.length+2)]); + var r=spl.word[2],u=spl.word[3]; + addRoomEntry(r,"message",[u,spl.rest[4]]); } else { alert("Unknown push message type '"+type+"'!"); } @@ -49,9 +74,9 @@ function reconnect(){ var fn=net_callbacks[id]; var obj; if(type=="ok")fn(true); - else if(type=="error")fn(null,rest); - else if(type=="name")fn(rest); - else if(type=="list")fn(rest.split(" ").slice(1)); + else if(type=="error")fn(null,spl.rest[2]); + else if(type=="name")fn(spl.rest[2]); + else if(type=="list")fn(spl.word.slice(3)); else alert("Unknown server response message type '"+type+"'!"); } else { alert("No callback for server message id '"+id+"'!"); @@ -70,6 +95,27 @@ function reconnect(){ }); } +function fetchRoomList(){ + net_send("list_rooms",function(list,err){ + if(err){ + addRoomEntry(":console","error",["Unable to fetch room list: "+err]); + } else { + var roomid; + for(roomid in roomlogs.keys()){ + if(roomid!=":console")roomlogs.delete(roomid); + } + roomlist=[":console"]; + var i; + for(i=0;i<list.length;i++){ + roomlist.push(list[i]); + roomlogs.set(list[i],[]); + // fetchRoomHistory(list[i]); + } + updateRoomList(); + } + }); +} + function updateStatus(){ var str=null; if(!sock||sock.readyState>=2){ @@ -99,7 +145,9 @@ function updateRoomList(){ if(roomlist[i]==currentroom)div.classList.add("selected"); div.addEventListener("click",function(roomid){ currentroom=roomid; + updateRoomList(); drawRoom(currentroom); + document.getElementById("roominput").focus(); }.bind(this,roomlist[i])); div.appendChild(document.createTextNode(roomlist[i])); rldiv.appendChild(div); @@ -117,7 +165,7 @@ function drawRoom(roomid){ else roomtitle.firstChild.nodeValue=roomid; var tr,td; - var items=roomlogs[roomid]; + var items=roomlogs.get(roomid); if(!items){ alert("drawRoom on nonexistent roomid '"+roomid+"'!"); return; @@ -130,17 +178,28 @@ function drawRoom(roomid){ function drawRoomEntry(type,args){ var tbody=document.getElementById("roomlog"); var tr=document.createElement("tr"); - var td; + var td1=document.createElement("td"),td2=document.createElement("td"); + var node1=document.createTextNode(""),node2=document.createTextNode(""); + td1.appendChild(node1); td2.appendChild(node2); + tr.appendChild(td1); tr.appendChild(td2); + tbody.appendChild(tr); switch(type){ case "message": - td=document.createElement("td"); - td.appendChild(document.createTextNode(args[0])); - tr.appendChild(td); - td=document.createElement("td"); - td.classList.add("message"); - td.appendChild(document.createTextNode(args[1])); - tr.appendChild(td); - tbody.appendChild(tr); + tr.classList.add("message"); + node1.nodeValue="<"+args[0]+">"; + node2.nodeValue=args[1]; + break; + + case "error": + tr.classList.add("error"); + node1.nodeValue="--"; + node2.nodeValue=args[0]; + break; + + case "notice": + tr.classList.add("notice"); + node1.nodeValue="--"; + node2.nodeValue=args[0]; break; default: @@ -150,21 +209,73 @@ function drawRoomEntry(type,args){ } function addRoomEntry(roomid,type,args){ - if(!roomlogs[roomid]){ + if(!roomlogs.get(roomid)){ alert("addRoomEntry on nonexistent roomid '"+roomid+"'!"); return; } - roomlogs[roomid].push([type,args]); + roomlogs.get(roomid).push([type,args]); if(roomid==currentroom){ drawRoomEntry(type,args); } } +function executeCommand(roomid,text){ + var spl=fancysplit(text,true); + if(spl.word.length==0)return; + var cmd=spl.word[0]; + var creds=null; + switch(cmd){ + case "register": + case "login": + if(spl.word.length<3){ + addRoomEntry(roomid,"error",["Usage: /login <username> <password>"]); + break; + } + creds=[spl.word[1],spl.rest[2]]; + net_send(cmd+" "+creds[0]+" "+creds[1],function(ok,err){ + if(ok){ + username=creds[0]; + addRoomEntry(roomid,"notice",["Logged in as user '"+creds[0]+"'"]); + updateStatus(); + fetchRoomList(); + } else { + addRoomEntry(roomid,"error",["Unable to "+cmd+": "+err]); + } + }); + break; + + default: + addRoomEntry(roomid,"error",["Unknown command '"+cmd+"'"]); + break; + } +} + +function sendMessage(roomid,text){ + if(roomid[0]==":"){ + addRoomEntry(roomid,"error",["Cannot send a message here"]); + return; + } + var sentAs=username,msg=text.replace(/\n/g,""); + net_send("send "+roomid+" "+msg,function(ok,err){ + if(ok){ + addRoomEntry(roomid,"message",[sentAs,msg]); + return; + } + addRoomEntry(roomid,"error",["Unable to send message: "+err]); + }); +} + function doSend(){ var inputelem=document.getElementById("roominput"); var text=inputelem.value; inputelem.value=""; - addRoomEntry(currentroom,"message",["-",text]); + + if(text.length==0)return; + if(text[0]=="/"){ + executeCommand(currentroom,text.slice(1)); + } else { + sendMessage(currentroom,text); + } } function doKeypress(ev){ @@ -174,6 +285,7 @@ function doKeypress(ev){ window.addEventListener("load",function(){ reconnect(); drawRoom(currentroom); + document.getElementById("roominput").focus(); }); </script> <style> @@ -215,7 +327,7 @@ table{ margin:8px 0px 10px 0px; } .roomlistitem{ - margin:1px 0px; + margin:2px 0px; padding:3px 2px; background-color:#223; cursor:pointer; @@ -251,10 +363,20 @@ table{ } #roomlog_table{ width:100%; - /*height:100%;*/ } #roomlog > tr > td:first-child{ width:150px; + padding-right:20px; + text-align:right; +} +#roomlog > tr.message{ + color:inherit; +} +#roomlog > tr.error{ + color:#f44; +} +#roomlog > tr.notice{ + color:#a8f; } #roombar_tr{ |