import { useEffect, useState } from "preact/hooks"; interface ChatMessage { text: string; sender: string; timestamp: string; } export default function Chat() { const [messages, setMessages] = useState([]); const [newMessage, setNewMessage] = useState(""); const [username, setUsername] = useState(""); const [socket, setSocket] = useState(null); const [isConnected, setIsConnected] = useState(false); const [userCount, setUserCount] = useState(0); useEffect(() => { if (!username) { const randomNum = Math.floor(Math.random() * 10000); setUsername(`User${randomNum}`); } const ws = new WebSocket(`ws://${globalThis.location.host}/api/chat`); ws.onopen = () => { console.log("Connected to chat"); setIsConnected(true); setSocket(ws); }; ws.onmessage = (event) => { try { const data = JSON.parse(event.data); if (data.type === "user_count") { setUserCount(data.count); } else { setMessages((prev) => [...prev, data]); const chatBox = document.getElementById("chat-messages"); if (chatBox) { setTimeout(() => { chatBox.scrollTop = chatBox.scrollHeight; }, 50); } } } catch (err) { console.error("Error processing message:", err); } }; ws.onclose = () => { console.log("Disconnected from chat"); setIsConnected(false); }; return () => { ws.close(); }; }, []); const sendMessage = (e: Event) => { e.preventDefault(); if (!newMessage.trim() || !socket) return; const messageData = { text: newMessage, sender: username, timestamp: new Date().toISOString(), }; socket.send(JSON.stringify(messageData)); setNewMessage(""); }; return (

Live Chat

{isConnected ? `${userCount} online • Messages are not saved` : "Connecting..."}

{messages.length === 0 ? (

No messages yet. Be the first to chat!

) : ( messages.map((msg, i) => (
{msg.sender === username ? "You" : msg.sender} {new Date(msg.timestamp).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", })}

{msg.text}

)) )}
setNewMessage(e.currentTarget.value)} placeholder="Type your message..." class="flex-1 px-4 py-3 bg-gray-800 text-white rounded-l-lg border-0 focus:outline-none focus:ring-2 focus:ring-secondary placeholder-gray-500" disabled={!isConnected} maxLength={2000} />

You are chatting as{" "} {username}

); }