Files
documenso/packages/lib/client-only/hooks/use-page-renderer.ts
ephraimduncan 138d663c25 chore: merge main, resolve biome formatting conflicts
Merge origin/main into feat/external-2fa-codes. Resolve formatting
conflicts caused by biome rollout; preserve both feature streams:
PR's external 2FA token + signing-session 2FA proof additions plus
main's RateLimit/RecipientExpired/signingReminders/date-auto-insert.

In complete-document-with-token.ts, drop the duplicate early
field-fetching block introduced when main moved that logic later
with date auto-insert support; keep the EXTERNAL_TWO_FACTOR_AUTH
check using derivedRecipientActionAuth.
2026-05-12 11:46:11 +00:00

86 lines
2.0 KiB
TypeScript

import Konva from 'konva';
import { useEffect, useMemo, useRef } from 'react';
import type { PageRenderData } from '../providers/envelope-render-provider';
type RenderFunction = (props: { stage: Konva.Stage; pageLayer: Konva.Layer }) => void;
export const usePageRenderer = (renderFunction: RenderFunction, pageData: PageRenderData) => {
const { pageWidth, pageHeight, scale, imageLoadingState, pageNumber } = pageData;
const konvaContainer = useRef<HTMLDivElement>(null);
const stage = useRef<Konva.Stage | null>(null);
const pageLayer = useRef<Konva.Layer | null>(null);
/**
* The raw viewport with no scaling. Basically the actual PDF size.
*/
const unscaledViewport = useMemo(
() => ({
scale: 1,
width: pageWidth,
height: pageHeight,
}),
[pageWidth, pageHeight],
);
/**
* The viewport scaled according to page width.
*/
const scaledViewport = useMemo(
() => ({
scale,
width: pageWidth * scale,
height: pageHeight * scale,
}),
[pageWidth, pageHeight, scale],
);
useEffect(() => {
const { current: container } = konvaContainer;
if (!container || imageLoadingState !== 'loaded') {
return;
}
stage.current = new Konva.Stage({
container,
id: `page-${pageNumber}`,
width: scaledViewport.width,
height: scaledViewport.height,
scale: {
x: scale,
y: scale,
},
});
// Create the main layer for interactive elements.
pageLayer.current = new Konva.Layer();
stage.current.add(pageLayer.current);
renderFunction({
stage: stage.current,
pageLayer: pageLayer.current,
});
void document.fonts.ready.then(() => {
pageLayer.current?.batchDraw();
});
return () => {
stage.current?.destroy();
stage.current = null;
};
}, [imageLoadingState, scaledViewport]);
return {
konvaContainer,
stage,
pageLayer,
unscaledViewport,
scaledViewport,
};
};