Unverified Commit d3a66e31 authored by Ferhat's avatar Ferhat Committed by GitHub

[web] Add support for ChunkEvents during image loading (#52558)

* Add support for ChunkEvents for web
* Add lint skip for webOnly call in _network_image_web
parent 757b39ba
...@@ -13,7 +13,9 @@ import 'image_stream.dart'; ...@@ -13,7 +13,9 @@ import 'image_stream.dart';
/// The dart:html implementation of [image_provider.NetworkImage]. /// The dart:html implementation of [image_provider.NetworkImage].
/// ///
/// NetworkImage on the web does not support decoding to a specified size. /// NetworkImage on the web does not support decoding to a specified size.
class NetworkImage extends image_provider.ImageProvider<image_provider.NetworkImage> implements image_provider.NetworkImage { class NetworkImage
extends image_provider.ImageProvider<image_provider.NetworkImage>
implements image_provider.NetworkImage {
/// Creates an object that fetches the image at the given URL. /// Creates an object that fetches the image at the given URL.
/// ///
/// The arguments [url] and [scale] must not be null. /// The arguments [url] and [scale] must not be null.
...@@ -31,22 +33,41 @@ class NetworkImage extends image_provider.ImageProvider<image_provider.NetworkIm ...@@ -31,22 +33,41 @@ class NetworkImage extends image_provider.ImageProvider<image_provider.NetworkIm
final Map<String, String> headers; final Map<String, String> headers;
@override @override
Future<NetworkImage> obtainKey(image_provider.ImageConfiguration configuration) { Future<NetworkImage> obtainKey(
image_provider.ImageConfiguration configuration) {
return SynchronousFuture<NetworkImage>(this); return SynchronousFuture<NetworkImage>(this);
} }
@override @override
ImageStreamCompleter load(image_provider.NetworkImage key, image_provider.DecoderCallback decode) { ImageStreamCompleter load(
image_provider.NetworkImage key, image_provider.DecoderCallback decode) {
// Ownership of this controller is handed off to [_loadAsync]; it is that
// method's responsibility to close the controller's stream when the image
// has been loaded or an error is thrown.
final StreamController<ImageChunkEvent> chunkEvents =
StreamController<ImageChunkEvent>();
return MultiFrameImageStreamCompleter( return MultiFrameImageStreamCompleter(
codec: _loadAsync(key as NetworkImage, decode), chunkEvents: chunkEvents.stream,
scale: key.scale, codec: _loadAsync(key as NetworkImage, decode, chunkEvents),
informationCollector: () { scale: key.scale,
informationCollector: _imageStreamInformationCollector(key));
}
InformationCollector _imageStreamInformationCollector(
image_provider.NetworkImage key) {
InformationCollector collector;
assert(() {
collector = () {
return <DiagnosticsNode>[ return <DiagnosticsNode>[
DiagnosticsProperty<image_provider.ImageProvider>('Image provider', this), DiagnosticsProperty<image_provider.ImageProvider>(
'Image provider', this),
DiagnosticsProperty<NetworkImage>('Image key', key as NetworkImage), DiagnosticsProperty<NetworkImage>('Image key', key as NetworkImage),
]; ];
}, };
); return true;
}());
return collector;
} }
// TODO(garyq): We should eventually support custom decoding of network images on Web as // TODO(garyq): We should eventually support custom decoding of network images on Web as
...@@ -55,13 +76,20 @@ class NetworkImage extends image_provider.ImageProvider<image_provider.NetworkIm ...@@ -55,13 +76,20 @@ class NetworkImage extends image_provider.ImageProvider<image_provider.NetworkIm
// Web does not support decoding network images to a specified size. The decode parameter // Web does not support decoding network images to a specified size. The decode parameter
// here is ignored and the web-only `ui.webOnlyInstantiateImageCodecFromUrl` will be used // here is ignored and the web-only `ui.webOnlyInstantiateImageCodecFromUrl` will be used
// directly in place of the typical `instantiateImageCodec` method. // directly in place of the typical `instantiateImageCodec` method.
Future<ui.Codec> _loadAsync(NetworkImage key, image_provider.DecoderCallback decode) { Future<ui.Codec> _loadAsync(
NetworkImage key,
image_provider.DecoderCallback decode,
StreamController<ImageChunkEvent> chunkEvents) {
assert(key == this); assert(key == this);
final Uri resolved = Uri.base.resolve(key.url); final Uri resolved = Uri.base.resolve(key.url);
// This API only exists in the web engine implementation and is not // This API only exists in the web engine implementation and is not
// contained in the analyzer summary for Flutter. // contained in the analyzer summary for Flutter.
return ui.webOnlyInstantiateImageCodecFromUrl(resolved) as Future<ui.Codec>; // ignore: undefined_function return ui.webOnlyInstantiateImageCodecFromUrl(resolved, // ignore: undefined_function
chunkCallback: (int bytes, int total) {
chunkEvents.add(ImageChunkEvent(
cumulativeBytesLoaded: bytes, expectedTotalBytes: total));
}) as Future<ui.Codec>; // ignore: undefined_function
} }
@override @override
...@@ -69,14 +97,13 @@ class NetworkImage extends image_provider.ImageProvider<image_provider.NetworkIm ...@@ -69,14 +97,13 @@ class NetworkImage extends image_provider.ImageProvider<image_provider.NetworkIm
if (other.runtimeType != runtimeType) { if (other.runtimeType != runtimeType) {
return false; return false;
} }
return other is NetworkImage return other is NetworkImage && other.url == url && other.scale == scale;
&& other.url == url
&& other.scale == scale;
} }
@override @override
int get hashCode => ui.hashValues(url, scale); int get hashCode => ui.hashValues(url, scale);
@override @override
String toString() => '${objectRuntimeType(this, 'NetworkImage')}("$url", scale: $scale)'; String toString() =>
'${objectRuntimeType(this, 'NetworkImage')}("$url", scale: $scale)';
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment