From 8ef61a1285862b12c61b33f4b89501bf770cec30 Mon Sep 17 00:00:00 2001 From: "Adriano (daitarn)" Date: Wed, 28 Oct 2026 22:04:20 +0100 Subject: [PATCH] Registra spento sul frame gia' registrato, nuovo grab dopo il reset Refs #123 Co-Authored-By: Claude Sonnet 5.5 --- .../flask_app/static/js/vision_execute.js | 10 +++++++--- .../flask_app/tests/js/test_vision_rows.js | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/frontend/flask_app/static/js/vision_execute.js b/src/frontend/flask_app/static/js/vision_execute.js index d5267f9..883d57f 100644 --- a/src/frontend/flask_app/static/js/vision_execute.js +++ b/src/frontend/flask_app/static/js/vision_execute.js @@ -32,6 +32,7 @@ function visionExecute() { preview: false, // result on screen is an analysis only, not saved saved: false, // «Registra» done: the saved result replaces the preview lastBlob: null, // last frame shown, the one «Registra» saves + recordedBlob: null, // #123: frame saved by the last successful «Registra»: not recordable twice paused: false, // operator paused the in-line loop registering: false, // «Registra» in progress: the loop stands still leaving: false, // page is being left: no more requests @@ -43,8 +44,10 @@ function visionExecute() { // #120: «Rimisura»/nuovo ciclo (task-result-reset): il pezzo va registrato di nuovo, anche senza camera window.addEventListener('task-result-reset', () => { this.saved = false; - this.preview = !!this.result; - this.kick(); + // #123: il frame gia' registrato non e' piu' un'anteprima ne' si registra due volte + this.preview = !!this.result && this.lastBlob !== this.recordedBlob; + // #123: camera impulsiva = frame nuovo subito (come all'apertura); in linea riparte il ciclo + if (this.hasCamera && !this.inLinea) this.grab(); else this.kick(); }); if (!this.hasCamera) return; document.addEventListener('visibilitychange', () => { if (!document.hidden) this.kick(); }); @@ -58,7 +61,7 @@ function visionExecute() { get hasCamera() { return !!(window.__visionCfg || {}).cameraAvailable; }, get inLinea() { return this.hasCamera && (window.__visionCfg || {}).modo === 'in_linea'; }, // «Registra» needs a frame on screen that is not saved yet - get canRecord() { return !!this.lastBlob && !this.saved && !this.registering; }, + get canRecord() { return !!this.lastBlob && this.lastBlob !== this.recordedBlob && !this.saved && !this.registering; }, // #123: non sul frame gia' registrato shouldRun() { return this.inLinea && !this.paused && !this.saved && !this.registering @@ -145,6 +148,7 @@ function visionExecute() { if (!this.error && this.result && this.result.vision_result_id) { this.preview = false; this.saved = true; + this.recordedBlob = blob; // #123: questo frame e' registrato, Registra resta spento finche' non ne arriva uno nuovo this._emitRecorded(); // #120: la pagina conta le quote registrate } } finally { diff --git a/src/frontend/flask_app/tests/js/test_vision_rows.js b/src/frontend/flask_app/tests/js/test_vision_rows.js index af6eec7..c9bdf2c 100644 --- a/src/frontend/flask_app/tests/js/test_vision_rows.js +++ b/src/frontend/flask_app/tests/js/test_vision_rows.js @@ -175,6 +175,26 @@ c5.acquire = async function () { this.result = { vision_result_id: 7, measuremen h(); check('#120 task-result-reset: saved = false', c5.saved === false); + // #123: dopo Registra + task-result-reset Registra e' spento sul frame registrato, anteprima spenta, impulsiva = grab + win.__visionCfg = { cameraAvailable: true, modo: 'impulsiva', subtasks: [] }; + const c9 = ctx.visionExecute(); + let grabs = 0; + c9.grab = async function () { grabs++; }; + c9.lastBlob = { name: 'f1' }; + c9.acquire = async function () { this.result = { vision_result_id: 11, measurements: okMs }; }; + check('#123 prima di Registra: canRecord', c9.canRecord === true); + await c9.record(); + check('#123 dopo Registra: canRecord falso (saved)', c9.canRecord === false && c9.recordedBlob === c9.lastBlob); + c9.$nextTick = () => {}; // #123: nel test nessun grab di apertura + c9.init(); // registra l'ascolto di task-result-reset + grabs = 0; + (listeners['task-result-reset'] || []).slice(-1)[0](); + check('#123 reset sul frame registrato: canRecord falso', c9.canRecord === false && c9.saved === false); + check('#123 reset sul frame registrato: niente badge anteprima', c9.preview === false); + check('#123 reset in impulsiva: un solo grab', grabs === 1, String(grabs)); + c9.lastBlob = { name: 'f2' }; + check('#123 frame nuovo: canRecord vero', c9.canRecord === true); + // #119 #122: saveName = titolo del task (nome proposto da ), 'immagine' se manca win.__visionCfg = { taskName: 'Roto3', subtasks: [] }; check('#122 saveName = nome del task', ctx.visionExecute().saveName === 'Roto3');