From 6fc628aee3bf74351244df69594bab2ec66aa9d8 Mon Sep 17 00:00:00 2001 From: Zhongheng Liu Date: Thu, 21 Dec 2023 19:07:06 +0200 Subject: [PATCH] Temporary solution: renderToStaticMarkup --- .vscode/launch.json | 20 +++++++++++ src/App.tsx | 11 +++--- src/Chat/Chat.tsx | 80 +++++++++++++++++--------------------------- src/Chat/Message.tsx | 2 +- src/Chat/Socket.tsx | 61 +++++++++++++++++++++++++++++++++ src/index.tsx | 2 -- 6 files changed, 118 insertions(+), 58 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 src/Chat/Socket.tsx diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..0853fbc --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Launch Program", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/src/Chat/Chat.tsx", + "outFiles": [ + "${workspaceFolder}/**/*.js" + ] + } + ] +} \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 84234b7..56cd405 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,16 +1,17 @@ -import React from "react"; +import React, { useState } from "react"; import ChatWrapper from "./Chat/Chat"; const App = (): React.ReactElement => { - var username: string | null = prompt("Username: ") + const [username, setUsername] = useState() if (!username) { - alert("Invalid username!") - var username: string | null = prompt("Username: ") + const newName = prompt("Username:") as string + setUsername(newName) } return (

Local Area Network Chat Application

This web application was built for the purposes of an EPQ project.
- + + { }
) } diff --git a/src/Chat/Chat.tsx b/src/Chat/Chat.tsx index 817ada2..080ea71 100644 --- a/src/Chat/Chat.tsx +++ b/src/Chat/Chat.tsx @@ -1,9 +1,11 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { Message } from "./Message"; import { Client, Stomp } from "@stomp/stompjs"; import { MessageType } from "./types"; -import useWebSocket from "react-use-websocket"; - +import { renderToStaticMarkup } from 'react-dom/server'; +const domain = "localhost" +const port = "8080" +const connectionAddress = `ws://${domain}:${port}/ws` const ChatWrapper = ( { user, @@ -14,24 +16,23 @@ const ChatWrapper = ( brokerURL: string, } ): React.ReactElement => { - const domain = "localhost" - const port = "8080" - const connectionAddress = `ws://${domain}:${port}/ws` const stompClient = new Client({ brokerURL: connectionAddress }) - const [destination, setDestination] = useState("/app/chat") - const [connected, setConnected] = useState(false) - const [subscribe, setSubscribe] = useState("/sub/chat") - const [username, setUsername] = useState(user) - const [children, setChildren] = useState() + const destination = "/app/chat" + const subscribe = "/sub/chat" + // const [children, setChildren] = useState([]) stompClient.onConnect = (frame) => { - setConnected(true); stompClient.subscribe(subscribe, (message) => { console.log(`Collected new message: ${message.body}`); const {from, to, content} = JSON.parse(message.body) as MessageType const messageElement = - setChildren(messageElement) + // setChildren((prev) => [...prev, messageElement]) + console.log(messageElement); + + // Temporary solution + const container = document.getElementById("chat-inner") as HTMLDivElement + container.innerHTML += renderToStaticMarkup(messageElement) }) } stompClient.onWebSocketError = (error) => { @@ -42,58 +43,37 @@ const ChatWrapper = ( console.error('Broker reported error: ' + frame.headers['message']); console.error('Additional details: ' + frame.body); }; + const sendDataButtonHandler = (ev: React.MouseEvent) => { console.log("WebSockets handler invoked.") - ev.preventDefault() + const entryElement: HTMLInputElement = document.getElementById("data-entry") as HTMLInputElement const messageData = { - from: username, + from: user, to: "everyone", content: entryElement.value } console.log(`STOMP connection status: ${stompClient.connected}`); - if (stompClient.connected) { - stompClient.publish({ - body: JSON.stringify(messageData), - destination: destination - }) - } else {alert("STOMP not activated!")} + stompClient.publish({ + body: JSON.stringify(messageData), + destination: destination + }) + ev.preventDefault() } - const connect = () => { + useEffect(() => { stompClient.activate() - } - const disconnect = () => { - stompClient.deactivate() - } - // connection.addEventListener("open", (ev: Event) => { - // ev.preventDefault() - // connection.send("Hello world!") - // }) - // connection.addEventListener("message", (ev: MessageEvent) => { - // ev.preventDefault() - // const wrappers = document.getElementsByClassName(msgWrapperClassName) - - // // Matches data from JSON data input against ChatMessage datatype for processing - // const data = JSON.parse(ev.data) as ChatMessage - // for (let index = 0; index < wrappers.length; index++) { - // const element: Element | null = wrappers.item(index); - // if (!element) { - // console.error("msgWrapper class cannot be found! Message not delivered.") - // return - // } - // messageElementsArray.push() - // // TODO Create new message - // // DDL 20 DEC - // } - // }) + return () => { + stompClient.deactivate() + } + }, []) return (
- - + {/* + */}
- {children} + {/* {children} */}
diff --git a/src/Chat/Message.tsx b/src/Chat/Message.tsx index 9299ff8..ec89348 100644 --- a/src/Chat/Message.tsx +++ b/src/Chat/Message.tsx @@ -9,5 +9,5 @@ export const Message = ( } ): React.ReactElement<{ sender: string; text: string; }> => { - return (

Message from {sender} @ {}: {text}

); + return (

Message from {sender}: {text}

); }; diff --git a/src/Chat/Socket.tsx b/src/Chat/Socket.tsx new file mode 100644 index 0000000..cbb4e10 --- /dev/null +++ b/src/Chat/Socket.tsx @@ -0,0 +1,61 @@ +import { Client } from "@stomp/stompjs" +import { useState } from "react" +import { Message } from "./Message" +import { MessageType } from "./types" + +const Socket = ( + { + address, + user, + messageCallback, + }: + { + address: string, + user: string, + messageCallback: (element: JSX.Element) => {}, + } +) => { + const stompClient = new Client({ + brokerURL: address + }) + const destination = "/app/chat" + const subscribe = "/sub/chat" + stompClient.onConnect = (frame) => { + stompClient.subscribe(subscribe, (message) => { + console.log(`Collected new message: ${message.body}`); + const {from, to, content} = JSON.parse(message.body) as MessageType + const messageElement = + // return message to parent + messageCallback(messageElement) + }) + } + stompClient.onWebSocketError = (error) => { + console.error('Error with websocket', error); + }; + + stompClient.onStompError = (frame) => { + console.error('Broker reported error: ' + frame.headers['message']); + console.error('Additional details: ' + frame.body); + }; + + const send = () => { + console.log("WebSockets handler invoked.") + + const entryElement: HTMLInputElement = document.getElementById("data-entry") as HTMLInputElement + const messageData = + { + from: user, + to: "everyone", + content: entryElement.value + } + console.log(`STOMP connection status: ${stompClient.connected}`); + + stompClient.publish({ + body: JSON.stringify(messageData), + destination: destination + }) + } + stompClient.activate() + return (<>) +} +export default Socket; \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index 23b3422..1dafd93 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -7,7 +7,5 @@ const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement ); root.render( - - ); \ No newline at end of file