71 lines
1.6 KiB
TypeScript
71 lines
1.6 KiB
TypeScript
|
import { useContext, useState } from "react";
|
||
|
import useWebSocket from "react-use-websocket";
|
||
|
import { wsUrl } from "./constants";
|
||
|
import CBOR from "cbor";
|
||
|
import * as uuid from "uuid";
|
||
|
import { RoomContext } from "./lib/roomContext";
|
||
|
|
||
|
export default function Chat() {
|
||
|
const { roomId, clientId } = useContext(RoomContext);
|
||
|
const [chats, setChats] = useState([]);
|
||
|
const [message, setMessage] = useState("");
|
||
|
|
||
|
const {
|
||
|
sendMessage,
|
||
|
lastJsonMessage,
|
||
|
readyState: newReadyState,
|
||
|
} = useWebSocket(wsUrl, {
|
||
|
share: true,
|
||
|
onOpen: ({}) => {
|
||
|
console.log("Shiet, connected.");
|
||
|
},
|
||
|
onMessage: async (event) => {
|
||
|
const data = CBOR.decode(await event.data.arrayBuffer());
|
||
|
console.log("received", data);
|
||
|
|
||
|
if (data.type === "ChatMessage") {
|
||
|
setChats([...chats, data]);
|
||
|
}
|
||
|
},
|
||
|
});
|
||
|
|
||
|
function sendCborMessage(data) {
|
||
|
let cbor = CBOR.encode(data);
|
||
|
sendMessage(cbor);
|
||
|
}
|
||
|
|
||
|
function onSubmit(e) {
|
||
|
e.preventDefault();
|
||
|
sendCborMessage({
|
||
|
type: "ChatMessage",
|
||
|
timestamp: new Date().toISOString(),
|
||
|
message_id: uuid.v4(),
|
||
|
room_id: roomId,
|
||
|
author: clientId,
|
||
|
content: message,
|
||
|
});
|
||
|
setMessage("");
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<>
|
||
|
Messages:
|
||
|
<ul>
|
||
|
{chats.map((x) => (
|
||
|
<li key={x.message_id}>
|
||
|
[{x.timestamp}] {uuid.stringify(x.author)}: {x.content}
|
||
|
</li>
|
||
|
))}
|
||
|
</ul>
|
||
|
<form onSubmit={onSubmit}>
|
||
|
<input
|
||
|
type="text"
|
||
|
value={message}
|
||
|
onChange={(e) => setMessage(e.target.value)}
|
||
|
placeholder="Type a message..."
|
||
|
/>
|
||
|
</form>
|
||
|
</>
|
||
|
);
|
||
|
}
|