mirror of
https://github.com/documenso/documenso.git
synced 2025-11-20 11:41:44 +10:00
chore: remove unused stuff
This commit is contained in:
@ -11,10 +11,6 @@ import type { TLocalField } from '@documenso/lib/client-only/hooks/use-editor-fi
|
|||||||
import { usePageRenderer } from '@documenso/lib/client-only/hooks/use-page-renderer';
|
import { usePageRenderer } from '@documenso/lib/client-only/hooks/use-page-renderer';
|
||||||
import { useCurrentEnvelopeEditor } from '@documenso/lib/client-only/providers/envelope-editor-provider';
|
import { useCurrentEnvelopeEditor } from '@documenso/lib/client-only/providers/envelope-editor-provider';
|
||||||
import { useCurrentEnvelopeRender } from '@documenso/lib/client-only/providers/envelope-render-provider';
|
import { useCurrentEnvelopeRender } from '@documenso/lib/client-only/providers/envelope-render-provider';
|
||||||
import {
|
|
||||||
registerPageCanvas,
|
|
||||||
unregisterPageCanvas,
|
|
||||||
} from '@documenso/lib/client-only/utils/page-canvas-registry';
|
|
||||||
import { FIELD_META_DEFAULT_VALUES } from '@documenso/lib/types/field-meta';
|
import { FIELD_META_DEFAULT_VALUES } from '@documenso/lib/types/field-meta';
|
||||||
import {
|
import {
|
||||||
MIN_FIELD_HEIGHT_PX,
|
MIN_FIELD_HEIGHT_PX,
|
||||||
@ -62,15 +58,6 @@ export default function EnvelopeEditorFieldsPageRenderer() {
|
|||||||
[editorFields.localFields, pageContext.pageNumber],
|
[editorFields.localFields, pageContext.pageNumber],
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* Cleanup: Unregister canvas when component unmounts
|
|
||||||
*/
|
|
||||||
useEffect(() => {
|
|
||||||
return () => {
|
|
||||||
unregisterPageCanvas(pageContext.pageNumber);
|
|
||||||
};
|
|
||||||
}, [pageContext.pageNumber]);
|
|
||||||
|
|
||||||
const handleResizeOrMove = (event: KonvaEventObject<Event>) => {
|
const handleResizeOrMove = (event: KonvaEventObject<Event>) => {
|
||||||
const { current: container } = canvasElement;
|
const { current: container } = canvasElement;
|
||||||
|
|
||||||
@ -231,15 +218,6 @@ export default function EnvelopeEditorFieldsPageRenderer() {
|
|||||||
currentStage.on('transformend', () => setIsFieldChanging(false));
|
currentStage.on('transformend', () => setIsFieldChanging(false));
|
||||||
|
|
||||||
currentPageLayer.batchDraw();
|
currentPageLayer.batchDraw();
|
||||||
|
|
||||||
// Register this page's canvas references now that everything is initialized
|
|
||||||
if (canvasElement.current && currentStage) {
|
|
||||||
registerPageCanvas({
|
|
||||||
pageNumber: pageContext.pageNumber,
|
|
||||||
pdfCanvas: canvasElement.current,
|
|
||||||
konvaStage: currentStage,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import { match } from 'ts-pattern';
|
|||||||
|
|
||||||
import { useCurrentEnvelopeEditor } from '@documenso/lib/client-only/providers/envelope-editor-provider';
|
import { useCurrentEnvelopeEditor } from '@documenso/lib/client-only/providers/envelope-editor-provider';
|
||||||
import { useCurrentEnvelopeRender } from '@documenso/lib/client-only/providers/envelope-render-provider';
|
import { useCurrentEnvelopeRender } from '@documenso/lib/client-only/providers/envelope-render-provider';
|
||||||
import { getPageCanvasRefs } from '@documenso/lib/client-only/utils/page-canvas-registry';
|
|
||||||
import type { TDetectedFormField } from '@documenso/lib/types/document-analysis';
|
import type { TDetectedFormField } from '@documenso/lib/types/document-analysis';
|
||||||
import type {
|
import type {
|
||||||
TCheckboxFieldMeta,
|
TCheckboxFieldMeta,
|
||||||
@ -54,63 +53,6 @@ const EnvelopeEditorFieldsPageRenderer = lazy(
|
|||||||
async () => import('./envelope-editor-fields-page-renderer'),
|
async () => import('./envelope-editor-fields-page-renderer'),
|
||||||
);
|
);
|
||||||
|
|
||||||
const enforceMinimumFieldDimensions = (params: {
|
|
||||||
positionX: number;
|
|
||||||
positionY: number;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
pageWidth: number;
|
|
||||||
pageHeight: number;
|
|
||||||
}): {
|
|
||||||
positionX: number;
|
|
||||||
positionY: number;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
} => {
|
|
||||||
const MIN_HEIGHT_PX = 30;
|
|
||||||
const MIN_WIDTH_PX = 36;
|
|
||||||
|
|
||||||
const widthPx = (params.width / 100) * params.pageWidth;
|
|
||||||
const heightPx = (params.height / 100) * params.pageHeight;
|
|
||||||
|
|
||||||
let adjustedWidth = params.width;
|
|
||||||
let adjustedHeight = params.height;
|
|
||||||
let adjustedPositionX = params.positionX;
|
|
||||||
let adjustedPositionY = params.positionY;
|
|
||||||
|
|
||||||
if (widthPx < MIN_WIDTH_PX) {
|
|
||||||
const centerXPx = (params.positionX / 100) * params.pageWidth + widthPx / 2;
|
|
||||||
adjustedWidth = (MIN_WIDTH_PX / params.pageWidth) * 100;
|
|
||||||
adjustedPositionX = ((centerXPx - MIN_WIDTH_PX / 2) / params.pageWidth) * 100;
|
|
||||||
|
|
||||||
if (adjustedPositionX < 0) {
|
|
||||||
adjustedPositionX = 0;
|
|
||||||
} else if (adjustedPositionX + adjustedWidth > 100) {
|
|
||||||
adjustedPositionX = 100 - adjustedWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (heightPx < MIN_HEIGHT_PX) {
|
|
||||||
const centerYPx = (params.positionY / 100) * params.pageHeight + heightPx / 2;
|
|
||||||
adjustedHeight = (MIN_HEIGHT_PX / params.pageHeight) * 100;
|
|
||||||
|
|
||||||
adjustedPositionY = ((centerYPx - MIN_HEIGHT_PX / 2) / params.pageHeight) * 100;
|
|
||||||
|
|
||||||
if (adjustedPositionY < 0) {
|
|
||||||
adjustedPositionY = 0;
|
|
||||||
} else if (adjustedPositionY + adjustedHeight > 100) {
|
|
||||||
adjustedPositionY = 100 - adjustedHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
positionX: adjustedPositionX,
|
|
||||||
positionY: adjustedPositionY,
|
|
||||||
width: adjustedWidth,
|
|
||||||
height: adjustedHeight,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const detectFormFieldsInDocument = async (params: {
|
const detectFormFieldsInDocument = async (params: {
|
||||||
envelopeId: string;
|
envelopeId: string;
|
||||||
onProgress: (current: number, total: number) => void;
|
onProgress: (current: number, total: number) => void;
|
||||||
@ -247,30 +189,12 @@ export const EnvelopeEditorFieldsPage = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const [pageNumber, fields] of fieldsPerPage.entries()) {
|
for (const [pageNumber, fields] of fieldsPerPage.entries()) {
|
||||||
const pageCanvasRefs = getPageCanvasRefs(pageNumber);
|
|
||||||
|
|
||||||
for (const detected of fields) {
|
for (const detected of fields) {
|
||||||
const [ymin, xmin, ymax, xmax] = detected.boundingBox;
|
const [ymin, xmin, ymax, xmax] = detected.boundingBox;
|
||||||
let positionX = (xmin / 1000) * 100;
|
const positionX = (xmin / 1000) * 100;
|
||||||
let positionY = (ymin / 1000) * 100;
|
const positionY = (ymin / 1000) * 100;
|
||||||
let width = ((xmax - xmin) / 1000) * 100;
|
const width = ((xmax - xmin) / 1000) * 100;
|
||||||
let height = ((ymax - ymin) / 1000) * 100;
|
const height = ((ymax - ymin) / 1000) * 100;
|
||||||
|
|
||||||
if (pageCanvasRefs) {
|
|
||||||
const adjusted = enforceMinimumFieldDimensions({
|
|
||||||
positionX,
|
|
||||||
positionY,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
pageWidth: pageCanvasRefs.pdfCanvas.width,
|
|
||||||
pageHeight: pageCanvasRefs.pdfCanvas.height,
|
|
||||||
});
|
|
||||||
|
|
||||||
positionX = adjusted.positionX;
|
|
||||||
positionY = adjusted.positionY;
|
|
||||||
width = adjusted.width;
|
|
||||||
height = adjusted.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fieldType = detected.label as FieldType;
|
const fieldType = detected.label as FieldType;
|
||||||
const resolvedRecipientId =
|
const resolvedRecipientId =
|
||||||
@ -482,30 +406,12 @@ export const EnvelopeEditorFieldsPage = () => {
|
|||||||
|
|
||||||
let totalAdded = 0;
|
let totalAdded = 0;
|
||||||
for (const [pageNumber, detectedFields] of fieldsPerPage.entries()) {
|
for (const [pageNumber, detectedFields] of fieldsPerPage.entries()) {
|
||||||
const pageCanvasRefs = getPageCanvasRefs(pageNumber);
|
|
||||||
|
|
||||||
for (const detected of detectedFields) {
|
for (const detected of detectedFields) {
|
||||||
const [ymin, xmin, ymax, xmax] = detected.boundingBox;
|
const [ymin, xmin, ymax, xmax] = detected.boundingBox;
|
||||||
let positionX = (xmin / 1000) * 100;
|
const positionX = (xmin / 1000) * 100;
|
||||||
let positionY = (ymin / 1000) * 100;
|
const positionY = (ymin / 1000) * 100;
|
||||||
let width = ((xmax - xmin) / 1000) * 100;
|
const width = ((xmax - xmin) / 1000) * 100;
|
||||||
let height = ((ymax - ymin) / 1000) * 100;
|
const height = ((ymax - ymin) / 1000) * 100;
|
||||||
|
|
||||||
if (pageCanvasRefs) {
|
|
||||||
const adjusted = enforceMinimumFieldDimensions({
|
|
||||||
positionX,
|
|
||||||
positionY,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
pageWidth: pageCanvasRefs.pdfCanvas.width,
|
|
||||||
pageHeight: pageCanvasRefs.pdfCanvas.height,
|
|
||||||
});
|
|
||||||
|
|
||||||
positionX = adjusted.positionX;
|
|
||||||
positionY = adjusted.positionY;
|
|
||||||
width = adjusted.width;
|
|
||||||
height = adjusted.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fieldType = detected.label as FieldType;
|
const fieldType = detected.label as FieldType;
|
||||||
const resolvedRecipientId =
|
const resolvedRecipientId =
|
||||||
|
|||||||
@ -445,12 +445,6 @@ export const aiRoute = new Hono<HonoEnv>()
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.info('AI analyze recipients raw response', {
|
|
||||||
envelopeId,
|
|
||||||
pageNumber: page.pageNumber,
|
|
||||||
recipients: result.object,
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pageNumber: page.pageNumber,
|
pageNumber: page.pageNumber,
|
||||||
recipients: result.object,
|
recipients: result.object,
|
||||||
@ -467,7 +461,7 @@ export const aiRoute = new Hono<HonoEnv>()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { pageNumber, recipients } = result.value;
|
const { recipients } = result.value;
|
||||||
|
|
||||||
const recipientsWithEmails = recipients.map((recipient) => {
|
const recipientsWithEmails = recipients.map((recipient) => {
|
||||||
const email = resolveRecipientEmail(recipient.email);
|
const email = resolveRecipientEmail(recipient.email);
|
||||||
@ -482,12 +476,6 @@ export const aiRoute = new Hono<HonoEnv>()
|
|||||||
return normalizedRecipient;
|
return normalizedRecipient;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.info('AI analyze recipients normalized response', {
|
|
||||||
envelopeId,
|
|
||||||
pageNumber,
|
|
||||||
recipients: recipientsWithEmails,
|
|
||||||
});
|
|
||||||
|
|
||||||
allRecipients.push(...recipientsWithEmails);
|
allRecipients.push(...recipientsWithEmails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,110 +0,0 @@
|
|||||||
import type Konva from 'konva';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents canvas references for a specific PDF page.
|
|
||||||
*/
|
|
||||||
export interface PageCanvasRefs {
|
|
||||||
/** The page number (1-indexed) */
|
|
||||||
pageNumber: number;
|
|
||||||
/** The canvas element containing the rendered PDF */
|
|
||||||
pdfCanvas: HTMLCanvasElement;
|
|
||||||
/** The Konva stage containing field overlays */
|
|
||||||
konvaStage: Konva.Stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Module-level registry to store canvas references by page number.
|
|
||||||
* This allows any component to access page canvases without prop drilling.
|
|
||||||
*/
|
|
||||||
const pageCanvasRegistry = new Map<number, PageCanvasRefs>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a page's canvas references.
|
|
||||||
* Call this when a page renderer mounts and has valid canvas refs.
|
|
||||||
*
|
|
||||||
* @param refs - The canvas references to register
|
|
||||||
*/
|
|
||||||
export const registerPageCanvas = (refs: PageCanvasRefs): void => {
|
|
||||||
pageCanvasRegistry.set(refs.pageNumber, refs);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregister a page's canvas references.
|
|
||||||
* Call this when a page renderer unmounts to prevent memory leaks.
|
|
||||||
*
|
|
||||||
* @param pageNumber - The page number to unregister
|
|
||||||
*/
|
|
||||||
export const unregisterPageCanvas = (pageNumber: number): void => {
|
|
||||||
pageCanvasRegistry.delete(pageNumber);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get canvas references for a specific page.
|
|
||||||
*
|
|
||||||
* @param pageNumber - The page number to retrieve
|
|
||||||
* @returns The canvas references, or undefined if not registered
|
|
||||||
*/
|
|
||||||
export const getPageCanvasRefs = (pageNumber: number): PageCanvasRefs | undefined => {
|
|
||||||
return pageCanvasRegistry.get(pageNumber);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all registered page numbers.
|
|
||||||
*
|
|
||||||
* @returns Array of page numbers currently registered
|
|
||||||
*/
|
|
||||||
export const getRegisteredPageNumbers = (): number[] => {
|
|
||||||
return Array.from(pageCanvasRegistry.keys()).sort((a, b) => a - b);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Composite a PDF page with its field overlays into a single PNG Blob.
|
|
||||||
* This creates a temporary canvas, draws the PDF canvas first (background),
|
|
||||||
* then draws the Konva canvas on top (field overlays).
|
|
||||||
*
|
|
||||||
* @param pageNumber - The page number to composite (1-indexed)
|
|
||||||
* @returns Promise that resolves to a PNG Blob, or null if page not found or compositing fails
|
|
||||||
*/
|
|
||||||
export const compositePageToBlob = async (pageNumber: number): Promise<Blob | null> => {
|
|
||||||
const refs = getPageCanvasRefs(pageNumber);
|
|
||||||
|
|
||||||
if (!refs) {
|
|
||||||
console.warn(`Page ${pageNumber} is not registered for canvas capture`);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Create temporary canvas with same dimensions as PDF canvas
|
|
||||||
const tempCanvas = document.createElement('canvas');
|
|
||||||
tempCanvas.width = refs.pdfCanvas.width;
|
|
||||||
tempCanvas.height = refs.pdfCanvas.height;
|
|
||||||
|
|
||||||
const ctx = tempCanvas.getContext('2d');
|
|
||||||
if (!ctx) {
|
|
||||||
console.error('Failed to get 2D context for temporary canvas');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw PDF canvas first (background layer)
|
|
||||||
ctx.drawImage(refs.pdfCanvas, 0, 0);
|
|
||||||
|
|
||||||
// Get Konva canvas and draw on top (field overlays)
|
|
||||||
// Note: Konva's toCanvas() returns a new canvas with all layers rendered
|
|
||||||
const konvaCanvas = refs.konvaStage.toCanvas();
|
|
||||||
ctx.drawImage(konvaCanvas, 0, 0);
|
|
||||||
|
|
||||||
// Convert to PNG Blob
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
tempCanvas.toBlob((blob) => {
|
|
||||||
if (blob) {
|
|
||||||
resolve(blob);
|
|
||||||
} else {
|
|
||||||
reject(new Error('Failed to convert canvas to blob'));
|
|
||||||
}
|
|
||||||
}, 'image/png');
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error compositing page ${pageNumber}:`, error);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -26,7 +26,7 @@ export const renderPdfToImage = async (pdfBytes: Uint8Array) => {
|
|||||||
const pdf = await loadingTask.promise;
|
const pdf = await loadingTask.promise;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const scale = 4;
|
const scale = 2;
|
||||||
|
|
||||||
const pages = await Promise.all(
|
const pages = await Promise.all(
|
||||||
Array.from({ length: pdf.numPages }, async (_, index) => {
|
Array.from({ length: pdf.numPages }, async (_, index) => {
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
/**
|
|
||||||
* Shared constants for field dimension enforcement.
|
|
||||||
*
|
|
||||||
* These constants ensure consistency between:
|
|
||||||
* 1. AI prompt (server/api/ai.ts) - instructs Gemini on minimum field dimensions
|
|
||||||
* 2. Client enforcement (envelope-editor-fields-page.tsx) - fallback validation
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Minimum field height in pixels.
|
|
||||||
* Fields smaller than this will be expanded to meet minimum usability requirements.
|
|
||||||
*/
|
|
||||||
export const MIN_FIELD_HEIGHT_PX = 30;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Minimum field width in pixels.
|
|
||||||
* Fields smaller than this will be expanded to meet minimum usability requirements.
|
|
||||||
*/
|
|
||||||
export const MIN_FIELD_WIDTH_PX = 36;
|
|
||||||
Reference in New Issue
Block a user