mirror of
https://github.com/zadam/trilium.git
synced 2026-08-04 22:30:51 +02:00
feat(ocr): reintroduce batch processing
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "preact/hooks";
|
||||
|
||||
import { t } from "../../../services/i18n";
|
||||
import server from "../../../services/server";
|
||||
import toast from "../../../services/toast";
|
||||
import { FormTextBoxWithUnit } from "../../react/FormTextBox";
|
||||
import FormToggle from "../../react/FormToggle";
|
||||
import { useTriliumOption, useTriliumOptionBool } from "../../react/hooks";
|
||||
@@ -92,6 +96,83 @@ function OcrSettings() {
|
||||
onChange={setOcrMinConfidence}
|
||||
/>
|
||||
</OptionsRow>
|
||||
|
||||
<BatchProcessing />
|
||||
</OptionsSection>
|
||||
);
|
||||
}
|
||||
|
||||
interface BatchProgress {
|
||||
inProgress: boolean;
|
||||
total: number;
|
||||
processed: number;
|
||||
percentage?: number;
|
||||
}
|
||||
|
||||
function BatchProcessing() {
|
||||
const [ progress, setProgress ] = useState<BatchProgress | null>(null);
|
||||
const pollingRef = useRef<ReturnType<typeof setInterval>>(null);
|
||||
|
||||
const pollProgress = useCallback(() => {
|
||||
server.get<BatchProgress>("ocr/batch-progress").then((data) => {
|
||||
setProgress(data);
|
||||
if (!data.inProgress && pollingRef.current) {
|
||||
clearInterval(pollingRef.current);
|
||||
pollingRef.current = null;
|
||||
toast.showMessage(t("images.batch_ocr_completed", { processed: data.processed }));
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
// Clean up polling on unmount.
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (pollingRef.current) {
|
||||
clearInterval(pollingRef.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
async function startBatch() {
|
||||
try {
|
||||
const result = await server.post<{ success: boolean; message?: string }>("ocr/batch-process");
|
||||
if (result.success) {
|
||||
toast.showMessage(t("images.batch_ocr_starting"));
|
||||
pollingRef.current = setInterval(pollProgress, 2000);
|
||||
pollProgress();
|
||||
} else {
|
||||
toast.showError(result.message || t("images.batch_ocr_error", { error: "Unknown" }));
|
||||
}
|
||||
} catch {
|
||||
// Server errors are already shown as toasts by server.ts.
|
||||
}
|
||||
}
|
||||
|
||||
const isRunning = progress?.inProgress ?? false;
|
||||
|
||||
return (
|
||||
<OptionsRow name="batch-ocr" label={t("images.batch_ocr_title")} description={t("images.batch_ocr_description")}>
|
||||
{isRunning ? (
|
||||
<div style={{ width: "100%" }}>
|
||||
<div className="progress" style={{ height: "24px" }}>
|
||||
<div
|
||||
className="progress-bar progress-bar-striped progress-bar-animated"
|
||||
role="progressbar"
|
||||
style={{ width: `${progress?.percentage ?? 0}%` }}
|
||||
>
|
||||
{t("images.batch_ocr_progress", { processed: progress?.processed ?? 0, total: progress?.total ?? 0 })}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary"
|
||||
onClick={startBatch}
|
||||
>
|
||||
<span className="bx bx-play" />{" "}{t("images.batch_ocr_start")}
|
||||
</button>
|
||||
)}
|
||||
</OptionsRow>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user