Implemented hello message on join
refactored typedefs
This commit is contained in:
parent
91da28f1fb
commit
4a7c3fbeda
7 changed files with 44 additions and 31 deletions
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB |
|
@ -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 |
|
@ -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": ".",
|
||||||
|
|
|
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
export type MessageType = {
|
export type MessageType = {
|
||||||
from: string,
|
fromUserId: string,
|
||||||
to: string,
|
toUserId: string,
|
||||||
content: string
|
content: string,
|
||||||
|
timeMillis: number
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue