48 lines
1.4 KiB
Dart
48 lines
1.4 KiB
Dart
import 'package:dio/dio.dart';
|
|
|
|
/// Lightweight cancel handle around a single `Dio.download` call. The download
|
|
/// itself is started by [run]; the handle returns synchronously so callers can
|
|
/// install it into shared state before the first progress event can fire.
|
|
class FileDownloader {
|
|
FileDownloader();
|
|
|
|
final CancelToken _cancelToken = CancelToken();
|
|
bool _cancelled = false;
|
|
|
|
bool get isCancelled => _cancelled;
|
|
|
|
void cancel() {
|
|
if (_cancelled) return;
|
|
_cancelled = true;
|
|
_cancelToken.cancel('user cancelled');
|
|
}
|
|
|
|
/// Kicks off the download. Returns immediately; the download progresses in
|
|
/// the background and events are delivered via callbacks. Callbacks are not
|
|
/// invoked once [cancel] has been called.
|
|
void run({
|
|
required Dio client,
|
|
required String url,
|
|
required String savePath,
|
|
required void Function(double percent) onProgress,
|
|
required void Function() onDone,
|
|
required void Function(Object error) onError,
|
|
}) {
|
|
client.download(
|
|
url,
|
|
savePath,
|
|
cancelToken: _cancelToken,
|
|
onReceiveProgress: (received, total) {
|
|
if (_cancelled || total <= 0) return;
|
|
onProgress((received / total) * 100);
|
|
},
|
|
).then((_) {
|
|
if (_cancelled) return;
|
|
onDone();
|
|
}).catchError((Object error) {
|
|
if (_cancelled) return;
|
|
onError(error);
|
|
}).ignore();
|
|
}
|
|
}
|