From 9af2577c6e9282069774bff200955273575a530a Mon Sep 17 00:00:00 2001 From: Gazook89 Date: Thu, 30 Apr 2026 21:05:08 -0500 Subject: [PATCH] Add print cycle events and loading msg Since the print cycle now loads all images not-yet-loaded (due to lazy loading), there can be a moment of time where it appears pressing Get PDF is doing nothing, depending on connection speed. To add a "loading" message, a custom event is fired at the start and end of the print cycle (before the print dialog comes up). --- client/homebrew/navbar/print.navitem.jsx | 20 ++++++++++-- shared/helpers.js | 39 ++++++++++++++---------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/client/homebrew/navbar/print.navitem.jsx b/client/homebrew/navbar/print.navitem.jsx index ea262cf03..e669214b3 100644 --- a/client/homebrew/navbar/print.navitem.jsx +++ b/client/homebrew/navbar/print.navitem.jsx @@ -1,9 +1,25 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import Nav from './nav.jsx'; import { printCurrentBrew } from '@shared/helpers.js'; export default function(){ + const [printing, setPrinting] = useState(false); + + // listen for print cycle events to display "loading" message since it can take some time. + useEffect(()=>{ + document.addEventListener('print:startprep', handlePrintStartPrep); + document.addEventListener('print:finishedprep', handlePrintPrepFinished); + return ()=>{ + document.removeEventListener('print:startprep', handlePrintStartPrep); + document.removeEventListener('print:finishedprep', handlePrintPrepFinished); + } + }, []); + + const handlePrintStartPrep = ()=>{ setPrinting(true); }; + + const handlePrintPrepFinished = ()=>{ setPrinting(false); }; + return - get PDF + {printing ? 'loading' : 'get PDF'} ; }; diff --git a/shared/helpers.js b/shared/helpers.js index e8b5596b6..eeb09daf4 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -107,26 +107,33 @@ const splitTextStyleAndMetadata = (brew)=>{ const printCurrentBrew = async ()=>{ if(window.typeof !== 'undefined') { - const iframeDoc = window.frames['BrewRenderer'].contentDocument; + // fire a custom event for the print cycle + document.dispatchEvent(new CustomEvent('print:startprep')); + try { + const iframeDoc = window.frames['BrewRenderer'].contentDocument; - // get all img elements with lazy loading (currently only elements generated through MarkedJS) - const lazyImages = [...iframeDoc.querySelectorAll('img[loading="lazy"]')]; - lazyImages.forEach((img)=>{ img.loading = 'eager'; }); + // get all img elements with lazy loading (currently only elements generated through MarkedJS) + const lazyImages = [...iframeDoc.querySelectorAll('img[loading="lazy"]')]; + lazyImages.forEach((img)=>{ img.loading = 'eager'; }); - // waits for images to load before resolving promise and opening print dialog - await Promise.all( - lazyImages - .filter((img)=>!img.complete) - .map((img)=>new Promise((resolve)=>{ img.onload = resolve; img.onerror = resolve; })) - ); + // waits for images to load before resolving promise and opening print dialog + await Promise.all( + lazyImages + .filter((img)=>!img.complete) + .map((img)=>new Promise((resolve)=>{ img.onload = resolve; img.onerror = resolve; })) + ); - window.frames['BrewRenderer'].contentWindow.print(); + window.frames['BrewRenderer'].contentWindow.print(); - //Force DOM reflow; Print dialog causes a repaint, and @media print CSS somehow makes out-of-view pages disappear - const node = iframeDoc.getElementsByClassName('brewRenderer').item(0); - node.style.display='none'; - node.offsetHeight; // accessing this is enough to trigger a reflow - node.style.display=''; + //Force DOM reflow; Print dialog causes a repaint, and @media print CSS somehow makes out-of-view pages disappear + const node = iframeDoc.getElementsByClassName('brewRenderer').item(0); + node.style.display='none'; + node.offsetHeight; // accessing this is enough to trigger a reflow + node.style.display=''; + } finally { + // when lazy load images have all been loaded, and the doc re-rendered for print preview, emit 'finished' event. + document.dispatchEvent(new CustomEvent('print:finishedprep')); + } } };