Improve many things on frontend

This commit is contained in:
Radon Rosborough 2021-08-15 15:58:06 -07:00
parent 570060ae9c
commit f92c12d8b0
3 changed files with 137 additions and 67 deletions

View File

@ -1,30 +1,81 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" style="overflow: hidden">
<head>
<meta charset="utf-8" />
<title><%= config.name %> - Riju</title>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css"
integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"
integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
/>
<link rel="stylesheet" href="/css/app.css" />
</head>
<body>
<div id="app">
<div id="editor" class="column"></div>
<div id="terminal" class="column"></div>
<button type="button" class="btn btn-success" id="runButton">Run</button>
<button type="button" class="btn btn-info" id="formatButton">Prettify</button>
<a href="/" class="btn btn-secondary" id="backButton">Switch to a different language</a>
</div>
<script>
window.rijuConfig = <%- JSON.stringify(config) %>;
</script>
<script src="/js/app.js"></script>
<script src="/js/app.js" defer></script>
<% if (fathomSiteId) { %>
<script src="https://cdn.usefathom.com/script.js" data-site="<%= fathomSiteId %>" defer></script>
<% } %>
</head>
<body>
<div class="columns" style="height: 100vh; margin: 0">
<div class="column" style="padding: 0">
<div id="header" style="border-bottom-style: solid; border-bottom-width: 1px; border-bottom-color: lightgray">
<a href="/" class="button is-small is-info">
<span class="icon is-small">
<i class="fas fa-home"></i>
</span>
</a>
<span style="display: inline-block; vertical-align: middle; margin-left: 6px; padding-top: 2px">
<b>Riju :: <%= config.name %></b>
</span>
<span style="display: inline-block; vertical-align: middle; height: 100%"></span>
<button id="runButton" type="button" class="button is-small is-success is-pulled-right">
<span>Run</span>
<span class="icon is-small">
<i class="fas fa-play"></i>
</span>
</button>
<button id="formatButton" type="button" class="button is-small is-info is-pulled-right is-hidden">
<span>Prettify</span>
<span class="icon is-small">
<i class="fas fa-code"></i>
</span>
</button>
<button id="lspButton" type="button" class="button is-small is-warning is-pulled-right is-hidden">
<span>Autocomplete OFF</span>
<span class="icon is-small">
<i class="fas fa-bolt"></i>
</span>
</button>
</div>
<div style="height: 100%">
<div id="editor" style="height: 100%; padding: 12px; padding-left: 0"></div>
</div>
</div>
<div class="column" id="terminal" style="background: black; padding: 0">
</div>
</div>
<div class="modal" id="modal">
<div class="modal-background will-close-modal"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title" id="modal-title"></p>
<button class="delete will-close-modal" aria-label="close"></button>
</header>
<section class="modal-card-body">
<pre id="modal-data"></pre>
</section>
</div>
</div>
</body>
</html>

View File

@ -21,6 +21,21 @@ import "xterm/css/xterm.css";
const DEBUG = window.location.hash === "#debug";
const config = window.rijuConfig;
const formatButton = document.getElementById("formatButton");
function closeModal() {
document.querySelector("html").classList.remove("is-clipped");
document.getElementById("modal").classList.remove("is-active");
}
function showError({ message, data }) {
document.getElementById("modal-title").innerText = message;
document.getElementById("modal-data").innerText =
data || "(no output on stderr)";
document.getElementById("modal").classList.add("is-active");
document.querySelector("html").classList.add("is-clipped");
}
class RijuMessageReader extends AbstractMessageReader {
constructor(socket) {
super();
@ -101,6 +116,9 @@ class RijuMessageWriter extends AbstractMessageWriter {
}
async function main() {
let serviceLogBuffers = {};
let serviceLogLines = {};
const term = new Terminal();
const fitAddon = new FitAddon();
term.loadAddon(fitAddon);
@ -126,9 +144,10 @@ async function main() {
}
function tryConnect() {
serviceLogBuffers = {};
serviceLogLines = {};
let clientDisposable = null;
let servicesDisposable = null;
const serviceLogBuffers = {};
console.log("Connecting to server...");
socket = new WebSocket(
(document.location.protocol === "http:" ? "ws://" : "wss://") +
@ -169,6 +188,8 @@ async function main() {
term.write(message.output);
return;
case "formattedCode":
formatButton.disabled = false;
formatButton.classList.remove("is-loading");
if (
typeof message.code !== "string" ||
typeof message.originalCode !== "string"
@ -235,19 +256,32 @@ async function main() {
console.error("Unexpected message from server:", message);
return;
}
if (DEBUG) {
let buffer = serviceLogBuffers[message.service] || "";
buffer += message.output;
while (buffer.includes("\n")) {
const idx = buffer.indexOf("\n");
const line = buffer.slice(0, idx);
buffer = buffer.slice(idx + 1);
let buffer = serviceLogBuffers[message.service] || "";
let lines = serviceLogLines[message.service] || [];
buffer += message.output;
while (buffer.includes("\n")) {
const idx = buffer.indexOf("\n");
const line = buffer.slice(0, idx);
buffer = buffer.slice(idx + 1);
lines.push(line);
if (DEBUG) {
console.log(`${message.service.toUpperCase()} || ${line}`);
}
serviceLogBuffers[message.service] = buffer;
}
serviceLogBuffers[message.service] = buffer;
serviceLogLines[message.service] = lines;
return;
case "serviceCrashed":
case "serviceFailed":
if (typeof message.service !== "string") {
console.error("Unexpected message from server:", message);
return;
}
formatButton.disabled = false;
formatButton.classList.remove("is-loading");
showError({
message: "Could not prettify code!",
data: serviceLogLines["formatter"].join("\n"),
});
return;
default:
console.error("Unexpected message from server:", message);
@ -288,6 +322,15 @@ async function main() {
minimap: { enabled: false },
scrollbar: { verticalScrollbarSize: 0 },
});
editor.addAction({
id: "runCode",
label: "Run",
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter],
contextMenuGroupId: "2_execution",
run: () => {
sendMessage({ event: "runCode", code: editor.getValue() });
},
});
window.addEventListener("resize", () => editor.layout());
editor.getModel().setValue(config.template + "\n");
monaco.editor.setModelLanguage(
@ -299,11 +342,25 @@ async function main() {
sendMessage({ event: "runCode", code: editor.getValue() });
});
if (config.format) {
document.getElementById("formatButton").classList.add("visible");
document.getElementById("formatButton").addEventListener("click", () => {
formatButton.classList.remove("is-hidden");
formatButton.addEventListener("click", () => {
formatButton.classList.add("is-loading");
formatButton.disabled = true;
serviceLogBuffers["formatter"] = "";
serviceLogLines["formatter"] = [];
sendMessage({ event: "formatCode", code: editor.getValue() });
});
}
if (config.lsp) {
document.getElementById("lspButton").classList.remove("is-hidden");
document.getElementById("lspButton").addEventListener("click", () => {
// Do stuff here
});
}
for (const elt of document.querySelectorAll(".will-close-modal")) {
elt.addEventListener("click", closeModal);
}
}
main().catch(console.error);

View File

@ -1,45 +1,7 @@
body {
margin: 0;
height: 100vh;
.xterm {
padding: 12px;
}
#app {
height: 100%;
}
.column {
width: 50%;
height: 100%;
float: left;
}
#editor {
overflow: hidden;
}
#terminal {
background: black;
}
#runButton {
position: absolute;
top: 25px;
right: calc(50% + 25px);
}
#formatButton {
position: absolute;
bottom: 25px;
right: calc(50% + 25px);
visibility: hidden;
}
#formatButton.visible {
visibility: visible;
}
#backButton {
position: absolute;
left: 25px;
bottom: 25px;
#header .button {
border-radius: 0;
}