Skip to content

Commit a15309f

Browse files
felixbroehlihadeed
authored andcommitted
fix(image-loader): resolve gray content in image issue (#163)
* subscribe error callback * add subscribe error callback * prevent loading of the same file * debug log * Update package.json * Update package.json * Update image-loader.ts * Update image-loader.ts * Update image-loader.ts * Update image-loader.ts
1 parent 58afbde commit a15309f

File tree

1 file changed

+83
-39
lines changed

1 file changed

+83
-39
lines changed

src/providers/image-loader.ts

Lines changed: 83 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -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 !/^(https?|file):\/\/\/?/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

Comments
 (0)