Add max amount of messages in scroll & auto-scroll

This commit is contained in:
strNophix 2022-10-20 19:47:06 +02:00
parent b1a4470c68
commit 4d92bc3e86
2 changed files with 36 additions and 5 deletions

View File

@ -1,5 +1,5 @@
import { FC, useEffect, useState } from "react" import { FC, KeyboardEventHandler, useEffect, useRef, useState } from "react"
import { CHAT_URL } from "../../config" import { CHAT_URL, MAX_CHAT_MESSAGES } from "../../config"
import useSession from "../../hooks/useSession" import useSession from "../../hooks/useSession"
import { ChatMessage as Message } from "../../types" import { ChatMessage as Message } from "../../types"
import Input from "../common/Input" import Input from "../common/Input"
@ -8,15 +8,43 @@ import ChatMessage from "../message/ChatMessage"
const Chat: FC = () => { const Chat: FC = () => {
const { session } = useSession() const { session } = useSession()
const [messages, setMessages] = useState<Message[]>([]) const [messages, setMessages] = useState<Message[]>([])
const wsRef = useRef<WebSocket | null>(null)
const messagesEndRef = useRef<HTMLDivElement | null>(null)
useEffect(() => { useEffect(() => {
const ws = new WebSocket(CHAT_URL) wsRef.current = new WebSocket(CHAT_URL)
ws.onmessage = (ev) => { wsRef.current.onmessage = (ev) => {
const newMsg = JSON.parse(ev.data) as Message const newMsg = JSON.parse(ev.data) as Message
setMessages((old) => [...old, newMsg]) if (typeof newMsg === "string") return
setMessages((old) => {
if (old.length >= MAX_CHAT_MESSAGES) old.shift()
return [...old, newMsg]
})
}
return () => {
if (wsRef.current) wsRef.current.close()
} }
}, []) }, [])
useEffect(() => {
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" })
}, [messages])
const handleChatInput: KeyboardEventHandler<HTMLInputElement> = (event) => {
if (event.key === "Enter" && wsRef.current) {
const msg = JSON.stringify({
fromUser: "niku",
fromUserID: 10,
toUser: "niku",
toUserID: 10,
content: event.currentTarget.value,
})
wsRef.current.send(msg)
event.currentTarget.value = ""
}
}
return ( return (
<div className="bg-zinc-900 w-80 border-l border-l-zinc-700 flex flex-col"> <div className="bg-zinc-900 w-80 border-l border-l-zinc-700 flex flex-col">
<div className="flex flex-row justify-center items-center border-b border-b-zinc-700 p-2 h-12"> <div className="flex flex-row justify-center items-center border-b border-b-zinc-700 p-2 h-12">
@ -26,12 +54,14 @@ const Chat: FC = () => {
{messages.map((message) => ( {messages.map((message) => (
<ChatMessage key={message.messageId.toString()} message={message} /> <ChatMessage key={message.messageId.toString()} message={message} />
))} ))}
<div ref={messagesEndRef} />
</div> </div>
<div className="m-2"> <div className="m-2">
<Input <Input
disabled={!session} disabled={!session}
className="w-full p-2" className="w-full p-2"
placeholder="Send a message" placeholder="Send a message"
onKeyDown={handleChatInput}
/> />
</div> </div>
</div> </div>

View File

@ -1,2 +1,3 @@
export const KRATOS_URL = "http://127.0.0.1:4433" export const KRATOS_URL = "http://127.0.0.1:4433"
export const CHAT_URL = "ws://localhost:1323" export const CHAT_URL = "ws://localhost:1323"
export const MAX_CHAT_MESSAGES = 50