diff --git a/android/app/build.gradle b/android/app/build.gradle
index 3ecfc63..c74c06e 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -285,6 +285,8 @@ dependencies {
} else {
implementation jscFlavor
}
+
+ implementation project(':react-native-fs')
}
if (isNewArchitectureEnabled()) {
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 045c4e7..ce3243e 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -2,6 +2,8 @@
package="com.browses3">
+
+
+ android:theme="@style/AppTheme"
+ android:requestLegacyExternalStorage="true">
{
ToastAndroid.show('Successfully saved settings', ToastAndroid.SHORT);
})
.catch(e => {
- console.log(e);
ToastAndroid.show('Failed to save settings', ToastAndroid.SHORT);
throw e;
});
diff --git a/src/screens/Buckets.js b/src/screens/Buckets.js
index 10ed579..3db9a20 100644
--- a/src/screens/Buckets.js
+++ b/src/screens/Buckets.js
@@ -1,11 +1,12 @@
import React, {useState, useEffect} from 'react';
-import {ScrollView, ToastAndroid} from 'react-native';
+import {ScrollView, ToastAndroid, Text} from 'react-native';
import useS3 from '../hooks/useS3';
import Bucket from '../components/Bucket';
const Buckets = () => {
const s3 = useS3();
const [buckets, setBuckets] = useState([]);
+ const [loading, setLoading] = useState(true);
useEffect(() => {
if (s3 && !buckets.length) {
@@ -16,10 +17,15 @@ const Buckets = () => {
}
setBuckets(data.Buckets);
+ setLoading(false);
});
}
}, [s3]);
+ if (loading) {
+ return Loading...;
+ }
+
return (
{buckets.map(bucket => (
diff --git a/src/screens/DirectoryDetails.js b/src/screens/DirectoryDetails.js
index df29f75..50fa522 100644
--- a/src/screens/DirectoryDetails.js
+++ b/src/screens/DirectoryDetails.js
@@ -1,5 +1,5 @@
import React, {useState, useEffect} from 'react';
-import {ScrollView, ToastAndroid} from 'react-native';
+import {ScrollView, ToastAndroid, Text} from 'react-native';
import {useRoute} from '@react-navigation/native';
import useS3 from '../hooks/useS3';
import Directory from '../components/Directory';
@@ -9,6 +9,7 @@ const DirectoryDetails = () => {
const route = useRoute();
const s3 = useS3();
const [contents, setContents] = useState({dirs: [], files: []});
+ const [loading, setLoading] = useState(true);
useEffect(() => {
if (s3 && !contents.length) {
@@ -29,11 +30,16 @@ const DirectoryDetails = () => {
}
setContents({dirs: data.CommonPrefixes, files: data.Contents});
+ setLoading(false);
},
);
}
}, [s3]);
+ if (loading) {
+ return Loading...;
+ }
+
return (
{contents.dirs.map(dir => (
diff --git a/src/screens/FileDetails.js b/src/screens/FileDetails.js
index bc55382..831e568 100644
--- a/src/screens/FileDetails.js
+++ b/src/screens/FileDetails.js
@@ -1,14 +1,16 @@
-import React, {useState, useEffect} from 'react';
+import React, {useState, useEffect, useCallback} from 'react';
import {
StyleSheet,
ScrollView,
Text,
+ View,
Button,
ToastAndroid,
PermissionsAndroid,
} from 'react-native';
import {useRoute} from '@react-navigation/native';
import prettyBytes from 'pretty-bytes';
+import RNFS from 'react-native-fs';
import useS3 from '../hooks/useS3';
const FileDetails = () => {
@@ -18,10 +20,10 @@ const FileDetails = () => {
useEffect(() => {
if (s3 && !data) {
- s3.getObject(
+ s3.headObject(
{
Bucket: route.params.bucket,
- Key: route.params.file
+ Key: route.params.file,
},
(err, data) => {
if (err) {
@@ -35,6 +37,66 @@ const FileDetails = () => {
}
}, [s3]);
+ const download = useCallback(() => {
+ PermissionsAndroid.request(
+ PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
+ )
+ .then(granted => {
+ if (granted != PermissionsAndroid.RESULTS.GRANTED) {
+ throw new Error('No permission');
+ }
+ })
+ .then(() =>
+ PermissionsAndroid.request(
+ PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
+ ),
+ )
+ .then(granted => {
+ if (granted != PermissionsAndroid.RESULTS.GRANTED) {
+ throw new Error('No permission');
+ }
+ })
+ .then(() => {
+ ToastAndroid.show('Downloading...', ToastAndroid.LONG);
+
+ s3.getObject(
+ {
+ Bucket: route.params.bucket,
+ Key: route.params.file,
+ },
+ (err, data) => {
+ if (err) {
+ ToastAndroid.show('Failed to download file', ToastAndroid.SHORT);
+ return;
+ }
+
+ const dir = `${RNFS.DownloadDirectoryPath}/BrowseS3/${route.params.bucket}`;
+ const file = `${dir}/${route.params.file.replace(/\//g, '_')}`;
+ const fileContents = data.Body.toString('base64');
+
+ RNFS.mkdir(dir)
+ .then(() => RNFS.writeFile(file, fileContents, 'base64'))
+ .then(() => RNFS.scanFile(file))
+ .then(() => {
+ ToastAndroid.show('Download completed', ToastAndroid.SHORT);
+ })
+ .catch(e => {
+ ToastAndroid.show(
+ 'Failed to download file',
+ ToastAndroid.SHORT,
+ );
+ });
+ },
+ );
+ })
+ .catch(() => {
+ ToastAndroid.show(
+ 'You need to grant the write permission to download files',
+ ToastAndroid.SHORT,
+ );
+ });
+ }, [s3, route]);
+
if (!data) {
return Loading...;
}
@@ -48,6 +110,9 @@ const FileDetails = () => {
Size: {prettyBytes(data.ContentLength)}
Content type: {data.ContentType}
+
+
+
);
};
diff --git a/src/screens/SignUp.js b/src/screens/SignUp.js
index 3442e0b..984c938 100644
--- a/src/screens/SignUp.js
+++ b/src/screens/SignUp.js
@@ -21,7 +21,6 @@ const SignUp = () => {
signUp(email, pass)
.then(() => {
- console.log('asdasd');
navigation.reset({index: 0, routes: [{name: 'Buckets'}]});
})
.catch(() => {});