import React, { useMemo } from 'react'; import { AlertCircle, Loader2 } from 'lucide-react'; import { TreeNode, TREE_ROW_HEIGHT } from './SftpPaneTreeNode'; // eslint-disable-next-line @typescript-eslint/no-explicit-any type SftpPaneTreeRowsProps = Record; export function useSftpPaneTreeRows(props: SftpPaneTreeRowsProps) { const { nodeDescriptors, scrollTop, viewportHeight, tRef, columnTemplate, visibleColumns, selectedPaths, dragOverNodePath, toggleExpand, handleNodeClick, stableOnOpenEntry, stableOnDragStart, stableOnDragEnd, handleNodeDragOver, handleNodeDrop, handleNodeDragLeave, handleNodeContextMenu, } = props; const { totalHeight, visibleRange } = useMemo(() => { const totalCount = nodeDescriptors.length; const total = totalCount * TREE_ROW_HEIGHT; const shouldVirtualize = viewportHeight > 0 && totalCount > 50; if (!shouldVirtualize) { return { totalHeight: 0, visibleRange: { start: 0, end: totalCount - 1, virtualized: false } }; } const overscan = 6; const start = Math.max(0, Math.floor(scrollTop / TREE_ROW_HEIGHT) - overscan); const end = Math.min(totalCount - 1, Math.ceil((scrollTop + viewportHeight) / TREE_ROW_HEIGHT) + overscan); return { totalHeight: total, visibleRange: { start, end, virtualized: true } }; }, [nodeDescriptors.length, scrollTop, viewportHeight]); // ── Render visible rows ────────────────────────────────────────── const treeRows = useMemo(() => { const { start, end, virtualized } = visibleRange; const rows: React.ReactNode[] = []; for (let i = start; i <= end; i++) { const descriptor = nodeDescriptors[i]; if (!descriptor) continue; let content: React.ReactNode; if (descriptor.type === 'loading') { content = (
{tRef.current('sftp.tree.loading')}
); } else if (descriptor.type === 'error') { content = (
{tRef.current('sftp.tree.loadError')}
); } else { content = ( ); } const key = descriptor.type === 'node' ? descriptor.entryPath : descriptor.key; if (virtualized) { rows.push(
{content}
, ); } else { rows.push({content}); } } return rows; }, [ visibleRange, nodeDescriptors, columnTemplate, visibleColumns, selectedPaths, dragOverNodePath, toggleExpand, handleNodeClick, stableOnOpenEntry, stableOnDragStart, stableOnDragEnd, handleNodeDragOver, handleNodeDrop, handleNodeDragLeave, handleNodeContextMenu, tRef, ]); return { totalHeight, treeRows, visibleRange }; }