Hey the chat works now a bit.

This commit is contained in:
Dave Smith-Hayes 2024-10-08 08:42:15 -04:00
parent 03c51e7dbe
commit 9e1ecbbe1f
11 changed files with 1860 additions and 115 deletions

View File

@ -1,14 +0,0 @@
import m from "mithril";
import { MessageBox } from "./MessageBox";
import { LoginForm } from "./Login";
export function createChatApp({ ws, session }) {
return {
view: function () {
return m("div", { class: "container" }, [
m("h1", "A Stupid Chat Application"),
m(LoginForm)
]);
}
};
}

View File

@ -1,37 +0,0 @@
import m from "mithril";
import Cookies from "js-cookie";
export function LoginForm() {
let loggedIn = false;
async function login(e) {
e.preventDefault();
const formData = new FormData(e.target);
const res = await m.request({
method: "POST",
url: "/login",
body: formData
});
if (res.success) {
Cookies.set('logged-in', true);
} else {
Cookies.remove('logged-in');
}
}
return {
oninit: function() {
loggedIn = !!Cookies.get('logged-in');
},
view: function() {
return m("form", { action: "/login", method: "post", onsubmit: login }, [
m("label", { for: "username" }, "Username"),
m("input", { type: "text", name: "username" }),
m("input", { type: "submit", value: "Login" })
]);
}
}
}

View File

@ -1,7 +0,0 @@
import m from "mithril";
export const MessageBox = {
view: function () {
return m("div", { id: "message-box" }, "Do Something");
}
}

View File

@ -1,10 +1,62 @@
import m from "mithril";
import { createChatApp } from "./components/ChatApp";
import { createWebSocket } from "./websocket";
import { Sessions } from "./session";
// open the WS to the server
const ws = createWebSocket();
const session = new Sessions();
const ChatApp = createChatApp({ ws, session });
m.mount(document.getElementById("app"), ChatApp);
// on new message event, call m.redraw();
const messages = [];
const socket = createWebSocket();
socket.onmessage = function (event) {
if (event.type === "message") {
const message = JSON.parse(event.data);
messages.push(message);
m.redraw();
}
}
function newMessageText(name, message) {
return `${name}: ${message}`;
}
const MessageBox = {
view: function () {
return m(".messages", messages.map(function(message) {
return m(".message", newMessageText(message.chatter, message.message));
}));
}
};
function sendMessage(e) {
e.preventDefault();
const form = new FormData(e.target);
const message = {};
for (const [key, value] of form.entries()) {
message[key] = value;
}
socket.send(JSON.stringify(message));
}
const MessageInput = {
view: function () {
return m("div", [
m("form", { method: "post", onsubmit: sendMessage }, [
m("input", { name: "chatter", placeholder: "Name" }),
m("input", { name: "message", placeholder: "Message" }),
m("input", { type: "submit", value: "Send" })
])
]);
}
};
const Chat = {
view: function(vnode) {
return m("div", [
m(MessageBox),
m(MessageInput)
])
}
};
m.mount(document.getElementById("app"), Chat);

View File

@ -0,0 +1,14 @@
import m from 'mithril';
// login to the server
function login(e) {
}
export const Login = {
return m("form", { action: "/login", method: "post", onsubmit: login }, [
m("label", { for: "username" }, "Username"),
m("input", { type: "text", name: "username" }),
m("input", { type: "submit", value: "Login" })
]);
};

View File

@ -1,31 +0,0 @@
export class Sessions extends EventManager {
constructor() {
this.users = [];
}
userExists(user) {
return !!this.findUser(user);
}
findUser(user) {
return this.users.find(u => u.username === user.username);
}
addUser(user) {
if (!this.userExists(user)) {
this.users.push(user);
this.emit('user-logged-in', user);
}
}
clearUser(user) {
if (this.userExists(user)) {
const index = this.users.indexOf(user);
if (index > -1) {
this.users.splice(index - 1, 1);
this.emit('user-removed', user);
}
}
}
}

View File

@ -0,0 +1,2 @@
const state = {};

View File

@ -2,7 +2,7 @@
"name": "chat-app",
"scripts": {
"dev": "bun run --hot src/index.ts",
"build": "rm -r static/js && bun build.ts"
"build": "rm -r static/js; bun build.ts"
},
"dependencies": {
"@types/mithril": "^2.2.7",

View File

@ -8,8 +8,8 @@ export const chatters = new Array<Chatter>();
export type Message = {
message: string,
timestamp: Date
chatter: Chatter
timestamp: Date,
chatter: string,
};
export function createMessageString(message: Message): string {
@ -21,7 +21,7 @@ export class ChatRoom extends EventEmitter {
public constructor() {
super();
this.message = new Array<Message>();
this.messages = new Array<Message>();
}
public getMessages(): Message[] {

View File

@ -4,12 +4,10 @@ import type { ServerWebSocket } from "hono";
import {
chatRoom,
createMessageString,
type Chatter,
type Message
} from "./chat-room.ts";
const app = new Hono();
const users: string[] = [];
// Set up the chat socket
const { upgradeWebSocket, websocket } = createBunWebSocket<ServerWebSocket>();
@ -19,22 +17,15 @@ app.get("/chat-service", upgradeWebSocket((c) => {
chatRoom.addListener('message-added', function (e) {
ws.send(JSON.stringify({
message: e.message.message,
chatter: e.message.chatter
chatter: e.message.chatter,
timestamp: e.message.timestamp
}));
});
},
onMessage(event, ws) {
const data = JSON.parse(event.data);
if (!chatters.find(c => c.name == data.chatter.name)) {
chatters.push(data.chatter);
}
const message: Message = {
chatter: data.chatter,
message: data.message,
timestamp: Date.now() as string
};
const { data } = event;
const message = JSON.parse(data);
message.timestamp = Date.now() as string;
chatRoom.addMessage(message);
},
@ -42,7 +33,7 @@ app.get("/chat-service", upgradeWebSocket((c) => {
console.log("Connection closed.");
},
onError(event) {
console.log(event);
console.error(event);
}
}
}));

1775
chat-app/static/js/index.js Normal file

File diff suppressed because it is too large Load Diff