forked from retoor/devplacepy
- 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
81 lines
2.6 KiB
JavaScript
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,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|