@onekeyfe/react-native-cloud-fs 3.0.14 → 3.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -74,4 +74,14 @@ def kotlin_version = getExtOrDefault("kotlinVersion")
74
74
  dependencies {
75
75
  implementation "com.facebook.react:react-android"
76
76
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
77
+
78
+ // Google Drive / Sign-In
79
+ implementation "com.google.android.gms:play-services-auth:21.3.0"
80
+ implementation "com.google.http-client:google-http-client-gson:1.44.1"
81
+ implementation("com.google.api-client:google-api-client-android:2.7.0") {
82
+ exclude group: "org.apache.httpcomponents"
83
+ }
84
+ implementation("com.google.apis:google-api-services-drive:v3-rev20241027-2.0.0") {
85
+ exclude group: "org.apache.httpcomponents"
86
+ }
77
87
  }
@@ -0,0 +1,108 @@
1
+ package com.rncloudfs
2
+
3
+ import android.util.Log
4
+ import com.google.android.gms.tasks.Task
5
+ import com.google.android.gms.tasks.Tasks
6
+ import com.google.api.client.http.FileContent
7
+ import com.google.api.services.drive.Drive
8
+ import com.google.api.services.drive.model.FileList
9
+ import java.io.BufferedReader
10
+ import java.io.InputStreamReader
11
+ import java.util.concurrent.Executors
12
+
13
+ class DriveServiceHelper(private val driveService: Drive) {
14
+
15
+ private val executor = Executors.newSingleThreadExecutor()
16
+
17
+ fun saveFile(
18
+ sourcePath: String,
19
+ destinationPath: String,
20
+ mimeType: String?,
21
+ useDocumentsFolder: Boolean
22
+ ): Task<String> {
23
+ var existingFileId: String? = null
24
+ val fileList = Tasks.await(queryFiles(useDocumentsFolder))
25
+ for (file in fileList.files) {
26
+ if (file.name.equals(destinationPath, ignoreCase = true)) {
27
+ existingFileId = file.id
28
+ }
29
+ }
30
+ return createFile(sourcePath, destinationPath, mimeType, useDocumentsFolder, existingFileId)
31
+ }
32
+
33
+ fun createFile(
34
+ sourcePath: String,
35
+ destinationPath: String,
36
+ mimeType: String?,
37
+ useDocumentsFolder: Boolean,
38
+ fileId: String?
39
+ ): Task<String> {
40
+ return Tasks.call(executor) {
41
+ try {
42
+ val sourceFile = java.io.File(sourcePath)
43
+ val mediaContent = FileContent(mimeType, sourceFile)
44
+ val parentFolder = listOf(if (useDocumentsFolder) "root" else "appDataFolder")
45
+ val metadata = com.google.api.services.drive.model.File()
46
+ .setMimeType(mimeType)
47
+ .setName(destinationPath)
48
+ if (fileId == null) {
49
+ metadata.parents = parentFolder
50
+ }
51
+
52
+ val googleFile = if (fileId != null) {
53
+ driveService.files().update(fileId, metadata, mediaContent).execute()
54
+ } else {
55
+ driveService.files().create(metadata, mediaContent).execute()
56
+ }
57
+
58
+ googleFile?.id ?: throw java.io.IOException("Null result when requesting file creation.")
59
+ } catch (e: Exception) {
60
+ Log.e(TAG, e.toString())
61
+ throw e
62
+ }
63
+ }
64
+ }
65
+
66
+ fun checkIfFileExists(fileId: String): Task<Boolean> {
67
+ return Tasks.call(executor) {
68
+ val metadata = driveService.files().get(fileId).execute()
69
+ metadata != null
70
+ }
71
+ }
72
+
73
+ fun deleteFile(fileId: String): Task<Boolean> {
74
+ return Tasks.call(executor) {
75
+ driveService.files().delete(fileId).execute()
76
+ true
77
+ }
78
+ }
79
+
80
+ fun readFile(fileId: String): Task<String> {
81
+ return Tasks.call(executor) {
82
+ driveService.files().get(fileId).executeMediaAsInputStream().use { inputStream ->
83
+ BufferedReader(InputStreamReader(inputStream)).use { reader ->
84
+ val sb = StringBuilder()
85
+ var line: String?
86
+ while (reader.readLine().also { line = it } != null) {
87
+ sb.append(line)
88
+ }
89
+ sb.toString()
90
+ }
91
+ }
92
+ }
93
+ }
94
+
95
+ fun queryFiles(useDocumentsFolder: Boolean): Task<FileList> {
96
+ return Tasks.call(executor) {
97
+ driveService.files().list()
98
+ .setSpaces(if (useDocumentsFolder) "drive" else "appDataFolder")
99
+ .setFields("nextPageToken, files(id, name, modifiedTime)")
100
+ .setPageSize(100)
101
+ .execute()
102
+ }
103
+ }
104
+
105
+ companion object {
106
+ private const val TAG = "DriveServiceHelper"
107
+ }
108
+ }
@@ -1,50 +1,425 @@
1
1
  package com.rncloudfs
2
2
 
3
+ import android.app.Activity
4
+ import android.content.Intent
5
+ import android.net.Uri
6
+ import android.util.Log
7
+ import android.webkit.MimeTypeMap
8
+ import com.facebook.react.bridge.ActivityEventListener
9
+ import com.facebook.react.bridge.LifecycleEventListener
3
10
  import com.facebook.react.bridge.Promise
4
11
  import com.facebook.react.bridge.ReactApplicationContext
5
12
  import com.facebook.react.bridge.ReadableMap
13
+ import com.facebook.react.bridge.WritableNativeArray
14
+ import com.facebook.react.bridge.WritableNativeMap
6
15
  import com.facebook.react.module.annotations.ReactModule
16
+ import com.google.android.gms.auth.api.signin.GoogleSignIn
17
+ import com.google.android.gms.auth.api.signin.GoogleSignInClient
18
+ import com.google.android.gms.auth.api.signin.GoogleSignInOptions
19
+ import com.google.android.gms.common.api.ApiException
20
+ import com.google.android.gms.common.api.Scope
21
+ import com.google.api.client.extensions.android.http.AndroidHttp
22
+ import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential
23
+ import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException
24
+ import com.google.api.client.json.gson.GsonFactory
25
+ import com.google.api.services.drive.Drive
26
+ import com.google.api.services.drive.DriveScopes
27
+ import java.util.Collections
7
28
 
8
29
  @ReactModule(name = RNCloudFsModule.NAME)
9
- class RNCloudFsModule(reactContext: ReactApplicationContext) :
10
- NativeRNCloudFsSpec(reactContext) {
30
+ class RNCloudFsModule(private val reactContext: ReactApplicationContext) :
31
+ NativeRNCloudFsSpec(reactContext), LifecycleEventListener, ActivityEventListener {
32
+
33
+ private var mDriveServiceHelper: DriveServiceHelper? = null
34
+ private var signInPromise: Promise? = null
35
+ private var mPendingPromise: Promise? = null
36
+ private var mPendingOptions: ReadableMap? = null
37
+ private var mPendingOperation: String? = null
38
+
39
+ init {
40
+ reactContext.addLifecycleEventListener(this)
41
+ reactContext.addActivityEventListener(this)
42
+ }
11
43
 
12
44
  companion object {
13
45
  const val NAME = "RNCloudFs"
14
- private const val NOT_AVAILABLE_ERROR = "iCloud is not available on Android"
46
+ private const val TAG = "RNCloudFs"
47
+ private const val REQUEST_CODE_SIGN_IN = 1
48
+ private const val REQUEST_AUTHORIZATION = 11
49
+ private const val COPY_TO_CLOUD = "CopyToCloud"
50
+ private const val LIST_FILES = "ListFiles"
15
51
  }
16
52
 
17
53
  override fun getName(): String = NAME
18
54
 
55
+ // region iOS-only stubs
56
+
19
57
  override fun isAvailable(promise: Promise) {
20
58
  promise.resolve(false)
21
59
  }
22
60
 
23
61
  override fun createFile(options: ReadableMap, promise: Promise) {
24
- promise.reject("NOT_AVAILABLE", NOT_AVAILABLE_ERROR)
62
+ promise.reject("NOT_AVAILABLE", "iCloud is not available on Android")
25
63
  }
26
64
 
27
- override fun fileExists(options: ReadableMap, promise: Promise) {
28
- promise.reject("NOT_AVAILABLE", NOT_AVAILABLE_ERROR)
65
+ override fun getIcloudDocument(filename: String, promise: Promise) {
66
+ promise.reject("NOT_AVAILABLE", "iCloud is not available on Android")
29
67
  }
30
68
 
31
- override fun listFiles(options: ReadableMap, promise: Promise) {
32
- promise.reject("NOT_AVAILABLE", NOT_AVAILABLE_ERROR)
69
+ override fun syncCloud(promise: Promise) {
70
+ promise.reject("NOT_AVAILABLE", "iCloud is not available on Android")
33
71
  }
34
72
 
35
- override fun getIcloudDocument(filename: String, promise: Promise) {
36
- promise.reject("NOT_AVAILABLE", NOT_AVAILABLE_ERROR)
73
+ // endregion
74
+
75
+ // region Google Sign-In
76
+
77
+ override fun loginIfNeeded(promise: Promise) {
78
+ if (mDriveServiceHelper == null) {
79
+ val account = GoogleSignIn.getLastSignedInAccount(reactContext)
80
+ if (account == null) {
81
+ signInPromise = promise
82
+ requestSignIn()
83
+ } else {
84
+ val credential = GoogleAccountCredential.usingOAuth2(
85
+ reactContext, Collections.singleton(DriveScopes.DRIVE_APPDATA)
86
+ )
87
+ credential.selectedAccount = account.account
88
+ val googleDriveService = Drive.Builder(
89
+ AndroidHttp.newCompatibleTransport(),
90
+ GsonFactory(),
91
+ credential
92
+ ).build()
93
+ mDriveServiceHelper = DriveServiceHelper(googleDriveService)
94
+ promise.resolve(true)
95
+ }
96
+ } else {
97
+ promise.resolve(true)
98
+ }
99
+ }
100
+
101
+ override fun logout(promise: Promise) {
102
+ val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
103
+ .requestEmail()
104
+ .requestScopes(Scope(DriveScopes.DRIVE_FILE))
105
+ .build()
106
+ val client: GoogleSignInClient = GoogleSignIn.getClient(reactContext, signInOptions)
107
+ mDriveServiceHelper = null
108
+ client.signOut()
109
+ .addOnSuccessListener { promise.resolve(true) }
110
+ .addOnFailureListener { exception ->
111
+ Log.e(TAG, "Couldn't log out.", exception)
112
+ promise.reject(exception)
113
+ }
114
+ }
115
+
116
+ override fun getCurrentlySignedInUserData(promise: Promise) {
117
+ val account = GoogleSignIn.getLastSignedInAccount(reactContext)
118
+ if (account == null) {
119
+ promise.resolve(null)
120
+ } else {
121
+ val photoUrl: Uri? = account.photoUrl
122
+ val resultData = WritableNativeMap()
123
+ resultData.putString("email", account.email)
124
+ resultData.putString("name", account.displayName)
125
+ resultData.putString("avatarUrl", photoUrl?.toString())
126
+ promise.resolve(resultData)
127
+ }
128
+ }
129
+
130
+ private fun requestSignIn() {
131
+ Log.d(TAG, "Requesting sign-in")
132
+ val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
133
+ .requestEmail()
134
+ .requestScopes(Scope(DriveScopes.DRIVE_FILE))
135
+ .build()
136
+ val client: GoogleSignInClient = GoogleSignIn.getClient(reactContext, signInOptions)
137
+ reactContext.startActivityForResult(client.signInIntent, REQUEST_CODE_SIGN_IN, null)
138
+ }
139
+
140
+ // endregion
141
+
142
+ // region Google Drive operations
143
+
144
+ override fun fileExists(options: ReadableMap, promise: Promise) {
145
+ val helper = mDriveServiceHelper
146
+ if (helper != null) {
147
+ val fileId = options.getString("fileId") ?: ""
148
+ Log.d(TAG, "Checking file $fileId")
149
+ helper.checkIfFileExists(fileId)
150
+ .addOnSuccessListener { exists -> promise.resolve(exists) }
151
+ .addOnFailureListener { exception ->
152
+ try {
153
+ val e = exception as UserRecoverableAuthIOException
154
+ reactContext.startActivityForResult(e.intent, REQUEST_AUTHORIZATION, null)
155
+ } catch (e: Exception) {
156
+ Log.e(TAG, "Couldn't check file.", exception)
157
+ promise.reject(exception)
158
+ }
159
+ }
160
+ } else {
161
+ promise.reject("NOT_LOGGED_IN", "Google Drive not initialized. Call loginIfNeeded first.")
162
+ }
37
163
  }
38
164
 
39
165
  override fun deleteFromCloud(item: ReadableMap, promise: Promise) {
40
- promise.reject("NOT_AVAILABLE", NOT_AVAILABLE_ERROR)
166
+ val helper = mDriveServiceHelper
167
+ if (helper != null) {
168
+ val fileId = item.getString("id") ?: ""
169
+ Log.d(TAG, "Deleting file $fileId")
170
+ helper.deleteFile(fileId)
171
+ .addOnSuccessListener { deleted -> promise.resolve(deleted) }
172
+ .addOnFailureListener { exception ->
173
+ try {
174
+ val e = exception as UserRecoverableAuthIOException
175
+ reactContext.startActivityForResult(e.intent, REQUEST_AUTHORIZATION, null)
176
+ } catch (e: Exception) {
177
+ Log.e(TAG, "Couldn't delete file.", exception)
178
+ promise.reject(exception)
179
+ }
180
+ }
181
+ } else {
182
+ promise.reject("NOT_LOGGED_IN", "Google Drive not initialized. Call loginIfNeeded first.")
183
+ }
184
+ }
185
+
186
+ override fun listFiles(options: ReadableMap, promise: Promise) {
187
+ val helper = mDriveServiceHelper
188
+ if (helper != null) {
189
+ Log.d(TAG, "Querying for files.")
190
+ val useDocumentsFolder = if (options.hasKey("scope")) {
191
+ options.getString("scope")?.lowercase() == "visible"
192
+ } else {
193
+ true
194
+ }
195
+ try {
196
+ helper.queryFiles(useDocumentsFolder)
197
+ .addOnSuccessListener { fileList ->
198
+ val files = WritableNativeArray()
199
+ for (file in fileList.files) {
200
+ val fileInfo = WritableNativeMap()
201
+ fileInfo.putString("name", file.name)
202
+ fileInfo.putString("id", file.id)
203
+ fileInfo.putString("lastModified", file.modifiedTime.toString())
204
+ files.pushMap(fileInfo)
205
+ }
206
+ val result = WritableNativeMap()
207
+ result.putArray("files", files)
208
+ promise.resolve(result)
209
+ clearPendingOperations()
210
+ }
211
+ .addOnFailureListener { exception ->
212
+ clearPendingOperations()
213
+ try {
214
+ Log.e(TAG, "Unable to query files: ${exception.cause?.message}")
215
+ val e = exception as UserRecoverableAuthIOException
216
+ mPendingPromise = promise
217
+ mPendingOptions = options
218
+ mPendingOperation = LIST_FILES
219
+ reactContext.startActivityForResult(e.intent, REQUEST_AUTHORIZATION, null)
220
+ } catch (e: Exception) {
221
+ promise.reject(e)
222
+ }
223
+ }
224
+ } catch (exception: Exception) {
225
+ try {
226
+ val e = exception as java.util.concurrent.ExecutionException
227
+ mPendingPromise = promise
228
+ mPendingOptions = options
229
+ mPendingOperation = LIST_FILES
230
+ val intent = (e.cause as UserRecoverableAuthIOException).intent
231
+ reactContext.startActivityForResult(intent, REQUEST_AUTHORIZATION, null)
232
+ } catch (e: Exception) {
233
+ promise.reject(exception)
234
+ Log.e(TAG, "Unable to query files: ${exception.cause?.message}")
235
+ }
236
+ }
237
+ } else {
238
+ promise.reject("NOT_LOGGED_IN", "Google Drive not initialized. Call loginIfNeeded first.")
239
+ }
41
240
  }
42
241
 
43
242
  override fun copyToCloud(options: ReadableMap, promise: Promise) {
44
- promise.reject("NOT_AVAILABLE", NOT_AVAILABLE_ERROR)
243
+ val helper = mDriveServiceHelper
244
+ if (helper != null) {
245
+ if (!options.hasKey("sourcePath")) {
246
+ promise.reject("error", "sourcePath not specified")
247
+ return
248
+ }
249
+ val source = options.getMap("sourcePath")
250
+ var uriOrPath = source?.getString("uri")
251
+ if (uriOrPath == null) {
252
+ uriOrPath = source?.getString("path")
253
+ }
254
+ if (uriOrPath == null) {
255
+ promise.reject("no path", "no source uri or path was specified")
256
+ return
257
+ }
258
+ if (!options.hasKey("targetPath")) {
259
+ promise.reject("error", "targetPath not specified")
260
+ return
261
+ }
262
+ val destinationPath = options.getString("targetPath") ?: ""
263
+ val mimeType = if (options.hasKey("mimetype")) options.getString("mimetype") else null
264
+ val useDocumentsFolder = if (options.hasKey("scope")) {
265
+ options.getString("scope")?.lowercase() == "visible"
266
+ } else {
267
+ true
268
+ }
269
+ val actualMimeType = if (mimeType == null) guessMimeType(uriOrPath) else null
270
+
271
+ try {
272
+ helper.saveFile(uriOrPath, destinationPath, actualMimeType, useDocumentsFolder)
273
+ .addOnSuccessListener { fileId ->
274
+ Log.d(TAG, "Saving $fileId")
275
+ promise.resolve(fileId)
276
+ clearPendingOperations()
277
+ }
278
+ .addOnFailureListener { exception ->
279
+ clearPendingOperations()
280
+ try {
281
+ val e = exception as UserRecoverableAuthIOException
282
+ reactContext.startActivityForResult(e.intent, REQUEST_AUTHORIZATION, null)
283
+ } catch (e: Exception) {
284
+ Log.e(TAG, "Couldn't create file.", exception)
285
+ }
286
+ promise.reject(exception)
287
+ }
288
+ } catch (exception: Exception) {
289
+ try {
290
+ val e = exception as java.util.concurrent.ExecutionException
291
+ mPendingPromise = promise
292
+ mPendingOptions = options
293
+ mPendingOperation = COPY_TO_CLOUD
294
+ val intent = (e.cause as UserRecoverableAuthIOException).intent
295
+ reactContext.startActivityForResult(intent, REQUEST_AUTHORIZATION, null)
296
+ } catch (e: Exception) {
297
+ promise.reject(exception)
298
+ Log.e(TAG, "Couldn't create file.", exception)
299
+ }
300
+ }
301
+ } else {
302
+ promise.reject("NOT_LOGGED_IN", "Google Drive not initialized. Call loginIfNeeded first.")
303
+ }
45
304
  }
46
305
 
47
- override fun syncCloud(promise: Promise) {
48
- promise.reject("NOT_AVAILABLE", NOT_AVAILABLE_ERROR)
306
+ override fun getGoogleDriveDocument(fileId: String, promise: Promise) {
307
+ val helper = mDriveServiceHelper
308
+ if (helper != null) {
309
+ Log.d(TAG, "Reading file $fileId")
310
+ helper.readFile(fileId)
311
+ .addOnSuccessListener { content -> promise.resolve(content) }
312
+ .addOnFailureListener { exception ->
313
+ try {
314
+ val e = exception as UserRecoverableAuthIOException
315
+ reactContext.startActivityForResult(e.intent, REQUEST_AUTHORIZATION, null)
316
+ } catch (e: Exception) {
317
+ Log.e(TAG, "Couldn't read file.", exception)
318
+ promise.reject(exception)
319
+ }
320
+ }
321
+ } else {
322
+ promise.reject("NOT_LOGGED_IN", "Google Drive not initialized. Call loginIfNeeded first.")
323
+ }
324
+ }
325
+
326
+ // endregion
327
+
328
+ // region Activity result handling
329
+
330
+ private fun clearPendingOperations() {
331
+ mPendingOperation = null
332
+ mPendingPromise = null
333
+ mPendingOptions = null
334
+ }
335
+
336
+ override fun onActivityResult(activity: Activity?, requestCode: Int, resultCode: Int, data: Intent?) {
337
+ when (requestCode) {
338
+ REQUEST_CODE_SIGN_IN -> {
339
+ val task = GoogleSignIn.getSignedInAccountFromIntent(data)
340
+ handleSignInResult(task)
341
+ }
342
+ REQUEST_AUTHORIZATION -> {
343
+ if (resultCode == Activity.RESULT_OK && data != null) {
344
+ val copiedPendingOperation = mPendingOperation
345
+ if (copiedPendingOperation != null) {
346
+ reactContext.runOnNativeModulesQueueThread {
347
+ mPendingOperation = null
348
+ when (copiedPendingOperation) {
349
+ COPY_TO_CLOUD -> {
350
+ try {
351
+ mPendingOptions?.let { copyToCloud(it, mPendingPromise!!) }
352
+ } catch (e: Exception) {
353
+ mPendingPromise?.reject(e)
354
+ clearPendingOperations()
355
+ }
356
+ }
357
+ LIST_FILES -> {
358
+ try {
359
+ mPendingOptions?.let { listFiles(it, mPendingPromise!!) }
360
+ } catch (e: Exception) {
361
+ mPendingPromise?.reject(e)
362
+ clearPendingOperations()
363
+ }
364
+ }
365
+ }
366
+ }
367
+ }
368
+ } else if (resultCode == Activity.RESULT_CANCELED && mPendingPromise != null) {
369
+ mPendingPromise?.reject("canceled", "User canceled")
370
+ } else if (mPendingPromise != null) {
371
+ mPendingPromise?.reject(
372
+ "unknown error",
373
+ "Operation failed: $mPendingOperation result code $resultCode"
374
+ )
375
+ }
376
+ }
377
+ }
378
+ }
379
+
380
+ private fun handleSignInResult(completedTask: com.google.android.gms.tasks.Task<com.google.android.gms.auth.api.signin.GoogleSignInAccount>) {
381
+ try {
382
+ val googleAccount = completedTask.getResult(ApiException::class.java)
383
+ Log.d(TAG, "Signed in as ${googleAccount.email}")
384
+
385
+ val credential = GoogleAccountCredential.usingOAuth2(
386
+ reactContext, Collections.singleton(DriveScopes.DRIVE_APPDATA)
387
+ )
388
+ credential.selectedAccount = googleAccount.account
389
+ val googleDriveService = Drive.Builder(
390
+ AndroidHttp.newCompatibleTransport(),
391
+ GsonFactory(),
392
+ credential
393
+ ).build()
394
+
395
+ mDriveServiceHelper = DriveServiceHelper(googleDriveService)
396
+
397
+ signInPromise?.resolve(true)
398
+ signInPromise = null
399
+ } catch (e: ApiException) {
400
+ Log.w(TAG, "signInResult:failed code=${e.statusCode}")
401
+ signInPromise?.reject("signInResult:${e.statusCode}", e.message)
402
+ signInPromise = null
403
+ }
404
+ }
405
+
406
+ // endregion
407
+
408
+ // region Lifecycle
409
+
410
+ override fun onHostResume() {}
411
+ override fun onHostPause() {}
412
+ override fun onHostDestroy() {}
413
+ override fun onNewIntent(intent: Intent?) {}
414
+
415
+ // endregion
416
+
417
+ private fun guessMimeType(url: String): String? {
418
+ val extension = MimeTypeMap.getFileExtensionFromUrl(url)
419
+ return if (extension != null) {
420
+ MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
421
+ } else {
422
+ null
423
+ }
49
424
  }
50
425
  }
package/ios/CloudFs.mm CHANGED
@@ -302,10 +302,37 @@
302
302
  for (NSMetadataItem *item in query.results) {
303
303
  [self downloadFileIfNotAvailable:item];
304
304
  }
305
- return resolve(nil);
305
+ return resolve(@YES);
306
306
  }];
307
307
  }
308
308
 
309
+ // MARK: - Android-only stubs
310
+
311
+ - (void)loginIfNeeded:(RCTPromiseResolveBlock)resolve
312
+ reject:(RCTPromiseRejectBlock)reject
313
+ {
314
+ resolve(@NO);
315
+ }
316
+
317
+ - (void)logout:(RCTPromiseResolveBlock)resolve
318
+ reject:(RCTPromiseRejectBlock)reject
319
+ {
320
+ resolve(@NO);
321
+ }
322
+
323
+ - (void)getGoogleDriveDocument:(NSString *)fileId
324
+ resolve:(RCTPromiseResolveBlock)resolve
325
+ reject:(RCTPromiseRejectBlock)reject
326
+ {
327
+ reject(@"NOT_AVAILABLE", @"Google Drive is not available on iOS", nil);
328
+ }
329
+
330
+ - (void)getCurrentlySignedInUserData:(RCTPromiseResolveBlock)resolve
331
+ reject:(RCTPromiseRejectBlock)reject
332
+ {
333
+ resolve([NSNull null]);
334
+ }
335
+
309
336
  // MARK: - Private helpers
310
337
 
311
338
  - (void)moveToICloudDirectory:(bool)documentsFolder
@@ -2,4 +2,5 @@
2
2
 
3
3
  import NativeCloudFs from "./NativeCloudFs.js";
4
4
  export const CloudFs = NativeCloudFs;
5
+ export default NativeCloudFs;
5
6
  //# sourceMappingURL=index.js.map
@@ -1,13 +1,50 @@
1
1
  import type { TurboModule } from 'react-native';
2
2
  export interface Spec extends TurboModule {
3
3
  isAvailable(): Promise<boolean>;
4
- createFile(options: Object): Promise<Object>;
5
- fileExists(options: Object): Promise<boolean>;
6
- listFiles(options: Object): Promise<Object>;
4
+ syncCloud(): Promise<boolean>;
5
+ listFiles(options: {
6
+ scope: string;
7
+ targetPath?: string;
8
+ }): Promise<{
9
+ files: Array<{
10
+ id: string;
11
+ name: string;
12
+ lastModified: string;
13
+ isFile?: boolean;
14
+ }>;
15
+ }>;
16
+ deleteFromCloud(item: {
17
+ id: string;
18
+ path?: string;
19
+ }): Promise<boolean>;
20
+ fileExists(options: {
21
+ fileId?: string;
22
+ targetPath?: string;
23
+ scope?: string;
24
+ }): Promise<boolean>;
25
+ copyToCloud(options: {
26
+ mimetype?: string | null;
27
+ scope: string;
28
+ sourcePath: {
29
+ path?: string;
30
+ uri?: string;
31
+ };
32
+ targetPath: string;
33
+ }): Promise<string>;
34
+ createFile(options: {
35
+ targetPath: string;
36
+ content: string;
37
+ scope?: string;
38
+ }): Promise<string>;
7
39
  getIcloudDocument(filename: string): Promise<string>;
8
- deleteFromCloud(item: Object): Promise<Object>;
9
- copyToCloud(options: Object): Promise<Object>;
10
- syncCloud(): Promise<void>;
40
+ loginIfNeeded(): Promise<boolean>;
41
+ logout(): Promise<boolean>;
42
+ getGoogleDriveDocument(fileId: string): Promise<string>;
43
+ getCurrentlySignedInUserData(): Promise<{
44
+ email: string;
45
+ name: string;
46
+ avatarUrl: string | null;
47
+ } | null>;
11
48
  }
12
49
  declare const _default: Spec;
13
50
  export default _default;
@@ -1,3 +1,5 @@
1
+ import NativeCloudFs from './NativeCloudFs';
1
2
  export declare const CloudFs: import("./NativeCloudFs").Spec;
3
+ export default NativeCloudFs;
2
4
  export type { Spec as CloudFsSpec } from './NativeCloudFs';
3
5
  //# sourceMappingURL=index.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/react-native-cloud-fs",
3
- "version": "3.0.14",
3
+ "version": "3.0.16",
4
4
  "description": "react-native-cloud-fs TurboModule for OneKey",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -2,14 +2,50 @@ import { TurboModuleRegistry } from 'react-native';
2
2
  import type { TurboModule } from 'react-native';
3
3
 
4
4
  export interface Spec extends TurboModule {
5
+ // Shared
5
6
  isAvailable(): Promise<boolean>;
6
- createFile(options: Object): Promise<Object>;
7
- fileExists(options: Object): Promise<boolean>;
8
- listFiles(options: Object): Promise<Object>;
7
+ syncCloud(): Promise<boolean>;
8
+ listFiles(options: {
9
+ scope: string;
10
+ targetPath?: string;
11
+ }): Promise<{
12
+ files: Array<{
13
+ id: string;
14
+ name: string;
15
+ lastModified: string;
16
+ isFile?: boolean;
17
+ }>;
18
+ }>;
19
+ deleteFromCloud(item: { id: string; path?: string }): Promise<boolean>;
20
+ fileExists(options: {
21
+ fileId?: string;
22
+ targetPath?: string;
23
+ scope?: string;
24
+ }): Promise<boolean>;
25
+ copyToCloud(options: {
26
+ mimetype?: string | null;
27
+ scope: string;
28
+ sourcePath: { path?: string; uri?: string };
29
+ targetPath: string;
30
+ }): Promise<string>;
31
+ createFile(options: {
32
+ targetPath: string;
33
+ content: string;
34
+ scope?: string;
35
+ }): Promise<string>;
36
+
37
+ // iOS only
9
38
  getIcloudDocument(filename: string): Promise<string>;
10
- deleteFromCloud(item: Object): Promise<Object>;
11
- copyToCloud(options: Object): Promise<Object>;
12
- syncCloud(): Promise<void>;
39
+
40
+ // Android only
41
+ loginIfNeeded(): Promise<boolean>;
42
+ logout(): Promise<boolean>;
43
+ getGoogleDriveDocument(fileId: string): Promise<string>;
44
+ getCurrentlySignedInUserData(): Promise<{
45
+ email: string;
46
+ name: string;
47
+ avatarUrl: string | null;
48
+ } | null>;
13
49
  }
14
50
 
15
51
  export default TurboModuleRegistry.getEnforcing<Spec>('RNCloudFs');
package/src/index.tsx CHANGED
@@ -1,4 +1,5 @@
1
1
  import NativeCloudFs from './NativeCloudFs';
2
2
 
3
3
  export const CloudFs = NativeCloudFs;
4
+ export default NativeCloudFs;
4
5
  export type { Spec as CloudFsSpec } from './NativeCloudFs';