pdf layer toggle (#6028)

This commit is contained in:
Anthony Stirling
2026-03-30 17:04:53 +01:00
committed by GitHub
parent cdc288e78d
commit a06b6a4bac
12 changed files with 924 additions and 147 deletions
@@ -10,6 +10,7 @@ import { PdfViewerToolbar } from '@app/components/viewer/PdfViewerToolbar';
import { ThumbnailSidebar } from '@app/components/viewer/ThumbnailSidebar';
import { BookmarkSidebar } from '@app/components/viewer/BookmarkSidebar';
import { AttachmentSidebar } from '@app/components/viewer/AttachmentSidebar';
import { LayerSidebar } from '@app/components/viewer/LayerSidebar';
import { useNavigationGuard, useNavigationState } from '@app/contexts/NavigationContext';
import { useSignature } from '@app/contexts/SignatureContext';
import { useRedaction } from '@app/contexts/RedactionContext';
@@ -125,6 +126,8 @@ const EmbedPdfViewerContent = ({
toggleThumbnailSidebar,
isBookmarkSidebarVisible,
isAttachmentSidebarVisible,
isLayerSidebarVisible,
setHasLayers,
isCommentsSidebarVisible,
isSearchInterfaceVisible,
searchInterfaceActions,
@@ -700,6 +703,46 @@ const EmbedPdfViewerContent = ({
return () => window.removeEventListener('formfill:apply', handler);
}, [handleFormApply]);
// Apply layer visibility changes - reload the modified PDF into the viewer
const layerApplyInProgressRef = useRef(false);
const handleLayerApply = useCallback(async (modifiedBlob: Blob) => {
if (layerApplyInProgressRef.current) return;
if (!currentFile || activeFileIds.length === 0) return;
layerApplyInProgressRef.current = true;
try {
const pageToRestore = lastKnownScrollPageRef.current;
const currentRotation = rotationState.rotation ?? 0;
const filename = currentFile.name || 'document.pdf';
const file = new File([modifiedBlob], filename, { type: 'application/pdf' });
const currentFileId = activeFiles[activeFileIndex]?.fileId;
if (!currentFileId) throw new Error('Current file ID not found');
const parentStub = selectors.getStirlingFileStub(currentFileId);
if (!parentStub) throw new Error('Parent stub not found');
const { stirlingFiles, stubs } = await createStirlingFilesAndStubs([file], parentStub, 'multiTool');
pendingScrollRestoreRef.current = pageToRestore;
scrollRestoreAttemptsRef.current = 0;
pendingRotationRestoreRef.current = currentRotation;
rotationRestoreAttemptsRef.current = 0;
const newFileId = stubs[0]?.id;
if (newFileId) {
pendingFileIdRef.current = newFileId;
}
await actions.consumeFiles([currentFileId], stirlingFiles, stubs);
} catch (error) {
console.error('[Viewer] Apply layer changes failed:', error);
} finally {
layerApplyInProgressRef.current = false;
}
}, [currentFile, activeFiles, activeFileIndex, actions, selectors, activeFileIds.length, rotationState.rotation]);
// Discard pending redactions but save already-applied ones
// This is called when user clicks "Discard & Leave" - we want to:
// 1. NOT commit pending redaction marks (they get discarded)
@@ -919,6 +962,7 @@ const EmbedPdfViewerContent = ({
(isThumbnailSidebarVisible ? sidebarWidthRem : 0) +
(isBookmarkSidebarVisible ? sidebarWidthRem : 0) +
(isAttachmentSidebarVisible ? sidebarWidthRem : 0) +
(isLayerSidebarVisible ? sidebarWidthRem : 0) +
(isCommentsSidebarVisible ? commentsSidebarWidthRem : 0);
return (
@@ -987,7 +1031,7 @@ const EmbedPdfViewerContent = ({
redactionTrackerRef={redactionTrackerRef as React.RefObject<RedactionPendingTrackerAPI>}
fileId={currentFileId}
isCommentsSidebarVisible={isCommentsSidebarVisible}
commentsSidebarRightOffset={`${(isThumbnailSidebarVisible ? sidebarWidthRem : 0) + (isBookmarkSidebarVisible ? sidebarWidthRem : 0) + (isAttachmentSidebarVisible ? sidebarWidthRem : 0)}rem`}
commentsSidebarRightOffset={`${(isThumbnailSidebarVisible ? sidebarWidthRem : 0) + (isBookmarkSidebarVisible ? sidebarWidthRem : 0) + (isAttachmentSidebarVisible ? sidebarWidthRem : 0) + (isLayerSidebarVisible ? sidebarWidthRem : 0)}rem`}
onSignatureAdded={() => {
// Handle signature added - for debugging, enable console logs as needed
// Future: Handle signature completion
@@ -1057,6 +1101,18 @@ const EmbedPdfViewerContent = ({
documentCacheKey={bookmarkCacheKey}
preloadCacheKeys={allBookmarkCacheKeys}
/>
<LayerSidebar
visible={isLayerSidebarVisible}
rightOffset={
(isThumbnailSidebarVisible ? sidebarWidthRem : 0) +
(isBookmarkSidebarVisible ? sidebarWidthRem : 0) +
(isAttachmentSidebarVisible ? sidebarWidthRem : 0)
}
file={effectiveFile?.file ?? null}
documentCacheKey={bookmarkCacheKey}
onApplyLayers={handleLayerApply}
onLayersDetected={setHasLayers}
/>
{/* Navigation Warning Modal */}
{!previewFile && (