precache method
Pre-caches data from the network.
cacheSegments
: Number of segments to cache.
downloadNow
: If true, downloads immediately; otherwise, pushes tasks to the queue.
progressListen
: If true, returns a StreamController with progress updates.
Returns a StreamController emitting progress maps, or null
if not listening.
Implementation
@override
Future<StreamController<Map>?> precache(
String url,
Map<String, Object>? headers,
int cacheSegments,
bool downloadNow,
bool progressListen,
) async {
StreamController<Map>? _streamController;
if (progressListen) _streamController = StreamController();
int contentLength = await head(url.toSafeUri(), headers: headers);
if (contentLength > 0) {
int segmentSize = contentLength ~/ Config.segmentSize +
(contentLength % Config.segmentSize > 0 ? 1 : 0);
if (cacheSegments > segmentSize) {
cacheSegments = segmentSize;
}
}
int downloadedSize = 0;
int totalSize = cacheSegments;
int count = 0;
while (count < cacheSegments) {
DownloadTask task = DownloadTask(uri: url.toSafeUri(), headers: headers);
// Set the start and end range for each segment
task.startRange += Config.segmentSize * count;
task.endRange = task.startRange + Config.segmentSize - 1;
count++;
if (downloadNow) {
Uint8List? data = await cache(task);
if (data != null) {
downloadedSize += 1;
_streamController?.sink.add({
'progress': downloadedSize / totalSize,
'url': task.url,
'startRange': task.startRange,
'endRange': task.endRange,
});
continue;
}
download(task).whenComplete(() {
downloadedSize += 1;
_streamController?.sink.add({
'progress': downloadedSize / totalSize,
'url': task.url,
'startRange': task.startRange,
'endRange': task.endRange,
});
});
} else {
push(task);
}
}
return _streamController;
}