Merge pull request #2308 from BlueWallet/msmac

FIX: Was unable to import key on macOS
This commit is contained in:
GLaDOS 2020-12-13 10:07:35 +00:00 committed by GitHub
commit 7afdd3394f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 51 deletions

View file

@ -5,6 +5,8 @@ import Share from 'react-native-share';
import loc from '../loc'; import loc from '../loc';
import DocumentPicker from 'react-native-document-picker'; import DocumentPicker from 'react-native-document-picker';
import isCatalyst from 'react-native-is-catalyst'; import isCatalyst from 'react-native-is-catalyst';
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
import { presentCameraNotAuthorizedAlert } from '../class/camera';
const LocalQRCode = require('@remobile/react-native-qrcode-local-image'); const LocalQRCode = require('@remobile/react-native-qrcode-local-image');
const writeFileAndExport = async function (filename, contents) { const writeFileAndExport = async function (filename, contents) {
@ -92,6 +94,56 @@ const _readPsbtFileIntoBase64 = async function (uri) {
} }
}; };
const showImagePickerAndReadImage = () => {
return new Promise((resolve, reject) =>
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) {
resolve(result);
} else {
reject(new Error(loc.send.qr_error_no_qrcode));
}
});
}
},
),
);
};
const takePhotoWithImagePickerAndReadPhoto = () => {
return new Promise((resolve, reject) =>
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) {
resolve(result);
} else {
reject(new Error(loc.send.qr_error_no_qrcode));
}
});
} else if (response.error) {
presentCameraNotAuthorizedAlert(response.error);
}
},
),
);
};
const showFilePickerAndReadFile = async function () { const showFilePickerAndReadFile = async function () {
try { try {
const res = await DocumentPicker.pick({ const res = await DocumentPicker.pick({
@ -141,3 +193,5 @@ const showFilePickerAndReadFile = async function () {
module.exports.writeFileAndExport = writeFileAndExport; module.exports.writeFileAndExport = writeFileAndExport;
module.exports.openSignedTransaction = openSignedTransaction; module.exports.openSignedTransaction = openSignedTransaction;
module.exports.showFilePickerAndReadFile = showFilePickerAndReadFile; module.exports.showFilePickerAndReadFile = showFilePickerAndReadFile;
module.exports.showImagePickerAndReadImage = showImagePickerAndReadImage;
module.exports.takePhotoWithImagePickerAndReadPhoto = takePhotoWithImagePickerAndReadPhoto;

View file

@ -1,17 +1,16 @@
/* global alert */ /* global alert */
import React, { useState } from 'react'; import React, { useState } from 'react';
import { ActivityIndicator, Platform, ScrollView, StyleSheet, View } from 'react-native'; import { ActivityIndicator, ScrollView, StyleSheet, View } from 'react-native';
import { BlueNavigationStyle, BlueSpacing20, SafeBlueArea } from '../../BlueComponents'; import { BlueNavigationStyle, BlueSpacing20, SafeBlueArea } from '../../BlueComponents';
import { DynamicQRCode } from '../../components/DynamicQRCode'; import { DynamicQRCode } from '../../components/DynamicQRCode';
import { SquareButton } from '../../components/SquareButton'; import { SquareButton } from '../../components/SquareButton';
import { getSystemName } from 'react-native-device-info'; import { getSystemName } from 'react-native-device-info';
import loc from '../../loc'; import loc from '../../loc';
import { launchCamera } from 'react-native-image-picker';
import ScanQRCode from './ScanQRCode';
import { useNavigation, useRoute, useTheme } from '@react-navigation/native'; import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
import ActionSheet from '../ActionSheet';
const bitcoin = require('bitcoinjs-lib'); const bitcoin = require('bitcoinjs-lib');
const fs = require('../../blue_modules/fs'); const fs = require('../../blue_modules/fs');
const LocalQRCode = require('@remobile/react-native-qrcode-local-image');
const isDesktop = getSystemName() === 'Mac OS X'; const isDesktop = getSystemName() === 'Mac OS X';
const PsbtMultisigQRCode = () => { const PsbtMultisigQRCode = () => {
@ -41,35 +40,33 @@ const PsbtMultisigQRCode = () => {
} else if (ret.data.indexOf('+') === -1 && ret.data.indexOf('=') === -1 && ret.data.indexOf('=') === -1) { } else 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 looks like NOT base64, so maybe its transaction's hex
// we dont support it in this flow // we dont support it in this flow
alert(loc.wallets.import_error);
} else { } else {
// psbt base64? // psbt base64?
navigate('PsbtMultisig', { receivedPSBTBase64: ret.data }); navigate('PsbtMultisig', { receivedPSBTBase64: ret.data });
} }
}; };
const showActionSheet = () => {
const options = [loc._.cancel, loc.wallets.take_photo, loc.wallets.list_long_choose, loc.wallets.import_file];
ActionSheet.showActionSheetWithOptions({ options, cancelButtonIndex: 0 }, async buttonIndex => {
if (buttonIndex === 1) {
fs.takePhotoWithImagePickerAndReadPhoto.then(onBarScanned);
} else if (buttonIndex === 2) {
fs.showImagePickerAndReadImage(onBarScanned).catch(error => alert(error.message));
} else if (buttonIndex === 3) {
const { data } = await fs.showFilePickerAndReadFile();
if (data) {
onBarScanned({ data });
}
}
});
};
const openScanner = () => { const openScanner = () => {
if (isDesktop) { if (isDesktop) {
launchCamera( showActionSheet();
{
title: null,
mediaType: 'photo',
takePhotoButtonTitle: null,
},
response => {
if (response.uri) {
const uri = Platform.OS === 'ios' ? response.uri.toString().replace('file://', '') : response.uri;
LocalQRCode.decode(uri, (error, result) => {
if (!error) {
onBarScanned(result);
} else {
alert(loc.send.qr_error_no_qrcode);
}
});
} else if (response.error) {
ScanQRCode.presentCameraNotAuthorizedAlert(response.error);
}
},
);
} else { } else {
navigate('ScanQRCodeRoot', { navigate('ScanQRCodeRoot', {
screen: 'ScanQRCode', screen: 'ScanQRCode',

View file

@ -29,8 +29,6 @@ import { HDSegwitBech32Wallet, MultisigCosigner, MultisigHDWallet } from '../../
import { useNavigation, useRoute, useTheme } from '@react-navigation/native'; import { useNavigation, useRoute, useTheme } from '@react-navigation/native';
import loc from '../../loc'; import loc from '../../loc';
import { getSystemName } from 'react-native-device-info'; import { getSystemName } from 'react-native-device-info';
import { launchCamera } from 'react-native-image-picker';
import ScanQRCode from '../send/ScanQRCode';
import QRCode from 'react-native-qrcode-svg'; import QRCode from 'react-native-qrcode-svg';
import { SquareButton } from '../../components/SquareButton'; import { SquareButton } from '../../components/SquareButton';
import BottomModal from '../../components/BottomModal'; import BottomModal from '../../components/BottomModal';
@ -38,6 +36,7 @@ import MultipleStepsListItem, {
MultipleStepsListItemButtohType, MultipleStepsListItemButtohType,
MultipleStepsListItemDashType, MultipleStepsListItemDashType,
} from '../../components/MultipleStepsListItem'; } from '../../components/MultipleStepsListItem';
import ActionSheet from '../ActionSheet';
import Clipboard from '@react-native-community/clipboard'; import Clipboard from '@react-native-community/clipboard';
import showPopupMenu from 'react-native-popup-menu-android'; import showPopupMenu from 'react-native-popup-menu-android';
import ToolTip from 'react-native-tooltip'; import ToolTip from 'react-native-tooltip';
@ -48,7 +47,6 @@ const prompt = require('../../blue_modules/prompt');
const A = require('../../blue_modules/analytics'); const A = require('../../blue_modules/analytics');
const fs = require('../../blue_modules/fs'); const fs = require('../../blue_modules/fs');
const isDesktop = getSystemName() === 'Mac OS X'; const isDesktop = getSystemName() === 'Mac OS X';
const LocalQRCode = require('@remobile/react-native-qrcode-local-image');
const staticCache = {}; const staticCache = {};
const WalletsAddMultisigStep2 = () => { const WalletsAddMultisigStep2 = () => {
@ -315,7 +313,7 @@ const WalletsAddMultisigStep2 = () => {
const onBarScanned = ret => { const onBarScanned = ret => {
setIsProvideMnemonicsModalVisible(false); setIsProvideMnemonicsModalVisible(false);
navigation.dangerouslyGetParent().pop(); if (!isDesktop) navigation.dangerouslyGetParent().pop();
if (!ret.data) ret = { data: ret }; if (!ret.data) ret = { data: ret };
if (ret.data.toUpperCase().startsWith('UR')) { if (ret.data.toUpperCase().startsWith('UR')) {
alert('BC-UR not decoded. This should never happen'); alert('BC-UR not decoded. This should never happen');
@ -392,29 +390,8 @@ const WalletsAddMultisigStep2 = () => {
}; };
const scanOrOpenFile = () => { const scanOrOpenFile = () => {
setIsProvideMnemonicsModalVisible(false);
if (isDesktop) { if (isDesktop) {
launchCamera( showActionSheet();
{
title: null,
mediaType: 'photo',
takePhotoButtonTitle: null,
},
response => {
if (response.uri) {
const uri = Platform.OS === 'ios' ? response.uri.toString().replace('file://', '') : response.uri;
LocalQRCode.decode(uri, (error, result) => {
if (!error) {
onBarScanned(result);
} else {
alert(loc.send.qr_error_no_qrcode);
}
});
} else if (response.error) {
ScanQRCode.presentCameraNotAuthorizedAlert(response.error);
}
},
);
} else { } else {
navigation.navigate('ScanQRCodeRoot', { navigation.navigate('ScanQRCodeRoot', {
screen: 'ScanQRCode', screen: 'ScanQRCode',
@ -426,6 +403,23 @@ const WalletsAddMultisigStep2 = () => {
} }
}; };
const showActionSheet = () => {
const options = [loc._.cancel, loc.wallets.take_photo, loc.wallets.list_long_choose, loc.wallets.import_file];
ActionSheet.showActionSheetWithOptions({ options, cancelButtonIndex: 0 }, async buttonIndex => {
if (buttonIndex === 1) {
fs.takePhotoWithImagePickerAndReadPhoto.then(onBarScanned);
} else if (buttonIndex === 2) {
fs.showImagePickerAndReadImage(onBarScanned).catch(error => alert(error.message));
} else if (buttonIndex === 3) {
const { data } = await fs.showFilePickerAndReadFile();
if (data) {
onBarScanned({ data });
}
}
});
};
const _renderKeyItem = el => { const _renderKeyItem = el => {
const renderProvideKeyButtons = el.index === cosigners.length; const renderProvideKeyButtons = el.index === cosigners.length;
const isChecked = el.index < cosigners.length; const isChecked = el.index < cosigners.length;