@@ -54,6 +54,11 @@ export class ImageLoader {
54
54
55
55
private processing : number = 0 ;
56
56
57
+ /**
58
+ * Fast accessable Object for currently processing items
59
+ */
60
+ private currentlyProcessing : { [ index : string ] : Promise < any > } = { } ;
61
+
57
62
private cacheIndex : IndexItem [ ] = [ ] ;
58
63
59
64
private currentCacheSize : number = 0 ;
@@ -167,13 +172,16 @@ export class ImageLoader {
167
172
return new Promise < string > ( ( resolve , reject ) => {
168
173
169
174
const getImage = ( ) => {
170
- this . getCachedImagePath ( imageUrl )
171
- . then ( resolve )
172
- . catch ( ( ) => {
173
- // image doesn't exist in cache, lets fetch it and save it
174
- this . addItemToQueue ( imageUrl , resolve , reject ) ;
175
- } ) ;
176
-
175
+ if ( this . isImageUrlRelative ( imageUrl ) ) {
176
+ resolve ( imageUrl ) ;
177
+ } else {
178
+ this . getCachedImagePath ( imageUrl )
179
+ . then ( resolve )
180
+ . catch ( ( ) => {
181
+ // image doesn't exist in cache, lets fetch it and save it
182
+ this . addItemToQueue ( imageUrl , resolve , reject ) ;
183
+ } ) ;
184
+ }
177
185
} ;
178
186
179
187
const check = ( ) => {
@@ -195,6 +203,14 @@ export class ImageLoader {
195
203
196
204
}
197
205
206
+ /**
207
+ * Returns if an imageUrl is an relative path
208
+ * @param imageUrl
209
+ */
210
+ private isImageUrlRelative ( imageUrl : string ) {
211
+ return ! / ^ ( h t t p s ? | f i l e ) : \/ \/ \/ ? / i. test ( imageUrl ) ;
212
+ }
213
+
198
214
/**
199
215
* Add an item to the queue
200
216
* @param imageUrl
@@ -237,39 +253,67 @@ export class ImageLoader {
237
253
238
254
// take the first item from queue
239
255
const currentItem : QueueItem = this . queue . splice ( 0 , 1 ) [ 0 ] ;
240
-
241
- // process more items concurrently if we can
242
- if ( this . canProcess ) this . processQueue ( ) ;
243
-
244
- // function to call when done processing this item
245
- // this will reduce the processing number
246
- // then will execute this function again to process any remaining items
247
- const done = ( ) => {
248
- this . processing -- ;
249
- this . processQueue ( ) ;
250
- } ;
251
-
252
- const localDir = this . file . cacheDirectory + this . config . cacheDirectoryName + '/' ;
253
- const fileName = this . createFileName ( currentItem . imageUrl ) ;
254
-
255
- this . http . get ( currentItem . imageUrl , {
256
- responseType : 'blob' ,
257
- headers : this . config . httpHeaders ,
258
- } ) . subscribe ( ( data : Blob ) => {
259
- this . file . writeFile ( localDir , fileName , data ) . then ( ( file : FileEntry ) => {
260
- if ( this . shouldIndex ) {
261
- this . addFileToIndex ( file ) . then ( this . maintainCacheSize . bind ( this ) ) ;
262
- }
263
- return this . getCachedImagePath ( currentItem . imageUrl ) ;
264
- } ) . then ( ( localUrl ) => {
265
- currentItem . resolve ( localUrl ) ;
266
- done ( ) ;
267
- } ) . catch ( ( e ) => {
268
- currentItem . reject ( ) ;
269
- this . throwError ( e ) ;
270
- done ( ) ;
256
+ if ( this . currentlyProcessing [ currentItem . imageUrl ] === undefined ) {
257
+ this . currentlyProcessing [ currentItem . imageUrl ] = new Promise ( ( resolve , reject ) => {
258
+ // process more items concurrently if we can
259
+ if ( this . canProcess ) this . processQueue ( ) ;
260
+
261
+ // function to call when done processing this item
262
+ // this will reduce the processing number
263
+ // then will execute this function again to process any remaining items
264
+ const done = ( ) => {
265
+ this . processing -- ;
266
+ this . processQueue ( ) ;
267
+
268
+ if ( this . currentlyProcessing [ currentItem . imageUrl ] !== undefined ) {
269
+ delete this . currentlyProcessing [ currentItem . imageUrl ] ;
270
+ }
271
+ } ;
272
+
273
+ const error = ( e ) => {
274
+ currentItem . reject ( ) ;
275
+ this . throwError ( e ) ;
276
+ done ( ) ;
277
+ } ;
278
+
279
+ const localDir = this . file . cacheDirectory + this . config . cacheDirectoryName + '/' ;
280
+ const fileName = this . createFileName ( currentItem . imageUrl ) ;
281
+
282
+ this . http . get ( currentItem . imageUrl , {
283
+ responseType : 'blob' ,
284
+ headers : this . config . httpHeaders ,
285
+ } ) . subscribe (
286
+ ( data : Blob ) => {
287
+ this . file . writeFile ( localDir , fileName , data , { replace : true } ) . then ( ( file : FileEntry ) => {
288
+ if ( this . shouldIndex ) {
289
+ this . addFileToIndex ( file ) . then ( ( ) => {
290
+ this . getCachedImagePath ( currentItem . imageUrl ) . then ( ( localUrl ) => {
291
+ currentItem . resolve ( localUrl ) ;
292
+ resolve ( ) ;
293
+ done ( ) ;
294
+ this . maintainCacheSize ( ) ;
295
+ } ) ;
296
+ } ) ;
297
+ }
298
+ } ) . catch ( ( e ) => {
299
+ //Could not write image
300
+ error ( e ) ;
301
+ } ) ;
302
+ } ,
303
+ ( e ) => {
304
+ //Could not get image via httpClient
305
+ error ( e ) ;
306
+ }
307
+ ) ;
271
308
} ) ;
272
- } ) ;
309
+ } else {
310
+ //Prevented same Image from loading at the same time
311
+ this . currentlyProcessing [ currentItem . imageUrl ] . then ( ( ) => {
312
+ this . getCachedImagePath ( currentItem . imageUrl ) . then ( ( localUrl ) => {
313
+ currentItem . resolve ( localUrl ) ;
314
+ } )
315
+ } ) ;
316
+ }
273
317
}
274
318
275
319
/**
0 commit comments