Improve many things on frontend
This commit is contained in:
parent
570060ae9c
commit
f92c12d8b0
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue