Skip to content

Commit

Permalink
Fix threads virtual scroller issues (#529)
Browse files Browse the repository at this point in the history
* Slice PageParams when slicing the pages;

* Avoid duplicates that causes broken virtualizer;
  • Loading branch information
stef-coenen authored Jan 17, 2025
1 parent de13462 commit ee9be6b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,26 @@ export const CommunityHistory = memo(
maxAge: maxAge,
});

const [flattenedMsgs, isSliced] =
useMemo(() => {
const flat = (messages?.pages?.flatMap((page) => page?.searchResults)?.filter(Boolean) ||
[]) as HomebaseFile<CommunityMessage>[];

if (inAThread && (!maxAge || origin.fileMetadata.created > maxAge)) {
flat.push(origin as HomebaseFile<CommunityMessage>);
}

if (!maxShowOptions) return [flat, false];
const maxShow = maxShowOptions.count;
return [flat.slice(0, maxShow), maxShow && flat.length > maxShow];
}, [messages, origin, maxShowOptions]) || [];
const [flattenedMsgs, isSliced] = useMemo(() => {
const flat: HomebaseFile<CommunityMessage>[] = [];

messages?.pages?.forEach((page) => {
page?.searchResults?.forEach((result) => {
if (result) flat.push(result);
});
});

flat.sort((a, b) => b.fileMetadata.created - a.fileMetadata.created);

if (inAThread && (!maxAge || origin.fileMetadata.created > maxAge)) {
flat.push(origin as HomebaseFile<CommunityMessage>);
}

if (!maxShowOptions) return [flat, false];

const maxShow = maxShowOptions.count;
return [flat.slice(0, maxShow), flat.length > maxShow];
}, [messages, origin, maxShowOptions, inAThread, maxAge]);

useEffect(() => {
if (setIsEmptyChat && isFetched && (!flattenedMsgs || flattenedMsgs.length === 0))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useCommunity } from '../../hooks/community/useCommunity';
import { ErrorBoundary, LoadingBlock, t, COMMUNITY_ROOT_PATH } from '@homebase-id/common-app';
import { Link, useParams } from 'react-router-dom';
import { memo, useRef } from 'react';
import { memo, useMemo, useRef } from 'react';
import { ChatBubble, ChevronLeft } from '@homebase-id/common-app/icons';
import { HomebaseFile } from '@homebase-id/js-lib/core';
import { CommunityDefinition } from '../../providers/CommunityDefinitionProvider';
import { useCommunityThreads } from '../../hooks/community/threads/useCommunityThreads';
import { ThreadMeta, useCommunityThreads } from '../../hooks/community/threads/useCommunityThreads';
import { CommunityThreadCatchup } from '../../components/Community/catchup/CommunityThreadCatchup';
import { useMarkCommunityAsRead } from '../../hooks/community/useMarkCommunityAsRead';
import { useVirtualizer } from '@tanstack/react-virtual';
Expand All @@ -21,13 +21,27 @@ export const CommunityThreadsCatchup = memo(() => {
odinId: odinKey,
communityId: communityId,
});
const uniqueFlatThreadMetas = useMemo(() => {
if (!flatThreadMetas) return [];
const uniqueThreads: Record<string, ThreadMeta> = {};

for (let i = 0; i < flatThreadMetas?.length; i++) {
if (uniqueThreads[flatThreadMetas[i].threadId]) {
continue;
} else {
uniqueThreads[flatThreadMetas[i].threadId] = flatThreadMetas[i];
}
}

return Object.values(uniqueThreads);
}, [flatThreadMetas]);

const virtualizer = useVirtualizer({
getScrollElement: () => scrollRef.current,
count: flatThreadMetas?.length || 0,
count: uniqueFlatThreadMetas?.length || 0,
estimateSize: () => 500,
overscan: 5,
getItemKey: (index) => flatThreadMetas?.[index]?.threadId || index,
overscan: 4,
getItemKey: (index) => uniqueFlatThreadMetas?.[index]?.threadId || index,
});
const items = virtualizer.getVirtualItems();

Expand Down Expand Up @@ -60,7 +74,7 @@ export const CommunityThreadsCatchup = memo(() => {
<div className="flex h-full flex-grow flex-col overflow-hidden">
<div className="flex h-full flex-grow flex-col">
<CommunityCatchupHeader community={community} />
{!flatThreadMetas?.length ? (
{!uniqueFlatThreadMetas?.length ? (
<p className="m-auto text-lg">{t('No threads found')}</p>
) : (
<div className="relative h-20 flex-grow flex-col overflow-auto p-3" ref={scrollRef}>
Expand All @@ -77,7 +91,7 @@ export const CommunityThreadsCatchup = memo(() => {
}}
>
{items.map((item) => {
const threadMeta = flatThreadMetas?.[item.index];
const threadMeta = uniqueFlatThreadMetas?.[item.index];
return (
<div
key={item.key}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export const OdinQueryClient = ({
if (data?.pages?.length && data?.pages?.length > 2) {
const adjustedData = { ...data };
adjustedData.pages = adjustedData.pages.slice(0, 2);
adjustedData.pageParams = adjustedData.pageParams.slice(0, 2);
return adjustedData;
}

Expand Down

0 comments on commit ee9be6b

Please sign in to comment.