11import { useEffect , useRef , useState } from "react" ;
22
3- const usePoll = ( url ) => {
3+ const useLongPoll = ( url ) => {
44 const [ messages , setMessages ] = useState ( [ ] ) ;
55 const cursorRef = useRef ( 0 ) ;
66 const activeRef = useRef ( true ) ;
77
88 useEffect ( ( ) => {
9+ fetch ( `${ url } /poll/history` )
10+ . then ( ( r ) => r . json ( ) )
11+ . then ( ( history ) => {
12+ setMessages ( history ) ;
13+ cursorRef . current = history . length ;
14+ } ) ;
15+
916 const poll = async ( ) => {
1017 while ( activeRef . current ) {
1118 try {
1219 const res = await fetch ( `${ url } /poll?since=${ cursorRef . current } ` ) ;
1320 const data = await res . json ( ) ;
1421
1522 if ( data . messages . length > 0 ) {
16- cursorRef . current = data . cursor ;
17- setMessages ( ( prev ) => [ ...prev , ...data . messages ] ) ;
23+ data . messages . forEach ( ( msg ) => {
24+ if ( msg . index !== undefined ) {
25+ setMessages ( ( prev ) =>
26+ prev . map ( ( m , i ) => ( i === msg . index ? { ...m , ...msg } : m ) ) ,
27+ ) ;
28+ } else {
29+ cursorRef . current = data . cursor ;
30+ setMessages ( ( prev ) => [ ...prev , msg ] ) ;
31+ }
32+ } ) ;
1833 }
1934 } catch {
2035 await new Promise ( ( r ) => setTimeout ( r , 2000 ) ) ;
@@ -29,17 +44,25 @@ const usePoll = (url) => {
2944 } , [ url ] ) ;
3045
3146 const sendMessage = async ( text ) => {
32- const message = { text, time : new Date ( ) . toISOString ( ) } ;
33- setMessages ( ( prev ) => [ ...prev , { ...message } ] ) ;
34-
35- await fetch ( `${ url } /message` , {
47+ const msg = { text, time : new Date ( ) . toISOString ( ) , likes : 0 , dislikes : 0 } ;
48+ setMessages ( ( prev ) => [ ...prev , { ...msg , self : true } ] ) ;
49+ await fetch ( `${ url } /poll/message` , {
3650 method : "POST" ,
3751 headers : { "Content-Type" : "application/json" } ,
38- body : JSON . stringify ( message ) ,
52+ body : JSON . stringify ( msg ) ,
3953 } ) ;
4054 } ;
4155
42- return { messages, sendMessage } ;
56+ const reactToMessage = async ( index , type ) => {
57+ setMessages ( ( prev ) =>
58+ prev . map ( ( msg , i ) =>
59+ i === index ? { ...msg , [ type ] : msg [ type ] + 1 } : msg ,
60+ ) ,
61+ ) ;
62+ await fetch ( `${ url } /poll/message/${ index } /${ type } ` , { method : "PATCH" } ) ;
63+ } ;
64+
65+ return { messages, sendMessage, reactToMessage } ;
4366} ;
4467
45- export default usePoll ;
68+ export default useLongPoll ;
0 commit comments