diff --git a/Dockerfile b/Dockerfile index d99ef9d..304eda0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM nginx:alpine -COPY index.html styles.css app.js sw.js /usr/share/nginx/html/ +COPY index.html styles.css app.js sw.js manifest.json icon.svg /usr/share/nginx/html/ COPY nginx.conf /etc/nginx/conf.d/default.conf COPY docker-entrypoint.sh /docker-entrypoint.sh RUN chmod +x /docker-entrypoint.sh diff --git a/app.js b/app.js index a3233ad..55a82d6 100644 --- a/app.js +++ b/app.js @@ -1251,14 +1251,6 @@ async function loadArtists(){ // ─── PWA ─── function injectPWA(){ - const m={name:'NovaSonic',short_name:'NovaSonic',description:'Subsonic/Navidrome Music Client', - start_url:'index.html',display:'standalone',background_color:'#07070f',theme_color:'#07070f', - icons:[{src:"data:image/svg+xml,♫",sizes:'192x192',type:'image/svg+xml'}]}; - try{ - const blob=new Blob([JSON.stringify(m)],{type:'application/json'}); - const link=document.createElement('link');link.rel='manifest';link.href=URL.createObjectURL(blob); - document.head.appendChild(link); - }catch{} if ('serviceWorker' in navigator) { navigator.serviceWorker.register('sw.js').catch(() => {}); } diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..42b0a97 --- /dev/null +++ b/icon.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/index.html b/index.html index 5e20435..c641195 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,8 @@ + + NovaSonic diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..1e2b74d --- /dev/null +++ b/manifest.json @@ -0,0 +1,25 @@ +{ + "name": "NovaSonic", + "short_name": "NovaSonic", + "description": "Self-hosted music streaming PWA", + "start_url": "/", + "scope": "/", + "display": "standalone", + "orientation": "portrait-primary", + "background_color": "#07070f", + "theme_color": "#07070f", + "icons": [ + { + "src": "icon.svg", + "sizes": "any", + "type": "image/svg+xml", + "purpose": "any" + }, + { + "src": "icon.svg", + "sizes": "any", + "type": "image/svg+xml", + "purpose": "maskable" + } + ] +} diff --git a/nginx.conf b/nginx.conf index 4994a9a..2da2952 100644 --- a/nginx.conf +++ b/nginx.conf @@ -29,6 +29,12 @@ server { add_header Cache-Control "no-cache, no-store, must-revalidate"; } + # Manifest – short cache so icon/name updates roll out quickly + location = /manifest.json { + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Access-Control-Allow-Origin "*"; + } + # SPA fallback location / { try_files $uri $uri/ /index.html; diff --git a/sw.js b/sw.js index ef6d9be..a9627b1 100644 --- a/sw.js +++ b/sw.js @@ -1,5 +1,5 @@ -const CACHE = 'ns-v16'; -const PRECACHE = ['/', 'index.html', 'styles.css', 'app.js', 'sw.js']; +const CACHE = 'ns-v17'; +const PRECACHE = ['/', 'index.html', 'styles.css', 'app.js', 'sw.js', 'manifest.json', 'icon.svg']; const SKIP_URLS = ['/rest/stream', '/rest/download', '/config.js']; self.addEventListener('install', e => {