@kesha-antonov/react-native-background-downloader 4.5.5 → 4.5.8
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 +5 -1
- package/android/src/main/java/com/eko/DownloadConstants.kt +7 -0
- package/android/src/main/java/com/eko/Downloader.kt +80 -111
- package/android/src/main/java/com/eko/RNBGDTaskConfig.kt +4 -1
- package/android/src/main/java/com/eko/RNBackgroundDownloaderModuleImpl.kt +97 -17
- package/android/src/main/java/com/eko/ResumableDownloadService.kt +153 -37
- package/android/src/main/java/com/eko/ResumableDownloader.kt +66 -12
- package/android/src/main/java/com/eko/UIDTDownloadJobService.kt +25 -4
- package/android/src/main/java/com/eko/UnmeteredNetworkGate.kt +366 -0
- package/android/src/main/java/com/eko/uidt/UIDTJobManager.kt +76 -14
- package/android/src/main/java/com/eko/uidt/UIDTJobState.kt +11 -0
- package/android/src/main/java/com/eko/utils/NetworkRequestUtils.kt +43 -0
- package/android/src/main/java/com/eko/utils/StorageManager.kt +32 -45
- package/ios/RNBackgroundDownloader.mm +4 -3
- package/package.json +4 -4
|
@@ -196,7 +196,34 @@ class StorageManager(context: Context, private val name: String) {
|
|
|
196
196
|
val headers: Map<String, String>,
|
|
197
197
|
val bytesDownloaded: Long,
|
|
198
198
|
val bytesTotal: Long,
|
|
199
|
-
val metadata: String = "{}"
|
|
199
|
+
val metadata: String = "{}",
|
|
200
|
+
// Nullable so records persisted by older versions (key absent in JSON)
|
|
201
|
+
// load as null and fall back to true instead of Gson's default false.
|
|
202
|
+
val isAllowedOverMetered: Boolean? = null
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
// Single mapping pair between the runtime record and the persisted DTO so a
|
|
206
|
+
// new field is added in one place instead of once per save/load method
|
|
207
|
+
private fun Downloader.PausedDownloadInfo.toData() = PausedDownloadInfoData(
|
|
208
|
+
configId = configId,
|
|
209
|
+
url = url,
|
|
210
|
+
destination = destination,
|
|
211
|
+
headers = headers,
|
|
212
|
+
bytesDownloaded = bytesDownloaded,
|
|
213
|
+
bytesTotal = bytesTotal,
|
|
214
|
+
metadata = metadata,
|
|
215
|
+
isAllowedOverMetered = isAllowedOverMetered
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
private fun PausedDownloadInfoData.toInfo() = Downloader.PausedDownloadInfo(
|
|
219
|
+
configId = configId,
|
|
220
|
+
url = url,
|
|
221
|
+
destination = destination,
|
|
222
|
+
headers = headers,
|
|
223
|
+
bytesDownloaded = bytesDownloaded,
|
|
224
|
+
bytesTotal = bytesTotal,
|
|
225
|
+
metadata = metadata,
|
|
226
|
+
isAllowedOverMetered = isAllowedOverMetered ?: true
|
|
200
227
|
)
|
|
201
228
|
|
|
202
229
|
/**
|
|
@@ -206,17 +233,7 @@ class StorageManager(context: Context, private val name: String) {
|
|
|
206
233
|
try {
|
|
207
234
|
val gson = Gson()
|
|
208
235
|
// Convert to serializable data class
|
|
209
|
-
val mapCopy = pausedDownloads.mapValues { (_, info) ->
|
|
210
|
-
PausedDownloadInfoData(
|
|
211
|
-
configId = info.configId,
|
|
212
|
-
url = info.url,
|
|
213
|
-
destination = info.destination,
|
|
214
|
-
headers = info.headers,
|
|
215
|
-
bytesDownloaded = info.bytesDownloaded,
|
|
216
|
-
bytesTotal = info.bytesTotal,
|
|
217
|
-
metadata = info.metadata
|
|
218
|
-
)
|
|
219
|
-
}
|
|
236
|
+
val mapCopy = pausedDownloads.mapValues { (_, info) -> info.toData() }
|
|
220
237
|
val str = gson.toJson(mapCopy)
|
|
221
238
|
|
|
222
239
|
if (isMMKVAvailable && mmkv != null) {
|
|
@@ -248,17 +265,7 @@ class StorageManager(context: Context, private val name: String) {
|
|
|
248
265
|
val mapType = object : TypeToken<Map<String, PausedDownloadInfoData>>() {}.type
|
|
249
266
|
val dataMap: Map<String, PausedDownloadInfoData> = gson.fromJson(str, mapType)
|
|
250
267
|
// Convert back to PausedDownloadInfo
|
|
251
|
-
return dataMap.mapValues { (_, data) ->
|
|
252
|
-
Downloader.PausedDownloadInfo(
|
|
253
|
-
configId = data.configId,
|
|
254
|
-
url = data.url,
|
|
255
|
-
destination = data.destination,
|
|
256
|
-
headers = data.headers,
|
|
257
|
-
bytesDownloaded = data.bytesDownloaded,
|
|
258
|
-
bytesTotal = data.bytesTotal,
|
|
259
|
-
metadata = data.metadata
|
|
260
|
-
)
|
|
261
|
-
}.toMutableMap()
|
|
268
|
+
return dataMap.mapValues { (_, data) -> data.toInfo() }.toMutableMap()
|
|
262
269
|
}
|
|
263
270
|
} catch (e: Exception) {
|
|
264
271
|
RNBackgroundDownloaderModuleImpl.logE(TAG, "Failed to load paused downloads: ${e.message}")
|
|
@@ -291,17 +298,7 @@ class StorageManager(context: Context, private val name: String) {
|
|
|
291
298
|
fun saveActiveDownloads(activeDownloads: Map<String, Downloader.PausedDownloadInfo>) {
|
|
292
299
|
try {
|
|
293
300
|
val gson = Gson()
|
|
294
|
-
val mapCopy = activeDownloads.mapValues { (_, info) ->
|
|
295
|
-
PausedDownloadInfoData(
|
|
296
|
-
configId = info.configId,
|
|
297
|
-
url = info.url,
|
|
298
|
-
destination = info.destination,
|
|
299
|
-
headers = info.headers,
|
|
300
|
-
bytesDownloaded = info.bytesDownloaded,
|
|
301
|
-
bytesTotal = info.bytesTotal,
|
|
302
|
-
metadata = info.metadata
|
|
303
|
-
)
|
|
304
|
-
}
|
|
301
|
+
val mapCopy = activeDownloads.mapValues { (_, info) -> info.toData() }
|
|
305
302
|
val str = gson.toJson(mapCopy)
|
|
306
303
|
|
|
307
304
|
if (isMMKVAvailable && mmkv != null) {
|
|
@@ -331,17 +328,7 @@ class StorageManager(context: Context, private val name: String) {
|
|
|
331
328
|
val gson = Gson()
|
|
332
329
|
val mapType = object : TypeToken<Map<String, PausedDownloadInfoData>>() {}.type
|
|
333
330
|
val dataMap: Map<String, PausedDownloadInfoData> = gson.fromJson(str, mapType)
|
|
334
|
-
return dataMap.mapValues { (_, data) ->
|
|
335
|
-
Downloader.PausedDownloadInfo(
|
|
336
|
-
configId = data.configId,
|
|
337
|
-
url = data.url,
|
|
338
|
-
destination = data.destination,
|
|
339
|
-
headers = data.headers,
|
|
340
|
-
bytesDownloaded = data.bytesDownloaded,
|
|
341
|
-
bytesTotal = data.bytesTotal,
|
|
342
|
-
metadata = data.metadata
|
|
343
|
-
)
|
|
344
|
-
}.toMutableMap()
|
|
331
|
+
return dataMap.mapValues { (_, data) -> data.toInfo() }.toMutableMap()
|
|
345
332
|
}
|
|
346
333
|
} catch (e: Exception) {
|
|
347
334
|
RNBackgroundDownloaderModuleImpl.logE(TAG, "Failed to load active downloads: ${e.message}")
|
|
@@ -1588,7 +1588,7 @@ RCT_EXPORT_METHOD(getExistingDownloadTasks: (RCTPromiseResolveBlock)resolve reje
|
|
|
1588
1588
|
NSString *method = options.method() ? options.method() : @"POST";
|
|
1589
1589
|
NSString *metadata = options.metadata() ? options.metadata() : @"";
|
|
1590
1590
|
NSDictionary *headers = options.headers() ? (NSDictionary *)options.headers() : nil;
|
|
1591
|
-
NSString *fieldName = options.fieldName() ? options.fieldName() :
|
|
1591
|
+
NSString *fieldName = options.fieldName() ? options.fieldName() : nil;
|
|
1592
1592
|
NSString *mimeType = options.mimeType() ? options.mimeType() : nil;
|
|
1593
1593
|
NSDictionary *parameters = options.parameters() ? (NSDictionary *)options.parameters() : nil;
|
|
1594
1594
|
|
|
@@ -1610,7 +1610,7 @@ RCT_EXPORT_METHOD(upload:(NSDictionary *)options) {
|
|
|
1610
1610
|
NSString *method = options[@"method"] ?: @"POST";
|
|
1611
1611
|
NSString *metadata = options[@"metadata"] ?: @"";
|
|
1612
1612
|
NSDictionary *headers = options[@"headers"];
|
|
1613
|
-
NSString *fieldName = options[@"fieldName"]
|
|
1613
|
+
NSString *fieldName = options[@"fieldName"];
|
|
1614
1614
|
NSString *mimeType = options[@"mimeType"];
|
|
1615
1615
|
NSDictionary *parameters = options[@"parameters"];
|
|
1616
1616
|
|
|
@@ -1697,8 +1697,9 @@ RCT_EXPORT_METHOD(upload:(NSDictionary *)options) {
|
|
|
1697
1697
|
NSString *filename = [source lastPathComponent];
|
|
1698
1698
|
NSString *contentType = mimeType ?: @"application/octet-stream";
|
|
1699
1699
|
|
|
1700
|
+
NSString *multipartFieldName = fieldName ?: @"file";
|
|
1700
1701
|
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
1701
|
-
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n",
|
|
1702
|
+
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", multipartFieldName, filename] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
1702
1703
|
[body appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", contentType] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
1703
1704
|
|
|
1704
1705
|
NSData *fileData = [NSData dataWithContentsOfFile:source];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kesha-antonov/react-native-background-downloader",
|
|
3
|
-
"version": "4.5.
|
|
3
|
+
"version": "4.5.8",
|
|
4
4
|
"description": "A library for React-Native to help you download large files on iOS and Android both in the foreground and most importantly in the background.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"lint": "eslint .",
|
|
56
56
|
"typecheck": "tsc src/*.ts --noEmit --strict --skipLibCheck",
|
|
57
57
|
"build": "rm -rf lib && tsc -p tsconfig.build.json",
|
|
58
|
-
"prepare": "npm run build",
|
|
58
|
+
"prepare": "npm run build && npm run build-plugin",
|
|
59
59
|
"prepublishOnly": "npm run build-plugin && npm run build && npm run typecheck && jest && npm run lint",
|
|
60
60
|
"build-plugin": "tsc plugin/src/index.ts --outDir plugin/build --target ES2018 --module commonjs --declaration --esModuleInterop --strict --skipLibCheck",
|
|
61
|
-
"
|
|
61
|
+
"release": "npm publish",
|
|
62
62
|
"test": "jest"
|
|
63
63
|
},
|
|
64
64
|
"lint-staged": {
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
"eslint-plugin-react-hooks": "^5.1.0",
|
|
106
106
|
"eslint-plugin-standard": "^5.0.0",
|
|
107
107
|
"immer": "^10.1.3",
|
|
108
|
-
"jest": "^
|
|
108
|
+
"jest": "^29.7.0",
|
|
109
109
|
"lint-staged": ">=16",
|
|
110
110
|
"metro-react-native-babel-preset": "^0.77.0",
|
|
111
111
|
"react": "19.1.0",
|