forked from npomfret/react-native-cloud-fs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RNCloudFs.android.js
105 lines (96 loc) · 3.5 KB
/
RNCloudFs.android.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import {GoogleSignin} from '@react-native-google-signin/google-signin';
import GDrive from 'react-native-google-drive-api-wrapper';
import RNFS from 'react-native-fs';
import {FileList, File} from './common';
async function getParents(parts, scope, parentId) {
if (parts.length) {
const req = {
spaces: scope === 'hidden' ? 'appDataFolder' : 'drive',
fields: 'nextPageToken, files(id, name)',
q: "mimeType = 'application/vnd.google-apps.folder' and name = '" + parts[0] + "'",
};
if (parentId) req.q += " and '" + parentId + "' in parents";
else if (scope === 'hidden') req.q += " and 'appDataFolder' in parents";
const res = await (await GDrive.files.list(req)).json();
if (!res.files.length) {
//TODO create it not found
throw new Error('path not found');
}
if (parts.length > 1) {
return getParents(parts.slice(1), scope, res.files[0].id);
} else {
return [res.files[0].id];
}
} else {
return scope === 'hidden' ? ['appDataFolder'] : [];
}
}
export default class RNCloudFs {
static _initialized = false;
static _initializing = null;
static async fileExists() {
await RNCloudFs._ensureInitialized();
throw new Error('not implemented');
}
static async copyToCloud({sourcePath, targetPath, mimeType, scope}) {
await RNCloudFs._ensureInitialized();
if (!sourcePath.path) {
throw new Error('only path is supported for now');
}
const parts = targetPath.split('/');
const metadata = {
name: parts[parts.length - 1],
parents: await getParents(parts.slice(0, parts.length - 1), scope)
}
const data = await RNFS.readFile(sourcePath.path, 'base64');
const res = await (await GDrive.files.createFileMultipart(data, mimeType, metadata, true)).json();
return res.webContentLink;
}
static async listFiles({targetPath, scope}) {
await RNCloudFs._ensureInitialized();
const req = {
spaces: scope === 'hidden' ? 'appDataFolder' : 'drive',
fields: 'nextPageToken, files(id, name, size, modifiedTime, mimeType)',
};
if (targetPath) {
const parts = targetPath.split('/');
const parents = await getParents(parts, scope);
req.q = "'" + parents[0] + "' in parents";
}
//TODO handle pagination
const result = await (await GDrive.files.list(req)).json();
const files = result.files.map(({id, name, size, modifiedTime, mimeType}) => {
const isDirectory = mimeType === 'application/vnd.google-apps.folder';
const isFile = !isDirectory;
const uri = `https://www.googleapis.com/drive/v3/files/${id}?alt=media`
return new File(name, null, uri, modifiedTime, size, isFile, isDirectory);
});
return new FileList(targetPath, files || []);
}
static get accessToken() {
return RNCloudFs._accessToken;
}
static _ensureInitialized() {
if (RNCloudFs._initialized || RNCloudFs._initializing) {
return RNCloudFs._initializing;
}
RNCloudFs._initializing = RNCloudFs._initialize();
return RNCloudFs._initializing;
}
static async _initialize() {
try {
GoogleSignin.configure({
scopes: ['https://www.googleapis.com/auth/drive.appdata']
});
await GoogleSignin.hasPlayServices();
await GoogleSignin.signIn();
const { accessToken } = await GoogleSignin.getTokens();
GDrive.init();
GDrive.setAccessToken(accessToken);
RNCloudFs._accessToken = accessToken;
RNCloudFs._initialized = true;
} finally {
RNCloudFs._initializing = null;
}
}
}