@@ -4,10 +4,11 @@ import { Member, Message, Profile } from "@prisma/client";
4
4
import { ChatWelcome } from "./chat-welcome" ;
5
5
import { Loader2 , ServerCrash } from "lucide-react" ;
6
6
import { useChatQuery } from "@/hooks/use-chat-query" ;
7
- import { Fragment } from "react" ;
7
+ import { Fragment , useRef , ElementRef } from "react" ;
8
8
import { ChatItem } from "./chat-item" ;
9
9
import { format } from "date-fns" ;
10
10
import { useChatSocket } from "@/hooks/use-chat-socket" ;
11
+ import { useChatScroll } from "@/hooks/use-chat-scroll" ;
11
12
12
13
type MessageWithMemberWithProfile = Message & {
13
14
member : Member & {
@@ -44,6 +45,9 @@ export const ChatMessages: React.FC<ChatMessagesProps> = ({
44
45
const addKey = `chat:${ chatId } :messages` ;
45
46
const updateKey = `chat:${ chatId } :messages:update` ;
46
47
48
+ const chatRef = useRef < ElementRef < "div" > > ( null ) ;
49
+ const bottomRef = useRef < ElementRef < "div" > > ( null ) ;
50
+
47
51
const { data, status, fetchNextPage, hasNextPage, isFetchingNextPage } =
48
52
useChatQuery ( {
49
53
queryKey,
@@ -58,6 +62,14 @@ export const ChatMessages: React.FC<ChatMessagesProps> = ({
58
62
updateKey,
59
63
} ) ;
60
64
65
+ useChatScroll ( {
66
+ chatRef,
67
+ bottomRef,
68
+ loadMore : fetchNextPage ,
69
+ shouldLoadMore : ! isFetchingNextPage && ! ! hasNextPage ,
70
+ count : data ?. pages [ 0 ] ?. items ?. length ?? 0 ,
71
+ } ) ;
72
+
61
73
if ( status === "loading" ) {
62
74
return (
63
75
< div className = "flex flex-col flex-1 justify-center items-center" >
@@ -81,9 +93,24 @@ export const ChatMessages: React.FC<ChatMessagesProps> = ({
81
93
}
82
94
83
95
return (
84
- < div className = "flex-1 flex flex-col py-4 overflow-y-auto" >
85
- < div className = "flex-1" />
86
- < ChatWelcome type = { type } name = { name } />
96
+ < div ref = { chatRef } className = "flex-1 flex flex-col py-4 overflow-y-auto" >
97
+ { ! hasNextPage && < div className = "flex-1" /> }
98
+ { ! hasNextPage && < ChatWelcome type = { type } name = { name } /> }
99
+
100
+ { hasNextPage && (
101
+ < div className = "flex justify-center" >
102
+ { isFetchingNextPage ? (
103
+ < Loader2 className = "w-7 h-7 text-zinc-500 animate-spin my-4" />
104
+ ) : (
105
+ < button
106
+ onClick = { ( ) => fetchNextPage ( ) }
107
+ className = "text-zinc-500 hover:text-zinc-600 dark:textzinc-400 text-xs my-4 dark:hover:text-zinc-300 transition"
108
+ >
109
+ Load previous messages
110
+ </ button >
111
+ ) }
112
+ </ div >
113
+ ) }
87
114
< div className = "flex flex-col-reverse mt-auto" >
88
115
{ data ?. pages . map ( ( page , i ) => (
89
116
< Fragment key = { i } >
@@ -105,6 +132,7 @@ export const ChatMessages: React.FC<ChatMessagesProps> = ({
105
132
</ Fragment >
106
133
) ) }
107
134
</ div >
135
+ < div ref = { bottomRef } />
108
136
</ div >
109
137
) ;
110
138
} ;
0 commit comments