blob: e2199463d226b11ab381828114c2a48f26e4c3ee [file] [log] [blame]
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {readResponsePayload} from '../elements/shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';
import {
ServiceWorkerMessageType,
TRIGGER_NOTIFICATION_UPDATES_MS,
} from '../services/service-worker-installer';
import {ParsedChangeInfo} from '../types/types';
/**
* `self` is for a worker what `window` is for the web app. It is called
* the `ServiceWorkerGlobalScope`, see
* https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope
*/
const ctx = self as {} as ServiceWorkerGlobalScope;
ctx.addEventListener('message', async event => {
if (event.data?.type !== ServiceWorkerMessageType.TRIGGER_NOTIFICATIONS) {
throw new Error(`Unsupported event type: ${event.data?.type}`);
}
const changes = await serviceWorker.getLatestAttentionSetChange();
// TODO(milutin): Implement handling more than 1 change
if (changes && changes.length > 0) {
serviceWorker.showNotification(changes[0]);
}
});
class ServiceWorker {
latestUpdateTimestampMs?: number;
showNotification(change: ParsedChangeInfo) {
// TODO(milutin): Replace with getReason from attention-set-util.
// For get Reason you will need AccountInfo.
const body = 'Administrator replied on the change';
// TODO(milutin): Implement event.action that
// focus on firstWindowClient and open change there.
// TODO(milutin): Add gerrit host icon
ctx.registration.showNotification(change.subject, {body});
}
async getLatestAttentionSetChange(): Promise<ParsedChangeInfo[]> {
// We throttle polling, since there can be many clients triggerring
// always only one service worker.
if (this.latestUpdateTimestampMs) {
const durationFromLatestUpdateMS =
Date.now() - this.latestUpdateTimestampMs;
if (durationFromLatestUpdateMS < TRIGGER_NOTIFICATION_UPDATES_MS) {
return [];
}
}
this.latestUpdateTimestampMs = Date.now();
// TODO(milutin): Implement more generic query builder
const response = await fetch(
'/changes/?O=1000081&S=0&n=25&q=attention%3Aself'
);
const payload = await readResponsePayload(response);
const changes = payload.parsed as unknown as ParsedChangeInfo[] | undefined;
// TODO(milutin): Filter changes you are already notified about.
return changes ?? [];
}
}
/** Singleton instance being referenced in `onmessage` function above. */
const serviceWorker = new ServiceWorker();