1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2024-11-03 21:04:03 +08:00
pigallery2/frontend/app/gallery/grid/thumnailLoader.service.ts

172 lines
4.6 KiB
TypeScript
Raw Normal View History

2016-06-17 06:05:31 +08:00
import {Injectable} from "@angular/core";
2016-06-17 17:25:15 +08:00
import {Config} from "../../config/Config";
import {GalleryCacheService} from "../cache.gallery.service";
2017-03-20 07:01:41 +08:00
import {Photo} from "../Photo";
2016-06-17 06:05:31 +08:00
export enum ThumbnailLoadingPriority{
high, medium, low
}
2016-06-17 06:05:31 +08:00
@Injectable()
export class ThumbnailLoaderService {
2016-12-27 06:36:38 +08:00
que: Array<ThumbnailTask> = [];
runningRequests: number = 0;
2016-06-17 06:05:31 +08:00
2016-12-27 06:36:38 +08:00
constructor(private galleryChacheService: GalleryCacheService) {
2016-06-17 06:05:31 +08:00
}
2016-06-24 04:25:16 +08:00
removeTasks() {
this.que = [];
}
2016-12-27 06:36:38 +08:00
removeTask(taskEntry: ThumbnailTaskEntity) {
for (let i = 0; i < this.que.length; i++) {
let index = this.que[i].taskEntities.indexOf(taskEntry);
if (index == -1) {
this.que[i].taskEntities.splice(index, 1);
if (this.que[i].taskEntities.length == 0) {
this.que.splice(i, 1);
}
return;
}
}
}
2017-03-20 07:01:41 +08:00
loadImage(photo: Photo, priority: ThumbnailLoadingPriority, listener: ThumbnailLoadingListener): ThumbnailTaskEntity {
2016-12-27 06:36:38 +08:00
let tmp: ThumbnailTask = null;
2016-06-24 04:25:16 +08:00
//is image already qued?
2016-06-17 17:25:15 +08:00
for (let i = 0; i < this.que.length; i++) {
2017-03-20 07:01:41 +08:00
if (this.que[i].photo.getThumbnailPath() == photo.getThumbnailPath()) {
2016-06-17 17:25:15 +08:00
tmp = this.que[i];
break;
2016-06-17 06:05:31 +08:00
}
2016-06-17 17:25:15 +08:00
}
let thumbnailTaskEntity = {priority: priority, listener: listener};
2016-06-24 04:25:16 +08:00
//add to previous
2016-06-17 17:25:15 +08:00
if (tmp != null) {
tmp.taskEntities.push(thumbnailTaskEntity);
2016-06-24 04:25:16 +08:00
if (tmp.inProgress == true) {
listener.onStartedLoading();
2016-06-24 04:25:16 +08:00
}
} else {//create new task
2016-06-17 17:25:15 +08:00
this.que.push({
2017-03-20 07:01:41 +08:00
photo: photo,
2016-06-24 04:25:16 +08:00
inProgress: false,
taskEntities: [thumbnailTaskEntity]
2016-06-17 17:25:15 +08:00
});
}
setImmediate(this.run);
return thumbnailTaskEntity;
}
2016-12-27 06:36:38 +08:00
private getNextTask(): ThumbnailTask {
if (this.que.length === 0) {
return null;
}
for (let i = 0; i < this.que.length; i++) {
for (let j = 0; j < this.que[i].taskEntities.length; j++) {
if (this.que[i].inProgress == false && this.que[i].taskEntities[j].priority === ThumbnailLoadingPriority.high) {
return this.que[i];
}
}
}
for (let i = 0; i < this.que.length; i++) {
for (let j = 0; j < this.que[i].taskEntities.length; j++) {
if (this.que[i].inProgress == false && this.que[i].taskEntities[j].priority === ThumbnailLoadingPriority.medium) {
return this.que[i];
}
}
}
2016-06-17 06:05:31 +08:00
for (let i = 0; i < this.que.length; i++) {
if (this.que[i].inProgress == false) {
return this.que[i];
}
}
return null;
2016-06-17 06:05:31 +08:00
}
2016-12-27 06:36:38 +08:00
private taskReady(task: ThumbnailTask) {
let i = this.que.indexOf(task);
if (i == -1) {
if (task.taskEntities.length !== 0) {
console.error("ThumbnailLoader: can't find task to remove");
}
return;
}
this.que.splice(i, 1);
}
2016-06-17 06:05:31 +08:00
run = () => {
2016-06-17 17:25:15 +08:00
if (this.que.length === 0 || this.runningRequests >= Config.Client.concurrentThumbnailGenerations) {
2016-06-17 06:05:31 +08:00
return;
}
let task = this.getNextTask();
if (task === null) {
return;
}
2016-06-17 17:25:15 +08:00
this.runningRequests++;
2016-12-27 06:36:38 +08:00
task.taskEntities.forEach(te => te.listener.onStartedLoading());
2016-06-24 04:25:16 +08:00
task.inProgress = true;
2016-06-17 06:05:31 +08:00
let curImg = new Image();
2016-06-24 04:25:16 +08:00
curImg.onload = () => {
2017-03-20 07:01:41 +08:00
task.photo.thumbnailLoaded();
this.galleryChacheService.photoUpdated(task.photo.photo);
2016-12-27 06:36:38 +08:00
task.taskEntities.forEach((te: ThumbnailTaskEntity) => te.listener.onLoad());
2016-06-24 04:25:16 +08:00
this.taskReady(task);
2016-06-17 17:25:15 +08:00
this.runningRequests--;
2016-06-17 06:05:31 +08:00
this.run();
};
2016-06-24 04:25:16 +08:00
curImg.onerror = (error) => {
2016-12-27 06:36:38 +08:00
task.taskEntities.forEach((te: ThumbnailTaskEntity) => te.listener.onError(error));
2016-06-24 04:25:16 +08:00
this.taskReady(task);
2016-06-17 17:25:15 +08:00
this.runningRequests--;
2016-06-17 06:05:31 +08:00
this.run();
};
2017-03-20 07:01:41 +08:00
curImg.src = task.photo.getThumbnailPath();
};
}
2016-06-17 06:05:31 +08:00
export interface ThumbnailLoadingListener {
2016-12-27 06:36:38 +08:00
onStartedLoading: () => void;
onLoad: () => void;
onError: (error: any) => void;
}
export interface ThumbnailTaskEntity {
2016-12-27 06:36:38 +08:00
priority: ThumbnailLoadingPriority;
listener: ThumbnailLoadingListener;
2016-06-17 06:05:31 +08:00
}
interface ThumbnailTask {
2017-03-20 07:01:41 +08:00
photo: Photo;
2016-12-27 06:36:38 +08:00
inProgress: boolean;
taskEntities: Array<ThumbnailTaskEntity>;
2016-06-17 06:05:31 +08:00
}