From 42ba0e3275cbc0d519292fb3ca9b7a27c4e27cad Mon Sep 17 00:00:00 2001 From: ari melody Date: Sun, 1 Oct 2023 17:17:05 +0100 Subject: [PATCH] lcd theme, auto scrolling fix, external server support --- public/scripts/main.js | 121 ++++++++++++++++++++++++----------------- server/main.js | 11 +++- 2 files changed, 82 insertions(+), 50 deletions(-) diff --git a/public/scripts/main.js b/public/scripts/main.js index 092f47d..ed8c3f6 100644 --- a/public/scripts/main.js +++ b/public/scripts/main.js @@ -8,6 +8,7 @@ var client; var my_colour = false; var pre_buffer_chars = 0; +var server_url = ""; const DATA_TYPES = { text: 0, @@ -31,10 +32,12 @@ to help you feel a little more comfortable, i've prepared some commands for you: changes the foreground and background colours of your terminal! \`foreground\` and \`background\` must be hex colour codes, such as \`#ff00ff\`. -- set_palette(palette) +- set_palette(palette_name) 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!`); + try it out! enter \`PALETTE\` into your console and browse the list of themes we have!`); + + server_url = new URL(window.location).searchParams.get("server") || window.location.host; const foreground = localStorage.getItem("foreground"); const background = localStorage.getItem("background"); @@ -42,6 +45,10 @@ to help you feel a little more comfortable, i've prepared some commands for you: set_colours(foreground, background); } + if (localStorage.getItem("lcd")) { + document.body.classList.add("lcd"); + } + content = document.getElementById("content"); mobile_input = document.getElementById("mobile-input"); @@ -71,7 +78,7 @@ function loop() { } function connect() { - client = new WebSocket("wss://" + window.location.host); + client = new WebSocket("wss://" + server_url); client.addEventListener('open', () => { add_system_message(`\nConnection successful.\n\n`); @@ -98,7 +105,7 @@ function add_system_message(text) { function handle_message(data) { if (!data.type && data.type != 0) return; - const is_at_bottom = content.scrollTop == content.scrollTopMax; + const is_at_bottom = content.scrollHeight - content.offsetHeight - content.scrollTop < 10; switch (data.type) { case DATA_TYPES.colour: @@ -143,7 +150,7 @@ function handle_message(data) { new_caret(); - if (is_at_bottom) content.scrollTop = content.scrollTopMax; + if (is_at_bottom) content.scrollTop = content.scrollHeight - content.offsetHeight; } function new_caret() { @@ -231,7 +238,7 @@ function handle_input(event) { text: event.key, }); - content.scrollTop = content.scrollTopMax; + content.scrollTop = content.scrollHeight - content.offsetHeight; } function handle_paste(event) { @@ -246,62 +253,65 @@ function handle_paste(event) { type: DATA_TYPES.text, text: paste, }); - content.scrollTop = content.scrollTopMax; + content.scrollTop = content.scrollHeight - content.offsetHeight - 28; } const PALETTE = { - ari: - ["#b7fd49", "#111111"], - green: - ["#00ff00", "#111111"], - gold: - ["#f9cb16", "#111111"], - bsod: - ["#ffffff", "#0000ff"], - starlight: - ["#d2b660", "#110717"], + ari: ["#b7fd49", "#111111"], + mono: ["#ffffff", "#111111"], + green: ["#00ff00", "#111111"], + gold: ["#f9cb16", "#111111"], + bsod: ["#ffffff", "#0000ff"], + starlight: ["#d2b660", "#110717"], + aperture: ["#ffce14", "#1d0b00"], + halloween: ["#ff8000", "#1a120a"], 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"], - }, + 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"], + /* @jorun@meta.jorun.dev */ + jorun: ["#0080ff", "#0d1020"], + /* @meowcatheorange@moth.zone */ + meowca: ["#ff4000", "#130805"], + /* @alcea@pb.todon.de */ alcea: { - peach: - ["#cf4a7299", "#fff"], - purple: - ["#7f00ff", "#fff"], + peach: ["#cf4a7299", "#ffffff"], + purple: ["#7f00ff", "#ffffff"], }, }, }; function set_palette(palette) { + if (typeof(palette) === "object" && palette.isArray()) { + set_colours(palette[0], palette[1]); + console.log(`Palette changed to [${palette}]`); + return true; + } + const palette_route = palette.split("."); + var palette = PALETTE; + for (var i = 0; i < palette_route.length; i++) { + var palette = palette[palette_route[i]]; + if (!palette) { + console.error(`Palette [${palette_route.join(".")}] does not exist. Enter \`PALETTE\` for a list of palettes.`); + return false; + } + } set_colours(palette[0], palette[1]); + console.log(`Palette changed to [${palette}].`); + return true; } function set_colours(foreground, background) { @@ -318,6 +328,19 @@ function clear_colours() { document.documentElement.style.removeProperty('--bgcolour'); } +/** + * toggles LCD theme + */ +function toggle_lcd() { + if (document.body.classList.contains("lcd") || localStorage.getItem("lcd")) { + document.body.classList.remove("lcd"); + localStorage.removeItem("lcd"); + } else { + document.body.classList.add("lcd"); + localStorage.setItem("lcd", true); + } +} + document.addEventListener("DOMContentLoaded", () => { start(); }); diff --git a/server/main.js b/server/main.js index f143615..5b49896 100644 --- a/server/main.js +++ b/server/main.js @@ -41,6 +41,7 @@ const MOTDS = [ "there is science to do...", "now fully open-source!", "somehow not the worst communication app!", + "\"oh this is like nano but multiplayer\"", ]; const STATIC_PATH = path.join(process.cwd(), "public"); @@ -57,10 +58,18 @@ let buffer = ""; const MAX_BUFFER_SIZE = 10240; const MAX_MESSAGE_LENGTH = 1024; +/** + * simple file fetching for the HTTPS server + */ async function get_file(url) { + // ignore query params...not very helpful when getting files! + url = url.split("?")[0]; + const paths = [STATIC_PATH, url]; if (url.endsWith("/")) paths.push("index.html"); const file_path = path.join(...paths); + + // check for path traversal. path traversal is...bad. const path_traversal = !file_path.startsWith(STATIC_PATH); const exists = await fs.promises.access(file_path).then(...[() => true, () => false]); if (path_traversal || !exists) return false; @@ -98,7 +107,7 @@ wss.on('connection', socket => { colour: false, sticky: true, })); - if (buffer) { + if (buffer.length > 0) { socket.send(JSON.stringify({ type: DATA_TYPES.buffer, data: buffer,