mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-26 14:19:24 +00:00
Full width page editor, reduced batch size for thumbnail generation
This commit is contained in:
parent
76aec0a39e
commit
1eb89a22c2
@ -1,4 +1,4 @@
|
|||||||
import React, { useRef, useEffect } from 'react';
|
import React, { useRef, useEffect, useState, useCallback } from 'react';
|
||||||
import { Box } from '@mantine/core';
|
import { Box } from '@mantine/core';
|
||||||
import { useVirtualizer } from '@tanstack/react-virtual';
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||||
import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
import { dropTargetForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
||||||
@ -31,15 +31,56 @@ const DragDropGrid = <T extends DragDropItem>({
|
|||||||
const itemRefs = useRef<Map<string, HTMLDivElement>>(new Map());
|
const itemRefs = useRef<Map<string, HTMLDivElement>>(new Map());
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
// Responsive grid configuration
|
||||||
// Grid configuration
|
const [itemsPerRow, setItemsPerRow] = useState(4);
|
||||||
const ITEMS_PER_ROW = 4;
|
const ITEM_WIDTH = 320; // 20rem (page width)
|
||||||
|
const ITEM_GAP = 24; // 1.5rem gap between items
|
||||||
const ITEM_HEIGHT = 340; // 20rem + gap
|
const ITEM_HEIGHT = 340; // 20rem + gap
|
||||||
const OVERSCAN = items.length > 1000 ? 8 : 4; // More overscan for large documents
|
const OVERSCAN = items.length > 1000 ? 8 : 4; // More overscan for large documents
|
||||||
|
|
||||||
|
// Calculate items per row based on container width
|
||||||
|
const calculateItemsPerRow = useCallback(() => {
|
||||||
|
if (!containerRef.current) return 4; // Default fallback
|
||||||
|
|
||||||
|
const containerWidth = containerRef.current.offsetWidth;
|
||||||
|
if (containerWidth === 0) return 4; // Container not measured yet
|
||||||
|
|
||||||
|
// Calculate how many items fit: (width - gap) / (itemWidth + gap)
|
||||||
|
const availableWidth = containerWidth - ITEM_GAP; // Account for first gap
|
||||||
|
const itemWithGap = ITEM_WIDTH + ITEM_GAP;
|
||||||
|
const calculated = Math.floor(availableWidth / itemWithGap);
|
||||||
|
|
||||||
|
return Math.max(1, calculated); // At least 1 item per row
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Update items per row when container resizes
|
||||||
|
useEffect(() => {
|
||||||
|
const updateLayout = () => {
|
||||||
|
const newItemsPerRow = calculateItemsPerRow();
|
||||||
|
setItemsPerRow(newItemsPerRow);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initial calculation
|
||||||
|
updateLayout();
|
||||||
|
|
||||||
|
// Listen for window resize
|
||||||
|
window.addEventListener('resize', updateLayout);
|
||||||
|
|
||||||
|
// Use ResizeObserver for container size changes
|
||||||
|
const resizeObserver = new ResizeObserver(updateLayout);
|
||||||
|
if (containerRef.current) {
|
||||||
|
resizeObserver.observe(containerRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('resize', updateLayout);
|
||||||
|
resizeObserver.disconnect();
|
||||||
|
};
|
||||||
|
}, [calculateItemsPerRow]);
|
||||||
|
|
||||||
// Virtualization with react-virtual library
|
// Virtualization with react-virtual library
|
||||||
const rowVirtualizer = useVirtualizer({
|
const rowVirtualizer = useVirtualizer({
|
||||||
count: Math.ceil(items.length / ITEMS_PER_ROW),
|
count: Math.ceil(items.length / itemsPerRow),
|
||||||
getScrollElement: () => containerRef.current?.closest('[data-scrolling-container]') as Element,
|
getScrollElement: () => containerRef.current?.closest('[data-scrolling-container]') as Element,
|
||||||
estimateSize: () => ITEM_HEIGHT,
|
estimateSize: () => ITEM_HEIGHT,
|
||||||
overscan: OVERSCAN,
|
overscan: OVERSCAN,
|
||||||
@ -64,8 +105,8 @@ const DragDropGrid = <T extends DragDropItem>({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
|
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
|
||||||
const startIndex = virtualRow.index * ITEMS_PER_ROW;
|
const startIndex = virtualRow.index * itemsPerRow;
|
||||||
const endIndex = Math.min(startIndex + ITEMS_PER_ROW, items.length);
|
const endIndex = Math.min(startIndex + itemsPerRow, items.length);
|
||||||
const rowItems = items.slice(startIndex, endIndex);
|
const rowItems = items.slice(startIndex, endIndex);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1179,7 +1179,7 @@ const PageEditor = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{showLoading && (
|
{showLoading && (
|
||||||
<Box p="md" pt="xl">
|
<Box p={0}>
|
||||||
<SkeletonLoader type="controls" />
|
<SkeletonLoader type="controls" />
|
||||||
|
|
||||||
|
|
||||||
@ -1215,7 +1215,7 @@ const PageEditor = ({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{displayDocument && (
|
{displayDocument && (
|
||||||
<Box p="md" pt="xl">
|
<Box p={0}>
|
||||||
{/* Enhanced Processing Status */}
|
{/* Enhanced Processing Status */}
|
||||||
{globalProcessing && processingProgress < 100 && (
|
{globalProcessing && processingProgress < 100 && (
|
||||||
<Box mb="md" p="sm" style={{ backgroundColor: 'var(--mantine-color-blue-0)', borderRadius: 8 }}>
|
<Box mb="md" p="sm" style={{ backgroundColor: 'var(--mantine-color-blue-0)', borderRadius: 8 }}>
|
||||||
|
@ -19,7 +19,7 @@ let batchTimer: number | null = null;
|
|||||||
const activeRequests = new Map<string, Promise<string | null>>();
|
const activeRequests = new Map<string, Promise<string | null>>();
|
||||||
|
|
||||||
// Batch processing configuration
|
// Batch processing configuration
|
||||||
const BATCH_SIZE = 50; // Process thumbnails in batches of 50
|
const BATCH_SIZE = 20; // Process thumbnails in batches of 20 for better UI responsiveness
|
||||||
const BATCH_DELAY = 100; // Wait 100ms to collect requests before processing
|
const BATCH_DELAY = 100; // Wait 100ms to collect requests before processing
|
||||||
const PRIORITY_BATCH_DELAY = 50; // Faster processing for the first batch (visible pages)
|
const PRIORITY_BATCH_DELAY = 50; // Faster processing for the first batch (visible pages)
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ export class ThumbnailGenerationService {
|
|||||||
|
|
||||||
const allResults: ThumbnailResult[] = [];
|
const allResults: ThumbnailResult[] = [];
|
||||||
let completed = 0;
|
let completed = 0;
|
||||||
const batchSize = 5; // Small batches for UI responsiveness
|
const batchSize = 3; // Smaller batches for better UI responsiveness
|
||||||
|
|
||||||
// Process pages in small batches
|
// Process pages in small batches
|
||||||
for (let i = 0; i < pageNumbers.length; i += batchSize) {
|
for (let i = 0; i < pageNumbers.length; i += batchSize) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user