Files
devplacepy/devplacepy/static/js/PushManager.js
T
retoor 244a524b91 feat: add authenticated my-profile endpoint and clean breadcrumb markdown in SEO context
- Add GET /profile route returning own profile page with tab support, backed by new my_profile_page handler in profile/index.py and documented in docs_api.py
- Introduce _clean_breadcrumbs helper in seo.py that strips markdown from breadcrumb names before passing to schema generation
- Skip data-confirm modal for elements with data-auto-submit attribute in ModalManager.js
- Guard PushManager subscription against missing userUid and capture it from document body dataset
- Switch profile bio template from render_title to render_content and use div instead of span for proper block rendering
2026-07-01 13:15:33 +00:00

81 lines
2.6 KiB
JavaScript

// retoor <retoor@molodetz.nl>
import { Http } from "./Http.js";
export class PushManager {
constructor() {
this.supported = "serviceWorker" in navigator && "PushManager" in window && "Notification" in window;
if (!this.supported) {
return;
}
this.userUid = document.body.dataset.userUid || "";
this.triggers = Array.from(document.querySelectorAll("[data-push-enable]"));
this.bindTriggers();
this.refreshTriggerVisibility();
this.register(true).catch((error) => console.error("Push silent register failed:", error));
}
bindTriggers() {
this.triggers.forEach((trigger) => {
trigger.addEventListener("click", (event) => {
event.preventDefault();
this.optIn();
});
});
}
refreshTriggerVisibility() {
const granted = Notification.permission === "granted";
this.triggers.forEach((trigger) => {
trigger.hidden = granted;
});
}
async optIn() {
const permission = await Notification.requestPermission();
if (permission === "granted") {
await this.register(false);
}
}
async register(silent) {
try {
const registration = await navigator.serviceWorker.register("/service-worker.js");
await registration.update();
await navigator.serviceWorker.ready;
if (Notification.permission !== "granted") {
this.refreshTriggerVisibility();
return;
}
if (!this.userUid) {
return;
}
const keyData = await Http.getJson("/push.json");
const applicationServerKey = Uint8Array.from(atob(keyData.publicKey), (c) => c.charCodeAt(0));
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey,
});
await Http.postJson("/push.json", subscription.toJSON());
this.refreshTriggerVisibility();
} catch (error) {
if (error.status === 401) {
return;
}
console.error("Error registering push notifications:", error);
if (!silent) {
window.app.dialog.alert({
title: "Push notifications",
message: "Enabling push notifications failed. Please check your browser settings and try again.\n\n" + error,
});
}
}
}
}