diff options
Diffstat (limited to 'webclient/client.html')
| -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{ | 
