WebViewer Version:
Do you have an issue with a specific file(s)?
Can you reproduce using one of our samples or online demos?
Are you using the WebViewer server?
Does the issue only happen on certain browsers?
Is your issue related to a front-end framework?
Is your issue related to annotations?
Please give a brief summary of your issue:
(Think of this as an email subject)
Please describe your issue and provide steps to reproduce it:
(The more descriptive your answer, the faster we are able to help you)
The WebViewer Document Comparison Tool has the bottom of the change list being cut off. I have tried every type of positioning to change it.
Please provide a link to a minimal sample where the issue is reproducible:
import {
Button,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalOverlay,
} from '@chakra-ui/react';
import { useTaskDocumentViewerContext } from '@/app/context/TaskDocumentContext';
import DiffViewer from '@/app/components/webviewer/DiffViewer';
import { memo } from 'react';
const DocumentComparisonModal = () => {
const {
documentComparison1,
documentComparison2,
setIsDocumentComparisonModalOpen,
isDocumentComparisonModalOpen,
} = useTaskDocumentViewerContext();
const handleClose = () => {
setIsDocumentComparisonModalOpen(false);
};
return (
<Modal
isCentered
isOpen={isDocumentComparisonModalOpen}
onClose={handleClose}
size="7xl"
>
<ModalOverlay />
<ModalContent>
<ModalCloseButton />
<ModalBody>
<DiffViewer
documentComparison1={documentComparison1}
documentComparison2={documentComparison2}
/>
</ModalBody>
<ModalFooter>
<Button onClick={handleClose}>Close</Button>
</ModalFooter>
</ModalContent>
</Modal>
);
};
export default memo(DocumentComparisonModal);
import React, {
useEffect,
useRef,
useState,
useCallback,
useMemo,
} from 'react';
import WebViewer, { Core } from '@pdftron/webviewer';
import { rootApiUrl } from '@/config/root_api_url';
import { pdfUrlFromId } from '../file_viewer/FileViewerHelpers';
import useFileBlobDirect from '../../hooks/useFileBlobDirect';
import { DocumentComparison } from '../../context/TaskDocumentContext';
interface DiffViewerProps {
documentComparison1: DocumentComparison | null;
documentComparison2: DocumentComparison | null;
}
const DiffViewer = ({
documentComparison1,
documentComparison2,
}: DiffViewerProps) => {
const viewerRef = useRef<HTMLDivElement>(null);
const [documentViewers, setDocumentViewers] = useState<Core.DocumentViewer[]>(
[],
);
const doc1BlobFromHook = useFileBlobDirect({
fileUrl: pdfUrlFromId('main_documents', documentComparison1?.id ?? ''),
rootUrl: rootApiUrl,
});
const doc2BlobFromHook = useFileBlobDirect({
fileUrl: pdfUrlFromId('main_documents', documentComparison2?.id ?? ''),
rootUrl: rootApiUrl,
});
const doc1Blob = useMemo(
() =>
documentComparison1?.blob
? { blob: documentComparison1.blob }
: doc1BlobFromHook,
[documentComparison1?.blob, doc1BlobFromHook],
);
const doc2Blob = useMemo(
() =>
documentComparison2?.blob
? { blob: documentComparison2.blob }
: doc2BlobFromHook,
[documentComparison2?.blob, doc2BlobFromHook],
);
const initializeDiffViewer = useCallback(() => {
if (!viewerRef.current) return;
WebViewer(
{
path: '/lib',
licenseKey: process.env.NEXT_PUBLIC_APRYSE_SDK_KEY,
fullAPI: true,
viewerRef.current,
).then(async (instance) => {
const { UI, Core } = instance;
const { Annotations } = Core;
const { Color } = Annotations;
UI.enterMultiViewerMode();
UI.addEventListener(UI.Events.MULTI_VIEWER_READY, () => {
const [docViewer1, docViewer2] = Core.getDocumentViewers();
setDocumentViewers([docViewer1, docViewer2]);
const startCompare = async () => {
const doc1 = docViewer1.getDocument();
const doc2 = docViewer2.getDocument();
if (doc1 && doc2) {
UI.enableMultiViewerSync();
const beforeColor = new Color(21, 205, 131, 0.4);
const afterColor = new Color(255, 73, 73, 0.4);
const options = { beforeColor, afterColor };
await docViewer1.startSemanticDiff(docViewer2, options);
}
};
docViewer1.addEventListener('documentLoaded', startCompare);
docViewer2.addEventListener('documentLoaded', startCompare);
UI.enableFeatures([UI.Feature.ComparePages]);
UI.openElements(['comparePanel']);
});
});
}, []);
useEffect(() => {
initializeDiffViewer();
}, [initializeDiffViewer]);
useEffect(() => {
if (
documentViewers &&
documentViewers.length === 2 &&
doc1Blob?.blob &&
doc2Blob?.blob
) {
documentViewers[0].loadDocument(doc1Blob.blob, {
filename: documentComparison1?.fileName ?? '',
extension: 'pdf',
});
documentViewers[1].loadDocument(doc2Blob.blob, {
filename: documentComparison2?.fileName ?? '',
extension: 'pdf',
});
}
}, [
documentViewers,
doc1Blob,
doc2Blob,
documentComparison1?.fileName,
documentComparison2?.fileName,
]);
return <div ref={viewerRef} style={{ height: '90vh', width: '95vw' }} />;
};
export default DiffViewer;