From fdb1efcb1e9667738c8730e2c166bbc92b3e2247 Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Fri, 10 Apr 2026 17:26:59 -0400 Subject: [PATCH] feat: add PWA manifest with radio shortcut + cache radio page - Create manifest.json with app name, icons, and shortcuts (Music, Radio, Offline) - Add /radio to service worker shell cache for offline navigation - Bump SW cache version to v2 to invalidate stale caches - Link manifest in layout metadata Co-Authored-By: Claude Opus 4.6 --- app/layout.tsx | 2 +- public/manifest.json | 49 ++++++++++++++++++++++++++++++++++++++++++++ public/sw.js | 5 +++-- 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 public/manifest.json diff --git a/app/layout.tsx b/app/layout.tsx index d93b55f..51a3b2a 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -25,7 +25,7 @@ export const metadata: Metadata = { metadataBase: new URL("https://jefflix.com"), title: "Jefflix - Seize the Streams of Production", description: "A revolutionary approach to media consumption. Free from subscriptions, owned by the people.", - generator: "v0.app", + manifest: "/manifest.json", icons: { icon: [ { diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..3a05210 --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,49 @@ +{ + "name": "Jefflix", + "short_name": "Jefflix", + "description": "Self-hosted media streaming — movies, TV, music, and world radio", + "start_url": "/", + "display": "standalone", + "background_color": "#0a0a0a", + "theme_color": "#0a0a0a", + "orientation": "any", + "scope": "/", + "icons": [ + { + "src": "/icon-light-32x32.png", + "sizes": "32x32", + "type": "image/png" + }, + { + "src": "/apple-icon.png", + "sizes": "180x180", + "type": "image/png" + }, + { + "src": "/icon.svg", + "sizes": "any", + "type": "image/svg+xml" + } + ], + "shortcuts": [ + { + "name": "Music", + "short_name": "Music", + "url": "/music", + "icons": [{ "src": "/icon.svg", "sizes": "any" }] + }, + { + "name": "World Radio", + "short_name": "Radio", + "url": "/radio", + "icons": [{ "src": "/icon.svg", "sizes": "any" }] + }, + { + "name": "Offline Library", + "short_name": "Offline", + "url": "/offline", + "icons": [{ "src": "/icon.svg", "sizes": "any" }] + } + ], + "categories": ["entertainment", "music"] +} diff --git a/public/sw.js b/public/sw.js index 1de4e9d..9fc1a63 100644 --- a/public/sw.js +++ b/public/sw.js @@ -1,6 +1,6 @@ /// -const CACHE_NAME = 'soulsync-shell-v1' +const CACHE_NAME = 'soulsync-shell-v2' const DB_NAME = 'soulsync-offline' const AUDIO_STORE = 'audio-blobs' @@ -8,6 +8,7 @@ const AUDIO_STORE = 'audio-blobs' const SHELL_FILES = [ '/', '/music', + '/radio', '/offline', ] @@ -27,7 +28,7 @@ self.addEventListener('install', (event) => { self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((keys) => - Promise.all(keys.filter((k) => k !== CACHE_NAME).map((k) => caches.delete(k))) + Promise.all(keys.filter((k) => k !== CACHE_NAME && k.startsWith('soulsync-')).map((k) => caches.delete(k))) ) ) self.clients.claim()