BlueWallet/screen/send/ScanQRCode.js

187 lines
5.2 KiB
JavaScript
Raw Normal View History

2019-09-21 13:37:37 -04:00
/* global alert */
import React, { useState } from 'react';
2020-05-31 16:30:01 +03:00
import { Image, View, TouchableOpacity, StatusBar, Platform, StyleSheet } from 'react-native';
2019-05-02 16:33:03 -04:00
import { RNCamera } from 'react-native-camera';
2019-09-21 13:37:37 -04:00
import { Icon } from 'react-native-elements';
import ImagePicker from 'react-native-image-picker';
import { useNavigation, useRoute, useIsFocused } from '@react-navigation/native';
2019-12-31 21:31:04 -06:00
import DocumentPicker from 'react-native-document-picker';
import RNFS from 'react-native-fs';
2020-07-20 16:38:46 +03:00
import loc from '../../loc';
2019-09-21 13:37:37 -04:00
const LocalQRCode = require('@remobile/react-native-qrcode-local-image');
const createHash = require('create-hash');
2018-01-30 22:42:38 +00:00
const styles = StyleSheet.create({
root: {
flex: 1,
backgroundColor: '#000000',
},
rnCamera: {
flex: 1,
},
closeTouch: {
width: 40,
height: 40,
backgroundColor: 'rgba(0,0,0,0.4)',
justifyContent: 'center',
borderRadius: 20,
position: 'absolute',
right: 16,
top: 44,
},
closeImage: {
alignSelf: 'center',
},
imagePickerTouch: {
width: 40,
height: 40,
backgroundColor: 'rgba(0,0,0,0.4)',
justifyContent: 'center',
borderRadius: 20,
position: 'absolute',
left: 24,
bottom: 48,
},
filePickerTouch: {
width: 40,
height: 40,
backgroundColor: 'rgba(0,0,0,0.4)',
justifyContent: 'center',
borderRadius: 20,
position: 'absolute',
left: 96,
bottom: 48,
},
});
const ScanQRCode = () => {
2019-12-27 18:53:34 -06:00
const [isLoading, setIsLoading] = useState(false);
2020-05-31 16:30:01 +03:00
const navigation = useNavigation();
2020-05-27 14:12:17 +03:00
const route = useRoute();
const showFileImportButton = route.params.showFileImportButton || false;
2020-05-27 14:12:17 +03:00
const { launchedBy, onBarScanned } = route.params;
const scannedCache = {};
const isFocused = useIsFocused();
const HashIt = function (s) {
return createHash('sha256').update(s).digest().toString('hex');
};
2019-12-27 18:53:34 -06:00
const onBarCodeRead = ret => {
const h = HashIt(ret.data);
if (scannedCache[h]) {
// this QR was already scanned by this ScanQRCode, lets prevent firing duplicate callbacks
return;
}
scannedCache[h] = +new Date();
2020-05-21 11:36:03 -04:00
if (!isLoading) {
2019-12-27 18:53:34 -06:00
setIsLoading(true);
try {
if (launchedBy) {
2020-05-31 16:30:01 +03:00
navigation.navigate(launchedBy);
2019-12-27 18:53:34 -06:00
}
2019-12-31 21:31:04 -06:00
if (ret.additionalProperties) {
onBarScanned(ret.data, ret.additionalProperties);
} else {
onBarScanned(ret.data);
}
2019-12-27 18:53:34 -06:00
} catch (e) {
console.log(e);
}
}
setIsLoading(false);
};
2018-01-30 22:42:38 +00:00
2019-12-31 21:31:04 -06:00
const showFilePicker = async () => {
setIsLoading(true);
try {
const res = await DocumentPicker.pick();
const file = await RNFS.readFile(res.uri);
const fileParsed = JSON.parse(file);
if (fileParsed.keystore.xpub) {
2020-01-02 14:54:34 -06:00
let masterFingerprint;
if (fileParsed.keystore.ckcc_xfp) {
2020-01-02 22:02:41 -06:00
masterFingerprint = Number(fileParsed.keystore.ckcc_xfp);
2020-01-02 14:54:34 -06:00
}
onBarCodeRead({ data: fileParsed.keystore.xpub, additionalProperties: { masterFingerprint, label: fileParsed.keystore.label } });
2019-12-31 21:31:04 -06:00
} else {
throw new Error();
}
} catch (err) {
if (!DocumentPicker.isCancel(err)) {
2020-07-20 16:38:46 +03:00
alert(loc.send.qr_error_no_wallet);
2019-12-31 21:31:04 -06:00
}
setIsLoading(false);
}
setIsLoading(false);
};
2018-01-30 22:42:38 +00:00
const showImagePicker = () => {
if (!isLoading) {
setIsLoading(true);
ImagePicker.launchImageLibrary(
{
title: null,
mediaType: 'photo',
takePhotoButtonTitle: null,
},
response => {
if (response.uri) {
const uri = Platform.OS === 'ios' ? response.uri.toString().replace('file://', '') : response.path.toString();
LocalQRCode.decode(uri, (error, result) => {
if (!error) {
onBarCodeRead({ data: result });
} else {
2020-07-20 16:38:46 +03:00
alert(loc.send.qr_error_no_qrcode);
}
});
}
setIsLoading(false);
},
);
}
};
const dismiss = () => {
2020-05-31 16:30:01 +03:00
navigation.navigate(launchedBy);
};
2019-12-27 18:53:34 -06:00
return (
<View style={styles.root}>
2020-06-02 22:00:45 -04:00
<StatusBar hidden />
{!isLoading && isFocused && (
2019-05-02 16:33:03 -04:00
<RNCamera
captureAudio={false}
androidCameraPermissionOptions={{
2020-07-20 16:38:46 +03:00
title: loc.send.permission_camera_title,
message: loc.send.permission_camera_message,
buttonPositive: loc._.ok,
buttonNegative: loc._.cancel,
2019-05-02 16:33:03 -04:00
}}
style={styles.rnCamera}
2019-12-27 18:53:34 -06:00
onBarCodeRead={onBarCodeRead}
2019-05-02 16:33:03 -04:00
barCodeTypes={[RNCamera.Constants.BarCodeType.qr]}
/>
2019-12-27 18:53:34 -06:00
)}
2020-05-30 10:47:32 +03:00
<TouchableOpacity style={styles.closeTouch} onPress={dismiss}>
<Image style={styles.closeImage} source={require('../../img/close-white.png')} />
</TouchableOpacity>
2020-05-30 10:47:32 +03:00
<TouchableOpacity style={styles.imagePickerTouch} onPress={showImagePicker}>
2020-05-21 15:55:03 +02:00
<Icon name="image" type="font-awesome" color="#ffffff" />
2019-12-27 18:53:34 -06:00
</TouchableOpacity>
2019-12-31 21:31:04 -06:00
{showFileImportButton && (
<TouchableOpacity style={styles.filePickerTouch} onPress={showFilePicker}>
2020-05-21 15:55:03 +02:00
<Icon name="file-import" type="material-community" color="#ffffff" />
2019-09-21 13:37:37 -04:00
</TouchableOpacity>
2019-12-31 21:31:04 -06:00
)}
2019-12-27 18:53:34 -06:00
</View>
);
};
2018-03-18 02:48:23 +00:00
2019-12-27 18:53:34 -06:00
ScanQRCode.navigationOptions = {
2020-05-27 14:12:17 +03:00
headerShown: false,
2019-12-27 18:53:34 -06:00
};
2019-12-27 18:53:34 -06:00
export default ScanQRCode;