Fix PWA install: static manifest.json + proper SVG icon
- Replace blob: manifest (ignored by Chrome) with static manifest.json - Replace data: URL icon with real icon.svg file - Link manifest and apple-touch-icon directly in <head> - Remove blob/data URL generation from app.js Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
042ce0b095
commit
56c5662a11
7 files changed
+58
-11
No files matched your search
+1
-1
@@ -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
|
||||
|
||||
@@ -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,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><rect width='100' height='100' rx='20' fill='%23e8a020'/><text y='.9em' font-size='70' x='15'>♫</text></svg>",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(() => {});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<rect width="512" height="512" rx="90" fill="#07070f"/>
|
||||
<rect width="512" height="512" rx="90" fill="url(#bg)"/>
|
||||
<defs>
|
||||
<radialGradient id="bg" cx="30%" cy="40%" r="80%">
|
||||
<stop offset="0%" stop-color="#1a1a2e"/>
|
||||
<stop offset="100%" stop-color="#07070f"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
<!-- Music note -->
|
||||
<g fill="#e8a020">
|
||||
<!-- Note head 1 -->
|
||||
<ellipse cx="180" cy="340" rx="48" ry="36" transform="rotate(-15 180 340)"/>
|
||||
<!-- Note head 2 -->
|
||||
<ellipse cx="332" cy="300" rx="48" ry="36" transform="rotate(-15 332 300)"/>
|
||||
<!-- Stem -->
|
||||
<rect x="218" y="160" width="18" height="185" rx="9"/>
|
||||
<rect x="370" y="120" width="18" height="185" rx="9"/>
|
||||
<!-- Beam -->
|
||||
<rect x="218" y="160" width="170" height="22" rx="11"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 855 B |
@@ -7,6 +7,8 @@
|
||||
<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-title" content="NovaSonic">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="apple-touch-icon" href="icon.svg">
|
||||
<title>NovaSonic</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@300;400;500&display=swap" rel="stylesheet">
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
Reference in new issue
Block a user