diff --git a/blue_modules/fs.ts b/blue_modules/fs.ts
index 6869a8375..18b3af253 100644
--- a/blue_modules/fs.ts
+++ b/blue_modules/fs.ts
@@ -1,10 +1,10 @@
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 RNFS from 'react-native-fs';
import { launchImageLibrary } from 'react-native-image-picker';
import Share from 'react-native-share';
-
+import { request, PERMISSIONS } from 'react-native-permissions';
import presentAlert from '../components/Alert';
import loc from '../loc';
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
* 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) {
const sanitizedFileName = _sanitizeFileName(fileName);
if (Platform.OS === 'ios') {
@@ -46,44 +47,34 @@ export const writeFileAndExport = async function (fileName: string, contents: st
await RNFS.writeFile(filePath, contents);
await _shareOpen(filePath, showShareDialog);
} else if (Platform.OS === 'android') {
- const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, {
- title: loc.send.permission_storage_title,
- message: loc.send.permission_storage_message,
- buttonNeutral: loc.send.permission_storage_later,
- buttonNegative: loc._.cancel,
- 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 {
- await RNFS.writeFile(filePath, contents);
- console.log(`file saved to ${filePath}`);
- if (showShareDialog) {
- await _shareOpen(filePath);
- } else {
- presentAlert({ message: loc.formatString(loc.send.file_saved_at_path, { fileName: sanitizedFileName }) });
+ const isAndroidVersion33OrAbove = Platform.Version >= 33;
+ const permissionType = isAndroidVersion33OrAbove ? PERMISSIONS.ANDROID.READ_MEDIA_IMAGES : PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE;
+ request(permissionType).then(async result => {
+ if (result === 'granted') {
+ const filePath = RNFS.ExternalDirectoryPath + `/${sanitizedFileName}`;
+ try {
+ await RNFS.writeFile(filePath, contents);
+ if (showShareDialog) {
+ await _shareOpen(filePath);
+ } else {
+ presentAlert({ message: loc.formatString(loc.send.file_saved_at_path, { filePath }) });
+ }
+ } catch (e: any) {
+ presentAlert({ message: e.message });
}
- } catch (e: any) {
- console.log(e);
- }
- } else {
- console.log('Storage Permission: Denied');
- Alert.alert(loc.send.permission_storage_title, loc.send.permission_storage_denied_message, [
- {
- text: loc.send.open_settings,
- onPress: () => {
- Linking.openSettings();
+ } else {
+ Alert.alert(loc.send.permission_storage_title, loc.send.permission_storage_denied_message, [
+ {
+ text: loc.send.open_settings,
+ onPress: () => {
+ Linking.openSettings();
+ },
+ style: 'default',
},
- style: 'default',
- },
- { text: loc._.cancel, onPress: () => {}, style: 'cancel' },
- ]);
- }
- } else {
- presentAlert({ message: 'Not implemented for this platform' });
+ { text: loc._.cancel, onPress: () => {}, style: 'cancel' },
+ ]);
+ }
+ });
}
};
diff --git a/loc/en.json b/loc/en.json
index 96ef838dc..9ecf5079e 100644
--- a/loc/en.json
+++ b/loc/en.json
@@ -178,8 +178,6 @@
"permission_camera_message": "We need your permission to use your camera.",
"psbt_sign": "Sign a transaction",
"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_title": "Storage Access Permission",
"psbt_clipboard": "Copy to Clipboard",
@@ -193,8 +191,8 @@
"reset_amount": "Reset Amount",
"reset_amount_confirm": "Would you like to reset the amount?",
"success_done": "Done",
- "txSaved": "The transaction file ({filePath}) has been saved in your Downloads folder.",
- "file_saved_at_path": "The file ({fileName}) has been saved in your Downloads folder.",
+ "txSaved": "The transaction file ({filePath}) has been saved.",
+ "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_bip47": "This wallet cannot send to BIP47 payment codes",
"cant_find_bip47_notification": "Add this Payment Code to contacts first",
diff --git a/screen/settings/SelfTest.js b/screen/settings/SelfTest.js
index 51249db02..afca3de6c 100644
--- a/screen/settings/SelfTest.js
+++ b/screen/settings/SelfTest.js
@@ -11,7 +11,7 @@ import * as BlueElectrum from '../../blue_modules/BlueElectrum';
import * as encryption from '../../blue_modules/encryption';
import * as fs from '../../blue_modules/fs';
import ecc from '../../blue_modules/noble_ecc';
-import { BlueCard, BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents';
+import { BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents';
import {
HDAezeedWallet,
HDSegwitBech32Wallet,
@@ -22,7 +22,6 @@ import {
} from '../../class';
import presentAlert from '../../components/Alert';
import Button from '../../components/Button';
-import SafeArea from '../../components/SafeArea';
import SaveFileButton from '../../components/SaveFileButton';
import loc from '../../loc';
@@ -285,46 +284,42 @@ export default class SelfTest extends Component {
}
render() {
- if (this.state.isLoading) {
- return ;
- }
-
return (
-
-
-
-
+
+
- {(() => {
- if (this.state.isOk) {
- return (
-
-
- OK
-
-
- {loc.settings.about_selftest_ok}
-
- );
- } else {
- return (
-
-
- {this.state.errorMessage}
-
-
- );
- }
- })()}
-
-
-
-
-
-
-
-
-
+ {this.state.isLoading ? (
+
+ ) : (
+ (() => {
+ if (this.state.isOk) {
+ return (
+
+
+ OK
+
+
+ {loc.settings.about_selftest_ok}
+
+ );
+ } else {
+ return (
+
+
+ {this.state.errorMessage}
+
+
+ );
+ }
+ })()
+ )}
+
+
+
+
+
+
+
);
}
}