react-native-blob-util 0.17.2 → 0.18.1
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.
- package/README.md +12 -5
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConst.java +1 -0
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFS.java +2 -3
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java +29 -12
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilStream.java +8 -3
- package/android/src/newarch/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +11 -0
- package/android/src/oldarch/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +11 -0
- package/class/ReactNativeBlobUtilReadStream.js +66 -62
- package/class/ReactNativeBlobUtilSession.js +6 -11
- package/class/ReactNativeBlobUtilWriteStream.js +4 -9
- package/codegenSpecs/NativeBlobUtils.js +6 -9
- package/fetch.js +30 -23
- package/index.d.ts +4 -0
- package/index.js +2 -14
- package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.h +5 -4
- package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.mm +44 -26
- package/ios/ReactNativeBlobUtil.xcodeproj/project.pbxproj +117 -36
- package/ios/ReactNativeBlobUtilConst.h +1 -0
- package/ios/ReactNativeBlobUtilConst.mm +1 -0
- package/ios/ReactNativeBlobUtilFS.h +1 -4
- package/ios/ReactNativeBlobUtilFS.mm +24 -30
- package/ios/ReactNativeBlobUtilNetwork.h +1 -2
- package/ios/ReactNativeBlobUtilNetwork.mm +2 -24
- package/ios/ReactNativeBlobUtilRequest.h +3 -4
- package/ios/ReactNativeBlobUtilRequest.mm +8 -17
- package/package.json +4 -4
- package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.vcxproj +2 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ react-native-blob-util version **0.10.16** and up is only compatible with react
|
|
|
27
27
|
- JSON stream supported base on [Oboe.js](https://github.com/jimhigson/oboe.js/) @jimhigson
|
|
28
28
|
|
|
29
29
|
## React Native New Architecture
|
|
30
|
-
With
|
|
30
|
+
With React Native 0.68.0 the switch to enable the new aritechture was introduced.
|
|
31
31
|
Starting with version 0.17.0 this library introduces support for the new architecture as well. Of course the old architecture will still be supproted.
|
|
32
32
|
Further information about it and how to use it you can find here: https://reactnative.dev/docs/next/the-new-architecture/landing-page
|
|
33
33
|
|
|
@@ -92,14 +92,21 @@ After `0.10.3` you can install this package directly from Github
|
|
|
92
92
|
npm install --save github:RonRadtke/react-native-blob-util#<branch_name>
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
+
**iOS**
|
|
96
|
+
|
|
97
|
+
When using the package from npm, run `pod install` from the `ios` directory:
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
cd ios; pod install; cd ..
|
|
101
|
+
```
|
|
102
|
+
|
|
95
103
|
**Okhttp**
|
|
96
104
|
|
|
97
105
|
For using the library okhttp3 is required. It's in general included in react-native. The library uses the okhttp version shipped with react-native or used by your app. For very old devices android devices okhttp 3.12 can be used.
|
|
98
106
|
|
|
99
107
|
**Manually Link Native Modules**
|
|
100
108
|
|
|
101
|
-
If you're using RN 0.60 or higher,
|
|
102
|
-
|
|
109
|
+
If you're using RN 0.60 or higher, manual linking should not be required anymore.
|
|
103
110
|
|
|
104
111
|
If automatically linking doesn't work for you, see instructions on [manually linking](https://github.com/RonRadtke/react-native-blob-util/wiki/Manually-Link-Package#index).
|
|
105
112
|
|
|
@@ -658,14 +665,14 @@ Android 10 introduced scoped storage and thus new APIs to store files to Documen
|
|
|
658
665
|
|
|
659
666
|
#### CopyToMediaStore
|
|
660
667
|
|
|
661
|
-
Copies an existing file from the internal Storage to the Media Store. <br> An
|
|
668
|
+
Copies an existing file from the internal Storage to the Media Store. <br> An example for downloading a file and storing it to the `downloads` collection
|
|
662
669
|
|
|
663
670
|
```js
|
|
664
671
|
ReactNativeBlobUtil
|
|
665
672
|
.config({
|
|
666
673
|
fileCache: true
|
|
667
674
|
})
|
|
668
|
-
.fetch('GET', 'https://example.de/image.png'
|
|
675
|
+
.fetch('GET', 'https://example.de/image.png')
|
|
669
676
|
.then(async (res) => {
|
|
670
677
|
let result = await ReactNativeBlobUtil.MediaCollection.copyToMediaStore({
|
|
671
678
|
name: filename, // name of the file
|
|
@@ -6,6 +6,7 @@ public class ReactNativeBlobUtilConst {
|
|
|
6
6
|
public static final String EVENT_PROGRESS = "ReactNativeBlobUtilProgress";
|
|
7
7
|
public static final String EVENT_HTTP_STATE = "ReactNativeBlobUtilState";
|
|
8
8
|
public static final String EVENT_MESSAGE = "ReactNativeBlobUtilMessage";
|
|
9
|
+
public static final String EVENT_FILESYSTEM = "ReactNativeBlobUtilFilesystem";
|
|
9
10
|
public static final String FILE_PREFIX = "ReactNativeBlobUtil-file://";
|
|
10
11
|
public static final String CONTENT_PREFIX = "ReactNativeBlobUtil-content://";
|
|
11
12
|
public static final String FILE_PREFIX_BUNDLE_ASSET = "bundle-assets://";
|
|
@@ -19,6 +19,8 @@ import com.facebook.react.bridge.ReadableArray;
|
|
|
19
19
|
import com.facebook.react.bridge.WritableArray;
|
|
20
20
|
import com.facebook.react.bridge.WritableMap;
|
|
21
21
|
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
|
22
|
+
import com.facebook.react.uimanager.UIManagerHelper;
|
|
23
|
+
import com.facebook.react.uimanager.events.EventDispatcher;
|
|
22
24
|
|
|
23
25
|
import java.io.File;
|
|
24
26
|
import java.io.FileInputStream;
|
|
@@ -37,9 +39,6 @@ class ReactNativeBlobUtilFS {
|
|
|
37
39
|
|
|
38
40
|
private ReactApplicationContext mCtx;
|
|
39
41
|
private DeviceEventManagerModule.RCTDeviceEventEmitter emitter;
|
|
40
|
-
private String encoding = "base64";
|
|
41
|
-
private OutputStream writeStreamInstance = null;
|
|
42
|
-
private static HashMap<String, ReactNativeBlobUtilFS> fileStreams = new HashMap<>();
|
|
43
42
|
|
|
44
43
|
ReactNativeBlobUtilFS(ReactApplicationContext ctx) {
|
|
45
44
|
this.mCtx = ctx;
|
|
@@ -13,6 +13,7 @@ import android.net.NetworkInfo;
|
|
|
13
13
|
import android.net.Uri;
|
|
14
14
|
import android.os.Build;
|
|
15
15
|
import android.os.Bundle;
|
|
16
|
+
import android.os.Environment;
|
|
16
17
|
import android.os.Handler;
|
|
17
18
|
import android.os.Message;
|
|
18
19
|
import android.util.Base64;
|
|
@@ -49,6 +50,8 @@ import java.nio.charset.CharsetDecoder;
|
|
|
49
50
|
import java.util.ArrayList;
|
|
50
51
|
import java.util.HashMap;
|
|
51
52
|
|
|
53
|
+
import java.util.UUID;
|
|
54
|
+
|
|
52
55
|
import java.util.List;
|
|
53
56
|
import java.util.Locale;
|
|
54
57
|
import java.util.concurrent.Executors;
|
|
@@ -252,19 +255,29 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
252
255
|
if (options.addAndroidDownloads.hasKey("path")) {
|
|
253
256
|
req.setDestinationUri(Uri.parse("file://" + options.addAndroidDownloads.getString("path")));
|
|
254
257
|
}
|
|
255
|
-
// #391 Add MIME type to the request
|
|
256
258
|
if (options.addAndroidDownloads.hasKey("mime")) {
|
|
257
259
|
req.setMimeType(options.addAndroidDownloads.getString("mime"));
|
|
258
260
|
}
|
|
259
261
|
if (options.addAndroidDownloads.hasKey("mediaScannable") && options.addAndroidDownloads.getBoolean("mediaScannable")) {
|
|
260
262
|
req.allowScanningByMediaScanner();
|
|
261
263
|
}
|
|
264
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && options.addAndroidDownloads.hasKey("storeInDownloads") && options.addAndroidDownloads.getBoolean("storeInDownloads")) {
|
|
265
|
+
String t = options.addAndroidDownloads.getString("title");
|
|
266
|
+
if(t == null || t.isEmpty())
|
|
267
|
+
t = UUID.randomUUID().toString();
|
|
268
|
+
if(this.options.appendExt != null && !this.options.appendExt.isEmpty())
|
|
269
|
+
t += "." + this.options.appendExt;
|
|
270
|
+
|
|
271
|
+
req.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, t);
|
|
272
|
+
}
|
|
273
|
+
|
|
262
274
|
// set headers
|
|
263
275
|
ReadableMapKeySetIterator it = headers.keySetIterator();
|
|
264
276
|
while (it.hasNextKey()) {
|
|
265
277
|
String key = it.nextKey();
|
|
266
278
|
req.addRequestHeader(key, headers.getString(key));
|
|
267
279
|
}
|
|
280
|
+
|
|
268
281
|
// Attempt to add cookie, if it exists
|
|
269
282
|
URL urlObj;
|
|
270
283
|
try {
|
|
@@ -862,9 +875,8 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
862
875
|
DownloadManager dm = (DownloadManager) appCtx.getSystemService(Context.DOWNLOAD_SERVICE);
|
|
863
876
|
dm.query(query);
|
|
864
877
|
Cursor c = dm.query(query);
|
|
865
|
-
// #236 unhandled null check for DownloadManager.query() return value
|
|
866
878
|
if (c == null) {
|
|
867
|
-
this.
|
|
879
|
+
this.invoke_callback("Download manager failed to download from " + this.url + ". Query was unsuccessful ", null, null);
|
|
868
880
|
return;
|
|
869
881
|
}
|
|
870
882
|
|
|
@@ -872,10 +884,9 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
872
884
|
try {
|
|
873
885
|
// the file exists in media content database
|
|
874
886
|
if (c.moveToFirst()) {
|
|
875
|
-
// #297 handle failed request
|
|
876
887
|
int statusCode = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
|
|
877
888
|
if (statusCode == DownloadManager.STATUS_FAILED) {
|
|
878
|
-
this.
|
|
889
|
+
this.invoke_callback("Download manager failed to download from " + this.url + ". Status Code = " + statusCode, null, null);
|
|
879
890
|
return;
|
|
880
891
|
}
|
|
881
892
|
String contentUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
|
|
@@ -904,17 +915,25 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
904
915
|
if (!exists)
|
|
905
916
|
throw new Exception("Download manager download failed, the file does not downloaded to destination.");
|
|
906
917
|
else
|
|
907
|
-
this.
|
|
918
|
+
this.invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_PATH, customDest);
|
|
908
919
|
|
|
909
920
|
} catch (Exception ex) {
|
|
910
921
|
ex.printStackTrace();
|
|
911
|
-
this.
|
|
922
|
+
this.invoke_callback(ex.getLocalizedMessage(), null);
|
|
912
923
|
}
|
|
913
|
-
}
|
|
924
|
+
}
|
|
925
|
+
else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && options.addAndroidDownloads.hasKey("storeInDownloads") && options.addAndroidDownloads.getBoolean("storeInDownloads")){
|
|
926
|
+
Uri downloadeduri = dm.getUriForDownloadedFile(downloadManagerId);
|
|
927
|
+
if(downloadeduri == null)
|
|
928
|
+
this.callback.invoke("Download manager could not resolve downloaded file uri.", ReactNativeBlobUtilConst.RNFB_RESPONSE_PATH, null);
|
|
929
|
+
else
|
|
930
|
+
this.callback.invoke(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_PATH, downloadeduri.toString());
|
|
931
|
+
}
|
|
932
|
+
else {
|
|
914
933
|
if (filePath == null)
|
|
915
|
-
this.
|
|
934
|
+
this.invoke_callback("Download manager could not resolve downloaded file path.", ReactNativeBlobUtilConst.RNFB_RESPONSE_PATH, null);
|
|
916
935
|
else
|
|
917
|
-
this.
|
|
936
|
+
this.invoke_callback(null, ReactNativeBlobUtilConst.RNFB_RESPONSE_PATH, filePath);
|
|
918
937
|
}
|
|
919
938
|
|
|
920
939
|
}
|
|
@@ -946,6 +965,4 @@ public class ReactNativeBlobUtilReq extends BroadcastReceiver implements Runnabl
|
|
|
946
965
|
|
|
947
966
|
return client;
|
|
948
967
|
}
|
|
949
|
-
|
|
950
|
-
|
|
951
968
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
package com.ReactNativeBlobUtil;
|
|
2
2
|
|
|
3
|
+
import static com.ReactNativeBlobUtil.ReactNativeBlobUtilConst.EVENT_FILESYSTEM;
|
|
4
|
+
|
|
3
5
|
import android.net.Uri;
|
|
4
6
|
import android.os.SystemClock;
|
|
5
7
|
import android.util.Base64;
|
|
@@ -249,7 +251,8 @@ public class ReactNativeBlobUtilStream {
|
|
|
249
251
|
WritableMap eventData = Arguments.createMap();
|
|
250
252
|
eventData.putString("event", event);
|
|
251
253
|
eventData.putString("detail", data);
|
|
252
|
-
|
|
254
|
+
eventData.putString("streamId", streamName);
|
|
255
|
+
this.emitter.emit(EVENT_FILESYSTEM, eventData);
|
|
253
256
|
}
|
|
254
257
|
|
|
255
258
|
// "event" always is "data"...
|
|
@@ -257,7 +260,8 @@ public class ReactNativeBlobUtilStream {
|
|
|
257
260
|
WritableMap eventData = Arguments.createMap();
|
|
258
261
|
eventData.putString("event", event);
|
|
259
262
|
eventData.putArray("detail", data);
|
|
260
|
-
|
|
263
|
+
eventData.putString("streamId", streamName);
|
|
264
|
+
this.emitter.emit(EVENT_FILESYSTEM, eventData);
|
|
261
265
|
}
|
|
262
266
|
|
|
263
267
|
// "event" always is "error"...
|
|
@@ -266,7 +270,8 @@ public class ReactNativeBlobUtilStream {
|
|
|
266
270
|
eventData.putString("event", event);
|
|
267
271
|
eventData.putString("code", code);
|
|
268
272
|
eventData.putString("detail", message);
|
|
269
|
-
|
|
273
|
+
eventData.putString("streamId", streamName);
|
|
274
|
+
this.emitter.emit(EVENT_FILESYSTEM, eventData);
|
|
270
275
|
}
|
|
271
276
|
|
|
272
277
|
/**
|
|
@@ -26,6 +26,17 @@ public class ReactNativeBlobUtil extends NativeBlobUtilsSpec {
|
|
|
26
26
|
delegate = new ReactNativeBlobUtilImpl(reactContext);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
// Required for rn built in EventEmitter Calls.
|
|
30
|
+
@ReactMethod
|
|
31
|
+
public void addListener(String eventName) {
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@ReactMethod
|
|
36
|
+
public void removeListeners(Integer count) {
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
29
40
|
@Override
|
|
30
41
|
protected Map<String, Object> getTypedExportedConstants() {
|
|
31
42
|
Map<String, Object> res = new HashMap<>();
|
|
@@ -27,6 +27,17 @@ public class ReactNativeBlobUtil extends ReactContextBaseJavaModule {
|
|
|
27
27
|
delegate = new ReactNativeBlobUtilImpl(reactContext);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// Required for rn built in EventEmitter Calls.
|
|
31
|
+
@ReactMethod
|
|
32
|
+
public void addListener(String eventName) {
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@ReactMethod
|
|
37
|
+
public void removeListeners(Integer count) {
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
30
41
|
@NonNull
|
|
31
42
|
@Override
|
|
32
43
|
public String getName() {
|
|
@@ -2,80 +2,84 @@
|
|
|
2
2
|
// Use of this source code is governed by a MIT-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
DeviceEventEmitter,
|
|
7
|
-
NativeAppEventEmitter,
|
|
8
|
-
} from 'react-native';
|
|
5
|
+
import {NativeEventEmitter} from 'react-native';
|
|
9
6
|
import UUID from '../utils/uuid';
|
|
10
7
|
|
|
11
8
|
import ReactNativeBlobUtil from "../codegenSpecs/NativeBlobUtils";
|
|
12
|
-
|
|
9
|
+
|
|
10
|
+
const emitter = new NativeEventEmitter(ReactNativeBlobUtil);
|
|
13
11
|
|
|
14
12
|
export default class ReactNativeBlobUtilReadStream {
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
path: string;
|
|
15
|
+
encoding: 'utf8' | 'ascii' | 'base64';
|
|
16
|
+
bufferSize: ?number;
|
|
17
|
+
closed: boolean;
|
|
18
|
+
tick: number = 10;
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
20
|
+
constructor(path: string, encoding: string, bufferSize?: ?number, tick: number) {
|
|
21
|
+
if (!path)
|
|
22
|
+
throw Error('ReactNativeBlobUtil could not open file stream with empty `path`');
|
|
23
|
+
this.encoding = encoding || 'utf8';
|
|
24
|
+
this.bufferSize = bufferSize;
|
|
25
|
+
this.path = path;
|
|
26
|
+
this.closed = false;
|
|
27
|
+
this.tick = tick;
|
|
28
|
+
this._onData = () => {
|
|
29
|
+
};
|
|
30
|
+
this._onEnd = () => {
|
|
31
|
+
};
|
|
32
|
+
this._onError = () => {
|
|
33
|
+
};
|
|
34
|
+
this.streamId = 'RNFBRS' + UUID();
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
36
|
+
// register for file stream event
|
|
37
|
+
let subscription = emitter.addListener('ReactNativeBlobUtilFilesystem', (e) => {
|
|
38
|
+
if (typeof e === 'string') e = JSON.parse(e);
|
|
39
|
+
console.log(e, this.streamId, e.streamId, e.streamId === this.streamId)
|
|
40
|
+
if (e.streamId !== this.streamId) return; // wrong stream
|
|
41
|
+
let {event, code, detail} = e;
|
|
42
|
+
if (this._onData && event === 'data') {
|
|
43
|
+
this._onData(detail);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
else if (this._onEnd && event === 'end') {
|
|
47
|
+
this._onEnd(detail);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const err = new Error(detail);
|
|
51
|
+
err.code = code || 'EUNSPECIFIED';
|
|
52
|
+
if (this._onError)
|
|
53
|
+
this._onError(err);
|
|
54
|
+
else
|
|
55
|
+
throw err;
|
|
56
|
+
}
|
|
57
|
+
// when stream closed or error, remove event handler
|
|
58
|
+
if (event === 'error' || event === 'end') {
|
|
59
|
+
subscription.remove();
|
|
60
|
+
this.closed = true;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
59
63
|
|
|
60
|
-
|
|
64
|
+
}
|
|
61
65
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
open() {
|
|
67
|
+
if (!this.closed)
|
|
68
|
+
ReactNativeBlobUtil.readStream(this.path, this.encoding, this.bufferSize || 10240, this.tick || -1, this.streamId);
|
|
69
|
+
else
|
|
70
|
+
throw new Error('Stream closed');
|
|
71
|
+
}
|
|
68
72
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
73
|
+
onData(fn: () => void) {
|
|
74
|
+
this._onData = fn;
|
|
75
|
+
}
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
onError(fn) {
|
|
78
|
+
this._onError = fn;
|
|
79
|
+
}
|
|
76
80
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
onEnd(fn) {
|
|
82
|
+
this._onEnd = fn;
|
|
83
|
+
}
|
|
80
84
|
|
|
81
85
|
}
|
|
@@ -2,12 +2,7 @@
|
|
|
2
2
|
// Use of this source code is governed by a MIT-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
DeviceEventEmitter,
|
|
7
|
-
NativeAppEventEmitter,
|
|
8
|
-
} from 'react-native';
|
|
9
|
-
|
|
10
|
-
import ReactNativeBlobUtil from "../codegenSpecs/NativeBlobUtils";
|
|
5
|
+
import ReactNativeBlobUtil from '../codegenSpecs/NativeBlobUtils';
|
|
11
6
|
|
|
12
7
|
let sessions = {};
|
|
13
8
|
|
|
@@ -29,8 +24,8 @@ export default class ReactNativeBlobUtilSession {
|
|
|
29
24
|
|
|
30
25
|
constructor(name:string, list:Array<string>) {
|
|
31
26
|
this.name = name;
|
|
32
|
-
if(!sessions[name]) {
|
|
33
|
-
if(Array.isArray(list))
|
|
27
|
+
if (!sessions[name]) {
|
|
28
|
+
if (Array.isArray(list))
|
|
34
29
|
sessions[name] = list;
|
|
35
30
|
else
|
|
36
31
|
sessions[name] = [];
|
|
@@ -44,8 +39,8 @@ export default class ReactNativeBlobUtilSession {
|
|
|
44
39
|
|
|
45
40
|
remove(path:string):ReactNativeBlobUtilSession {
|
|
46
41
|
let list = sessions[this.name];
|
|
47
|
-
for(let i of list) {
|
|
48
|
-
if(list[i] === path) {
|
|
42
|
+
for (let i of list) {
|
|
43
|
+
if (list[i] === path) {
|
|
49
44
|
sessions[this.name].splice(i, 1);
|
|
50
45
|
break;
|
|
51
46
|
}
|
|
@@ -60,7 +55,7 @@ export default class ReactNativeBlobUtilSession {
|
|
|
60
55
|
dispose():Promise {
|
|
61
56
|
return new Promise((resolve, reject) => {
|
|
62
57
|
ReactNativeBlobUtil.removeSession(sessions[this.name], (err) => {
|
|
63
|
-
if(err)
|
|
58
|
+
if (err)
|
|
64
59
|
reject(new Error(err));
|
|
65
60
|
else {
|
|
66
61
|
delete sessions[this.name];
|
|
@@ -2,12 +2,7 @@
|
|
|
2
2
|
// Use of this source code is governed by a MIT-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
DeviceEventEmitter,
|
|
7
|
-
NativeAppEventEmitter,
|
|
8
|
-
} from 'react-native';
|
|
9
|
-
|
|
10
|
-
import ReactNativeBlobUtil from "../codegenSpecs/NativeBlobUtils";
|
|
5
|
+
import ReactNativeBlobUtil from '../codegenSpecs/NativeBlobUtils';
|
|
11
6
|
export default class ReactNativeBlobUtilWriteStream {
|
|
12
7
|
|
|
13
8
|
id : string;
|
|
@@ -24,17 +19,17 @@ export default class ReactNativeBlobUtilWriteStream {
|
|
|
24
19
|
return new Promise((resolve, reject) => {
|
|
25
20
|
try {
|
|
26
21
|
let method = this.encoding === 'ascii' ? 'writeArrayChunk' : 'writeChunk';
|
|
27
|
-
if(this.encoding.toLocaleLowerCase() === 'ascii' && !Array.isArray(data)) {
|
|
22
|
+
if (this.encoding.toLocaleLowerCase() === 'ascii' && !Array.isArray(data)) {
|
|
28
23
|
reject(new Error('ascii input data must be an Array'));
|
|
29
24
|
return;
|
|
30
25
|
}
|
|
31
26
|
ReactNativeBlobUtil[method](this.id, data, (error) => {
|
|
32
|
-
if(error)
|
|
27
|
+
if (error)
|
|
33
28
|
reject(new Error(error));
|
|
34
29
|
else
|
|
35
30
|
resolve(this);
|
|
36
31
|
});
|
|
37
|
-
} catch(err) {
|
|
32
|
+
} catch (err) {
|
|
38
33
|
reject(new Error(err));
|
|
39
34
|
}
|
|
40
35
|
});
|
|
@@ -66,9 +66,9 @@ export interface Spec extends TurboModule {
|
|
|
66
66
|
// Android Only APIs
|
|
67
67
|
+actionViewIntent: (path: string, mime: string, chooserTitle: string) => Promise<void>;
|
|
68
68
|
+addCompleteDownload: (config: Object) => Promise<void>;
|
|
69
|
-
+copyToInternal: (contentUri: string, destpath: string) => Promise<string>;
|
|
69
|
+
+copyToInternal: (contentUri: string, destpath: string) => Promise<string>;
|
|
70
70
|
+copyToMediaStore: (filedata: Object, mt: string, path: string) => Promise<string>;
|
|
71
|
-
+createMediaFile: (filedata: Object, mt: string) => Promise<string>;
|
|
71
|
+
+createMediaFile: (filedata: Object, mt: string) => Promise<string>;
|
|
72
72
|
+getBlob: (contentUri: string, encoding: string) => Promise<Array<any>>;
|
|
73
73
|
+getContentIntent: (mime: string) => Promise<string>;
|
|
74
74
|
+getSDCardDir: () => Promise<string>;
|
|
@@ -76,10 +76,7 @@ export interface Spec extends TurboModule {
|
|
|
76
76
|
+scanFile: (pairs: Array<any>, callback: (value: Array<any>) => void) => void;
|
|
77
77
|
+writeToMediaFile: (fileUri: string, path: string, transformFile: boolean) => Promise<string>;
|
|
78
78
|
}
|
|
79
|
-
|
|
80
|
-
export default (TurboModuleRegistry.get<Spec>(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
79
|
+
|
|
80
|
+
export default (TurboModuleRegistry.get<Spec>('ReactNativeBlobUtil'): ?Spec);
|
|
81
|
+
|
|
82
|
+
|
package/fetch.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import {ReactNativeBlobUtilConfig} from
|
|
2
|
-
import URIUtil from
|
|
3
|
-
import fs from
|
|
4
|
-
import getUUID from
|
|
5
|
-
import {
|
|
6
|
-
import {FetchBlobResponse} from
|
|
7
|
-
import CanceledFetchError from
|
|
8
|
-
import ReactNativeBlobUtil from
|
|
1
|
+
import {ReactNativeBlobUtilConfig} from 'types';
|
|
2
|
+
import URIUtil from './utils/uri';
|
|
3
|
+
import fs from './fs';
|
|
4
|
+
import getUUID from './utils/uuid';
|
|
5
|
+
import {NativeEventEmitter} from 'react-native';
|
|
6
|
+
import {FetchBlobResponse} from './class/ReactNativeBlobUtilBlobResponse';
|
|
7
|
+
import CanceledFetchError from './class/ReactNativeBlobUtilCanceledFetchError';
|
|
8
|
+
import ReactNativeBlobUtil from './codegenSpecs/NativeBlobUtils';
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
const eventEmitter = new NativeEventEmitter(ReactNativeBlobUtil);
|
|
11
11
|
|
|
12
12
|
// register message channel event handler.
|
|
13
|
-
|
|
13
|
+
eventEmitter.addListener('ReactNativeBlobUtilMessage', (e) => {
|
|
14
|
+
if (typeof e === 'string') e = JSON.parse(e);
|
|
14
15
|
|
|
16
|
+
console.log('add listener')
|
|
15
17
|
if (e.event === 'warn') {
|
|
16
18
|
console.warn(e.detail);
|
|
17
19
|
}
|
|
@@ -19,7 +21,7 @@ emitter.addListener("ReactNativeBlobUtilMessage", (e) => {
|
|
|
19
21
|
throw e.detail;
|
|
20
22
|
}
|
|
21
23
|
else {
|
|
22
|
-
console.log(
|
|
24
|
+
console.log('ReactNativeBlobUtil native message', e.detail);
|
|
23
25
|
}
|
|
24
26
|
});
|
|
25
27
|
|
|
@@ -105,7 +107,7 @@ function fetchFile(options = {}, method, url, headers = {}, body): Promise {
|
|
|
105
107
|
.then((stream) => new Promise((resolve, reject) => {
|
|
106
108
|
stream.open();
|
|
107
109
|
info = {
|
|
108
|
-
state:
|
|
110
|
+
state: '2',
|
|
109
111
|
headers: {'source': 'system-fs'},
|
|
110
112
|
status: 200,
|
|
111
113
|
respType: 'text',
|
|
@@ -188,31 +190,36 @@ export function fetch(...args: any): Promise {
|
|
|
188
190
|
let nativeMethodName = Array.isArray(body) ? 'fetchBlobForm' : 'fetchBlob';
|
|
189
191
|
|
|
190
192
|
// on progress event listener
|
|
191
|
-
subscription =
|
|
193
|
+
subscription = eventEmitter.addListener('ReactNativeBlobUtilProgress', (e) => {
|
|
194
|
+
if (typeof e === 'string') e = JSON.parse(e);
|
|
192
195
|
if (e.taskId === taskId && promise.onProgress) {
|
|
193
196
|
promise.onProgress(e.written, e.total, e.chunk);
|
|
194
197
|
}
|
|
195
198
|
});
|
|
196
199
|
|
|
197
|
-
subscriptionUpload =
|
|
200
|
+
subscriptionUpload = eventEmitter.addListener('ReactNativeBlobUtilProgress-upload', (e) => {
|
|
201
|
+
if (typeof e === 'string') e = JSON.parse(e);
|
|
198
202
|
if (e.taskId === taskId && promise.onUploadProgress) {
|
|
199
203
|
promise.onUploadProgress(e.written, e.total);
|
|
200
204
|
}
|
|
201
205
|
});
|
|
202
206
|
|
|
203
|
-
stateEvent =
|
|
207
|
+
stateEvent = eventEmitter.addListener('ReactNativeBlobUtilState', (e) => {
|
|
208
|
+
if (typeof e === 'string') e = JSON.parse(e);
|
|
204
209
|
if (e.taskId === taskId)
|
|
205
210
|
respInfo = e;
|
|
206
211
|
promise.onStateChange && promise.onStateChange(e);
|
|
207
212
|
});
|
|
208
213
|
|
|
209
|
-
subscription =
|
|
214
|
+
subscription = eventEmitter.addListener('ReactNativeBlobUtilExpire', (e) => {
|
|
215
|
+
if (typeof e === 'string') e = JSON.parse(e);
|
|
210
216
|
if (e.taskId === taskId && promise.onExpire) {
|
|
211
217
|
promise.onExpire(e);
|
|
212
218
|
}
|
|
213
219
|
});
|
|
214
220
|
|
|
215
|
-
partEvent =
|
|
221
|
+
partEvent = eventEmitter.addListener('ReactNativeBlobUtilServerPush', (e) => {
|
|
222
|
+
if (typeof e === 'string') e = JSON.parse(e);
|
|
216
223
|
if (e.taskId === taskId && promise.onPartData) {
|
|
217
224
|
promise.onPartData(e.chunk);
|
|
218
225
|
}
|
|
@@ -244,11 +251,11 @@ export function fetch(...args: any): Promise {
|
|
|
244
251
|
subscriptionUpload.remove();
|
|
245
252
|
stateEvent.remove();
|
|
246
253
|
partEvent.remove();
|
|
247
|
-
delete promise
|
|
248
|
-
delete promise
|
|
249
|
-
delete promise
|
|
250
|
-
delete promise
|
|
251
|
-
delete promise
|
|
254
|
+
delete promise.progress;
|
|
255
|
+
delete promise.uploadProgress;
|
|
256
|
+
delete promise.stateChange;
|
|
257
|
+
delete promise.part;
|
|
258
|
+
delete promise.cancel;
|
|
252
259
|
// delete promise['expire']
|
|
253
260
|
promise.cancel = () => {
|
|
254
261
|
};
|
|
@@ -329,7 +336,7 @@ export function fetch(...args: any): Promise {
|
|
|
329
336
|
subscriptionUpload.remove();
|
|
330
337
|
stateEvent.remove();
|
|
331
338
|
ReactNativeBlobUtil.cancelRequest(taskId, fn);
|
|
332
|
-
promiseReject(new CanceledFetchError(
|
|
339
|
+
promiseReject(new CanceledFetchError('canceled'));
|
|
333
340
|
};
|
|
334
341
|
promise.taskId = taskId;
|
|
335
342
|
|
package/index.d.ts
CHANGED
|
@@ -782,6 +782,10 @@ export interface AddAndroidDownloads {
|
|
|
782
782
|
* (https://developer.android.com/reference/android/app/DownloadManager.html#addCompletedDownload(java.lang.String, java.lang.String, boolean, java.lang.String, java.lang.String, long, boolean))
|
|
783
783
|
*/
|
|
784
784
|
mediaScannable?: boolean;
|
|
785
|
+
/**
|
|
786
|
+
* Only for Android >= Q; Enforces the file being stored to the MediaCollection Downloads. This might overwrite any value given in "path"
|
|
787
|
+
*/
|
|
788
|
+
storeInDownloads?: boolean;
|
|
785
789
|
/**
|
|
786
790
|
* A boolean value decide whether show a notification when download complete.
|
|
787
791
|
*/
|