Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BA-2081: chat rooms refetch issue #182

Merged
merged 2 commits into from
Feb 14, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 58 additions & 33 deletions packages/components/modules/messages/web/ChatRoomsList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
'use client'

import { ChangeEventHandler, FC, useCallback, useMemo, useState, useTransition } from 'react'
import {
ChangeEventHandler,
FC,
useCallback,
useEffect,
useMemo,
useState,
useTransition,
} from 'react'

import { LoadingState } from '@baseapp-frontend/design-system/components/web/displays'
import { Searchbar as DefaultSearchbar } from '@baseapp-frontend/design-system/components/web/inputs'
Expand Down Expand Up @@ -28,6 +36,7 @@ const ChatRoomsList: FC<ChatRoomsListProps> = ({
VirtuosoProps = {},
}) => {
const [tab, setTab] = useState<ChatTabValues>(CHAT_TAB_VALUES.active)
const [renderList, setRenderList] = useState<boolean>(true)

const [isRefetchPending, startRefetchTransition] = useTransition()
const { data, loadNext, isLoadingNext, hasNext, refetch } = useRoomsList(
Expand All @@ -44,39 +53,53 @@ const ChatRoomsList: FC<ChatRoomsListProps> = ({
const handleSearchChange: ChangeEventHandler<HTMLInputElement> = (e) => {
const value = e.target.value || ''
startTransition(() => {
refetch({
q: value,
unreadMessages: isInUnreadTab,
archived: isInArchivedTab,
})
refetch(
{
q: value,
unreadMessages: isInUnreadTab,
archived: isInArchivedTab,
},
{ fetchPolicy: 'network-only' },
)
})
}

const handleSearchClear = () => {
startTransition(() => {
reset()
refetch({
q: '',
unreadMessages: isInUnreadTab,
archived: isInArchivedTab,
})
refetch(
{
q: '',
unreadMessages: isInUnreadTab,
archived: isInArchivedTab,
},
{ fetchPolicy: 'network-only' },
)
})
}

const handleChange = (event: React.SyntheticEvent, newTab: string) => {
setTab(newTab as ChatTabValues)
startRefetchTransition(() => {
setRenderList(false)
refetch(
{
q: searchValue,
unreadMessages: newTab === CHAT_TAB_VALUES.unread,
archived: newTab === CHAT_TAB_VALUES.archived,
},
{ fetchPolicy: 'store-and-network' },
{ fetchPolicy: 'network-only' },
)
})
}

// Virtuoso has a bug where it does not recognize endReached if the data is changed while the component is still mounted.
// The `renderList` state is a workaround to force the component to dismount and remount,
// to ensure that Virtuoso will recognized endReached everytime the tab is changed
useEffect(() => {
setRenderList(true)
}, [data])

const { id: selectedRoom, setChatRoom } = useChatRoom()
const chatRooms = useMemo(
() => data?.chatRooms?.edges?.filter((edge) => edge?.node).map((edge) => edge?.node) || [],
Expand Down Expand Up @@ -126,29 +149,14 @@ const ChatRoomsList: FC<ChatRoomsListProps> = ({
)

const renderListContent = () => {
const emptyChatRoomsList = chatRooms.length === 0

if (!isPending && searchValue && emptyChatRoomsList) return <SearchNotFoundState />
const hasEmptyStates = !isPending && chatRooms.length === 0

if (!isPending && emptyChatRoomsList) return <EmptyChatRoomsState />
if (hasEmptyStates) {
if (searchValue) return <SearchNotFoundState />
return <EmptyChatRoomsState />
}

return (
<Virtuoso
data={chatRooms}
overscan={1}
itemContent={(_index, item) => renderItem(item)}
style={{ scrollbarWidth: 'none' }}
components={{
Footer: renderLoadingState,
}}
endReached={() => {
if (hasNext) {
loadNext(5)
}
}}
{...VirtuosoProps}
/>
)
return undefined
}

return (
Expand Down Expand Up @@ -194,6 +202,23 @@ const ChatRoomsList: FC<ChatRoomsListProps> = ({
<Tab label={renderTabLabel(CHAT_TAB_VALUES.archived)} value={CHAT_TAB_VALUES.archived} />
</Tabs>
{renderListContent()}
{renderList && (
<Virtuoso
data={chatRooms}
overscan={1}
itemContent={(_index, item) => renderItem(item)}
style={{ scrollbarWidth: 'none' }}
components={{
Footer: renderLoadingState,
}}
endReached={() => {
if (hasNext) {
loadNext(5)
}
}}
{...VirtuosoProps}
/>
)}
</ChatRoomListContainer>
)
}
Expand Down
Loading