1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2024-11-03 21:04:03 +08:00
pigallery2/frontend/app/gallery/gallery.service.ts
Patrik J. Braun 609c788d91 improving API performance by removing null properties
adding photo caption reading
2018-12-05 17:29:33 +01:00

197 lines
6.4 KiB
TypeScript

import {Injectable} from '@angular/core';
import {NetworkService} from '../model/network/network.service';
import {ContentWrapper} from '../../../common/entities/ConentWrapper';
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
import {SearchTypes} from '../../../common/entities/AutoCompleteItem';
import {GalleryCacheService} from './cache.gallery.service';
import {BehaviorSubject} from 'rxjs';
import {SharingDTO} from '../../../common/entities/SharingDTO';
import {Config} from '../../../common/config/public/Config';
import {ShareService} from './share.service';
import {NavigationService} from '../model/navigation.service';
import {SortingMethods} from '../../../common/entities/SortingMethods';
import {QueryService} from '../model/query.service';
import {QueryParams} from '../../../common/QueryParams';
@Injectable()
export class GalleryService {
public content: BehaviorSubject<ContentWrapper>;
public sorting: BehaviorSubject<SortingMethods>;
private lastDirectory: DirectoryDTO;
private searchId: any;
private ongoingSearch: {
text: string,
type: SearchTypes
} = null;
private ongoingInstantSearch: {
text: string,
type: SearchTypes
} = null;
private runInstantSearchFor: string;
constructor(private networkService: NetworkService,
private galleryCacheService: GalleryCacheService,
private _shareService: ShareService,
private navigationService: NavigationService) {
this.content = new BehaviorSubject<ContentWrapper>(new ContentWrapper());
this.sorting = new BehaviorSubject<SortingMethods>(Config.Client.Other.defaultPhotoSortingMethod);
}
lastRequest: { directory: string } = {
directory: null
};
setSorting(sorting: SortingMethods): void {
this.sorting.next(sorting);
}
public async loadDirectory(directoryName: string): Promise<void> {
const content = new ContentWrapper();
content.directory = this.galleryCacheService.getDirectory(directoryName);
content.searchResult = null;
this.content.next(content);
this.lastRequest.directory = directoryName;
const params: { [key: string]: any } = {};
if (Config.Client.Sharing.enabled === true) {
if (this._shareService.isSharing()) {
params[QueryParams.gallery.sharingKey_short] = this._shareService.getSharingKey();
}
}
if (content.directory && content.directory.lastModified && content.directory.lastScanned &&
!content.directory.isPartial) {
params['knownLastModified'] = content.directory.lastModified;
params['knownLastScanned'] = content.directory.lastScanned;
}
try {
const cw = await this.networkService.getJson<ContentWrapper>('/gallery/content/' + directoryName, params);
if (!cw || cw.notModified === true) {
return;
}
this.galleryCacheService.setDirectory(cw.directory); // save it before adding references
if (this.lastRequest.directory !== directoryName) {
return;
}
DirectoryDTO.addReferences(<DirectoryDTO>cw.directory);
this.lastDirectory = <DirectoryDTO>cw.directory;
this.content.next(cw);
} catch (e) {
console.error(e);
this.navigationService.toGallery().catch(console.error);
}
}
public async search(text: string, type?: SearchTypes): Promise<void> {
if (this.searchId != null) {
clearTimeout(this.searchId);
}
if (text === null || text === '' || text.trim() === '.') {
return null;
}
this.ongoingSearch = {text: text, type: type};
this.content.next(new ContentWrapper());
const cw = new ContentWrapper();
cw.searchResult = this.galleryCacheService.getSearch(text, type);
if (cw.searchResult == null) {
if (this.runInstantSearchFor === text && !type) {
await this.instantSearch(text, type);
return;
}
const params: { type?: SearchTypes } = {};
if (typeof type !== 'undefined' && type !== null) {
params['type'] = type;
}
cw.searchResult = (await this.networkService.getJson<ContentWrapper>('/search/' + text, params)).searchResult;
if (this.ongoingSearch &&
(this.ongoingSearch.text !== text || this.ongoingSearch.type !== type)) {
return;
}
this.galleryCacheService.setSearch(text, type, cw.searchResult);
}
this.content.next(cw);
}
public async instantSearch(text: string, type?: SearchTypes): Promise<ContentWrapper> {
if (text === null || text === '' || text.trim() === '.') {
const content = new ContentWrapper(this.lastDirectory);
this.content.next(content);
if (this.searchId != null) {
clearTimeout(this.searchId);
}
if (!this.lastDirectory) {
this.loadDirectory('/').catch(console.error);
}
return null;
}
if (this.searchId != null) {
clearTimeout(this.searchId);
}
this.runInstantSearchFor = null;
this.ongoingInstantSearch = {text: text, type: type};
const cw = new ContentWrapper();
cw.directory = null;
cw.searchResult = this.galleryCacheService.getSearch(text);
if (cw.searchResult == null) {
// If result is not search cache, try to load more
this.searchId = setTimeout(() => {
this.search(text, type).catch(console.error);
this.searchId = null;
}, Config.Client.Search.InstantSearchTimeout);
cw.searchResult = this.galleryCacheService.getInstantSearch(text);
if (cw.searchResult == null) {
cw.searchResult = (await this.networkService.getJson<ContentWrapper>('/instant-search/' + text)).searchResult;
if (this.ongoingInstantSearch &&
(this.ongoingInstantSearch.text !== text || this.ongoingInstantSearch.type !== type)) {
return;
}
this.galleryCacheService.setInstantSearch(text, cw.searchResult);
}
}
this.content.next(cw);
// if instant search do not have a result, do not do a search
if (cw.searchResult.media.length === 0 && cw.searchResult.directories.length === 0) {
if (this.searchId != null) {
clearTimeout(this.searchId);
}
}
return cw;
}
public async getSharing(sharingKey: string): Promise<SharingDTO> {
return this.networkService.getJson<SharingDTO>('/share/' + sharingKey);
}
isSearchResult(): boolean {
return !!this.content.value.searchResult;
}
runInstantSearch(searchText: string) {
this.runInstantSearchFor = searchText;
}
}