feat: add pwa manifest and service worker
Wire up a production service worker and web app manifest with install metadata and icon assets. Bump project version to 2.1.0 and register the worker from the main page for offline-ready behavior. Made-with: Cursor
This commit is contained in:
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "growing-galaxy",
|
"name": "growing-galaxy",
|
||||||
"version": "0.0.1",
|
"version": "2.1.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "growing-galaxy",
|
"name": "growing-galaxy",
|
||||||
"version": "0.0.1",
|
"version": "2.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/preact": "^4.1.3",
|
"@astrojs/preact": "^4.1.3",
|
||||||
"astro": "^5.15.5",
|
"astro": "^5.15.5",
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "growing-galaxy",
|
"name": "growing-galaxy",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.0.1",
|
"version": "2.1.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev --host",
|
"dev": "astro dev --host",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "BSC Score",
|
||||||
|
"short_name": "BSC Score",
|
||||||
|
"description": "Professional pool and billiards scoring application",
|
||||||
|
"start_url": "/",
|
||||||
|
"scope": "/",
|
||||||
|
"display": "standalone",
|
||||||
|
"orientation": "portrait",
|
||||||
|
"background_color": "#1a1a1a",
|
||||||
|
"theme_color": "#1a1a1a",
|
||||||
|
"lang": "de",
|
||||||
|
"categories": [
|
||||||
|
"sports",
|
||||||
|
"utilities",
|
||||||
|
"productivity"
|
||||||
|
],
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "/icon-192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/icon-512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "/icon-512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png",
|
||||||
|
"purpose": "maskable"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
const CACHE_NAME = 'bscscore-v2.1.0';
|
||||||
|
const APP_SHELL = [
|
||||||
|
'/',
|
||||||
|
'/index.html',
|
||||||
|
'/manifest.webmanifest',
|
||||||
|
'/favicon.ico',
|
||||||
|
'/icon-192.png',
|
||||||
|
'/icon-512.png',
|
||||||
|
];
|
||||||
|
|
||||||
|
self.addEventListener('install', (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
caches.open(CACHE_NAME).then((cache) => cache.addAll(APP_SHELL)),
|
||||||
|
);
|
||||||
|
self.skipWaiting();
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('activate', (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
caches.keys().then((keys) =>
|
||||||
|
Promise.all(
|
||||||
|
keys.map((key) => {
|
||||||
|
if (key !== CACHE_NAME) {
|
||||||
|
return caches.delete(key);
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
self.clients.claim();
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('fetch', (event) => {
|
||||||
|
const { request } = event;
|
||||||
|
const requestUrl = new URL(request.url);
|
||||||
|
|
||||||
|
if (request.method !== 'GET' || requestUrl.origin !== self.location.origin) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.mode === 'navigate') {
|
||||||
|
event.respondWith(
|
||||||
|
fetch(request)
|
||||||
|
.then((response) => {
|
||||||
|
const responseClone = response.clone();
|
||||||
|
caches.open(CACHE_NAME).then((cache) => cache.put(request, responseClone));
|
||||||
|
return response;
|
||||||
|
})
|
||||||
|
.catch(() => caches.match(request).then((cached) => cached || caches.match('/'))),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.respondWith(
|
||||||
|
caches.match(request).then((cachedResponse) => {
|
||||||
|
if (cachedResponse) {
|
||||||
|
return cachedResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetch(request).then((networkResponse) => {
|
||||||
|
const networkClone = networkResponse.clone();
|
||||||
|
caches.open(CACHE_NAME).then((cache) => cache.put(request, networkClone));
|
||||||
|
return networkResponse;
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -19,11 +19,14 @@ import App from "../components/App";
|
|||||||
<meta name="theme-color" content="#1a1a1a">
|
<meta name="theme-color" content="#1a1a1a">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<link rel="manifest" href="/manifest.webmanifest">
|
||||||
|
|
||||||
<!-- Favicon -->
|
<!-- Favicon -->
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||||||
<link rel="icon" type="image/png" sizes="192x192" href="/icon-192.png">
|
<link rel="icon" type="image/png" sizes="192x192" href="/icon-192.png">
|
||||||
<link rel="icon" type="image/png" sizes="512x512" href="/icon-512.png">
|
<link rel="icon" type="image/png" sizes="512x512" href="/icon-512.png">
|
||||||
|
<link rel="apple-touch-icon" href="/icon-192.png">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -34,5 +37,14 @@ import App from "../components/App";
|
|||||||
-->
|
-->
|
||||||
<App client:only="preact" slot="app-content" />
|
<App client:only="preact" slot="app-content" />
|
||||||
</BscScoreApp>
|
</BscScoreApp>
|
||||||
|
<script>
|
||||||
|
if (typeof window !== 'undefined' && 'serviceWorker' in navigator) {
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
navigator.serviceWorker.register('/sw.js').catch((error) => {
|
||||||
|
console.error('Service worker registration failed:', error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user