Skip to content

Commit 09871bd

Browse files
committed
fix(image-loader): delete one file at once to maintain cache size
1 parent 8655454 commit 09871bd

File tree

1 file changed

+54
-29
lines changed

1 file changed

+54
-29
lines changed

src/providers/image-loader.ts

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
import { Injectable } from '@angular/core';
2-
import { File, FileEntry, FileReader } from '@ionic-native/file';
2+
import { File, FileEntry, FileReader, FileError } from '@ionic-native/file';
33
import { Transfer } from '@ionic-native/transfer';
44
import { ImageLoaderConfig } from "./image-loader-config";
55
import { Platform } from 'ionic-angular';
66
import * as _ from 'lodash';
77

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+
820
@Injectable()
921
export class ImageLoader {
1022

@@ -32,19 +44,11 @@ export class ImageLoader {
3244
* Queue items
3345
* @type {Array}
3446
*/
35-
private queue: Array<{
36-
imageUrl: string;
37-
resolve: Function;
38-
reject: Function;
39-
}> = [];
47+
private queue: QueueItem[] = [];
4048

4149
private processing: number = 0;
4250

43-
private cacheIndex: Array<{
44-
name: string;
45-
modificationTime: Date;
46-
size: number;
47-
}> = [];
51+
private cacheIndex: IndexItem[] = [];
4852

4953
private currentCacheSize: number = 0;
5054

@@ -134,7 +138,7 @@ export class ImageLoader {
134138
getImagePath(imageUrl: string): Promise<string> {
135139
return new Promise<string>((resolve, reject) => {
136140

137-
let getImage = () => {
141+
const getImage = () => {
138142
this.getCachedImagePath(imageUrl)
139143
.then(resolve)
140144
.catch(() => {
@@ -144,7 +148,7 @@ export class ImageLoader {
144148

145149
};
146150

147-
let check = () => {
151+
const check = () => {
148152
if (this.isInit) {
149153
if (this.isCacheReady) {
150154
getImage();
@@ -204,7 +208,7 @@ export class ImageLoader {
204208
this.processing++;
205209

206210
// 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];
208212

209213
// process more items concurrently if we can
210214
if (this.canProcess) this.processQueue();
@@ -217,7 +221,7 @@ export class ImageLoader {
217221
this.processQueue();
218222
};
219223

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);
221225
this.downloadImage(currentItem.imageUrl, localPath)
222226
.then((file: FileEntry) => {
223227

@@ -333,12 +337,31 @@ export class ImageLoader {
333337

334338
if (this.config.maxCacheSize > -1 && this.indexed) {
335339

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();
342365

343366
}
344367

@@ -358,10 +381,10 @@ export class ImageLoader {
358381
}
359382

360383
// get file name
361-
let fileName = this.createFileName(url);
384+
const fileName = this.createFileName(url);
362385

363386
// get full path
364-
let dirPath = this.file.cacheDirectory + this.config.cacheDirectoryName;
387+
const dirPath = this.file.cacheDirectory + this.config.cacheDirectoryName;
365388

366389
// check if exists
367390
this.file.resolveLocalFilesystemUrl(dirPath + '/' + fileName)
@@ -396,21 +419,23 @@ export class ImageLoader {
396419

397420
/**
398421
* Throws a console error if debug mode is enabled
399-
* @param error {string} Error message
422+
* @param args {any[]} Error message
400423
*/
401-
private throwError(error: any): void {
424+
private throwError(...args: any[]): void {
402425
if (this.config.debugMode) {
403-
console.error('ImageLoader Error', error);
426+
args.unshift('ImageLoader Error: ');
427+
console.error.apply(console, args);
404428
}
405429
}
406430

407431
/**
408432
* Throws a console warning if debug mode is enabled
409-
* @param error {string} Error message
433+
* @param args {any[]} Error message
410434
*/
411-
private throwWarning(error: any): void {
435+
private throwWarning(...args: any[]): void {
412436
if (this.config.debugMode) {
413-
console.warn('ImageLoader Warning', error);
437+
args.unshift('ImageLoader Warning: ');
438+
console.warn.apply(console, args);
414439
}
415440
}
416441

0 commit comments

Comments
 (0)