commit
c9d3005970
4 changed files with 67 additions and 11 deletions
|
|
@ -545,7 +545,9 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
window.addEventListener('beforeinstallprompt', (e) => {
|
||||
e.preventDefault();
|
||||
deferredPrompt = e;
|
||||
showInstallPrompt(deferredPrompt);
|
||||
if (!localStorage.getItem('installPromptDismissed')) {
|
||||
showInstallPrompt(deferredPrompt);
|
||||
}
|
||||
});
|
||||
|
||||
if (!localStorage.getItem('shortcuts-shown')) {
|
||||
|
|
@ -596,6 +598,7 @@ function showInstallPrompt(deferredPrompt) {
|
|||
|
||||
document.getElementById('dismiss-install').addEventListener('click', () => {
|
||||
notification.remove();
|
||||
localStorage.setItem('installPromptDismissed', 'true');
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
"description": "A minimalist music streaming application",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"display_override": [
|
||||
"window-controls-overlay"
|
||||
],
|
||||
"background_color": "#000000",
|
||||
"theme_color": "#000000",
|
||||
"orientation": "portrait-primary",
|
||||
|
|
|
|||
19
styles.css
19
styles.css
|
|
@ -2813,3 +2813,22 @@ input:checked + .slider::before {
|
|||
font-size: 4rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Window Controls Overlay */
|
||||
@media (display-mode: window-controls-overlay) {
|
||||
.app-container {
|
||||
margin-top: env(titlebar-area-height, 0);
|
||||
}
|
||||
|
||||
.main-header {
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
.main-header * {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
padding-top: max(1.5rem, env(titlebar-area-height, 0));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
51
sw.js
51
sw.js
|
|
@ -1,5 +1,6 @@
|
|||
//sw.js
|
||||
const CACHE_NAME = 'monochrome-v2';
|
||||
const CACHE_NAME = 'monochrome-v4';
|
||||
const IMAGE_CACHE_NAME = 'monochrome-images-v1';
|
||||
const urlsToCache = [
|
||||
'/',
|
||||
'/index.html',
|
||||
|
|
@ -11,11 +12,20 @@ const urlsToCache = [
|
|||
'/js/ui.js',
|
||||
'/js/utils.js',
|
||||
'/js/cache.js',
|
||||
'/manifest.json'
|
||||
'/js/router.js',
|
||||
'/js/events.js',
|
||||
'/js/ui-interactions.js',
|
||||
'/js/settings.js',
|
||||
'/js/lastfm.js',
|
||||
'/js/lyrics.js',
|
||||
'/js/downloads.js',
|
||||
'/manifest.json',
|
||||
'/assets/logo.svg',
|
||||
'/assets/appicon.png'
|
||||
];
|
||||
|
||||
self.addEventListener('install', event => {
|
||||
self.skipWaiting(); // Force activation
|
||||
self.skipWaiting();
|
||||
event.waitUntil(
|
||||
caches.open(CACHE_NAME)
|
||||
.then(cache => cache.addAll(urlsToCache))
|
||||
|
|
@ -23,19 +33,40 @@ self.addEventListener('install', event => {
|
|||
});
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
const url = new URL(event.request.url);
|
||||
|
||||
// Cache Images (Cache-First)
|
||||
if (url.hostname === 'resources.tidal.com' || url.hostname === 'picsum.photos') {
|
||||
event.respondWith(
|
||||
caches.open(IMAGE_CACHE_NAME).then(cache => {
|
||||
return cache.match(event.request).then(response => {
|
||||
return response || fetch(event.request).then(networkResponse => {
|
||||
if (networkResponse.ok) {
|
||||
cache.put(event.request, networkResponse.clone());
|
||||
}
|
||||
return networkResponse;
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Static Assets & App Shell (Cache-First)
|
||||
event.respondWith(
|
||||
caches.match(event.request)
|
||||
.then(response => response || fetch(event.request))
|
||||
.catch(() => {
|
||||
// Return 404 or handle offline fallback here if needed
|
||||
// For now, just ensuring the promise doesn't reject uncaught
|
||||
return new Response('Network error', { status: 408 });
|
||||
.then(response => {
|
||||
// Return cached response if found
|
||||
if (response) return response;
|
||||
|
||||
// Otherwise fetch from network
|
||||
return fetch(event.request);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('activate', event => {
|
||||
const cacheWhitelist = [CACHE_NAME];
|
||||
const cacheWhitelist = [CACHE_NAME, IMAGE_CACHE_NAME];
|
||||
event.waitUntil(
|
||||
caches.keys().then(cacheNames => {
|
||||
return Promise.all(
|
||||
|
|
@ -44,7 +75,7 @@ self.addEventListener('activate', event => {
|
|||
return caches.delete(cacheName);
|
||||
}
|
||||
})
|
||||
).then(() => self.clients.claim()); // Take control immediately
|
||||
).then(() => self.clients.claim());
|
||||
})
|
||||
);
|
||||
});
|
||||
Loading…
Reference in a new issue