Fixed file reordering placeholder

This commit is contained in:
Reece 2025-10-25 13:06:10 +01:00
parent aaae81c68e
commit fbe2dc2958
4 changed files with 53 additions and 25 deletions

View File

@ -511,7 +511,7 @@ const DragDropGrid = <T extends DragDropItem>({
const sourcePageNumber = activeData.pageNumber;
const overData = over?.data.current;
const targetIndex = resolveTargetIndex(
let targetIndex = resolveTargetIndex(
hoveredItemId,
finalDropSide,
visibleItems,
@ -521,6 +521,8 @@ const DragDropGrid = <T extends DragDropItem>({
);
if (targetIndex === null) return;
if (targetIndex < 0) targetIndex = 0;
if (targetIndex > items.length) targetIndex = items.length;
// Check if this page is box-selected
const isBoxSelected = boxSelectedPageIds.includes(active.id as string);

View File

@ -200,6 +200,7 @@ const PageEditor = ({
break;
}
}
if (!hasAdditions && !hasRemovals) return;
setEditedDocument(prev => {
@ -213,22 +214,18 @@ const PageEditor = ({
// Insert new pages while preserving current interleaving
if (hasAdditions) {
// Insert file-by-file at the correct anchors
for (const [, additions] of newByFile) {
// Check if any page has insertAfterPageId (specific insertion point)
const hasSpecificInsertPoint = additions.some(p => (p as any).insertAfterPageId);
// Rebuild pages array respecting the order from mergedPdfDocument
// This handles file selection/deselection correctly (placeholder positioning)
const mergedOrder = mergedPdfDocument.pages.map(p => p.id);
const pageById = new Map(pages.map(p => [p.id, p]));
if (hasSpecificInsertPoint) {
// Insert after specific page (ignores file order)
const insertAfterPageId = (additions[0] as any).insertAfterPageId;
const insertAfterIndex = pages.findIndex(p => p.id === insertAfterPageId);
const insertAt = insertAfterIndex >= 0 ? insertAfterIndex + 1 : pages.length;
pages.splice(insertAt, 0, ...additions);
} else {
// Normal add: append to end
pages.push(...additions);
}
// Add new pages to the map
for (const [, additions] of newByFile) {
additions.forEach(p => pageById.set(p.id, p));
}
// Rebuild in mergedPdfDocument order
pages = mergedOrder.map(id => pageById.get(id)!).filter(Boolean);
}
// Renumber without reordering
@ -350,17 +347,28 @@ const PageEditor = ({
}, [displayDocument, setSelectedPageIds, setSelectionMode]);
// Automatically include newly added pages in the current selection
const previousPageIdsRef = useRef<Set<string>>(new Set());
useEffect(() => {
if (!displayDocument || displayDocument.pages.length === 0) return;
if (!displayDocument || displayDocument.pages.length === 0) {
previousPageIdsRef.current = new Set();
return;
}
const currentSelection = new Set(selectedPageIds);
const newlyAddedPageIds = displayDocument.pages
.map(page => page.id)
.filter(pageId => !currentSelection.has(pageId));
const currentIds = new Set(displayDocument.pages.map(page => page.id));
const newlyAddedPageIds: string[] = [];
currentIds.forEach(id => {
if (!previousPageIdsRef.current.has(id)) {
newlyAddedPageIds.push(id);
}
});
if (newlyAddedPageIds.length > 0) {
setSelectedPageIds([...selectedPageIds, ...newlyAddedPageIds]);
const next = new Set(selectedPageIds);
newlyAddedPageIds.forEach(id => next.add(id));
setSelectedPageIds(Array.from(next));
}
previousPageIdsRef.current = currentIds;
}, [displayDocument, selectedPageIds, setSelectedPageIds]);
// DOM-first command handlers

View File

@ -445,7 +445,7 @@ const PageThumbnail: React.FC<PageThumbnailProps> = ({
backgroundColor: 'white',
border: '1px solid #e9ecef',
borderRadius: 2
}}></div>
}} />
</div>
) : thumbnailUrl ? (
<img

View File

@ -142,10 +142,21 @@ export function usePageDocument(): PageDocumentHook {
return filePages;
};
// Collect all pages from original files (without renumbering yet)
// Collect all pages from original files, respecting their previous positions
const selectedFileIdsSet = new Set(state.ui.selectedFileIds);
// Sort original files by their position in fileOrder (so placeholders stay in correct spot)
// Use fileOrder as source of truth since it persists across page editor sessions
const fileOrderMap = new Map(allFileIds.map((id, index) => [id, index]));
const sortedOriginalFileIds = [...originalFileIds].sort((a, b) => {
const posA = fileOrderMap.get(a) ?? Number.MAX_SAFE_INTEGER;
const posB = fileOrderMap.get(b) ?? Number.MAX_SAFE_INTEGER;
return posA - posB;
});
const originalFilePages: PDFPage[] = [];
originalFileIds.forEach(fileId => {
sortedOriginalFileIds.forEach(fileId => {
const isSelected = selectedFileIdsSet.has(fileId);
const filePages = createPagesFromFile(fileId, 1, isSelected); // Temporary numbering
originalFilePages.push(...filePages);
@ -184,6 +195,13 @@ export function usePageDocument(): PageDocumentHook {
return null;
}
// Pages are already in the correct order from the sorted assembly above
// Just ensure page numbers are sequential
pages = pages.map((page, index) => ({
...page,
pageNumber: index + 1,
}));
const mergedDoc: PDFDocument = {
id: activeFileIds.join('-'),
name,
@ -193,7 +211,7 @@ export function usePageDocument(): PageDocumentHook {
};
return mergedDoc;
}, [activeFileIds, primaryFileId, primaryStirlingFileStub, processedFilePages, processedFileTotalPages, selectors, activeFilesSignature, selectedFileIdsKey, state.ui.selectedFileIds]);
}, [activeFileIds, primaryFileId, primaryStirlingFileStub, processedFilePages, processedFileTotalPages, selectors, activeFilesSignature, selectedFileIdsKey, state.ui.selectedFileIds, allFileIds]);
// Large document detection for smart loading
const isVeryLargeDocument = useMemo(() => {