Prevent total lockup when generating PDF, show status updates during generation

This commit is contained in:
Skylar Ittner 2021-07-02 02:43:47 -06:00
parent 367daeca57
commit 4609cc114f
2 changed files with 41 additions and 18 deletions

View File

@ -100,7 +100,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<div class="card">
<div class="card-body">
<div class="btn-toolbar" role="toolbar">
<div class="btn-toolbar d-inline-block" role="toolbar">
<div class="btn-group me-2 mb-2" role="group" aria-label="First group">
<div class="btn btn-primary" onclick="addPDF();"><i class="fas fa-file-pdf"></i> Add PDF</div>
<div class="btn btn-primary" onclick="savePDF();"><i class="fas fa-save"></i> Save Signed PDF</div>
@ -108,6 +108,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<div class="btn btn-primary" onclick="openSettingsModal();"><i class="fas fa-cog"></i> Settings</div>
</div>
</div>
<div id="statustext" class="d-inline-block"></div>
<div class="btn-toolbar" role="toolbar">
<div class="btn-group me-2 mb-2" role="group" aria-label="First group">
<div class="btn btn-primary" onclick="pdfZoom('fitheight');"><i class="fas fa-arrows-alt-v"></i> Fit Height</div>
@ -139,7 +140,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<script src="node_modules/pdfjs-dist/build/pdf.min.js"></script>
<script src="node_modules/jspdf/dist/jspdf.umd.min.js"></script>
<script src="node_modules/signature_pad/dist/signature_pad.umd.min.js"></script>
<script src="node_modules/jshashes/hashes.min.js"></script>
<script src="js/kbpgp-2.1.15.js"></script>
<script src="js/svg-to-image.js"></script>
<script src="js/util.js"></script>

View File

@ -40,8 +40,10 @@ function closePDF(showuserconfirm) {
$("#page-canvas-container .page-canvas").remove();
}
function generatePDF() {
function generatePDF(callback) {
var canvases = $("#page-canvas-container .page-canvas");
var statustextEl = $("#statustext");
statustextEl.html("<i class='fas fa-spin fa-spinner'></i> Processing document...");
const pdf = new jsPDF({
unit: "in",
compress: true
@ -49,19 +51,32 @@ function generatePDF() {
// creating a PDF creates a blank page that we don't want to use,
// as we haven't done the calculations yet
pdf.deletePage(1);
for (var i = 0; i < canvases.length; i++) {
var canvas = $("#page-canvas-container .page-canvas")[i];
var widthpx = canvas.getContext("2d").canvas.width;
var heightpx = canvas.getContext("2d").canvas.height;
var pageWidthInches = widthpx / (pdfAssumedDPI * pdfPageScale);
var pageHeightInches = heightpx / (pdfAssumedDPI * pdfPageScale);
console.log(pageWidthInches + " x " + pageHeightInches);
var pageFormat = [pageWidthInches, pageHeightInches];
var pageOrientation = (pageWidthInches > pageHeightInches ? "landscape" : "portrait");
pdf.addPage(pageFormat, pageOrientation);
pdf.addImage($("#page-canvas-container .page-canvas")[i].toDataURL(), 0, 0, pageWidthInches, pageHeightInches);
// Render each page in order with a pause in between to keep UI responsive
var processPage = function (i) {
if (i < canvases.length) {
statustextEl.html("<i class='fas fa-spin fa-spinner'></i> Processing page " + (i + 1) + " of " + canvases.length + "...");
console.log("Processing " + (i + 1));
var canvas = canvases[i];
var widthpx = canvas.getContext("2d").canvas.width;
var heightpx = canvas.getContext("2d").canvas.height;
var pageWidthInches = widthpx / (pdfAssumedDPI * pdfPageScale);
var pageHeightInches = heightpx / (pdfAssumedDPI * pdfPageScale);
console.log(pageWidthInches + " x " + pageHeightInches);
var pageFormat = [pageWidthInches, pageHeightInches];
var pageOrientation = (pageWidthInches > pageHeightInches ? "landscape" : "portrait");
pdf.addPage(pageFormat, pageOrientation);
pdf.addImage(canvases[i].toDataURL(), 0, 0, pageWidthInches, pageHeightInches);
i++;
setTimeout(function () {
processPage(i)
}, 100);
} else {
statustextEl.html("");
callback(pdf);
}
}
return pdf;
processPage(0);
}
function getPDFAsByteArray(pdf) {
@ -93,15 +108,23 @@ function makeAndSaveSignedPDF(pdf, savepath, callback) {
function savePDF() {
disableGuideBox();
var statustextEl = $("#statustext");
loadKeyFromLocalStorage(function (message, ok) {
if (ok) {
openSaveFileDialog(function (path) {
var pdf = generatePDF();
makeAndSaveSignedPDF(pdf, path, function (result) {
alert("File signed and saved.\n SHA256 of file (without signature): " + result.hash);
generatePDF(function (pdf) {
statustextEl.html("<i class='fas fa-spin fa-spinner'></i> Signing document...");
makeAndSaveSignedPDF(pdf, path, function (result) {
statustextEl.html("<i class='fas fa-check'></i> Signed and saved!");
alert("File signed and saved.\nSHA256 of file (without signature): " + result.hash);
setTimeout(function () {
statustextEl.html("");
}, 5000);
});
});
}, "signed.pdf", ".pdf");
} else {
statustextEl.html("");
alert("Error: " + message);
}
});