Files
justthefrax/host.html
2025-01-06 09:25:14 -08:00

211 lines
5.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<title>just the frax!</title>
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
<style>
:root {
--accent: #459991;
--accent-hover: #65e5d9;
}
.block {
border-radius: 10px;
border: thin gray solid;
margin: 10px;
margin-bottom: 5px;
padding: 5px 15px;
}
.warn {
background: orange;
color: black;
}
.title {
font-size: 1.2em;
font-weight: bold;
}
input {
width: 45%;
}
#players {
display: flex;
}
#warning {
display: none;
}
#players .block {
flex-grow: 1;
}
.team-list {
width: 100%;
button {
width: 100%;
}
}
</style>
</head>
<body>
<header>
<h1>just the frax!</h1>
<p>A game of truth and lies.</p>
</header>
<div class="block">
<div class="title">Status</div>
<div id="status-message"></div>
</div>
<div class="block warn" id="warning">
<div class="title">Error</div>
<p id="warning-message"></p>
</div>
<div id="players">
</div>
<div class="block">
<div class="title">Send Story</div>
<div>
<label for="recipient">Recipient</label>
<input type="text" id="recipient" readonly="true" value="None"/>
<textarea id="story-text"></textarea>
<button type="button" id="send-button">Send</send>
</div>
</div>
<script type="module">
const teams = new Map();
let recipient = null;
function updateRecipient(player) {
recipient = player;
const textarea = document.getElementById("recipient");
if (player)
textarea.value = player.name;
else
textarea.value = "None";
}
function updateTeamsView() {
const playersDiv = document.getElementById("players");
playersDiv.innerHTML = "";
teams.forEach((team, name) => {
const teamDiv = document.createElement("div");
teamDiv.classList.add("block");
teamDiv.innerHTML = `<div class='title'>Team ${name}</div>`;
const list = document.createElement("div");
list.classList.add("team-list");
team.forEach(player => {
const item = document.createElement("button");
item.innerHTML = player.name;
item.addEventListener("click", () => {
updateRecipient(player);
});
list.appendChild(item);
});
teamDiv.appendChild(list);
playersDiv.appendChild(teamDiv);
});
}
function addPlayer(player) {
if (!teams.has(player.team)) {
teams.set(player.team, new Map());
}
const team = teams.get(player.team);
team.set(player.id, player);
updateTeamsView();
}
function removePlayer(player) {
if (!teams.has(player.team))
return
const team = teams.get(player.team);
team.delete(player.id);
updateTeamsView();
}
function sendMessage(conn, type, message) {
const data = JSON.stringify({type, message});
console.log("Sending:", data);
conn.send(data);
}
function handleMessage(data, conn) {
console.warn("Got message data:", data);
const msg = JSON.parse(data)
switch (msg.type) {
case "error":
showError(msg.message);
break;
case "join":
addPlayer(msg.message);
break;
case "part":
removePlayer(msg.message);
break;
case "reveal":
break;
default:
showError(`Unknown message type: ${msg.type}`);
}
}
function showStatus(message) {
const statusDiv = document.getElementById('status-message');
statusDiv.innerHTML = message;
}
function showError(message) {
const warnDiv = document.getElementById('warning');
const warnMessage = document.getElementById('warning-message');
warnMessage.innerHTML = message;
warnDiv.style.display = "block";
}
var proto = "ws:";
if (location.protocol == "https:")
proto = "wss:";
showStatus("Connecting...");
const conn = new WebSocket(`${proto}//${location.host}/host/ws`);
conn.addEventListener("close", e => { showStatus("Disconnected."); });
conn.addEventListener("error", e => { showError("Websocket error."); });
conn.addEventListener("message", e => { handleMessage(e.data, conn); });
conn.addEventListener("open", e => { showStatus("Connected") });
const sendButton = document.getElementById('send-button');
sendButton.addEventListener("click", () => {
const textArea = document.getElementById('story-text');
const story = textArea.value;
sendMessage(conn, "activate", { player: recipient.id, story });
textArea.value = "";
updateRecipient(null);
});
</script>
</body>
</html>