diff --git a/model.py b/model.py index e7b855b..a6c45f8 100644 --- a/model.py +++ b/model.py @@ -41,6 +41,9 @@ class Model(object): self.model["clients"] = {} if not "sessions" in self.model: self.model["sessions"] = {} + for session in self.model["sessions"]: + if not "name" in self.model["sessions"][session]: + self.model["sessions"][session]["name"] = "Defaultname" @ApiMethod async def test_api(self, clientid): @@ -56,34 +59,50 @@ class Model(object): await self.send_state(clientid) @ApiMethod - async def create_session(self, clientid) -> str: - sessionname = generate_random_id() - newsession = {"id": sessionname, "owner": clientid, "clients": []} - self.model["sessions"][sessionname] = newsession + async def create_session(self, clientid, sessionname) -> str: + if not sessionname: + raise Exception("Cant be empty!") + sessionid = generate_random_id() + newsession = {"id": sessionid, "owner": clientid, "clients": [], "name": sessionname } + self.model["sessions"][sessionid] = newsession + await self.send_state(clientid) + + @ApiMethod + async def change_sessionname(self, clientid, sessionid, sessionname) -> str: + if not sessionname: + raise Exception("Cant be empty!") + if self.model["sessions"][sessionid]["owner"] == clientid: + self.model["sessions"][sessionid]["name"] = sessionname + await self.send_state(clientid) + + @ApiMethod + async def leave_session(self, clientid): + sessionid = self.model["clients"][clientid]["session"] + del self.model["clients"][clientid]["session"] + self.model["sessions"][sessionid]["clients"].remove(clientid) await self.send_state(clientid) @ApiMethod async def join_session(self, clientid, sessionid): if sessionid in self.model["sessions"]: - # remove old session - if "session" in self.model["clients"][clientid]: - oldsession = self.model["clients"][clientid]["session"] - self.model["sessions"][oldsession]["clients"].remove(clientid) - - self.model["sessions"][sessionid]["clients"].append(clientid) + # session exists self.model["clients"][clientid]["session"] = sessionid - await self.send_state(clientid) - else: - raise Exception(f"Session {sessionid} does not exist") + if not clientid in self.model["sessions"][sessionid]["clients"]: + self.model["sessions"][sessionid]["clients"].append(clientid) + await self.send_state(clientid) async def send_state(self, clientid): # TODO: compute state, send to client - session = "No session" + data = {} if "session" in self.model["clients"][clientid]: - session = self.model["clients"][clientid]["session"] - allsessions = [ name for name in self.model["sessions"] ] - username = self.model["clients"][clientid]["username"] if "username" in self.model["clients"][clientid] else "Joe" - data = {"currentsession": session, "allsessions": allsessions, "username": username} + sessionid = self.model["clients"][clientid]["session"] + data["session"] = {"id": sessionid, "name": self.model["sessions"][sessionid]["name"] } + allsessions = { name: { "id": name, "name": self.model["sessions"][name]["name"] } for name in self.model["sessions"] } + for session in allsessions: + if self.model["sessions"][session]["owner"] == clientid: + allsessions[session]["owner"] = True + data["allsessions"] = allsessions + data["username"] = self.model["clients"][clientid]["username"] if "username" in self.model["clients"][clientid] else "Joe" for socket in self.sockets[clientid]: await socket.send_json(data) @@ -103,8 +122,10 @@ class Model(object): return clientid in self.model["clients"] def create_client(self, name="Joe") -> str: + if not name: + raise Exception("Username cannot be empty!") clientname = generate_random_id() - newclient = {"id": clientname, "username": name} + newclient = {"id": clientname, "username": name, "sessions": []} self.model["clients"][clientname] = newclient return clientname diff --git a/static/renderer.js b/static/renderer.js index dd1ab31..bf5a868 100644 --- a/static/renderer.js +++ b/static/renderer.js @@ -6,12 +6,16 @@ ws.onmessage = function(event) { const msg = JSON.parse(event.data); console.log(msg); - - if (msg.hasOwnProperty('currentsession')) { - document.getElementById('current_session').innerText = msg.currentsession; + + if (msg.hasOwnProperty('session')) { + document.getElementById('active-session').innerText = msg.session["name"]; + document.getElementById('btn-leave-session').style.display = "inline-block"; + } else { + document.getElementById('active-session').innerText = "None"; + document.getElementById('btn-leave-session').style.display = "none"; } if (msg.hasOwnProperty('username')) { - document.getElementById('greeting').innerText = "Hello, " + msg.username + "!"; + document.getElementById('label-username').innerText = msg.username; } if (msg.hasOwnProperty('allsessions')) { @@ -19,13 +23,81 @@ ws.onmessage = function(event) { while (all_sessions.children.length) all_sessions.lastChild.remove(); - for (let session of msg.allsessions) { - const button = document.createElement('button'); - button.innerText = session; - button.onclick = async (e) => await fetch('api/join_session', { - method: 'POST', body: JSON.stringify({sessionid: session}) - }); - all_sessions.appendChild(button); - } + //for (let session in msg.allsessions) { + Object.keys(msg.allsessions).forEach( session => { + + var sessionid = msg.allsessions[session]["id"] + var sessionname = msg.allsessions[session]["name"] + const tehsession = document.createElement('div'); + + const labelname = document.createElement('span'); + owned = ("owner" in msg.allsessions[session]); + labelname.innerText = sessionname; + + tehsession.appendChild(labelname); + + if (owned) { + const inputname = document.createElement('input'); + inputname.style.display = "none"; + const btnedit = document.createElement('button'); + btnedit.innerText = '🖉' + const btnconfirm = document.createElement('button'); + btnconfirm.innerText = '✔' + btnconfirm.style.display = "none" + const btndiscard = document.createElement('button'); + btndiscard.innerText = '✘' + btndiscard.style.display = "none" + + btnedit.onclick = async function (e) { + inputname.style.display = "inline-block"; + inputname.value = sessionname; + btnedit.style.display = "none"; + btnconfirm.style.display = "inline-block"; + btndiscard.style.display = "inline-block"; + labelname.style.display = "none"; + } + btndiscard.onclick = async function (e) { + inputname.style.display = "none"; + btnedit.style.display = "inline-block"; + btnconfirm.style.display = "none"; + btndiscard.style.display = "none"; + labelname.style.display = "inline-block"; + } + btnconfirm.onclick = async function (e) { + text = inputname.value; + if (Boolean(text)) { + let data = {"sessionid": sessionid, "sessionname": text}; + await fetch('api/change_sessionname', { + method: 'POST', + body: JSON.stringify(data), + }); + inputname.style.display = "none"; + btnedit.style.display = "inline-block"; + btnconfirm.style.display = "none"; + btndiscard.style.display = "none"; + labelname.style.display = "inline-block"; + } else { + console.log("cant be empty"); + } + } + + tehsession.appendChild(inputname); + tehsession.appendChild(btnedit); + tehsession.appendChild(btnconfirm); + tehsession.appendChild(btndiscard); + } + + if ((! msg.hasOwnProperty('session')) || msg.session["id"] != sessionid) { + const btnjoin = document.createElement('button'); + btnjoin.innerText = "Join"; + btnjoin.onclick = async (e) => await fetch('api/join_session', { + method: 'POST', body: JSON.stringify({"sessionid": sessionid}) + }); + + tehsession.appendChild(btnjoin); + } + + all_sessions.appendChild(tehsession); + }) } }; diff --git a/ui.html b/ui.html index 279e14c..6f9e4db 100644 --- a/ui.html +++ b/ui.html @@ -4,49 +4,104 @@ leafblade Minecraft Server +
+
+ Hello, + _ + + + + +

-You are not in any session.
+ +
+Active Session:None + +
+
+ +
+ +Available sessions


- +
+ +Create Session
+ + +
+