@@ -54,6 +54,11 @@ export class ImageLoader {
5454
5555 private processing : number = 0 ;
5656
57+ /**
58+ * Fast accessable Object for currently processing items
59+ */
60+ private currentlyProcessing : { [ index : string ] : Promise < any > } = { } ;
61+
5762 private cacheIndex : IndexItem [ ] = [ ] ;
5863
5964 private currentCacheSize : number = 0 ;
@@ -167,13 +172,16 @@ export class ImageLoader {
167172 return new Promise < string > ( ( resolve , reject ) => {
168173
169174 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+ }
177185 } ;
178186
179187 const check = ( ) => {
@@ -195,6 +203,14 @@ export class ImageLoader {
195203
196204 }
197205
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+
198214 /**
199215 * Add an item to the queue
200216 * @param imageUrl
@@ -237,39 +253,67 @@ export class ImageLoader {
237253
238254 // take the first item from queue
239255 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+ ) ;
271308 } ) ;
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+ }
273317 }
274318
275319 /**
0 commit comments