diff --git a/README.md b/README.md new file mode 100644 index 0000000..37b12d9 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# OpenTerminal +An online terminal and communal text buffer + +![openterminal thumbnail image](public/img/thumbnail.png) + +## how it works + +a simple static web server pushes out the html, css and javascript needed to make this function well and look pretty on client devices. from there, clients connect back to the server's websocket, which they then exchange keystroke information with, back and forth, all passing through the server's own saved buffer. (if you refresh the page, everything's still there!) + +### wouldn't this be really easy to grief? + +yes! + +jokes aside- while i do absolutely see how an open, self-moderated text buffer is hilariously easy to grief, i could also imagine users taking the concept and pushing it quite a bit further than what i'm doing here. who knows? maybe a anti-spam bot could come in, read through the buffer for any *nefarious* material, and backpedal through the buffer just enough to remove it, before replacing the otherwise above-board text from memory. + +...or maybe it'll just become a garbage-posting haven. regardless, it's a fun little idea, so i made it anyway. + +## roadmap + +- rewrite backend in go/rust (me no like javascript raaaahhh) +- colour palette switcher in the UI (rather than in console) +- multiple "channels" (at least if one gets flooded, there's somewhere else you can go) + +### "maybe" roadmap + +- master server (anyone can host a channel and post to the MS) + diff --git a/public/img/thumbnail.png b/public/img/thumbnail.png new file mode 100644 index 0000000..f161c7e Binary files /dev/null and b/public/img/thumbnail.png differ diff --git a/public/index.html b/public/index.html index 3731f6e..fe21d2a 100644 --- a/public/index.html +++ b/public/index.html @@ -2,6 +2,20 @@ OpenTerminal + + + + + + + + + + + + + + @@ -12,7 +26,14 @@

+			
 		
+
diff --git a/public/scripts/main.js b/public/scripts/main.js index 37dcf8d..dcaa4cb 100644 --- a/public/scripts/main.js +++ b/public/scripts/main.js @@ -1,6 +1,7 @@ var buffer = ""; var send_buffer = ""; var content; +var mobile_input; var client; var pre_buffer_chars = 0; var term_interval = 10; @@ -10,7 +11,7 @@ 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. +home to an online terminal and communal text buffer. i hope you enjoy your stay here! to help you feel a little more comfortable, i've prepared some commands for you: @@ -31,6 +32,11 @@ to help you feel a little more comfortable, i've prepared some commands for you: } content = document.getElementById("content"); + mobile_input = document.getElementById("mobile-input"); + + content.addEventListener("click", () => { + mobile_input.focus(); + }); buffer += "Connecting to the server..."; @@ -52,6 +58,8 @@ function loop() { send_buffer = send_buffer.substring(1); } + mobile_input.value = content.innerText; + setTimeout(loop, term_interval); } @@ -72,7 +80,7 @@ function connect() { }); client.addEventListener('close', () => { - insert_text("\n\n[CONNECTION LOST]"); + insert_text("\n\n[CONNECTION LOST, PLEASE REFRESH]"); }); } @@ -83,8 +91,10 @@ function insert_text(text) { 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 if (text == "\b") { + if (content.innerText.length > pre_buffer_chars) { + content.innerText = content.innerText.slice(0, content.innerText.length - 1); + } } else { content.innerText += text; } diff --git a/public/styles/main.css b/public/styles/main.css index 795052a..8db73df 100644 --- a/public/styles/main.css +++ b/public/styles/main.css @@ -13,12 +13,12 @@ body { } main { - margin: 1rem; + margin: 1rem 1rem 0 1rem; border: 1px solid var(--colour); } pre#content { - height: calc(100vh - 66px); + height: calc(100vh - 5rem); margin: 0; padding: 1rem; overflow-x: hidden; @@ -46,6 +46,37 @@ div#carat { } } +footer { + height: 18px; + padding: .5em 2em; + display: flex; + gap: 1em; + align-items: center; +} + +footer ul { + width: 100%; + margin: 0; + padding: 0; + display: flex; + justify-content: space-between; +} + +footer li { + list-style: none; + opacity: .5; +} + +footer li:hover { + text-shadow: 0 0 1em, 0 0 3em; + opacity: 1; +} + +footer a { + color: var(--colour); + text-decoration: none; +} + div#overlay { position: fixed; top: 0; @@ -69,3 +100,15 @@ div#overlay { opacity: .6; } } + +#mobile-input { + position: absolute; + top: 1.2em; + left: 1.2em; + width: calc(100vw - 3em); + height: calc(100vh - 3.9em); + opacity: 0; + user-select: none; + pointer-events: none; +} + diff --git a/res/thumbnail.afphoto b/res/thumbnail.afphoto new file mode 100644 index 0000000..85a9560 Binary files /dev/null and b/res/thumbnail.afphoto differ diff --git a/server/main.js b/server/main.js index d7e1b26..2fd58c7 100644 --- a/server/main.js +++ b/server/main.js @@ -29,13 +29,15 @@ const motds = [ "how's the weather?", "with each web request, my server room grows hotter.", "mobile support coming later probably!", + "there is science to do...", + "now fully open-source!", + "somehow not the worst communication app!", ]; const STATIC_PATH = path.join(process.cwd(), "public"); const banner = -`OpenTerminal v0.1.0 -made with <3 by ari melody +`Welcome to OpenTerminal! `; @@ -43,7 +45,8 @@ const PORT = process.env.PORT || 8080; let sockets = []; let buffer = ""; -let MAX_BUFFER_SIZE = 10240; +const MAX_BUFFER_SIZE = 10240; +const MAX_MESSAGE_LENGTH = 64; async function get_file(url) { const paths = [STATIC_PATH, url]; @@ -73,22 +76,25 @@ const server = https.createServer(config, async (req, res) => { const wss = new Websocket.Server({ server }); wss.on('connection', socket => { - socket.send(banner + motds[Math.floor(Math.random() * motds.length)] + "\n\n"); + socket.send(`${banner}/* ${motds[Math.floor(Math.random() * motds.length)]} */\n\n`); socket.send(buffer); sockets.push(socket); - console.log(`new connection.\n\tcurrent connections: ${sockets.length}`); + // console.log(`new connection.\n\tcurrent connections: ${sockets.length}`); socket.on('message', handle_message); socket.on('close', () => { sockets = sockets.filter(s => s !== socket); - console.log(`connection closed.\n\tcurrent connections: ${sockets.length}`); + // console.log(`connection closed.\n\tcurrent connections: ${sockets.length}`); }); }); function handle_message(msg) { + if (msg.length > MAX_MESSAGE_LENGTH) { + return; + } if (msg == '\b') { buffer = buffer.slice(0, buffer.length - 1); send_text('\b'); @@ -101,9 +107,6 @@ function handle_message(msg) { send_text('\n'); return; } - if (msg.length > 1) { - return; - } buffer += msg.toString(); send_text(msg.toString());