Refine external signing flow and mobile PDF placement
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState, useRef, useCallback } from 'react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { Document, Page, pdfjs } from 'react-pdf';
|
||||
import 'react-pdf/dist/Page/AnnotationLayer.css';
|
||||
import 'react-pdf/dist/Page/TextLayer.css';
|
||||
@@ -31,10 +31,33 @@ export default function PdfSignaturePlacer({
|
||||
const [numPages, setNumPages] = useState(null);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [sigBox, setSigBox] = useState(null); // { x, y } in container px
|
||||
const stageRef = useRef(null);
|
||||
const containerRef = useRef(null);
|
||||
const [pageSize, setPageSize] = useState(null); // rendered px size
|
||||
const [pageRenderWidth, setPageRenderWidth] = useState(600);
|
||||
const signatureWidth = getSignatureWidth(signatureStyle, signerName);
|
||||
|
||||
useEffect(() => {
|
||||
const stage = stageRef.current;
|
||||
if (!stage) return undefined;
|
||||
|
||||
const updateWidth = () => {
|
||||
const nextWidth = Math.max(280, Math.min(600, Math.floor(stage.clientWidth || 600)));
|
||||
setPageRenderWidth(nextWidth);
|
||||
};
|
||||
|
||||
updateWidth();
|
||||
|
||||
if (typeof ResizeObserver === 'undefined') {
|
||||
window.addEventListener('resize', updateWidth);
|
||||
return () => window.removeEventListener('resize', updateWidth);
|
||||
}
|
||||
|
||||
const observer = new ResizeObserver(() => updateWidth());
|
||||
observer.observe(stage);
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
const getCanvasMetrics = () => {
|
||||
const container = containerRef.current;
|
||||
const canvas = container?.querySelector('.react-pdf__Page__canvas');
|
||||
@@ -59,12 +82,12 @@ export default function PdfSignaturePlacer({
|
||||
setPageSize({ width: page.width, height: page.height });
|
||||
};
|
||||
|
||||
const handleContainerClick = (e) => {
|
||||
const handlePointerDown = (event) => {
|
||||
const metrics = getCanvasMetrics();
|
||||
if (!metrics) return;
|
||||
|
||||
const x = e.clientX - metrics.canvasRect.left;
|
||||
const y = e.clientY - metrics.canvasRect.top;
|
||||
const x = event.clientX - metrics.canvasRect.left;
|
||||
const y = event.clientY - metrics.canvasRect.top;
|
||||
const clampedX = Math.min(Math.max(x, 0), metrics.width - signatureWidth);
|
||||
const clampedY = Math.min(Math.max(y, 0), metrics.height - SIG_H);
|
||||
|
||||
@@ -177,35 +200,37 @@ export default function PdfSignaturePlacer({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="pdf-placer-canvas"
|
||||
onClick={handleContainerClick}
|
||||
style={{ cursor: 'crosshair', position: 'relative', display: 'inline-block' }}
|
||||
>
|
||||
<Document file={pdfBlob} onLoadSuccess={handleDocLoad}>
|
||||
<Page
|
||||
pageNumber={currentPage}
|
||||
width={600}
|
||||
onLoadSuccess={(p) => setPageSize({
|
||||
width: p.width, height: p.height,
|
||||
pdfWidth: p.originalWidth, pdfHeight: p.originalHeight,
|
||||
})}
|
||||
/>
|
||||
</Document>
|
||||
<div ref={stageRef} className="pdf-placer-stage">
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="pdf-placer-canvas"
|
||||
onPointerDown={handlePointerDown}
|
||||
style={{ cursor: 'crosshair', position: 'relative', display: 'inline-block' }}
|
||||
>
|
||||
<Document file={pdfBlob} onLoadSuccess={handleDocLoad}>
|
||||
<Page
|
||||
pageNumber={currentPage}
|
||||
width={pageRenderWidth}
|
||||
onLoadSuccess={(p) => setPageSize({
|
||||
width: p.width, height: p.height,
|
||||
pdfWidth: p.originalWidth, pdfHeight: p.originalHeight,
|
||||
})}
|
||||
/>
|
||||
</Document>
|
||||
|
||||
{sigBox && (
|
||||
<div
|
||||
className={`sig-preview-box sig-preview-box--${signatureStyle}`}
|
||||
data-background={signatureStyle === 'qr' ? qrBackground : undefined}
|
||||
data-border={signatureStyle === 'qr' ? qrBorder : undefined}
|
||||
style={{ left: sigBox.x, top: sigBox.y, width: signatureWidth, height: SIG_H }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{signatureStyle === 'classic' && <div className="sig-preview-bar" />}
|
||||
{renderPreview()}
|
||||
</div>
|
||||
)}
|
||||
{sigBox && (
|
||||
<div
|
||||
className={`sig-preview-box sig-preview-box--${signatureStyle}`}
|
||||
data-background={signatureStyle === 'qr' ? qrBackground : undefined}
|
||||
data-border={signatureStyle === 'qr' ? qrBorder : undefined}
|
||||
style={{ left: sigBox.x, top: sigBox.y, width: signatureWidth, height: SIG_H }}
|
||||
onPointerDown={(e) => e.stopPropagation()}
|
||||
>
|
||||
{signatureStyle === 'classic' && <div className="sig-preview-bar" />}
|
||||
{renderPreview()}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{sigBox && (
|
||||
|
||||
Reference in New Issue
Block a user