mirror of
https://github.com/xuthus83/pigallery2.git
synced 2024-11-03 21:04:03 +08:00
168 lines
4.4 KiB
TypeScript
168 lines
4.4 KiB
TypeScript
///<reference path="../../../browser.d.ts"/>
|
|
|
|
import {Injectable} from "@angular/core";
|
|
import {GridPhoto} from "./GridPhoto";
|
|
import {Config} from "../../config/Config";
|
|
import {GalleryCacheService} from "../cache.gallery.service";
|
|
|
|
export enum ThumbnailLoadingPriority{
|
|
high, medium, low
|
|
}
|
|
|
|
@Injectable()
|
|
export class ThumbnailLoaderService {
|
|
|
|
que:Array<ThumbnailTask> = [];
|
|
runningRequests:number = 0;
|
|
|
|
constructor(private galleryChacheService:GalleryCacheService) {
|
|
}
|
|
|
|
removeTasks() {
|
|
this.que = [];
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
loadImage(gridPhoto:GridPhoto, priority:ThumbnailLoadingPriority, listener:ThumbnailLoadingListener):ThumbnailTaskEntity {
|
|
|
|
let tmp:ThumbnailTask = null;
|
|
//is image already qued?
|
|
for (let i = 0; i < this.que.length; i++) {
|
|
if (this.que[i].gridPhoto.getThumbnailPath() == gridPhoto.getThumbnailPath()) {
|
|
tmp = this.que[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
let thumbnailTaskEntity = {priority: priority, listener: listener};
|
|
//add to previous
|
|
if (tmp != null) {
|
|
tmp.taskEntities.push(thumbnailTaskEntity);
|
|
if (tmp.inProgress == true) {
|
|
listener.onStartedLoading();
|
|
}
|
|
|
|
|
|
} else {//create new task
|
|
this.que.push({
|
|
gridPhoto: gridPhoto,
|
|
inProgress: false,
|
|
taskEntities: [thumbnailTaskEntity]
|
|
});
|
|
}
|
|
setImmediate(this.run);
|
|
return thumbnailTaskEntity;
|
|
|
|
}
|
|
|
|
|
|
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].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].taskEntities[j].priority === ThumbnailLoadingPriority.medium) {
|
|
return this.que[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return this.que[0];
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
run = () => {
|
|
if (this.que.length === 0 || this.runningRequests >= Config.Client.concurrentThumbnailGenerations) {
|
|
return;
|
|
}
|
|
let task = this.getNextTask();
|
|
|
|
if (task === null) {
|
|
return;
|
|
}
|
|
|
|
this.runningRequests++;
|
|
task.taskEntities.forEach(te=>te.listener.onStartedLoading());
|
|
task.inProgress = true;
|
|
|
|
let curImg = new Image();
|
|
curImg.src = task.gridPhoto.getThumbnailPath();
|
|
|
|
curImg.onload = () => {
|
|
|
|
task.gridPhoto.thumbnailLoaded();
|
|
this.galleryChacheService.photoUpdated(task.gridPhoto.photo);
|
|
task.taskEntities.forEach(te=>te.listener.onLoad());
|
|
|
|
this.taskReady(task);
|
|
this.runningRequests--;
|
|
this.run();
|
|
};
|
|
|
|
curImg.onerror = (error) => {
|
|
task.taskEntities.forEach(te=>te.listener.onError(error));
|
|
|
|
this.taskReady(task);
|
|
this.runningRequests--;
|
|
this.run();
|
|
};
|
|
};
|
|
}
|
|
|
|
|
|
export interface ThumbnailLoadingListener {
|
|
onStartedLoading:()=>void;
|
|
onLoad:()=>void;
|
|
onError:(error)=>void;
|
|
}
|
|
|
|
|
|
export interface ThumbnailTaskEntity {
|
|
|
|
priority:ThumbnailLoadingPriority;
|
|
listener:ThumbnailLoadingListener;
|
|
}
|
|
|
|
interface ThumbnailTask {
|
|
gridPhoto:GridPhoto;
|
|
inProgress:boolean;
|
|
taskEntities:Array<ThumbnailTaskEntity>;
|
|
|
|
}
|