Add max amount of messages in scroll & auto-scroll
This commit is contained in:
parent
b1a4470c68
commit
4d92bc3e86
@ -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>
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user