clean up dom access and IDs
This commit is contained in:
parent
331150a0ff
commit
7a294373c5
7 changed files with 512 additions and 492 deletions
488
static/admin.js
488
static/admin.js
|
@ -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;'>← table list</a><br>";
|
|
||||||
infoHtml += `<textarea id='auxMsgZone'>${table.auxMsg}</textarea><br><button onclick='publishAuxMsg()'>Set Status</button>`
|
|
||||||
infoHtml += "<button onclick='destroyTable()'>Destroy Table</button><br/>";
|
|
||||||
infoHtml += "<input id='map_img_upload' type='file'/><button onclick='uploadMapImg()'>Upload Map</button><br/>"
|
|
||||||
if (mapImgs.ok) {
|
|
||||||
infoHtml += "<label>Available Maps</label>";
|
|
||||||
const imgs = (await mapImgs.json()).sort();
|
|
||||||
infoHtml += "<ul class='two_btn_list'>";
|
|
||||||
for (const i of imgs) {
|
|
||||||
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`;
|
|
||||||
}
|
|
||||||
infoHtml += "</ul>";
|
|
||||||
} else {
|
|
||||||
infoHtml += "<label>Maps couldn't be retrieved</label>";
|
|
||||||
}
|
|
||||||
adminZone.innerHTML = infoHtml;
|
|
||||||
|
|
||||||
let tokenListHTML = "<input id='token_img_upload' type='file'/><button onclick='uploadTokenImg()'>Upload Sprite</button><br/>";
|
const table = await tableData.json()
|
||||||
if (tokenImgs.ok) {
|
|
||||||
const tokens = (await tokenImgs.json()).sort();
|
mgmtHTML = `<a href='#' onclick='getTables();return false;'>← table list</a><br>\n` +
|
||||||
tokenListHTML += "<ul class='single_btn_list'>";
|
`<textarea id='aux_msg_input'>${table.auxMsg}</textarea><br><button onclick='publishAuxMsg()'>Set Status</button>\n` +
|
||||||
for (const t of tokens) {
|
`<button onclick='destroyTable()'>Destroy Table</button><br/>\n` +
|
||||||
const parts = t.split("/");
|
`<input id='map_img_upload' type='file'/><button onclick='uploadImg("map")'>Upload Map</button><br/>\n`
|
||||||
tokenListHTML += `<li><a href="${t}" target="_blank">${parts[parts.length - 1]}</a> <button onclick="deleteImg('${t}')">Delete</button></li>\n`
|
|
||||||
}
|
if (mapImgs.ok) {
|
||||||
tokenListHTML += "</ul>";
|
const imgs = (await mapImgs.json()).sort();
|
||||||
fillSpriteDropdown(tokens);
|
mgmtHTML = imgs.reduce((s, i) => {
|
||||||
|
const parts = i.split("/");
|
||||||
|
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>";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
tokenListHTML += "<label>Sprites couldn't be retrieved</label>"
|
mgmtHTML += "<label>Maps couldn't be retrieved</label>";
|
||||||
|
}
|
||||||
|
$("table_management").innerHTML = mgmtHTML;
|
||||||
|
|
||||||
|
let spriteListHTML = `<input id='token_img_upload' type='file'/><button onclick='uploadImg("token")'>Upload Sprite</button><br/>`;
|
||||||
|
|
||||||
|
if (tokenImgs.ok) {
|
||||||
|
const sprites = (await tokenImgs.json()).sort();
|
||||||
|
spriteListHTML = sprites.reduce((s, t) => {
|
||||||
|
const parts = t.split("/");
|
||||||
|
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>";
|
||||||
|
fillSpriteDropdown(sprites);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
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 = "🔒"
|
const locked = $("token_aspect_lock").checked;
|
||||||
} else {
|
$("aspect_lock_label").innerHTML = locked ? "🔒" : "🔓"
|
||||||
aspectLockLabel.innerHTML = "🔓"
|
} 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;
|
const dropdown = $("sprite_dropdown");
|
||||||
|
const tokenName = $("token_name");
|
||||||
|
const tokenWidth = $("token_width");
|
||||||
|
const tokenHeight = $("token_height");
|
||||||
|
const tokenCX = $("token_cx");
|
||||||
|
const tokenCY = $("token_cy");
|
||||||
|
const preview = $("token_admin_preview");
|
||||||
|
|
||||||
if (!existing) {
|
if (dropdown && tokenName && tokenWidth && tokenHeight && tokenCX && tokenCY && preview) {
|
||||||
const tokenNameParts = tokenSpriteDropdown[tokenSpriteDropdown.selectedIndex].text.split(".");
|
|
||||||
tokenNameParts.pop();
|
const img = document.createElement("img");
|
||||||
tokenName.value = tokenNameParts.join(".");
|
img.src = dropdown[dropdown.selectedIndex].value;
|
||||||
}
|
|
||||||
|
|
||||||
img.onload = () => {
|
|
||||||
const w = img.naturalWidth;
|
|
||||||
const h = img.naturalHeight;
|
|
||||||
|
|
||||||
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");
|
||||||
|
|
||||||
|
if (newTableName && newTablePass) {
|
||||||
|
const headers = new Headers();
|
||||||
|
headers.set('Authorization', 'Bearer ' + adminToken.access_token);
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.set("name", newTableName.value);
|
formData.set("name", newTableName.value);
|
||||||
formData.set("passcode", newTablePass.value);
|
formData.set("passcode", newTablePass.value);
|
||||||
|
|
||||||
let bodyStr = "{";
|
let bodyStr = "{";
|
||||||
for (const pair of formData.entries()) {
|
for (const pair of formData.entries()) {
|
||||||
bodyStr += `"${pair[0]}": "${pair[1]}",`;
|
bodyStr += `"${pair[0]}": "${pair[1]}",`;
|
||||||
}
|
}
|
||||||
bodyStr = bodyStr.slice(0, -1);
|
bodyStr = bodyStr.slice(0, -1);
|
||||||
bodyStr += "}";
|
bodyStr += "}";
|
||||||
const res = await fetch('/admin/api/table/', {
|
|
||||||
method: 'POST',
|
try {
|
||||||
headers: headers,
|
const res = await fetch('/admin/api/table/', {
|
||||||
body: bodyStr,
|
method: 'POST',
|
||||||
});
|
headers: headers,
|
||||||
if (res.ok) {
|
body: bodyStr,
|
||||||
getTables();
|
});
|
||||||
setTableCreateFormVisible(false);
|
if (res.ok) {
|
||||||
} else if (res.status === 422) {
|
getTables();
|
||||||
setErr('Table name and passcode must be only alphanumeric and underscores');
|
setTableCreateFormVisible(false);
|
||||||
} else {
|
} else if (res.status === 422) {
|
||||||
setErr('Error creating table');
|
setErr("Table name and passcode must be only alphanumeric and underscores");
|
||||||
|
} else {
|
||||||
|
setErr("Error creating table");
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
setErr("Error creating table");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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">🔒</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">🔒</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>
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
351
static/socket.js
351
static/socket.js
|
@ -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 = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue