Use react native camera instead of expo one

This commit is contained in:
Arnaud Vergnet 2020-04-29 11:34:52 +02:00
parent 4f49b48fc5
commit 8daa2641dc
4 changed files with 46 additions and 125 deletions

View file

@ -137,6 +137,7 @@ android {
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 16 versionCode 16
versionName "2.0.0" versionName "2.0.0"
missingDimensionStrategy 'react-native-camera', 'general'
} }
splits { splits {
abi { abi {
@ -194,6 +195,8 @@ dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"]) implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.facebook.react:react-native:+" // From node_modules implementation "com.facebook.react:react-native:+" // From node_modules
addUnimodulesDependencies([exclude: [ addUnimodulesDependencies([exclude: [
'expo-camera',
'expo-barcode-scanner',
'expo-error-recovery', 'expo-error-recovery',
'expo-image-loader', 'expo-image-loader',
'expo-keep-awake', 'expo-keep-awake',

View file

@ -7,8 +7,6 @@ import org.unimodules.core.interfaces.Package;
public class BasePackageList { public class BasePackageList {
public List<Package> getPackageList() { public List<Package> getPackageList() {
return Arrays.<Package>asList( return Arrays.<Package>asList(
new expo.modules.barcodescanner.BarCodeScannerPackage(),
new expo.modules.camera.CameraPackage(),
new expo.modules.constants.ConstantsPackage(), new expo.modules.constants.ConstantsPackage(),
new expo.modules.filesystem.FileSystemPackage(), new expo.modules.filesystem.FileSystemPackage(),
new expo.modules.font.FontLoaderPackage(), new expo.modules.font.FontLoaderPackage(),

View file

@ -18,14 +18,13 @@
] ]
}, },
"dependencies": { "dependencies": {
"@nartc/react-native-barcode-mask": "^1.1.9",
"@react-native-community/masked-view": "0.1.6", "@react-native-community/masked-view": "0.1.6",
"@react-navigation/bottom-tabs": "^5.1.1", "@react-navigation/bottom-tabs": "^5.1.1",
"@react-navigation/drawer": "^5.1.1", "@react-navigation/drawer": "^5.1.1",
"@react-navigation/native": "^5.0.9", "@react-navigation/native": "^5.0.9",
"@react-navigation/stack": "^5.1.1", "@react-navigation/stack": "^5.1.1",
"expo": "^37.0.0", "expo": "^37.0.0",
"expo-barcode-scanner": "~8.1.0",
"expo-camera": "latest",
"i18n-js": "^3.3.0", "i18n-js": "^3.3.0",
"react": "~16.9.0", "react": "~16.9.0",
"react-dom": "16.9.0", "react-dom": "16.9.0",
@ -35,6 +34,7 @@
"react-native-appearance": "~0.3.3", "react-native-appearance": "~0.3.3",
"react-native-autolink": "^3.0.0", "react-native-autolink": "^3.0.0",
"react-native-calendars": "^1.260.0", "react-native-calendars": "^1.260.0",
"react-native-camera": "^3.23.1",
"react-native-collapsible": "^1.5.2", "react-native-collapsible": "^1.5.2",
"react-native-gesture-handler": "~1.6.0", "react-native-gesture-handler": "~1.6.0",
"react-native-image-modal": "^1.0.6", "react-native-image-modal": "^1.0.6",

View file

@ -1,15 +1,16 @@
// @flow // @flow
import * as React from 'react'; import * as React from 'react';
import {Linking, StyleSheet, View} from "react-native"; import {Linking, Platform, StyleSheet, View} from "react-native";
import {Button, Text, withTheme} from 'react-native-paper'; import {Button, Text, withTheme} from 'react-native-paper';
import {BarCodeScanner} from "expo-barcode-scanner"; import {RNCamera} from 'react-native-camera';
import {Camera} from 'expo-camera'; import {BarcodeMask} from '@nartc/react-native-barcode-mask';
import URLHandler from "../../utils/URLHandler"; import URLHandler from "../../utils/URLHandler";
import AlertDialog from "../../components/Dialogs/AlertDialog"; import AlertDialog from "../../components/Dialogs/AlertDialog";
import i18n from 'i18n-js'; import i18n from 'i18n-js';
import CustomTabBar from "../../components/Tabbar/CustomTabBar"; import CustomTabBar from "../../components/Tabbar/CustomTabBar";
import LoadingConfirmDialog from "../../components/Dialogs/LoadingConfirmDialog"; import LoadingConfirmDialog from "../../components/Dialogs/LoadingConfirmDialog";
import {PERMISSIONS, request, RESULTS} from 'react-native-permissions';
type Props = {}; type Props = {};
type State = { type State = {
@ -40,9 +41,14 @@ class ScannerScreen extends React.Component<Props, State> {
this.requestPermissions(); this.requestPermissions();
} }
requestPermissions = () => Camera.requestPermissionsAsync().then(this.updatePermissionStatus); requestPermissions = () => {
if (Platform.OS === 'android')
request(PERMISSIONS.ANDROID.CAMERA).then(this.updatePermissionStatus)
else
request(PERMISSIONS.IOS.CAMERA).then(this.updatePermissionStatus)
};
updatePermissionStatus = ({status}) => this.setState({hasPermission: status === "granted"}); updatePermissionStatus = (result) => this.setState({hasPermission: result === RESULTS.GRANTED});
handleCodeScanned = ({type, data}) => { handleCodeScanned = ({type, data}) => {
if (!URLHandler.isUrlValid(data)) if (!URLHandler.isUrlValid(data))
@ -71,36 +77,6 @@ class ScannerScreen extends React.Component<Props, State> {
</View> </View>
} }
getOverlay() {
return (
<View style={{flex: 1}}>
<View style={{flex: 1}}>
<View style={{...overlayBackground, top: 0, height: '10%', width: '80%', left: '10%'}}/>
<View style={{...overlayBackground, left: 0, width: '10%', height: '100%'}}/>
<View style={{...overlayBackground, right: 0, width: '10%', height: '100%'}}/>
<View style={{...overlayBackground, bottom: 0, height: '10%', width: '80%', left: '10%'}}/>
</View>
<View style={styles.overlayTopLeft}>
<View style={{...overlayHorizontalLineStyle, top: 0}}/>
<View style={{...overlayVerticalLineStyle, left: 0}}/>
</View>
<View style={styles.overlayTopRight}>
<View style={{...overlayHorizontalLineStyle, top: 0}}/>
<View style={{...overlayVerticalLineStyle, right: 0}}/>
</View>
<View style={styles.overlayBottomLeft}>
<View style={{...overlayHorizontalLineStyle, bottom: 0}}/>
<View style={{...overlayVerticalLineStyle, left: 0}}/>
</View>
<View style={styles.overlayBottomRight}>
<View style={{...overlayHorizontalLineStyle, bottom: 0}}/>
<View style={{...overlayVerticalLineStyle, right: 0}}/>
</View>
</View>
);
}
showHelpDialog = () => { showHelpDialog = () => {
this.setState({ this.setState({
dialogVisible: true, dialogVisible: true,
@ -133,19 +109,22 @@ class ScannerScreen extends React.Component<Props, State> {
getScanner() { getScanner() {
return ( return (
<View style={styles.cameraContainer}> <RNCamera
<Camera onBarCodeRead={this.state.scanned ? undefined : this.handleCodeScanned}
onBarCodeScanned={this.state.scanned ? undefined : this.handleCodeScanned} type={RNCamera.Constants.Type.back}
type={Camera.Constants.Type.back} barCodeScannerSettings={{
barCodeScannerSettings={{ barCodeTypes: [RNCamera.Constants.BarCodeType.qr],
barCodeTypes: [BarCodeScanner.Constants.BarCodeType.qr], }}
}} style={StyleSheet.absoluteFill}
style={StyleSheet.absoluteFill} captureAudio={false}
ratio={'1:1'} >
> <BarcodeMask
{this.getOverlay()} backgroundColor={"#000"}
</Camera> maskOpacity={0.5}
</View> animatedLineThickness={1}
animationDuration={1000}
/>
</RNCamera>
); );
} }
@ -153,22 +132,20 @@ class ScannerScreen extends React.Component<Props, State> {
return ( return (
<View style={{ <View style={{
...styles.container, ...styles.container,
marginBottom: CustomTabBar.TAB_BAR_HEIGHT + 20 marginBottom: CustomTabBar.TAB_BAR_HEIGHT
}}> }}>
{this.state.hasPermission {this.state.hasPermission
? this.getScanner() ? this.getScanner()
: this.getPermissionScreen() : this.getPermissionScreen()
} }
<View style={{height: 50}}> <Button
<Button icon="information"
icon="information" mode="contained"
mode="contained" onPress={this.showHelpDialog}
onPress={this.showHelpDialog} style={styles.button}
style={styles.button} >
> {i18n.t("scannerScreen.helpButton")}
{i18n.t("scannerScreen.helpButton")} </Button>
</Button>
</View>
<AlertDialog <AlertDialog
visible={this.state.dialogVisible} visible={this.state.dialogVisible}
onDismiss={this.onDialogDismiss} onDismiss={this.onDialogDismiss}
@ -185,74 +162,17 @@ class ScannerScreen extends React.Component<Props, State> {
} }
} }
const borderOffset = '10%';
const overlayBoxStyle = {
position: 'absolute',
width: 25,
height: 25,
};
const overlayLineStyle = {
position: 'absolute',
backgroundColor: "#fff",
borderRadius: 2,
};
const overlayHorizontalLineStyle = {
...overlayLineStyle,
width: '100%',
height: 5,
};
const overlayVerticalLineStyle = {
...overlayLineStyle,
height: '100%',
width: 5,
};
const overlayBackground = {
backgroundColor: "rgba(0,0,0,0.47)",
position: "absolute",
};
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
justifyContent: 'center', justifyContent: 'center',
}, },
cameraContainer: {
marginTop: 'auto',
marginBottom: 'auto',
aspectRatio: 1,
width: '100%',
},
button: { button: {
position: 'absolute', position: 'absolute',
bottom: 5, bottom: 20,
width: '80%', width: '80%',
left: '10%' left: '10%'
}, },
overlayTopLeft: {
...overlayBoxStyle,
top: borderOffset,
left: borderOffset,
},
overlayTopRight: {
...overlayBoxStyle,
top: borderOffset,
right: borderOffset,
},
overlayBottomLeft: {
...overlayBoxStyle,
bottom: borderOffset,
left: borderOffset,
},
overlayBottomRight: {
...overlayBoxStyle,
bottom: borderOffset,
right: borderOffset,
},
}); });
export default withTheme(ScannerScreen); export default withTheme(ScannerScreen);