diff --git a/server/src/manager/data.rs b/server/src/manager/data.rs index 8cf04a2..2db08b0 100644 --- a/server/src/manager/data.rs +++ b/server/src/manager/data.rs @@ -732,6 +732,8 @@ pub async fn thread_system(mut app:App, bus:Bus) send_user_status.push(session.p_dusk.user); session.undo = 0; + } else { + println!("notice: bad play {} {} {}", play.source, play.from, play.to); } } } diff --git a/www/js/const.js b/www/js/const.js index de92466..32e6605 100644 --- a/www/js/const.js +++ b/www/js/const.js @@ -1,7 +1,5 @@ let MAIN = null; let MENU = null; -let SCENE = null; -let SCENE_STACK = [ ]; let CONNECTED = false; let SOCKET = null; diff --git a/www/js/interface.js b/www/js/interface.js index 629864d..6797374 100644 --- a/www/js/interface.js +++ b/www/js/interface.js @@ -1355,8 +1355,11 @@ const INTERFACE = { } }, - message(code, data) { - if(data === null) { return; } + message(msg) { + if(msg === null) { return; } + + let code = msg.code; + let data = msg.data; switch(code) { case OpCode.GameState: { diff --git a/www/js/main.js b/www/js/main.js index 1b33440..7084e5f 100644 --- a/www/js/main.js +++ b/www/js/main.js @@ -1,7 +1,7 @@ document.addEventListener("DOMContentLoaded", () => { - SCENE = SCENES.Offline; - LOAD(SCENES.Init); + SCENE.load(SCENES.Offline); + SCENE.load(SCENES.Init); - document.addEventListener("beforeunload", UNLOAD); - window.addEventListener("popstate", LOAD_URL); + document.addEventListener("beforeunload", SCENE.unload); + window.addEventListener("popstate", SCENE.load_url); }); diff --git a/www/js/scene.js b/www/js/scene.js index b799a6f..9e53319 100644 --- a/www/js/scene.js +++ b/www/js/scene.js @@ -1,8 +1,119 @@ +class SceneManager { + constructor() { + this.scene = null; + this.preload = false; + } + + load(scene, data=null) { + this.unload(); + UI.rebuild(); + + if(scene !== null) { + // Prepare new scene + this.scene = new scene(); + + // Preload scene if defined + if(this.scene.preload !== undefined) { + if(this.scene.preload(data, null)) { + this.preload = true; + } else { + this.scene.load(SCENES.Browse); + } + } + + // Otherwise, load scene + else { + this.preload = false; + this.scene.load(data); + UI.update_status(); + } + } + } + + unload() { + if(!this.preload && this.scene !== null && this.scene.unload !== undefined) { + this.scene.unload(); + } + } + + load_url() { + let parts = window.location.pathname.split("/"); + + if(parts.length > 1) { + switch(parts[1]) { + case "continue": this.load(SCENES.Continue); return; + case "live": this.load(SCENES.Live); return; + case "history": this.load(SCENES.History); return; + case "practice": this.load(SCENES.GamePractice); return; + case "guide": this.load(SCENES.Guide); return; + case "about": this.load(SCENES.About); return; + case "challenge": this.load(SCENES.Challenge); return; + case "extras": this.load(SCENES.Extras); return; + + case "game": { + if(parts[2]) { + let token = UNPACK.base64(parts[2] + "="); + this.load(SCENES.GameLoad, { + token:token, + mode:INTERFACE.Mode.Review, + }); + return; + } + } break; + + case "u": { + if(parts[2]) { + this.load(SCENES.Profile, { + handle:parts[2], + }); + return; + } + } break; + } + } + this.load(SCENES.Browse); + } + + disconnect() { + if(this.scene !== null && this.scene.disconnect !== undefined) { + this.scene.disconnect(); + } + } + + message(msg) { + if(this.scene !== null) { + // Handle preloading scene + if(this.preload) { + + // Send message to preloader + let result = this.scene.load(msg); + + // Finalize scene if load successful + if(result === true) { + this.preload = false; + UI.update_status(); + } + + // Load default scene if preload failed + else if(result === false) { + this.load(SCENES.Browse); + } + } + + // Handle loaded scene + else { + this.scene.message(msg); + } + } + } +} + +let SCENE = new SceneManager(); const SCENES = { Init: class{ constructor() { } load() { - LOAD(SCENES.Offline); + SCENE.load(SCENES.Offline); RECONNECT(); return true; } @@ -13,17 +124,17 @@ const SCENES = { load() { UI.nav([ UI.button(LANG("reconnect"), () => { RECONNECT(); }), - UI.button(LANG("practice"), () => { LOAD(SCENES.GamePractice); }), + UI.button(LANG("practice"), () => { SCENE.load(SCENES.GamePractice); }), ], []); return true; } - message(code, data) { - switch(code) { + message(msg) { + switch(msg.code) { case OpCode.Hello: { console.log("CLIENT VERSION: '" + CONFIG_VERSION + "'"); - console.log("SERVER VERSION: '" + data.version + "'"); + console.log("SERVER VERSION: '" + msg.data.version + "'"); - if(CONFIG_VERSION == data.version) { + if(CONFIG_VERSION == msg.data.version) { RESUME(); } else { location.reload(); @@ -111,21 +222,21 @@ const SCENES = { return true; } - message(code, data) { - if(code == OpCode.Register && data !== null) { + message(msg) { + if(msg.code == OpCode.Register && msg.data !== null) { let submit = document.getElementById("submit"); - switch(data.status) { + switch(msg.data.status) { case Status.Ok: { - let b64_token = PACK.base64(data.token); - let b64_secret = PACK.base64(data.secret); + let b64_token = PACK.base64(msg.data.token); + let b64_secret = PACK.base64(msg.data.secret); sessionStorage.setItem("auth", b64_token); sessionStorage.setItem("auth_secret", b64_secret); - LOAD_URL(); + SCENE.load_url(); } break; default: { submit.removeAttribute("disabled"); - switch(data.status) { + switch(msg.data.status) { case Status.BadHandle: { document.getElementById("handle").setAttribute("class", "error"); submit.setAttribute("class", "error"); @@ -144,7 +255,7 @@ const SCENES = { } } disconnect() { - LOAD(SCENES.Offline); + SCENE.load(SCENES.Offline); } }, @@ -208,17 +319,17 @@ const SCENES = { return true; } - message(code, data) { - if(code == OpCode.Authenticate && data !== null) { + message(msg) { + if(msg.code == OpCode.Authenticate && msg.data !== null) { let submit = document.getElementById("submit"); - switch(data.status) { + switch(msg.data.status) { case Status.Ok: { - sessionStorage.setItem("auth", PACK.base64(data.token)); - sessionStorage.setItem("auth_secret", PACK.base64(data.secret)); + sessionStorage.setItem("auth", PACK.base64(msg.data.token)); + sessionStorage.setItem("auth_secret", PACK.base64(msg.data.secret)); CONTEXT.Auth = { - handle: data.handle, + handle: msg.data.handle, }; - LOAD_URL(); + SCENE.load_url(); } break; case Status.Error: { submit.removeAttribute("disabled"); @@ -231,16 +342,27 @@ const SCENES = { } } disconnect() { - LOAD(SCENES.Offline); + SCENE.load(SCENES.Offline); } }, Browse:class{ constructor() { + this.data = null; this.page = 1; this.pages = 1; } - load() { + preload() { + this.refresh(); + return true; + } + load(msg) { + if(msg.code != OpCode.SessionList) { + return null; + } else { + this.data = msg.data.records; + } + if(SOCKET !== null) { UI.mainmenu("browse"); @@ -252,14 +374,14 @@ const SCENES = { [ indicator_page, UI.button("◀", () => { - if(SCENE.page < SCENE.pages) { SCENE.page += 1; } - SCENE.refresh(); + if(this.page < this.pages) { this.page += 1; } + this.refresh(); }), UI.button("▶", () => { - if(SCENE.page > 1) { SCENE.page -= 1; } - SCENE.refresh(); + if(this.page > 1) { this.page -= 1; } + this.refresh(); }), - UI.button(LANG("refresh"), () => { SCENE.referesh(); }), + UI.button(LANG("refresh"), () => { this.referesh(); }), ], { auth:true, session:true } ); @@ -267,20 +389,19 @@ const SCENES = { let table = document.createElement("table"); table.setAttribute("id", "content"); table.setAttribute("class", "list session"); + table.appendChild(UI.session_table(this.data)); UI.maincontent(table); - SCENE.refresh(); - history.pushState(null, "Dzura", "/"); } else { - LOAD(SCENES.Offline); + SCENE.load(SCENES.Offline); } return true; } refresh() { MESSAGE_SESSION_LIST(this.page, 2, false, false); } - message(code, data) { + /*message(code, data) { switch(code) { case OpCode.SessionList: { let table = document.getElementById("content"); @@ -292,18 +413,29 @@ const SCENES = { } } break; } - } + }*/ disconnect() { - LOAD(SCENES.Offline); + SCENE.load(SCENES.Offline); } }, Continue:class{ constructor() { + this.data = null; this.page = 1; this.pages = 1; } - load() { + preload() { + this.refresh(); + return true; + } + load(msg) { + if(msg.code != OpCode.SessionList) { + return null; + } else { + this.data = msg.data.records; + } + if(sessionStorage.getItem("auth") === null) return false; UI.mainmenu("continue"); @@ -316,32 +448,31 @@ const SCENES = { [ indicator_page, UI.button("◀", () => { - if(SCENE.page < SCENE.pages) { SCENE.page += 1; } - SCENE.refresh(); + if(this.page < this.pages) { this.page += 1; } + this.refresh(); }), UI.button("▶", () => { - if(SCENE.page > 1) { SCENE.page -= 1; } - SCENE.refresh(); + if(this.page > 1) { this.page -= 1; } + this.refresh(); }), - UI.button(LANG("refresh"), () => { SCENE.referesh(); }), + UI.button(LANG("refresh"), () => { this.referesh(); }), ], { auth:true, session:true } ); let table = document.createElement("table"); table.setAttribute("id", "content"); - table.setAttribute("class", "list session-resume"); + table.setAttribute("class", "list session"); + table.appendChild(UI.session_table(this.data)); UI.maincontent(table); - SCENE.refresh(); - history.pushState(null, "Dzura - Continue", "/continue/"); return true; } refresh() { MESSAGE_SESSION_LIST(this.page, 2, true, false); } - message(code, data) { + /*message(code, data) { switch(code) { case OpCode.SessionList: { let table = document.getElementById("content"); @@ -353,74 +484,29 @@ const SCENES = { } } break; } - } + }*/ disconnect() { - LOAD(SCENES.Offline); + SCENE.load(SCENES.Offline); } }, - /*Join:{ - load() { - if(sessionStorage.getItem("auth") === null) return false; - - CONTEXT.Data = { - page:0, - records:[], - }; - - UI.mainmenu("join"); - UI.mainnav( - [ ], - [ - UI.div([UI.text("0 - 0 of 0")]), - UI.button("◀", null), - UI.button("▶", null), - UI.button("Refresh", null), - ], - { auth:true, session:true } - ); - - let table = document.createElement("table"); - table.setAttribute("id", "content"); - table.setAttribute("class", "list"); - MAIN.appendChild(table); - - SCENE.refresh(); - - history.pushState(null, "Dzura - Join", "/join/"); - return true; - }, - refresh() { - MESSAGE_SESSION_LIST(0, 1, false, false); - }, - message(code, data) { - switch(code) { - case OpCode.SessionList: { - let table = document.getElementById("content"); - UI.clear(table); - - if(data !== null) { - table.appendChild(UI.session_table_join(data.records)); - } - } break; - case OpCode.SessionView: { - if(data.status == Status.Ok) { - LOAD(SCENES.Game, data); - } - } break; - } - }, - disconnect() { - LOAD(SCENES.Offline); - }, - },*/ - Live:class{ constructor() { + this.data = null; this.page = 1; this.pages = 1; } - load() { + preload() { + this.refresh(); + return true; + } + load(msg) { + if(msg.code != OpCode.SessionList) { + return null; + } else { + this.data = msg.data.records; + } + UI.mainmenu("live"); let indicator_page = UI.div([]); @@ -431,14 +517,14 @@ const SCENES = { [ indicator_page, UI.button("◀", () => { - if(SCENE.page < SCENE.pages) { SCENE.page += 1; } - SCENE.refresh(); + if(this.page < this.pages) { this.page += 1; } + this.refresh(); }), UI.button("▶", () => { - if(SCENE.page > 1) { SCENE.page -= 1; } - SCENE.refresh(); + if(this.page > 1) { this.page -= 1; } + this.refresh(); }), - UI.button(LANG("refresh"), () => { SCENE.referesh(); }), + UI.button(LANG("refresh"), () => { this.referesh(); }), ], { auth:true, session:true } ); @@ -446,17 +532,16 @@ const SCENES = { let table = document.createElement("table"); table.setAttribute("id", "content"); table.setAttribute("class", "list session"); + table.appendChild(UI.session_table(this.data)); UI.maincontent(table); - SCENE.refresh(); - history.pushState(null, "Dzura - Live", "/live/"); return true; } refresh() { MESSAGE_SESSION_LIST(this.page, 2, false, true); } - message(code, data) { + /*message(code, data) { switch(code) { case OpCode.SessionList: { let table = document.getElementById("content"); @@ -468,18 +553,29 @@ const SCENES = { } } break; } - } + }*/ disconnect() { - LOAD(SCENES.Offline); + SCENE.load(SCENES.Offline); } }, History:class{ constructor() { + this.data = null; this.page = 1; this.pages = 1; } - load() { + preload() { + this.refresh(); + return true; + } + load(msg) { + if(msg.code != OpCode.SessionList) { + return null; + } else { + this.data = msg.data.records; + } + UI.mainmenu("history"); let indicator_page = UI.div([]); @@ -490,14 +586,14 @@ const SCENES = { [ indicator_page, UI.button("◀", () => { - if(SCENE.page < SCENE.pages) { SCENE.page += 1; } - SCENE.refresh(); + if(this.page < this.pages) { this.page += 1; } + this.refresh(); }), UI.button("▶", () => { - if(SCENE.page > 1) { SCENE.page -= 1; } - SCENE.refresh(); + if(this.page > 1) { this.page -= 1; } + this.refresh(); }), - UI.button(LANG("refresh"), () => { SCENE.referesh(); }), + UI.button(LANG("refresh"), () => { this.referesh(); }), ], { auth:true, session:true } ); @@ -505,17 +601,16 @@ const SCENES = { let table = document.createElement("table"); table.setAttribute("id", "content"); table.setAttribute("class", "list session"); + table.appendChild(UI.session_table(this.data)); UI.maincontent(table); - SCENE.refresh(); - history.pushState(null, "Dzura - History", "/history/"); return true; } refresh() { MESSAGE_SESSION_LIST(this.page, 3, false, false); } - message(code, data) { + /*message(code, data) { switch(code) { case OpCode.SessionList: { let table = document.getElementById("content"); @@ -527,9 +622,9 @@ const SCENES = { } } break; } - } + }*/ disconnect() { - LOAD(SCENES.Offline); + SCENE.load(SCENES.Offline); } }, @@ -604,8 +699,18 @@ const SCENES = { }, Profile:class{ - constructor() { } + constructor() { + this.data = { + handle: "", + stats: { + games_played: 0, + }, + history: [ ], + }; + } load(data) { + if(sessionStorage.getItem("auth") === null) return false; + UI.mainmenu_account(data, "profile"); // Left Buttons @@ -626,6 +731,8 @@ const SCENES = { Account:class{ constructor() { } load(data) { + if(sessionStorage.getItem("auth") === null) return false; + UI.mainmenu_account(data, "account"); // Left Buttons @@ -640,7 +747,7 @@ const SCENES = { ]); sessionStorage.clear(); CONTEXT.Auth = null; - LOAD(SCENES.Browse); + SCENE.load(SCENES.Browse); })); UI.mainnav(buttons_left, buttons_right); @@ -654,6 +761,8 @@ const SCENES = { Subscription:class{ constructor() { } load(data) { + if(sessionStorage.getItem("auth") === null) return false; + UI.mainmenu_account(null, "subscription"); // Left Buttons @@ -673,8 +782,23 @@ const SCENES = { }, Invitations:class{ - constructor() { } - load(data) { + constructor() { + this.data = null; + } + preload(data) { + if(sessionStorage.getItem("auth") === null) return false; + MESSAGE_COMPOSE([ + PACK.u16(OpCode.InviteList), + ]); + return true; + } + load(msg) { + if(msg.code == OpCode.InviteList) { + this.data = msg.data.records; + } else { + return null; + } + UI.mainmenu_account(null, "invitations"); // Left Buttons @@ -695,17 +819,14 @@ const SCENES = { let table = document.createElement("table"); table.setAttribute("id", "content"); table.setAttribute("class", "list invite"); + table.appendChild(UI.invite_table(this.data)); UI.maincontent(table); - MESSAGE_COMPOSE([ - PACK.u16(OpCode.InviteList), - ]); - history.pushState(null, "Dzura - About", "/u/" + CONTEXT.Auth.handle); return true; } - message(code, data) { - switch(code) { + message(msg) { + switch(msg.code) { case OpCode.InviteAcquire: { MESSAGE_COMPOSE([ PACK.u16(OpCode.InviteList), @@ -713,46 +834,12 @@ const SCENES = { } break; case OpCode.InviteList: { + this.data = msg.data.records; + let table = document.getElementById("content"); UI.clear(table); - if(data !== null) { - table.appendChild(UI.invite_table(data.records)); - } - } break; - } - } - }, - - GameLoad:class{ - constructor() { - this.mode = null; - this.token = null; - this.turn = null; - this.rotate = 0; - } - load(data) { - this.mode = data.mode; - this.token = data.token; - if(data.rotate !== undefined) { this.rotate = data.rotate; } - if(data.turn !== undefined) { this.turn = data.turn; } - MESSAGE_SESSION_VIEW(this.token, this.mode == INTERFACE.Mode.Player); - return true; - } - message(code, data) { - switch(code) { - case OpCode.SessionView: { - if(data.status == Status.Ok) { - LOAD(SCENES.Game, { - mode:this.mode, - token:this.token, - view:data, - turn:this.turn, - rotate:this.rotate, - }); - } else { - LOAD(SCENES.Browse); - } + table.appendChild(UI.invite_table(this.data)); } break; } } @@ -760,12 +847,33 @@ const SCENES = { Game:class{ constructor() { + this.mode = null; + this.token = null; + this.turn = null; + this.rotate = 0; + this.game = null; } - load(data) { + preload(data) { + this.mode = data.mode; + this.token = data.token; + if(data.rotate !== undefined) { this.rotate = data.rotate; } + if(data.turn !== undefined) { this.turn = data.turn; } + MESSAGE_SESSION_VIEW(this.token, this.mode == INTERFACE.Mode.Player); + return true; + } + load(msg) { + if(msg.code == OpCode.SessionView) { + if(msg.data.status != Status.Ok) { + return false; + } + } else { + return null; + } + // Bottom Buttons let buttons_bottom = [ ]; - if(data.mode == INTERFACE.Mode.Player) { + if(this.mode == INTERFACE.Mode.Player) { let button_undo = UI.button(LANG("undo"), () => { INTERFACE.undo(); }); button_undo.setAttribute("id", "button-undo"); buttons_bottom.push(button_undo); @@ -778,7 +886,7 @@ const SCENES = { buttons_bottom.push(button_react); } buttons_bottom.push(UI.button(LANG("back"), () => { - LOAD(SCENES.Browse); + SCENE.load(SCENES.Browse); })); // Standard Top Buttons @@ -788,31 +896,31 @@ const SCENES = { ]; // Resume / Review Buttons - if(data.view.player != 0) { - if(data.mode == INTERFACE.Mode.Review) { + if(msg.data.player != 0) { + if(this.mode == INTERFACE.Mode.Review) { if(!data.view.is_complete) { let callback_resume = function() { - LOAD(SCENES.GameLoad, { + SCENE.load(SCENES.Game, { token:this.token, mode:INTERFACE.Mode.Player, rotate:2 + ((INTERFACE_DATA.player & 1) ^ INTERFACE_DATA.rotate), }); } callback_resume = callback_resume.bind({ - token: data.token, + token: this.token, }); buttons_top.push(UI.button(LANG("resume"), callback_resume)); } } else { let callback_review = function() { - LOAD(SCENES.GameLoad, { + SCENE.load(SCENES.Game, { token:this.token, mode:INTERFACE.Mode.Review, rotate:2 + ((INTERFACE_DATA.player & 1) ^ INTERFACE_DATA.rotate), }); } callback_review = callback_review.bind({ - token: data.token, + token: this.token, }); buttons_top.push(UI.button(LANG("review"), callback_review)); @@ -820,7 +928,7 @@ const SCENES = { } // Practice Button - if(data.mode == INTERFACE.Mode.Review) { + if(this.mode == INTERFACE.Mode.Review) { let play_callback = function() { let turn = INTERFACE_DATA.Replay.turn; if(INTERFACE_DATA.Game.history.length > 0) { @@ -829,7 +937,7 @@ const SCENES = { } } - LOAD(SCENES.GamePractice, { + SCENE.load(SCENES.GamePractice, { token:this.token, history:INTERFACE_DATA.Game.history, turn:turn, @@ -837,7 +945,7 @@ const SCENES = { }); } play_callback = play_callback.bind({ - token: data.token, + token: this.token, }); buttons_top.push(UI.button(LANG("practice"), play_callback)); } @@ -845,7 +953,7 @@ const SCENES = { UI.nav(buttons_top, buttons_bottom); // Turn Indicators, Scroll Bar - if(data.mode == INTERFACE.Mode.Review) { + if(this.mode == INTERFACE.Mode.Review) { let ind_turn = UI.div([UI.text("0 / 0")]); ind_turn.setAttribute("id", "indicator-turn"); @@ -873,24 +981,24 @@ const SCENES = { MAIN.appendChild(canvas); // Interface - INTERFACE.init(data.token, data.mode, { - rotate:data.rotate, + INTERFACE.init(this.token, this.mode, { + rotate:this.rotate, }); - if(data.turn !== null) { - INTERFACE_DATA.Replay.turn = data.turn; + if(this.turn !== null) { + INTERFACE_DATA.Replay.turn = this.turn; } - history.pushState(null, "Dzura - Game", "/game/" + PACK.base64(data.token).slice(0, -1)); + history.pushState(null, "Dzura - Game", "/game/" + PACK.base64(this.token).slice(0, -1)); return true; } unload() { INTERFACE.uninit(); } - message(code, data) { - INTERFACE.message(code, data); + message(msg) { + INTERFACE.message(msg); } disconnect() { - LOAD(SCENES.Offline); + SCENE.load(SCENES.Offline); } }, @@ -907,7 +1015,7 @@ const SCENES = { if(data !== null) { let callback_review = function() { - LOAD(SCENES.GameLoad, { + SCENE.load(SCENES.Game, { token:this.token, mode:INTERFACE.Mode.Review, turn:INTERFACE_DATA.Game.history_begin.length, @@ -924,7 +1032,7 @@ const SCENES = { let buttons_bottom = [ ]; buttons_bottom.push(UI.button(LANG("undo"), () => { INTERFACE.undo(); })); buttons_bottom.push(UI.button(LANG("reset"), () => { INTERFACE.reset(); })); - buttons_bottom.push(UI.button(LANG("back"), () => { LOAD(SCENES.Browse); })); + buttons_bottom.push(UI.button(LANG("back"), () => { SCENE.load(SCENES.Browse); })); UI.nav(buttons_top, buttons_bottom); @@ -955,53 +1063,19 @@ const SCENES = { } }, - /*Await:{ - load() { - if(sessionStorage.getItem("auth") === null) return false; - UI.mainmenu("await"); - UI.mainnav([], [], { session:true }); - - let container = document.createElement("section"); - let form = document.createElement("div"); - form.appendChild(UI.text("Await a challenger:")); - form.appendChild(UI.table(null, [ - [ UI.label("Accepting", "in-accept"), UI.checkbox("in-accept") ], - ])); - - let button = UI.button("Update", (event) => { - let accepting = 0; - if(document.getElementById("in-accept").value == "on") { - accepting = 1; - } - - let flags = 0; - flags |= accepting; - - MESSAGE_COMPOSE([ - PACK.u16(OpCode.UserAwait), - PACK.u32(flags), - ]); - - LOAD_URL(); - }); - form.appendChild(button); - - container.appendChild(form); - MAIN.appendChild(container); - MAIN.setAttribute("class", "form"); - - return true; - }, - disconnect() { - LOAD(SCENES.Offline); - }, - },*/ - - Challenge:class{ + Users:class{ constructor() { this.page = 0; } - load() { + preload() { + this.refresh(); + return true; + } + load(msg) { + if(msg.code != OpCode.UserList) { + return null; + } + if(sessionStorage.getItem("auth") === null) return false; CONTEXT.Data = { @@ -1024,9 +1098,43 @@ const SCENES = { let table = document.createElement("table"); table.setAttribute("id", "content"); table.setAttribute("class", "list challenge"); - UI.maincontent(table); - SCENE.refresh(); + // Insert table rows + let rows = [ ]; + + for(let r = 0; r < msg.data.users.length; ++r) { + let buttons = [ ]; + + let callback = function(event) { + MESSAGE_CHALLENGE(this.handle); + + event.target.innerText = "Sent"; + event.target.setAttribute("class", "highlight"); + event.target.setAttribute("disabled", ""); + }; + callback = callback.bind({handle: msg.data.users[r].handle}); + buttons.push(UI.button(LANG("challenge"), callback)); + + let handle = UI.text(msg.data.users[r].handle); + if(!msg.data.users[r].is_online) { + handle = UI.span([handle], "text-system"); + } + + rows.push([ + handle, + UI.text(LANG("unranked")), + buttons, + ]); + } + + let tbody = UI.table_content( + [ LANG("handle"), LANG("rank"), "" ], + rows, + ); + + table.appendChild(tbody); + + UI.maincontent(table); history.pushState(null, "Dzura", "/challenge/"); return true; @@ -1036,58 +1144,22 @@ const SCENES = { PACK.u16(OpCode.UserList), ]); } - message(code, data) { - switch(code) { - case OpCode.UserList: { - let table = document.getElementById("content"); - UI.clear(table); - - if(data !== null) { - let rows = [ ]; - - for(let r = 0; r < data.users.length; ++r) { - let buttons = [ ]; - - let callback = function(event) { - MESSAGE_CHALLENGE(this.handle); - - event.target.innerText = "Sent"; - event.target.setAttribute("class", "highlight"); - event.target.setAttribute("disabled", ""); - }; - callback = callback.bind({handle: data.users[r].handle}); - buttons.push(UI.button(LANG("challenge"), callback)); - - let handle = UI.text(data.users[r].handle); - if(!data.users[r].is_online) { - handle = UI.span([handle], "text-system"); - } - - rows.push([ - handle, - UI.text(LANG("unranked")), - buttons, - ]); - } - - let tbody = UI.table_content( - [ LANG("handle"), LANG("rank"), "" ], - rows, - ); - - table.appendChild(tbody); - } - } break; - } - } disconnect() { - LOAD(SCENES.Offline); + SCENE.load(SCENES.Offline); } }, - ChallengeList:class{ + Requests:class{ constructor() { } - load() { + preload() { + this.refresh(); + return true; + } + load(msg) { + if(msg.code != OpCode.ChallengeList) { + return null; + } + if(sessionStorage.getItem("auth") === null) return false; CONTEXT.Data = { @@ -1110,9 +1182,39 @@ const SCENES = { let table = document.createElement("table"); table.setAttribute("id", "content"); table.setAttribute("class", "list challenge"); - UI.maincontent(table); - SCENE.refresh(); + let rows = [ ]; + + for(let r = 0; r < msg.data.challenges.length; ++r) { + let buttons = [ ]; + + let callback_accept = function() { + MESSAGE_CHALLENGE_ANSWER(this.handle, true); + }; + callback_accept = callback_accept.bind({handle: msg.data.challenges[r].handle}); + buttons.push(UI.button(LANG("accept"), callback_accept)); + + let callback_decline = function() { + MESSAGE_CHALLENGE_ANSWER(this.handle, false); + }; + callback_decline = callback_decline.bind({handle: msg.data.challenges[r].handle}); + buttons.push(UI.button(LANG("decline"), callback_decline)); + + rows.push([ + UI.text(msg.data.challenges[r].handle), + UI.text(LANG("unranked")), + buttons, + ]); + } + + let tbody = UI.table_content( + [ LANG("handle"), LANG("rank"), "" ], + rows, + ); + + table.appendChild(tbody); + + UI.maincontent(table); history.pushState(null, "Dzura", "/challenge/"); return true; @@ -1122,110 +1224,58 @@ const SCENES = { PACK.u16(OpCode.ChallengeList), ]); } - message(code, data) { - switch(code) { + message(msg) { + switch(msg.code) { case OpCode.ChallengeList: { let table = document.getElementById("content"); UI.clear(table); - if(data !== null) { - let rows = [ ]; + let rows = [ ]; - for(let r = 0; r < data.challenges.length; ++r) { - let buttons = [ ]; + for(let r = 0; r < msg.data.challenges.length; ++r) { + let buttons = [ ]; - let callback_accept = function() { - MESSAGE_CHALLENGE_ANSWER(this.handle, true); - }; - callback_accept = callback_accept.bind({handle: data.challenges[r].handle}); - buttons.push(UI.button(LANG("accept"), callback_accept)); + let callback_accept = function() { + MESSAGE_CHALLENGE_ANSWER(this.handle, true); + }; + callback_accept = callback_accept.bind({handle: msg.data.challenges[r].handle}); + buttons.push(UI.button(LANG("accept"), callback_accept)); - let callback_decline = function() { - MESSAGE_CHALLENGE_ANSWER(this.handle, false); - }; - callback_decline = callback_decline.bind({handle: data.challenges[r].handle}); - buttons.push(UI.button(LANG("decline"), callback_decline)); + let callback_decline = function() { + MESSAGE_CHALLENGE_ANSWER(this.handle, false); + }; + callback_decline = callback_decline.bind({handle: msg.data.challenges[r].handle}); + buttons.push(UI.button(LANG("decline"), callback_decline)); - rows.push([ - UI.text(data.challenges[r].handle), - UI.text(LANG("unranked")), - buttons, - ]); - } - - let tbody = UI.table_content( - [ LANG("handle"), LANG("rank"), "" ], - rows, - ); - - table.appendChild(tbody); + rows.push([ + UI.text(msg.data.challenges[r].handle), + UI.text(LANG("unranked")), + buttons, + ]); } + + let tbody = UI.table_content( + [ LANG("handle"), LANG("rank"), "" ], + rows, + ); + + table.appendChild(tbody); } break; case OpCode.ChallengeAnswer: { - if(data.status == Status.Ok) { - LOAD(SCENES.GameLoad, { - token:data.token, + if(msg.data.status == Status.Ok) { + SCENE.load(SCENES.Game, { + token:msg.data.token, mode:INTERFACE.Mode.Player, }); } else { - SCENE.refresh(); + this.refresh(); } } break; } } disconnect() { - LOAD(SCENES.Offline); + SCENE.load(SCENES.Offline); } }, }; - -function LOAD(scene, data=null) { - UNLOAD(); - UI.rebuild(); - SCENE = new scene(); - if(!SCENE.load(data)) { LOAD(SCENES.Browse); } - UI.update_status(); -} - -function UNLOAD() { - if(SCENE !== null && SCENE.unload !== undefined) { SCENE.unload(); } -} - -function LOAD_URL() { - let parts = window.location.pathname.split("/"); - - if(parts.length > 1) { - switch(parts[1]) { - case "continue": LOAD(SCENES.Continue); return; - case "live": LOAD(SCENES.Live); return; - case "history": LOAD(SCENES.History); return; - case "practice": LOAD(SCENES.GamePractice); return; - case "guide": LOAD(SCENES.Guide); return; - case "about": LOAD(SCENES.About); return; - case "challenge": LOAD(SCENES.Challenge); return; - case "extras": LOAD(SCENES.Extras); return; - - case "game": { - if(parts[2]) { - let token = UNPACK.base64(parts[2] + "="); - LOAD(SCENES.GameLoad, { - token:token, - mode:INTERFACE.Mode.Review, - }); - return; - } - } break; - - case "u": { - if(parts[2]) { - LOAD(SCEENS.Profile, { - handle:parts[2], - }); - return; - } - } break; - } - } - LOAD(SCENES.Browse); -} diff --git a/www/js/system.js b/www/js/system.js index 940cf71..ccf5c78 100644 --- a/www/js/system.js +++ b/www/js/system.js @@ -41,7 +41,8 @@ function RESUME() { secret, ]); } else { - LOAD_URL(); + console.log("HERE"); + SCENE.load_url(); } } @@ -143,7 +144,7 @@ function MESSAGE(event) { sessionStorage.clear(); } - LOAD_URL(); + SCENE.load_url(); } break; case OpCode.Deauthenticate: { @@ -566,7 +567,13 @@ function MESSAGE(event) { console.log("RECV Undefined " + code); return; } - if(SCENE.message !== undefined) { SCENE.message(code, data) }; + + if(data !== null) { + SCENE.message({ + code: code, + data: data, + }); + } } function MESSAGE_COMPOSE(data) { diff --git a/www/js/ui.js b/www/js/ui.js index e1938d0..92141e3 100644 --- a/www/js/ui.js +++ b/www/js/ui.js @@ -127,15 +127,15 @@ const UI = { if(sessionStorage.getItem("auth") === null) { if(features.auth === true) { - left.appendChild(UI.button(LANG("register"), () => { LOAD(SCENES.Register); })); - left.appendChild(UI.button(LANG("login"), () => { LOAD(SCENES.Authenticate); })); + left.appendChild(UI.button(LANG("register"), () => { SCENE.load(SCENES.Register); })); + left.appendChild(UI.button(LANG("login"), () => { SCENE.load(SCENES.Authenticate); })); } } else { if(features.session === true) { - let button_challenge = UI.button(LANG("requests"), () => { LOAD(SCENES.ChallengeList); }); + let button_challenge = UI.button(LANG("requests"), () => { SCENE.load(SCENES.Requests); }); button_challenge.setAttribute("id", "button-requests"); - left.appendChild(UI.button(LANG("users"), () => { LOAD(SCENES.Challenge); })); + left.appendChild(UI.button(LANG("users"), () => { SCENE.load(SCENES.Users); })); left.appendChild(button_challenge); } } @@ -166,24 +166,24 @@ const UI = { let top = [ ]; let bottom = [ ]; - top.push(UI.button(LANG("browse"), () => { LOAD(SCENES.Browse); }, page == "browse")); + top.push(UI.button(LANG("browse"), () => { SCENE.load(SCENES.Browse); }, page == "browse")); if(sessionStorage.getItem("auth") !== null) { - let button_resume = UI.button(LANG("resume"), () => { LOAD(SCENES.Continue); }, page == "continue"); + let button_resume = UI.button(LANG("resume"), () => { SCENE.load(SCENES.Continue); }, page == "continue"); button_resume.setAttribute("id", "button-resume"); top.push(button_resume); - //top.push(UI.button("Join", () => { LOAD(SCENES.Join); }, page == "join")); + //top.push(UI.button("Join", () => { SCENE.load(SCENES.Join); }, page == "join")); } - top.push(UI.button(LANG("live"), () => { LOAD(SCENES.Live); }, page == "live")); - top.push(UI.button(LANG("history"), () => { LOAD(SCENES.History); }, page == "history")); - top.push(UI.button(LANG("practice"), () => { LOAD(SCENES.GamePractice); }, page == "practice")); - top.push(UI.button(LANG("guide"), () => { LOAD(SCENES.Guide); }, page == "guide")); - top.push(UI.button(LANG("about"), () => { LOAD(SCENES.About); }, page == "about")); + top.push(UI.button(LANG("live"), () => { SCENE.load(SCENES.Live); }, page == "live")); + top.push(UI.button(LANG("history"), () => { SCENE.load(SCENES.History); }, page == "history")); + top.push(UI.button(LANG("practice"), () => { SCENE.load(SCENES.GamePractice); }, page == "practice")); + top.push(UI.button(LANG("guide"), () => { SCENE.load(SCENES.Guide); }, page == "guide")); + top.push(UI.button(LANG("about"), () => { SCENE.load(SCENES.About); }, page == "about")); if(CONTEXT.Auth !== null) { - bottom.push(UI.button(LANG("account"), () => { LOAD(SCENES.Account); })); + bottom.push(UI.button(LANG("account"), () => { SCENE.load(SCENES.Account); })); } - bottom.push(UI.button(LANG("extras"), () => { LOAD(SCENES.Extras) }, page == "extras")); + bottom.push(UI.button(LANG("extras"), () => { SCENE.load(SCENES.Extras) }, page == "extras")); UI.nav(top, bottom); } @@ -194,16 +194,16 @@ const UI = { let buttons_bottom = [ ]; // Top Buttons - buttons_top.push(UI.button("Profile", () => { LOAD(SCENES.Profile, { handle:CONTEXT.Auth.handle }) }, page == "profile")); + buttons_top.push(UI.button("Profile", () => { SCENE.load(SCENES.Profile, { handle:CONTEXT.Auth.handle }) }, page == "profile")); buttons_top.push(UI.button("History", () => { }, page == "history")); // Bottom Buttons if(data === null || data.handle === CONTEXT.Auth.handle) { - buttons_bottom.push(UI.button("Account", () => { LOAD(SCENES.Account) }, page == "account")); - buttons_bottom.push(UI.button("Subscription", () => { LOAD(SCENES.Subscription) }, page == "subscription")); - buttons_bottom.push(UI.button("Invitations", () => { LOAD(SCENES.Invitations) }, page == "invitations")); + buttons_bottom.push(UI.button("Account", () => { SCENE.load(SCENES.Account) }, page == "account")); + buttons_bottom.push(UI.button("Subscription", () => { SCENE.load(SCENES.Subscription) }, page == "subscription")); + buttons_bottom.push(UI.button("Invitations", () => { SCENE.load(SCENES.Invitations) }, page == "invitations")); } - buttons_bottom.push(UI.button(LANG("back"), () => { LOAD(SCENES.Browse); })); + buttons_bottom.push(UI.button(LANG("back"), () => { SCENE.load(SCENES.Browse); })); UI.nav(buttons_top, buttons_bottom); }, @@ -216,7 +216,7 @@ const UI = { let buttons = [ ]; let join_callback = function() { - LOAD(SCENES.GameLoad, { + SCENE.load(SCENES.Game, { token:this.token, mode:INTERFACE.Mode.Player, }); @@ -226,7 +226,7 @@ const UI = { }); let spectate_callback = function() { - LOAD(SCENES.GameLoad, { + SCENE.load(SCENES.Game, { token:this.token, mode:INTERFACE.Mode.Review, }); @@ -278,7 +278,7 @@ const UI = { let buttons = [ ]; let join_callback = function() { SCENE_FORWARD = SCENE; - LOAD(SCENES.GameLoad, { + SCENE.load(SCENES.Game, { token:this.token, mode:INTERFACE.Mode.Player, }); @@ -287,7 +287,7 @@ const UI = { let spectate_callback = function() { SCENE_FORWARD = SCENE; - LOAD(SCENES.GameLoad, { + SCENE.load(SCENES.Game, { token:this.token, mode:INTERFACE.Mode.Review, }); @@ -327,7 +327,7 @@ const UI = { for(let r = 0; r < records.length; ++r) { let buttons = [ ]; let join_callback = function() { - LOAD(SCENES.Game, { + SCENE.load(SCENES.Game, { token:this.token, mode:INTERFACE.Mode.Player, }); @@ -367,7 +367,7 @@ const UI = { let buttons = [ ]; let view_callback = function() { SCENE_FORWARD = SCENE; - LOAD(SCENES.GameLoad, { + SCENE.load(SCENES.Game, { token:this.token, mode:INTERFACE.Mode.Review, });