211 lines
5.1 KiB
HTML
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>
|