From d57e1569b3e5afc5c9a2d43ebb78074a6f2ddf08 Mon Sep 17 00:00:00 2001 From: Vasilii Mikhailovskii Date: Thu, 5 Dec 2024 21:06:57 +0200 Subject: [PATCH] push notification works --- .gitea/workflows/deploy-app-frontend.yaml | 4 +- apps/frontend/components.d.ts | 1 + apps/frontend/public/service-worker.js | 110 +++++++++------------ apps/frontend/src/App.vue | 35 +++---- apps/frontend/src/manifest.json | 2 +- apps/frontend/src/registerServiceWorker.ts | 56 +++++------ apps/frontend/src/router/index.ts | 15 +-- apps/frontend/vite.config.ts | 9 ++ 8 files changed, 115 insertions(+), 117 deletions(-) diff --git a/.gitea/workflows/deploy-app-frontend.yaml b/.gitea/workflows/deploy-app-frontend.yaml index d78e356..62d1fd0 100644 --- a/.gitea/workflows/deploy-app-frontend.yaml +++ b/.gitea/workflows/deploy-app-frontend.yaml @@ -21,8 +21,8 @@ jobs: VITE_MANIFEST_NAME: НаСвязи VITE_MANIFEST_SHORT_NAME: НаСвязи VITE_MANIFEST_ID: https://hereconnect.condev.ru - VITE_MANIFEST_START_URL: https://hereconnect.condev.ru/manage/dashboard - VITE_MANIFEST_SCOPE: https://hereconnect.condev.ru/ + #VITE_MANIFEST_START_URL: https://hereconnect.condev.ru/ + #VITE_MANIFEST_SCOPE: https://hereconnect.condev.ru/ steps: - uses: actions/checkout@v4 diff --git a/apps/frontend/components.d.ts b/apps/frontend/components.d.ts index 59dc2a8..9593fea 100644 --- a/apps/frontend/components.d.ts +++ b/apps/frontend/components.d.ts @@ -30,6 +30,7 @@ declare module 'vue' { ProgressSpinner: typeof import('primevue/progressspinner')['default'] QRCodeCard: typeof import('./src/components/manage/QRCodeCard.vue')['default'] QueryRender: typeof import('./src/components/QueryRender.vue')['default'] + RadioButton: typeof import('primevue/radiobutton')['default'] ReadContactInfo: typeof import('./src/components/read/ReadContactInfo.vue')['default'] ReadMessageSender: typeof import('./src/components/read/ReadMessageSender.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] diff --git a/apps/frontend/public/service-worker.js b/apps/frontend/public/service-worker.js index 8c3799e..adf1221 100644 --- a/apps/frontend/public/service-worker.js +++ b/apps/frontend/public/service-worker.js @@ -1,13 +1,12 @@ -const VER = 7 +const VER = 14 self.addEventListener('message', async (event) => { - event.waitUntil(debug(event.source, Object.assign({ answer: true }, event.data))) + event.waitUntil(debug(Object.assign({ answer: true }, event.data))) }) self.addEventListener('install', (event) => { - console.log('install event:', event) // The promise that skipWaiting() returns can be safely ignored. - event.waitUntil(self.skipWaiting().then(() => debug(event.source, { installed: true }))) + event.waitUntil(self.skipWaiting().then(() => debug({ installed: true }))) // Perform any other actions required for your // service worker to install, potentially inside @@ -21,23 +20,34 @@ self.addEventListener('activate', (event) => { ) }) -self.addEventListener('push', (event) => { +self.addEventListener('push', async (event) => { + debug({ + event: 'push', + }) // PushData keys structure standart https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification let pushData = event.data.json() if (!pushData || !pushData.notification.title) { - console.error('Received WebPush with an empty title. Received body: ', pushData) + debug({ + error: 'Received WebPush with an empty title. Received body', + }) } - event.waitUntil( - self.registration - .showNotification(pushData.notification.title, pushData.notification.options) - .then(function () { - // You can save to your analytics fact that push was shown - // fetch('https://your_backend_server.com/track_show?message_id=' + pushData.data.message_id); - }), - ) + self.registration + .showNotification(pushData.notification.title, pushData.notification.options) + .then(function () { + // You can save to your analytics fact that push was shown + // fetch('https://your_backend_server.com/track_show?message_id=' + pushData.data.message_id); + }) + .catch((error) => { + debug({ + errorShowNotification: error.message, + }) + }) }) self.addEventListener('notificationclick', (event) => { + debug({ + event: 'notificationclick', + }) event.waitUntil(handleNotificationClick(event)) }) @@ -45,18 +55,13 @@ async function handleNotificationClick(event) { event.notification.close() if (!event.notification.data) { - await debug(null, { + await debug({ error: 'Click on WebPush with empty data, where url should be. Notification', }) - console.error( - 'Click on WebPush with empty data, where url should be. Notification: ', - event.notification, - ) return } if (!event.notification.data.url) { - await debug(null, { error: 'Click on WebPush without url. Notification' }) - console.error('Click on WebPush without url. Notification: ', event.notification) + await debug({ error: 'Click on WebPush without url. Notification' }) return } @@ -74,75 +79,56 @@ async function openURL(urlToOpen) { for (const client of matchedClients) { const clientUrlObj = new URL(client.url) try { + await debug(client, { + urlToOpen, + 'client.url': client.url, + }) + if ( urlToOpenObj.pathname + urlToOpenObj.search !== clientUrlObj.pathname + clientUrlObj.search ) { - await debug(client, { - urlToOpenObj: urlToOpenObj.pathname + urlToOpenObj.search, - clientUrlObj: clientUrlObj.pathname + clientUrlObj.search, - }) continue } if (client.focused) { + debug({ 'client.focused': true }) return } await client.focus() + debug({ 'client.focus()': true }) return } catch (error) { await debug({ error: error.message }) } } } catch (error) { - console.error('get client error', error) + debug({ 'get client error': error }) } } catch (error) { - console.error('openURL error', error) + debug({ 'openURL error': error }) + } + + if (matchedClients && matchedClients.length) { + debug({ 'no matched clients': true }) } try { const client = await clients.openWindow(urlToOpen) if (!client) { - await debug(client, { error: 'client is null' }) - throw new Error('client is null') + await debug({ error: 'client is null' }) } + debug({ 'clients.openWindow()': true }) } catch (error) { await debug(matchedClients && matchedClients[0], { error: error.message }) - console.error(error) } } -async function debug(client, data) { - try { - if (!client) { - const matchedClients = await clients.matchAll({ type: 'window', includeUncontrolled: true }) - for (const matchedClient of matchedClients) { - if (matchedClient.focused) { - client = matchedClient - break - } - } - if (!client && matchedClients.length) { - return Promise.all(matchedClients.map((client) => debug(client, data))) - } - } - - if (!client) { - throw new Error('not found client for debug') - } - - if (!client.postMessage) { - console.error('not found client.postMessage for debug', client) - return - } - - await client.postMessage({ - type: 'debug', - debug: Object.assign({ VER }, data || {}), - }) - } catch (error) { - console.error(error) - } -} +function debug() {} +// async function debug(...args) { +// return fetch('https://hereconnect-debug.condev.ru/debug', { +// method: 'POST', +// body: JSON.stringify(args), +// }) +// } diff --git a/apps/frontend/src/App.vue b/apps/frontend/src/App.vue index 35d0298..5b40cb7 100644 --- a/apps/frontend/src/App.vue +++ b/apps/frontend/src/App.vue @@ -2,8 +2,8 @@ import { RouterView } from 'vue-router' import { registerServiceWorker } from '@/registerServiceWorker' -const router = useRouter() -const debugEnabled = ref(import.meta.env.DEV) +// const router = useRouter() +const debugEnabled = ref(false) // import.meta.env.DEV) const debugItems = ref([]) const debug = (...data: unknown[]) => { if (debugEnabled.value) { @@ -14,21 +14,21 @@ const debug = (...data: unknown[]) => { provide('debug', debug) registerServiceWorker() - .then(() => { - console.log('Service Worker успешно зарегистрирован') - navigator.serviceWorker.addEventListener('message', (event) => { - if (event.data.type === 'debug') { - if ('debug' in event.data && typeof event.data.debug === 'object') { - debug(event.data.debug) - } - } else if (event.data.type === 'notificationClick' && !event.data.matchUrl) { - const url = new URL(event.data.url, location.origin) - console.debug('go to', `${url.pathname}${url.search}${url.hash}`) - router.push(`${url.pathname}${url.search}${url.hash}`) - } - }) - }) - .catch(console.error) +// .then(() => { +// // console.log('Service Worker успешно зарегистрирован') +// navigator.serviceWorker.addEventListener('message', (event) => { +// if (event.data.type === 'debug') { +// if ('debug' in event.data && typeof event.data.debug === 'object') { +// debug(event.data.debug) +// } +// } else if (event.data.type === 'notificationclick' && !event.data.matchUrl) { +// const url = new URL(event.data.url, location.origin) +// // console.debug('go to', `${url.pathname}${url.search}${url.hash}`) +// router.push(`${url.pathname}${url.search}${url.hash}`) +// } +// }) +// }) +// .catch(console.error) diff --git a/apps/frontend/src/manifest.json b/apps/frontend/src/manifest.json index d655c28..b48cf62 100644 --- a/apps/frontend/src/manifest.json +++ b/apps/frontend/src/manifest.json @@ -1,7 +1,7 @@ { "short_name": "НаСвязи", "id": "hereconnect", - "start_url": "/manage/dashboard", + "start_url": "/", "theme_color": "#ffffff", "background_color": "#ffffff", "display": "standalone", diff --git a/apps/frontend/src/registerServiceWorker.ts b/apps/frontend/src/registerServiceWorker.ts index a641a31..5e2eb95 100644 --- a/apps/frontend/src/registerServiceWorker.ts +++ b/apps/frontend/src/registerServiceWorker.ts @@ -3,36 +3,36 @@ export async function registerServiceWorker() { throw new Error('Ваш браузер не поддерживает Service Worker.') } - function requestDebugVersion() { - navigator.serviceWorker?.controller?.postMessage({ - type: 'requestDebugVersion', - }) - } + // function requestDebugVersion() { + // navigator.serviceWorker?.controller?.postMessage({ + // type: 'requestDebugVersion', + // }) + // } navigator.serviceWorker.addEventListener('controllerchange', () => { - console.log('Service Worker controller has changed.') - requestDebugVersion() + // console.log('Service Worker controller has changed.') + // requestDebugVersion() }) - try { - const registration = await navigator.serviceWorker.register('/service-worker.js') - console.log('Service Worker зарегистрирован:', registration) - - requestDebugVersion() - - window.addEventListener( - 'focus', - () => { - navigator.serviceWorker?.controller?.postMessage({ - type: 'focused', - }) - }, - {}, - ) - - return registration - } catch (error) { - console.error('Ошибка регистрации Service Worker:', error) - throw error - } + // try { + const registration = await navigator.serviceWorker.register('/service-worker.js') + // console.log('Service Worker зарегистрирован:', registration) + // + // requestDebugVersion() + // + // window.addEventListener( + // 'focus', + // () => { + // navigator.serviceWorker?.controller?.postMessage({ + // type: 'focused', + // }) + // }, + // {}, + // ) + // + return registration + // } catch (error) { + // console.error('Ошибка регистрации Service Worker:', error) + // throw error + // } } diff --git a/apps/frontend/src/router/index.ts b/apps/frontend/src/router/index.ts index 058a82a..8016fb0 100644 --- a/apps/frontend/src/router/index.ts +++ b/apps/frontend/src/router/index.ts @@ -1,23 +1,24 @@ import { createRouter, createWebHistory } from 'vue-router' import { ROUTE_NAMES } from '@/constants/routes' -import HomeView from '@/views/HomeView.vue' + +function isRunningStandalone() { + return window.matchMedia('(display-mode: standalone)').matches +} const routes = [ { path: '/', name: ROUTE_NAMES.HOME, - component: HomeView, + component: () => + isRunningStandalone() + ? import('@/views/ManageDashboardView.vue') + : import('@/views/HomeView.vue'), }, { path: '/create', name: ROUTE_NAMES.CREATE, component: () => import('@/views/CreateView.vue'), }, - { - path: '/app/start', - name: ROUTE_NAMES.APP_START, - component: () => import('@/views/ManageDashboardView.vue'), - }, { path: '/manage/dashboard', name: ROUTE_NAMES.MANAGE_DASHBOARD, diff --git a/apps/frontend/vite.config.ts b/apps/frontend/vite.config.ts index e47a24e..c84793d 100644 --- a/apps/frontend/vite.config.ts +++ b/apps/frontend/vite.config.ts @@ -133,6 +133,15 @@ export default defineConfig(({ mode }) => { res.end(JSON.stringify(result, null, 2)) }, } satisfies RouteConfig, + 'POST /debug': { + async handler(req, res) { + process.stdout.write('\ndebug: ') + req.pipe(process.stdout) + res.statusCode = 200 + res.setHeader('Content-Type', 'application/json') + res.end('true') + }, + } satisfies RouteConfig, }, }), {