diff --git a/package-lock.json b/package-lock.json index 119f37d..69ed81c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "react-router-dom": "^6.11.2", "react-scripts": "5.0.1", "socket.io-client": "^4.7.2", + "unique-names-generator": "^4.7.1", "url": "^0.11.1", "web-vitals": "^2.1.4" }, @@ -17035,6 +17036,14 @@ "node": ">=4" } }, + "node_modules/unique-names-generator": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/unique-names-generator/-/unique-names-generator-4.7.1.tgz", + "integrity": "sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow==", + "engines": { + "node": ">=8" + } + }, "node_modules/unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", diff --git a/package.json b/package.json index a055cf6..35cff0a 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "react-router-dom": "^6.11.2", "react-scripts": "5.0.1", "socket.io-client": "^4.7.2", + "unique-names-generator": "^4.7.1", "url": "^0.11.1", "web-vitals": "^2.1.4" }, diff --git a/src/components/chat.jsx b/src/components/chat.jsx index 158960d..b19a860 100644 --- a/src/components/chat.jsx +++ b/src/components/chat.jsx @@ -1,30 +1,54 @@ import React, { useContext, useState } from "react"; -import { Button, Input } from "@douyinfe/semi-ui"; +import { Button, Input, Tag, Avatar } from "@douyinfe/semi-ui"; import { IconSend } from "@douyinfe/semi-icons"; import { socket } from "../data/socket"; import { MessageContext } from "../pages/editor"; export default function Chat() { const [message, setMessage] = useState(""); - const { messages, setMessages } = useContext(MessageContext); + const { messages } = useContext(MessageContext); return (
-
- {messages.map((m, i) => ( -
{m}
- ))} +
+ {messages.map((m, i) => + m.type === "note" ? ( +
+ + {m.message} + +
+ ) : messages[i + 1].id !== m.id ? ( +
+ + {m.name.split(" ").map((c) => c[0])} + +
+
{m.name}
+
{m.message}
+
+
+ ) : ( +
+ {m.message} +
+ ) + )}
{ e.preventDefault(); - if (message !== "") { - setMessages((prev) => [...prev, message]); + if (message.trim() !== "") { socket.emit("send-message", message); } setMessage(""); }} - className="flex" + className="flex mt-2" > setMessage(v)} diff --git a/src/data/data.js b/src/data/data.js index 2b88c14..6a202f1 100644 --- a/src/data/data.js +++ b/src/data/data.js @@ -40,6 +40,26 @@ const tableThemes = [ const noteThemes = ["#ffdfd9", "#fcf7ac", "#cffcb1", "#c7d2ff", "#e7c7ff"]; +const avatarThemes = [ + "amber", + "blue", + "cyan", + "green", + "grey", + "indigo", + "light-blue", + "light-green", + "lime", + "orange", + "pink", + "rain", + "red", + "teal", + "violet", + "yellow", + "white", +]; + const defaultTableTheme = "#175e7a"; const defaultNoteTheme = "#fcf7ac"; const bgBlue = "#124559"; @@ -88,6 +108,7 @@ export { noteThemes, defaultTableTheme, defaultNoteTheme, + avatarThemes, Cardinality, Constraint, Tab, diff --git a/src/pages/editor.jsx b/src/pages/editor.jsx index 5eadaad..816af28 100644 --- a/src/pages/editor.jsx +++ b/src/pages/editor.jsx @@ -7,10 +7,12 @@ import { Tab, defaultTableTheme, defaultNoteTheme, + avatarThemes, Action, ObjectType, } from "../data/data"; import { socket } from "../data/socket"; +import { uniqueNamesGenerator, colors, animals } from "unique-names-generator"; export const LayoutContext = createContext(); export const TableContext = createContext(); @@ -401,15 +403,44 @@ export default function Editor(props) { socket.connect(); - const onConnect = () => console.log(`You connected with id: ${socket.id}`); - const onRecieve = (value) => setMessages((prev) => [...prev, value]); + const onConnect = () => { + const name = uniqueNamesGenerator({ + dictionaries: [colors, animals], + separator: " ", + style: "capital", + }); + const color = + avatarThemes[Math.floor(Math.random() * avatarThemes.length)]; + socket.emit("new-user", name, color); + setMessages((prev) => [ + ...prev, + { message: `You joined as ${name}`, type: "note", action: "join" }, + ]); + }; + const onRecieve = (value) => + setMessages((prev) => [{ ...value, type: "message" }, ...prev]); + const onUserConnected = (name) => + setMessages((prev) => [ + { message: `${name} just joined`, type: "note", action: "join" }, + ...prev, + ]); + const onUserDisconnected = (name) => + setMessages((prev) => [ + { message: `${name} left`, type: "note", action: "leave" }, + ...prev, + ]); socket.on("connect", onConnect); socket.on("recieve-message", onRecieve); + socket.on("user-connected", onUserConnected); + socket.on("user-disconnected", onUserDisconnected); return () => { socket.off("connect", onConnect); socket.off("recieve-message", onRecieve); + socket.off("user-connected", onUserConnected); + socket.off("user-disconnected", onUserDisconnected); + socket.disconnect(); }; }, []);