Make downloads faster (#580)

This commit is contained in:
Imran Remtulla
2025-03-07 14:46:51 -05:00
parent 0fd496e660
commit 4200e1d954

View File

@ -9,6 +9,7 @@ import 'package:battery_plus/battery_plus.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'dart:typed_data';
import 'package:android_intent_plus/flag.dart'; import 'package:android_intent_plus/flag.dart';
import 'package:android_package_installer/android_package_installer.dart'; import 'package:android_package_installer/android_package_installer.dart';
@ -345,18 +346,43 @@ Future<File> downloadFile(String url, String fileName, bool fileNameHasExt,
// Perform the download // Perform the download
var received = 0; var received = 0;
double? progress; double? progress;
DateTime? lastProgressUpdate; // Track last progress update time
const throttleDuration = Duration(milliseconds: 100); // Throttle interval
if (rangeStart > 0 && fullContentLength != null) { if (rangeStart > 0 && fullContentLength != null) {
received = rangeStart; received = rangeStart;
} }
await response.stream.map((s) { const bufferSizeThreshold = 64 * 1024; // 64KB
received += s.length; final buffer = BytesBuilder(); // Efficiently accumulates bytes
progress = await response.stream
(fullContentLength != null ? (received / fullContentLength) * 100 : 30); .map((chunk) {
if (onProgress != null) { received += chunk.length;
onProgress(progress); final now = DateTime.now();
} if (onProgress != null &&
return s; (lastProgressUpdate == null ||
}).pipe(sink); now.difference(lastProgressUpdate!) >= throttleDuration)) {
progress = fullContentLength != null
? (received / fullContentLength) * 100
: 30;
onProgress(progress);
lastProgressUpdate = now;
}
return chunk;
})
.transform(StreamTransformer<List<int>, List<int>>.fromHandlers(
handleData: (List<int> data, EventSink<List<int>> sink) {
buffer.add(data);
if (buffer.length >= bufferSizeThreshold) {
sink.add(buffer.takeBytes());
}
},
handleDone: (EventSink<List<int>> sink) {
if (buffer.isNotEmpty) {
sink.add(buffer.takeBytes());
}
sink.close();
},
))
.pipe(sink);
await sink.close(); await sink.close();
progress = null; progress = null;
if (onProgress != null) { if (onProgress != null) {