Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-qr-scanner

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-qr-scanner - npm Package Compare versions

Comparing version 0.0.8 to 0.0.9

.storybook/main.js

4

.eslintrc.json

@@ -75,7 +75,7 @@ {

"react/react-in-jsx-scope": "warn",
"react/require-extension": "warn",
"react/require-extension": "off",
"react/self-closing-comp": "warn",
"react/sort-comp": "warn",
"react/wrap-multilines": "warn"
"react/jsx-wrap-multilines": "warn"
}
}

@@ -23,3 +23,3 @@ const gulp = require('gulp')

gulp.task('worker', [ 'clean' ], function() {
gulp.task('worker', gulp.series('clean', function() {
return gulp

@@ -30,5 +30,5 @@ .src([ paths.jsQR, paths.worker ])

.pipe(gulp.dest(paths.destination))
})
}))
gulp.task('build', [ 'worker' ], function() {
gulp.task('build', gulp.series('worker', function() {
return gulp

@@ -39,10 +39,10 @@ .src(paths.scripts)

.pipe(gulp.dest(paths.destination))
})
}))
// Rerun the task when a file changes
gulp.task('watch', function() {
gulp.watch(paths.scripts, [ 'build' ])
gulp.watch(paths.scripts, gulp.series('build'))
})
// The default task (called when you run `gulp` from cli)
gulp.task('default', [ 'build' ])
gulp.task('default', gulp.series('build'))

@@ -1,3 +0,1 @@

"use strict";
function NoVideoInputDevicesError() {

@@ -9,4 +7,4 @@ this.name = 'NoVideoInputDevicesError';

NoVideoInputDevicesError.prototype = new Error();
module.exports = {
export default {
NoVideoInputDevicesError: NoVideoInputDevicesError
};

@@ -1,3 +0,1 @@

"use strict";
var _require = require('./errors'),

@@ -11,3 +9,3 @@ NoVideoInputDevicesError = _require.NoVideoInputDevicesError;

module.exports = function getDeviceId(facingMode) {
function getDeviceId(facingMode) {
var chooseDeviceId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultDeviceIdChooser;

@@ -48,2 +46,4 @@ // Get manual deviceId from available devices.

});
};
}
export default getDeviceId;

@@ -1,4 +0,2 @@

"use strict";
module.exports = function havePropsChanged(prevProps, nextProps, keys) {
function havePropsChanged(prevProps, nextProps, keys) {
var changedProps = [];

@@ -11,2 +9,4 @@ keys.forEach(function (key) {

return changedProps;
};
}
export default havePropsChanged;
{
"name": "react-qr-scanner",
"version": "0.0.8",
"version": "0.0.9",
"description": "A react component for reading QR codes from the webcam.",

@@ -31,31 +31,33 @@ "main": "./lib/index.js",

"devDependencies": {
"@babel/cli": "^7.0.0",
"@babel/core": "^7.1.2",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-do-expressions": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
"@babel/plugin-proposal-function-bind": "^7.0.0",
"@babel/plugin-proposal-function-sent": "^7.0.0",
"@babel/plugin-proposal-json-strings": "^7.0.0",
"@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/preset-env": "^7.1.0",
"@babel/preset-react": "^7.0.0",
"@storybook/addon-actions": "^3.4.11",
"@storybook/cli": "^3.4.11",
"@storybook/react": "^3.4.11",
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.6",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/plugin-proposal-decorators": "^7.8.3",
"@babel/plugin-proposal-do-expressions": "^7.8.3",
"@babel/plugin-proposal-export-default-from": "^7.8.3",
"@babel/plugin-proposal-export-namespace-from": "^7.8.3",
"@babel/plugin-proposal-function-bind": "^7.8.3",
"@babel/plugin-proposal-function-sent": "^7.8.3",
"@babel/plugin-proposal-json-strings": "^7.8.3",
"@babel/plugin-proposal-logical-assignment-operators": "^7.8.3",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
"@babel/plugin-proposal-numeric-separator": "^7.8.3",
"@babel/plugin-proposal-optional-chaining": "^7.9.0",
"@babel/plugin-proposal-pipeline-operator": "^7.8.3",
"@babel/plugin-proposal-throw-expressions": "^7.8.3",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-import-meta": "^7.8.3",
"@babel/preset-env": "^7.9.6",
"@babel/preset-react": "^7.9.4",
"@storybook/addon-actions": "^5.3.18",
"@storybook/cli": "^5.3.18",
"@storybook/react": "^5.3.18",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.1",
"del": "^3.0.0",
"eslint": "^5.6.1",
"eslint-plugin-react": "^7.11.1",
"gulp": "^3.9.1",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.1.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"del": "^5.1.0",
"eslint": "^6.8.0",
"eslint-plugin-react": "^7.19.0",
"gulp": "^4.0.2",
"gulp-babel": "^8.0.0",

@@ -67,8 +69,8 @@ "gulp-butternut": "^1.0.0",

"dependencies": {
"jsqr": "^1.1.1",
"prop-types": "^15.6.2",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"webrtc-adapter": "^6.4.0"
"jsqr": "^1.3.1",
"prop-types": "^15.7.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"webrtc-adapter": "^7.5.1"
}
}

@@ -7,4 +7,4 @@ function NoVideoInputDevicesError() {

module.exports = {
export default {
NoVideoInputDevicesError,
}

@@ -10,3 +10,3 @@ const { NoVideoInputDevicesError } = require('./errors')

module.exports = function getDeviceId(facingMode, chooseDeviceId = defaultDeviceIdChooser) {
function getDeviceId(facingMode, chooseDeviceId = defaultDeviceIdChooser) {
// Get manual deviceId from available devices.

@@ -47,1 +47,3 @@ return new Promise((resolve, reject) => {

}
export default getDeviceId

@@ -1,2 +0,2 @@

module.exports = function havePropsChanged(prevProps, nextProps, keys) {
function havePropsChanged(prevProps, nextProps, keys) {
const changedProps = []

@@ -10,1 +10,3 @@ keys.forEach(key => {

}
export default havePropsChanged

@@ -1,6 +0,5 @@

const React = require('react')
const { Component } = React
const PropTypes = require('prop-types')
const getDeviceId = require('./getDeviceId')
const havePropsChanged = require('./havePropsChanged')
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import getDeviceId from './getDeviceId'
import havePropsChanged from './havePropsChanged'

@@ -11,2 +10,3 @@ // Require adapter to support older browser implementations

// Inline worker.js as a string value of workerBlob.
// eslint-disable-next-line no-undef
const workerBlob = new Blob([__inline('../lib/worker.js')], {

@@ -19,27 +19,8 @@ type: 'application/javascript',

module.exports = class Reader extends Component {
static propTypes = {
onScan: PropTypes.func.isRequired,
onError: PropTypes.func.isRequired,
onLoad: PropTypes.func,
onImageLoad: PropTypes.func,
delay: PropTypes.oneOfType([PropTypes.number, PropTypes.bool]),
facingMode: PropTypes.oneOf(['rear', 'front']),
legacyMode: PropTypes.bool,
maxImageSize: PropTypes.number,
style: PropTypes.any,
className: PropTypes.string,
chooseDeviceId: PropTypes.func,
};
static defaultProps = {
delay: 500,
maxImageSize: 1000,
facingMode: 'rear',
};
class Reader extends Component {
els = {};
constructor(props) {
super(props)
this.els = {}
// Bind function to the class

@@ -58,2 +39,3 @@ this.initiate = this.initiate.bind(this)

}
componentDidMount() {

@@ -70,3 +52,4 @@ // Initiate web worker execute handler according to mode.

}
componentWillReceiveProps(nextProps) {
shouldComponentUpdate(nextProps) {
// React according to change in props

@@ -76,14 +59,14 @@ const changedProps = havePropsChanged(this.props, nextProps, propsKeys)

for (const prop of changedProps) {
if (prop == 'facingMode') {
if (prop === 'facingMode') {
this.clearComponent()
this.initiate(nextProps)
break
} else if (prop == 'delay') {
if (this.props.delay == false && !nextProps.legacyMode) {
} else if (prop === 'delay') {
if (this.props.delay === false && !nextProps.legacyMode) {
this.timeout = setTimeout(this.check, nextProps.delay)
}
if (nextProps.delay == false) {
if (nextProps.delay === false) {
clearTimeout(this.timeout)
}
} else if (prop == 'legacyMode') {
} else if (prop === 'legacyMode') {
if (this.props.legacyMode && !nextProps.legacyMode) {

@@ -99,8 +82,7 @@ this.clearComponent()

}
}
shouldComponentUpdate(nextProps) {
// Only render when the `propsKeys` have changed.
const changedProps = havePropsChanged(this.props, nextProps, propsKeys)
return changedProps.length > 0
}
componentWillUnmount() {

@@ -114,2 +96,3 @@ // Stop web-worker and clear the component

}
clearComponent() {

@@ -131,2 +114,3 @@ // Remove all event listeners and variables

}
initiate(props = this.props) {

@@ -148,2 +132,3 @@ const { onError, facingMode, chooseDeviceId } = props

}
handleVideo(stream) {

@@ -153,3 +138,3 @@ const { preview } = this.els

// Handle different browser implementations of MediaStreams as src
if(preview.srcObject !== undefined){
if (preview.srcObject !== undefined) {
preview.srcObject = stream

@@ -175,2 +160,3 @@ } else if (preview.mozSrcObject !== undefined) {

}
handleLoadStart() {

@@ -181,7 +167,7 @@ const { delay, onLoad } = this.props

if(typeof onLoad == 'function') {
if (typeof onLoad === 'function') {
onLoad()
}
if (typeof delay == 'number') {
if (typeof delay === 'number') {
this.timeout = setTimeout(this.check, delay)

@@ -193,2 +179,3 @@ }

}
check() {

@@ -207,3 +194,3 @@ const { legacyMode, maxImageSize, delay } = this.props

const greatestSize = width > height ? width : height
if(greatestSize > maxImageSize){
if (greatestSize > maxImageSize) {
const ratio = maxImageSize / greatestSize

@@ -233,12 +220,21 @@ height = ratio * height

}
handleWorkerMessage(e) {
const { onScan, legacyMode, delay } = this.props
const { preview, canvas, img } = this.els
const decoded = e.data
if (decoded && decoded.data) {
const ctx = canvas.getContext('2d')
ctx.drawImage(legacyMode ? img : preview, 0, 0, canvas.width, canvas.height)
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
onScan(decoded.data, imageData)
} else {
onScan(null)
}
onScan((decoded && decoded.data) || null)
if (!legacyMode && typeof delay == 'number' && this.worker) {
if (!legacyMode && typeof delay === 'number' && this.worker) {
this.timeout = setTimeout(this.check, delay)
}
}
initiateLegacyMode() {

@@ -252,6 +248,7 @@ this.reader = new FileReader()

if(typeof this.props.onLoad == 'function') {
if (typeof this.props.onLoad === 'function') {
this.props.onLoad()
}
}
handleInputChange(e) {

@@ -261,2 +258,3 @@ const selectedImg = e.target.files[0]

}
handleReaderLoad(e) {

@@ -266,2 +264,3 @@ // Set selected image blob as img source

}
openImageDialog() {

@@ -271,2 +270,3 @@ // Function to be executed by parent in user action context to trigger img file uploader

}
setRefFactory(key) {

@@ -277,2 +277,3 @@ return element => {

}
render() {

@@ -307,1 +308,23 @@ const { style, className, onImageLoad, legacyMode } = this.props

}
Reader.propTypes = {
onScan: PropTypes.func.isRequired,
onError: PropTypes.func.isRequired,
onLoad: PropTypes.func,
onImageLoad: PropTypes.func,
delay: PropTypes.oneOfType([PropTypes.number, PropTypes.bool]),
facingMode: PropTypes.oneOf(['rear', 'front']),
legacyMode: PropTypes.bool,
maxImageSize: PropTypes.number,
style: PropTypes.any,
className: PropTypes.string,
chooseDeviceId: PropTypes.func,
}
Reader.defaultProps = {
delay: 500,
maxImageSize: 1000,
facingMode: 'rear',
}
export default Reader
// jsQR is concatenated by gulp
self.addEventListener('message', function(e) {
self.addEventListener('message', function (e) {
// eslint-disable-next-line no-undef
const decoded = jsQR(

@@ -5,0 +6,0 @@ e.data.data,

@@ -1,5 +0,5 @@

import React, { Component } from 'react'
import { storiesOf } from '@storybook/react'
import { action } from '@storybook/addon-actions'
import Reader from './lib'
import React, { Component } from "react";
import { storiesOf } from "@storybook/react";
import { action } from '@storybook/addon-actions';
import Reader from "./lib";

@@ -9,6 +9,43 @@ class Wrapper extends Component {

super(props)
this.state = { facingMode: 'front', delay: 500 }
this.state = { cameraId: undefined, delay: 500, devices: [], loading: false }
}
componentWillMount() {
const { selectFacingMode } = this.props
if (navigator && selectFacingMode) {
this.setState({
loading: true,
})
navigator.mediaDevices.enumerateDevices()
.then((devices) => {
const videoSelect = []
devices.forEach((device) => {
if (device.kind === 'videoinput') {
videoSelect.push(device)
}
})
return videoSelect
})
.then((devices) => {
this.setState({
cameraId: devices[0].deviceId,
devices,
loading: false,
})
})
.catch((error) => {
console.log(error)
})
}
}
selectCamera = () => {
return this.state.cameraId
}
render() {
const { selectFacingMode, selectDelay, legacyMode } = this.props
const { cameraId, devices } = this.state

@@ -19,28 +56,35 @@ const previewStyle = { width: 320 }

{
selectFacingMode && (
<select
onChange={e => this.setState({ facingMode: e.target.value })}
>
<option value="front">Front</option>
<option value="rear">Rear</option>
</select>
)
selectFacingMode && devices.length && (
<select
onChange={e => {
const value = e.target.value
this.setState({ cameraId: undefined }, () => {
this.setState({ cameraId: value })
})
}}
>
{devices.map((deviceInfo, index) => (
<React.Fragment key={deviceInfo.deviceId}><option value={deviceInfo.deviceId}>{deviceInfo.label || `camera ${index}`}</option></React.Fragment>
))}
</select>
)
}
{
selectDelay && (
<div>
<button onClick={() => this.setState({ delay: false })}>
Disable Delay
<div>
<button onClick={() => this.setState({ delay: false })}>
Disable Delay
</button>
<input
placeholder="Delay in ms"
type="number"
value={this.state.delay}
onChange={e =>
this.setState({ delay: parseInt(e.target.value) })}
/>
</div>
)
<input
placeholder="Delay in ms"
type="number"
value={this.state.delay}
onChange={e =>
this.setState({ delay: parseInt(e.target.value) })}
/>
</div>
)
}
<Reader
{(cameraId || !selectFacingMode) && (<Reader
chooseDeviceId={this.selectCamera}
style={previewStyle}

@@ -52,3 +96,2 @@ onError={action('Error')}

ref="reader"
facingMode={this.state.facingMode}
legacyMode={legacyMode}

@@ -58,9 +101,9 @@ maxImageSize={1000}

className="reader-container"
/>
/>)}
{
legacyMode && (
<button onClick={() => this.refs.reader.openImageDialog()}>
Open Image Dialog
<button onClick={() => this.refs.reader.openImageDialog()}>
Open Image Dialog
</button>
)
)
}

@@ -72,6 +115,6 @@ </div>

storiesOf('QR Reader', module)
.add('FacingMode not specified', () => <Wrapper />)
.add('Choose facingMode', () => <Wrapper selectFacingMode />)
storiesOf("QR Reader", module)
.add('Camera not specified', () => <Wrapper />)
.add('Choose camera', () => <Wrapper selectFacingMode />)
.add('Legacy mode', () => <Wrapper legacyMode />)
.add('Choose delay', () => <Wrapper selectDelay />)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc