From add5c2f65467fd9c1a87b79837d249d00a223197 Mon Sep 17 00:00:00 2001 From: Dave Smith-Hayes Date: Mon, 28 Oct 2024 21:47:30 -0400 Subject: [PATCH] Add the CSS to amek this work, log better in the app --- chat-app/frontend/index.js | 13 ++++++- chat-app/src/index.ts | 12 +++--- chat-app/static/css/main.css | 51 ++++++++++++++----------- chat-app/static/index.html | 1 + chat-app/static/js/index.js | 73 ++++++++++++++++++++---------------- 5 files changed, 88 insertions(+), 62 deletions(-) diff --git a/chat-app/frontend/index.js b/chat-app/frontend/index.js index 8fa822f..9f7bb3c 100644 --- a/chat-app/frontend/index.js +++ b/chat-app/frontend/index.js @@ -50,18 +50,27 @@ function sendMessage(e) { const MessageInput = { view: function () { return m("div.chat-input", [ - m("form", { method: "post", onsubmit: sendMessage }, [ + m("form", { method: "post", onsubmit: this.handleSubmit }, [ m("input", { name: "chatter", placeholder: "Name" }), m("input", { name: "message", placeholder: "Message", id: "message", required: true }), m("input", { type: "submit", value: "Send" }) ]) ]); + }, + nameHidden: false, + handleSubmit: function (e) { + sendMessage(e); + if (!this.nameHidden) { + const chatterInput = document.querySelector('input[name="chatter"]') + chatterInput.setAttribute('style', 'display: none'); + this.nameHidden = true; + } } }; const Chat = { view: function(vnode) { - return m("div", [ + return m("div", { class: 'container' }, [ m(MessageBox), m(MessageInput) ]) diff --git a/chat-app/src/index.ts b/chat-app/src/index.ts index 451ee6c..6bf406e 100644 --- a/chat-app/src/index.ts +++ b/chat-app/src/index.ts @@ -14,16 +14,15 @@ const { upgradeWebSocket, websocket } = createBunWebSocket(); app.get("/chat-service", upgradeWebSocket((c) => { return { onOpen(event, ws) { - console.log(`Connection established from ${ws.raw.remoteAddress}`); + console.log(JSON.stringify({ message: `Connection established`, remoteHost: ws.raw.remoteAddress })); - chatRoom.addListener('message-added', async function (e) { + chatRoom.addListener('message-added', function (e) { const message = JSON.stringify({ message: e.message.message, chatter: e.message.chatter, timestamp: e.message.timestamp }); - console.log(message); ws.send(message); }); }, @@ -33,12 +32,13 @@ app.get("/chat-service", upgradeWebSocket((c) => { message.timestamp = Date.now() as string; chatRoom.addMessage(message); + console.log(JSON.stringify(message)); }, onClose() { - console.log("Connection closed."); + console.log(JSON.stringify({ message: `Connection closed.` })); }, onError(event, ws) { - console.error(event); + console.error(JSON.stringify({ event })); ws.close(); } } @@ -55,4 +55,4 @@ Bun.serve({ websocket }); -console.log(`Chat is running on ${process.env.APP_PORT}`); +console.log(JSON.stringify({ message: `Chat is running`, port: process.env.APP_PORT})); diff --git a/chat-app/static/css/main.css b/chat-app/static/css/main.css index 5f9067f..596c5de 100644 --- a/chat-app/static/css/main.css +++ b/chat-app/static/css/main.css @@ -9,12 +9,19 @@ div { box-sizing: border-box; } +.container { + display: flex; + flex-direction: column; + height: 100vh; +} + .messages { padding: 1em; display: flex; flex-direction: column-reverse; - height: auto; + flex-grow: 1; overflow: auto; + position: relative; } .messages .message { @@ -33,14 +40,12 @@ div { } .chat-input { - position: fixed; - bottom: 0; width: 100%; box-sizing: border-box; border-top: 1px solid #ccc; - height: auto; padding: 1em; background-color: #f4efe6; + align-self: flex-end; } .chat-input > form { display: flex; @@ -51,6 +56,8 @@ div { .chat-input > form > submit { padding: 1em 1.25em; margin-right: 1em; + box-sizing: border-box; + font-famil: monospace !important; } .chat-input > form > submit { background-color: #020a03; @@ -58,7 +65,6 @@ div { border-radius: 5px; color: #fffbf6; font-weight: bold; - font-family: monospace !important; padding: 0.75em 1em; margin-right: 0; } @@ -67,47 +73,48 @@ div { border: 1px solid #020a03; border-radius: 5px; color: #0c0b09; - font-family: monospace; } .chat-input > form > input[name="message"] { width: 75%; border: 1px solid #020a03; border-radius: 5px; color: #0c0b09; - font-family: monospace; } @media only screen and (max-width: 600px) { .chat-input { - padding: 2.5em; + padding: 1em; } .chat-input > form { display: flex; + flex-wrap: wrap; width: 100%; box-sizing: border-box; - flex-direction: column; + } + + .chat-input > form > input, + .chat-input > form > submit { + box-sizing: border-box; + margin: 0.25em; + font-size: 1em; + padding: 0.75em 1em; + border-radius: 0.25em; + width: 100%; } .chat-input > form > input[name="chatter"] { width: 100%; - font-size: 3.5em; - margin-bottom: 0.5em; - box-sizing: border-box; + order: 1; } .chat-input > form > input[name="message"] { - width: 100%; - font-size: 3.5em; - margin-bottom: 0.5em; - box-sizing: border-box; + width: 60%; + order: 2; } - - .chat-input > form > input, .chat-input > form > submit { - padding: 0.75em 1em; - border-radius: 0.25em; - width: 100%; - font-size: 3.5em; + .chat-input > form > input[type=submit] { + width: 34%; + order: 3; } } diff --git a/chat-app/static/index.html b/chat-app/static/index.html index 8e52699..9352792 100644 --- a/chat-app/static/index.html +++ b/chat-app/static/index.html @@ -2,6 +2,7 @@ A Dumb Chat Application + diff --git a/chat-app/static/js/index.js b/chat-app/static/js/index.js index ec01f37..0b46776 100644 --- a/chat-app/static/js/index.js +++ b/chat-app/static/js/index.js @@ -79,11 +79,6 @@ var require_hasOwn = __commonJS((exports, module) => { // node_modules/mithril/render/hyperscript.js var require_hyperscript = __commonJS((exports, module) => { - var Vnode = require_vnode(); - var hyperscriptVnode = require_hyperscriptVnode(); - var hasOwn = require_hasOwn(); - var selectorParser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g; - var selectorCache = {}; function isEmpty(object) { for (var key in object) if (hasOwn.call(object, key)) @@ -152,6 +147,11 @@ var require_hyperscript = __commonJS((exports, module) => { vnode.tag = selector; return vnode; } + var Vnode = require_vnode(); + var hyperscriptVnode = require_hyperscriptVnode(); + var hasOwn = require_hasOwn(); + var selectorParser = /(?:(^|#|\.)([^#\.\[\]]+))|(\[(.+?)(?:\s*=\s*("|'|)((?:\\["'\]]|.)*?)\5)?\])/g; + var selectorCache = {}; module.exports = hyperscript; }); @@ -187,7 +187,6 @@ var require_hyperscript2 = __commonJS((exports, module) => { // node_modules/mithril/render/domFor.js var require_domFor = __commonJS((exports, module) => { - var delayedRemoval = new WeakMap; function* domFor({ dom, domSize }, { generation } = {}) { if (dom != null) do { @@ -199,6 +198,7 @@ var require_domFor = __commonJS((exports, module) => { dom = nextSibling; } while (domSize); } + var delayedRemoval = new WeakMap; module.exports = { delayedRemoval, domFor @@ -1480,6 +1480,13 @@ var require_censor = __commonJS((exports, module) => { // node_modules/mithril/api/router.js var require_router = __commonJS((exports, module) => { + function decodeURIComponentSave(component) { + try { + return decodeURIComponent(component); + } catch (e) { + return component; + } + } var Vnode = require_vnode(); var m = require_hyperscript(); var buildPathname = require_build2(); @@ -1488,13 +1495,6 @@ var require_router = __commonJS((exports, module) => { var assign = require_assign(); var censor = require_censor(); var sentinel = {}; - function decodeURIComponentSave(component) { - try { - return decodeURIComponent(component); - } catch (e) { - return component; - } - } module.exports = function($window, mountRedraw) { var callAsync = $window == null ? null : typeof $window.setImmediate === "function" ? $window.setImmediate : $window.setTimeout; var p = Promise.resolve(); @@ -1721,34 +1721,18 @@ var import_mithril = __toESM(require_mithril(), 1); // frontend/websocket.js function createWebSocket() { - let appUrl = "chat.freedoom.party"; + let appUrl = "localhost:3000"; appUrl = `//${appUrl}/chat-service`; return new WebSocket(appUrl); } // frontend/index.js -var messages = []; -var socket = createWebSocket(); -socket.onmessage = function(event) { - if (event.type === "message") { - const message = JSON.parse(event.data); - messages.push(message); - import_mithril.default.redraw(); - } -}; function newMessageText(name, message) { return [ import_mithril.default("span.chatter", name + ": "), import_mithril.default("span.chatter-message", message) ]; } -var MessageBox = { - view: function() { - return import_mithril.default(".messages", { id: "message-box" }, messages.reverse().map(function(message) { - return import_mithril.default(".message", newMessageText(message.chatter, message.message)); - }), import_mithril.default("#anchor")); - } -}; function clearMessageInputBox() { const messageBox = document.getElementById("message"); messageBox.value = ""; @@ -1763,20 +1747,45 @@ function sendMessage(e) { socket.send(JSON.stringify(message)); clearMessageInputBox(); } +var messages = []; +var socket = createWebSocket(); +socket.onmessage = function(event) { + if (event.type === "message") { + const message = JSON.parse(event.data); + messages.push(message); + import_mithril.default.redraw(); + } +}; +var MessageBox = { + view: function() { + return import_mithril.default(".messages", { id: "message-box" }, messages.reverse().map(function(message) { + return import_mithril.default(".message", newMessageText(message.chatter, message.message)); + }), import_mithril.default("#anchor")); + } +}; var MessageInput = { view: function() { return import_mithril.default("div.chat-input", [ - import_mithril.default("form", { method: "post", onsubmit: sendMessage }, [ + import_mithril.default("form", { method: "post", onsubmit: this.handleSubmit }, [ import_mithril.default("input", { name: "chatter", placeholder: "Name" }), import_mithril.default("input", { name: "message", placeholder: "Message", id: "message", required: true }), import_mithril.default("input", { type: "submit", value: "Send" }) ]) ]); + }, + nameHidden: false, + handleSubmit: function(e) { + sendMessage(e); + if (!this.nameHidden) { + const chatterInput = document.querySelector('input[name="chatter"]'); + chatterInput.setAttribute("style", "display: none"); + this.nameHidden = true; + } } }; var Chat = { view: function(vnode) { - return import_mithril.default("div", [ + return import_mithril.default("div", { class: "container" }, [ import_mithril.default(MessageBox), import_mithril.default(MessageInput) ]);