Revert formatting churn in signing pages
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,354 +1,313 @@
|
|||||||
import { createIcons, icons } from 'lucide';
|
import { createIcons, icons } from 'lucide';
|
||||||
import { showAlert, showLoader, hideLoader } from '../ui.js';
|
import { showAlert, showLoader, hideLoader } from '../ui.js';
|
||||||
import {
|
import { readFileAsArrayBuffer, formatBytes, downloadFile, getPDFDocument } from '../utils/helpers.js';
|
||||||
readFileAsArrayBuffer,
|
|
||||||
formatBytes,
|
|
||||||
downloadFile,
|
|
||||||
getPDFDocument,
|
|
||||||
} from '../utils/helpers.js';
|
|
||||||
import { PDFDocument } from 'pdf-lib';
|
import { PDFDocument } from 'pdf-lib';
|
||||||
import { t } from '../i18n/i18n';
|
import { t } from '../i18n/i18n';
|
||||||
|
|
||||||
interface SignState {
|
interface SignState {
|
||||||
file: File | null;
|
file: File | null;
|
||||||
pdfDoc: any;
|
pdfDoc: any;
|
||||||
viewerIframe: HTMLIFrameElement | null;
|
viewerIframe: HTMLIFrameElement | null;
|
||||||
viewerReady: boolean;
|
viewerReady: boolean;
|
||||||
blobUrl: string | null;
|
blobUrl: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const signState: SignState = {
|
const signState: SignState = {
|
||||||
file: null,
|
file: null,
|
||||||
pdfDoc: null,
|
pdfDoc: null,
|
||||||
viewerIframe: null,
|
viewerIframe: null,
|
||||||
viewerReady: false,
|
viewerReady: false,
|
||||||
blobUrl: null,
|
blobUrl: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
if (document.readyState === 'loading') {
|
||||||
document.addEventListener('DOMContentLoaded', initializePage);
|
document.addEventListener('DOMContentLoaded', initializePage);
|
||||||
} else {
|
} else {
|
||||||
initializePage();
|
initializePage();
|
||||||
}
|
}
|
||||||
|
|
||||||
function initializePage() {
|
function initializePage() {
|
||||||
createIcons({ icons });
|
createIcons({ icons });
|
||||||
|
|
||||||
const fileInput = document.getElementById('file-input') as HTMLInputElement;
|
const fileInput = document.getElementById('file-input') as HTMLInputElement;
|
||||||
const dropZone = document.getElementById('drop-zone');
|
const dropZone = document.getElementById('drop-zone');
|
||||||
const processBtn = document.getElementById('process-btn');
|
const processBtn = document.getElementById('process-btn');
|
||||||
|
|
||||||
if (fileInput) {
|
if (fileInput) {
|
||||||
fileInput.addEventListener('change', handleFileUpload);
|
fileInput.addEventListener('change', handleFileUpload);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dropZone) {
|
if (dropZone) {
|
||||||
dropZone.addEventListener('dragover', (e) => {
|
dropZone.addEventListener('dragover', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
dropZone.classList.add('bg-gray-700');
|
dropZone.classList.add('bg-gray-700');
|
||||||
|
});
|
||||||
|
|
||||||
|
dropZone.addEventListener('dragleave', () => {
|
||||||
|
dropZone.classList.remove('bg-gray-700');
|
||||||
|
});
|
||||||
|
|
||||||
|
dropZone.addEventListener('drop', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
dropZone.classList.remove('bg-gray-700');
|
||||||
|
const droppedFiles = e.dataTransfer?.files;
|
||||||
|
if (droppedFiles && droppedFiles.length > 0) {
|
||||||
|
handleFile(droppedFiles[0]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear value on click to allow re-selecting the same file
|
||||||
|
fileInput?.addEventListener('click', () => {
|
||||||
|
if (fileInput) fileInput.value = '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processBtn) {
|
||||||
|
processBtn.addEventListener('click', applyAndSaveSignatures);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('back-to-tools')?.addEventListener('click', () => {
|
||||||
|
cleanup();
|
||||||
|
window.location.href = import.meta.env.BASE_URL;
|
||||||
});
|
});
|
||||||
|
|
||||||
dropZone.addEventListener('dragleave', () => {
|
|
||||||
dropZone.classList.remove('bg-gray-700');
|
|
||||||
});
|
|
||||||
|
|
||||||
dropZone.addEventListener('drop', (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
dropZone.classList.remove('bg-gray-700');
|
|
||||||
const droppedFiles = e.dataTransfer?.files;
|
|
||||||
if (droppedFiles && droppedFiles.length > 0) {
|
|
||||||
handleFile(droppedFiles[0]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Clear value on click to allow re-selecting the same file
|
|
||||||
fileInput?.addEventListener('click', () => {
|
|
||||||
if (fileInput) fileInput.value = '';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (processBtn) {
|
|
||||||
processBtn.addEventListener('click', applyAndSaveSignatures);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById('back-to-tools')?.addEventListener('click', () => {
|
|
||||||
cleanup();
|
|
||||||
window.location.href = import.meta.env.BASE_URL;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFileUpload(e: Event) {
|
function handleFileUpload(e: Event) {
|
||||||
const input = e.target as HTMLInputElement;
|
const input = e.target as HTMLInputElement;
|
||||||
if (input.files && input.files.length > 0) {
|
if (input.files && input.files.length > 0) {
|
||||||
handleFile(input.files[0]);
|
handleFile(input.files[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFile(file: File) {
|
function handleFile(file: File) {
|
||||||
if (
|
if (file.type !== 'application/pdf' && !file.name.toLowerCase().endsWith('.pdf')) {
|
||||||
file.type !== 'application/pdf' &&
|
showAlert('Invalid File', 'Please select a PDF file.');
|
||||||
!file.name.toLowerCase().endsWith('.pdf')
|
return;
|
||||||
) {
|
}
|
||||||
showAlert('Invalid File', 'Please select a PDF file.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
signState.file = file;
|
signState.file = file;
|
||||||
updateFileDisplay();
|
updateFileDisplay();
|
||||||
setupSignTool();
|
setupSignTool();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateFileDisplay() {
|
async function updateFileDisplay() {
|
||||||
const fileDisplayArea = document.getElementById('file-display-area');
|
const fileDisplayArea = document.getElementById('file-display-area');
|
||||||
|
|
||||||
if (!fileDisplayArea || !signState.file) return;
|
if (!fileDisplayArea || !signState.file) return;
|
||||||
|
|
||||||
fileDisplayArea.innerHTML = '';
|
|
||||||
|
|
||||||
const fileDiv = document.createElement('div');
|
|
||||||
fileDiv.className =
|
|
||||||
'flex items-center justify-between bg-gray-700 p-3 rounded-lg';
|
|
||||||
|
|
||||||
const infoContainer = document.createElement('div');
|
|
||||||
infoContainer.className = 'flex flex-col flex-1 min-w-0';
|
|
||||||
|
|
||||||
const nameSpan = document.createElement('div');
|
|
||||||
nameSpan.className = 'truncate font-medium text-gray-200 text-sm mb-1';
|
|
||||||
nameSpan.textContent = signState.file.name;
|
|
||||||
|
|
||||||
const metaSpan = document.createElement('div');
|
|
||||||
metaSpan.className = 'text-xs text-gray-400';
|
|
||||||
metaSpan.textContent = `${formatBytes(signState.file.size)} • ${t('common.loadingPageCount')}`;
|
|
||||||
|
|
||||||
infoContainer.append(nameSpan, metaSpan);
|
|
||||||
|
|
||||||
const removeBtn = document.createElement('button');
|
|
||||||
removeBtn.className = 'ml-4 text-red-400 hover:text-red-300 flex-shrink-0';
|
|
||||||
removeBtn.innerHTML = '<i data-lucide=\"trash-2\" class=\"w-4 h-4\"></i>';
|
|
||||||
removeBtn.onclick = () => {
|
|
||||||
signState.file = null;
|
|
||||||
signState.pdfDoc = null;
|
|
||||||
fileDisplayArea.innerHTML = '';
|
fileDisplayArea.innerHTML = '';
|
||||||
document.getElementById('signature-editor')?.classList.add('hidden');
|
|
||||||
};
|
|
||||||
|
|
||||||
fileDiv.append(infoContainer, removeBtn);
|
const fileDiv = document.createElement('div');
|
||||||
fileDisplayArea.appendChild(fileDiv);
|
fileDiv.className = 'flex items-center justify-between bg-gray-700 p-3 rounded-lg';
|
||||||
createIcons({ icons });
|
|
||||||
|
|
||||||
// Load page count
|
const infoContainer = document.createElement('div');
|
||||||
try {
|
infoContainer.className = 'flex flex-col flex-1 min-w-0';
|
||||||
const arrayBuffer = await readFileAsArrayBuffer(signState.file);
|
|
||||||
const pdfDoc = await getPDFDocument({ data: arrayBuffer }).promise;
|
const nameSpan = document.createElement('div');
|
||||||
metaSpan.textContent = `${formatBytes(signState.file.size)} • ${pdfDoc.numPages} pages`;
|
nameSpan.className = 'truncate font-medium text-gray-200 text-sm mb-1';
|
||||||
} catch (error) {
|
nameSpan.textContent = signState.file.name;
|
||||||
console.error('Error loading PDF:', error);
|
|
||||||
}
|
const metaSpan = document.createElement('div');
|
||||||
|
metaSpan.className = 'text-xs text-gray-400';
|
||||||
|
metaSpan.textContent = `${formatBytes(signState.file.size)} • ${t('common.loadingPageCount')}`;
|
||||||
|
|
||||||
|
infoContainer.append(nameSpan, metaSpan);
|
||||||
|
|
||||||
|
const removeBtn = document.createElement('button');
|
||||||
|
removeBtn.className = 'ml-4 text-red-400 hover:text-red-300 flex-shrink-0';
|
||||||
|
removeBtn.innerHTML = '<i data-lucide=\"trash-2\" class=\"w-4 h-4\"></i>';
|
||||||
|
removeBtn.onclick = () => {
|
||||||
|
signState.file = null;
|
||||||
|
signState.pdfDoc = null;
|
||||||
|
fileDisplayArea.innerHTML = '';
|
||||||
|
document.getElementById('signature-editor')?.classList.add('hidden');
|
||||||
|
};
|
||||||
|
|
||||||
|
fileDiv.append(infoContainer, removeBtn);
|
||||||
|
fileDisplayArea.appendChild(fileDiv);
|
||||||
|
createIcons({ icons });
|
||||||
|
|
||||||
|
// Load page count
|
||||||
|
try {
|
||||||
|
const arrayBuffer = await readFileAsArrayBuffer(signState.file);
|
||||||
|
const pdfDoc = await getPDFDocument({ data: arrayBuffer }).promise;
|
||||||
|
metaSpan.textContent = `${formatBytes(signState.file.size)} • ${pdfDoc.numPages} pages`;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading PDF:', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setupSignTool() {
|
async function setupSignTool() {
|
||||||
const signatureEditor = document.getElementById('signature-editor');
|
const signatureEditor = document.getElementById('signature-editor');
|
||||||
if (signatureEditor) {
|
if (signatureEditor) {
|
||||||
signatureEditor.classList.remove('hidden');
|
signatureEditor.classList.remove('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
showLoader('Loading PDF viewer...');
|
showLoader('Loading PDF viewer...');
|
||||||
|
|
||||||
const container = document.getElementById('canvas-container-sign');
|
const container = document.getElementById('canvas-container-sign');
|
||||||
if (!container) {
|
if (!container) {
|
||||||
console.error('Sign tool canvas container not found');
|
console.error('Sign tool canvas container not found');
|
||||||
hideLoader();
|
hideLoader();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!signState.file) {
|
if (!signState.file) {
|
||||||
console.error('No file loaded for signing');
|
console.error('No file loaded for signing');
|
||||||
hideLoader();
|
hideLoader();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
container.textContent = '';
|
container.textContent = '';
|
||||||
const iframe = document.createElement('iframe');
|
const iframe = document.createElement('iframe');
|
||||||
iframe.style.width = '100%';
|
iframe.style.width = '100%';
|
||||||
iframe.style.height = '100%';
|
iframe.style.height = '100%';
|
||||||
iframe.style.border = 'none';
|
iframe.style.border = 'none';
|
||||||
container.appendChild(iframe);
|
container.appendChild(iframe);
|
||||||
signState.viewerIframe = iframe;
|
signState.viewerIframe = iframe;
|
||||||
|
|
||||||
const pdfBytes = await readFileAsArrayBuffer(signState.file);
|
const pdfBytes = await readFileAsArrayBuffer(signState.file);
|
||||||
const blob = new Blob([pdfBytes as BlobPart], { type: 'application/pdf' });
|
const blob = new Blob([pdfBytes as BlobPart], { type: 'application/pdf' });
|
||||||
signState.blobUrl = URL.createObjectURL(blob);
|
signState.blobUrl = URL.createObjectURL(blob);
|
||||||
|
|
||||||
try {
|
|
||||||
const existingPrefsRaw = localStorage.getItem('pdfjs.preferences');
|
|
||||||
const existingPrefs = existingPrefsRaw ? JSON.parse(existingPrefsRaw) : {};
|
|
||||||
delete (existingPrefs as any).annotationEditorMode;
|
|
||||||
const newPrefs = {
|
|
||||||
...existingPrefs,
|
|
||||||
enableSignatureEditor: true,
|
|
||||||
enablePermissions: false,
|
|
||||||
};
|
|
||||||
localStorage.setItem('pdfjs.preferences', JSON.stringify(newPrefs));
|
|
||||||
} catch {}
|
|
||||||
|
|
||||||
const viewerUrl = new URL(
|
|
||||||
`${import.meta.env.BASE_URL}pdfjs-viewer/viewer.html`,
|
|
||||||
window.location.origin
|
|
||||||
);
|
|
||||||
const query = new URLSearchParams({ file: signState.blobUrl });
|
|
||||||
iframe.src = `${viewerUrl.toString()}?${query.toString()}`;
|
|
||||||
|
|
||||||
iframe.onload = () => {
|
|
||||||
hideLoader();
|
|
||||||
signState.viewerReady = true;
|
|
||||||
try {
|
try {
|
||||||
const viewerWindow: any = iframe.contentWindow;
|
const existingPrefsRaw = localStorage.getItem('pdfjs.preferences');
|
||||||
if (viewerWindow && viewerWindow.PDFViewerApplication) {
|
const existingPrefs = existingPrefsRaw ? JSON.parse(existingPrefsRaw) : {};
|
||||||
const app = viewerWindow.PDFViewerApplication;
|
delete (existingPrefs as any).annotationEditorMode;
|
||||||
const doc = viewerWindow.document;
|
const newPrefs = {
|
||||||
const eventBus = app.eventBus;
|
...existingPrefs,
|
||||||
eventBus?._on('annotationeditoruimanager', () => {
|
enableSignatureEditor: true,
|
||||||
const editorModeButtons = doc.getElementById('editorModeButtons');
|
enablePermissions: false,
|
||||||
editorModeButtons?.classList.remove('hidden');
|
};
|
||||||
const editorSignature = doc.getElementById('editorSignature');
|
localStorage.setItem('pdfjs.preferences', JSON.stringify(newPrefs));
|
||||||
editorSignature?.removeAttribute('hidden');
|
} catch { }
|
||||||
const editorSignatureButton = doc.getElementById(
|
|
||||||
'editorSignatureButton'
|
|
||||||
) as HTMLButtonElement | null;
|
|
||||||
if (editorSignatureButton) {
|
|
||||||
editorSignatureButton.disabled = false;
|
|
||||||
}
|
|
||||||
const editorStamp = doc.getElementById('editorStamp');
|
|
||||||
editorStamp?.removeAttribute('hidden');
|
|
||||||
const editorStampButton = doc.getElementById(
|
|
||||||
'editorStampButton'
|
|
||||||
) as HTMLButtonElement | null;
|
|
||||||
if (editorStampButton) {
|
|
||||||
editorStampButton.disabled = false;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const highlightBtn = doc.getElementById(
|
|
||||||
'editorHighlightButton'
|
|
||||||
) as HTMLButtonElement | null;
|
|
||||||
highlightBtn?.click();
|
|
||||||
} catch {}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Could not initialize PDF.js viewer for signing:', e);
|
|
||||||
}
|
|
||||||
|
|
||||||
const saveBtn = document.getElementById(
|
const viewerUrl = new URL(`${import.meta.env.BASE_URL}pdfjs-viewer/viewer.html`, window.location.origin);
|
||||||
'process-btn'
|
const query = new URLSearchParams({ file: signState.blobUrl });
|
||||||
) as HTMLButtonElement | null;
|
iframe.src = `${viewerUrl.toString()}?${query.toString()}`;
|
||||||
if (saveBtn) {
|
|
||||||
saveBtn.style.display = '';
|
iframe.onload = () => {
|
||||||
}
|
hideLoader();
|
||||||
};
|
signState.viewerReady = true;
|
||||||
|
try {
|
||||||
|
const viewerWindow: any = iframe.contentWindow;
|
||||||
|
if (viewerWindow && viewerWindow.PDFViewerApplication) {
|
||||||
|
const app = viewerWindow.PDFViewerApplication;
|
||||||
|
const doc = viewerWindow.document;
|
||||||
|
const eventBus = app.eventBus;
|
||||||
|
eventBus?._on('annotationeditoruimanager', () => {
|
||||||
|
const editorModeButtons = doc.getElementById('editorModeButtons');
|
||||||
|
editorModeButtons?.classList.remove('hidden');
|
||||||
|
const editorSignature = doc.getElementById('editorSignature');
|
||||||
|
editorSignature?.removeAttribute('hidden');
|
||||||
|
const editorSignatureButton = doc.getElementById('editorSignatureButton') as HTMLButtonElement | null;
|
||||||
|
if (editorSignatureButton) {
|
||||||
|
editorSignatureButton.disabled = false;
|
||||||
|
}
|
||||||
|
const editorStamp = doc.getElementById('editorStamp');
|
||||||
|
editorStamp?.removeAttribute('hidden');
|
||||||
|
const editorStampButton = doc.getElementById('editorStampButton') as HTMLButtonElement | null;
|
||||||
|
if (editorStampButton) {
|
||||||
|
editorStampButton.disabled = false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const highlightBtn = doc.getElementById('editorHighlightButton') as HTMLButtonElement | null;
|
||||||
|
highlightBtn?.click();
|
||||||
|
} catch { }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not initialize PDF.js viewer for signing:', e);
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveBtn = document.getElementById('process-btn') as HTMLButtonElement | null;
|
||||||
|
if (saveBtn) {
|
||||||
|
saveBtn.style.display = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function applyAndSaveSignatures() {
|
async function applyAndSaveSignatures() {
|
||||||
if (!signState.viewerReady || !signState.viewerIframe) {
|
if (!signState.viewerReady || !signState.viewerIframe) {
|
||||||
showAlert('Viewer not ready', 'Please wait for the PDF viewer to load.');
|
showAlert('Viewer not ready', 'Please wait for the PDF viewer to load.');
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const viewerWindow: any = signState.viewerIframe.contentWindow;
|
|
||||||
if (!viewerWindow || !viewerWindow.PDFViewerApplication) {
|
|
||||||
showAlert('Viewer not ready', 'The PDF viewer is still initializing.');
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = viewerWindow.PDFViewerApplication;
|
try {
|
||||||
const flattenCheckbox = document.getElementById(
|
const viewerWindow: any = signState.viewerIframe.contentWindow;
|
||||||
'flatten-signature-toggle'
|
if (!viewerWindow || !viewerWindow.PDFViewerApplication) {
|
||||||
) as HTMLInputElement | null;
|
showAlert('Viewer not ready', 'The PDF viewer is still initializing.');
|
||||||
const shouldFlatten = flattenCheckbox?.checked;
|
return;
|
||||||
|
|
||||||
if (shouldFlatten) {
|
|
||||||
showLoader('Flattening and saving PDF...');
|
|
||||||
|
|
||||||
const rawPdfBytes = await app.pdfDocument.saveDocument(
|
|
||||||
app.pdfDocument.annotationStorage
|
|
||||||
);
|
|
||||||
const pdfBytes = new Uint8Array(rawPdfBytes);
|
|
||||||
const pdfDoc = await PDFDocument.load(pdfBytes);
|
|
||||||
pdfDoc.getForm().flatten();
|
|
||||||
const flattenedPdfBytes = await pdfDoc.save();
|
|
||||||
|
|
||||||
const blob = new Blob([flattenedPdfBytes as BlobPart], {
|
|
||||||
type: 'application/pdf',
|
|
||||||
});
|
|
||||||
downloadFile(
|
|
||||||
blob,
|
|
||||||
`signed_flattened_${signState.file?.name || 'document.pdf'}`
|
|
||||||
);
|
|
||||||
|
|
||||||
hideLoader();
|
|
||||||
showAlert('Success', 'Signed PDF saved successfully!', 'success', () => {
|
|
||||||
resetState();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
app.eventBus?.dispatch('download', { source: app });
|
|
||||||
showAlert(
|
|
||||||
'Success',
|
|
||||||
'Signed PDF downloaded successfully!',
|
|
||||||
'success',
|
|
||||||
() => {
|
|
||||||
resetState();
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
const app = viewerWindow.PDFViewerApplication;
|
||||||
|
const flattenCheckbox = document.getElementById('flatten-signature-toggle') as HTMLInputElement | null;
|
||||||
|
const shouldFlatten = flattenCheckbox?.checked;
|
||||||
|
|
||||||
|
if (shouldFlatten) {
|
||||||
|
showLoader('Flattening and saving PDF...');
|
||||||
|
|
||||||
|
const rawPdfBytes = await app.pdfDocument.saveDocument(app.pdfDocument.annotationStorage);
|
||||||
|
const pdfBytes = new Uint8Array(rawPdfBytes);
|
||||||
|
const pdfDoc = await PDFDocument.load(pdfBytes);
|
||||||
|
pdfDoc.getForm().flatten();
|
||||||
|
const flattenedPdfBytes = await pdfDoc.save();
|
||||||
|
|
||||||
|
const blob = new Blob([flattenedPdfBytes as BlobPart], { type: 'application/pdf' });
|
||||||
|
downloadFile(blob, `signed_flattened_${signState.file?.name || 'document.pdf'}`);
|
||||||
|
|
||||||
|
hideLoader();
|
||||||
|
showAlert('Success', 'Signed PDF saved successfully!', 'success', () => {
|
||||||
|
resetState();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
app.eventBus?.dispatch('download', { source: app });
|
||||||
|
showAlert('Success', 'Signed PDF downloaded successfully!', 'success', () => {
|
||||||
|
resetState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to export the signed PDF:', error);
|
||||||
|
hideLoader();
|
||||||
|
showAlert('Export failed', 'Could not export the signed PDF. Please try again.');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to export the signed PDF:', error);
|
|
||||||
hideLoader();
|
|
||||||
showAlert(
|
|
||||||
'Export failed',
|
|
||||||
'Could not export the signed PDF. Please try again.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetState() {
|
function resetState() {
|
||||||
cleanup();
|
cleanup();
|
||||||
signState.file = null;
|
signState.file = null;
|
||||||
signState.viewerIframe = null;
|
signState.viewerIframe = null;
|
||||||
signState.viewerReady = false;
|
signState.viewerReady = false;
|
||||||
|
|
||||||
const signatureEditor = document.getElementById('signature-editor');
|
const signatureEditor = document.getElementById('signature-editor');
|
||||||
if (signatureEditor) {
|
if (signatureEditor) {
|
||||||
signatureEditor.classList.add('hidden');
|
signatureEditor.classList.add('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
const container = document.getElementById('canvas-container-sign');
|
const container = document.getElementById('canvas-container-sign');
|
||||||
if (container) {
|
if (container) {
|
||||||
container.textContent = '';
|
container.textContent = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileDisplayArea = document.getElementById('file-display-area');
|
const fileDisplayArea = document.getElementById('file-display-area');
|
||||||
if (fileDisplayArea) {
|
if (fileDisplayArea) {
|
||||||
fileDisplayArea.innerHTML = '';
|
fileDisplayArea.innerHTML = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const processBtn = document.getElementById(
|
const processBtn = document.getElementById('process-btn') as HTMLButtonElement | null;
|
||||||
'process-btn'
|
if (processBtn) {
|
||||||
) as HTMLButtonElement | null;
|
processBtn.style.display = 'none';
|
||||||
if (processBtn) {
|
}
|
||||||
processBtn.style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
const flattenCheckbox = document.getElementById(
|
const flattenCheckbox = document.getElementById('flatten-signature-toggle') as HTMLInputElement | null;
|
||||||
'flatten-signature-toggle'
|
if (flattenCheckbox) {
|
||||||
) as HTMLInputElement | null;
|
flattenCheckbox.checked = false;
|
||||||
if (flattenCheckbox) {
|
}
|
||||||
flattenCheckbox.checked = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleanup() {
|
function cleanup() {
|
||||||
if (signState.blobUrl) {
|
if (signState.blobUrl) {
|
||||||
URL.revokeObjectURL(signState.blobUrl);
|
URL.revokeObjectURL(signState.blobUrl);
|
||||||
signState.blobUrl = null;
|
signState.blobUrl = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user