diff --git a/client/src/app/site/services/autoupdate/autoupdate.service.ts b/client/src/app/site/services/autoupdate/autoupdate.service.ts index 1c044fcdc3..c8a6cecf66 100644 --- a/client/src/app/site/services/autoupdate/autoupdate.service.ts +++ b/client/src/app/site/services/autoupdate/autoupdate.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@angular/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; -import { filter, firstValueFrom, fromEvent } from 'rxjs'; import { ModelRequest } from 'src/app/domain/interfaces/model-request'; import { Collection, Id, Ids } from '../../../domain/definitions/key-types'; @@ -11,6 +10,7 @@ import { Mutex } from '../../../infrastructure/utils/promises'; import { BannerDefinition, BannerService } from '../../modules/site-wrapper/services/banner.service'; import { ModelRequestObject } from '../model-request-builder'; import { ViewModelStoreUpdateService } from '../view-model-store-update.service'; +import { WindowVisibilityService } from '../window-visibility.service'; import { AutoupdateCommunicationService } from './autoupdate-communication.service'; import { autoupdateFormatToModelData, AutoupdateModelData, ModelData } from './utils'; @@ -66,6 +66,8 @@ export const OUT_OF_SYNC_BANNER: BannerDefinition = { icon: `sync_disabled` }; +const PAUSE_ON_INACTIVITY_TIMEOUT = 5 * 60 * 1000; // 5 Minutes + @Injectable({ providedIn: `root` }) @@ -79,7 +81,8 @@ export class AutoupdateService { private httpEndpointService: HttpStreamEndpointService, private viewmodelStoreUpdate: ViewModelStoreUpdateService, private communication: AutoupdateCommunicationService, - private bannerService: BannerService + private bannerService: BannerService, + private visibilityService: WindowVisibilityService ) { this.setAutoupdateConfig(null); this.httpEndpointService.registerEndpoint( @@ -94,6 +97,9 @@ export class AutoupdateService { this.communication.listenShouldReconnect().subscribe(() => { this.pauseUntilVisible(); }); + this.visibilityService.hiddenFor(PAUSE_ON_INACTIVITY_TIMEOUT).subscribe(() => { + this.pauseUntilVisible(); + }); window.addEventListener(`beforeunload`, () => { for (const id of Object.keys(this._activeRequestObjects)) { @@ -120,11 +126,7 @@ export class AutoupdateService { modelSubscription.close(); } - if (document.visibilityState !== `visible`) { - await firstValueFrom( - fromEvent(document, `visibilitychange`).pipe(filter(() => document.visibilityState === `visible`)) - ); - } + await this.visibilityService.waitUntilVisible(); const openRequests = []; for (const reqData of pausedRequests) { diff --git a/client/src/app/site/services/window-visibility.service.ts b/client/src/app/site/services/window-visibility.service.ts new file mode 100644 index 0000000000..f2e3cb7450 --- /dev/null +++ b/client/src/app/site/services/window-visibility.service.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { debounceTime, filter, firstValueFrom, fromEvent, map, Observable } from 'rxjs'; + +@Injectable({ + providedIn: `root` +}) +export class WindowVisibilityService { + public constructor() {} + + public async waitUntilVisible(): Promise { + if (document.visibilityState !== `visible`) { + await firstValueFrom( + fromEvent(document, `visibilitychange`).pipe(filter(() => document.visibilityState === `visible`)) + ); + } + } + + public hiddenFor(ms: number): Observable { + return fromEvent(document, `visibilitychange`).pipe( + debounceTime(ms), + filter(() => document.visibilityState === `hidden`), + map(() => {}) + ); + } +}