Add regular polling for checks

Also poll when the document becomes visible.

Change-Id: Ifbcefff82fe1d3fb16ce7e22975ac6f085ca3757
diff --git a/polygerrit-ui/app/services/checks/checks-service.ts b/polygerrit-ui/app/services/checks/checks-service.ts
index 3ce714a..fd1f810 100644
--- a/polygerrit-ui/app/services/checks/checks-service.ts
+++ b/polygerrit-ui/app/services/checks/checks-service.ts
@@ -16,6 +16,7 @@
  */
 
 import {
+  filter,
   switchMap,
   takeWhile,
   throttleTime,
@@ -44,6 +45,7 @@
   Observable,
   of,
   Subject,
+  timer,
 } from 'rxjs';
 import {PatchSetNumber} from '../../types/common';
 
@@ -54,6 +56,8 @@
 
   private checkToPluginMap = new Map<string, string>();
 
+  private readonly documentVisibilityChange$ = new BehaviorSubject(undefined);
+
   constructor() {
     checkToPluginMap$.subscribe(map => {
       this.checkToPluginMap = map;
@@ -61,6 +65,9 @@
     latestPatchNum$.subscribe(num => {
       updateStateSetPatchset(num);
     });
+    document.addEventListener('visibilitychange', () => {
+      this.documentVisibilityChange$.next(undefined);
+    });
   }
 
   setPatchset(num: PatchSetNumber) {
@@ -89,17 +96,25 @@
     this.providers[pluginName] = provider;
     this.reloadSubjects[pluginName] = new BehaviorSubject<void>(undefined);
     updateStateSetProvider(pluginName, config);
-    // Both, changed numbers and and announceUpdate request should trigger.
+    const pollIntervalMs = (config?.fetchPollingIntervalSeconds ?? 60) * 1000;
+    // Various events should trigger fetching checks from the provider:
+    // 1. Change number and patchset number changes.
+    // 2. Specific reload requests.
+    // 3. Regular polling starting with an initial fetch right now.
+    // 4. A hidden Gerrit tab becoming visible.
     combineLatest([
       changeNum$,
       checksPatchsetNumber$,
       this.reloadSubjects[pluginName].pipe(throttleTime(1000)),
+      timer(0, pollIntervalMs),
+      this.documentVisibilityChange$,
     ])
       .pipe(
         takeWhile(_ => !!this.providers[pluginName]),
+        filter(_ => document.visibilityState !== 'hidden'),
         withLatestFrom(change$),
         switchMap(
-          ([[changeNum, patchNum, _], change]): Observable<FetchResponse> => {
+          ([[changeNum, patchNum], change]): Observable<FetchResponse> => {
             if (
               !change ||
               !changeNum ||
@@ -128,6 +143,5 @@
           response.actions
         );
       });
-    this.reload(pluginName);
   }
 }