";
tokenSelect.innerHTML = tokenSelectHTML;
}
function makeUpToDate(table) {
if (table) {
// map image has to be set before tokens can be handled!
if (table.mapImg) {
setMapImg(table.mapImg);
}
if (table.auxMsg) {
setAuxMsg(table.auxMsg);
}
if (table.diceRolls) {
logDice(table.diceRolls);
} else if (table.diceRoll) {
logDice(table.diceRoll);
}
if (table.tokens) {
updateTokens(table.tokens);
} else if (table.token) {
updateTokens([table.token]);
}
}
}
function setMapImg(url) {
initializeMap(url);
}
function isTableKeyValid(name, passcode) {
const r = /^[a-zA-Z0-9_]+$/;
return r.test(name) && r.test(passcode);
}
function dial() {
// get tableKey from UI
const tblNameInput = document.getElementById("input_table_name");
const tblPassInput = document.getElementById("input_table_pass");
if (tblNameInput && tblPassInput && tblNameInput.value && tblPassInput.value) {
if (isTableKeyValid(tblNameInput.value, tblPassInput.value)) {
tableKey.name = tblNameInput.value;
tableKey.passcode = tblPassInput.value;
if (conn) {
conn.close(1000);
}
conn = new WebSocket(`ws://${location.host}/subscribe`, `${tableKey.name}.${tableKey.passcode}`);
conn.addEventListener("close", e => {
if (e.code == 1006) {
setErr("Table not found - check the name and passcode are correct");
} else if (e.code > 1001) {
// TODO: add message to let user know they are reconnecting
setErr("Websocket error: trying to reconnect");
setTimeout(dial, 1000)
} else {
tabletop = document.getElementById("tabletop");
if (tabletop) {
tabletop.style.display = "none";
}
table = null;
while (tokens.some(t=>t)) {
tokens[0].m.removeFrom(map);
tokens.shift();
}
mapImg.removeFrom(map);
mapImg = null;
}
});
conn.addEventListener("open", e => {
// TODO: add message to let user know they are at the table
tabletop = document.getElementById("tabletop");
if (tabletop) {
tabletop.style.display = "block";
}
});
conn.addEventListener("error", e => {
setErr(`${e.name}: ${e.message}`);
conn.close(3000);
})
conn.addEventListener("message", e => {
const data = JSON.parse(e.data);
if (table == null) {
// dicerolls are treated as a byte array when marshalling to json, so we have to decode them
data.diceRolls.forEach(r=>{
r.roll = Uint8Array.from(atob(r.roll), c => c.charCodeAt(0))
})
table = data;
makeUpToDate(table);
} else {
if (data.diceRoll) {
data.diceRoll.roll = Uint8Array.from(atob(data.diceRoll.roll), c => c.charCodeAt(0));
}
makeUpToDate(data);
}
console.log(data);
});
} else {
setErr("Table name and passcode can only be alphanumeric and underscores");
}
}else {
setErr("Table name and passcode required");
}
}
async function publish(msg) {
msg.key = tableKey;
const res = await fetch('/publish', {
method: 'POST',
body: JSON.stringify(msg)
});
if (!res.ok) {
setErr("Failed to publish message");
}
}