5
5
useContext ,
6
6
useRef ,
7
7
} from "react"
8
- import {
9
- useParams ,
10
- } from "react-router-dom"
11
8
import {
12
9
useAuthStore ,
13
10
} from "../store.js"
@@ -19,7 +16,6 @@ import {
19
16
20
17
export const Chat = ( { chatId} ) => {
21
18
let [ messages , setMessages ] = useState ( [ ] )
22
- let divRef = useRef ( )
23
19
let messageRef = useRef ( )
24
20
let needsScroll = useRef ( false )
25
21
let stompClient = useContext ( StompContext )
@@ -28,8 +24,7 @@ export const Chat = ({chatId}) => {
28
24
useEffect ( ( ) => {
29
25
stompClient . subscribe ( "/topic/chat/" + chatId , ( m ) => {
30
26
let message = JSON . parse ( m . body )
31
- let msg = messageRef . current
32
- needsScroll . current = msg . scrollHeight <= msg . scrollTop + msg . offsetHeight
27
+ needsScroll . current = isLastChildVisible ( messageRef . current )
33
28
setMessages ( previous => {
34
29
if ( previous . length && previous [ previous . length - 1 ] . n === message . n ) {
35
30
return previous
@@ -54,7 +49,7 @@ export const Chat = ({chatId}) => {
54
49
if ( ! needsScroll . current ) {
55
50
return
56
51
}
57
- window . setTimeout ( ( ) => divRef . current ?. scrollIntoView ( { behavior : "smooth" } ) , 0 )
52
+ window . setTimeout ( ( ) => messageRef . current ?. lastChild ?. scrollIntoView ( { behavior : "smooth" } ) , 0 )
58
53
} , [ messages ] )
59
54
60
55
let onSendMessage = useCallback ( ( event ) => doTry ( async ( ) => {
@@ -71,14 +66,22 @@ export const Chat = ({chatId}) => {
71
66
} ) , [ stompClient , chatId ] )
72
67
73
68
return < >
74
- < div ref = { messageRef }
75
- className = "grow border border-gray-500 bg-gray-900 rounded-lg p-1 overflow-y-scroll" >
76
- { messages . map ( message => (
77
- < p key = { message . n } > { message . user + ": " + message . message } </ p >
78
- ) ) }
79
- < div ref = { divRef } />
69
+ < div
70
+ className = "grow border border-gray-500 bg-gray-900 rounded-lg flex flex-col overflow-y-hidden" >
71
+ < div className = "px-1 flex-none h-14 overflow-y-scroll" >
72
+ < p > Radolf!</ p >
73
+ < p > Radolf!</ p >
74
+ < p > Radolf!</ p >
75
+ < p > Radolf!</ p >
76
+ </ div >
77
+ < div className = "w-full flex-none h-[2px] bg-gray-500" />
78
+ < div ref = { messageRef } className = "px-1 overflow-y-scroll" >
79
+ { messages . map ( message => (
80
+ < p key = { message . n } > { message . user + ": " + message . message } </ p >
81
+ ) ) }
82
+ </ div >
80
83
</ div >
81
- < form className = "flex-0 mb-2" onSubmit = { onSendMessage } >
84
+ < form className = "flex-none mb-2" onSubmit = { onSendMessage } >
82
85
< input
83
86
className = "w-full rounded-lg p-2 border border-gray-500 bg-stone-800 text-stone-100"
84
87
type = "text"
@@ -87,3 +90,11 @@ export const Chat = ({chatId}) => {
87
90
</ form >
88
91
</ >
89
92
}
93
+
94
+ function isLastChildVisible ( container ) {
95
+ let lastChild = container . lastChild
96
+ let lastChildTop = lastChild . offsetTop
97
+ let containerTop = container . scrollTop + container . offsetTop
98
+ let containerBottom = containerTop + container . clientHeight
99
+ return lastChildTop < containerBottom
100
+ }
0 commit comments