2018-03-31 03:30:30 +08:00
|
|
|
import {Injectable} from '@angular/core';
|
2019-03-03 17:30:12 +08:00
|
|
|
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';
|
2018-03-31 03:30:30 +08:00
|
|
|
import {GalleryCacheService} from './cache.gallery.service';
|
2018-05-23 08:27:07 +08:00
|
|
|
import {BehaviorSubject} from 'rxjs';
|
2019-03-03 17:30:12 +08:00
|
|
|
import {SharingDTO} from '../../../../common/entities/SharingDTO';
|
|
|
|
import {Config} from '../../../../common/config/public/Config';
|
2018-03-31 03:30:30 +08:00
|
|
|
import {ShareService} from './share.service';
|
2019-03-03 17:30:12 +08:00
|
|
|
import {NavigationService} from '../../model/navigation.service';
|
|
|
|
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
|
|
|
import {QueryParams} from '../../../../common/QueryParams';
|
2018-05-29 02:03:12 +08:00
|
|
|
|
2016-03-20 23:54:30 +08:00
|
|
|
|
|
|
|
@Injectable()
|
2016-05-09 23:04:56 +08:00
|
|
|
export class GalleryService {
|
2016-05-05 23:51:51 +08:00
|
|
|
|
2017-06-21 19:47:21 +08:00
|
|
|
public content: BehaviorSubject<ContentWrapper>;
|
2018-05-29 02:03:12 +08:00
|
|
|
public sorting: BehaviorSubject<SortingMethods>;
|
2019-02-23 06:39:01 +08:00
|
|
|
lastRequest: { directory: string } = {
|
|
|
|
directory: null
|
|
|
|
};
|
2017-06-11 04:32:56 +08:00
|
|
|
private lastDirectory: DirectoryDTO;
|
|
|
|
private searchId: any;
|
2018-12-05 04:43:07 +08:00
|
|
|
private ongoingSearch: {
|
|
|
|
text: string,
|
|
|
|
type: SearchTypes
|
|
|
|
} = null;
|
|
|
|
private ongoingInstantSearch: {
|
|
|
|
text: string,
|
|
|
|
type: SearchTypes
|
|
|
|
} = null;
|
|
|
|
private runInstantSearchFor: string;
|
2017-06-11 04:32:56 +08:00
|
|
|
|
2017-07-04 01:17:49 +08:00
|
|
|
constructor(private networkService: NetworkService,
|
|
|
|
private galleryCacheService: GalleryCacheService,
|
2018-05-27 09:44:32 +08:00
|
|
|
private _shareService: ShareService,
|
2018-12-06 00:29:33 +08:00
|
|
|
private navigationService: NavigationService) {
|
2017-06-21 19:47:21 +08:00
|
|
|
this.content = new BehaviorSubject<ContentWrapper>(new ContentWrapper());
|
2018-11-02 23:24:37 +08:00
|
|
|
this.sorting = new BehaviorSubject<SortingMethods>(Config.Client.Other.defaultPhotoSortingMethod);
|
2017-06-11 04:32:56 +08:00
|
|
|
}
|
|
|
|
|
2018-05-29 02:03:12 +08:00
|
|
|
setSorting(sorting: SortingMethods): void {
|
|
|
|
this.sorting.next(sorting);
|
2018-12-20 06:14:33 +08:00
|
|
|
if (this.content.value.directory) {
|
|
|
|
if (sorting !== Config.Client.Other.defaultPhotoSortingMethod) {
|
|
|
|
this.galleryCacheService.setSorting(this.content.value.directory, sorting);
|
|
|
|
} else {
|
|
|
|
this.galleryCacheService.removeSorting(this.content.value.directory);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
setContent(content: ContentWrapper): void {
|
|
|
|
this.content.next(content);
|
|
|
|
if (content.directory) {
|
|
|
|
const sort = this.galleryCacheService.getSorting(content.directory);
|
|
|
|
if (sort !== null) {
|
|
|
|
this.sorting.next(sort);
|
|
|
|
} else {
|
|
|
|
this.sorting.next(Config.Client.Other.defaultPhotoSortingMethod);
|
|
|
|
}
|
|
|
|
}
|
2018-05-29 02:03:12 +08:00
|
|
|
}
|
|
|
|
|
2018-12-09 20:59:51 +08:00
|
|
|
|
2018-12-06 00:29:33 +08:00
|
|
|
public async loadDirectory(directoryName: string): Promise<void> {
|
2017-06-21 19:47:21 +08:00
|
|
|
const content = new ContentWrapper();
|
2017-06-11 04:32:56 +08:00
|
|
|
|
2017-06-21 19:47:21 +08:00
|
|
|
content.directory = this.galleryCacheService.getDirectory(directoryName);
|
|
|
|
content.searchResult = null;
|
|
|
|
|
2018-11-30 22:36:42 +08:00
|
|
|
|
2018-12-20 06:14:33 +08:00
|
|
|
this.setContent(content);
|
2017-06-11 04:32:56 +08:00
|
|
|
this.lastRequest.directory = directoryName;
|
|
|
|
|
2018-11-29 06:49:33 +08:00
|
|
|
const params: { [key: string]: any } = {};
|
2018-05-13 00:19:51 +08:00
|
|
|
if (Config.Client.Sharing.enabled === true) {
|
2017-07-04 01:17:49 +08:00
|
|
|
if (this._shareService.isSharing()) {
|
2018-11-30 22:36:42 +08:00
|
|
|
params[QueryParams.gallery.sharingKey_short] = this._shareService.getSharingKey();
|
2017-07-04 01:17:49 +08:00
|
|
|
}
|
|
|
|
}
|
2017-07-08 06:18:24 +08:00
|
|
|
|
2017-07-22 01:14:22 +08:00
|
|
|
if (content.directory && content.directory.lastModified && content.directory.lastScanned &&
|
|
|
|
!content.directory.isPartial) {
|
2018-12-09 19:02:02 +08:00
|
|
|
params[QueryParams.gallery.knownLastModified] = content.directory.lastModified;
|
|
|
|
params[QueryParams.gallery.knownLastScanned] = content.directory.lastScanned;
|
2017-07-04 01:17:49 +08:00
|
|
|
}
|
2017-06-11 04:32:56 +08:00
|
|
|
|
2018-12-06 00:29:33 +08:00
|
|
|
try {
|
|
|
|
const cw = await this.networkService.getJson<ContentWrapper>('/gallery/content/' + directoryName, params);
|
2017-07-20 02:47:09 +08:00
|
|
|
|
|
|
|
|
2018-05-27 09:44:32 +08:00
|
|
|
if (!cw || cw.notModified === true) {
|
|
|
|
return;
|
|
|
|
}
|
2017-06-11 04:32:56 +08:00
|
|
|
|
2018-05-27 09:44:32 +08:00
|
|
|
this.galleryCacheService.setDirectory(cw.directory); // save it before adding references
|
2017-03-18 07:11:53 +08:00
|
|
|
|
2018-05-27 09:44:32 +08:00
|
|
|
if (this.lastRequest.directory !== directoryName) {
|
|
|
|
return;
|
|
|
|
}
|
2016-05-10 01:14:33 +08:00
|
|
|
|
2018-05-27 09:44:32 +08:00
|
|
|
DirectoryDTO.addReferences(<DirectoryDTO>cw.directory);
|
2017-06-21 19:47:21 +08:00
|
|
|
|
2018-05-27 09:44:32 +08:00
|
|
|
this.lastDirectory = <DirectoryDTO>cw.directory;
|
2018-12-20 06:14:33 +08:00
|
|
|
this.setContent(cw);
|
2018-12-06 00:29:33 +08:00
|
|
|
} catch (e) {
|
2018-11-30 22:36:42 +08:00
|
|
|
console.error(e);
|
2018-12-05 04:43:07 +08:00
|
|
|
this.navigationService.toGallery().catch(console.error);
|
2018-12-06 00:29:33 +08:00
|
|
|
}
|
2017-06-11 04:32:56 +08:00
|
|
|
}
|
|
|
|
|
2018-12-05 04:43:07 +08:00
|
|
|
public async search(text: string, type?: SearchTypes): Promise<void> {
|
2017-07-30 15:06:12 +08:00
|
|
|
if (this.searchId != null) {
|
|
|
|
clearTimeout(this.searchId);
|
|
|
|
}
|
2018-05-13 00:19:51 +08:00
|
|
|
if (text === null || text === '' || text.trim() === '.') {
|
2018-03-31 03:30:30 +08:00
|
|
|
return null;
|
2017-06-11 04:32:56 +08:00
|
|
|
}
|
2016-05-16 17:03:11 +08:00
|
|
|
|
2018-12-05 04:43:07 +08:00
|
|
|
this.ongoingSearch = {text: text, type: type};
|
|
|
|
|
|
|
|
|
2018-12-20 06:14:33 +08:00
|
|
|
this.setContent(new ContentWrapper());
|
2017-07-30 15:06:12 +08:00
|
|
|
const cw = new ContentWrapper();
|
|
|
|
cw.searchResult = this.galleryCacheService.getSearch(text, type);
|
|
|
|
if (cw.searchResult == null) {
|
2018-12-05 04:43:07 +08:00
|
|
|
if (this.runInstantSearchFor === text && !type) {
|
|
|
|
await this.instantSearch(text, type);
|
|
|
|
return;
|
|
|
|
}
|
2019-02-16 00:47:09 +08:00
|
|
|
const params: { [key: string]: any } = {};
|
2018-12-05 04:43:07 +08:00
|
|
|
if (typeof type !== 'undefined' && type !== null) {
|
2019-02-16 00:47:09 +08:00
|
|
|
params[QueryParams.gallery.search.type] = type;
|
2017-07-30 15:06:12 +08:00
|
|
|
}
|
2018-03-31 03:30:30 +08:00
|
|
|
cw.searchResult = (await this.networkService.getJson<ContentWrapper>('/search/' + text, params)).searchResult;
|
2018-12-05 04:43:07 +08:00
|
|
|
if (this.ongoingSearch &&
|
|
|
|
(this.ongoingSearch.text !== text || this.ongoingSearch.type !== type)) {
|
|
|
|
return;
|
|
|
|
}
|
2017-07-30 15:06:12 +08:00
|
|
|
this.galleryCacheService.setSearch(text, type, cw.searchResult);
|
|
|
|
}
|
2018-12-20 06:14:33 +08:00
|
|
|
this.setContent(cw);
|
2017-06-11 04:32:56 +08:00
|
|
|
}
|
|
|
|
|
2018-12-05 04:43:07 +08:00
|
|
|
public async instantSearch(text: string, type?: SearchTypes): Promise<ContentWrapper> {
|
2018-05-13 00:19:51 +08:00
|
|
|
if (text === null || text === '' || text.trim() === '.') {
|
2017-07-30 15:06:12 +08:00
|
|
|
const content = new ContentWrapper(this.lastDirectory);
|
2018-12-20 06:14:33 +08:00
|
|
|
this.setContent(content);
|
2017-07-30 15:06:12 +08:00
|
|
|
if (this.searchId != null) {
|
|
|
|
clearTimeout(this.searchId);
|
|
|
|
}
|
|
|
|
if (!this.lastDirectory) {
|
2018-12-06 00:29:33 +08:00
|
|
|
this.loadDirectory('/').catch(console.error);
|
2017-07-30 15:06:12 +08:00
|
|
|
}
|
2018-03-31 03:30:30 +08:00
|
|
|
return null;
|
2017-06-11 04:32:56 +08:00
|
|
|
}
|
2016-05-10 03:43:52 +08:00
|
|
|
|
2017-06-11 04:32:56 +08:00
|
|
|
if (this.searchId != null) {
|
|
|
|
clearTimeout(this.searchId);
|
|
|
|
}
|
2018-12-05 04:43:07 +08:00
|
|
|
this.runInstantSearchFor = null;
|
|
|
|
this.ongoingInstantSearch = {text: text, type: type};
|
2017-06-11 04:32:56 +08:00
|
|
|
|
2017-07-30 15:06:12 +08:00
|
|
|
|
|
|
|
const cw = new ContentWrapper();
|
|
|
|
cw.directory = null;
|
|
|
|
cw.searchResult = this.galleryCacheService.getSearch(text);
|
|
|
|
if (cw.searchResult == null) {
|
2018-12-05 04:43:07 +08:00
|
|
|
// If result is not search cache, try to load more
|
2017-07-30 15:06:12 +08:00
|
|
|
this.searchId = setTimeout(() => {
|
2018-12-06 00:29:33 +08:00
|
|
|
this.search(text, type).catch(console.error);
|
2017-07-30 15:06:12 +08:00
|
|
|
this.searchId = null;
|
|
|
|
}, Config.Client.Search.InstantSearchTimeout);
|
|
|
|
|
|
|
|
cw.searchResult = this.galleryCacheService.getInstantSearch(text);
|
|
|
|
|
|
|
|
if (cw.searchResult == null) {
|
2018-03-31 03:30:30 +08:00
|
|
|
cw.searchResult = (await this.networkService.getJson<ContentWrapper>('/instant-search/' + text)).searchResult;
|
2018-12-05 04:43:07 +08:00
|
|
|
if (this.ongoingInstantSearch &&
|
|
|
|
(this.ongoingInstantSearch.text !== text || this.ongoingInstantSearch.type !== type)) {
|
|
|
|
return;
|
|
|
|
}
|
2017-07-30 15:06:12 +08:00
|
|
|
this.galleryCacheService.setInstantSearch(text, cw.searchResult);
|
|
|
|
}
|
|
|
|
}
|
2018-12-20 06:14:33 +08:00
|
|
|
this.setContent(cw);
|
2017-07-30 15:06:12 +08:00
|
|
|
|
2018-05-13 00:19:51 +08:00
|
|
|
// if instant search do not have a result, do not do a search
|
2018-11-05 02:28:32 +08:00
|
|
|
if (cw.searchResult.media.length === 0 && cw.searchResult.directories.length === 0) {
|
2017-07-30 15:06:12 +08:00
|
|
|
if (this.searchId != null) {
|
|
|
|
clearTimeout(this.searchId);
|
|
|
|
}
|
|
|
|
}
|
2017-07-04 01:17:49 +08:00
|
|
|
return cw;
|
|
|
|
|
|
|
|
}
|
2016-05-10 03:43:52 +08:00
|
|
|
|
2017-07-04 01:17:49 +08:00
|
|
|
public async getSharing(sharingKey: string): Promise<SharingDTO> {
|
2018-03-31 03:30:30 +08:00
|
|
|
return this.networkService.getJson<SharingDTO>('/share/' + sharingKey);
|
2017-06-11 04:32:56 +08:00
|
|
|
}
|
2016-03-20 23:54:30 +08:00
|
|
|
|
2018-12-05 04:43:07 +08:00
|
|
|
|
|
|
|
isSearchResult(): boolean {
|
|
|
|
return !!this.content.value.searchResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
runInstantSearch(searchText: string) {
|
|
|
|
this.runInstantSearchFor = searchText;
|
|
|
|
}
|
2016-03-20 23:54:30 +08:00
|
|
|
}
|