mirror of
https://github.com/Noratrieb/viewstrap.git
synced 2026-01-14 08:35:11 +01:00
379 lines
9.3 KiB
HTML
379 lines
9.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Viewstrap</title>
|
|
<style>
|
|
html {
|
|
font-family: sans-serif;
|
|
}
|
|
|
|
h1 {
|
|
margin: 0;
|
|
}
|
|
|
|
.center-inner {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.item {
|
|
height: 100px;
|
|
width: 100px;
|
|
border: 1px black solid;
|
|
}
|
|
|
|
.item-action {
|
|
background: rgb(188, 188, 188);
|
|
}
|
|
|
|
.item-text {
|
|
font-size: 18pt;
|
|
text-align: center;
|
|
}
|
|
|
|
#inventory-wrapper {
|
|
display: flex;
|
|
height: 100px;
|
|
gap: 5px;
|
|
}
|
|
|
|
.item-compiler {
|
|
background: rgb(185, 210, 181);
|
|
}
|
|
|
|
.region {
|
|
border: 2px solid grey;
|
|
padding: 5px;
|
|
}
|
|
|
|
.crafting-wrapper {
|
|
display: flex;
|
|
}
|
|
|
|
.crafting-slot {
|
|
background: grey;
|
|
}
|
|
|
|
.crafting-slot-dragover {
|
|
background: green;
|
|
}
|
|
|
|
.crafting-icon {
|
|
height: 100px;
|
|
width: 70px;
|
|
font-size: 20pt;
|
|
}
|
|
|
|
.crafting-progress-indicator {
|
|
height: 100px;
|
|
width: 100px;
|
|
}
|
|
|
|
.crafting-progress-arrow {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.crafting-progress-arrow-running {
|
|
background: linear-gradient(
|
|
0deg,
|
|
#ff2400,
|
|
#e81d1d,
|
|
#e8b71d,
|
|
#e3e81d,
|
|
#1de840,
|
|
#1ddde8,
|
|
#2b1de8,
|
|
#dd00f3,
|
|
#dd00f3
|
|
);
|
|
|
|
background-size: 1800% 1800%;
|
|
animation: rainbow 10s ease infinite;
|
|
}
|
|
|
|
@keyframes rainbow {
|
|
0% {
|
|
background-position: 0% 82%;
|
|
}
|
|
50% {
|
|
background-position: 100% 19%;
|
|
}
|
|
100% {
|
|
background-position: 0% 82%;
|
|
}
|
|
}
|
|
|
|
#error {
|
|
color: red;
|
|
margin-left: 10px;
|
|
font-size: 18px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="region">
|
|
<h1>Inventory</h1>
|
|
<div id="inventory-wrapper"></div>
|
|
</div>
|
|
|
|
<div class="region">
|
|
<h1>Crafting</h1>
|
|
<div class="crafting-wrapper">
|
|
<div id="crafting-slot-1" class="crafting-slot item"></div>
|
|
<div class="crafting-icon center-inner">
|
|
<span class>➕</span>
|
|
</div>
|
|
<div id="crafting-slot-2" class="crafting-slot item"></div>
|
|
<div
|
|
id="crafting-progress-arrow"
|
|
class="crafting-progress-arrow"
|
|
role="button"
|
|
onclick="compile()"
|
|
>
|
|
<svg class="crafting-progress-indicator" viewBox="0 0 100 100">
|
|
<!--
|
|
Arrow.
|
|
line length 50, line height 20
|
|
triangle full height 20+2*20
|
|
triangle width 30
|
|
-->
|
|
<path
|
|
fill="currentColor"
|
|
d="
|
|
M 10,40
|
|
l 50,0
|
|
l 0,-20
|
|
L 90,50
|
|
L 60,80
|
|
l 0,-20
|
|
l -50,0
|
|
"
|
|
></path>
|
|
</svg>
|
|
</div>
|
|
<div class="crafting-slot item center-inner"></div>
|
|
|
|
<div id="error"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<textarea id="stdout" rows="30" cols="80"></textarea>
|
|
<textarea id="stderr" rows="30" cols="80"></textarea>
|
|
</div>
|
|
|
|
<script>
|
|
class Item {
|
|
constructor(name, type) {
|
|
this.name = name;
|
|
this.type = type;
|
|
}
|
|
}
|
|
|
|
const errorElem = document.getElementById("error");
|
|
|
|
function setError(msg) {
|
|
error.innerText = msg;
|
|
}
|
|
function resetError() {
|
|
error.innerText = "";
|
|
}
|
|
|
|
function renderItem(item) {
|
|
const inner = document.createElement("div");
|
|
inner.innerText = item.name;
|
|
inner.classList.add("item-text");
|
|
const elem = document.createElement("div");
|
|
elem.classList.add(`item-${item.type}`);
|
|
elem.classList.add("center-inner");
|
|
elem.classList.add("item");
|
|
elem.item = item;
|
|
elem.appendChild(inner);
|
|
elem.draggable = true;
|
|
elem.addEventListener("dragstart", (event) => {
|
|
const dt = event.dataTransfer;
|
|
dt.setData("application/json", JSON.stringify(item));
|
|
dt.dropEffect = "move";
|
|
});
|
|
return elem;
|
|
}
|
|
|
|
function setupDragDropSlot(elem) {
|
|
elem.addEventListener("dragover", (event) => {
|
|
event.preventDefault();
|
|
elem.classList.add("crafting-slot-dragover");
|
|
});
|
|
elem.addEventListener("dragleave", (event) => {
|
|
event.preventDefault();
|
|
elem.classList.remove("crafting-slot-dragover");
|
|
});
|
|
elem.addEventListener("drop", (event) => {
|
|
event.preventDefault();
|
|
|
|
resetError();
|
|
|
|
const data = JSON.parse(
|
|
event.dataTransfer.getData("application/json")
|
|
);
|
|
const item = new Item(data.name, data.type);
|
|
const itemElem = renderItem(item);
|
|
|
|
elem.innerHTML = "";
|
|
elem.appendChild(itemElem);
|
|
elem.classList.remove("crafting-slot-dragover");
|
|
elem.item = item;
|
|
});
|
|
}
|
|
|
|
class Inventory {
|
|
constructor(initialItems) {
|
|
this.dom = document.getElementById("inventory-wrapper");
|
|
|
|
for (const item of initialItems) {
|
|
const elem = renderItem(item);
|
|
this.dom.appendChild(elem);
|
|
}
|
|
|
|
this.craftingSlot1 = document.getElementById("crafting-slot-1");
|
|
this.craftingSlot2 = document.getElementById("crafting-slot-2");
|
|
|
|
setupDragDropSlot(this.craftingSlot1);
|
|
setupDragDropSlot(this.craftingSlot2);
|
|
}
|
|
|
|
items() {
|
|
const children = this.dom.children;
|
|
return Array.from(children).map((child) => child.item);
|
|
}
|
|
|
|
appendIfNotExists(item) {
|
|
const items = this.items();
|
|
if (
|
|
!items.find(
|
|
(inner) => inner.name == item.name && inner.type == item.type
|
|
)
|
|
) {
|
|
const elem = renderItem(item);
|
|
this.dom.appendChild(elem);
|
|
}
|
|
}
|
|
}
|
|
|
|
const stdout = document.getElementById("stdout");
|
|
const stderr = document.getElementById("stderr");
|
|
|
|
const compilersWrapper = document.getElementById("inventory-wrapper");
|
|
|
|
const compileActions = document.querySelectorAll(".compile-action");
|
|
|
|
const craftingProgressArrow = document.getElementById(
|
|
"crafting-progress-arrow"
|
|
);
|
|
|
|
const inventory = new Inventory([
|
|
new Item("compiler", "action"),
|
|
new Item("library", "action"),
|
|
]);
|
|
|
|
const ws = new WebSocket("ws://localhost:3000/ws");
|
|
|
|
ws.addEventListener("open", () => {
|
|
for (elem of compileActions) {
|
|
elem.disabled = false;
|
|
}
|
|
|
|
ws.send(JSON.stringify("ListCompilers"));
|
|
});
|
|
|
|
ws.addEventListener("message", (event) => {
|
|
console.log("Received event", event.data);
|
|
|
|
const msg = JSON.parse(event.data);
|
|
|
|
if ("Stdout" in msg) {
|
|
stdout.value += msg.Stdout;
|
|
}
|
|
if ("Stderr" in msg) {
|
|
stdout.value += msg.Stderr;
|
|
}
|
|
if ("AvailableCompilers" in msg) {
|
|
for (const compiler of msg.AvailableCompilers) {
|
|
inventory.appendIfNotExists(
|
|
new Item(`rustc ${compiler}`, "compiler")
|
|
);
|
|
}
|
|
}
|
|
if ("Done" in msg) {
|
|
craftingProgressArrow.classList.remove(
|
|
"crafting-progress-arrow-running"
|
|
);
|
|
const error = msg.Done ? "" : "an error occurred";
|
|
setError(error);
|
|
updateCompilers();
|
|
}
|
|
});
|
|
|
|
function compile() {
|
|
const arrowClasses = craftingProgressArrow.classList;
|
|
if (arrowClasses.contains("crafting-progress-arrow-running")) {
|
|
return;
|
|
}
|
|
|
|
console.log("compiling");
|
|
|
|
resetError();
|
|
|
|
const item1 = inventory.craftingSlot1.item;
|
|
if (!item1) {
|
|
setError("left side must be filled");
|
|
return;
|
|
}
|
|
const item2 = inventory.craftingSlot2.item;
|
|
if (!item2) {
|
|
setError("right side must be filled");
|
|
return;
|
|
}
|
|
|
|
console.log("Items", item1, item2);
|
|
|
|
const action = [item1, item2].find((item) => item.type == "action");
|
|
if (!action) {
|
|
setError("must include an action in the crafting receipe");
|
|
return;
|
|
}
|
|
const compiler = [item1, item2].find((item) => item.type == "compiler");
|
|
if (!compiler) {
|
|
setError("must include a compiler in the crafting receipe");
|
|
return;
|
|
}
|
|
|
|
arrowClasses.add("crafting-progress-arrow-running");
|
|
|
|
const compilerName = compiler.name.split(" ")[1];
|
|
const actionName = {
|
|
library: "BuildLibrary",
|
|
compiler: "BuildCompiler",
|
|
}[action.name];
|
|
|
|
ws.send(
|
|
JSON.stringify({
|
|
Compile: { compiler: compilerName, action: actionName },
|
|
})
|
|
);
|
|
|
|
stdout.value = "";
|
|
stderr.value = "";
|
|
}
|
|
|
|
function updateCompilers() {
|
|
console.log("list compilers");
|
|
|
|
ws.send(JSON.stringify("ListCompilers"));
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|