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 => {