diff --git a/index.js b/index.js index 1dd6bd9..4c6c555 100644 --- a/index.js +++ b/index.js @@ -3,347 +3,332 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import { StyleSheet, Dimensions, Vibration, Animated, Easing, View, Text, Platform, TouchableWithoutFeedback, PermissionsAndroid } from 'react-native'; +import { + StyleSheet, + Dimensions, + Vibration, + Animated, + Easing, + View, + Text, + Platform, + PermissionsAndroid +} from 'react-native'; import { request, PERMISSIONS, RESULTS } from 'react-native-permissions'; import { RNCamera as Camera } from 'react-native-camera'; const CAMERA_FLASH_MODE = Camera.Constants.FlashMode; -const CAMERA_FLASH_MODES = [CAMERA_FLASH_MODE.torch, CAMERA_FLASH_MODE.on, CAMERA_FLASH_MODE.off, CAMERA_FLASH_MODE.auto]; +const CAMERA_FLASH_MODES = [ + CAMERA_FLASH_MODE.torch, + CAMERA_FLASH_MODE.on, + CAMERA_FLASH_MODE.off, + CAMERA_FLASH_MODE.auto +]; export default class QRCodeScanner extends Component { - static propTypes = { - onRead: PropTypes.func.isRequired, - vibrate: PropTypes.bool, - reactivate: PropTypes.bool, - reactivateTimeout: PropTypes.number, - cameraTimeout: PropTypes.number, - fadeIn: PropTypes.bool, - showMarker: PropTypes.bool, - cameraType: PropTypes.oneOf(['front', 'back']), - customMarker: PropTypes.element, - containerStyle: PropTypes.any, - cameraStyle: PropTypes.any, - markerStyle: PropTypes.any, - topViewStyle: PropTypes.any, - bottomViewStyle: PropTypes.any, - topContent: PropTypes.oneOfType([PropTypes.element, PropTypes.string]), - bottomContent: PropTypes.oneOfType([PropTypes.element, PropTypes.string]), - notAuthorizedView: PropTypes.element, - permissionDialogTitle: PropTypes.string, - permissionDialogMessage: PropTypes.string, - buttonPositive: PropTypes.string, - checkAndroid6Permissions: PropTypes.bool, - flashMode: PropTypes.oneOf(CAMERA_FLASH_MODES), - cameraProps: PropTypes.object, - cameraTimeoutView: PropTypes.element, - }; + static propTypes = { + onRead: PropTypes.func.isRequired, + vibrate: PropTypes.bool, + reactivate: PropTypes.bool, + reactivateTimeout: PropTypes.number, + fadeIn: PropTypes.bool, + showMarker: PropTypes.bool, + cameraType: PropTypes.oneOf(['front', 'back']), + customMarker: PropTypes.element, + containerStyle: PropTypes.any, + cameraStyle: PropTypes.any, + markerStyle: PropTypes.any, + topViewStyle: PropTypes.any, + bottomViewStyle: PropTypes.any, + topContent: PropTypes.oneOfType([PropTypes.element, PropTypes.string]), + bottomContent: PropTypes.oneOfType([PropTypes.element, PropTypes.string]), + notAuthorizedView: PropTypes.element, + permissionDialogTitle: PropTypes.string, + permissionDialogMessage: PropTypes.string, + buttonPositive: PropTypes.string, + checkAndroid6Permissions: PropTypes.bool, + flashMode: PropTypes.oneOf(CAMERA_FLASH_MODES), + cameraProps: PropTypes.object + }; - static defaultProps = { - onRead: () => console.log('QR code scanned!'), - reactivate: false, - vibrate: true, - reactivateTimeout: 0, - cameraTimeout: 0, - fadeIn: true, - showMarker: false, - cameraType: 'back', - notAuthorizedView: ( - - - Camera not authorized - - - ), - pendingAuthorizationView: ( - - - ... - - - ), - permissionDialogTitle: 'Info', - permissionDialogMessage: 'Need camera permission', - buttonPositive: 'OK', - checkAndroid6Permissions: false, - flashMode: CAMERA_FLASH_MODE.auto, - cameraProps: {}, - cameraTimeoutView: ( - - Tap to activate camera - - ), - }; + static defaultProps = { + onRead: () => console.log('QR code scanned!'), + reactivate: false, + vibrate: true, + reactivateTimeout: 0, + fadeIn: true, + showMarker: false, + cameraType: 'back', + notAuthorizedView: ( + + + Camera not authorized + + + ), + pendingAuthorizationView: ( + + + ... + + + ), + permissionDialogTitle: 'Info', + permissionDialogMessage: 'Need camera permission', + buttonPositive: 'OK', + checkAndroid6Permissions: false, + flashMode: CAMERA_FLASH_MODE.auto, + cameraProps: {} + }; - constructor(props) { - super(props); - this.state = { - scanning: false, - isCameraActivated: true, - fadeInOpacity: new Animated.Value(0), - isAuthorized: false, - isAuthorizationChecked: false, - disableVibrationByUser: false, - }; + constructor(props) { + super(props); + this.state = { + scanning: false, + fadeInOpacity: new Animated.Value(0), + isAuthorized: false, + isAuthorizationChecked: false, + disableVibrationByUser: false + }; - this._scannerTimeout = null; - this._handleBarCodeRead = this._handleBarCodeRead.bind(this); - } + this._scannerTimeout = null; + this._handleBarCodeRead = this._handleBarCodeRead.bind(this); + } - componentDidMount() { - if (Platform.OS === 'ios') { - request(PERMISSIONS.IOS.CAMERA).then(cameraStatus => { - this.setState({ - isAuthorized: cameraStatus === RESULTS.GRANTED, - isAuthorizationChecked: true, - }); - }); - } else if (Platform.OS === 'android' && this.props.checkAndroid6Permissions) { - PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA, { - title: this.props.permissionDialogTitle, - message: this.props.permissionDialogMessage, - buttonPositive: this.props.buttonPositive, - }).then(granted => { - const isAuthorized = granted === PermissionsAndroid.RESULTS.GRANTED; + componentDidMount() { + if (Platform.OS === 'ios') { + request(PERMISSIONS.IOS.CAMERA).then(cameraStatus => { + this.setState({ + isAuthorized: cameraStatus === RESULTS.GRANTED, + isAuthorizationChecked: true + }); + }); + } else if ( + Platform.OS === 'android' && + this.props.checkAndroid6Permissions + ) { + PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA, { + title: this.props.permissionDialogTitle, + message: this.props.permissionDialogMessage + }).then(granted => { + const isAuthorized = granted === PermissionsAndroid.RESULTS.GRANTED; - this.setState({ isAuthorized, isAuthorizationChecked: true }); - }); - } else { - this.setState({ isAuthorized: true, isAuthorizationChecked: true }); - } + this.setState({ isAuthorized, isAuthorizationChecked: true }); + }); + } else { + this.setState({ isAuthorized: true, isAuthorizationChecked: true }); + } - if (this.props.fadeIn) { - Animated.sequence([ - Animated.delay(1000), - Animated.timing(this.state.fadeInOpacity, { - toValue: 1, - easing: Easing.inOut(Easing.quad), - useNativeDriver: true, - }), - ]).start(); - } - } + if (this.props.fadeIn) { + Animated.sequence([ + Animated.delay(1000), + Animated.timing(this.state.fadeInOpacity, { + toValue: 1, + easing: Easing.inOut(Easing.quad), + useNativeDriver: true + }) + ]).start(); + } + } - componentWillUnmount() { - if (this._scannerTimeout !== null) { - clearTimeout(this._scannerTimeout); - } - this._scannerTimeout = null; - } + componentWillUnmount() { + if (this._scannerTimeout !== null) { + clearTimeout(this._scannerTimeout); + } + this._scannerTimeout = null; + } - disable() { - this.setState({ disableVibrationByUser: true }); - } - enable() { - this.setState({ disableVibrationByUser: false }); - } + disable() { + this.setState({ disableVibrationByUser: true }); + } + enable() { + this.setState({ disableVibrationByUser: false }); + } - _setScanning(value) { - this.setState({ scanning: value }); - } + _setScanning(value) { + this.setState({ scanning: value }); + } - _setCamera(value) { - this.setState( - { - isCameraActivated: value, - scanning: false, - fadeInOpacity: new Animated.Value(0), - }, - () => { - if (value && this.props.fadeIn) { - if (this.props.fadeIn) { - Animated.sequence([ - Animated.delay(10), - Animated.timing(this.state.fadeInOpacity, { - toValue: 1, - easing: Easing.inOut(Easing.quad), - useNativeDriver: true, - }), - ]).start(); - } - } - } - ); - } + _handleBarCodeRead(e) { + if (!this.state.scanning && !this.state.disableVibrationByUser) { + if (this.props.vibrate) { + Vibration.vibrate(); + } + this._setScanning(true); + this.props.onRead(e); + if (this.props.reactivate) { + this._scannerTimeout = setTimeout( + () => this._setScanning(false), + this.props.reactivateTimeout + ); + } + } + } - _handleBarCodeRead(e) { - if (!this.state.scanning && !this.state.disableVibrationByUser) { - if (this.props.vibrate) { - Vibration.vibrate(); - } - this._setScanning(true); - this.props.onRead(e); - if (this.props.reactivate) { - this._scannerTimeout = setTimeout(() => this._setScanning(false), this.props.reactivateTimeout); - } - } - } + _renderTopContent() { + if (this.props.topContent) { + return this.props.topContent; + } + return null; + } - _renderTopContent() { - if (this.props.topContent) { - return this.props.topContent; - } - return null; - } + _renderBottomContent() { + if (this.props.bottomContent) { + return this.props.bottomContent; + } + return null; + } - _renderBottomContent() { - if (this.props.bottomContent) { - return this.props.bottomContent; - } - return null; - } + _renderCameraMarker() { + if (this.props.showMarker) { + if (this.props.customMarker) { + return this.props.customMarker; + } else { + return ( + + + + ); + } + } + return null; + } - _renderCameraMarker() { - if (this.props.showMarker) { - if (this.props.customMarker) { - return this.props.customMarker; - } else { - return ( - - - - ); - } - } - return null; - } + _renderCameraComponent() { + return ( + + + - _renderCameraComponent() { - return ( - - {this._renderCameraMarker()} - - ); - } + {this._renderCameraMarker()} - _renderCamera() { - const { notAuthorizedView, pendingAuthorizationView, cameraType, cameraTimeoutView } = this.props; + + - if (!this.state.isCameraActivated) { - return this._setCamera(true)}>{cameraTimeoutView}; - } + + ); + } - const { isAuthorized, isAuthorizationChecked } = this.state; - if (isAuthorized) { - if (this.props.cameraTimeout > 0) { - this.timer && clearTimeout(this.timer); - this.timer = setTimeout(() => this._setCamera(false), this.props.cameraTimeout); - } + _renderCamera() { + const { + notAuthorizedView, + pendingAuthorizationView, + cameraType + } = this.props; + const { isAuthorized, isAuthorizationChecked } = this.state; + if (isAuthorized) { + if (this.props.fadeIn) { + return ( + + {this._renderCameraComponent()} + + ); + } + return this._renderCameraComponent(); + } else if (!isAuthorizationChecked) { + return pendingAuthorizationView; + } else { + return notAuthorizedView; + } + } + reactivate() { + this._setScanning(false); + } - if (this.props.fadeIn) { - return ( - - {this._renderCameraComponent()} - - ); - } - return this._renderCameraComponent(); - } else if (!isAuthorizationChecked) { - return pendingAuthorizationView; - } else { - return notAuthorizedView; - } - } - - reactivate() { - this._setScanning(false); - } - - render() { - return ( - - {this._renderTopContent()} - - {this._renderCamera()} - - {this._renderBottomContent()} - - ); - } + render() { + return ( + + + {this._renderTopContent()} + + {this._renderCamera()} + + {this._renderBottomContent()} + + + ); + } } const styles = StyleSheet.create({ - mainContainer: { - flex: 1, - }, - infoView: { - flex: 2, - justifyContent: 'center', - alignItems: 'center', - width: Dimensions.get('window').width, - }, + mainContainer: { + flex: 1 + }, + infoView: { + flex: 2, + justifyContent: 'center', + alignItems: 'center', + width: Dimensions.get('window').width + }, - camera: { - flex: 0, - alignItems: 'center', - justifyContent: 'center', - backgroundColor: 'transparent', - height: Dimensions.get('window').height, - width: Dimensions.get('window').width, - }, + camera: { + flex: 0, + alignItems: 'center', + justifyContent: 'center', + backgroundColor: 'transparent', + height: Dimensions.get('window').width, + width: Dimensions.get('window').width + }, - rectangleContainer: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - backgroundColor: 'transparent', - }, + rectangleContainer: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + backgroundColor: 'transparent' + }, - rectangle: { - height: 250, - width: 250, - borderWidth: 2, - borderColor: '#00FF00', - backgroundColor: 'transparent', - }, -}); \ No newline at end of file + rectangle: { + height: 250, + width: 250, + borderWidth: 2, + borderColor: '#00FF00', + backgroundColor: 'transparent' + } +});