dzura/www/js/ui.js

423 lines
13 KiB
JavaScript

const UI = {
text(value) {
return document.createTextNode(value);
},
button(text, callback, select=false) {
let button = document.createElement("button");
button.innerText = text;
if(select) { button.setAttribute("class", "selected"); }
if(callback !== null) { button.addEventListener("click", callback); }
return button;
},
submit(text) {
let button = document.createElement("input");
button.setAttribute("type", "submit");
button.value = text;
return button;
},
slider(id, callback) {
let input = document.createElement("input");
if(id !== null) { input.setAttribute("id", id); }
input.setAttribute("type", "range");
input.setAttribute("value", "0");
input.setAttribute("min", "0");
input.setAttribute("max", "0");
if(callback !== null) { input.addEventListener("input", callback); }
return input;
},
checkbox(id, callback) {
let input = document.createElement("input");
if(id !== null) { input.setAttribute("id", id); }
input.setAttribute("type", "checkbox");
if(callback !== null) { input.addEventListener("change", callback); }
return input;
},
textbox(id, placeholder) {
let input = document.createElement("input");
input.setAttribute("type", "text");
if(id !== null) { input.setAttribute("id", id); }
input.setAttribute("placeholder", placeholder);
return input;
},
password(id) {
let input = document.createElement("input");
input.setAttribute("type", "password");
if(id !== null) { input.setAttribute("id", id); }
return input;
},
label(name, id) {
let label = document.createElement("label");
label.setAttribute("for", id);
label.innerText = name;
return label;
},
span(children, attr_class) {
let span = document.createElement("span");
if(attr_class !== undefined) { span.setAttribute("class", attr_class); }
for(child of children) { span.appendChild(child); }
return span;
},
div(children, attr_class) {
let div = document.createElement("div");
if(attr_class !== undefined) { div.setAttribute("class", attr_class); }
for(child of children) { div.appendChild(child); }
return div;
},
table_content(header, rows) {
let tbody = document.createElement("tbody");
if(header !== null) {
let row = document.createElement("tr");
for(head of header) {
let cell = document.createElement("th");
cell.innerText = head;
row.appendChild(cell);
}
tbody.appendChild(row);
}
for(row of rows) {
let tr = document.createElement("tr");
for(node of row) {
let cell = document.createElement("td");
if(Array.isArray(node)) { for(item of node) { cell.appendChild(item); } }
else { cell.appendChild(node); }
tr.appendChild(cell);
}
tbody.appendChild(tr);
}
return tbody;
},
table(header, rows) {
let table = document.createElement("table");
table.appendChild(this.table_content(header, rows));
return table;
},
mainnav(left_children, right_children, features={}) {
let header = document.createElement("nav");
let left = document.createElement("section");
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); }));
}
} else {
if(features.session === true) {
let button_challenge = UI.button(LANG("requests"), () => { LOAD(SCENES.ChallengeList); });
button_challenge.setAttribute("id", "button-requests");
left.appendChild(UI.button(LANG("users"), () => { LOAD(SCENES.Challenge); }));
left.appendChild(button_challenge);
}
}
for(child of left_children) { left.appendChild(child); }
let right = document.createElement("section");
for(child of right_children) { right.appendChild(child); }
header.appendChild(left);
header.appendChild(right);
MAIN.appendChild(header);
},
nav(top, bottom) {
let section = document.createElement("section");
for(node of top) { section.appendChild(node); }
MENU.appendChild(section);
section = document.createElement("section");
for(node of bottom) { section.appendChild(node); }
MENU.appendChild(section);
},
mainmenu(page) {
if(SOCKET !== null) {
let top = [ ];
let bottom = [ ];
top.push(UI.button(LANG("browse"), () => { LOAD(SCENES.Browse); }, page == "browse"));
if(sessionStorage.getItem("auth") !== null) {
let button_resume = UI.button(LANG("resume"), () => { 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(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"));
if(sessionStorage.getItem("auth") !== null) {
bottom.push(UI.button("Logout", () => {
MESSAGE_COMPOSE([
PACK.u16(OpCode.Deauthenticate),
]);
sessionStorage.clear();
LOAD_URL();
}));
}
UI.nav(top, bottom);
}
},
session_table(records) {
let rows = [ ];
for(let r = 0; r < records.length; ++r) {
let buttons = [ ];
let join_callback = function() {
LOAD(SCENES.Game, {
token:this.token,
mode:INTERFACE.Mode.Player,
});
MESSAGE_SESSION_VIEW(this.token, true);
};
join_callback = join_callback.bind({token: records[r].token});
let spectate_callback = function() {
LOAD(SCENES.Game, {
token:this.token,
mode:INTERFACE.Mode.Review,
});
MESSAGE_SESSION_VIEW(this.token, false);
};
spectate_callback = spectate_callback.bind({token: records[r].token});
if(records[r].player != 0) {
let button_resume = UI.button(LANG("resume"), join_callback);
if(records[r].is_turn) {
button_resume.setAttribute("class", "highlight");
}
buttons.push(button_resume);
buttons.push(UI.button(LANG("review"), spectate_callback));
} else {
buttons.push(UI.button(LANG("view"), spectate_callback));
}
let dawn = UI.text(records[r].dawn);
let dusk = UI.text(records[r].dusk);
rows.push([
dawn,
dusk,
UI.text(records[r].turn),
UI.text(records[r].viewers),
buttons,
]);
}
let tbody = UI.table_content(
[ LANG("dawn"), LANG("dusk"), LANG("turn"), LANG("viewers"), "" ],
rows,
);
return tbody;
},
session_table_resume(records) {
let rows = [ ];
for(let r = 0; r < records.length; ++r) {
let buttons = [ ];
let join_callback = function() {
SCENE_FORWARD = SCENE;
LOAD(SCENES.Game, {
token:this.token,
mode:INTERFACE.Mode.Player,
});
MESSAGE_SESSION_VIEW(this.token, true);
};
join_callback = join_callback.bind({token: records[r].token});
let spectate_callback = function() {
SCENE_FORWARD = SCENE;
LOAD(SCENES.Game, {
token:this.token,
mode:INTERFACE.Mode.Review,
});
MESSAGE_SESSION_VIEW(this.token, false);
};
spectate_callback = spectate_callback.bind({token: records[r].token});
let button_resume = UI.button(LANG("resume"), join_callback);
if(records[r].is_turn) {
button_resume.setAttribute("class", "highlight");
}
buttons.push(button_resume);
buttons.push(UI.button(LANG("review"), spectate_callback));
let handle = records[r].dawn;
if(records[r].player == 1) { handle = records[r].dusk; }
rows.push([
UI.text(handle),
UI.text(records[r].turn),
UI.text(records[r].viewers),
buttons,
]);
}
let tbody = UI.table_content(
[ LANG("handle"), LANG("turn"), LANG("viewers"), "" ],
rows,
);
return tbody;
},
/*session_table_join(records) {
let rows = [ ];
for(let r = 0; r < records.length; ++r) {
let buttons = [ ];
let join_callback = function() {
LOAD(SCENES.Game, {
token:this.token,
mode:INTERFACE.Mode.Player,
});
MESSAGE_SESSION_VIEW(this.token, true);
};
join_callback = join_callback.bind({token: records[r].token});
if(records[r].player) {
buttons.push(UI.button("View", join_callback));
} else {
buttons.push(UI.button("Join", join_callback));
}
let host = UI.text(records[r].dawn);
if(records[r].dawn == "") { dawn = UI.span([UI.text("Vacant")], "text-system"); }
rows.push([
host,
buttons,
]);
}
let tbody = UI.table_content(
[ "Host", "" ],
rows,
);
return tbody;
},*/
session_table_history(records) {
let rows = [ ];
for(let r = 0; r < records.length; ++r) {
let buttons = [ ];
let view_callback = function() {
SCENE_FORWARD = SCENE;
LOAD(SCENES.Game, {
token:this.token,
mode:INTERFACE.Mode.Review,
});
MESSAGE_SESSION_VIEW(this.token, false);
};
view_callback = view_callback.bind({token: records[r].token});
buttons.push(UI.button(LANG("review"), view_callback));
let dawn = UI.text(records[r].dawn);
let dusk = UI.text(records[r].dusk);
rows.push([
dawn,
dusk,
UI.text(records[r].turn),
buttons,
]);
}
let tbody = UI.table_content(
[ LANG("dawn"), LANG("dusk"), LANG("turns"), "" ],
rows,
);
return tbody;
},
page_indicator(first, last, total) {
let ind = document.getElementById("indicator-page");
UI.clear(ind);
ind.appendChild(UI.text(LANG_PAGEOF(first, last, total)));
},
clear(dom) {
while(dom.lastChild !== null) { dom.removeChild(dom.lastChild); }
},
rebuild() {
this.clear(document.body);
MENU = document.createElement("nav");
let title = document.createElement("header");
title.innerText = "Dzura";
MENU.appendChild(title);
MAIN = document.createElement("main");
document.body.appendChild(MENU);
document.body.appendChild(MAIN);
},
update_status() {
let b_requests = document.getElementById("button-requests");
let b_resume = document.getElementById("button-resume");
if(b_requests !== null) {
let text = LANG("requests");
if(STATUS.challenge > 0) {
if(STATUS.challenge < 10) {
text += " " + String.fromCharCode("❶".charCodeAt(0) + (STATUS.challenge - 1));
} else {
text += " ❾";
}
} else {
text += " ⓿";
}
b_requests.innerText = text;
}
if(b_resume !== null) {
let text = LANG("resume");
if(STATUS.resume > 0) {
if(STATUS.resume < 10) {
text += " " + String.fromCharCode("❶".charCodeAt(0) + (STATUS.resume - 1));
} else {
text += " ❾";
}
} else {
text += " ⓿";
}
b_resume.innerText = text;
}
},
};