Implemented hello message on join

refactored typedefs
This commit is contained in:
Zhongheng Liu 2024-01-02 19:10:32 +02:00
commit 4a7c3fbeda
No known key found for this signature in database
7 changed files with 44 additions and 31 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

View file

@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <!-- <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<meta <meta
@ -24,11 +24,14 @@
work correctly both with client-side routing and a non-root public URL. work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
<title>React App</title> <title>IRC application instance</title>
</head> </head>
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root"></div>
<div id="copyright">
<pre>Copyright 2024-2025 Zhongheng Liu @ Byron College</pre>
</div>
<!-- <!--
This HTML file is a template. This HTML file is a template.
If you open it directly in the browser, you will see an empty page. If you open it directly in the browser, you will see an empty page.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

View file

@ -6,16 +6,6 @@
"src": "favicon.ico", "src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16", "sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon" "type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
} }
], ],
"start_url": ".", "start_url": ".",

View file

@ -9,6 +9,11 @@ import { renderToStaticMarkup } from 'react-dom/server';
const domain = window.location.hostname const domain = window.location.hostname
const port = "8080" const port = "8080"
const connectionAddress = `ws://${domain}:${port}/ws` const connectionAddress = `ws://${domain}:${port}/ws`
const endpoints = {
destination: "/app/chat",
subscription: "/sub/chat",
history: "/api/v1/chat/history/"
}
const ChatWrapper = ( const ChatWrapper = (
{ {
user, user,
@ -22,14 +27,12 @@ const ChatWrapper = (
const stompClient = new Client({ const stompClient = new Client({
brokerURL: connectionAddress brokerURL: connectionAddress
}) })
const destination = "/app/chat"
const subscribe = "/sub/chat"
// TODO solve issue with non-static markup // TODO solve issue with non-static markup
stompClient.onConnect = (frame) => { stompClient.onConnect = (frame) => {
stompClient.subscribe(subscribe, (message) => { stompClient.subscribe(endpoints.subscription, (message) => {
console.log(`Collected new message: ${message.body}`); console.log(`Collected new message: ${message.body}`);
const {from, to, content} = JSON.parse(message.body) as MessageType const {fromUserId, toUserId, content, timeMillis} = JSON.parse(message.body) as MessageType
const messageElement = <Message sender={from} text={content} /> const messageElement = <Message sender={fromUserId} text={content} />
console.log(messageElement); console.log(messageElement);
// Temporary solution // Temporary solution
@ -38,6 +41,15 @@ const ChatWrapper = (
// Truly horrible and disgusting // Truly horrible and disgusting
container.innerHTML += renderToStaticMarkup(messageElement) container.innerHTML += renderToStaticMarkup(messageElement)
});
stompClient.publish({
body: JSON.stringify({
fromUserId: user,
toUserId: "everyone",
content: `${user} has joined the server!`,
timeMillis: Date.now()
}),
destination: endpoints.destination
}) })
} }
@ -52,24 +64,25 @@ const ChatWrapper = (
}; };
// Button press event handler. // Button press event handler.
const sendDataButtonHandler = (ev: React.MouseEvent) => { const sendData = () => {
console.log("WebSockets handler invoked.") console.log("WebSockets handler invoked.")
// There must be a react-native and non-document-getElementById way to do this // There must be a react-native and non-document-getElementById way to do this
// TODO Explore // TODO Explore
const entryElement: HTMLInputElement = document.getElementById("data-entry") as HTMLInputElement const entryElement: HTMLInputElement = document.getElementById("data-entry") as HTMLInputElement
const messageData = if (!entryElement.value) {alert("Message cannot be empty!"); return;}
const messageData: MessageType =
{ {
from: user, fromUserId: user,
to: "everyone", toUserId: "everyone",
content: entryElement.value content: entryElement.value,
timeMillis: Date.now()
} }
console.log(`STOMP connection status: ${stompClient.connected}`); console.log(`STOMP connection status: ${stompClient.connected}`);
stompClient.publish({ stompClient.publish({
body: JSON.stringify(messageData), body: JSON.stringify(messageData),
destination: destination destination: endpoints.destination
}) });
ev.preventDefault() entryElement.value = "";
} }
useEffect(() => { useEffect(() => {
// Stomp client is disconnected after each re-render // Stomp client is disconnected after each re-render
@ -78,12 +91,18 @@ const ChatWrapper = (
return () => { return () => {
stompClient.deactivate() stompClient.deactivate()
} }
}, []) }, [stompClient])
// https://www.w3schools.com/jsref/obj_keyboardevent.asp
document.addEventListener("keypress", (ev: KeyboardEvent) => {
if (ev.key == "Enter") {
sendData();
}
})
return ( return (
<div className="chat"> <div className="chat">
<div id="chat-inner"> <div id="chat-inner">
</div> </div>
<span><input id="data-entry"></input><button onClick={ev => sendDataButtonHandler(ev)}>Send</button></span> <span><input id="data-entry"></input><button onClick={() => sendData()}>Send</button></span>
</div> </div>
) )
} }

View file

@ -1,5 +1,6 @@
export type MessageType = { export type MessageType = {
from: string, fromUserId: string,
to: string, toUserId: string,
content: string content: string,
timeMillis: number
} }