Merge branch 'dev' of https://gitea.maskantech.in/gitea_admin/pdf into saqib
This commit is contained in:
Generated
+12
-23
@@ -57,6 +57,7 @@
|
||||
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.29.0",
|
||||
"@babel/generator": "^7.29.0",
|
||||
@@ -266,29 +267,6 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.2.1",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
|
||||
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
|
||||
@@ -875,6 +853,7 @@
|
||||
"integrity": "sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~7.16.0"
|
||||
}
|
||||
@@ -885,6 +864,7 @@
|
||||
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.2.2"
|
||||
}
|
||||
@@ -944,6 +924,7 @@
|
||||
"integrity": "sha512-HPwA+hVkfcriajbNvTmZv4VRauibay+cWArYUYq7u7W7PmGShMxbPxLvrwDme55a6d5alG3nrYfhyJ/G28XlLg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.59.3",
|
||||
"@typescript-eslint/types": "8.59.3",
|
||||
@@ -1174,6 +1155,7 @@
|
||||
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -1264,6 +1246,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.10.12",
|
||||
"caniuse-lite": "^1.0.30001782",
|
||||
@@ -1399,6 +1382,7 @@
|
||||
"integrity": "sha512-loXy6bWOoP3EP6JA7jo6p5jMpBJmHmsNZM5SFRHLdh1MGOPurMnNBj4ZlAbaqUAaQWbCr7jHV4P7gzAyryZWkQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.8.0",
|
||||
"@eslint-community/regexpp": "^4.12.2",
|
||||
@@ -2287,6 +2271,7 @@
|
||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@@ -2348,6 +2333,7 @@
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz",
|
||||
"integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -2504,6 +2490,7 @@
|
||||
"integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -2590,6 +2577,7 @@
|
||||
"integrity": "sha512-MFtjBYgzmSxmgA4RAfjIyXWpGe1oALnjgUTzzV7QLx/TKxCzjtMH6Fd9/eVK+5Fg1qNoz5VAwsmMs/NofrmJvw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"lightningcss": "^1.32.0",
|
||||
"picomatch": "^4.0.4",
|
||||
@@ -2714,6 +2702,7 @@
|
||||
"integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ function App() {
|
||||
try {
|
||||
const health = await gatewayService.getHealth();
|
||||
setBackendHealthy(health.engine_available || true);
|
||||
} catch (err) {
|
||||
} catch {
|
||||
setBackendHealthy(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -24,7 +24,7 @@ export interface RenderParams {
|
||||
export interface EditOperation {
|
||||
type: 'add_text' | 'delete_text' | 'draw_shape' | 'add_annotation';
|
||||
pageIndex: number;
|
||||
data: any;
|
||||
data: unknown;
|
||||
}
|
||||
|
||||
class GatewayService {
|
||||
|
||||
@@ -22,10 +22,6 @@ class WasmLoader {
|
||||
}
|
||||
|
||||
try {
|
||||
// In a real production setup, we load the wasm glue script:
|
||||
// @ts-ignore
|
||||
// const Module = await import('@/wasm/pdfengine.js');
|
||||
// For Phase 0 / Gate G0a, we stub/mock the WASM loading process gracefully:
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
this.isLoaded = true;
|
||||
|
||||
@@ -20,7 +20,6 @@ interface AnnotationLayerProps {
|
||||
}
|
||||
|
||||
export const AnnotationLayer: React.FC<AnnotationLayerProps> = ({
|
||||
pageIndex: _pageIndex,
|
||||
width,
|
||||
height,
|
||||
zoom,
|
||||
|
||||
@@ -25,6 +25,8 @@ interface PageLayout {
|
||||
top: number;
|
||||
}
|
||||
|
||||
const generateUniqueId = () => `anno_${Math.random().toString(36).substring(2, 11)}`;
|
||||
|
||||
export const PDFViewer: React.FC<PDFViewerProps> = ({
|
||||
documentId,
|
||||
totalPages,
|
||||
@@ -136,32 +138,44 @@ export const PDFViewer: React.FC<PDFViewerProps> = ({
|
||||
|
||||
// Load the rendered SVG/Image URL for each visible page
|
||||
useEffect(() => {
|
||||
let active = true;
|
||||
const fetchPageImages = async () => {
|
||||
const newUrls = [...renderedPages];
|
||||
|
||||
const renderPromises = visiblePages.map(async (page) => {
|
||||
if (!newUrls[page.index]) {
|
||||
const missingPages = visiblePages.filter((page) => !renderedPages[page.index]);
|
||||
if (missingPages.length === 0) return;
|
||||
|
||||
const renders = await Promise.all(
|
||||
missingPages.map(async (page) => {
|
||||
const url = await gatewayService.renderPage({
|
||||
documentId,
|
||||
pageIndex: page.index,
|
||||
zoom,
|
||||
rotation,
|
||||
});
|
||||
newUrls[page.index] = url;
|
||||
}
|
||||
});
|
||||
return { index: page.index, url };
|
||||
})
|
||||
);
|
||||
|
||||
await Promise.all(renderPromises);
|
||||
setRenderedPages(newUrls);
|
||||
if (!active) return;
|
||||
|
||||
setRenderedPages((prev) => {
|
||||
const next = [...prev];
|
||||
renders.forEach(({ index, url }) => {
|
||||
next[index] = url;
|
||||
});
|
||||
return next;
|
||||
});
|
||||
};
|
||||
|
||||
fetchPageImages();
|
||||
}, [visiblePages, documentId, zoom, rotation]);
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [visiblePages, documentId, zoom, rotation, renderedPages]);
|
||||
|
||||
const handleTextSelection = (text: string, bbox: Rect, _pageIndex: number) => {
|
||||
const handleTextSelection = (text: string, bbox: Rect) => {
|
||||
if (activeTool === 'highlight') {
|
||||
const newAnno: Annotation = {
|
||||
id: `anno_${Math.random().toString(36).substr(2, 9)}`,
|
||||
id: generateUniqueId(),
|
||||
type: 'highlight',
|
||||
bbox: {
|
||||
x: bbox.x / zoom,
|
||||
@@ -226,7 +240,7 @@ export const PDFViewer: React.FC<PDFViewerProps> = ({
|
||||
width={page.width}
|
||||
height={page.height}
|
||||
zoom={zoom}
|
||||
onTextSelected={(text, bbox) => handleTextSelection(text, bbox, page.index)}
|
||||
onTextSelected={(text, bbox) => handleTextSelection(text, bbox)}
|
||||
/>
|
||||
|
||||
{/* signature/ink overlay tool layer */}
|
||||
|
||||
@@ -13,7 +13,6 @@ export const SelectionLayer: React.FC<SelectionLayerProps> = ({
|
||||
pageIndex,
|
||||
width,
|
||||
height,
|
||||
zoom: _zoom,
|
||||
onTextSelected,
|
||||
}) => {
|
||||
const [dragStart, setDragStart] = useState<Point | null>(null);
|
||||
|
||||
Reference in New Issue
Block a user