mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-26 01:06:23 +02:00
refactor: improve infinite scroll implementation in DocumentsTableShell by adding separate scroll references for desktop and mobile views
This commit is contained in:
parent
dc6c18b3f6
commit
fc120bcb38
1 changed files with 22 additions and 27 deletions
|
|
@ -178,10 +178,6 @@ function DocumentNameTooltip({
|
||||||
<span className="text-muted-foreground">Created:</span>{" "}
|
<span className="text-muted-foreground">Created:</span>{" "}
|
||||||
{formatAbsoluteDate(doc.created_at)}
|
{formatAbsoluteDate(doc.created_at)}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
|
||||||
<span className="text-muted-foreground">Source:</span>{" "}
|
|
||||||
{getDocumentTypeLabel(doc.document_type)}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
@ -331,27 +327,30 @@ export function DocumentsTableShell({
|
||||||
|
|
||||||
const desktopSentinelRef = useRef<HTMLDivElement>(null);
|
const desktopSentinelRef = useRef<HTMLDivElement>(null);
|
||||||
const mobileSentinelRef = useRef<HTMLDivElement>(null);
|
const mobileSentinelRef = useRef<HTMLDivElement>(null);
|
||||||
|
const desktopScrollRef = useRef<HTMLDivElement>(null);
|
||||||
|
const mobileScrollRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!onLoadMore || !hasMore || loadingMore) return;
|
if (!onLoadMore || !hasMore || loadingMore) return;
|
||||||
|
|
||||||
const observer = new IntersectionObserver(
|
const observers: IntersectionObserver[] = [];
|
||||||
(entries) => {
|
|
||||||
if (entries.some((e) => e.isIntersecting)) {
|
|
||||||
onLoadMore();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ root: null, rootMargin: "200px", threshold: 0 }
|
|
||||||
);
|
|
||||||
|
|
||||||
if (desktopSentinelRef.current) {
|
const observe = (root: HTMLElement | null, sentinel: HTMLElement | null) => {
|
||||||
observer.observe(desktopSentinelRef.current);
|
if (!root || !sentinel) return;
|
||||||
}
|
const observer = new IntersectionObserver(
|
||||||
if (mobileSentinelRef.current) {
|
(entries) => {
|
||||||
observer.observe(mobileSentinelRef.current);
|
if (entries.some((e) => e.isIntersecting)) onLoadMore();
|
||||||
}
|
},
|
||||||
|
{ root, rootMargin: "150px", threshold: 0 }
|
||||||
|
);
|
||||||
|
observer.observe(sentinel);
|
||||||
|
observers.push(observer);
|
||||||
|
};
|
||||||
|
|
||||||
return () => observer.disconnect();
|
observe(desktopScrollRef.current, desktopSentinelRef.current);
|
||||||
|
observe(mobileScrollRef.current, mobileSentinelRef.current);
|
||||||
|
|
||||||
|
return () => { for (const o of observers) o.disconnect(); };
|
||||||
}, [onLoadMore, hasMore, loadingMore]);
|
}, [onLoadMore, hasMore, loadingMore]);
|
||||||
|
|
||||||
const handleViewDocument = useCallback(async (doc: Document) => {
|
const handleViewDocument = useCallback(async (doc: Document) => {
|
||||||
|
|
@ -589,7 +588,7 @@ export function DocumentsTableShell({
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
</Table>
|
</Table>
|
||||||
<div className="flex-1 overflow-auto">
|
<div ref={desktopScrollRef} className="flex-1 overflow-auto">
|
||||||
<Table className="table-fixed w-full">
|
<Table className="table-fixed w-full">
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{sorted.map((doc, index) => {
|
{sorted.map((doc, index) => {
|
||||||
|
|
@ -661,15 +660,13 @@ export function DocumentsTableShell({
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
{hasMore && (
|
{hasMore && (
|
||||||
<div ref={desktopSentinelRef} className="flex items-center justify-center py-3">
|
<div ref={desktopSentinelRef} className="py-3" />
|
||||||
{loadingMore && <Spinner size="sm" className="text-muted-foreground" />}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mobile Card View */}
|
{/* Mobile Card View */}
|
||||||
<div className="md:hidden divide-y divide-border/50 flex-1 overflow-auto">
|
<div ref={mobileScrollRef} className="md:hidden divide-y divide-border/50 flex-1 overflow-auto">
|
||||||
{sorted.map((doc, index) => {
|
{sorted.map((doc, index) => {
|
||||||
const isSelected = selectedIds.has(doc.id);
|
const isSelected = selectedIds.has(doc.id);
|
||||||
const canSelect = isSelectable(doc);
|
const canSelect = isSelectable(doc);
|
||||||
|
|
@ -731,9 +728,7 @@ export function DocumentsTableShell({
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{hasMore && (
|
{hasMore && (
|
||||||
<div ref={mobileSentinelRef} className="flex items-center justify-center py-3">
|
<div ref={mobileSentinelRef} className="py-3" />
|
||||||
{loadingMore && <Spinner size="sm" className="text-muted-foreground" />}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue