clean up dom access and IDs

This commit is contained in:
Iris Lightshard 2023-07-19 01:43:06 -06:00
parent 331150a0ff
commit 7a294373c5
Signed by: nilix
GPG key ID: 3B7FBC22144E6398
7 changed files with 512 additions and 492 deletions

View file

@ -1,28 +1,10 @@
let adminToken = null; let adminToken = null;
const adminWrapper = document.getElementById("adminWrapper");
const adminZone = document.getElementById("adminZone");
const spriteZone = document.getElementById("spriteZone");
const createTableForm = document.getElementById("createTableForm");
const createTokenForm = document.getElementById("createTokenForm");
const tokenWrapper = document.getElementById("adminWrapper_tokens");
const newTableName = document.getElementById("newTableName");
const newTablePass = document.getElementById("newTablePass");
const tokenSpriteDropdown = document.getElementById("token_combobox");
const tokenName = document.getElementById("token_name");
const tokenWidth = document.getElementById("token_width");
const tokenHeight = document.getElementById("token_height");
const tokenCX = document.getElementById("token_cx");
const tokenCY = document.getElementById("token_cy");
const previewZone = document.getElementById("tokenPreview_zone");
const tokenAspect = document.getElementById("tokenKeepAspect");
const aspectLockLabel = document.getElementById("aspectLockLabel");
const tokenZone = document.getElementById("tokenZone");
async function rebindUi(name, pass) { async function loadAdmin(name, pass) {
try { try {
const headers = new Headers(); const headers = new Headers();
headers.set('Authorization', 'Bearer ' + adminToken.access_token); headers.set('Authorization', 'Bearer ' + adminToken.access_token);
const res = await fetch(`/admin/api/table/${name}?passcode=${pass}`, { const tableData = await fetch(`/admin/api/table/${name}?passcode=${pass}`, {
method: 'GET', method: 'GET',
headers: headers, headers: headers,
}); });
@ -37,71 +19,70 @@ async function rebindUi(name, pass) {
headers: headers, headers: headers,
}); });
let infoHtml = "" let mgmtHTML = ""
if (res.ok) { if (tableData.ok) {
document.getElementById("input_table_name").value = name; $("input_table_name").value = name;
document.getElementById("input_table_pass").value = pass; $("input_table_pass").value = pass;
dial(); dial();
const table = await res.json()
infoHtml = "<a href='#' onclick='getTables();return false;'>&larr; table list</a><br>"; const table = await tableData.json()
infoHtml += `<textarea id='auxMsgZone'>${table.auxMsg}</textarea><br><button onclick='publishAuxMsg()'>Set Status</button>`
infoHtml += "<button onclick='destroyTable()'>Destroy Table</button><br/>"; mgmtHTML = `<a href='#' onclick='getTables();return false;'>&larr; table list</a><br>\n` +
infoHtml += "<input id='map_img_upload' type='file'/><button onclick='uploadMapImg()'>Upload Map</button><br/>" `<textarea id='aux_msg_input'>${table.auxMsg}</textarea><br><button onclick='publishAuxMsg()'>Set Status</button>\n` +
`<button onclick='destroyTable()'>Destroy Table</button><br/>\n` +
`<input id='map_img_upload' type='file'/><button onclick='uploadImg("map")'>Upload Map</button><br/>\n`
if (mapImgs.ok) { if (mapImgs.ok) {
infoHtml += "<label>Available Maps</label>";
const imgs = (await mapImgs.json()).sort(); const imgs = (await mapImgs.json()).sort();
infoHtml += "<ul class='two_btn_list'>"; mgmtHTML = imgs.reduce((s, i) => {
for (const i of imgs) {
const parts = i.split("/"); const parts = i.split("/");
infoHtml += `<li><a href="${i}" target="_blank">${parts[parts.length - 1]}</a> <button onclick="sendMapImg('${i}');">Set</button> <button onclick="deleteImg('${i}')">Delete</button></li>\n`; return s + `<li><a href="${i}" target="_blank">${parts[parts.length - 1]}</a> <button onclick="sendMapImg('${i}');">Set</button> <button onclick="deleteImg('${i}')">Delete</button></li>\n`;
} }, mgmtHTML + "<label>Available Maps</label><ul class='two_btn_list'>") + "</ul>";
infoHtml += "</ul>";
} else { } else {
infoHtml += "<label>Maps couldn't be retrieved</label>"; mgmtHTML += "<label>Maps couldn't be retrieved</label>";
} }
adminZone.innerHTML = infoHtml; $("table_management").innerHTML = mgmtHTML;
let spriteListHTML = `<input id='token_img_upload' type='file'/><button onclick='uploadImg("token")'>Upload Sprite</button><br/>`;
let tokenListHTML = "<input id='token_img_upload' type='file'/><button onclick='uploadTokenImg()'>Upload Sprite</button><br/>";
if (tokenImgs.ok) { if (tokenImgs.ok) {
const tokens = (await tokenImgs.json()).sort(); const sprites = (await tokenImgs.json()).sort();
tokenListHTML += "<ul class='single_btn_list'>"; spriteListHTML = sprites.reduce((s, t) => {
for (const t of tokens) {
const parts = t.split("/"); const parts = t.split("/");
tokenListHTML += `<li><a href="${t}" target="_blank">${parts[parts.length - 1]}</a> <button onclick="deleteImg('${t}')">Delete</button></li>\n` return s + `<li><a href="${t}" target="_blank">${parts[parts.length - 1]}</a> <button onclick="deleteImg('${t}')">Delete</button></li>\n`;
} }, spriteListHTML + "<ul class='single_btn_list'>") + "</ul>";
tokenListHTML += "</ul>"; fillSpriteDropdown(sprites);
fillSpriteDropdown(tokens);
} else { } else {
tokenListHTML += "<label>Sprites couldn't be retrieved</label>" spriteListHTML += "<label>Sprites couldn't be retrieved</label>"
} }
spriteZone.innerHTML = tokenListHTML; $("sprite_zone").innerHTML = spriteListHTML;
tokenWrapper.style.display = "inline"; $("token_management").style.display = "inline";
} else { } else {
console.log(res.status); console.log(res.status);
} }
} catch (err) { } catch (err) {
console.dir(err)
setErr(`${err.name}: ${err.message}`); setErr(`${err.name}: ${err.message}`);
} }
} }
function fillSpriteDropdown(tokens) { function fillSpriteDropdown(sprites) {
tokens = tokens.sort(); const dropdown = $("sprite_dropdown");
let options = "<option value=''>select</option>"; let options = "<option value=''>select</option>";
for (const t of tokens) { dropdown.innerHTML = sprites.reduce((s, t) => {
const parts = t.split("/"); const parts = t.split("/");
const o = `<option value="${t}">${parts[parts.length - 1]}</option>\n`; return s + `<option value="${t}">${parts[parts.length - 1]}</option>\n`;
options += o; }, "<option value=''>select</option>");
}
tokenSpriteDropdown.innerHTML = options;
} }
function previewSprite(source) { function previewSprite(source) {
if (source) { if (source) {
switch (source.id) { switch (source.id) {
case "token_combobox": case "sprite_dropdown":
reinitializeSpritePreview(); reinitializeSpritePreview();
break; break;
case "token_cx": case "token_cx":
@ -116,18 +97,24 @@ function previewSprite(source) {
} }
function toggleAspectLock() { function toggleAspectLock() {
if (tokenKeepAspect.checked) { try {
aspectLockLabel.innerHTML = "&#128274;" const locked = $("token_aspect_lock").checked;
} else { $("aspect_lock_label").innerHTML = locked ? "&#128274;" : "&#128275;"
aspectLockLabel.innerHTML = "&#128275;" } catch {}
}
} }
function scaleSpritePreview(source) { function scaleSpritePreview(source) {
if (mapImg && mapImg._image) { const tokenHeight = $("token_height");
const tokenWidth = $("token_width");
const tokenCX = $("token_cx");
const tokenCY = $("token_cy");
const tokenAspect = $("token_aspect_lock");
const preview = $("token_admin_preview");
if (mapImg && mapImg._image && tokenHeight && tokenWidth && tokenCX && tokenCY && tokenAspect && preview) {
const scaleFactor = mapImg._image.clientWidth / mapImg._image.naturalWidth; const scaleFactor = mapImg._image.clientWidth / mapImg._image.naturalWidth;
const keepAspect = tokenAspect.checked; const keepAspect = tokenAspect.checked;
const img = previewZone.children[0]; const img = preview.children[0];
tokenHeight.value = Math.floor(Number(tokenHeight.value)) tokenHeight.value = Math.floor(Number(tokenHeight.value))
tokenWidth.value = Math.floor(Number(tokenWidth.value)) tokenWidth.value = Math.floor(Number(tokenWidth.value))
@ -165,12 +152,20 @@ function scaleSpritePreview(source) {
function drawTokenOrigin() { function drawTokenOrigin() {
if (tokenSpriteDropdown.selectedIndex >= 0) { const dropdown = $("sprite_dropdown");
const tokenWidth = $("token_width");
const tokenHeight = $("token_height");
const tokenCX = $("token_cx");
const tokenCY = $("token_cy");
const preview = $("token_admin_preview");
if (dropdown && tokenWidth && tokenHeight && tokenCX && tokenCY && preview
&& dropdown.selectedIndex >= 0) {
tokenCX.value = Math.floor(Number(tokenCX.value)) tokenCX.value = Math.floor(Number(tokenCX.value))
tokenCY.value = Math.floor(Number(tokenCY.value)) tokenCY.value = Math.floor(Number(tokenCY.value))
const img = previewZone.children[0]; const img = preview.children[0];
const x = Number(tokenWidth.value) / Number(tokenCX.value); const x = Number(tokenWidth.value) / Number(tokenCX.value);
const y = Number(tokenHeight.value) / Number(tokenCY.value); const y = Number(tokenHeight.value) / Number(tokenCY.value);
@ -182,67 +177,82 @@ function drawTokenOrigin() {
originImg.style.left = (origin.x - 2) + "px"; originImg.style.left = (origin.x - 2) + "px";
originImg.style.top = (origin.y - 2) + "px"; originImg.style.top = (origin.y - 2) + "px";
if (previewZone.children.length > 1) { if (preview.children.length > 1) {
previewZone.replaceChild(originImg, previewZone.children[1]); preview.replaceChild(originImg, preview.children[1]);
} else { } else {
previewZone.appendChild(originImg); preview.appendChild(originImg);
} }
} }
} }
function reinitializeSpritePreview(existing = false) { function reinitializeSpritePreview(existing = false) {
const img = document.createElement("img");
img.src = tokenSpriteDropdown[tokenSpriteDropdown.selectedIndex].value;
if (!existing) { const dropdown = $("sprite_dropdown");
const tokenNameParts = tokenSpriteDropdown[tokenSpriteDropdown.selectedIndex].text.split("."); const tokenName = $("token_name");
tokenNameParts.pop(); const tokenWidth = $("token_width");
tokenName.value = tokenNameParts.join("."); const tokenHeight = $("token_height");
} const tokenCX = $("token_cx");
const tokenCY = $("token_cy");
const preview = $("token_admin_preview");
img.onload = () => { if (dropdown && tokenName && tokenWidth && tokenHeight && tokenCX && tokenCY && preview) {
const w = img.naturalWidth;
const h = img.naturalHeight; const img = document.createElement("img");
img.src = dropdown[dropdown.selectedIndex].value;
if (!existing) { if (!existing) {
tokenWidth.value = w; const tokenNameParts = dropdown[dropdown.selectedIndex].text.split(".");
tokenHeight.value = h; tokenNameParts.pop();
tokenCX.value = "" tokenName.value = tokenNameParts.join(".");
tokenCY.value = ""
} }
scaleSpritePreview();
}
previewZone.innerHTML = ""; img.onload = () => {
previewZone.appendChild(img); const w = img.naturalWidth;
const h = img.naturalHeight;
if (!existing) {
tokenWidth.value = w;
tokenHeight.value = h;
tokenCX.value = "";
tokenCY.value = "";
}
scaleSpritePreview();
}
preview.innerHTML = "";
preview.appendChild(img);
}
} }
function createToken() { function createToken() {
const w = Number(tokenWidth.value); const dropdown = $("sprite_dropdown");
const h = Number(tokenHeight.value); try {
const oX = Number(tokenCX.value); const w = Number($("token_width").value);
const oY = Number(tokenCY.value); const h = Number($("token_height").value);
const img = tokenSpriteDropdown[tokenSpriteDropdown.selectedIndex].value; const oX = Number($("token_cx").value);
const name = tokenName.value; const oY = Number($("token_cy").value);
const img = dropdown[dropdown.selectedIndex].value;
const name = $("token_name").value;
if (!isNaN(w) && !isNaN(h) && !isNaN(oX) && !isNaN(oY) && img && name) { if (!isNaN(w) && !isNaN(h) && !isNaN(oX) && !isNaN(oY) && img && name) {
// send it on the websocket and wait for it to come back // send it on the websocket and wait for it to come back
const [x, y] = [0, 0]; const [x, y] = [0, 0];
sendToken({ sendToken({
w: w, w: w,
h: h, h: h,
ox:oX, ox:oX,
oy:oY, oy:oY,
x: x, x: x,
y: y, y: y,
sprite: img, sprite: img,
name: name, name: name,
active: false} active: false
); });
setTokenCreateFormVisible(false); setTokenCreateFormVisible(false);
return; return;
} }
setErr("All token fields are required"); setErr("All token fields are required");
} catch {}
} }
function destroyToken(id) { function destroyToken(id) {
@ -257,21 +267,27 @@ function destroyToken(id) {
} }
function previewExistingToken(id) { function previewExistingToken(id) {
const existing = tokens.find(t=>t.t.id == id); try {
if (existing) { const existing = tokens.find(t=>t.t.id == id);
tokenWidth.value = existing.t.w; const dropdown = $("sprite_dropdown");
tokenHeight.value = existing.t.h; if (existing) {
tokenCX.value = existing.t.oX; $("token_width").value = existing.t.w;
tokenCY.value = existing.t.oY; $("token_height").value = existing.t.h;
tokenName.value = existing.t.name; $("token_cx").value = existing.t.oX;
for (let i = 0; i < tokenSpriteDropdown.options.length; i++) { $("token_cy").value = existing.t.oY;
if (tokenSpriteDropdown.options[i].value == existing.t.sprite) { $("token_name").value = existing.t.name;
tokenSpriteDropdown.selectedIndex = i; for (let i = 0; i < dropdown.options.length; i++ ) {
break; if (dropdown.options[i].value === existing.t.sprite) {
dropdown.selectedIndex = i;
break;
}
} }
reinitializeSpritePreview(true);
} }
reinitializeSpritePreview(true); } catch (err) {
console.log(err);
} }
} }
function copyToken(id) { function copyToken(id) {
@ -280,20 +296,19 @@ function copyToken(id) {
} }
function renderTokenMasterList() { function renderTokenMasterList() {
if (tokenZone) { const tokenList = $("token_list");
let tokenMasterListHTML = ""; if (tokenList) {
const scroll = tokenZone.scrollTop; const scroll = tokenList.scrollTop;
for (const t of tokens) { tokenList.innerHTML = tokens.reduce((s, t) => {
tokenMasterListHTML += `<li><a href="#" onclick="previewExistingToken('${t.t.id}');return false">${t.t.name}</a><button onclick="copyToken('${t.t.id}')">Copy</button><button onclick="destroyToken('${t.t.id}')">Destroy</button></li>\n`; return s + `<li><a href="#" onclick="previewExistingToken('${t.t.id}');return false">${t.t.name}</a><button onclick="copyToken('${t.t.id}')">Copy</button><button onclick="destroyToken('${t.t.id}')">Destroy</button></li>\n`;
} }, "");
tokenZone.innerHTML = tokenMasterListHTML; tokenList.scrollTop = scroll;
tokenZone.scrollTop = scroll;
} }
} }
function publishAuxMsg() { function publishAuxMsg() {
const txtArea = document.getElementById("auxMsgZone"); const txtArea = $("aux_msg_input");
if (txtArea != null) { if (txtArea) {
publish({auxMsg: txtArea.value, auth: adminToken.access_token}); publish({auxMsg: txtArea.value, auth: adminToken.access_token});
} }
} }
@ -306,54 +321,30 @@ function sendToken(t) {
publish({token: t, auth: adminToken.access_token}); publish({token: t, auth: adminToken.access_token});
} }
async function uploadMapImg() { async function uploadImg(imgType) {
try { try {
var input = document.getElementById("map_img_upload"); var input = $(`${imgType}_img_upload`);
var data = new FormData(); var data = new FormData();
data.append('file', input.files[0]); data.append('file', input.files[0]);
data.append('name', tableKey.name); data.append('name', tableKey.name);
data.append('passcode', tableKey.passcode); data.append('passcode', tableKey.passcode);
const headers = new Headers(); const headers = new Headers();
headers.set('Authorization', 'Bearer ' + adminToken.access_token); headers.set('Authorization', 'Bearer ' + adminToken.access_token);
res = await fetch(`/admin/api/upload/${tableKey.name}/map/`, { res = await fetch(`/admin/api/upload/${tableKey.name}/${imgType}/`, {
headers: headers, headers: headers,
method: "POST", method: "POST",
body: data, body: data,
}); });
if (res.ok) { if (res.ok) {
// refresh so we can see the new entry in the list loadAdmin(tableKey.name, tableKey.passcode);
rebindUi(tableKey.name, tableKey.passcode);
} else { } else {
throw new Error("Something went wrong uploading the map BG..."); throw new Error("Something went wrong uploading the ${imgType} image...");
}
} catch (err) {
setErr(`${err.name}: ${err.message}`);
}
}
async function uploadTokenImg() {
try {
var input = document.getElementById("token_img_upload");
var data = new FormData();
data.append('file', input.files[0]);
data.append('name', tableKey.name);
data.append('passcode', tableKey.passcode);
const headers = new Headers();
headers.set('Authorization', 'Bearer ' + adminToken.access_token);
res = await fetch(`/admin/api/upload/${tableKey.name}/token/`, {
headers: headers,
method: "POST",
body: data,
});
if (res.ok) {
// refresh so we can see the new entry in the list
rebindUi(tableKey.name, tableKey.passcode);
} else {
throw new Error("Something went wrong uploading the token sprite...");
} }
} catch (err) { } catch (err) {
setErr(`${err.name}: ${err.message}`); setErr(`${err.name}: ${err.message}`);
} }
} }
async function deleteImg(url) { async function deleteImg(url) {
try { try {
if (url.startsWith("/uploads/")) { if (url.startsWith("/uploads/")) {
@ -371,8 +362,7 @@ async function deleteImg(url) {
}); });
if (res.ok) { if (res.ok) {
// refresh UI loadAdmin(tableKey.name, tableKey.passcode);
rebindUi(tableKey.name, tableKey.passcode);
} else { } else {
throw new Error ("Something went wrong deleting the image..."); throw new Error ("Something went wrong deleting the image...");
} }
@ -393,12 +383,10 @@ async function destroyTable() {
body: JSON.stringify(tableKey) body: JSON.stringify(tableKey)
}); });
if (res.ok) { if (res.ok) {
conn.close(1000); leave();
initializeMap("");
getTables(); getTables();
} else { } else {
setErr(await res.json()); setErr("Error destroying table");
} }
} }
} catch (err) { } catch (err) {
@ -406,49 +394,58 @@ async function destroyTable() {
} }
} }
function sortByName(a, b) {
return (a.name < b.name)
? -1
: ((a.name > b.name)
? 1
: 0)
}
async function getTables() { async function getTables() {
try { try {
const headers = new Headers(); const headers = new Headers();
headers.set('Authorization', 'Bearer ' + adminToken.access_token); headers.set('Authorization', 'Bearer ' + adminToken.access_token);
const res = await fetch('/admin/api/table/', { const res = await fetch('/admin/api/table/', {
method: 'GET', method: 'GET',
headers: headers headers: headers
}); });
if (res.ok) { if (res.ok) {
const tableList = await res.json(); const tblMgmt = $("table_management");
tableList.sort((a,b)=>{ const tableList = (await res.json()).sort(sortByName);
if (a.name < b.name) {
return -1; tblMgmt.innerHTML = tableList.reduce((s, t)=>{
} else if (a.name > b.name) { return s + `<li><a href="#" onclick="loadAdmin('${t.name}','${t.passcode}');return false;">${t.name}</a></li>\n`
return 1; }, "<ul>\n" ) + "</ul>";
}
return 0;
});
let tableListHTML = "<ul>\n";
for (const t of tableList) {
tableListHTML += `<li><a href="#" onclick="rebindUi('${t.name}','${t.passcode}');return false;">${t.name}</a></li>\n`
}
tableListHTML += "</ul>" tableListHTML += "</ul>"
adminZone.innerHTML = tableListHTML; tblMgmt.style.display = "none";
tokenWrapper.style.display = "none";
} else { } else {
// fail silently // fail silently
} }
} catch { } catch {
// fail silently // fail silently
} }
} }
async function doLogin() { async function doLogin() {
const adminUsrInput = document.getElementById("name_entry"); const adminUsrInput = $("name_entry");
const adminPassInput = document.getElementById("input_admin_pass"); const adminPassInput = $("input_admin_pass");
const adminUI = $("admin_ui");
const tblMgmt = $("table_management");
const tokenMgmt = $("token_management");
if (adminUsrInput && adminPassInput) { if (adminUsrInput && adminPassInput && adminUI && tblMgmt && tokenMgmt) {
adminToken = await getAdminToken(adminUsrInput.value, adminPassInput.value); adminToken = await getAdminToken(adminUsrInput.value, adminPassInput.value);
if (adminToken) { if (adminToken) {
getTables(); getTables();
adminWrapper.style.display="inline";
adminZone.style.display = "block"; tblMgmt.style.display = "block";
tokenMgmt.style.display = "none";
adminUI.style.display="inline";
closeErr(); closeErr();
replaceAdminModal(); replaceAdminModal();
} else { } else {
@ -458,7 +455,7 @@ async function doLogin() {
} }
function replaceAdminModal() { function replaceAdminModal() {
const adminModal = document.getElementById("admin_modal"); const adminModal = $("admin_modal");
if (adminModal) { if (adminModal) {
adminModal.innerHTML = "<a href='./'>Logout</a>"; adminModal.innerHTML = "<a href='./'>Logout</a>";
} }
@ -483,61 +480,66 @@ async function getAdminToken(user, pass) {
} }
function setTableCreateFormVisible(v) { function setTableCreateFormVisible(v) {
if (createTableForm) { try {
createTableForm.style.display = v ? "block" : "none"; $("table_creation_form").style.display = v ? "block" : "none";
} if (!v) {
if (!v) { $("new_table_name").value = "";
if (newTableName) { $("new_table_pass").value = "";
newTableName.value = "";
} }
if (newTablePass) { } catch {}
newTablePass.value = "";
}
}
} }
function setTokenCreateFormVisible(v) { function setTokenCreateFormVisible(v) {
if (createTokenForm && tokenZone) { try {
if (v) { if (v) {
// clear the form when displaying because we may have values from a preview of an existing token $("token_width").value = "";
tokenWidth.value = ""; $("token_height").value = "";
tokenHeight.value = ""; $("token_cx").value = "";
tokenCX.value = ""; $("token_cy").value = "";
tokenCY.value = ""; $("token_name").value = "";
tokenName.value = ""; $("sprite_dropdown").selectedIndex = 0;
tokenSpriteDropdown.selectedIndex = 0;
} }
createTokenForm.style.display = v ? "block" : "none"; $("token_creation_form").style.display = v ? "block" : "none";
tokenZone.style.display = v ? "none" : "block"; $("token_list").style.display = v ? "none" : "block";
previewZone.innerHTML = ""; $("token_admin_preview").innerHTML = "";
} } catch {}
} }
async function createTable() { async function createTable() {
const headers = new Headers(); const newTableName = $("new_table_name");
headers.set('Authorization', 'Bearer ' + adminToken.access_token); const newTablePass = $("new_table_pass");
const formData = new FormData(); if (newTableName && newTablePass) {
formData.set("name", newTableName.value); const headers = new Headers();
formData.set("passcode", newTablePass.value); headers.set('Authorization', 'Bearer ' + adminToken.access_token);
let bodyStr = "{"; const formData = new FormData();
for (const pair of formData.entries()) { formData.set("name", newTableName.value);
bodyStr += `"${pair[0]}": "${pair[1]}",`; formData.set("passcode", newTablePass.value);
}
bodyStr = bodyStr.slice(0, -1); let bodyStr = "{";
bodyStr += "}"; for (const pair of formData.entries()) {
const res = await fetch('/admin/api/table/', { bodyStr += `"${pair[0]}": "${pair[1]}",`;
method: 'POST', }
headers: headers, bodyStr = bodyStr.slice(0, -1);
body: bodyStr, bodyStr += "}";
});
if (res.ok) { try {
getTables(); const res = await fetch('/admin/api/table/', {
setTableCreateFormVisible(false); method: 'POST',
} else if (res.status === 422) { headers: headers,
setErr('Table name and passcode must be only alphanumeric and underscores'); body: bodyStr,
} else { });
setErr('Error creating table'); if (res.ok) {
getTables();
setTableCreateFormVisible(false);
} else if (res.status === 422) {
setErr("Table name and passcode must be only alphanumeric and underscores");
} else {
setErr("Error creating table");
}
} catch {
setErr("Error creating table");
}
} }
} }

View file

@ -1,10 +1,10 @@
function rollDice() { function rollDice() {
const name = document.getElementById("name_entry"); const name = $("name_entry");
const numDice = document.getElementById("num_dice"); const numDice = $("num_dice");
const faces = document.getElementById("dice_faces"); const faces = $("dice_faces");
const note = document.getElementById("dice_note"); const note = $("dice_note");
if (conn == null || table == null) { if (!conn || !tableKey.name) {
setErr("Looks like you haven't joined a table yet."); setErr("Looks like you haven't joined a table yet.");
return; return;
} }

View file

@ -16,7 +16,7 @@
</noscript> </noscript>
<div id="map"></div> <div id="map"></div>
<div id="errWrapper" style='display:none'><button id="closeErr" onclick="closeErr()">x</button><div id="errDiv"></div></div> <div id="err_wrapper" style='display:none'><button id="err_close" onclick="closeErr()">x</button><div id="err_div"></div></div>
<nav> <nav>
<section id="user_section"> <section id="user_section">
@ -74,9 +74,9 @@
<details class="ui_win"><summary>status</summary><pre id="aux"></pre></details><br/> <details class="ui_win"><summary>status</summary><pre id="aux"></pre></details><br/>
<details class="ui_win"><summary>token select</summary> <details class="ui_win"><summary>token select</summary>
<button id="tokenPreview_alt_clear" onclick="dismissPreview()" style="display: none;">Dismiss Preview</button> <button id="token_preview_clear" onclick="dismissPreview()" style="display: none;">Dismiss Preview</button>
<div id="tokenPreview_alt"></div> <div id="token_preview"></div>
<input hidden id="tokenPreview_alt_id"/> <input hidden id="token_preview_id"/>
<ul id="token_select" class="single_btn_list"></ul> <ul id="token_select" class="single_btn_list"></ul>
</details><br/> </details><br/>
</div> </div>
@ -92,38 +92,38 @@
</details> </details>
<br/> <br/>
<div id="adminWrapper" style="display:none;"> <div id="admin_ui" style="display:none;">
<details id="admin_table_win" class="ui_win admin_win"><summary>table</summary> <details id="admin_table_win" class="ui_win admin_win"><summary>table</summary>
<button onclick="setTableCreateFormVisible(true)">New Table</button> <button onclick="setTableCreateFormVisible(true)">New Table</button>
<form onsubmit="return false" id="createTableForm" style="display:none;"> <form onsubmit="return false" id="table_creation_form" style="display:none;">
<label>Name<input id="newTableName"/></label><br/> <label>Name<input id="new_table_name"/></label><br/>
<label>Passcode<input id="newTablePass" type="password"/></label><br/> <label>Passcode<input id="new_table_pass" type="password"/></label><br/>
<button type="submit" onclick="createTable()">Create</button> <button type="submit" onclick="createTable()">Create</button>
<button onclick="setTableCreateFormVisible(false)">Cancel</button> <button onclick="setTableCreateFormVisible(false)">Cancel</button>
</form> </form>
<div id="adminZone"></div> <div id="table_management"></div>
</details><br/> </details><br/>
<div id="adminWrapper_tokens"> <div id="token_management">
<details id="admin_token_win" class="ui_win admin_win"><summary>tokens</summary> <details id="admin_token_win" class="ui_win admin_win"><summary>tokens</summary>
<button onclick="setTokenCreateFormVisible(true)">New Token</button> <button onclick="setTokenCreateFormVisible(true)">New Token</button>
<form onsubmit="return false" id="createTokenForm" style="display:none;"> <form onsubmit="return false" id="token_creation_form" style="display:none;">
<label>Sprite<select id="token_combobox" onchange="previewSprite(this)"></select></label><br/> <label>Sprite<select id="sprite_dropdown" onchange="previewSprite(this)"></select></label><br/>
<label>Name<input id="token_name"/></label><br/> <label>Name<input id="token_name"/></label><br/>
<label>Width<input type="number" id="token_width" min="1" max="9999" step="1" onchange="previewSprite(this)"/></label><label id="aspectLockLabel" for="tokenKeepAspect">&#128274;</label><input type="checkbox" checked id="tokenKeepAspect" onchange="toggleAspectLock()"/><br/> <label>Width<input type="number" id="token_width" min="1" max="9999" step="1" onchange="previewSprite(this)"/></label><label id="aspect_lock_label" for="token_aspect_lock">&#128274;</label><input type="checkbox" checked id="token_aspect_lock" onchange="toggleAspectLock()"/><br/>
<label>Height<input type="number" id="token_height" min="1" step="1" max="9999" onchange="previewSprite(this)"/></label><br/> <label>Height<input type="number" id="token_height" min="1" step="1" max="9999" onchange="previewSprite(this)"/></label><br/>
<label>cX<input type="number" id="token_cx" min="0" max="9999" step="1" onchange="previewSprite(this)"/></label><br/> <label>cX<input type="number" id="token_cx" min="0" max="9999" step="1" onchange="previewSprite(this)"/></label><br/>
<label>cY<input type="number" id="token_cy" min="0" max="9999" step="1" onchange="previewSprite(this)"/></label><br/> <label>cY<input type="number" id="token_cy" min="0" max="9999" step="1" onchange="previewSprite(this)"/></label><br/>
<button type="submit" onclick="createToken()">Create</button> <button type="submit" onclick="createToken()">Create</button>
<button onclick="setTokenCreateFormVisible(false)">Cancel</button> <button onclick="setTokenCreateFormVisible(false)">Cancel</button>
</form> </form>
<div id="tokenPreview_zone"></div> <div id="token_admin_preview"></div>
<ul id="tokenZone" class="two_btn_list"></ul> <ul id="token_list" class="two_btn_list"></ul>
</details><br/> </details><br/>
<details id="admin_sprite_win" class="ui_win admin_win"><summary>sprites</summary> <details id="admin_sprite_win" class="ui_win admin_win"><summary>sprites</summary>
<div id="spriteZone"></div> <div id="sprite_zone"></div>
</details> </details>
</div> </div>

View file

@ -8,18 +8,32 @@ function initializeMap(mapImgUrl) {
let init = false; let init = false;
if (!map) { if (!map) {
init = true; init = true;
map = L.map('map', { minZoom: 0, maxZoom: 4, crs: L.CRS.Simple, attributionControl: false, zoomControl: false }); map = L.map("map", {
map.on("zoomend", ()=>{resizeMarkers();scaleSpritePreview();scaleAltSpritePreview();}); minZoom: 0,
maxZoom: 4,
crs: L.CRS.Simple,
attributionControl: false,
zoomControl: false
});
map.on("zoomend", () => {
resizeMarkers();
scaleSpritePreview();
scaleAltSpritePreview();
});
} }
if (mapImg) { if (mapImg) {
mapImg.removeFrom(map); mapImg.removeFrom(map);
} }
mapImg = L.imageOverlay(mapImgUrl, worldBounds); mapImg = L.imageOverlay(mapImgUrl, worldBounds);
mapImg.addTo(map); mapImg.addTo(map);
map.setMaxBounds(cameraBounds); map.setMaxBounds(cameraBounds);
if (init) { if (init) {
map.setView([0,0], 2); map.setView([0,0], 2);
} }
resizeMarkers(); resizeMarkers();
} }
@ -92,7 +106,6 @@ function toggleActive(tokenId) {
if (existing) { if (existing) {
const self = Object.assign({}, existing.t); const self = Object.assign({}, existing.t);
self.active = !self.active; self.active = !self.active;
console.log(self);
publish({token: stripToken(self)}); publish({token: stripToken(self)});
} }
} }
@ -104,7 +117,6 @@ function moveToken(id) {
const realPos = existing.m.getLatLng(); const realPos = existing.m.getLatLng();
self.x = realPos.lng; self.x = realPos.lng;
self.y = realPos.lat; self.y = realPos.lat;
publish({token: stripToken(self)}); publish({token: stripToken(self)});
} }
} }
@ -131,7 +143,9 @@ function NewToken(token) {
draggable: true, draggable: true,
autoPan: true autoPan: true
}); });
marker.on("moveend", ()=>{moveToken(token.id)}); marker.on("moveend", ()=>{moveToken(token.id)});
const node = document.createElement('div'); const node = document.createElement('div');
node.innerText = token.name; node.innerText = token.name;
marker.bindPopup(node); marker.bindPopup(node);

View file

@ -1,177 +1,18 @@
let tableKey = { const tableKey = {
name: "", name: "",
passcode: "" passcode: ""
} }
let conn = null; let conn = null;
let offline = false; let offline = false;
let msgQ = []; const msgQ = [];
const lagDiv = document.getElementById("lag");
const secondaryPreviewZone = document.getElementById("tokenPreview_alt");
const secondaryPreviewIdInput = document.getElementById("tokenPreview_alt_id");
const dismissPreviewBtn = document.getElementById("tokenPreview_alt_clear");
function showTableModal(show) {
const modal = document.getElementById("table_modal");
if (modal) {
modal.style.display = show ? "block" : "none";
}
}
function fmtLeading(n) {
return n < 10 ? "0" + n : String(n);
}
function formatDice(r) {
const date = new Date(r.timestamp)
const p = document.createElement("p");
const month = date.getMonth() + 1;
const day = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();
const seconds = date.getSeconds();
p.innerHTML = `${date.getFullYear()}-${fmtLeading(month)}-${fmtLeading(day)} ${fmtLeading(hours)}:${fmtLeading(minutes)}:${fmtLeading(seconds)} ${r.player} rolled ${r.roll.length}d${r.faces} ${(r.note ? "(" + r.note + ")" : "")}<br>[${r.roll}] (total ${r.roll.reduce((a,c)=>a+c,0)})`;
return p;
}
function logDice(dice) {
const diceLog = document.getElementById("dice_log");
if (!Array.isArray(dice)) {
dice = [ dice ];
} else {
if (diceLog) {
diceLog.innerHTML = "";
}
}
if (diceLog) {
for(const r of dice) {
try{
const p = formatDice(r);
diceLog.append(p);
p.scrollIntoView();
} catch{}
}
}
}
function setAuxMsg(msg) {
const auxDiv = document.getElementById("aux");
if (auxDiv) {
auxDiv.innerText = msg;
}
}
function updateTokens(tokens) {
// update internal token array and map
processTokens(tokens);
// update token select window
renderTokenSelect();
// if admin, update token master list
renderTokenMasterList();
}
function renderTokenSelect() {
const tokenSelect = document.getElementById("token_select");
let tokenSelectHTML = ""
const scroll = tokenSelect.scrollTop;
for (const t of tokens) {
tokenSelectHTML += `<li><a href="#" onclick="initSpritePreviewById('${t.t.id}')">${t.t.name}</a><button onclick="toggleActive('${t.t.id}');return false">${(t.t.active ? "Deactivate" : "Activate")}</button></li>\n`;
}
tokenSelect.innerHTML = tokenSelectHTML;
tokenSelect.scrollTop = scroll;
}
// the following few functions aren't socket related but they directly relate to the previous function
function initSpritePreviewById(id) {
const token = tokens.find(t=>t.t.id == id);
let img = null;
if (token && id) {
img = document.createElement("img");
img.src = token.t.sprite;
secondaryPreviewIdInput.value = id;
img.onload = () => {
scaleAltSpritePreview();
}
}
dismissPreviewBtn.style.display = (token && id) ? "block" : "none";
secondaryPreviewZone.innerHTML = "";
if (img) {
secondaryPreviewZone.appendChild(img);
}
}
function dismissPreview() {
initSpritePreviewById(null);
}
function scaleAltSpritePreview() {
if (mapImg && mapImg._image) {
const id = secondaryPreviewIdInput.value;
const scaleFactor = mapImg._image.clientWidth / mapImg._image.naturalWidth;
const img = secondaryPreviewZone.children[0];
const token = tokens.find(t=>t.t.id == id);
if (img && token) {
img.width = token.t.w * scaleFactor;
img.height = token.t.h * scaleFactor;
}
}
}
function makeUpToDate(msg) {
if (msg) {
// map image has to be set before tokens can be handled!
if (msg.mapImg) {
setMapImg(msg.mapImg);
}
if (msg.auxMsg) {
setAuxMsg(msg.auxMsg);
}
if (msg.diceRolls) {
logDice(msg.diceRolls);
} else if (msg.diceRoll) {
logDice(msg.diceRoll);
}
if (msg.tokens) {
updateTokens(msg.tokens);
} else if (msg.token) {
updateTokens([msg.token]);
}
}
}
function setMapImg(url) {
initializeMap(url);
}
function isTableKeyValid(name, passcode) {
const r = /^[a-zA-Z0-9_]+$/;
return r.test(name) && r.test(passcode);
}
function leave() {
conn.close(1000);
}
function dial() { function dial() {
// get tableKey from UI // get tableKey from UI
const tblNameInput = document.getElementById("input_table_name"); const tblNameInput = $("input_table_name");
const tblPassInput = document.getElementById("input_table_pass"); const tblPassInput = $("input_table_pass");
const joinTblBtn = document.getElementById("table_join"); const joinTblBtn = $("table_join");
const leaveTblBtn = document.getElementById("table_leave"); const leaveTblBtn = $("table_leave");
if (tblNameInput && tblPassInput && tblNameInput.value && tblPassInput.value) { if (tblNameInput && tblPassInput && tblNameInput.value && tblPassInput.value) {
if (isTableKeyValid(tblNameInput.value, tblPassInput.value)) { if (isTableKeyValid(tblNameInput.value, tblPassInput.value)) {
@ -191,8 +32,11 @@ function dial() {
setErr("Table not found - check the name and passcode are correct"); setErr("Table not found - check the name and passcode are correct");
} else if (e.code > 1001) { } else if (e.code > 1001) {
lagDiv.style.display = "block"; const lagDiv = $("lag");
setTimeout(dial, 1000) if (lagDiv) {
lagDiv.style.display = "block";
setTimeout(dial, 1000)
}
} else { } else {
tblNameInput.readOnly = false; tblNameInput.readOnly = false;
@ -200,7 +44,7 @@ function dial() {
joinTblBtn.style.display = adminToken ? "none" : "inline"; joinTblBtn.style.display = adminToken ? "none" : "inline";
leaveTblBtn.style.display = "none"; leaveTblBtn.style.display = "none";
tabletop = document.getElementById("tabletop"); tabletop = $("tabletop");
if (tabletop) { if (tabletop) {
tabletop.style.display = "none"; tabletop.style.display = "none";
} }
@ -218,22 +62,29 @@ function dial() {
}); });
conn.addEventListener("open", e => { conn.addEventListener("open", e => {
offline = false; offline = false;
tblNameInput.readOnly = true; tblNameInput.readOnly = true;
tblPassInput.readOnly = true; tblPassInput.readOnly = true;
joinTblBtn.style.display = "none"; joinTblBtn.style.display = "none";
leaveTblBtn.style.display = adminToken ? "none" : "inline"; leaveTblBtn.style.display = adminToken ? "none" : "inline";
lagDiv.style.display = "none"; lagDiv = $("lag");
if (lagDiv) {
lagDiv.style.display = "none";
}
while (msgQ.some(m=>m)) { while (msgQ.some(m=>m)) {
publish(msgQ[0]); publish(msgQ[0]);
msgQ.shift(); msgQ.shift();
} }
closeErr(); closeErr();
tabletop = document.getElementById("tabletop"); tabletop = $("tabletop");
if (tabletop) { if (tabletop) {
tabletop.style.display = "block"; tabletop.style.display = "block";
} }
}); });
conn.addEventListener("error", e => { conn.addEventListener("error", e => {
setErr(`Websocket error`); setErr(`Websocket error`);
conn.close(3000); conn.close(3000);
@ -283,3 +134,163 @@ async function publish(msg) {
} }
} }
} }
function makeUpToDate(msg) {
if (msg) {
// map image has to be set before tokens can be handled!
if (msg.mapImg) {
setMapImg(msg.mapImg);
}
if (msg.auxMsg) {
setAuxMsg(msg.auxMsg);
}
if (msg.diceRolls) {
logDice(msg.diceRolls);
} else if (msg.diceRoll) {
logDice(msg.diceRoll);
}
if (msg.tokens) {
updateTokens(msg.tokens);
} else if (msg.token) {
updateTokens([msg.token]);
}
}
}
function fmtLeading(n) {
return n < 10 ? "0" + n : String(n);
}
function formatDice(r) {
const date = new Date(r.timestamp)
const p = document.createElement("p");
const month = date.getMonth() + 1;
const day = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();
const seconds = date.getSeconds();
p.innerHTML = `${date.getFullYear()}-${fmtLeading(month)}-${fmtLeading(day)} ${fmtLeading(hours)}:${fmtLeading(minutes)}:${fmtLeading(seconds)} ${r.player} rolled ${r.roll.length}d${r.faces} ${(r.note ? "(" + r.note + ")" : "")}<br>[${r.roll}] (total ${r.roll.reduce((a,c)=>a+c,0)})`;
return p;
}
function logDice(dice) {
const diceLog = $("dice_log");
if (!Array.isArray(dice)) {
dice = [ dice ];
} else {
if (diceLog) {
diceLog.innerHTML = "";
}
}
if (diceLog) {
for(const r of dice) {
try{
const p = formatDice(r);
diceLog.append(p);
p.scrollIntoView();
} catch{}
}
}
}
function setAuxMsg(msg) {
const auxDiv = $("aux");
if (auxDiv) {
auxDiv.innerText = msg;
}
}
function updateTokens(tokens) {
// update internal token array and map
processTokens(tokens);
// update token select window
renderTokenSelect();
// if admin, update token master list
renderTokenMasterList();
}
function renderTokenSelect() {
const tokenSelect = $("token_select");
if (tokenSelect) {
const scroll = tokenSelect.scrollTop;
tokenSelect.innerHTML = tokens.reduce((s, t) => {
return s + `<li><a href="#" onclick="initSpritePreviewById('${t.t.id}')">${t.t.name}</a><button onclick="toggleActive('${t.t.id}');return false">${(t.t.active ? "Deactivate" : "Activate")}</button></li>\n`;
}, "");
tokenSelect.scrollTop = scroll;
}
}
// the following few functions aren't socket related but they directly relate to the previous function
function initSpritePreviewById(id) {
const token = tokens.find(t=>t.t.id == id);
let img = null;
if (token && id) {
img = document.createElement("img");
img.src = token.t.sprite;
const hdnTokenId = $("token_preview_id");
if (hdnTokenId) {
hdnTokenId.value = id;
}
img.onload = () => {
scaleAltSpritePreview();
}
}
const previewClearBtn = $("token_preview_clear");
if (previewClearBtn) {
previewClearBtn.style.display = (token && id) ? "block" : "none";
}
const tokenPreview = $("token_preview");
if (tokenPreview) {
tokenPreview.innerHTML = "";
if (img) {
tokenPreview.appendChild(img);
}
}
}
function dismissPreview() {
initSpritePreviewById(null);
}
function scaleAltSpritePreview() {
const hdnTokenId = $("token_preview_id");
const tokenPreview = $("token_preview");
if (tokenPreview && hdnTokenId && mapImg && mapImg._image) {
const id = hdnTokenId.value;
const scaleFactor = mapImg._image.clientWidth / mapImg._image.naturalWidth;
const img = tokenPreview.children[0];
const token = tokens.find(t=>t.t.id == id);
if (img && token) {
img.width = token.t.w * scaleFactor;
img.height = token.t.h * scaleFactor;
}
}
}
function setMapImg(url) {
initializeMap(url);
}
function isTableKeyValid(name, passcode) {
const r = /^[a-zA-Z0-9_]+$/;
return r.test(name) && r.test(passcode);
}
function leave() {
conn.close(1000);
tableKey.name = "";
tableKey.passcode = "";
}

View file

@ -66,7 +66,7 @@ button:hover {
background: var(--main_color); background: var(--main_color);
} }
#errWrapper { #err_wrapper {
color: var(--err_color); color: var(--err_color);
background: var(--bg_color); background: var(--bg_color);
border: solid 2px var(--err_color); border: solid 2px var(--err_color);
@ -78,14 +78,14 @@ button:hover {
transform: translateX(-50%); transform: translateX(-50%);
} }
#closeErr { #err_close {
display: inline; display: inline;
border: none; border: none;
color: var(--err_color); color: var(--err_color);
padding: 0 1ch; padding: 0 1ch;
margin-right: 1ch; margin-right: 1ch;
} }
#errDiv { #err_div {
display: inline; display: inline;
} }
@ -130,15 +130,12 @@ pre {
overflow-y: auto; overflow-y: auto;
} }
#auxMsgZone { #aux_msg_input {
width: 100%; width: 100%;
padding:0.2em; padding:0.2em;
height: 8em; height: 8em;
} }
#adminWrapper {
}
summary { summary {
cursor: pointer; cursor: pointer;
} }
@ -205,11 +202,11 @@ nav {
background: transparent; background: transparent;
} }
#tokenKeepAspect { #token_aspect_lock {
display: none; display: none;
} }
#tokenPreview_zone { #token_admin_preview {
position: relative; position: relative;
} }

View file

@ -1,26 +1,17 @@
const errDiv = document.getElementById("errDiv");
const errWrapper = document.getElementById("errWrapper");
const defaultTheme = [ "#000000cc", "#ccccccff", "#1f9b92ff", "#002b36ff", "#DC143Cff" ]; const defaultTheme = [ "#000000cc", "#ccccccff", "#1f9b92ff", "#002b36ff", "#DC143Cff" ];
const bgCol_input = document.getElementById("bg_col_input");
const fgCol_input = document.getElementById("fg_col_input");
const mainCol_input = document.getElementById("main_col_input");
const subCol_input = document.getElementById("sub_col_input");
const errCol_input = document.getElementById("err_col_input");
const bgOp_input = document.getElementById("bg_col_opacity");
const fgOp_input = document.getElementById("fg_col_opacity");
const mainOp_input = document.getElementById("main_col_opacity");
const subOp_input = document.getElementById("sub_col_opacity");
const errOp_input = document.getElementById("err_col_opacity");
const saveData = { const saveData = {
username: "", username: "",
theme: defaultTheme, theme: defaultTheme,
} }
function $(id) {
return document.getElementById(id);
}
function setErr(x) { function setErr(x) {
const errDiv = $("err_div");
const errWrapper = $("err_wrapper");
if (errDiv) { if (errDiv) {
errDiv.innerHTML = x; errDiv.innerHTML = x;
} }
@ -30,6 +21,7 @@ function setErr(x) {
} }
function closeErr() { function closeErr() {
const errWrapper = $("err_wrapper");
if (errWrapper) { if (errWrapper) {
errWrapper.style.display = "none"; errWrapper.style.display = "none";
} }
@ -39,14 +31,14 @@ function loadStorage() {
saveData.username = localStorage.getItem("username"); saveData.username = localStorage.getItem("username");
savedTheme = JSON.parse(localStorage.getItem("theme")); savedTheme = JSON.parse(localStorage.getItem("theme"));
saveData.theme = savedTheme || defaultTheme; saveData.theme = savedTheme || defaultTheme;
const username = document.getElementById("name_entry"); const username = $("name_entry");
if (username) { if (username) {
username.value = saveData.username; username.value = saveData.username;
} }
} }
function saveName() { function saveName() {
const username = document.getElementById("name_entry"); const username = $("name_entry");
if (username) { if (username) {
saveData.username = username.value; saveData.username = username.value;
localStorage.setItem("username", saveData.username); localStorage.setItem("username", saveData.username);
@ -54,22 +46,26 @@ function saveName() {
} }
function setupDiceAutoScroll() { function setupDiceAutoScroll() {
const diceWin = document.getElementById("dice_win"); const diceWin = $("dice_win");
if (diceWin) { if (diceWin) {
diceWin.addEventListener("toggle", e => { diceWin.addEventListener("toggle", e => {
if (diceWin.open) { if (diceWin.open) {
const diceLog = document.getElementById("dice_log"); const diceLog = $("dice_log");
diceLog.children[diceLog.children.length - 1].scrollIntoView(); if (diceLog && diceLog.children.length > 0) {
diceLog.children[diceLog.children.length - 1].scrollIntoView();
}
} }
}); });
} }
} }
function hexToBytes(hex) { function hexToBytes(hex) {
let bytes = []; let bytes = [];
for (let c = 0; c < hex.length; c += 2) for (let c = 0; c < hex.length; c += 2) {
bytes.push(parseInt(hex.substr(c, 2), 16)); bytes.push(parseInt(hex.substr(c, 2), 16));
return bytes; }
return bytes;
} }
function toByte(v) { function toByte(v) {
@ -97,31 +93,31 @@ function resetTheme(theme) {
let err_opacity = hexToBytes(err_col.substr(7)); let err_opacity = hexToBytes(err_col.substr(7));
err_col = err_col.substr(0,7); err_col = err_col.substr(0,7);
bgCol_input.value = bg_col; $("bg_col_input").value = bg_col;
bgOp_input.value = bg_opacity; $("bg_col_opacity").value = bg_opacity;
fgCol_input.value = fg_col; $("fg_col_input").value = fg_col;
fgOp_input.value = fg_opacity; $("fg_col_opacity").value = fg_opacity;
mainCol_input.value = main_col; $("main_col_input").value = main_col;
mainOp_input.value = main_opacity; $("main_col_opacity").value = main_opacity;
subCol_input.value = sub_col; $("sub_col_input").value = sub_col;
subOp_input.value = sub_opacity; $("sub_col_opacity").value = sub_opacity;
errCol_input.value = err_col; $("err_col_input").value = err_col;
errOp_input.value = err_opacity; $("err_col_opacity").value = err_opacity;
} catch {} } catch {}
} }
function setTheme() { function setTheme() {
try{ try {
let bg_col = bgCol_input.value; let bg_col = $("bg_col_input").value
let bg_opacity = toByte(bgOp_input.value); let bg_opacity = toByte($("bg_col_opacity").value);
let fg_col = fgCol_input.value; let fg_col = $("fg_col_input").value;
let fg_opacity =(toByte(fgOp_input.value)); let fg_opacity = (toByte($("fg_col_opacity").value));
let main_col = mainCol_input.value; let main_col = $("main_col_input").value;
let main_opacity = (toByte(mainOp_input.value)); let main_opacity = (toByte($("main_col_opacity").value));
let sub_col = subCol_input.value; let sub_col = $("sub_col_input").value;
let sub_opacity = (toByte(subOp_input.value)); let sub_opacity = (toByte($("sub_col_opacity").value));
let err_col = errCol_input.value; let err_col = $("err_col_input").value;
let err_opacity = (toByte(errOp_input.value)); let err_opacity = (toByte($("err_col_opacity").value));
saveData.theme[0] = bg_col + bg_opacity; saveData.theme[0] = bg_col + bg_opacity;
saveData.theme[1] = fg_col + fg_opacity; saveData.theme[1] = fg_col + fg_opacity;