From af11db6f55b28b1588f5de32fe3d42520db9cadd Mon Sep 17 00:00:00 2001 From: Rusty Striker Date: Fri, 18 Oct 2024 16:07:10 +0300 Subject: [PATCH] split index.html to multiple files --- assets/web/app.js | 263 +++++++++++++++++++++ assets/web/index.html | 351 +--------------------------- assets/web/style.css | 74 ++++++ assets/web/{socket.js => tavern.js} | 0 src/main.rs | 15 +- 5 files changed, 356 insertions(+), 347 deletions(-) create mode 100644 assets/web/app.js create mode 100644 assets/web/style.css rename assets/web/{socket.js => tavern.js} (100%) diff --git a/assets/web/app.js b/assets/web/app.js new file mode 100644 index 0000000..1d341b5 --- /dev/null +++ b/assets/web/app.js @@ -0,0 +1,263 @@ +// init - game view (map) +const GRID_SIZE = 200; // Grid size in pixels +var mapScale = 1.0; +var mapOffsetX = 0.0; +var mapOffsetY = 0.0; +var draggedToken = { token: null, offX: 0, offY: 0 }; +var draggedDiv = { div: null, offX: 0, offY: 0 }; + +function init() { + let view = document.getElementById('game-view'); + view.onwheel = onGameViewScroll; + view.onmousemove = onGameMouseMove; + view.onmouseup = onGameMouseUp; + view.oncontextmenu = () => false; + // allow sending chat message using enter (and shift-enter for new line) + document.getElementById('newmsg-content').onkeypress = (e) => { + if(e.key == "Enter" && !e.shiftKey) { + sendChatMessage(); + return false; + } + } + document.getElementById('login-username').onkeypress = (e) => { + if(e.key == 'Enter') { + document.getElementById('login-pass').focus(); + return false; + } + } + document.getElementById('login-pass').onkeypress = (e) => { + if(e.key == 'Enter') { + onLoginClick(); + return false; + } + } + // focus on the username field for the sake of just pressing enter multiple times + document.getElementById('login-username').focus(); + document.body.onclick = (e) => { + document.getElementById('msg-context-menu').style.display = 'none'; + } + document.body.onmousemove = onMoveableDivDrag; + document.body.onmouseup = onMoveableDivMouseUp; + // TODO: Remove when done dev-ing + tavern.onmessage({ text: 'test', id: 1, source: 'rusty', character: 'bart' }); +} + +tavern.onlogin = (s) => { + if(s) { + let login = document.getElementById('login-screen'); + let game = document.getElementById('game'); + login.style.display = 'none'; + game.style.display = 'flex'; + // get last 50 msgs (i think that is enough for now) when we get in + tavern.get_last_msgs(50); + tavern.get_tokens(); + } + else { + alert("Invalid username or password!"); + } +} +tavern.onmessage = (m) => { + console.log(m); + let msg = document.createElement('div'); + msg.className = 'chat-message'; + // #abusing_style_order_as_both_id_variable_and_forcing_chronological_order + msg.style.order = m.id; + msg.innerHTML = ` +

+ ${m.character ?? ''} + (${m.source}) +

+
+

+ ${m.text.replace('\n', '\n
\n')} +

+ ` + msg.oncontextmenu = (e) => { + if(e.shiftKey) { return true; } + let cm = document.getElementById('msg-context-menu'); + cm.style.display = 'flex'; + cm.style.top = `${e.pageY}px`; + cm.style.left = `${e.pageX}px`; + return false; + } + if(m.actions) { + let holder = document.createElement('div'); + holder.style.display = 'flex'; + holder.style.flexWrap = 'wrap'; + msg.appendChild(holder); + for (const act of m.actions) { + let button = document.createElement('button'); + button.innerText = act.display_name ?? act.name; + button.action = act; + button.onclick = () => console.log(button.action); + button.style.margin = '2px'; + button.onclick = () => openRollsPopup(act); + holder.appendChild(button); + } + } + let history = document.getElementById('chat-history'); + // this is to force update everytime we get a duplicate msg to allow msg editing (yay) + let exists = Array.from(history.children).filter(e => e.style.order == m.id)[0]; + if(exists) { + history.removeChild(exists); + } + history.appendChild(msg); + msg.scrollIntoView(); +} +tavern.onspawntoken = (t) => { + console.log(t); + let map = document.getElementById('map'); + let token = document.createElement('div'); + token.className = 'token token-transition'; + token.style.top = `${t.y * GRID_SIZE}px`; + token.style.left = `${t.x * GRID_SIZE}px`; + token.token_id = t.token_id; + token.innerHTML = ` + + ` + token.onmousedown = (e) => { + token.classList.remove('token-transition'); + draggedToken.token = token; + draggedToken.offX = ((e.clientX - mapOffsetX) / mapScale) - parseInt(token.style.left); + draggedToken.offY = ((e.clientY - mapOffsetY) / mapScale) - parseInt(token.style.top); + token.children[0].style.cursor = 'grabbing'; + } + map.appendChild(token); +} +tavern.onmovetoken = (m) => { + let token = Array.from(document.getElementsByClassName('token')).filter(t => t.token_id == m.token_id)[0] + if(token) { + token.style.top = `${m.y * GRID_SIZE}px`; + token.style.left = `${m.x * GRID_SIZE}px`; + } +} +function onLoginClick() { + let username = document.getElementById('login-username').value; + let pass = document.getElementById('login-pass').value; + if(username == 'test') { + // TODO: Remove this for when im done dev-ing with this file + tavern.onlogin(true); + } + tavern.login(username, pass); +} +function onGameViewScroll(event) { + let map = document.getElementById('map'); + mapScale += (event.wheelDelta / 1800.0); + if(mapScale < 0.1) { mapScale = 0.1; } + map.style.transform = `scale(${mapScale})`; +} +function onGameMouseMove(event) { + if(event.buttons == 2) { + // right click + let map = document.getElementById('map'); + let mult = event.ctrlKey ? 2.0 : 1.0; + mapOffsetX += event.movementX * mult; + mapOffsetY += event.movementY * mult; + map.style.left = `${mapOffsetX}px`; + map.style.top = `${mapOffsetY}px`; + } + else if(draggedToken.token != null && event.buttons == 1) { + let top = (event.clientY - mapOffsetY) / mapScale - draggedToken.offY; + let left = (event.clientX - mapOffsetX) / mapScale - draggedToken.offX; + draggedToken.token.style.top = `${top}px`; + draggedToken.token.style.left = `${left}px`; + } +} +function onGameMouseUp() { + if(draggedToken.token != null) { + let t = draggedToken.token; + let x = Math.floor(0.5 + parseInt(t.style.left) / GRID_SIZE); + let y = Math.floor(0.5 + parseInt(t.style.top) / GRID_SIZE); + let id = t.token_id; + t.classList.add('token-transition'); + t.children[0].style.cursor = ''; + tavern.move_token(id, x, y); + draggedToken.token = null; + } +} +function sendChatMessage() { + let tb = document.getElementById('newmsg-content'); + // get the msg and reset the textarea + let text = tb.value; + tb.value = ''; + tavern.simple_msg(text); +} +function openRollsPopup(action) { + let holder = document.getElementById('dice-roll-holder'); + holder.innerHTML = ''; // remove all holder children + holder.action = action; + if(action.rolls != undefined && Array.isArray(action.rolls)) { + for (const r of action.rolls) { + // name (extra) (dice_amount)d(dice_type) + constant | enabled + console.log(r); + let row = document.createElement('div'); + row.style.display = 'flex'; + row.roll = r; + row.innerHTML = ` +

${r.name} ${r.extra != null ? '(' + r.extra + ')' : ''}

+

${r.dice_amount}d${r.dice_type} + ${r.constant}

+ + `; + holder.appendChild(row); + } + } + document.getElementById('dice-roll-title').innerText = action.display_name ?? action.name; + document.getElementById('dice-roll-popup').style.display = 'flex'; +} +function rollPopup() { + // TODO: Maybe let the server roll the dice? + // first - hide the popup + document.getElementById('dice-roll-popup').style.display = 'none'; + // get the holder and start rolling dice + let rolls = []; + let holder = document.getElementById('dice-roll-holder'); + for(const h of holder.children) { + if(h.roll && h.children[2].checked) { + let roll = { name: h.roll.name, extra: h.roll.extra }; + let msg = ''; + let sum = 0; + for (let i = 0; i < h.roll.dice_amount; i++) { + // Math.random gives a value in [0, 1), so we need to add 1 at the end + let roll = Math.floor(Math.random() * h.roll.dice_type) + 1; + sum += roll; + msg += `${roll}`; + if(i != h.roll.dice_amount - 1 || h.roll.constant != 0) { + msg += ' + '; + } + } + if(h.roll.constant != 0) { + sum += h.roll.constant; + msg += `${h.roll.constant}`; + } + roll.result = sum; + roll.result_text = msg; + rolls.push(roll); + } + } + console.log(rolls); + tavern.action_result(holder.action.name, 'Louise', [], rolls); +} +function onMoveableDivMouseDown(e, id) { + if(e.buttons == 1) { + let div = document.getElementById(id); + let rect = div.getBoundingClientRect(); + draggedDiv.div = div; + draggedDiv.offX = e.clientX - rect.x; + draggedDiv.offY = e.clientY - rect.y; + + } +} +function onMoveableDivDrag(e) { + if(draggedDiv.div) { + draggedDiv.div.style.right = ''; + draggedDiv.div.style.top = `${e.clientY - draggedDiv.offY}px`; + draggedDiv.div.style.left = `${e.clientX - draggedDiv.offX}px`; + } +} +function onMoveableDivMouseUp(e, id) { + draggedDiv.div = null; +} +function showHideDiv(id) { + let div = document.getElementById(id); + div.style.display = div.style.display == 'none' ? 'flex' : 'none'; +} \ No newline at end of file diff --git a/assets/web/index.html b/assets/web/index.html index 5eab126..79ff186 100644 --- a/assets/web/index.html +++ b/assets/web/index.html @@ -1,360 +1,22 @@ - - - - + + + +
+
+ +