1
1
import { Injectable } from '@angular/core' ;
2
- import { File , FileEntry , FileReader } from '@ionic-native/file' ;
2
+ import { File , FileEntry , FileReader , FileError } from '@ionic-native/file' ;
3
3
import { Transfer } from '@ionic-native/transfer' ;
4
4
import { ImageLoaderConfig } from "./image-loader-config" ;
5
5
import { Platform } from 'ionic-angular' ;
6
6
import * as _ from 'lodash' ;
7
7
8
+ interface IndexItem {
9
+ name : string ;
10
+ modificationTime : Date ;
11
+ size : number ;
12
+ }
13
+
14
+ interface QueueItem {
15
+ imageUrl : string ;
16
+ resolve : Function ;
17
+ reject : Function ;
18
+ }
19
+
8
20
@Injectable ( )
9
21
export class ImageLoader {
10
22
@@ -32,19 +44,11 @@ export class ImageLoader {
32
44
* Queue items
33
45
* @type {Array }
34
46
*/
35
- private queue : Array < {
36
- imageUrl : string ;
37
- resolve : Function ;
38
- reject : Function ;
39
- } > = [ ] ;
47
+ private queue : QueueItem [ ] = [ ] ;
40
48
41
49
private processing : number = 0 ;
42
50
43
- private cacheIndex : Array < {
44
- name : string ;
45
- modificationTime : Date ;
46
- size : number ;
47
- } > = [ ] ;
51
+ private cacheIndex : IndexItem [ ] = [ ] ;
48
52
49
53
private currentCacheSize : number = 0 ;
50
54
@@ -134,7 +138,7 @@ export class ImageLoader {
134
138
getImagePath ( imageUrl : string ) : Promise < string > {
135
139
return new Promise < string > ( ( resolve , reject ) => {
136
140
137
- let getImage = ( ) => {
141
+ const getImage = ( ) => {
138
142
this . getCachedImagePath ( imageUrl )
139
143
. then ( resolve )
140
144
. catch ( ( ) => {
@@ -144,7 +148,7 @@ export class ImageLoader {
144
148
145
149
} ;
146
150
147
- let check = ( ) => {
151
+ const check = ( ) => {
148
152
if ( this . isInit ) {
149
153
if ( this . isCacheReady ) {
150
154
getImage ( ) ;
@@ -204,7 +208,7 @@ export class ImageLoader {
204
208
this . processing ++ ;
205
209
206
210
// take the first item from queue
207
- const currentItem = this . queue . splice ( 0 , 1 ) [ 0 ] ;
211
+ const currentItem : QueueItem = this . queue . splice ( 0 , 1 ) [ 0 ] ;
208
212
209
213
// process more items concurrently if we can
210
214
if ( this . canProcess ) this . processQueue ( ) ;
@@ -217,7 +221,7 @@ export class ImageLoader {
217
221
this . processQueue ( ) ;
218
222
} ;
219
223
220
- let localPath = this . file . cacheDirectory + this . config . cacheDirectoryName + '/' + this . createFileName ( currentItem . imageUrl ) ;
224
+ const localPath = this . file . cacheDirectory + this . config . cacheDirectoryName + '/' + this . createFileName ( currentItem . imageUrl ) ;
221
225
this . downloadImage ( currentItem . imageUrl , localPath )
222
226
. then ( ( file : FileEntry ) => {
223
227
@@ -333,12 +337,31 @@ export class ImageLoader {
333
337
334
338
if ( this . config . maxCacheSize > - 1 && this . indexed ) {
335
339
336
- // we exceeded max cache size
337
- while ( this . currentCacheSize > this . config . maxCacheSize ) {
338
- let file = this . cacheIndex . splice ( 0 , 1 ) [ 0 ] ;
339
- this . file . removeFile ( this . file . cacheDirectory + this . config . cacheDirectoryName , file . name ) ;
340
- this . currentCacheSize -= file . size ;
341
- }
340
+ const maintain = ( ) => {
341
+ if ( this . currentCacheSize > this . config . maxCacheSize ) {
342
+
343
+ // called when item is done processing
344
+ const next : Function = ( ) => {
345
+ this . currentCacheSize -= file . size ;
346
+ maintain ( ) ;
347
+ } ;
348
+
349
+ // grab the first item in index since it's the oldest one
350
+ const file : IndexItem = this . cacheIndex . splice ( 0 , 1 ) [ 0 ] ;
351
+
352
+ // delete the file then process next file if necessary
353
+ this . file . removeFile ( this . file . cacheDirectory + this . config . cacheDirectoryName , file . name )
354
+ . then ( ( ) => next ( ) )
355
+ . catch ( ( e : FileError ) => {
356
+ next ( ) ;
357
+ if ( e . code != 1 ) { // ignore File not found error
358
+ this . throwError ( 'Error deleting file from cache to maintain size. ' , e )
359
+ }
360
+ } ) ;
361
+ }
362
+ } ;
363
+
364
+ maintain ( ) ;
342
365
343
366
}
344
367
@@ -358,10 +381,10 @@ export class ImageLoader {
358
381
}
359
382
360
383
// get file name
361
- let fileName = this . createFileName ( url ) ;
384
+ const fileName = this . createFileName ( url ) ;
362
385
363
386
// get full path
364
- let dirPath = this . file . cacheDirectory + this . config . cacheDirectoryName ;
387
+ const dirPath = this . file . cacheDirectory + this . config . cacheDirectoryName ;
365
388
366
389
// check if exists
367
390
this . file . resolveLocalFilesystemUrl ( dirPath + '/' + fileName )
@@ -396,21 +419,23 @@ export class ImageLoader {
396
419
397
420
/**
398
421
* Throws a console error if debug mode is enabled
399
- * @param error {string } Error message
422
+ * @param args {any[] } Error message
400
423
*/
401
- private throwError ( error : any ) : void {
424
+ private throwError ( ... args : any [ ] ) : void {
402
425
if ( this . config . debugMode ) {
403
- console . error ( 'ImageLoader Error' , error ) ;
426
+ args . unshift ( 'ImageLoader Error: ' ) ;
427
+ console . error . apply ( console , args ) ;
404
428
}
405
429
}
406
430
407
431
/**
408
432
* Throws a console warning if debug mode is enabled
409
- * @param error {string } Error message
433
+ * @param args {any[] } Error message
410
434
*/
411
- private throwWarning ( error : any ) : void {
435
+ private throwWarning ( ... args : any [ ] ) : void {
412
436
if ( this . config . debugMode ) {
413
- console . warn ( 'ImageLoader Warning' , error ) ;
437
+ args . unshift ( 'ImageLoader Warning: ' ) ;
438
+ console . warn . apply ( console , args ) ;
414
439
}
415
440
}
416
441
0 commit comments