|
// retoor <retoor@molodetz.nl>
|
|
|
|
import { Http } from "./Http.js";
|
|
import { Poller } from "./Poller.js";
|
|
|
|
export class CounterManager {
|
|
constructor(pubsub) {
|
|
if (!document.querySelector("[data-counter]")) {
|
|
return;
|
|
}
|
|
document.addEventListener("visibilitychange", () => {
|
|
if (document.visibilityState === "visible") {
|
|
this.poll();
|
|
}
|
|
});
|
|
const uid = document.body.dataset.userUid || "";
|
|
if (pubsub && uid) {
|
|
pubsub.subscribe(`user.${uid}.counts`, (data) => this.applyCounts(data));
|
|
}
|
|
this.poller = new Poller(() => this.poll(), 60000, { pauseHidden: true });
|
|
}
|
|
|
|
applyCounts(counts) {
|
|
if (!counts) return;
|
|
this.apply("notifications", counts.notifications);
|
|
this.apply("messages", counts.messages);
|
|
}
|
|
|
|
async poll() {
|
|
let counts;
|
|
try {
|
|
counts = await Http.getJson("/notifications/counts");
|
|
} catch (error) {
|
|
console.error("counter poll failed", error);
|
|
return;
|
|
}
|
|
this.applyCounts(counts);
|
|
}
|
|
|
|
apply(key, count) {
|
|
document.querySelectorAll(`[data-counter="${key}"]`).forEach((target) => {
|
|
const badge = target.querySelector("[data-counter-badge]");
|
|
if (!badge) {
|
|
return;
|
|
}
|
|
badge.textContent = count;
|
|
badge.hidden = count === 0;
|
|
const noun = target.dataset.counterNoun;
|
|
if (noun) {
|
|
const label =
|
|
count > 0
|
|
? `${count} unread ${noun}`
|
|
: `${noun.charAt(0).toUpperCase()}${noun.slice(1)}, no unread`;
|
|
target.setAttribute("aria-label", label);
|
|
}
|
|
});
|
|
}
|
|
}
|