mirror of
https://github.com/BlueWallet/BlueWallet.git
synced 2025-03-12 18:51:21 +01:00
Merge pull request #7051 from BlueWallet/saveandroid
FIX: FIle save on Android 13+
This commit is contained in:
commit
6dd7cad5ad
3 changed files with 66 additions and 82 deletions
|
@ -1,10 +1,10 @@
|
||||||
import LocalQRCode from '@remobile/react-native-qrcode-local-image';
|
import LocalQRCode from '@remobile/react-native-qrcode-local-image';
|
||||||
import { Alert, Linking, PermissionsAndroid, Platform } from 'react-native';
|
import { Alert, Linking, Platform } from 'react-native';
|
||||||
import DocumentPicker from 'react-native-document-picker';
|
import DocumentPicker from 'react-native-document-picker';
|
||||||
import RNFS from 'react-native-fs';
|
import RNFS from 'react-native-fs';
|
||||||
import { launchImageLibrary } from 'react-native-image-picker';
|
import { launchImageLibrary } from 'react-native-image-picker';
|
||||||
import Share from 'react-native-share';
|
import Share from 'react-native-share';
|
||||||
|
import { request, PERMISSIONS } from 'react-native-permissions';
|
||||||
import presentAlert from '../components/Alert';
|
import presentAlert from '../components/Alert';
|
||||||
import loc from '../loc';
|
import loc from '../loc';
|
||||||
import { isDesktop } from './environment';
|
import { isDesktop } from './environment';
|
||||||
|
@ -39,6 +39,7 @@ const _shareOpen = async (filePath: string, showShareDialog: boolean = false) =>
|
||||||
* Writes a file to fs, and triggers an OS sharing dialog, so user can decide where to put this file (share to cloud
|
* Writes a file to fs, and triggers an OS sharing dialog, so user can decide where to put this file (share to cloud
|
||||||
* or perhabs messaging app). Provided filename should be just a file name, NOT a path
|
* or perhabs messaging app). Provided filename should be just a file name, NOT a path
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const writeFileAndExport = async function (fileName: string, contents: string, showShareDialog: boolean = true) {
|
export const writeFileAndExport = async function (fileName: string, contents: string, showShareDialog: boolean = true) {
|
||||||
const sanitizedFileName = _sanitizeFileName(fileName);
|
const sanitizedFileName = _sanitizeFileName(fileName);
|
||||||
if (Platform.OS === 'ios') {
|
if (Platform.OS === 'ios') {
|
||||||
|
@ -46,31 +47,22 @@ export const writeFileAndExport = async function (fileName: string, contents: st
|
||||||
await RNFS.writeFile(filePath, contents);
|
await RNFS.writeFile(filePath, contents);
|
||||||
await _shareOpen(filePath, showShareDialog);
|
await _shareOpen(filePath, showShareDialog);
|
||||||
} else if (Platform.OS === 'android') {
|
} else if (Platform.OS === 'android') {
|
||||||
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, {
|
const isAndroidVersion33OrAbove = Platform.Version >= 33;
|
||||||
title: loc.send.permission_storage_title,
|
const permissionType = isAndroidVersion33OrAbove ? PERMISSIONS.ANDROID.READ_MEDIA_IMAGES : PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE;
|
||||||
message: loc.send.permission_storage_message,
|
request(permissionType).then(async result => {
|
||||||
buttonNeutral: loc.send.permission_storage_later,
|
if (result === 'granted') {
|
||||||
buttonNegative: loc._.cancel,
|
const filePath = RNFS.ExternalDirectoryPath + `/${sanitizedFileName}`;
|
||||||
buttonPositive: loc._.ok,
|
|
||||||
});
|
|
||||||
|
|
||||||
// In Android 13 no WRITE_EXTERNAL_STORAGE permission is needed
|
|
||||||
// @see https://stackoverflow.com/questions/76311685/permissionandroid-request-always-returns-never-ask-again-without-any-prompt-r
|
|
||||||
if (granted === PermissionsAndroid.RESULTS.GRANTED || Platform.Version >= 30) {
|
|
||||||
const filePath = RNFS.DownloadDirectoryPath + `/${sanitizedFileName}`;
|
|
||||||
try {
|
try {
|
||||||
await RNFS.writeFile(filePath, contents);
|
await RNFS.writeFile(filePath, contents);
|
||||||
console.log(`file saved to ${filePath}`);
|
|
||||||
if (showShareDialog) {
|
if (showShareDialog) {
|
||||||
await _shareOpen(filePath);
|
await _shareOpen(filePath);
|
||||||
} else {
|
} else {
|
||||||
presentAlert({ message: loc.formatString(loc.send.file_saved_at_path, { fileName: sanitizedFileName }) });
|
presentAlert({ message: loc.formatString(loc.send.file_saved_at_path, { filePath }) });
|
||||||
}
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log(e);
|
presentAlert({ message: e.message });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('Storage Permission: Denied');
|
|
||||||
Alert.alert(loc.send.permission_storage_title, loc.send.permission_storage_denied_message, [
|
Alert.alert(loc.send.permission_storage_title, loc.send.permission_storage_denied_message, [
|
||||||
{
|
{
|
||||||
text: loc.send.open_settings,
|
text: loc.send.open_settings,
|
||||||
|
@ -82,8 +74,7 @@ export const writeFileAndExport = async function (fileName: string, contents: st
|
||||||
{ text: loc._.cancel, onPress: () => {}, style: 'cancel' },
|
{ text: loc._.cancel, onPress: () => {}, style: 'cancel' },
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
presentAlert({ message: 'Not implemented for this platform' });
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -178,8 +178,6 @@
|
||||||
"permission_camera_message": "We need your permission to use your camera.",
|
"permission_camera_message": "We need your permission to use your camera.",
|
||||||
"psbt_sign": "Sign a transaction",
|
"psbt_sign": "Sign a transaction",
|
||||||
"open_settings": "Open Settings",
|
"open_settings": "Open Settings",
|
||||||
"permission_storage_later": "Ask me later.",
|
|
||||||
"permission_storage_message": "BlueWallet needs your permission to access your storage to save this file.",
|
|
||||||
"permission_storage_denied_message": "BlueWallet is unable to save this file. Please open your device settings and enable Storage Permission.",
|
"permission_storage_denied_message": "BlueWallet is unable to save this file. Please open your device settings and enable Storage Permission.",
|
||||||
"permission_storage_title": "Storage Access Permission",
|
"permission_storage_title": "Storage Access Permission",
|
||||||
"psbt_clipboard": "Copy to Clipboard",
|
"psbt_clipboard": "Copy to Clipboard",
|
||||||
|
@ -193,8 +191,8 @@
|
||||||
"reset_amount": "Reset Amount",
|
"reset_amount": "Reset Amount",
|
||||||
"reset_amount_confirm": "Would you like to reset the amount?",
|
"reset_amount_confirm": "Would you like to reset the amount?",
|
||||||
"success_done": "Done",
|
"success_done": "Done",
|
||||||
"txSaved": "The transaction file ({filePath}) has been saved in your Downloads folder.",
|
"txSaved": "The transaction file ({filePath}) has been saved.",
|
||||||
"file_saved_at_path": "The file ({fileName}) has been saved in your Downloads folder.",
|
"file_saved_at_path": "The file ({filePath}) has been saved.",
|
||||||
"cant_send_to_silentpayment_adress": "This wallet cannot send to SilentPayment addresses",
|
"cant_send_to_silentpayment_adress": "This wallet cannot send to SilentPayment addresses",
|
||||||
"cant_send_to_bip47": "This wallet cannot send to BIP47 payment codes",
|
"cant_send_to_bip47": "This wallet cannot send to BIP47 payment codes",
|
||||||
"cant_find_bip47_notification": "Add this Payment Code to contacts first",
|
"cant_find_bip47_notification": "Add this Payment Code to contacts first",
|
||||||
|
|
|
@ -11,7 +11,7 @@ import * as BlueElectrum from '../../blue_modules/BlueElectrum';
|
||||||
import * as encryption from '../../blue_modules/encryption';
|
import * as encryption from '../../blue_modules/encryption';
|
||||||
import * as fs from '../../blue_modules/fs';
|
import * as fs from '../../blue_modules/fs';
|
||||||
import ecc from '../../blue_modules/noble_ecc';
|
import ecc from '../../blue_modules/noble_ecc';
|
||||||
import { BlueCard, BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents';
|
import { BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents';
|
||||||
import {
|
import {
|
||||||
HDAezeedWallet,
|
HDAezeedWallet,
|
||||||
HDSegwitBech32Wallet,
|
HDSegwitBech32Wallet,
|
||||||
|
@ -22,7 +22,6 @@ import {
|
||||||
} from '../../class';
|
} from '../../class';
|
||||||
import presentAlert from '../../components/Alert';
|
import presentAlert from '../../components/Alert';
|
||||||
import Button from '../../components/Button';
|
import Button from '../../components/Button';
|
||||||
import SafeArea from '../../components/SafeArea';
|
|
||||||
import SaveFileButton from '../../components/SaveFileButton';
|
import SaveFileButton from '../../components/SaveFileButton';
|
||||||
import loc from '../../loc';
|
import loc from '../../loc';
|
||||||
|
|
||||||
|
@ -285,17 +284,14 @@ export default class SelfTest extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.state.isLoading) {
|
|
||||||
return <BlueLoading />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeArea>
|
<ScrollView automaticallyAdjustContentInsets contentInsetAdjustmentBehavior="automatic">
|
||||||
<BlueCard>
|
|
||||||
<ScrollView>
|
|
||||||
<BlueSpacing20 />
|
<BlueSpacing20 />
|
||||||
|
|
||||||
{(() => {
|
{this.state.isLoading ? (
|
||||||
|
<BlueLoading />
|
||||||
|
) : (
|
||||||
|
(() => {
|
||||||
if (this.state.isOk) {
|
if (this.state.isOk) {
|
||||||
return (
|
return (
|
||||||
<View style={styles.center}>
|
<View style={styles.center}>
|
||||||
|
@ -315,7 +311,8 @@ export default class SelfTest extends Component {
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})()}
|
})()
|
||||||
|
)}
|
||||||
<BlueSpacing20 />
|
<BlueSpacing20 />
|
||||||
<SaveFileButton fileName="bluewallet-selftest.txt" fileContent={'Success on ' + new Date().toUTCString()}>
|
<SaveFileButton fileName="bluewallet-selftest.txt" fileContent={'Success on ' + new Date().toUTCString()}>
|
||||||
<Button title="Test Save to Storage" />
|
<Button title="Test Save to Storage" />
|
||||||
|
@ -323,8 +320,6 @@ export default class SelfTest extends Component {
|
||||||
<BlueSpacing20 />
|
<BlueSpacing20 />
|
||||||
<Button title="Test File Import" onPress={this.onPressImportDocument} />
|
<Button title="Test File Import" onPress={this.onPressImportDocument} />
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</BlueCard>
|
|
||||||
</SafeArea>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue