FIX: Animated QRCode border. Change save path to Downloads folder.

This commit is contained in:
marcosrdz 2020-08-15 22:43:17 -04:00 committed by Overtorment
parent 345b53bc88
commit b1143c0664
8 changed files with 76 additions and 75 deletions

View file

@ -574,7 +574,7 @@ export const BluePrivateBalance = () => {
export const BlueCopyToClipboardButton = ({ stringToCopy, displayText = false }) => {
return (
<TouchableOpacity {...this.props} onPress={() => Clipboard.setString(stringToCopy)}>
<TouchableOpacity onPress={() => Clipboard.setString(stringToCopy)}>
<Text style={{ fontSize: 13, fontWeight: '400', color: '#68bbe1' }}>{displayText || loc.transactions.details_copy}</Text>
</TouchableOpacity>
);
@ -2733,7 +2733,7 @@ export class DynamicQRCode extends Component {
return currentFragment ? (
<View style={animatedQRCodeStyle.container}>
<BlueSpacing20 />
<View style={[animatedQRCodeStyle.qrcodeContainer, { height: this.state.qrCodeHeight }]}>
<View style={animatedQRCodeStyle.qrcodeContainer}>
<QRCode
value={currentFragment.toUpperCase()}
size={this.state.qrCodeHeight}
@ -2791,6 +2791,7 @@ const animatedQRCodeStyle = StyleSheet.create({
borderWidth: 6,
borderRadius: 8,
borderColor: '#FFFFFF',
margin: 6,
},
controller: {
width: '90%',

View file

@ -207,7 +207,10 @@ class DeeplinkSchemaMatch {
}
static isPossiblyPSBTFile(filePath) {
return filePath.toLowerCase().startsWith('file:') && filePath.toLowerCase().endsWith('-signed.psbt');
return (
(filePath.toLowerCase().startsWith('file:') || filePath.toLowerCase().startsWith('content:')) &&
filePath.toLowerCase().endsWith('-signed.psbt')
);
}
static isBothBitcoinAndLightningOnWalletSelect(wallet, uri) {

View file

@ -249,15 +249,15 @@ PODS:
- React
- react-native-blur (0.8.0):
- React
- react-native-camera (3.31.1):
- react-native-camera (3.35.0):
- React
- react-native-camera/RCT (= 3.31.1)
- react-native-camera/RN (= 3.31.1)
- react-native-camera/RCT (3.31.1):
- react-native-camera/RCT (= 3.35.0)
- react-native-camera/RN (= 3.35.0)
- react-native-camera/RCT (3.35.0):
- React
- react-native-camera/RN (3.31.1):
- react-native-camera/RN (3.35.0):
- React
- react-native-document-picker (3.2.0):
- react-native-document-picker (3.5.4):
- React
- react-native-image-picker (2.3.3):
- React
@ -341,7 +341,7 @@ PODS:
- React
- RNCMaskedView (0.1.10):
- React
- RNCPushNotificationIOS (1.3.0):
- RNCPushNotificationIOS (1.4.0):
- React
- RNDefaultPreference (1.4.3):
- React
@ -365,7 +365,7 @@ PODS:
- React
- RNSecureKeyStore (1.0.0):
- React
- RNSentry (1.6.1):
- RNSentry (1.6.3):
- React
- Sentry (~> 5.1.8)
- RNShare (3.7.0):
@ -654,8 +654,8 @@ SPEC CHECKSUMS:
react-native-biometrics: c892904948a32295b128f633bcc11eda020645c5
react-native-blue-crypto: 23f1558ad3d38d7a2edb7e2f6ed1bc520ed93e56
react-native-blur: cad4d93b364f91e7b7931b3fa935455487e5c33c
react-native-camera: c673127fd3bf9f9ac4ea6e65fce8160e8e0ae1d1
react-native-document-picker: e3516aff0dcf65ee0785d9bcf190eb10e2261154
react-native-camera: 9dd96065b956306de03ef2a2efc3583019f95941
react-native-document-picker: c5752781fbc0c126c627c1549b037c139444a4cf
react-native-image-picker: a6c3d644751a388b0fc8b56822ff7cbd398a3008
react-native-randombytes: 991545e6eaaf700b4ee384c291ef3d572e0b2ca8
react-native-safe-area-context: 0ed9288ed4409beabb0817b54efc047286fc84da
@ -677,7 +677,7 @@ SPEC CHECKSUMS:
RNCAsyncStorage: db711e29e5e0500d9bd21aa0c2e397efa45302b1
RNCClipboard: 5f3218dcdc28405aa2ae72b78e388f150b826dd3
RNCMaskedView: f5c7d14d6847b7b44853f7acb6284c1da30a3459
RNCPushNotificationIOS: 23c5b5fdae79f105c63236de5ca306a70c00c444
RNCPushNotificationIOS: f4a1a20fe1d70bbb1fab6abf86ffec2996012b12
RNDefaultPreference: 21816c0a6f61a2829ccc0cef034392e9b509ee5f
RNDeviceInfo: ab2ab4ca9e7f2bc4f35d62ab6ce2b66f2cbf1e7a
RNFS: 2bd9eb49dc82fa9676382f0585b992c424cd59df
@ -689,7 +689,7 @@ SPEC CHECKSUMS:
RNReactNativeHapticFeedback: 22c5ecf474428766c6b148f96f2ff6155cd7225e
RNScreens: b748efec66e095134c7166ca333b628cd7e6f3e2
RNSecureKeyStore: f1ad870e53806453039f650720d2845c678d89c8
RNSentry: 57824da1293d03966605d682d5868b11aa1b6e5a
RNSentry: ae1e005e4f2655775475445a9c49c1d343e8e3a7
RNShare: a1d5064df7a0ebe778d001869b3f0a124bf0a491
RNSVG: ce9d996113475209013317e48b05c21ee988d42e
RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4

View file

@ -199,7 +199,7 @@
"qr_error_no_qrcode": "The selected image does not contain a QR Code.",
"qr_error_no_wallet": "The selected file does not contain a wallet that can be imported.",
"success_done": "Done",
"txSaved": "This transaction has been saved in {filePath}"
"txSaved": "The transaction file ({filePath}) has been saved in your Downloads folder ."
},
"settings": {
"about": "About",

4
package-lock.json generated
View file

@ -14627,8 +14627,8 @@
"integrity": "sha512-FxjenoDZJKT53pp/Tl5gMsw5DA82Y5tOuySQlKS5AaDmw+Bu6EqEJjt0z4TRhJOVoqVJ35oCiZ3xViVbz/hB0w=="
},
"react-native-document-picker": {
"version": "git+https://github.com/BlueWallet/react-native-document-picker.git#9ce83792db340d01b1361d24b19613658abef4aa",
"from": "git+https://github.com/BlueWallet/react-native-document-picker.git#9ce83792db340d01b1361d24b19613658abef4aa"
"version": "git+https://github.com/BlueWallet/react-native-document-picker.git#3684d4fcc2bc0b47c32be39024e4796004c3e428",
"from": "git+https://github.com/BlueWallet/react-native-document-picker.git#3684d4fcc2bc0b47c32be39024e4796004c3e428"
},
"react-native-elements": {
"version": "2.0.2",

View file

@ -114,7 +114,7 @@
"react-native-camera": "3.35.0",
"react-native-default-preference": "1.4.3",
"react-native-device-info": "5.6.1",
"react-native-document-picker": "git+https://github.com/BlueWallet/react-native-document-picker.git#9ce83792db340d01b1361d24b19613658abef4aa",
"react-native-document-picker": "git+https://github.com/BlueWallet/react-native-document-picker.git#3684d4fcc2bc0b47c32be39024e4796004c3e428",
"react-native-elements": "2.0.2",
"react-native-fs": "2.16.6",
"react-native-gesture-handler": "1.7.0",

View file

@ -73,7 +73,7 @@ export default class SendCreate extends Component {
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Storage Permission: Granted');
const filePath = RNFS.ExternalCachesDirectoryPath + `/${this.fileName}`;
const filePath = RNFS.DownloadDirectoryPath + `/${this.fileName}`;
await RNFS.writeFile(filePath, this.state.tx);
alert(loc.formatString(loc.send.txSaved, { filePath }));
} else {

View file

@ -6,14 +6,14 @@ import {
ScrollView,
View,
Dimensions,
Image,
TextInput,
Linking,
Platform,
Text,
PermissionsAndroid,
Text,
StyleSheet,
} from 'react-native';
import ImagePicker from 'react-native-image-picker';
import Clipboard from '@react-native-community/clipboard';
import {
BlueButton,
@ -29,8 +29,8 @@ import {
} from '../../BlueComponents';
import PropTypes from 'prop-types';
import Share from 'react-native-share';
import { getSystemName } from 'react-native-device-info';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import { RNCamera } from 'react-native-camera';
import RNFS from 'react-native-fs';
import DocumentPicker from 'react-native-document-picker';
import { decodeUR, extractSingleWorkload } from 'bc-ur/dist';
@ -43,8 +43,9 @@ const BlueElectrum = require('../../blue_modules/BlueElectrum');
const BlueApp = require('../../BlueApp');
const bitcoin = require('bitcoinjs-lib');
const notifications = require('../../blue_modules/notifications');
const LocalQRCode = require('@remobile/react-native-qrcode-local-image');
const { height, width } = Dimensions.get('window');
const isDesktop = getSystemName() === 'Mac OS X';
const styles = StyleSheet.create({
root: {
flex: 1,
@ -131,7 +132,6 @@ export default class PsbtWithHardwareWallet extends Component {
const currentTotal = animatedQRCodeData[0].total;
if (total !== currentTotal) {
alert('invalid animated QRCode');
this.setState({ renderScanner: false });
}
}
if (!animatedQRCodeData.find(i => i.index === index)) {
@ -148,17 +148,10 @@ export default class PsbtWithHardwareWallet extends Component {
}),
() => {
if (this.state.animatedQRCodeData.length === total) {
this.setState(
{
renderScanner: false,
},
() => {
const payload = decodeUR(this.state.animatedQRCodeData.map(i => i.data));
const psbtB64 = Buffer.from(payload, 'hex').toString('base64');
const psbt = Psbt.fromBase64(psbtB64);
this.setState({ txhex: psbt.extractTransaction().toHex() });
},
);
const payload = decodeUR(this.state.animatedQRCodeData.map(i => i.data));
const psbtB64 = Buffer.from(payload, 'hex').toString('base64');
const psbt = Psbt.fromBase64(psbtB64);
this.setState({ txhex: psbt.extractTransaction().toHex() });
}
},
);
@ -176,31 +169,26 @@ export default class PsbtWithHardwareWallet extends Component {
};
onBarCodeRead = ret => {
if (RNCamera.Constants.CameraStatus === RNCamera.Constants.CameraStatus.READY) this.cameraRef.pausePreview();
if (ret.data.toUpperCase().startsWith('UR')) {
return this._onReadUniformResource(ret.data);
}
if (ret.data.indexOf('+') === -1 && ret.data.indexOf('=') === -1 && ret.data.indexOf('=') === -1) {
// this looks like NOT base64, so maybe its transaction's hex
this.setState({ renderScanner: false, txhex: ret.data });
this.setState({ txhex: ret.data });
return;
}
this.setState({ renderScanner: false }, () => {
try {
const Tx = this._combinePSBT(ret.data);
this.setState({ txhex: Tx.toHex() });
} catch (Err) {
alert(Err);
}
});
try {
const Tx = this._combinePSBT(ret.data);
this.setState({ txhex: Tx.toHex() });
} catch (Err) {
alert(Err);
}
};
constructor(props) {
super(props);
this.state = {
isLoading: false,
renderScanner: false,
qrCodeHeight: height > width ? width - 40 : width / 3,
memo: props.route.params.memo,
psbt: props.route.params.psbt,
@ -271,29 +259,6 @@ export default class PsbtWithHardwareWallet extends Component {
});
};
_renderScanner() {
return (
<SafeBlueArea style={styles.root}>
<RNCamera
captureAudio={false}
androidCameraPermissionOptions={{
title: loc.send.permission_camera_title,
message: loc.send.permission_camera_message,
buttonPositive: loc._.ok,
buttonNegative: loc._.cancel,
}}
ref={ref => (this.cameraRef = ref)}
style={styles.rootCamera}
onBarCodeRead={this.onBarCodeRead}
barCodeTypes={[RNCamera.Constants.BarCodeType.qr]}
/>
<TouchableOpacity style={styles.closeCamera} onPress={() => this.setState({ renderScanner: false })}>
<Image style={styles.closeCameraImage} source={require('../../img/close-white.png')} />
</TouchableOpacity>
</SafeBlueArea>
);
}
_renderSuccess() {
return (
<SafeBlueArea style={styles.root}>
@ -347,9 +312,9 @@ export default class PsbtWithHardwareWallet extends Component {
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Storage Permission: Granted');
const filePath = RNFS.ExternalCachesDirectoryPath + `/${this.fileName}`;
const filePath = RNFS.DownloadDirectoryPath + `/${this.fileName}`;
await RNFS.writeFile(filePath, this.state.isFirstPSBTAlreadyBase64 ? this.state.psbt : this.state.psbt.toBase64());
alert(loc.formatString(loc.send.txSaved, { filePath }));
alert(loc.formatString(loc.send.txSaved, { filePath: this.fileName }));
} else {
console.log('Storage Permission: Denied');
}
@ -375,6 +340,38 @@ export default class PsbtWithHardwareWallet extends Component {
}
};
openScanner = () => {
if (isDesktop) {
ImagePicker.launchCamera(
{
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) {
this.onBarScanned(result);
} else {
alert(loc.send.qr_error_no_qrcode);
}
});
}
},
);
} else {
this.props.navigation.navigate('ScanQRCodeRoot', {
screen: 'ScanQRCode',
params: {
launchedBy: this.props.route.name,
onBarScanned: this.onBarScanned,
},
});
}
};
render() {
if (this.state.isLoading) {
return (
@ -385,7 +382,6 @@ export default class PsbtWithHardwareWallet extends Component {
}
if (this.state.success) return this._renderSuccess();
if (this.state.renderScanner) return this._renderScanner();
if (this.state.txhex) return this._renderBroadcastHex();
return (
@ -403,7 +399,7 @@ export default class PsbtWithHardwareWallet extends Component {
type: 'font-awesome',
color: BlueCurrentTheme.colors.buttonTextColor,
}}
onPress={() => this.setState({ renderScanner: true, animatedQRCodeData: [] })}
onPress={this.openScanner}
title={loc.send.psbt_tx_scan}
/>
<BlueSpacing20 />
@ -449,6 +445,7 @@ PsbtWithHardwareWallet.propTypes = {
}),
route: PropTypes.shape({
params: PropTypes.object,
name: PropTypes.string,
}),
};