@@ -12,6 +12,8 @@ import 'package:cached_network_image_platform_interface'
12
12
import 'package:flutter/material.dart' ;
13
13
import 'package:flutter_cache_manager/flutter_cache_manager.dart' ;
14
14
15
+ enum _State { open, waitingForData, closing }
16
+
15
17
/// ImageLoader class to load images on the web platform.
16
18
class ImageLoader implements platform.ImageLoader {
17
19
@Deprecated ('Use loadImageAsync instead' )
@@ -115,39 +117,70 @@ class ImageLoader implements platform.ImageLoader {
115
117
int ? maxWidth,
116
118
Map <String , String >? headers,
117
119
VoidCallback evictImage,
118
- ) async * {
120
+ ) {
121
+ var streamController = StreamController <ui.Codec >();
122
+
119
123
try {
120
- await for ( final result in cacheManager.getFileStream (
124
+ final stream = cacheManager.getFileStream (
121
125
url,
122
- key: cacheKey,
123
126
withProgress: true ,
124
127
headers: headers,
125
- )) {
126
- if (result is DownloadProgress ) {
127
- chunkEvents.add (
128
- ImageChunkEvent (
129
- cumulativeBytesLoaded: result.downloaded,
130
- expectedTotalBytes: result.totalSize,
131
- ),
132
- );
133
- }
134
- if (result is FileInfo ) {
135
- final file = result.file;
136
- final bytes = await file.readAsBytes ();
137
- final decoded = await decode (bytes);
138
- yield decoded;
139
- }
140
- }
141
- } on Object {
142
- // Depending on where the exception was thrown, the image cache may not
143
- // have had a chance to track the key in the cache at all.
144
- // Schedule a microtask to give the cache a chance to add the key.
128
+ key: cacheKey,
129
+ );
130
+
131
+ var state = _State .open;
132
+
133
+ stream.listen (
134
+ (event) {
135
+ if (event is DownloadProgress ) {
136
+ chunkEvents.add (
137
+ ImageChunkEvent (
138
+ cumulativeBytesLoaded: event.downloaded,
139
+ expectedTotalBytes: event.totalSize,
140
+ ),
141
+ );
142
+ }
143
+ if (event is FileInfo ) {
144
+ if (state == _State .open) {
145
+ state = _State .waitingForData;
146
+ }
147
+
148
+ event.file
149
+ .readAsBytes ()
150
+ .then ((value) => decode (value))
151
+ .then ((data) {
152
+ streamController.add (data);
153
+ if (state == _State .closing) {
154
+ streamController.close ();
155
+ chunkEvents.close ();
156
+ }
157
+ });
158
+ }
159
+ },
160
+ onError: (e, st) {
161
+ scheduleMicrotask (() {
162
+ evictImage ();
163
+ });
164
+ streamController.addError (e, st);
165
+ },
166
+ onDone: () async {
167
+ if (state == _State .open) {
168
+ streamController.close ();
169
+ chunkEvents.close ();
170
+ } else if (state == _State .waitingForData) {
171
+ state = _State .closing;
172
+ }
173
+ },
174
+ cancelOnError: true ,
175
+ );
176
+ } on Object catch (e, st) {
145
177
scheduleMicrotask (() {
146
178
evictImage ();
147
179
});
148
- rethrow ;
180
+ streamController. addError (e, st) ;
149
181
}
150
- await chunkEvents.close ();
182
+
183
+ return streamController.stream;
151
184
}
152
185
153
186
Future <ui.Codec > _loadAsyncHtmlImage (
0 commit comments