1
1
'use client'
2
2
3
- import { ChangeEventHandler , FC , useCallback , useMemo , useState , useTransition } from 'react'
3
+ import {
4
+ ChangeEventHandler ,
5
+ FC ,
6
+ useCallback ,
7
+ useEffect ,
8
+ useMemo ,
9
+ useState ,
10
+ useTransition ,
11
+ } from 'react'
4
12
5
13
import { Searchbar as DefaultSearchbar , LoadingState } from '@baseapp-frontend/design-system'
6
14
@@ -29,6 +37,7 @@ const ChatRoomsList: FC<ChatRoomsListProps> = ({
29
37
VirtuosoProps = { } ,
30
38
} ) => {
31
39
const [ tab , setTab ] = useState < ChatTabValues > ( CHAT_TAB_VALUES . active )
40
+ const [ renderList , setRenderList ] = useState < boolean > ( true )
32
41
33
42
const [ isRefetchPending , startRefetchTransition ] = useTransition ( )
34
43
const { data, loadNext, isLoadingNext, hasNext, refetch } = useRoomsList (
@@ -45,39 +54,53 @@ const ChatRoomsList: FC<ChatRoomsListProps> = ({
45
54
const handleSearchChange : ChangeEventHandler < HTMLInputElement > = ( e ) => {
46
55
const value = e . target . value || ''
47
56
startTransition ( ( ) => {
48
- refetch ( {
49
- q : value ,
50
- unreadMessages : isInUnreadTab ,
51
- archived : isInArchivedTab ,
52
- } )
57
+ refetch (
58
+ {
59
+ q : value ,
60
+ unreadMessages : isInUnreadTab ,
61
+ archived : isInArchivedTab ,
62
+ } ,
63
+ { fetchPolicy : 'network-only' } ,
64
+ )
53
65
} )
54
66
}
55
67
56
68
const handleSearchClear = ( ) => {
57
69
startTransition ( ( ) => {
58
70
reset ( )
59
- refetch ( {
60
- q : '' ,
61
- unreadMessages : isInUnreadTab ,
62
- archived : isInArchivedTab ,
63
- } )
71
+ refetch (
72
+ {
73
+ q : '' ,
74
+ unreadMessages : isInUnreadTab ,
75
+ archived : isInArchivedTab ,
76
+ } ,
77
+ { fetchPolicy : 'network-only' } ,
78
+ )
64
79
} )
65
80
}
66
81
67
82
const handleChange = ( event : React . SyntheticEvent , newTab : string ) => {
68
83
setTab ( newTab as ChatTabValues )
69
84
startRefetchTransition ( ( ) => {
85
+ setRenderList ( false )
70
86
refetch (
71
87
{
72
88
q : searchValue ,
73
89
unreadMessages : newTab === CHAT_TAB_VALUES . unread ,
74
90
archived : newTab === CHAT_TAB_VALUES . archived ,
75
91
} ,
76
- { fetchPolicy : 'store-and- network' } ,
92
+ { fetchPolicy : 'network-only ' } ,
77
93
)
78
94
} )
79
95
}
80
96
97
+ // Virtuoso has a bug where it does not recognize endReached if the data is changed while the component is still mounted.
98
+ // The `renderList` state is a workaround to force the component to dismount and remount,
99
+ // to ensure that Virtuoso will recognized endReached everytime the tab is changed
100
+ useEffect ( ( ) => {
101
+ setRenderList ( true )
102
+ } , [ data ] )
103
+
81
104
const { id : selectedRoom , setChatRoom } = useChatRoom ( )
82
105
const chatRooms = useMemo (
83
106
( ) => data ?. chatRooms ?. edges ?. filter ( ( edge ) => edge ?. node ) . map ( ( edge ) => edge ?. node ) || [ ] ,
@@ -127,29 +150,14 @@ const ChatRoomsList: FC<ChatRoomsListProps> = ({
127
150
)
128
151
129
152
const renderListContent = ( ) => {
130
- const emptyChatRoomsList = chatRooms . length === 0
131
-
132
- if ( ! isPending && searchValue && emptyChatRoomsList ) return < SearchNotFoundState />
153
+ const hasEmptyStates = ! isPending && chatRooms . length === 0
133
154
134
- if ( ! isPending && emptyChatRoomsList ) return < EmptyChatRoomsState />
155
+ if ( hasEmptyStates ) {
156
+ if ( searchValue ) return < SearchNotFoundState />
157
+ return < EmptyChatRoomsState />
158
+ }
135
159
136
- return (
137
- < Virtuoso
138
- data = { chatRooms }
139
- overscan = { 1 }
140
- itemContent = { ( _index , item ) => renderItem ( item ) }
141
- style = { { scrollbarWidth : 'none' } }
142
- components = { {
143
- Footer : renderLoadingState ,
144
- } }
145
- endReached = { ( ) => {
146
- if ( hasNext ) {
147
- loadNext ( 5 )
148
- }
149
- } }
150
- { ...VirtuosoProps }
151
- />
152
- )
160
+ return undefined
153
161
}
154
162
155
163
return (
@@ -195,6 +203,23 @@ const ChatRoomsList: FC<ChatRoomsListProps> = ({
195
203
< Tab label = { renderTabLabel ( CHAT_TAB_VALUES . archived ) } value = { CHAT_TAB_VALUES . archived } />
196
204
</ Tabs >
197
205
{ renderListContent ( ) }
206
+ { renderList && (
207
+ < Virtuoso
208
+ data = { chatRooms }
209
+ overscan = { 1 }
210
+ itemContent = { ( _index , item ) => renderItem ( item ) }
211
+ style = { { scrollbarWidth : 'none' } }
212
+ components = { {
213
+ Footer : renderLoadingState ,
214
+ } }
215
+ endReached = { ( ) => {
216
+ if ( hasNext ) {
217
+ loadNext ( 5 )
218
+ }
219
+ } }
220
+ { ...VirtuosoProps }
221
+ />
222
+ ) }
198
223
</ ChatRoomListContainer >
199
224
)
200
225
}
0 commit comments