This commit is contained in:
@@ -21,8 +21,8 @@ jobs:
|
|||||||
VITE_MANIFEST_NAME: НаСвязи
|
VITE_MANIFEST_NAME: НаСвязи
|
||||||
VITE_MANIFEST_SHORT_NAME: НаСвязи
|
VITE_MANIFEST_SHORT_NAME: НаСвязи
|
||||||
VITE_MANIFEST_ID: https://hereconnect.condev.ru
|
VITE_MANIFEST_ID: https://hereconnect.condev.ru
|
||||||
VITE_MANIFEST_START_URL: https://hereconnect.condev.ru/manage/dashboard
|
#VITE_MANIFEST_START_URL: https://hereconnect.condev.ru/
|
||||||
VITE_MANIFEST_SCOPE: https://hereconnect.condev.ru/
|
#VITE_MANIFEST_SCOPE: https://hereconnect.condev.ru/
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|||||||
Vendored
+1
@@ -30,6 +30,7 @@ declare module 'vue' {
|
|||||||
ProgressSpinner: typeof import('primevue/progressspinner')['default']
|
ProgressSpinner: typeof import('primevue/progressspinner')['default']
|
||||||
QRCodeCard: typeof import('./src/components/manage/QRCodeCard.vue')['default']
|
QRCodeCard: typeof import('./src/components/manage/QRCodeCard.vue')['default']
|
||||||
QueryRender: typeof import('./src/components/QueryRender.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']
|
ReadContactInfo: typeof import('./src/components/read/ReadContactInfo.vue')['default']
|
||||||
ReadMessageSender: typeof import('./src/components/read/ReadMessageSender.vue')['default']
|
ReadMessageSender: typeof import('./src/components/read/ReadMessageSender.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
const VER = 7
|
const VER = 14
|
||||||
|
|
||||||
self.addEventListener('message', async (event) => {
|
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) => {
|
self.addEventListener('install', (event) => {
|
||||||
console.log('install event:', event)
|
|
||||||
// The promise that skipWaiting() returns can be safely ignored.
|
// 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
|
// Perform any other actions required for your
|
||||||
// service worker to install, potentially inside
|
// 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
|
// PushData keys structure standart https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/showNotification
|
||||||
let pushData = event.data.json()
|
let pushData = event.data.json()
|
||||||
if (!pushData || !pushData.notification.title) {
|
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
|
||||||
self.registration
|
.showNotification(pushData.notification.title, pushData.notification.options)
|
||||||
.showNotification(pushData.notification.title, pushData.notification.options)
|
.then(function () {
|
||||||
.then(function () {
|
// You can save to your analytics fact that push was shown
|
||||||
// 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);
|
||||||
// fetch('https://your_backend_server.com/track_show?message_id=' + pushData.data.message_id);
|
})
|
||||||
}),
|
.catch((error) => {
|
||||||
)
|
debug({
|
||||||
|
errorShowNotification: error.message,
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
self.addEventListener('notificationclick', (event) => {
|
self.addEventListener('notificationclick', (event) => {
|
||||||
|
debug({
|
||||||
|
event: 'notificationclick',
|
||||||
|
})
|
||||||
event.waitUntil(handleNotificationClick(event))
|
event.waitUntil(handleNotificationClick(event))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -45,18 +55,13 @@ async function handleNotificationClick(event) {
|
|||||||
event.notification.close()
|
event.notification.close()
|
||||||
|
|
||||||
if (!event.notification.data) {
|
if (!event.notification.data) {
|
||||||
await debug(null, {
|
await debug({
|
||||||
error: 'Click on WebPush with empty data, where url should be. Notification',
|
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
|
return
|
||||||
}
|
}
|
||||||
if (!event.notification.data.url) {
|
if (!event.notification.data.url) {
|
||||||
await debug(null, { error: 'Click on WebPush without url. Notification' })
|
await debug({ error: 'Click on WebPush without url. Notification' })
|
||||||
console.error('Click on WebPush without url. Notification: ', event.notification)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,75 +79,56 @@ async function openURL(urlToOpen) {
|
|||||||
for (const client of matchedClients) {
|
for (const client of matchedClients) {
|
||||||
const clientUrlObj = new URL(client.url)
|
const clientUrlObj = new URL(client.url)
|
||||||
try {
|
try {
|
||||||
|
await debug(client, {
|
||||||
|
urlToOpen,
|
||||||
|
'client.url': client.url,
|
||||||
|
})
|
||||||
|
|
||||||
if (
|
if (
|
||||||
urlToOpenObj.pathname + urlToOpenObj.search !==
|
urlToOpenObj.pathname + urlToOpenObj.search !==
|
||||||
clientUrlObj.pathname + clientUrlObj.search
|
clientUrlObj.pathname + clientUrlObj.search
|
||||||
) {
|
) {
|
||||||
await debug(client, {
|
|
||||||
urlToOpenObj: urlToOpenObj.pathname + urlToOpenObj.search,
|
|
||||||
clientUrlObj: clientUrlObj.pathname + clientUrlObj.search,
|
|
||||||
})
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client.focused) {
|
if (client.focused) {
|
||||||
|
debug({ 'client.focused': true })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await client.focus()
|
await client.focus()
|
||||||
|
debug({ 'client.focus()': true })
|
||||||
return
|
return
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await debug({ error: error.message })
|
await debug({ error: error.message })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('get client error', error)
|
debug({ 'get client error': error })
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('openURL error', error)
|
debug({ 'openURL error': error })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchedClients && matchedClients.length) {
|
||||||
|
debug({ 'no matched clients': true })
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const client = await clients.openWindow(urlToOpen)
|
const client = await clients.openWindow(urlToOpen)
|
||||||
if (!client) {
|
if (!client) {
|
||||||
await debug(client, { error: 'client is null' })
|
await debug({ error: 'client is null' })
|
||||||
throw new Error('client is null')
|
|
||||||
}
|
}
|
||||||
|
debug({ 'clients.openWindow()': true })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await debug(matchedClients && matchedClients[0], { error: error.message })
|
await debug(matchedClients && matchedClients[0], { error: error.message })
|
||||||
console.error(error)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function debug(client, data) {
|
function debug() {}
|
||||||
try {
|
// async function debug(...args) {
|
||||||
if (!client) {
|
// return fetch('https://hereconnect-debug.condev.ru/debug', {
|
||||||
const matchedClients = await clients.matchAll({ type: 'window', includeUncontrolled: true })
|
// method: 'POST',
|
||||||
for (const matchedClient of matchedClients) {
|
// body: JSON.stringify(args),
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+18
-17
@@ -2,8 +2,8 @@
|
|||||||
import { RouterView } from 'vue-router'
|
import { RouterView } from 'vue-router'
|
||||||
import { registerServiceWorker } from '@/registerServiceWorker'
|
import { registerServiceWorker } from '@/registerServiceWorker'
|
||||||
|
|
||||||
const router = useRouter()
|
// const router = useRouter()
|
||||||
const debugEnabled = ref(import.meta.env.DEV)
|
const debugEnabled = ref(false) // import.meta.env.DEV)
|
||||||
const debugItems = ref<string[]>([])
|
const debugItems = ref<string[]>([])
|
||||||
const debug = (...data: unknown[]) => {
|
const debug = (...data: unknown[]) => {
|
||||||
if (debugEnabled.value) {
|
if (debugEnabled.value) {
|
||||||
@@ -14,21 +14,21 @@ const debug = (...data: unknown[]) => {
|
|||||||
provide('debug', debug)
|
provide('debug', debug)
|
||||||
|
|
||||||
registerServiceWorker()
|
registerServiceWorker()
|
||||||
.then(() => {
|
// .then(() => {
|
||||||
console.log('Service Worker успешно зарегистрирован')
|
// // console.log('Service Worker успешно зарегистрирован')
|
||||||
navigator.serviceWorker.addEventListener('message', (event) => {
|
// navigator.serviceWorker.addEventListener('message', (event) => {
|
||||||
if (event.data.type === 'debug') {
|
// if (event.data.type === 'debug') {
|
||||||
if ('debug' in event.data && typeof event.data.debug === 'object') {
|
// if ('debug' in event.data && typeof event.data.debug === 'object') {
|
||||||
debug(event.data.debug)
|
// debug(event.data.debug)
|
||||||
}
|
// }
|
||||||
} else if (event.data.type === 'notificationClick' && !event.data.matchUrl) {
|
// } else if (event.data.type === 'notificationclick' && !event.data.matchUrl) {
|
||||||
const url = new URL(event.data.url, location.origin)
|
// const url = new URL(event.data.url, location.origin)
|
||||||
console.debug('go to', `${url.pathname}${url.search}${url.hash}`)
|
// // console.debug('go to', `${url.pathname}${url.search}${url.hash}`)
|
||||||
router.push(`${url.pathname}${url.search}${url.hash}`)
|
// router.push(`${url.pathname}${url.search}${url.hash}`)
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
.catch(console.error)
|
// .catch(console.error)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -43,6 +43,7 @@ registerServiceWorker()
|
|||||||
<span class="font-mono text-xs">{{ value }}</span>
|
<span class="font-mono text-xs">{{ value }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"short_name": "НаСвязи",
|
"short_name": "НаСвязи",
|
||||||
"id": "hereconnect",
|
"id": "hereconnect",
|
||||||
"start_url": "/manage/dashboard",
|
"start_url": "/",
|
||||||
"theme_color": "#ffffff",
|
"theme_color": "#ffffff",
|
||||||
"background_color": "#ffffff",
|
"background_color": "#ffffff",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
|
|||||||
@@ -3,36 +3,36 @@ export async function registerServiceWorker() {
|
|||||||
throw new Error('Ваш браузер не поддерживает Service Worker.')
|
throw new Error('Ваш браузер не поддерживает Service Worker.')
|
||||||
}
|
}
|
||||||
|
|
||||||
function requestDebugVersion() {
|
// function requestDebugVersion() {
|
||||||
navigator.serviceWorker?.controller?.postMessage({
|
// navigator.serviceWorker?.controller?.postMessage({
|
||||||
type: 'requestDebugVersion',
|
// type: 'requestDebugVersion',
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
||||||
console.log('Service Worker controller has changed.')
|
// console.log('Service Worker controller has changed.')
|
||||||
requestDebugVersion()
|
// requestDebugVersion()
|
||||||
})
|
})
|
||||||
|
|
||||||
try {
|
// try {
|
||||||
const registration = await navigator.serviceWorker.register('/service-worker.js')
|
const registration = await navigator.serviceWorker.register('/service-worker.js')
|
||||||
console.log('Service Worker зарегистрирован:', registration)
|
// console.log('Service Worker зарегистрирован:', registration)
|
||||||
|
//
|
||||||
requestDebugVersion()
|
// requestDebugVersion()
|
||||||
|
//
|
||||||
window.addEventListener(
|
// window.addEventListener(
|
||||||
'focus',
|
// 'focus',
|
||||||
() => {
|
// () => {
|
||||||
navigator.serviceWorker?.controller?.postMessage({
|
// navigator.serviceWorker?.controller?.postMessage({
|
||||||
type: 'focused',
|
// type: 'focused',
|
||||||
})
|
// })
|
||||||
},
|
// },
|
||||||
{},
|
// {},
|
||||||
)
|
// )
|
||||||
|
//
|
||||||
return registration
|
return registration
|
||||||
} catch (error) {
|
// } catch (error) {
|
||||||
console.error('Ошибка регистрации Service Worker:', error)
|
// console.error('Ошибка регистрации Service Worker:', error)
|
||||||
throw error
|
// throw error
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,24 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import { ROUTE_NAMES } from '@/constants/routes'
|
import { ROUTE_NAMES } from '@/constants/routes'
|
||||||
import HomeView from '@/views/HomeView.vue'
|
|
||||||
|
function isRunningStandalone() {
|
||||||
|
return window.matchMedia('(display-mode: standalone)').matches
|
||||||
|
}
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: ROUTE_NAMES.HOME,
|
name: ROUTE_NAMES.HOME,
|
||||||
component: HomeView,
|
component: () =>
|
||||||
|
isRunningStandalone()
|
||||||
|
? import('@/views/ManageDashboardView.vue')
|
||||||
|
: import('@/views/HomeView.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/create',
|
path: '/create',
|
||||||
name: ROUTE_NAMES.CREATE,
|
name: ROUTE_NAMES.CREATE,
|
||||||
component: () => import('@/views/CreateView.vue'),
|
component: () => import('@/views/CreateView.vue'),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/app/start',
|
|
||||||
name: ROUTE_NAMES.APP_START,
|
|
||||||
component: () => import('@/views/ManageDashboardView.vue'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/manage/dashboard',
|
path: '/manage/dashboard',
|
||||||
name: ROUTE_NAMES.MANAGE_DASHBOARD,
|
name: ROUTE_NAMES.MANAGE_DASHBOARD,
|
||||||
|
|||||||
@@ -133,6 +133,15 @@ export default defineConfig(({ mode }) => {
|
|||||||
res.end(JSON.stringify(result, null, 2))
|
res.end(JSON.stringify(result, null, 2))
|
||||||
},
|
},
|
||||||
} satisfies RouteConfig,
|
} 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,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user