update rendering
This commit is contained in:
parent
8f6a9c4a48
commit
1498ae5670
1 changed files with 55 additions and 23 deletions
|
@ -21,6 +21,8 @@ export default function FilePreview({ url: initialUrl = '', filename: initialFil
|
||||||
const [fileType, setFileType] = useState<string | null>(null);
|
const [fileType, setFileType] = useState<string | null>(null);
|
||||||
const [isVisible, setIsVisible] = useState(false);
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
const [isExpanded, setIsExpanded] = useState(false);
|
const [isExpanded, setIsExpanded] = useState(false);
|
||||||
|
const [visibleLines, setVisibleLines] = useState(20);
|
||||||
|
const CHUNK_SIZE = 50; // Number of additional lines to show when expanding
|
||||||
const INITIAL_LINES_TO_SHOW = 20;
|
const INITIAL_LINES_TO_SHOW = 20;
|
||||||
|
|
||||||
// Memoize the truncated filename
|
// Memoize the truncated filename
|
||||||
|
@ -86,9 +88,7 @@ export default function FilePreview({ url: initialUrl = '', filename: initialFil
|
||||||
contentValue = 'pdf';
|
contentValue = 'pdf';
|
||||||
} else if (contentType?.startsWith('text/')) {
|
} else if (contentType?.startsWith('text/')) {
|
||||||
const text = await response.text();
|
const text = await response.text();
|
||||||
contentValue = text.length > 100000
|
contentValue = text;
|
||||||
? text.substring(0, 100000) + '\n\n... Content truncated. Please download the file to view the complete content.'
|
|
||||||
: text;
|
|
||||||
} else if (filename.toLowerCase().endsWith('.mp4')) {
|
} else if (filename.toLowerCase().endsWith('.mp4')) {
|
||||||
contentValue = 'video';
|
contentValue = 'video';
|
||||||
} else {
|
} else {
|
||||||
|
@ -199,32 +199,49 @@ export default function FilePreview({ url: initialUrl = '', filename: initialFil
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
const headers = lines[0];
|
const headers = lines[0];
|
||||||
const rows = lines.slice(1).filter(row => row.some(cell => cell.length > 0)); // Skip empty rows
|
const dataRows = lines.slice(1).filter(row => row.some(cell => cell.length > 0)); // Skip empty rows
|
||||||
return { headers, rows };
|
|
||||||
|
// Remove the truncation message if it exists
|
||||||
|
const lastRow = dataRows[dataRows.length - 1];
|
||||||
|
if (lastRow && lastRow[0] && lastRow[0].includes('Content truncated')) {
|
||||||
|
dataRows.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return { headers, rows: dataRows };
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const renderCSVTable = useCallback((csvContent: string) => {
|
const renderCSVTable = useCallback((csvContent: string) => {
|
||||||
const { headers, rows } = parseCSV(csvContent);
|
const { headers, rows } = parseCSV(csvContent);
|
||||||
|
const totalRows = rows.length;
|
||||||
|
const rowsToShow = Math.min(visibleLines, totalRows);
|
||||||
|
const displayedRows = rows.slice(0, rowsToShow);
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<table class="table table-zebra w-full">
|
<table class="table w-full">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr class="bg-base-200">
|
||||||
${headers.map(header => `<th class="bg-base-200">${header}</th>`).join('')}
|
${headers.map(header => `<th class="px-4 py-2 text-left font-medium">${header}</th>`).join('')}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
${rows.map(row => `
|
${displayedRows.map((row, rowIndex) => `
|
||||||
<tr>
|
<tr class="${rowIndex % 2 === 0 ? 'bg-base-100' : 'bg-base-200/50'}">
|
||||||
${row.map(cell => `<td>${cell}</td>`).join('')}
|
${row.map(cell => `<td class="px-4 py-2 border-t border-base-300">${cell}</td>`).join('')}
|
||||||
</tr>
|
</tr>
|
||||||
`).join('')}
|
`).join('')}
|
||||||
|
${rowsToShow < totalRows ? `
|
||||||
|
<tr>
|
||||||
|
<td colspan="${headers.length}" class="px-4 py-3 text-base-content/70 bg-base-200/30 border-t border-base-300">
|
||||||
|
... ${totalRows - rowsToShow} more rows
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
` : ''}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}, []);
|
}, [visibleLines]);
|
||||||
|
|
||||||
const highlightCode = useCallback((code: string, language: string) => {
|
const highlightCode = useCallback((code: string, language: string) => {
|
||||||
// Skip highlighting for CSV
|
// Skip highlighting for CSV
|
||||||
|
@ -246,10 +263,9 @@ export default function FilePreview({ url: initialUrl = '', filename: initialFil
|
||||||
return renderCSVTable(code);
|
return renderCSVTable(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlighted = highlightCode(code, language);
|
|
||||||
const lines = code.split('\n');
|
const lines = code.split('\n');
|
||||||
const totalLines = lines.length;
|
const totalLines = lines.length;
|
||||||
const linesToShow = isExpanded ? totalLines : Math.min(INITIAL_LINES_TO_SHOW, totalLines);
|
const linesToShow = Math.min(visibleLines, totalLines);
|
||||||
|
|
||||||
let formattedCode = lines
|
let formattedCode = lines
|
||||||
.slice(0, linesToShow)
|
.slice(0, linesToShow)
|
||||||
|
@ -263,15 +279,23 @@ export default function FilePreview({ url: initialUrl = '', filename: initialFil
|
||||||
})
|
})
|
||||||
.join('');
|
.join('');
|
||||||
|
|
||||||
if (!isExpanded && totalLines > INITIAL_LINES_TO_SHOW) {
|
if (linesToShow < totalLines) {
|
||||||
formattedCode += `<div class="table-row ">
|
formattedCode += `<div class="table-row ">
|
||||||
<div class="table-cell"></div>
|
<div class="table-cell"></div>
|
||||||
<div class="table-cell pl-4 pt-2 text-base-content/70">... ${totalLines - INITIAL_LINES_TO_SHOW} more lines</div>
|
<div class="table-cell pl-4 pt-2 text-base-content/70">... ${totalLines - linesToShow} more lines</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return formattedCode;
|
return formattedCode;
|
||||||
}, [highlightCode, isExpanded, renderCSVTable]);
|
}, [highlightCode, visibleLines, renderCSVTable]);
|
||||||
|
|
||||||
|
const handleShowMore = useCallback(() => {
|
||||||
|
setVisibleLines(prev => Math.min(prev + CHUNK_SIZE, content?.split('\n').length || 0));
|
||||||
|
}, [content]);
|
||||||
|
|
||||||
|
const handleShowLess = useCallback(() => {
|
||||||
|
setVisibleLines(INITIAL_LINES_TO_SHOW);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="file-preview-container space-y-4">
|
<div className="file-preview-container space-y-4">
|
||||||
|
@ -378,12 +402,20 @@ export default function FilePreview({ url: initialUrl = '', filename: initialFil
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{content.split('\n').length > INITIAL_LINES_TO_SHOW && (
|
{content && content.split('\n').length > visibleLines && (
|
||||||
<button
|
<button
|
||||||
onClick={() => setIsExpanded(!isExpanded)}
|
onClick={handleShowMore}
|
||||||
className="btn btn-sm btn-ghost"
|
className="btn btn-sm btn-ghost"
|
||||||
>
|
>
|
||||||
{isExpanded ? 'Show Less' : 'Show More'}
|
Show More
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
{visibleLines > INITIAL_LINES_TO_SHOW && (
|
||||||
|
<button
|
||||||
|
onClick={handleShowLess}
|
||||||
|
className="btn btn-sm btn-ghost"
|
||||||
|
>
|
||||||
|
Show Less
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
|
@ -397,10 +429,10 @@ export default function FilePreview({ url: initialUrl = '', filename: initialFil
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="overflow-x-auto max-h-[600px] bg-base-200 ">
|
<div className="overflow-x-auto max-h-[600px] bg-base-200">
|
||||||
<div className="p-1">
|
<div className={`p-1 ${filename.toLowerCase().endsWith('.csv') ? 'p-4' : ''}`}>
|
||||||
<div
|
<div
|
||||||
className="hljs table w-full font-mono text-sm rounded-lg py-4 px-2"
|
className={filename.toLowerCase().endsWith('.csv') ? '' : 'hljs table w-full font-mono text-sm rounded-lg py-4 px-2'}
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: formatCodeWithLineNumbers(content, getLanguageFromFilename(filename))
|
__html: formatCodeWithLineNumbers(content, getLanguageFromFilename(filename))
|
||||||
}}
|
}}
|
||||||
|
|
Loading…
Reference in a new issue