Skip to content

Commit ba3d6e4

Browse files
committed
[FIX] web: barcode video scanner double scan
Before this commit, using the `BarcodeVideoScanner` component, it could happen the same barcode is scanned multiple times even if a `delayBetweenScan` is set. My guess is the `detectCode` interval has the time to be called once again before `barcodeDetected` pauses it, which could explain why this bug happens only on some device (slower devices.) To fix this issue, interval is replaced by a timeout, and timeout is re-created every time only when needed (so, it is not recreated immediately if a pause is needed.) closes odoo#176569 Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
1 parent 26ee3c0 commit ba3d6e4

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

addons/web/static/src/webclient/barcode/barcode_video_scanner.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export class BarcodeVideoScanner extends Component {
3232
*/
3333
setup() {
3434
this.videoPreviewRef = useRef("videoPreview");
35-
this.interval = null;
35+
this.detectorTimeout = null;
3636
this.stream = null;
3737
this.detector = null;
3838
this.overlayInfo = {};
@@ -86,12 +86,12 @@ export class BarcodeVideoScanner extends Component {
8686
const settings = track.getSettings();
8787
this.zoomRatio = Math.min(divWidth / settings.width, divHeight / settings.height);
8888
}
89-
this.interval = setInterval(this.detectCode.bind(this), 100);
89+
this.detectorTimeout = setTimeout(this.detectCode.bind(this), 100);
9090
});
9191

9292
onWillUnmount(() => {
93-
clearInterval(this.interval);
94-
this.interval = null;
93+
clearTimeout(this.detectorTimeout);
94+
this.detectorTimeout = null;
9595
if (this.stream) {
9696
this.stream.getTracks().forEach((track) => track.stop());
9797
this.stream = null;
@@ -129,11 +129,10 @@ export class BarcodeVideoScanner extends Component {
129129
* Attempt to detect codes in the current camera preview's frame
130130
*/
131131
async detectCode() {
132-
if (this.scanPaused) {
133-
return;
134-
}
132+
let barcodeDetected = false;
135133
try {
136134
const codes = await this.detector.detect(this.videoPreviewRef.el);
135+
barcodeDetected = Boolean(codes.length);
137136
for (const code of codes) {
138137
if (!this.isZXingBarcodeDetector() && this.overlayInfo.x && this.overlayInfo.y) {
139138
const { x, y, width, height } = this.adaptValuesWithRatio(code.boundingBox);
@@ -152,13 +151,17 @@ export class BarcodeVideoScanner extends Component {
152151
} catch (err) {
153152
this.props.onError(err);
154153
}
154+
if (!barcodeDetected || !this.props.delayBetweenScan) {
155+
this.detectorTimeout = setTimeout(this.detectCode.bind(this), 100);
156+
}
155157
}
156158

157159
barcodeDetected(barcode) {
158160
if (this.props.delayBetweenScan && !this.scanPaused) {
159161
this.scanPaused = true;
160-
setTimeout(() => {
162+
this.detectorTimeout = setTimeout(() => {
161163
this.scanPaused = false;
164+
this.detectorTimeout = setTimeout(this.detectCode.bind(this), 100);
162165
}, this.props.delayBetweenScan);
163166
}
164167
this.props.onResult(barcode);

0 commit comments

Comments
 (0)