From 947bfb7a118f3743e50fa2dd3c83e75d38c9207a Mon Sep 17 00:00:00 2001 From: David Walsh Date: Wed, 14 Oct 2020 16:48:09 -0500 Subject: [PATCH 1/3] Fix #9043 - Ensure QR code scanner works --- .../modals/qr-scanner/qr-scanner.component.js | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js index d78db3d14..330bd3fa4 100644 --- a/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js @@ -104,15 +104,28 @@ export default class QrScanner extends Component { componentWillUnmount () { this.mounted = false clearTimeout(this.permissionChecker) - if (this.codeReader) { - this.codeReader.reset() + this.teardownCodeReader(); + } + + teardownCodeReader() { + if(this.codeReader) { + this.codeReader.reset(); + this.codeReader.stop(); + this.codeReader = null; } } initCamera = async () => { + // The `decodeFromInputVideoDevice` call prompts the browser to show + // the user the camera permission request. We must then call it again + // once we receive permission so that the video displays. + // Removing this teardown will create 2 video streams in Firefox, one + // of which the user will not be able to remove without refreshing the page. + this.teardownCodeReader(); this.codeReader = new BrowserQRCodeReader() try { await this.codeReader.getVideoInputDevices() + this.checkPermissions(); const content = await this.codeReader.decodeFromInputVideoDevice(undefined, 'video') const result = this.parseContent(content.text) if (!this.mounted) { @@ -162,7 +175,7 @@ export default class QrScanner extends Component { stopAndClose = () => { if (this.codeReader) { - this.codeReader.reset() + this.teardownCodeReader(); } this.props.hideModal() } @@ -170,7 +183,7 @@ export default class QrScanner extends Component { tryAgain = () => { clearTimeout(this.permissionChecker) if (this.codeReader) { - this.codeReader.reset() + this.teardownCodeReader() } this.setState(this.getInitialState(), () => { this.checkEnvironment() From 15654b3d0bb627c0ee4f62a13a8c2cba2a8f3c62 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Wed, 14 Oct 2020 17:05:36 -0500 Subject: [PATCH 2/3] Prevent unnecessary teardown --- .../app/modals/qr-scanner/qr-scanner.component.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js index 330bd3fa4..cb95195a5 100644 --- a/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js @@ -119,10 +119,11 @@ export default class QrScanner extends Component { // The `decodeFromInputVideoDevice` call prompts the browser to show // the user the camera permission request. We must then call it again // once we receive permission so that the video displays. - // Removing this teardown will create 2 video streams in Firefox, one - // of which the user will not be able to remove without refreshing the page. - this.teardownCodeReader(); - this.codeReader = new BrowserQRCodeReader() + // It's important to prevent this codeReader from being created twice; + // Firefox otherwise starts 2 video streams, one of which cannot be stopped + if(!this.codeReader) { + this.codeReader = new BrowserQRCodeReader() + } try { await this.codeReader.getVideoInputDevices() this.checkPermissions(); From 998748430182e33d30018ff6ff77796ab4689ad3 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Wed, 14 Oct 2020 17:07:15 -0500 Subject: [PATCH 3/3] Fix lint --- .../modals/qr-scanner/qr-scanner.component.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js index cb95195a5..e49309adc 100644 --- a/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/app/modals/qr-scanner/qr-scanner.component.js @@ -104,14 +104,14 @@ export default class QrScanner extends Component { componentWillUnmount () { this.mounted = false clearTimeout(this.permissionChecker) - this.teardownCodeReader(); + this.teardownCodeReader() } - teardownCodeReader() { - if(this.codeReader) { - this.codeReader.reset(); - this.codeReader.stop(); - this.codeReader = null; + teardownCodeReader () { + if (this.codeReader) { + this.codeReader.reset() + this.codeReader.stop() + this.codeReader = null } } @@ -121,12 +121,12 @@ export default class QrScanner extends Component { // once we receive permission so that the video displays. // It's important to prevent this codeReader from being created twice; // Firefox otherwise starts 2 video streams, one of which cannot be stopped - if(!this.codeReader) { + if (!this.codeReader) { this.codeReader = new BrowserQRCodeReader() } try { await this.codeReader.getVideoInputDevices() - this.checkPermissions(); + this.checkPermissions() const content = await this.codeReader.decodeFromInputVideoDevice(undefined, 'video') const result = this.parseContent(content.text) if (!this.mounted) { @@ -176,7 +176,7 @@ export default class QrScanner extends Component { stopAndClose = () => { if (this.codeReader) { - this.teardownCodeReader(); + this.teardownCodeReader() } this.props.hideModal() }