Skip to content

Commit 0ebec2c

Browse files
committed
refactor(print): simplify and modularize
1 parent 6225f92 commit 0ebec2c

File tree

3 files changed

+435
-456
lines changed

3 files changed

+435
-456
lines changed

apps/client/src/widgets/dialogs/print_preview.tsx

Lines changed: 50 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ export default function PrintPreviewDialog() {
108108
const [printers, setPrinters] = useState<PrinterInfo[]>([]);
109109
const [destination, setDestination] = useState<string>(DESTINATION_PDF);
110110

111+
const skipNextRegenRef = useRef(false);
112+
111113
useEffect(() => {
112114
if (!shown || !isElectron()) return;
113115
const { ipcRenderer } = dynamicRequire("electron");
@@ -131,12 +133,54 @@ export default function PrintPreviewDialog() {
131133
}, [pdfUrl]);
132134

133135
useTriliumEvent("showPrintPreview", (data: PrintPreviewData) => {
136+
skipNextRegenRef.current = true;
134137
setNote(data.note);
135138
notePathRef.current = data.notePath;
136139
updatePreview(data.pdfBuffer);
137140
setShown(true);
138141
});
139142

143+
const regeneratePreview = useCallback((opts: PreviewOpts) => {
144+
if (!isElectron()) return;
145+
146+
setLoading(true);
147+
const { ipcRenderer } = dynamicRequire("electron");
148+
149+
const onResult = (_e: any, { buffer, error }: { buffer?: Uint8Array; error?: string }) => {
150+
toast.closePersistent("printing");
151+
if (error) {
152+
setLoading(false);
153+
toast.showError(t("print_preview.render_error"));
154+
return;
155+
}
156+
if (buffer) {
157+
updatePreview(buffer);
158+
}
159+
};
160+
ipcRenderer.once("export-as-pdf-preview-result", onResult);
161+
162+
ipcRenderer.send("export-as-pdf-preview", {
163+
notePath: notePathRef.current,
164+
pageSize: opts.pageSize,
165+
landscape: opts.landscape,
166+
scale: opts.scale,
167+
margins: opts.margins,
168+
pageRanges: opts.pageRanges
169+
});
170+
}, [updatePreview]);
171+
172+
useEffect(() => {
173+
if (!shown || !pageRangesValid) return;
174+
if (skipNextRegenRef.current) {
175+
skipNextRegenRef.current = false;
176+
return;
177+
}
178+
const handle = setTimeout(() => {
179+
regeneratePreview({ landscape, pageSize, scale, margins: marginsStr, pageRanges: pageRanges.trim() });
180+
}, 400);
181+
return () => clearTimeout(handle);
182+
}, [shown, landscape, pageSize, scale, marginsStr, pageRanges, pageRangesValid, regeneratePreview]);
183+
140184
function handleClose() {
141185
setShown(false);
142186
if (pdfUrl) {
@@ -183,90 +227,14 @@ export default function PrintPreviewDialog() {
183227
}
184228
}
185229

186-
function handleOrientationChange(newLandscape: boolean) {
187-
if (newLandscape === landscape) return;
188-
setLandscape(newLandscape);
189-
regeneratePreview({ landscape: newLandscape, pageSize, scale, margins: marginsStr, pageRanges });
190-
}
191-
192-
function handlePageSizeChange(newPageSize: string) {
193-
if (newPageSize === pageSize) return;
194-
setPageSize(newPageSize);
195-
regeneratePreview({ landscape, pageSize: newPageSize, scale, margins: marginsStr, pageRanges });
196-
}
197-
198-
const scaleDebounceRef = useRef<ReturnType<typeof setTimeout>>();
199-
200230
function handleScaleChange(newScale: number) {
201231
const clamped = Math.min(2, Math.max(0.1, Math.round(newScale * 10) / 10));
202232
setScaleStr(String(clamped));
203-
204-
clearTimeout(scaleDebounceRef.current);
205-
scaleDebounceRef.current = setTimeout(() => {
206-
regeneratePreview({ landscape, pageSize, scale: clamped, margins: marginsStr, pageRanges });
207-
}, 500);
208233
}
209234

210-
function handleMarginPresetChange(newPreset: string) {
211-
if (newPreset === marginPreset) return;
212-
const newValue = serializeMargins(newPreset as MarginPreset | "custom", customMargins);
213-
setMarginsStr(newValue);
214-
regeneratePreview({ landscape, pageSize, scale, margins: newValue, pageRanges });
215-
}
216-
217-
const marginDebounceRef = useRef<ReturnType<typeof setTimeout>>();
218-
219235
function handleCustomMarginChange(side: keyof CustomMargins, value: number) {
220236
const newCustom = { ...customMargins, [side]: Math.max(0, value) };
221-
const newValue = serializeMargins("custom", newCustom);
222-
setMarginsStr(newValue);
223-
224-
clearTimeout(marginDebounceRef.current);
225-
marginDebounceRef.current = setTimeout(() => {
226-
regeneratePreview({ landscape, pageSize, scale, margins: newValue, pageRanges });
227-
}, 500);
228-
}
229-
230-
const pageRangesDebounceRef = useRef<ReturnType<typeof setTimeout>>();
231-
232-
function handlePageRangesChange(newValue: string) {
233-
setPageRanges(newValue);
234-
235-
clearTimeout(pageRangesDebounceRef.current);
236-
if (!isValidPageRanges(newValue)) return;
237-
238-
pageRangesDebounceRef.current = setTimeout(() => {
239-
regeneratePreview({ landscape, pageSize, scale, margins: marginsStr, pageRanges: newValue.trim() });
240-
}, 600);
241-
}
242-
243-
function regeneratePreview(opts: PreviewOpts) {
244-
if (!isElectron()) return;
245-
246-
setLoading(true);
247-
const { ipcRenderer } = dynamicRequire("electron");
248-
249-
const onResult = (_e: any, { buffer, error }: { buffer?: Uint8Array; error?: string }) => {
250-
toast.closePersistent("printing");
251-
if (error) {
252-
setLoading(false);
253-
toast.showError(t("print_preview.render_error"));
254-
return;
255-
}
256-
if (buffer) {
257-
updatePreview(buffer);
258-
}
259-
};
260-
ipcRenderer.once("export-as-pdf-preview-result", onResult);
261-
262-
ipcRenderer.send("export-as-pdf-preview", {
263-
notePath: notePathRef.current,
264-
pageSize: opts.pageSize,
265-
landscape: opts.landscape,
266-
scale: opts.scale,
267-
margins: opts.margins,
268-
pageRanges: opts.pageRanges
269-
});
237+
setMarginsStr(serializeMargins("custom", newCustom));
270238
}
271239

272240
return (
@@ -338,15 +306,15 @@ export default function PrintPreviewDialog() {
338306
text={t("print_preview.portrait")}
339307
icon="bx-rectangle bx-rotate-90"
340308
className={!landscape ? "active" : ""}
341-
onClick={() => handleOrientationChange(false)}
309+
onClick={() => setLandscape(false)}
342310
disabled={loading}
343311
size="small"
344312
/>
345313
<Button
346314
text={t("print_preview.landscape")}
347315
icon="bx-rectangle"
348316
className={landscape ? "active" : ""}
349-
onClick={() => handleOrientationChange(true)}
317+
onClick={() => setLandscape(true)}
350318
disabled={loading}
351319
size="small"
352320
/>
@@ -357,7 +325,7 @@ export default function PrintPreviewDialog() {
357325
<select
358326
class="form-select form-select-sm"
359327
value={pageSize}
360-
onChange={(e) => handlePageSizeChange((e.target as HTMLSelectElement).value)}
328+
onChange={(e) => setPageSize((e.target as HTMLSelectElement).value)}
361329
disabled={loading}
362330
>
363331
{PAGE_SIZES.map((size) => (
@@ -380,7 +348,7 @@ export default function PrintPreviewDialog() {
380348
<select
381349
class="form-select form-select-sm"
382350
value={marginPreset}
383-
onChange={(e) => handleMarginPresetChange((e.target as HTMLSelectElement).value)}
351+
onChange={(e) => setMarginsStr(serializeMargins((e.target as HTMLSelectElement).value as MarginPreset | "custom", customMargins))}
384352
disabled={loading}
385353
>
386354
<option value="default">{t("print_preview.margins_default")}</option>
@@ -404,7 +372,7 @@ export default function PrintPreviewDialog() {
404372
class={`form-control form-control-sm ${!pageRangesValid ? "is-invalid" : ""}`}
405373
value={pageRanges}
406374
placeholder={t("print_preview.page_ranges_placeholder")}
407-
onInput={(e) => handlePageRangesChange((e.target as HTMLInputElement).value)}
375+
onInput={(e) => setPageRanges((e.target as HTMLInputElement).value)}
408376
disabled={loading}
409377
style={{ width: "140px" }}
410378
/>

0 commit comments

Comments
 (0)