release nouri 0.5.0 shopping rhythm pwa and reminders
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
(() => {
|
||||
const getCsrfToken = () => {
|
||||
const meta = document.querySelector('meta[name="csrf-token"]');
|
||||
return meta ? meta.getAttribute("content") : "";
|
||||
};
|
||||
|
||||
const getPushPublicKey = () => {
|
||||
const meta = document.querySelector('meta[name="nouri-push-public-key"]');
|
||||
return meta ? meta.getAttribute("content") : "";
|
||||
};
|
||||
|
||||
const urlBase64ToUint8Array = (base64String) => {
|
||||
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
|
||||
const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
|
||||
const rawData = window.atob(base64);
|
||||
return Uint8Array.from([...rawData].map((character) => character.charCodeAt(0)));
|
||||
};
|
||||
|
||||
const registerServiceWorker = async () => {
|
||||
if (!("serviceWorker" in navigator)) return null;
|
||||
return navigator.serviceWorker.register("/service-worker.js");
|
||||
};
|
||||
|
||||
const subscribeToPush = async () => {
|
||||
const publicKey = getPushPublicKey();
|
||||
if (!publicKey || !("serviceWorker" in navigator) || !("PushManager" in window)) return;
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
const permission = await Notification.requestPermission();
|
||||
if (permission !== "granted") return;
|
||||
|
||||
const existing = await registration.pushManager.getSubscription();
|
||||
const subscription = existing || await registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: urlBase64ToUint8Array(publicKey),
|
||||
});
|
||||
const subscriptionJson = subscription.toJSON();
|
||||
const payload = new URLSearchParams({
|
||||
csrf_token: getCsrfToken(),
|
||||
endpoint: subscription.endpoint,
|
||||
p256dh: subscriptionJson.keys && subscriptionJson.keys.p256dh ? subscriptionJson.keys.p256dh : "",
|
||||
auth: subscriptionJson.keys && subscriptionJson.keys.auth ? subscriptionJson.keys.auth : "",
|
||||
});
|
||||
await fetch("/push/subscribe", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
},
|
||||
body: payload.toString(),
|
||||
});
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
const unsubscribeFromPush = async () => {
|
||||
if (!("serviceWorker" in navigator)) return;
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
const subscription = await registration.pushManager.getSubscription();
|
||||
const payload = new URLSearchParams({ csrf_token: getCsrfToken() });
|
||||
if (subscription) {
|
||||
payload.set("endpoint", subscription.endpoint);
|
||||
await subscription.unsubscribe();
|
||||
}
|
||||
await fetch("/push/unsubscribe", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
},
|
||||
body: payload.toString(),
|
||||
});
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
registerServiceWorker();
|
||||
|
||||
const enableButton = document.querySelector("[data-push-enable]");
|
||||
const disableButton = document.querySelector("[data-push-disable]");
|
||||
|
||||
if (enableButton) {
|
||||
enableButton.addEventListener("click", () => {
|
||||
subscribeToPush().catch(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (disableButton) {
|
||||
disableButton.addEventListener("click", () => {
|
||||
unsubscribeFromPush().catch(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user