@underpostnet/underpost
Version:
283 lines (273 loc) • 9.81 kB
JavaScript
import { BtnIcon } from './BtnIcon.js';
import { s4 } from './CommonJs.js';
import { EventsUI } from './EventsUI.js';
import { LoadingAnimation } from './LoadingAnimation.js';
import { loggerFactory } from './Logger.js';
import { LoadRouter } from './Router.js';
import { Translate } from './Translate.js';
import { getProxyPath, htmls, s } from './VanillaJs.js';
const logger = loggerFactory(import.meta);
const Worker = {
devMode: () => location.origin.match('localhost') || location.origin.match('127.0.0.1'),
instance: async function ({ router, render }) {
logger.warn('Init');
window.ononline = async () => {
logger.warn('ononline');
};
window.onoffline = async () => {
logger.warn('onoffline');
};
setTimeout(() => {
if ('onLine' in navigator && navigator.onLine) window.ononline();
});
if ('serviceWorker' in navigator) {
navigator.serviceWorker.addEventListener('controllerchange', () => {
logger.info('The controller of current browsing context has changed.');
});
navigator.serviceWorker.ready.then((worker) => {
logger.info('Ready', worker);
// event message
navigator.serviceWorker.addEventListener('message', (event) => {
logger.info('Received event message', event.data);
const { status } = event.data;
switch (status) {
case 'loader':
{
LoadingAnimation.RenderCurrentSrcLoad(event);
}
break;
default:
break;
}
});
// if (navigator.serviceWorker.controller)
// navigator.serviceWorker.controller.postMessage({
// title: 'Hello from Client event message',
// });
// broadcast message
// const channel = new BroadcastChannel('sw-messages');
// channel.addEventListener('message', (event) => {
// logger.info('Received broadcast message', event.data);
// });
// channel.postMessage({ title: 'Hello from Client broadcast message' });
// channel.close();
});
}
this.RouterInstance = router();
const isInstall = await this.status();
if (!isInstall) await this.install();
await render();
LoadRouter(this.RouterInstance);
LoadingAnimation.removeSplashScreen();
if (this.devMode()) {
const delayLiveReload = 1250;
// Dev mode
window.addEventListener('visibilitychange', (event) => {
// if (document.visibilityState === 'visible') {
// Worker.reload(delayLiveReload);
// }
});
window.addEventListener('focus', function () {
// Worker.reload(delayLiveReload);
});
}
window.serviceWorkerReady = true;
},
// Get the current service worker registration.
getRegistration: async function () {
return await navigator.serviceWorker.getRegistration();
},
reload: async function (timeOut = 3000) {
return await new Promise((resolve) => {
if (navigator.serviceWorker && navigator.serviceWorker.controller)
navigator.serviceWorker.controller.postMessage({
status: 'skipWaiting',
});
// (location.href = `${location.origin}${location.pathname}${location.search}`)
setTimeout(() => resolve(location.reload()), timeOut);
});
},
update: async function () {
const isInstall = await this.status();
if (isInstall) {
const cacheNames = await caches.keys();
for (const cacheName of cacheNames) {
if (cacheName.match('components/') || cacheName.match('services/') || cacheName.match('.index.js')) {
await caches.delete(cacheName);
}
}
await this.updateServiceWorker();
}
},
updateServiceWorker: async function () {},
status: function () {
let status = false;
return new Promise((resolve, reject) => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.getRegistrations()
.then((registrations) => {
for (const registration of registrations) {
if (registration.installing) logger.info('installing', registration);
else if (registration.waiting) logger.info('waiting', registration);
else if (registration.active) {
logger.info('active', registration);
this.updateServiceWorker = async () => await registration.update();
}
}
if (registrations.length > 0) status = true;
})
.catch((...args) => {
logger.error(...args);
return resolve(false);
})
.finally((...args) => {
logger.info('Finally status', args);
return resolve(status);
});
} else {
logger.warn('Disabled');
return resolve(false);
}
});
},
install: function () {
return new Promise((resolve, reject) => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register(`${getProxyPath()}sw.js`, {
// scope: getProxyPath(),
// scope: '/',
type: 'module',
})
.then((...args) => {
logger.warn('Already Registered', args);
})
.catch((...args) => {
logger.error(...args);
return resolve(args);
})
.finally((...args) => {
logger.info('Finally install', args);
return resolve(args);
});
} else {
logger.warn('Disabled');
return resolve();
}
});
},
uninstall: function () {
return new Promise(async (resolve, reject) => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.getRegistrations()
.then(async (registrations) => {
const cacheNames = await caches.keys();
for (const cacheName of cacheNames) await caches.delete(cacheName);
for (const registration of registrations) {
logger.info('remove', registration);
registration.unregister();
}
})
.catch((...args) => {
logger.error(...args);
return resolve(args);
})
.finally((...args) => {
logger.info('Finally uninstall', args);
return resolve(args);
});
} else {
logger.warn('Disabled');
return resolve();
}
});
},
notificationActive: false,
notificationRequestPermission: function () {
return new Promise((resolve, reject) =>
Notification.requestPermission().then((result) => {
if (result === 'granted') {
this.notificationActive = true;
resolve(true);
} else {
this.notificationActive = false;
resolve(false);
}
}),
);
},
notificationShow: function () {
Notification.requestPermission().then((result) => {
if (result === 'granted') {
navigator.serviceWorker.ready.then((registration) => {
registration.showNotification('Vibration Sample', {
body: 'Buzz! Buzz!',
icon: '../images/touch/chrome-touch-icon.png',
vibrate: [200, 100, 200, 100, 200, 100, 200],
tag: 'vibration-sample',
requireInteraction: true, // boolean to manually close the notification
});
});
}
});
},
// TODO: GPS management
RenderSetting: async function () {
setTimeout(() => {
EventsUI.onClick(`.btn-clean-cache`, async (e) => {
e.preventDefault();
// await this.update();
localStorage.clear();
await this.uninstall();
await this.reload();
});
});
return html` <div class="in">
${await BtnIcon.Render({
class: 'inl section-mp btn-custom btn-install-service-controller hide',
label: html`<i class="fas fa-download"></i> ${Translate.Render('Install control service')}`,
})}
${await BtnIcon.Render({
class: 'inl section-mp btn-custom btn-uninstall-service-controller hide',
label: html`<i class="far fa-trash-alt"></i> ${Translate.Render('Uninstall control service')}`,
})}
${await BtnIcon.Render({
class: 'inl section-mp btn-custom btn-clean-cache',
label: html`<i class="fa-solid fa-broom"></i> ${Translate.Render('clean-cache')}`,
})}
${await BtnIcon.Render({
class: 'inl section-mp btn-custom btn-reload hide',
label: html`<i class="fas fa-sync-alt"></i> ${Translate.Render('Reload')}`,
})}
</div>`;
return;
s(`.btn-uninstall-service-controller`).classList.add('hide');
EventsUI.onClick(`.btn-install-service-controller`, async (e) => {
e.preventDefault();
const result = await this.install();
s(`.btn-install-service-controller`).classList.add('hide');
s(`.btn-uninstall-service-controller`).classList.remove('hide');
});
EventsUI.onClick(`.btn-uninstall-service-controller`, async (e) => {
e.preventDefault();
const result = await this.uninstall();
s(`.btn-uninstall-service-controller`).classList.add('hide');
s(`.btn-install-service-controller`).classList.remove('hide');
});
EventsUI.onClick(`.btn-reload`, async (e) => {
e.preventDefault();
location.reload();
});
const workerStatus = await this.status();
if (workerStatus) {
s(`.btn-install-service-controller`).classList.add('hide');
s(`.btn-uninstall-service-controller`).classList.remove('hide');
} else {
s(`.btn-uninstall-service-controller`).classList.add('hide');
s(`.btn-install-service-controller`).classList.remove('hide');
}
},
};
export { Worker };