feat(chartread): Add Accept/Override button and improve prompt handling for warnings and multi-sheet reads (resolves #137) #138
@@ -330,6 +330,7 @@
|
|||||||
<div class="chartread-actions">
|
<div class="chartread-actions">
|
||||||
<button class="primary" id="btnStartRead">Start Measurement</button>
|
<button class="primary" id="btnStartRead">Start Measurement</button>
|
||||||
<button class="primary hidden" id="btnCalibrate">✓ Calibrate</button>
|
<button class="primary hidden" id="btnCalibrate">✓ Calibrate</button>
|
||||||
|
<button class="primary hidden" id="btnAccept">✓ Accept Strip</button>
|
||||||
<button class="secondary hidden" id="btnRetry">↻ Retry Strip</button>
|
<button class="secondary hidden" id="btnRetry">↻ Retry Strip</button>
|
||||||
<button class="secondary hidden" id="btnSkip">⏭ Skip Strip</button>
|
<button class="secondary hidden" id="btnSkip">⏭ Skip Strip</button>
|
||||||
<button class="danger hidden" id="btnCancel">✕ Cancel</button>
|
<button class="danger hidden" id="btnCancel">✕ Cancel</button>
|
||||||
|
|||||||
+93
-20
@@ -23,6 +23,8 @@ const STATE = {
|
|||||||
CALIBRATING: "CALIBRATING",
|
CALIBRATING: "CALIBRATING",
|
||||||
AWAITING_STRIP: "AWAITING_STRIP",
|
AWAITING_STRIP: "AWAITING_STRIP",
|
||||||
READING: "READING",
|
READING: "READING",
|
||||||
|
WARNING: "WARNING",
|
||||||
|
PROMPT_CONTINUE: "PROMPT_CONTINUE",
|
||||||
ERROR: "ERROR",
|
ERROR: "ERROR",
|
||||||
FINISHED: "FINISHED",
|
FINISHED: "FINISHED",
|
||||||
};
|
};
|
||||||
@@ -36,6 +38,7 @@ const recordedPasses = [];
|
|||||||
export function initChartread() {
|
export function initChartread() {
|
||||||
const btnStartRead = document.getElementById("btnStartRead");
|
const btnStartRead = document.getElementById("btnStartRead");
|
||||||
const btnCalibrate = document.getElementById("btnCalibrate");
|
const btnCalibrate = document.getElementById("btnCalibrate");
|
||||||
|
const btnAccept = document.getElementById("btnAccept");
|
||||||
const btnRetry = document.getElementById("btnRetry");
|
const btnRetry = document.getElementById("btnRetry");
|
||||||
const btnSkip = document.getElementById("btnSkip");
|
const btnSkip = document.getElementById("btnSkip");
|
||||||
const btnCancel = document.getElementById("btnCancel");
|
const btnCancel = document.getElementById("btnCancel");
|
||||||
@@ -174,39 +177,71 @@ export function initChartread() {
|
|||||||
if (stateLabel) stateLabel.textContent = newState;
|
if (stateLabel) stateLabel.textContent = newState;
|
||||||
|
|
||||||
// Show/hide buttons based on state
|
// Show/hide buttons based on state
|
||||||
btnCalibrate.classList.add("hidden");
|
if (btnCalibrate) btnCalibrate.classList.add("hidden");
|
||||||
btnRetry.classList.add("hidden");
|
if (btnAccept) btnAccept.classList.add("hidden");
|
||||||
btnSkip.classList.add("hidden");
|
if (btnRetry) btnRetry.classList.add("hidden");
|
||||||
btnCancel.classList.add("hidden");
|
if (btnSkip) btnSkip.classList.add("hidden");
|
||||||
btnStartRead.classList.add("hidden");
|
if (btnCancel) btnCancel.classList.add("hidden");
|
||||||
|
if (btnStartRead) btnStartRead.classList.add("hidden");
|
||||||
|
|
||||||
switch (newState) {
|
switch (newState) {
|
||||||
case STATE.IDLE:
|
case STATE.IDLE:
|
||||||
btnStartRead.classList.remove("hidden");
|
if (btnStartRead) btnStartRead.classList.remove("hidden");
|
||||||
break;
|
break;
|
||||||
case STATE.CALIBRATING:
|
case STATE.CALIBRATING:
|
||||||
btnCalibrate.disabled = false;
|
if (btnCalibrate) {
|
||||||
btnCalibrate.textContent = "✓ Calibrate";
|
btnCalibrate.disabled = false;
|
||||||
btnCalibrate.classList.remove("hidden");
|
btnCalibrate.textContent = "✓ Calibrate";
|
||||||
btnCancel.classList.remove("hidden");
|
btnCalibrate.classList.remove("hidden");
|
||||||
|
}
|
||||||
|
if (btnCancel) btnCancel.classList.remove("hidden");
|
||||||
break;
|
break;
|
||||||
case STATE.AWAITING_STRIP:
|
case STATE.AWAITING_STRIP:
|
||||||
btnRetry.classList.remove("hidden");
|
if (btnRetry) {
|
||||||
btnSkip.classList.remove("hidden");
|
btnRetry.disabled = false;
|
||||||
btnCancel.classList.remove("hidden");
|
btnRetry.textContent = "↻ Retry Strip";
|
||||||
|
btnRetry.classList.remove("hidden");
|
||||||
|
}
|
||||||
|
if (btnSkip) btnSkip.classList.remove("hidden");
|
||||||
|
if (btnCancel) btnCancel.classList.remove("hidden");
|
||||||
break;
|
break;
|
||||||
case STATE.READING:
|
case STATE.READING:
|
||||||
btnCancel.classList.remove("hidden");
|
if (btnCancel) btnCancel.classList.remove("hidden");
|
||||||
|
break;
|
||||||
|
case STATE.WARNING:
|
||||||
|
if (btnAccept) {
|
||||||
|
btnAccept.disabled = false;
|
||||||
|
btnAccept.textContent = "✓ Accept Strip";
|
||||||
|
btnAccept.classList.remove("hidden");
|
||||||
|
}
|
||||||
|
if (btnRetry) {
|
||||||
|
btnRetry.disabled = false;
|
||||||
|
btnRetry.textContent = "↻ Retry Strip";
|
||||||
|
btnRetry.classList.remove("hidden");
|
||||||
|
}
|
||||||
|
if (btnCancel) btnCancel.classList.remove("hidden");
|
||||||
|
break;
|
||||||
|
case STATE.PROMPT_CONTINUE:
|
||||||
|
if (btnAccept) {
|
||||||
|
btnAccept.disabled = false;
|
||||||
|
btnAccept.textContent = "✓ Continue";
|
||||||
|
btnAccept.classList.remove("hidden");
|
||||||
|
}
|
||||||
|
if (btnCancel) btnCancel.classList.remove("hidden");
|
||||||
break;
|
break;
|
||||||
case STATE.ERROR:
|
case STATE.ERROR:
|
||||||
btnRetry.classList.remove("hidden");
|
if (btnRetry) {
|
||||||
btnSkip.classList.remove("hidden");
|
btnRetry.disabled = false;
|
||||||
btnCancel.classList.remove("hidden");
|
btnRetry.textContent = "↻ Retry Strip";
|
||||||
|
btnRetry.classList.remove("hidden");
|
||||||
|
}
|
||||||
|
if (btnSkip) btnSkip.classList.remove("hidden");
|
||||||
|
if (btnCancel) btnCancel.classList.remove("hidden");
|
||||||
break;
|
break;
|
||||||
case STATE.FINISHED:
|
case STATE.FINISHED:
|
||||||
// After a recorded pass, further sheets go through "Measure Another Sheet"
|
// After a recorded pass, further sheets go through "Measure Another Sheet"
|
||||||
if (recordedPasses.length === 0) {
|
if (recordedPasses.length === 0) {
|
||||||
btnStartRead.classList.remove("hidden");
|
if (btnStartRead) btnStartRead.classList.remove("hidden");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -267,7 +302,29 @@ export function initChartread() {
|
|||||||
const lineLower = line.toLowerCase();
|
const lineLower = line.toLowerCase();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(lineLower.includes("place") && (lineLower.includes("reference") || lineLower.includes("white") || lineLower.includes("calibrat"))) ||
|
lineLower.includes("(warning)") ||
|
||||||
|
lineLower.includes("use it anyway") ||
|
||||||
|
lineLower.includes("seem to have read strip pass") ||
|
||||||
|
lineLower.includes("unexpected response") ||
|
||||||
|
lineLower.includes("hit return to use it anyway")
|
||||||
|
) {
|
||||||
|
const previousPrompt = promptText ? promptText.textContent.trim() : "";
|
||||||
|
const isContinuationPrompt = lineLower.includes("hit return to use it anyway") || lineLower.includes("use it anyway");
|
||||||
|
setState(STATE.WARNING);
|
||||||
|
if (currentState === STATE.WARNING && isContinuationPrompt && previousPrompt && !previousPrompt.includes(line.trim())) {
|
||||||
|
setPrompt(`${previousPrompt}\n${line.trim()}`);
|
||||||
|
} else {
|
||||||
|
setPrompt(line.trim());
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
lineLower.includes("place sheet") ||
|
||||||
|
lineLower.includes("remove previous sheet") ||
|
||||||
|
(lineLower.includes("hit return to continue") && !lineLower.includes("use it anyway"))
|
||||||
|
) {
|
||||||
|
setState(STATE.PROMPT_CONTINUE);
|
||||||
|
setPrompt(line.trim());
|
||||||
|
} else if (
|
||||||
|
(lineLower.includes("place") && (lineLower.includes("reference") || lineLower.includes("white") || lineLower.includes("calibrat") || lineLower.includes("standard"))) ||
|
||||||
lineLower.includes("hit any key to continue") ||
|
lineLower.includes("hit any key to continue") ||
|
||||||
lineLower.includes("calibration")
|
lineLower.includes("calibration")
|
||||||
) {
|
) {
|
||||||
@@ -283,7 +340,7 @@ export function initChartread() {
|
|||||||
} else if (lineLower.includes("reading strip") || lineLower.includes("processing")) {
|
} else if (lineLower.includes("reading strip") || lineLower.includes("processing")) {
|
||||||
setState(STATE.READING);
|
setState(STATE.READING);
|
||||||
setPrompt(line.trim());
|
setPrompt(line.trim());
|
||||||
} else if (lineLower.includes("error") || lineLower.includes("too fast") || lineLower.includes("too slow") || lineLower.includes("misread")) {
|
} else if (lineLower.includes("error") || lineLower.includes("too fast") || lineLower.includes("too slow") || lineLower.includes("misread") || lineLower.includes("failed to read")) {
|
||||||
setState(STATE.ERROR);
|
setState(STATE.ERROR);
|
||||||
setPrompt("⚠️ " + line.trim());
|
setPrompt("⚠️ " + line.trim());
|
||||||
}
|
}
|
||||||
@@ -464,6 +521,22 @@ export function initChartread() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Accept / Continue button — sends newline ("\n")
|
||||||
|
if (btnAccept) {
|
||||||
|
btnAccept.addEventListener("click", async () => {
|
||||||
|
try {
|
||||||
|
btnAccept.disabled = true;
|
||||||
|
await invoke("send_stdin", { id: currentProcessId, input: "\n" });
|
||||||
|
setState(STATE.READING);
|
||||||
|
setPrompt("Accepted. Processing...");
|
||||||
|
} catch (e) {
|
||||||
|
console.error("send_stdin error:", e);
|
||||||
|
btnAccept.disabled = false;
|
||||||
|
setPrompt(`Failed to send accept signal: ${e}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Retry button — sends space + newline (same as confirm)
|
// Retry button — sends space + newline (same as confirm)
|
||||||
if (btnRetry) {
|
if (btnRetry) {
|
||||||
btnRetry.addEventListener("click", async () => {
|
btnRetry.addEventListener("click", async () => {
|
||||||
|
|||||||
@@ -455,6 +455,7 @@ button:disabled {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
min-height: 2.8em;
|
min-height: 2.8em;
|
||||||
|
white-space: pre-line;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chartread-actions {
|
.chartread-actions {
|
||||||
|
|||||||
Reference in New Issue
Block a user