From aa078c4228240a3b9cb7cf2a5b796f3ea5430ba6 Mon Sep 17 00:00:00 2001 From: Vladimir Voronin Date: Wed, 30 Oct 2024 17:36:03 +0300 Subject: [PATCH] chet novoe --- public/service-worker.js | 39 +++++++++++++++++++++++++++++++++++++ src/App.vue | 29 ++++++++++++++++++++++++--- src/main.ts | 21 ++++++++++++++++++++ src/services/pushManager.ts | 17 ++++++++++++++++ 4 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 public/service-worker.js create mode 100644 src/services/pushManager.ts diff --git a/public/service-worker.js b/public/service-worker.js new file mode 100644 index 0000000..ee4dbf6 --- /dev/null +++ b/public/service-worker.js @@ -0,0 +1,39 @@ +// public/service-worker.js + +self.addEventListener("push", (event) => { + const data = event.data.json(); + console.log(data); + const options = { + body: data.url, + icon: "/icon.png", + badge: "/badge.png", + data: data.url + }; + event.waitUntil(self.registration.showNotification(data.title, options)); + // console.log(data); +}); + +self.addEventListener('notificationclick', function (event) { + // console.log("Notification click event received."); // Сообщение об активации обработчика + console.log("Notification data:", event.notification.data); // Проверка данных уведомления + + event.notification.close(); // Закрываем уведомление + // console.log(event) + const targetUrl = event.notification.data && event.notification.data ? event.notification.data : '/'; + // console.log("Target URL to open:", targetUrl); // Выводим URL, который будет открыт + + event.waitUntil( + clients.matchAll({type: 'window', includeUncontrolled: true}).then(clientList => { + for (const client of clientList) { + if (client.url === targetUrl && 'focus' in client) { + // console.log("Focusing on existing client:", client.url); // Сообщение об активации уже открытого клиента + return client.focus(); + } + } + if (clients.openWindow) { + // console.log("Opening new window:", targetUrl); // Сообщение об открытии нового окна + return clients.openWindow(targetUrl); + } + }) + ); +}); diff --git a/src/App.vue b/src/App.vue index 35e98cc..4a62f82 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,15 +2,15 @@
-
@@ -18,6 +18,29 @@ import MenuBar from "./components/MenuBar.vue"; import OverlayView from "@/components/OverlayView.vue"; import ToolBar from "@/components/ToolBar.vue"; +import axiosSetup from "@/services/axiosSetup"; +import {onMounted} from "vue"; +import {subscribeUserToPush} from "@/services/pushManager"; + + +onMounted(async () => { + + try { + const subscription = await subscribeUserToPush(); + console.log("Push subscription:", subscription); + + // Отправка подписки на сервер для хранения + await fetch("http://localhost:8000/api/v1/push/subscribe", { + method: "POST", + headers: {"Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}`}, + body: JSON.stringify(subscription), + }); + } catch (error) { + console.error("Failed to subscribe to push:", error); + } + +}) + // @Options({ // components: { diff --git a/src/main.ts b/src/main.ts index ba495ba..0b678c4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -22,5 +22,26 @@ app.use(PrimeVue, { preset: Aura } }); +// main.js + +if ("serviceWorker" in navigator) { + navigator.serviceWorker.register("/service-worker.js").then((registration) => { + console.log("Service Worker registered with scope:", registration.scope); + }).catch((error) => { + console.error("Service Worker registration failed:", error); + }); +} + + +Notification.requestPermission().then((permission) => { + if (permission === 'granted') { + console.log('Разрешение на уведомления получено.'); + } +}); + +// Компонент Vue 3 или логика подписки + + + app.mount('#app'); \ No newline at end of file diff --git a/src/services/pushManager.ts b/src/services/pushManager.ts new file mode 100644 index 0000000..eb5289f --- /dev/null +++ b/src/services/pushManager.ts @@ -0,0 +1,17 @@ +// src/pushManager.ts +const applicationServerKey = 'BNrBrVdqH4dHz6egI24OEr1WuGi5BPjJ1pznANXoqwdlIYGyt9CAdeOnnMMWqxs1TZt2f0aG1He--Uh5hwFnKts'; + +function urlBase64ToUint8Array(base64String: string): Uint8Array { + const padding = "=".repeat((4 - (base64String.length % 4)) % 4); + const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/"); + const rawData = window.atob(base64); + return new Uint8Array([...rawData].map((char) => char.charCodeAt(0))); +} + +export async function subscribeUserToPush() { + const registration = await navigator.serviceWorker.ready; + return registration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: urlBase64ToUint8Array(applicationServerKey), + }); +}