blob: a604321a899afe2f5883f5a983d9ec4a1fd67854 [file] [log] [blame]
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {ParsedChangeInfo} from '../types/types';
import {getReason} from '../utils/attention-set-util';
import {readResponsePayload} from '../elements/shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';
import {filterAttentionChangesAfter} from '../utils/service-worker-util';
import {AccountDetailInfo} from '../api/rest-api';
import {TRIGGER_NOTIFICATION_UPDATES_MS} from '../services/service-worker-installer';
import {GerritView} from '../services/router/router-model';
import {generateUrl} from '../utils/router-util';
export class ServiceWorker {
constructor(private ctx: ServiceWorkerGlobalScope) {}
latestUpdateTimestampMs?: number;
showNotification(change: ParsedChangeInfo, account: AccountDetailInfo) {
const body = getReason(undefined, account, change);
const changeUrl = generateUrl({
view: GerritView.CHANGE,
changeNum: change._number,
project: change.project,
usp: 'service-worker-notification',
});
// We are adding origin because each notification can have different origin
// User can have different service workers for different origins/hosts.
// TODO(milutin): Check if this works properly with getBaseUrl()
const data = {url: `${self.location.origin}${changeUrl}`};
// TODO(milutin): Add gerrit host icon
this.ctx.registration.showNotification(change.subject, {body, data});
}
async getChangesToNotify(account: AccountDetailInfo) {
// 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 [];
}
}
const changes = await this.getLatestAttentionSetChanges();
const latestAttentionChanges = filterAttentionChangesAfter(
changes,
account,
this.latestUpdateTimestampMs
);
this.latestUpdateTimestampMs = Date.now();
return latestAttentionChanges;
}
async getLatestAttentionSetChanges(): Promise<ParsedChangeInfo[]> {
// 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;
return changes ?? [];
}
}