From 008cdb9001f9472269519db6a2307b40499410af Mon Sep 17 00:00:00 2001 From: jodusnodus Date: Fri, 12 May 2017 16:01:18 +0200 Subject: [PATCH] Build --- gulpfile.js | 37 ++++++++++++++++++------------------- lib/errors.js | 11 +++++++++++ lib/getDeviceId.js | 13 +++++++++++-- lib/index.js | 4 ++-- story.js | 2 +- 5 files changed, 43 insertions(+), 24 deletions(-) create mode 100644 lib/errors.js diff --git a/gulpfile.js b/gulpfile.js index 9e66361..a87189f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,44 +1,43 @@ -const gulp = require('gulp'); -const fs = require('fs'); -const del = require('del'); -const inlineStr = require('gulp-inline-str'); -const babel = require('gulp-babel'); -const uglify = require('gulp-uglify'); -const concat = require('gulp-concat'); +const gulp = require('gulp') +const fs = require('fs') +const del = require('del') +const inlineStr = require('gulp-inline-str') +const babel = require('gulp-babel') +const uglify = require('gulp-uglify') +const concat = require('gulp-concat') -const babelOptions = JSON.parse(fs.readFileSync('./.babelrc', 'utf8')); +const babelOptions = JSON.parse(fs.readFileSync('./.babelrc', 'utf8')) const paths = { - scripts: [ 'src/index.js', 'src/getDeviceId.js', 'src/havePropsChanged.js' ], scripts: [ 'src/index.js', 'src/getDeviceId.js', 'src/havePropsChanged.js', 'src/errors.js' ], worker: 'src/worker.js', jsQR: 'node_modules/jsqr/dist/jsQR.js', destination: './lib', -}; +} gulp.task('clean', function() { - return del([ paths.destination + '/*.js' ]); -}); + return del([ paths.destination + '/*.js' ]) +}) gulp.task('worker', [ 'clean' ], function() { return gulp .src([ paths.jsQR, paths.worker ]) .pipe(concat('worker.js')) - .pipe(gulp.dest(paths.destination)); -}); + .pipe(gulp.dest(paths.destination)) +}) gulp.task('build', [ 'worker' ], function() { return gulp .src(paths.scripts) .pipe(inlineStr({ basePath: paths.destination })) .pipe(babel(babelOptions)) - .pipe(gulp.dest(paths.destination)); -}); + .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, [ 'build' ]) +}) // The default task (called when you run `gulp` from cli) -gulp.task('default', [ 'watch', 'build' ]); +gulp.task('default', [ 'watch', 'build' ]) diff --git a/lib/errors.js b/lib/errors.js new file mode 100644 index 0000000..89ba4f9 --- /dev/null +++ b/lib/errors.js @@ -0,0 +1,11 @@ +'use strict'; + +function NoVideoInputDevicesError() { + this.name = 'NoVideoInputDevicesError'; + this.message = 'No video input devices found'; +} +NoVideoInputDevicesError.prototype = new Error(); + +module.exports = { + NoVideoInputDevicesError: NoVideoInputDevicesError +}; \ No newline at end of file diff --git a/lib/getDeviceId.js b/lib/getDeviceId.js index 5b89c51..664c9ac 100644 --- a/lib/getDeviceId.js +++ b/lib/getDeviceId.js @@ -1,16 +1,25 @@ 'use strict'; +var _require = require('./errors'), + NoVideoInputDevicesError = _require.NoVideoInputDevicesError; + module.exports = function getDeviceId(facingMode) { // Get manual deviceId from available devices. return new Promise(function (resolve, reject) { - navigator.mediaDevices.enumerateDevices().then(function (devices) { + var enumerateDevices = void 0; + try { + enumerateDevices = navigator.mediaDevices.enumerateDevices(); + } catch (err) { + reject(new NoVideoInputDevicesError()); + } + enumerateDevices.then(function (devices) { // Filter out non-videoinputs var videoDevices = devices.filter(function (device) { return device.kind == 'videoinput'; }); if (videoDevices.length < 1) { - reject(new Error('No video input devices found')); + reject(new NoVideoInputDevicesError()); return; } else if (videoDevices.length == 1) { // Only 1 video device available thus stop here diff --git a/lib/index.js b/lib/index.js index 4a1d30f..aab4fe3 100644 --- a/lib/index.js +++ b/lib/index.js @@ -4,7 +4,7 @@ var workerBlob=new Blob(["(function webpackUniversalModuleDefinition(root, facto var propsKeys=['delay','legacyMode','facingMode'];module.exports=(_temp=_class=function(_Component){_inherits(Reader,_Component);function Reader(props){_classCallCheck(this,Reader);// Bind function to the class var _this=_possibleConstructorReturn(this,(Reader.__proto__||Object.getPrototypeOf(Reader)).call(this,props));_this.els={};_this.initiate=_this.initiate.bind(_this);_this.initiateLegacyMode=_this.initiateLegacyMode.bind(_this);_this.check=_this.check.bind(_this);_this.handleVideo=_this.handleVideo.bind(_this);_this.handleLoadStart=_this.handleLoadStart.bind(_this);_this.handleInputChange=_this.handleInputChange.bind(_this);_this.clearComponent=_this.clearComponent.bind(_this);_this.handleReaderLoad=_this.handleReaderLoad.bind(_this);_this.openImageDialog=_this.openImageDialog.bind(_this);_this.handleWorkerMessage=_this.handleWorkerMessage.bind(_this);_this.setRefFactory=_this.setRefFactory.bind(_this);return _this;}_createClass(Reader,[{key:'componentDidMount',value:function componentDidMount(){// Initiate web worker execute handler according to mode. this.worker=new Worker(URL.createObjectURL(workerBlob));this.worker.onmessage=this.handleWorkerMessage;if(!this.props.legacyMode){this.initiate();}else{this.initiateLegacyMode();}}},{key:'componentWillReceiveProps',value:function componentWillReceiveProps(nextProps){// React according to change in props -var changedProps=havePropsChanged(this.props,nextProps,propsKeys);var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=changedProps[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var prop=_step.value;if(prop=='facingMode'){this.clearComponent();this.initiate(nextProps);break;}else if(prop=='delay'){if(this.props.delay==false){this.timeout=setTimeout(this.check,this.props.delay);}else if(nextProps.delay==false){clearTimeout(this.timeout);}}else if(prop=='legacyMode'){if(this.props.legacyMode&&!nextProps.legacyMode){this.clearComponent();this.initiate(nextProps);}else{this.clearComponent();this.componentDidUpdate=this.initiateLegacyMode;}break;}}}catch(err){_didIteratorError=true;_iteratorError=err;}finally{try{if(!_iteratorNormalCompletion&&_iterator.return){_iterator.return();}}finally{if(_didIteratorError){throw _iteratorError;}}}}},{key:'shouldComponentUpdate',value:function shouldComponentUpdate(nextProps){// Only render when the `propsKeys` have changed. +var changedProps=havePropsChanged(this.props,nextProps,propsKeys);var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=changedProps[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var prop=_step.value;if(prop=='facingMode'){this.clearComponent();this.initiate(nextProps);break;}else if(prop=='delay'){if(this.props.delay==false&&!nextProps.legacyMode){this.timeout=setTimeout(this.check,nextProps.delay);}if(nextProps.delay==false){clearTimeout(this.timeout);}}else if(prop=='legacyMode'){if(this.props.legacyMode&&!nextProps.legacyMode){this.clearComponent();this.initiate(nextProps);}else{this.clearComponent();this.componentDidUpdate=this.initiateLegacyMode;}break;}}}catch(err){_didIteratorError=true;_iteratorError=err;}finally{try{if(!_iteratorNormalCompletion&&_iterator.return){_iterator.return();}}finally{if(_didIteratorError){throw _iteratorError;}}}}},{key:'shouldComponentUpdate',value:function shouldComponentUpdate(nextProps){// Only render when the `propsKeys` have changed. var changedProps=havePropsChanged(this.props,nextProps,propsKeys);return changedProps.length>0;}},{key:'componentWillUnmount',value:function componentWillUnmount(){// Stop web-worker and clear the component if(this.worker){this.worker.terminate();this.worker=undefined;}this.clearComponent();}},{key:'clearComponent',value:function clearComponent(){// Remove all event listeners and variables if(this.timeout){clearTimeout(this.timeout);this.timeout=undefined;}if(this.stopCamera){this.stopCamera();}if(this.reader){this.reader.removeEventListener('load',this.handleReaderLoad);}if(this.els.img){this.els.img.removeEventListener('load',this.check);}}},{key:'initiate',value:function initiate(){var props=arguments.length>0&&arguments[0]!==undefined?arguments[0]:this.props;var onError=props.onError,facingMode=props.facingMode;getDeviceId(facingMode).then(function(deviceId){return navigator.mediaDevices.getUserMedia({video:{deviceId:deviceId,facingMode:facingMode=='rear'?'environment':'user',width:{min:360,ideal:1280,max:1920},height:{min:240,ideal:720,max:1080}}});}).then(this.handleVideo).catch(onError);}},{key:'handleVideo',value:function handleVideo(stream){var preview=this.els.preview;// Handle different browser implementations of `createObjectURL` @@ -17,4 +17,4 @@ this.worker.postMessage(imageData);}else{// Preview not ready -> check later this.timeout=setTimeout(this.check,delay);}}},{key:'handleWorkerMessage',value:function handleWorkerMessage(e){var _props3=this.props,onScan=_props3.onScan,legacyMode=_props3.legacyMode,delay=_props3.delay;var decoded=e.data;onScan(decoded||null);if(!legacyMode&&typeof delay=='number'&&this.worker){this.timeout=setTimeout(this.check,delay);}}},{key:'initiateLegacyMode',value:function initiateLegacyMode(){this.reader=new FileReader();this.reader.addEventListener('load',this.handleReaderLoad);this.els.img.addEventListener('load',this.check,false);// Reset componentDidUpdate this.componentDidUpdate=undefined;if(typeof this.props.onLoad=='function'){this.props.onLoad();}}},{key:'handleInputChange',value:function handleInputChange(e){var selectedImg=e.target.files[0];this.reader.readAsDataURL(selectedImg);}},{key:'handleReaderLoad',value:function handleReaderLoad(e){// Set selected image blob as img source this.els.img.src=e.target.result;}},{key:'openImageDialog',value:function openImageDialog(){// Function to be executed by parent in user action context to trigger img file uploader -this.els.input.click();}},{key:'setRefFactory',value:function setRefFactory(key){var _this2=this;return function(element){_this2.els[key]=element;};}},{key:'render',value:function render(){var hiddenStyle={display:'none'};var previewStyle=_extends({display:'block',objectFit:'contain'},this.props.style);return React.createElement('section',null,this.props.legacyMode?React.createElement('div',null,React.createElement('input',{style:hiddenStyle,type:'file',accept:'image/*',ref:this.setRefFactory('input'),onChange:this.handleInputChange}),React.createElement('img',{style:previewStyle,ref:this.setRefFactory('img')})):React.createElement('video',{style:previewStyle,ref:this.setRefFactory('preview')}),React.createElement('canvas',{style:hiddenStyle,ref:this.setRefFactory('canvas')}));}}]);return Reader;}(Component),_class.propTypes={onScan:PropTypes.func.isRequired,onError:PropTypes.func.isRequired,onLoad:PropTypes.func,delay:PropTypes.oneOfType([PropTypes.number,PropTypes.bool]),facingMode:PropTypes.string,legacyMode:PropTypes.bool,maxImageSize:PropTypes.number,style:PropTypes.object},_class.defaultProps={delay:500,style:{},maxImageSize:1500},_temp); \ No newline at end of file +this.els.input.click();}},{key:'setRefFactory',value:function setRefFactory(key){var _this2=this;return function(element){_this2.els[key]=element;};}},{key:'render',value:function render(){var hiddenStyle={display:'none'};var previewStyle=_extends({display:'block',objectFit:'contain'},this.props.style);return React.createElement('section',{className:this.props.className},this.props.legacyMode?React.createElement('div',null,React.createElement('input',{style:hiddenStyle,type:'file',accept:'image/*',ref:this.setRefFactory('input'),onChange:this.handleInputChange}),React.createElement('img',{style:previewStyle,ref:this.setRefFactory('img')})):React.createElement('video',{style:previewStyle,ref:this.setRefFactory('preview')}),React.createElement('canvas',{style:hiddenStyle,ref:this.setRefFactory('canvas')}));}}]);return Reader;}(Component),_class.propTypes={onScan:PropTypes.func.isRequired,onError:PropTypes.func.isRequired,onLoad:PropTypes.func,delay:PropTypes.oneOfType([PropTypes.number,PropTypes.bool]),facingMode:PropTypes.string,legacyMode:PropTypes.bool,maxImageSize:PropTypes.number,style:PropTypes.object,className:PropTypes.string},_class.defaultProps={delay:500,style:{},maxImageSize:1500},_temp); \ No newline at end of file diff --git a/story.js b/story.js index f879271..bd63572 100644 --- a/story.js +++ b/story.js @@ -24,7 +24,7 @@ class Wrapper extends Component { ) } { - selectDelay && ( + (selectDelay || legacyMode) && (