diff --git a/src/frontend/app/ui/gallery/contentLoader.service.ts b/src/frontend/app/ui/gallery/contentLoader.service.ts index aca7ed28..6afb7bd6 100644 --- a/src/frontend/app/ui/gallery/contentLoader.service.ts +++ b/src/frontend/app/ui/gallery/contentLoader.service.ts @@ -3,13 +3,13 @@ import {NetworkService} from '../../model/network/network.service'; import {ContentWrapperUtils, ContentWrapperWithError, PackedContentWrapperWithError} from '../../../../common/entities/ContentWrapper'; import {SubDirectoryDTO,} from '../../../../common/entities/DirectoryDTO'; import {GalleryCacheService} from './cache.gallery.service'; -import {BehaviorSubject, interval, Observable, Subscription} from 'rxjs'; +import {BehaviorSubject, interval, Observable, Subject, Subscription} from 'rxjs'; import {Config} from '../../../../common/config/public/Config'; import {ShareService} from './share.service'; import {NavigationService} from '../../model/navigation.service'; import {QueryParams} from '../../../../common/QueryParams'; import {ErrorCodes} from '../../../../common/entities/Error'; -import {map, skip} from 'rxjs/operators'; +import {map, skip, switchMap} from 'rxjs/operators'; import {MediaDTO} from '../../../../common/entities/MediaDTO'; import {FileDTO} from '../../../../common/entities/FileDTO'; @@ -17,13 +17,10 @@ import {FileDTO} from '../../../../common/entities/FileDTO'; export class ContentLoaderService implements OnDestroy { public content: BehaviorSubject; public originalContent: Observable; - lastRequest: { directory: string } = { - directory: null, - }; - private searchId: number; - private ongoingSearch: string = null; - private currentContentRequest: { type: 'directory' | 'search', value: string } = null; + private ongoingContentRequest: string = null; + private lastContentRequest: { type: 'directory' | 'search', value: string } = null; private pollingTimeSub: Subscription; + private pollingTimerRestart = new Subject(); constructor( private networkService: NetworkService, @@ -51,12 +48,22 @@ export class ContentLoaderService implements OnDestroy { if (!Config.Gallery.AutoUpdate.enable) { return; } - this.pollingTimeSub = interval(1000 * Config.Gallery.AutoUpdate.interval) - .pipe(skip(1)) // do not refresh right away + this.pollingTimeSub = this.pollingTimerRestart + .pipe( + // start a new interval each time pollingTimerRestart emits + switchMap(() => + interval(1000 * Config.Gallery.AutoUpdate.interval).pipe(skip(1)) + ) + ) .subscribe(() => { + if (this.ongoingContentRequest !== null) { + return; + } // do not refresh if another request is ongoing //TODO: optimize this. no need to force reload directory if it's not changed' only dated search results this.reloadCurrentContent().catch(console.error); }); + + this.pollingTimerRestart.next(); // start. } setContent(content: ContentWrapperWithError): void { @@ -72,8 +79,8 @@ export class ContentLoaderService implements OnDestroy { const cw = this.galleryCacheService.getDirectory(directoryName); this.setContent(ContentWrapperUtils.unpack(cw)); - this.lastRequest.directory = directoryName; - this.currentContentRequest = {type: 'directory', value: directoryName}; + this.ongoingContentRequest = directoryName; + this.lastContentRequest = {type: 'directory', value: directoryName}; // prepare server request const params: { [key: string]: unknown } = {}; @@ -103,15 +110,18 @@ export class ContentLoaderService implements OnDestroy { params ); + if (this.ongoingContentRequest !== directoryName) { + return; + } + this.ongoingContentRequest = null; + this.pollingTimerRestart.next(); + if (!cw || cw.notModified === true) { return; } this.galleryCacheService.setDirectory(cw); // save it before adding references - if (this.lastRequest.directory !== directoryName) { - return; - } this.setContent(ContentWrapperUtils.unpack(cw)); } catch (e) { console.error(e); @@ -120,12 +130,9 @@ export class ContentLoaderService implements OnDestroy { } public async search(query: string, forceReload = false): Promise { - if (this.searchId != null) { - clearTimeout(this.searchId); - } - this.ongoingSearch = query; - this.currentContentRequest = {type: 'search', value: query}; + this.ongoingContentRequest = query; + this.lastContentRequest = {type: 'search', value: query}; this.setContent({} as PackedContentWrapperWithError); let cw = this.galleryCacheService.getSearch(JSON.parse(query)); @@ -146,9 +153,11 @@ export class ContentLoaderService implements OnDestroy { } } - if (this.ongoingSearch !== query) { + if (this.ongoingContentRequest !== query) { return; } + this.ongoingContentRequest = null; + this.pollingTimerRestart.next(); this.setContent(ContentWrapperUtils.unpack(cw)); } @@ -158,14 +167,14 @@ export class ContentLoaderService implements OnDestroy { } public async reloadCurrentContent(): Promise { - if (!this.currentContentRequest) { + if (!this.lastContentRequest) { return; } - if (this.currentContentRequest.type === 'directory') { - await this.loadDirectory(this.currentContentRequest.value, true); - } else if (this.currentContentRequest.type === 'search') { - await this.search(this.currentContentRequest.value, true); + if (this.lastContentRequest.type === 'directory') { + await this.loadDirectory(this.lastContentRequest.value, true); + } else if (this.lastContentRequest.type === 'search') { + await this.search(this.lastContentRequest.value, true); } } }