import { useRef, useState, useEffect } from "react"; import { generateGruvboxFromString } from "./utils/generate_gruvbox"; import "./App.css"; function App() { const [socket, setSocket] = useState(null); const [posts, setPosts] = useState([]); const postsRef = useRef([]); const [content, setContent] = useState(""); const [username, setUsername] = useState(""); const [error, setError] = useState(""); const [color, setColor] = useState(""); const scrollToBottomOfChat = () => { const objDiv = document.getElementById("chat"); objDiv.scrollTop = objDiv.scrollHeight; }; useEffect(() => { const protocol = document.location.protocol === "https:" ? "wss:" : "ws:"; let socket; fetch("/posts") .then((r) => r.json()) .then((msgs) => { postsRef.current = msgs; setPosts(postsRef.current); scrollToBottomOfChat(); }) .then(() => { socket = new WebSocket(`${protocol}//${document.location.host}/`); socket.addEventListener("open", () => { socket.send("ping"); }); socket.addEventListener("message", (msg) => { const { data } = msg; if (data === "pong") return; const chat = JSON.parse(msg.data); if (chat.author) { postsRef.current = [...postsRef.current, chat]; setPosts(postsRef.current); scrollToBottomOfChat(); } }); setSocket(socket); }); return () => { socket.close(); }; }, []); useEffect(() => { setColor(generateGruvboxFromString(username)); }, [username]); const addPost = () => { setError(""); if (socket) { fetch("/posts", { method: "POST", headers: { Content: "application/json" }, body: JSON.stringify({ author: username, message: content }), }).then(() => setContent("")); } }; return (

TronglePosting in ELisp

Welcome!

{posts.map((post) => (
{post.author}:{" "} {post.message}
[{new Date(post.date).toLocaleString()}]
))}
{ setUsername(e.target.value); }} value={username} >
Post
{error ?

{error}

: null}
); } export default App;