PWA basic implemented (not for admin.php)
This commit is contained in:
parent
d7da479741
commit
acc77ac17f
12 changed files with 193 additions and 1 deletions
116
sw.js
116
sw.js
|
|
@ -1,3 +1,119 @@
|
|||
const MVLOG_CACHE_PREFIX = 'mvlog-pwa-';
|
||||
const MVLOG_CACHE_VERSION = 'mvlog-pwa-v1';
|
||||
const APP_SHELL_CACHE = `${MVLOG_CACHE_VERSION}-app-shell`;
|
||||
const RUNTIME_CACHE = `${MVLOG_CACHE_VERSION}-runtime`;
|
||||
|
||||
const APP_SHELL_URLS = [
|
||||
'/',
|
||||
'/offline.html',
|
||||
'/style.css',
|
||||
'/js/map_lightbox.js',
|
||||
'/assets/fonts/BebasNeue-Regular.ttf',
|
||||
'/assets/fonts/IBMPlexSans-SemiBold.ttf',
|
||||
'/assets/fonts/NotoSans-Bold.ttf',
|
||||
'/assets/img/background.jpg',
|
||||
'/assets/img/moto_travel.png',
|
||||
'/assets/img/pwa-icon-192.png',
|
||||
'/assets/img/pwa-icon-512.png',
|
||||
'/assets/img/pwa-maskable-512.png',
|
||||
'/assets/img/apple-touch-icon.png',
|
||||
'/manifest.json'
|
||||
];
|
||||
|
||||
self.addEventListener('install', event => {
|
||||
event.waitUntil((async () => {
|
||||
const cache = await caches.open(APP_SHELL_CACHE);
|
||||
await Promise.all(APP_SHELL_URLS.map(url =>
|
||||
cache.add(new Request(url, { cache: 'reload' })).catch(() => undefined)
|
||||
));
|
||||
await self.skipWaiting();
|
||||
})());
|
||||
});
|
||||
|
||||
self.addEventListener('activate', event => {
|
||||
event.waitUntil((async () => {
|
||||
const names = await caches.keys();
|
||||
await Promise.all(names.map(name => {
|
||||
if (name.startsWith(MVLOG_CACHE_PREFIX) && ![APP_SHELL_CACHE, RUNTIME_CACHE].includes(name)) {
|
||||
return caches.delete(name);
|
||||
}
|
||||
return undefined;
|
||||
}));
|
||||
await clients.claim();
|
||||
})());
|
||||
});
|
||||
|
||||
function shouldBypassFetch(request, url) {
|
||||
if (request.method !== 'GET') return true;
|
||||
if (!['http:', 'https:'].includes(url.protocol)) return true;
|
||||
if (url.origin !== self.location.origin) return false;
|
||||
|
||||
const path = url.pathname;
|
||||
if (path === '/admin.php' || path === '/login.php' || path === '/logout.php') return true;
|
||||
if (path === '/push_config.php' || path === '/push_subscribe.php' || path === '/job_status.php') return true;
|
||||
if (path.startsWith('/api/') || path.startsWith('/lib/') || path.startsWith('/cache/') || path.startsWith('/in-dir/')) return true;
|
||||
if (path.startsWith('/out-dir/') && /\.(mp4|m4v|mov|webm)$/i.test(path)) return true;
|
||||
if (/\.(mp4|m4v|mov|webm)$/i.test(path)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function isStaticAsset(url) {
|
||||
if (url.origin !== self.location.origin) return false;
|
||||
const path = url.pathname;
|
||||
return path === '/style.css'
|
||||
|| path === '/manifest.json'
|
||||
|| path === '/offline.html'
|
||||
|| path.startsWith('/assets/')
|
||||
|| path.startsWith('/js/');
|
||||
}
|
||||
|
||||
async function networkFirstNavigation(request) {
|
||||
try {
|
||||
const response = await fetch(request);
|
||||
if (response && response.ok) {
|
||||
const cache = await caches.open(RUNTIME_CACHE);
|
||||
cache.put(request, response.clone()).catch(() => undefined);
|
||||
}
|
||||
return response;
|
||||
} catch (error) {
|
||||
const exact = await caches.match(request);
|
||||
if (exact) return exact;
|
||||
const offline = await caches.match('/offline.html');
|
||||
if (offline) return offline;
|
||||
const home = await caches.match('/');
|
||||
if (home) return home;
|
||||
return new Response('Offline', { status: 503, headers: { 'Content-Type': 'text/plain; charset=utf-8' } });
|
||||
}
|
||||
}
|
||||
|
||||
async function staleWhileRevalidate(request) {
|
||||
const cached = await caches.match(request);
|
||||
const cache = await caches.open(RUNTIME_CACHE);
|
||||
const network = fetch(request).then(response => {
|
||||
if (response && response.ok) {
|
||||
cache.put(request, response.clone()).catch(() => undefined);
|
||||
}
|
||||
return response;
|
||||
}).catch(() => cached);
|
||||
return cached || network;
|
||||
}
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
const request = event.request;
|
||||
const url = new URL(request.url);
|
||||
if (shouldBypassFetch(request, url)) return;
|
||||
|
||||
if (request.mode === 'navigate') {
|
||||
event.respondWith(networkFirstNavigation(request));
|
||||
return;
|
||||
}
|
||||
|
||||
if (isStaticAsset(url)) {
|
||||
event.respondWith(staleWhileRevalidate(request));
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener('push', event => {
|
||||
let data = {};
|
||||
try { data = event.data ? event.data.json() : {}; } catch (e) { data = { title: 'MVLog', body: event.data ? event.data.text() : 'New article @ MVLog!' }; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue