updates style & introduces results overlay #2

Merged
arindy merged 1 commits from update-styling into main 2025-02-09 23:04:15 +01:00
7 changed files with 136 additions and 68 deletions

View File

@ -3,6 +3,8 @@ services:
container_name: dice-tower
image: dice-tower
restart: always
networks:
- reverse_proxy
networks:
reverse_proxy:

View File

@ -15,4 +15,11 @@ class OverlayResource {
fun get(@PathParam("diceid") diceid: String): TemplateInstance {
return Templates.overlay(diceid)
}
@GET
@Path("/results")
@Produces(MediaType.TEXT_HTML)
fun results(@PathParam("diceid") room: String): TemplateInstance {
return Templates.results(room)
}
}

View File

@ -0,0 +1,18 @@
package de.arindy.dicetower
import io.quarkus.qute.TemplateInstance
import jakarta.ws.rs.GET
import jakarta.ws.rs.Path
import jakarta.ws.rs.PathParam
import jakarta.ws.rs.Produces
import jakarta.ws.rs.core.MediaType
@Path("results/{room}")
class ResultsResource {
@GET
@Produces(MediaType.TEXT_HTML)
fun get(@PathParam("room") room: String): TemplateInstance {
return Templates.results(room)
}
}

View File

@ -7,4 +7,6 @@ import io.quarkus.qute.TemplateInstance
object Templates {
@JvmStatic
external fun overlay(diceid: String): TemplateInstance
@JvmStatic
external fun results(room: String): TemplateInstance
}

View File

@ -36,8 +36,11 @@
<body>
<div id="dice-box"></div>
<script type="module">
function url() {
return window.location.protocol + '//' + window.location.hostname + (window.location.port?.length > 0 ? ':' + window.location.port : '');
}
import DiceBox from "/vendor/dice-box/dice-box.es.js";
const evtSource = new EventSource(window.location.protocol + "//" + window.location.hostname + ':' + window.location.port + "/dice/{diceid??}/stream");
const evtSource = new EventSource(url() + "/dice/{diceid??}/stream");
const diceBox = new DiceBox("#dice-box", {
assetPath: "/vendor/assets/",
@ -62,9 +65,8 @@
evtSource.addEventListener("message", function (event) {
let data = JSON.parse(event.data);
diceBox.onRollComplete = (rollResult) => {
console.log(rollResult)
let httpRequest = new XMLHttpRequest();
httpRequest.open('POST',window.location.protocol + '//' + window.location.hostname + ':' + window.location.port + '/dice/' + data.room + '/results')
httpRequest.open('POST',url() + '/dice/' + data.room + '/results')
httpRequest.setRequestHeader('Content-Type', 'application/json')
httpRequest.send(JSON.stringify({
name: data.name,

View File

@ -3,6 +3,9 @@
<head>
<meta charset="UTF-8">
<title>Dice-Tower</title>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://www.w3schools.com/lib/w3-theme-black.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="/vendor/color-picker.js"></script>
<style>
.collapsible {
@ -24,87 +27,82 @@
overflow: hidden;
background-color: black;
}
button {
padding: 10px;
}
input {
margin: 10px;
}
</style>
</head>
<body>
<h1>Dice-Tower</h1>
<p>Welcome to Dice-Tower</p>
<label for="name" id="nameLabel">Name </label><input type="text" id="name" style="width: 500px" required/><br/>
<label for="room" id="roomLabel">Room </label><input type="text" id="room" style="width: 500px" required/><br/>
<div id="dice-tower" hidden>
<label for="overlayId">Overlay </label><input type="text" readonly id="overlayId" style="width: 500px"/>
<br/>
<label for="theme">Theme </label>
<select name="theme" id="theme">
<option value="default">Default</option>
<option value="blueGreenMetal">Blue-Green Metal</option>
<option value="diceOfRolling">Dice of Rolling</option>
<option value="gemstone">Gemstone</option>
<option value="gemstoneMarble">Marble Gemstone</option>
<option value="rock">Rock</option>
<option value="rust">Rust</option>
<option value="smooth">Smooth</option>
<option value="wooden">Wooden</option>
</select>
<br/>
<button type="button" class="collapsible">Theme Color</button>
<div class="content">
<color-picker value="#b218cd" id="themeColor"></color-picker>
</div><br/>
<p>Example Commands: "1d6", "2d8 1d100", "5d6+10"</p>
<label for="command">Command </label><input type="text" id="command"/><br/><br/>
</div>
<button hidden id="roll" onclick="roll()">Roll
</button>
<button id="start" onclick="start()">Start
</button>
<br/>
<div id="results">
<body class="w3-theme-l4">
<div class="w3-container w3-content" style="height: 100vh">
<h1>Dice-Tower</h1>
<p>Welcome to Dice-Tower</p>
<div class="w3-panel w3-white w3-card w3-display-container" style="padding: 25px">
<label for="name" id="nameLabel">Name </label><input type="text" id="name" style="width: 75%" required onkeyup="start(event)"/><br/>
<label for="room" id="roomLabel">Room </label><input type="text" id="room" style="width: 75%" required onkeyup="start(event)"/><br/>
</div>
<div id="dice-tower" hidden class="w3-panel w3-white w3-card w3-display-container" style="padding: 25px">
<label for="overlayId">Dice-Overlay </label><input type="text" readonly id="overlayId" style="width: 75%"/><br/>
<label for="resultsId">Results-Overlay </label><input type="text" readonly id="resultsId" style="width: 75%"/><br/>
<hr style="width:100%;color:black;background-color:black;height:1px">
<label for="theme">Theme </label>
<select name="theme" id="theme">
<option value="default">Default</option>
<option value="blueGreenMetal">Blue-Green Metal</option>
<option value="diceOfRolling">Dice of Rolling</option>
<option value="gemstone">Gemstone</option>
<option value="gemstoneMarble">Marble Gemstone</option>
<option value="rock">Rock</option>
<option value="rust">Rust</option>
<option value="smooth">Smooth</option>
<option value="wooden">Wooden</option>
</select>
<br/>
<button type="button" class="collapsible">Theme Color</button>
<div class="content">
<color-picker value="#b218cd" id="themeColor"></color-picker>
</div><br/>
<p>Example Commands: "1d6", "2d8 1d100", "5d6+10"</p>
<label for="command">Command </label><input type="text" id="command" onkeyup="roll(event)"/>
<button hidden id="roll" onclick="roll()">Roll</button>
</div>
<button id="start" onclick="start()">Start</button>
<div id="results" hidden class="w3-panel w3-white w3-card w3-display-container" style="padding: 25px; overflow: hidden; height: 50vh;">
<h2>Results</h2>
<iframe id="resultFrame" title="results" style="width: 100%; height: 85%; overflow: hidden" onload="this.height=this.contentWindow.document.body.scrollHeight;"></iframe>
</div>
</div>
<script>
function start() {
if(document.getElementById('name').value.length > 0 && document.getElementById('room').value.length > 0) {
document.getElementById('overlayId').value = window.location.protocol + '//' + window.location.hostname + ':' + window.location.port + '/overlay/' + document.getElementById('room').value + ':' + localStorage.getItem('userId');
function url() {
return window.location.protocol + '//' + window.location.hostname + (window.location.port?.length > 0 ? ':' + window.location.port : '');
}
function start(event) {
console.log(event)
if((!event || event.keyCode === 13) && document.getElementById('name').value.length > 0 && document.getElementById('room').value.length > 0) {
document.getElementById('overlayId').value = url() + '/overlay/' + document.getElementById('room').value + ':' + localStorage.getItem('userId');
document.getElementById('resultsId').value = url() + '/overlay/' + document.getElementById('room').value + '/results';
document.getElementById('resultFrame').src = url() + '/overlay/' + document.getElementById('room').value + '/results';
document.getElementById('roll').hidden = false;
document.getElementById('start').hidden = true;
document.getElementById('dice-tower').hidden = false;
document.getElementById('name').hidden = true;
document.getElementById('room').hidden = true;
document.getElementById('results').hidden = false;
document.getElementById('nameLabel').innerHTML = 'Name: <strong>' + document.getElementById('name').value + '</strong>';
document.getElementById('roomLabel').innerHTML = 'Room: <strong>' + document.getElementById('room').value + '</strong>';
const evtSource = new EventSource(window.location.protocol + '//' + window.location.hostname + ':' + window.location.port + '/dice/' + document.getElementById('room').value + '/results');
evtSource.addEventListener('message', function (event) {
console.log(event.data)
let data = JSON.parse(event.data);
let name = document.getElementById(data.name) ?? document.createElement('div');
name.id = data.name;
name.replaceChildren(...[]);
let node = document.createElement('p');
let resultText = ''
if (!data.results) {
resultText = ' rolling...'
} else {
data.results.forEach(result => {
let values = []
result.rolls.forEach(roll => {
values.push(roll.value);
})
resultText += ' (' + values.join(' + ') + (result.modifier > 0 ? ' <a style="text-decoration: underline">+' + result.modifier + '</a>': result.modifier < 0 ? ' <a style="text-decoration: underline">' + result.modifier + '</a>': '') + ' = <strong style="font-size: x-large">' + result.value + '</strong>) '
})
}
node.innerHTML = '<strong>' + data.name + ':</strong> &#127922; ' + resultText
name.appendChild(node)
document.getElementById('results').appendChild(name);
})
}
}
function roll() {
if(document.getElementById('name').value.length > 0 && document.getElementById('room').value.length > 0) {
function roll(event) {
if((!event || event.keyCode === 13) && document.getElementById('command').value?.length > 0) {
let httpRequest = new XMLHttpRequest();
httpRequest.open('POST',window.location.protocol + '//' + window.location.hostname + ':' + window.location.port + '/dice/' + document.getElementById('room').value + ':' + localStorage.getItem(`userId`))
httpRequest.open('POST', url() + '/dice/' + document.getElementById('room').value + ':' + localStorage.getItem(`userId`))
httpRequest.setRequestHeader('Content-Type', 'application/json')
httpRequest.send(JSON.stringify({
name: document.getElementById('name').value,

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Results</title>
</head>
<body>
<div id="results" style="padding: 25px; font-size: x-large">
</div>
<script type="module">
function url() {
return window.location.protocol + '//' + window.location.hostname + (window.location.port?.length > 0 ? ':' + window.location.port : '');
}
const evtSource = new EventSource(url() + '/dice/{room}/results');
evtSource.addEventListener('message', function (event) {
let data = JSON.parse(event.data);
let name = document.getElementById(data.name) ?? document.createElement('div');
name.id = data.name;
name.replaceChildren(...[]);
let node = document.createElement('p');
let resultText = ''
if (!data.results) {
resultText = ' rolling...'
} else {
data.results.forEach(result => {
let values = []
result.rolls.forEach(roll => {
values.push(roll.value);
})
resultText += ' (' + values.join(' + ') + (result.modifier > 0 ? ' <a style="text-decoration: underline">+' + result.modifier + '</a>': result.modifier < 0 ? ' <a style="text-decoration: underline">' + result.modifier + '</a>': '') + ' = <strong style="font-size: x-large">' + result.value + '</strong>) '
})
}
node.innerHTML = '<strong>' + data.name + ':</strong> &#127922; ' + resultText
name.appendChild(node)
document.getElementById('results').appendChild(name);
})
</script>
</body>
</html>