1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2024-11-03 21:04:03 +08:00
pigallery2/frontend/app/duplicates/duplicates.component.ts
2019-01-19 17:31:36 +01:00

133 lines
4.3 KiB
TypeScript

import {Component, HostListener, OnDestroy} from '@angular/core';
import {DuplicateService} from './duplicates.service';
import {Utils} from '../../../common/Utils';
import {QueryService} from '../model/query.service';
import {DuplicatesDTO} from '../../../common/entities/DuplicatesDTO';
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
import {Subscription} from 'rxjs';
import {Config} from '../../../common/config/public/Config';
import {PageHelper} from '../model/page.helper';
interface GroupedDuplicate {
name: string;
duplicates: DuplicatesDTO[];
}
@Component({
selector: 'app-duplicate',
templateUrl: './duplicates.component.html',
styleUrls: ['./duplicates.component.css']
})
export class DuplicateComponent implements OnDestroy {
directoryGroups: GroupedDuplicate[] = null;
renderedDirGroups: GroupedDuplicate[] = null;
renderedIndex = {
group: -1,
pairs: 0
};
subscription: Subscription;
renderTimer: number = null;
duplicateCount = {
pairs: 0,
photos: 0
};
constructor(public _duplicateService: DuplicateService,
public queryService: QueryService) {
this._duplicateService.getDuplicates().catch(console.error);
this.subscription = this._duplicateService.duplicates.subscribe((duplicates: DuplicatesDTO[]) => {
this.directoryGroups = [];
this.renderedIndex = {group: -1, pairs: 0};
this.renderedDirGroups = [];
this.duplicateCount = {
pairs: 0,
photos: 0
};
if (duplicates === null) {
return;
}
this.duplicateCount.photos = duplicates.reduce((prev: number, curr) => prev + curr.media.length, 0);
this.duplicateCount.pairs = duplicates.length;
const getMostFrequentDir = (dupls: DuplicatesDTO[]) => {
if (dupls.length === 0) {
return null;
}
const dirFrequency: { [key: number]: { count: number, dir: DirectoryDTO } } = {};
dupls.forEach(d => d.media.forEach(m => {
dirFrequency[m.directory.id] = dirFrequency[m.directory.id] || {dir: m.directory, count: 0};
dirFrequency[m.directory.id].count++;
}));
let max: { count: number, dir: DirectoryDTO } = {count: -1, dir: null};
for (const freq of Object.values(dirFrequency)) {
if (max.count <= freq.count) {
max = freq;
}
}
return max.dir;
};
while (duplicates.length > 0) {
const dir = getMostFrequentDir(duplicates);
const group = duplicates.filter(d => d.media.find(m => m.directory.id === dir.id));
duplicates = duplicates.filter(d => !d.media.find(m => m.directory.id === dir.id));
this.directoryGroups.push({name: this.getDirectoryPath(dir) + ' (' + group.length + ')', duplicates: group});
}
this.renderMore();
});
}
ngOnDestroy(): void {
if (this.subscription) {
this.subscription.unsubscribe();
this.subscription = null;
}
}
getDirectoryPath(directory: DirectoryDTO) {
return Utils.concatUrls(directory.path, directory.name);
}
renderMore = () => {
if (this.renderTimer !== null) {
clearTimeout(this.renderTimer);
this.renderTimer = null;
}
if (this.renderedIndex.group === this.directoryGroups.length - 1 &&
this.renderedIndex.pairs >=
this.directoryGroups[this.renderedIndex.group].duplicates.length) {
return;
}
if (this.shouldRenderMore()) {
if (this.renderedDirGroups.length === 0 ||
this.renderedIndex.pairs >=
this.directoryGroups[this.renderedIndex.group].duplicates.length) {
this.renderedDirGroups.push({
name: this.directoryGroups[++this.renderedIndex.group].name,
duplicates: []
});
this.renderedIndex.pairs = 0;
}
this.renderedDirGroups[this.renderedDirGroups.length - 1].duplicates
.push(this.directoryGroups[this.renderedIndex.group].duplicates[this.renderedIndex.pairs++]);
this.renderTimer = window.setTimeout(this.renderMore, 0);
}
};
@HostListener('window:scroll')
onScroll() {
this.renderMore();
}
private shouldRenderMore(): boolean {
return Config.Client.Other.enableOnScrollRendering === false ||
PageHelper.ScrollY >= PageHelper.MaxScrollY * 0.7
|| (document.body.clientHeight) * 0.85 < window.innerHeight;
}
}