|
@@ -33,6 +33,7 @@ public class RNFetchBlobFileResp extends ResponseBody {
|
33
|
33
|
long bytesDownloaded = 0;
|
34
|
34
|
ReactApplicationContext rctContext;
|
35
|
35
|
FileOutputStream ofStream;
|
|
36
|
+ boolean isEndMarkerReceived;
|
36
|
37
|
|
37
|
38
|
public RNFetchBlobFileResp(ReactApplicationContext ctx, String taskId, ResponseBody body, String path, boolean overwrite) throws IOException {
|
38
|
39
|
super();
|
|
@@ -41,6 +42,7 @@ public class RNFetchBlobFileResp extends ResponseBody {
|
41
|
42
|
this.originalBody = body;
|
42
|
43
|
assert path != null;
|
43
|
44
|
this.mPath = path;
|
|
45
|
+ this.isEndMarkerReceived = false;
|
44
|
46
|
if (path != null) {
|
45
|
47
|
boolean appendToExistingFile = !overwrite;
|
46
|
48
|
path = path.replace("?append=true", "");
|
|
@@ -68,6 +70,11 @@ public class RNFetchBlobFileResp extends ResponseBody {
|
68
|
70
|
return originalBody.contentLength();
|
69
|
71
|
}
|
70
|
72
|
|
|
73
|
+ public boolean isDownloadComplete() {
|
|
74
|
+ return (bytesDownloaded == contentLength()) // Case of non-chunked downloads
|
|
75
|
+ || (contentLength() == -1 && isEndMarkerReceived); // Case of chunked downloads
|
|
76
|
+ }
|
|
77
|
+
|
71
|
78
|
@Override
|
72
|
79
|
public BufferedSource source() {
|
73
|
80
|
ProgressReportingSource countable = new ProgressReportingSource();
|
|
@@ -83,22 +90,49 @@ public class RNFetchBlobFileResp extends ResponseBody {
|
83
|
90
|
bytesDownloaded += read > 0 ? read : 0;
|
84
|
91
|
if (read > 0) {
|
85
|
92
|
ofStream.write(bytes, 0, (int) read);
|
|
93
|
+ } else if (contentLength() == -1 && read == -1) {
|
|
94
|
+ // End marker has been received for chunked download
|
|
95
|
+ isEndMarkerReceived = true;
|
86
|
96
|
}
|
87
|
97
|
RNFetchBlobProgressConfig reportConfig = RNFetchBlobReq.getReportProgress(mTaskId);
|
88
|
|
- if (reportConfig != null && contentLength() != 0 &&reportConfig.shouldReport(bytesDownloaded / contentLength())) {
|
89
|
|
- WritableMap args = Arguments.createMap();
|
90
|
|
- args.putString("taskId", mTaskId);
|
91
|
|
- args.putString("written", String.valueOf(bytesDownloaded));
|
92
|
|
- args.putString("total", String.valueOf(contentLength()));
|
93
|
|
- rctContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
94
|
|
- .emit(RNFetchBlobConst.EVENT_PROGRESS, args);
|
|
98
|
+
|
|
99
|
+ if (contentLength() != 0) {
|
|
100
|
+
|
|
101
|
+ // For non-chunked download, progress is received / total
|
|
102
|
+ // For chunked download, progress can be either 0 (started) or 1 (ended)
|
|
103
|
+ float progress = (contentLength() != -1) ? bytesDownloaded / contentLength() : ( ( isEndMarkerReceived ) ? 1 : 0 );
|
|
104
|
+
|
|
105
|
+ if (reportConfig != null && reportConfig.shouldReport(progress /* progress */)) {
|
|
106
|
+ if (contentLength() != -1) {
|
|
107
|
+ // For non-chunked downloads
|
|
108
|
+ reportProgress(mTaskId, bytesDownloaded, contentLength());
|
|
109
|
+ } else {
|
|
110
|
+ // For chunked downloads
|
|
111
|
+ if (!isEndMarkerReceived) {
|
|
112
|
+ reportProgress(mTaskId, 0, contentLength());
|
|
113
|
+ } else{
|
|
114
|
+ reportProgress(mTaskId, bytesDownloaded, bytesDownloaded);
|
|
115
|
+ }
|
|
116
|
+ }
|
|
117
|
+ }
|
|
118
|
+
|
95
|
119
|
}
|
|
120
|
+
|
96
|
121
|
return read;
|
97
|
122
|
} catch(Exception ex) {
|
98
|
123
|
return -1;
|
99
|
124
|
}
|
100
|
125
|
}
|
101
|
126
|
|
|
127
|
+ private void reportProgress(String taskId, long bytesDownloaded, long contentLength) {
|
|
128
|
+ WritableMap args = Arguments.createMap();
|
|
129
|
+ args.putString("taskId", taskId);
|
|
130
|
+ args.putString("written", String.valueOf(bytesDownloaded));
|
|
131
|
+ args.putString("total", String.valueOf(contentLength));
|
|
132
|
+ rctContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
|
133
|
+ .emit(RNFetchBlobConst.EVENT_PROGRESS, args);
|
|
134
|
+ }
|
|
135
|
+
|
102
|
136
|
@Override
|
103
|
137
|
public Timeout timeout() {
|
104
|
138
|
return null;
|