server-side that!!

This commit is contained in:
ari melody 2023-09-30 07:58:03 +01:00
parent 32189ecd21
commit 1edc2efdec
Signed by: ari
GPG key ID: CF99829C92678188
10 changed files with 384 additions and 49 deletions

BIN
public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -1,17 +1,18 @@
<!DOCTYPE html>
<html lang="ie">
<head>
<title>Open Terminal</title>
<title>OpenTerminal</title>
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="/styles/main.css">
<link rel="icon" type="image/png" href="/favicon.png">
<script src="scripts/main.js"></script>
<script src="/scripts/main.js"></script>
</head>
<body>
<main>
<pre id="content"></pre>
<div id="overlay"></div>
</main>
<div id="overlay"></div>
</body>
</html>

View file

@ -1,45 +1,106 @@
var TERM_INTERVAL = 0;
var buffer = "";
var send_buffer = "";
var content;
const banner =
`OpenTerminal v0.1.0
made with <3 by ari melody
`;
var client;
var pre_buffer_chars = 0;
var term_interval = 10;
var ready = false;
function start() {
console.log("%chello, world!", "color: #b7fd49; font-size: 3rem; font-weight: bold");
console.log(
`welcome to OpenTerminal!
home to a little shared text buffer.
i hope you enjoy your stay here!
to help you feel a little more comfortable, i've prepared some commands for you:
- set_colours(foreground, background)
changes the foreground and background colours of your terminal!
\`foreground\` and \`background\` must be hex colour codes, such as \`#ff00ff\`.
- set_palette(palette)
changes the foreground and background colours of your terminal to one of our many options of premade themes! including but not limited to the entire collection of catppuccin mocha colours! (i really like their palette ;p)
try it out! type \`PALETTE.\` into your console and browse the list of themes we have!`);
const foreground = localStorage.getItem("foreground");
const background = localStorage.getItem("background");
if (foreground && background) {
set_colours(foreground, background);
}
content = document.getElementById("content");
send_text(banner);
buffer += "Connecting to the server...";
setTimeout(connect, 500);
loop();
}
function loop() {
if (buffer.length > 0) {
const carat = content.querySelector("#carat");
if (carat) carat.remove();
const char = buffer.slice(0, 1);
if (char == "\b") {
content.innerText = content.innerText.slice(0, content.innerText.length - 1);
} else {
content.innerText += char;
}
buffer = buffer.slice(1);
const new_carat = document.createElement("div");
new_carat.id = "carat";
content.appendChild(new_carat);
const char = buffer.substring(0, 1);
insert_text(char);
buffer = buffer.substring(1);
}
setTimeout(loop, TERM_INTERVAL);
if (send_buffer.length > 0) {
const char = send_buffer.substring(0, 1);
client.send(char);
send_buffer = send_buffer.substring(1);
}
setTimeout(loop, term_interval);
}
function connect() {
client = new WebSocket("wss://localhost:8080");
client.addEventListener('open', () => {
// insert_text('\x00');
buffer += "\nConnection successful.\n\n";
buffer += "=== BEGIN SESSION ===\n\n";
});
client.addEventListener('message', event => {
buffer += event.data;
if (pre_buffer_chars == 0) {
pre_buffer_chars = content.innerText.length + buffer.length;
}
});
client.addEventListener('close', () => {
insert_text("\n\n[CONNECTION LOST]");
});
}
function insert_text(text) {
const carat = content.querySelector("#carat");
if (carat) carat.remove();
if (text == "\x00") {
content.innerText = "";
pre_buffer_chars = 0;
} else if (text == "\b" && content.innerText.length > pre_buffer_chars) {
content.innerText = content.innerText.slice(0, content.innerText.length - 1);
} else {
content.innerText += text;
}
const new_carat = document.createElement("div");
new_carat.id = "carat";
content.appendChild(new_carat);
}
function handle_input(event) {
// console.debug(event.key);
if (event.key == "'") {
event.preventDefault();
}
if (event.key == "Backspace") {
if (event.ctrlKey) {
if (event.ctrlKey && send_buffer.length == 0) {
const last_space = content.innerText.lastIndexOf(" ");
const last_newline = content.innerText.lastIndexOf("\n");
@ -49,34 +110,108 @@ function handle_input(event) {
}
const word_length = content.innerText.length - break_at;
send_text("\b".repeat(word_length));
for (let i = 0; i < word_length; i++) {
send_buffer += '\b';
}
return;
}
send_text("\b");
send_buffer += '\b';
return;
}
if (event.key.startsWith("Arrow")) {
if (event.key == "Enter") {
send_buffer += '\n';
return;
}
switch (event.key) {
case 'Shift':
case 'Control':
case 'Alt':
return;
case 'Enter':
send_text('\n');
break;
}
if (event.key.length > 1) {
return;
}
if (event.ctrlKey) {
return;
}
send_text(event.key);
send_buffer += event.key;
content.scrollTop = content.scrollHeight;
}
function send_text(char) {
function handle_paste(event) {
event.preventDefault();
if (send_buffer.length > 0) {
return;
}
const paste = (event.clipboardData || window.clipboardData).getData("text");
send_buffer += paste;
content.scrollTop = content.scrollHeight;
buffer += char;
}
const PALETTE = {
ari:
["#b7fd49", "#111111"],
green:
["#00ff00", "#111111"],
gold:
["#f9cb16", "#111111"],
bsod:
["#ffffff", "#0000ff"],
starlight:
["#d2b660", "#110717"],
catppuccin: {
frappe: {
green: ["#a6d189", "#232634"],
},
macchiato: {
green: ["#a6da95", "#24273a"],
},
mocha: {
rosewater: ["#f9e2af", "#1e1e2e"],
flamingo: ["#f2cdcd", "#1e1e2e"],
pink: ["#f5c2e7", "#1e1e2e"],
mauve: ["#cba6f7", "#1e1e2e"],
red: ["#f38ba8", "#1e1e2e"],
maroon: ["#eba0ac", "#1e1e2e"],
peach: ["#fab387", "#1e1e2e"],
yellow: ["#f9e2af", "#1e1e2e"],
green: ["#a6e3a1", "#1e1e2e"],
teal: ["#94e2d5", "#1e1e2e"],
sky: ["#89dceb", "#1e1e2e"],
sapphire: ["#74c7ec", "#1e1e2e"],
blue: ["#89b4fa", "#1e1e2e"],
lavendar: ["#b4befe", "#1e1e2e"],
},
},
community: {
jorun: /* @jorun@meta.jorun.dev */
["#0080ff", "#0d1020"],
meowca: /* @meowcatheorange@moth.zone */
["#ff4000", "#130805"],
halloween:
["#ff8000", "#1a120a"],
alcea: {
peach:
["#cf4a7299", "#fff"],
purple:
["#7f00ff", "#fff"],
},
},
};
function set_palette(palette) {
set_colours(palette[0], palette[1]);
}
function set_colours(foreground, background) {
localStorage.setItem("foreground", foreground);
localStorage.setItem("background", background);
document.documentElement.style.setProperty('--colour', foreground);
document.documentElement.style.setProperty('--bgcolour', background);
}
function clear_colours() {
localStorage.removeItem("foreground");
localStorage.removeItem("background");
document.documentElement.style.removeProperty('--colour');
document.documentElement.style.removeProperty('--bgcolour');
}
document.addEventListener("DOMContentLoaded", () => {
@ -84,4 +219,5 @@ document.addEventListener("DOMContentLoaded", () => {
});
document.addEventListener("keydown", handle_input);
document.addEventListener("paste", handle_paste);

View file

@ -1,19 +1,20 @@
:root {
--term-colour: #00ff00;
--colour: #a6e3a1;
--bgcolour: #1e1e2e;
}
body {
margin: 0;
padding: 0;
color: var(--term-colour);
background: #111;
color: var(--colour);
background-color: var(--bgcolour);
font-family: monospace;
font-size: 12px;
}
main {
margin: 1rem;
border: 1px solid var(--term-colour);
border: 1px solid var(--colour);
}
pre#content {
@ -31,7 +32,7 @@ div#carat {
width: .5em;
height: .9em;
display: inline-block;
background: var(--term-colour);
background: var(--colour);
transform: translateY(1px);
animation: linear .5s infinite forwards carat-blink;
}