copyUrlToLocalStorageWithProgress method

  1. @override
Stream<int> copyUrlToLocalStorageWithProgress(
  1. String url,
  2. String targetName
)
override

Downloads the file at url to targetName, emitting download progress as integers from 0 to 100.

Implementation

@override
Stream<int> copyUrlToLocalStorageWithProgress(String url, String targetName) {
  final controller = StreamController<int>();

  Future<void> run() async {
    final resolved = await _resolve(targetName);
    final request = http.Request('GET', Uri.parse(url));
    final response = await httpClient.send(request);
    if (response.statusCode < 200 || response.statusCode >= 300) {
      await response.stream.drain<void>();
      throw HttpException(
        'HTTP ${response.statusCode} downloading $url',
        uri: Uri.parse(url),
      );
    }
    final total = response.contentLength;
    final sink = File(resolved).openWrite();
    try {
      if (total == null || total == 0) {
        controller.add(0);
        await response.stream.pipe(sink);
        controller.add(100);
        return;
      }

      var received = 0;
      var lastPercent = -1;
      await for (final chunk in response.stream) {
        sink.add(chunk);
        received += chunk.length;
        final percent = ((received / total) * 100).floor().clamp(0, 100);
        if (percent != lastPercent) {
          lastPercent = percent;
          controller.add(percent);
        }
      }
      if (lastPercent != 100) {
        controller.add(100);
      }
    } finally {
      await sink.close();
    }
  }

  unawaited(run()
      .then((_) {}, onError: controller.addError)
      .whenComplete(controller.close));
  return controller.stream;
}