Improve many things on frontend
This commit is contained in:
parent
570060ae9c
commit
f92c12d8b0
|
@ -1,30 +1,81 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en" style="overflow: hidden">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title><%= config.name %> - Riju</title>
|
<title><%= config.name %> - Riju</title>
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
|
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css"
|
||||||
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
|
integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q=="
|
||||||
crossorigin="anonymous"
|
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" />
|
<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>
|
<script>
|
||||||
window.rijuConfig = <%- JSON.stringify(config) %>;
|
window.rijuConfig = <%- JSON.stringify(config) %>;
|
||||||
</script>
|
</script>
|
||||||
<script src="/js/app.js"></script>
|
<script src="/js/app.js" defer></script>
|
||||||
<% if (fathomSiteId) { %>
|
<% if (fathomSiteId) { %>
|
||||||
<script src="https://cdn.usefathom.com/script.js" data-site="<%= fathomSiteId %>" defer></script>
|
<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>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -21,6 +21,21 @@ import "xterm/css/xterm.css";
|
||||||
const DEBUG = window.location.hash === "#debug";
|
const DEBUG = window.location.hash === "#debug";
|
||||||
const config = window.rijuConfig;
|
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 {
|
class RijuMessageReader extends AbstractMessageReader {
|
||||||
constructor(socket) {
|
constructor(socket) {
|
||||||
super();
|
super();
|
||||||
|
@ -101,6 +116,9 @@ class RijuMessageWriter extends AbstractMessageWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
let serviceLogBuffers = {};
|
||||||
|
let serviceLogLines = {};
|
||||||
|
|
||||||
const term = new Terminal();
|
const term = new Terminal();
|
||||||
const fitAddon = new FitAddon();
|
const fitAddon = new FitAddon();
|
||||||
term.loadAddon(fitAddon);
|
term.loadAddon(fitAddon);
|
||||||
|
@ -126,9 +144,10 @@ async function main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryConnect() {
|
function tryConnect() {
|
||||||
|
serviceLogBuffers = {};
|
||||||
|
serviceLogLines = {};
|
||||||
let clientDisposable = null;
|
let clientDisposable = null;
|
||||||
let servicesDisposable = null;
|
let servicesDisposable = null;
|
||||||
const serviceLogBuffers = {};
|
|
||||||
console.log("Connecting to server...");
|
console.log("Connecting to server...");
|
||||||
socket = new WebSocket(
|
socket = new WebSocket(
|
||||||
(document.location.protocol === "http:" ? "ws://" : "wss://") +
|
(document.location.protocol === "http:" ? "ws://" : "wss://") +
|
||||||
|
@ -169,6 +188,8 @@ async function main() {
|
||||||
term.write(message.output);
|
term.write(message.output);
|
||||||
return;
|
return;
|
||||||
case "formattedCode":
|
case "formattedCode":
|
||||||
|
formatButton.disabled = false;
|
||||||
|
formatButton.classList.remove("is-loading");
|
||||||
if (
|
if (
|
||||||
typeof message.code !== "string" ||
|
typeof message.code !== "string" ||
|
||||||
typeof message.originalCode !== "string"
|
typeof message.originalCode !== "string"
|
||||||
|
@ -235,19 +256,32 @@ async function main() {
|
||||||
console.error("Unexpected message from server:", message);
|
console.error("Unexpected message from server:", message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (DEBUG) {
|
let buffer = serviceLogBuffers[message.service] || "";
|
||||||
let buffer = serviceLogBuffers[message.service] || "";
|
let lines = serviceLogLines[message.service] || [];
|
||||||
buffer += message.output;
|
buffer += message.output;
|
||||||
while (buffer.includes("\n")) {
|
while (buffer.includes("\n")) {
|
||||||
const idx = buffer.indexOf("\n");
|
const idx = buffer.indexOf("\n");
|
||||||
const line = buffer.slice(0, idx);
|
const line = buffer.slice(0, idx);
|
||||||
buffer = buffer.slice(idx + 1);
|
buffer = buffer.slice(idx + 1);
|
||||||
|
lines.push(line);
|
||||||
|
if (DEBUG) {
|
||||||
console.log(`${message.service.toUpperCase()} || ${line}`);
|
console.log(`${message.service.toUpperCase()} || ${line}`);
|
||||||
}
|
}
|
||||||
serviceLogBuffers[message.service] = buffer;
|
|
||||||
}
|
}
|
||||||
|
serviceLogBuffers[message.service] = buffer;
|
||||||
|
serviceLogLines[message.service] = lines;
|
||||||
return;
|
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;
|
return;
|
||||||
default:
|
default:
|
||||||
console.error("Unexpected message from server:", message);
|
console.error("Unexpected message from server:", message);
|
||||||
|
@ -288,6 +322,15 @@ async function main() {
|
||||||
minimap: { enabled: false },
|
minimap: { enabled: false },
|
||||||
scrollbar: { verticalScrollbarSize: 0 },
|
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());
|
window.addEventListener("resize", () => editor.layout());
|
||||||
editor.getModel().setValue(config.template + "\n");
|
editor.getModel().setValue(config.template + "\n");
|
||||||
monaco.editor.setModelLanguage(
|
monaco.editor.setModelLanguage(
|
||||||
|
@ -299,11 +342,25 @@ async function main() {
|
||||||
sendMessage({ event: "runCode", code: editor.getValue() });
|
sendMessage({ event: "runCode", code: editor.getValue() });
|
||||||
});
|
});
|
||||||
if (config.format) {
|
if (config.format) {
|
||||||
document.getElementById("formatButton").classList.add("visible");
|
formatButton.classList.remove("is-hidden");
|
||||||
document.getElementById("formatButton").addEventListener("click", () => {
|
formatButton.addEventListener("click", () => {
|
||||||
|
formatButton.classList.add("is-loading");
|
||||||
|
formatButton.disabled = true;
|
||||||
|
serviceLogBuffers["formatter"] = "";
|
||||||
|
serviceLogLines["formatter"] = [];
|
||||||
sendMessage({ event: "formatCode", code: editor.getValue() });
|
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);
|
main().catch(console.error);
|
||||||
|
|
|
@ -1,45 +1,7 @@
|
||||||
body {
|
.xterm {
|
||||||
margin: 0;
|
padding: 12px;
|
||||||
height: 100vh;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#app {
|
#header .button {
|
||||||
height: 100%;
|
border-radius: 0;
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue