diff --git a/frontend/public/manifest.json b/frontend/public/manifest.json index 95177dd..d395073 100644 --- a/frontend/public/manifest.json +++ b/frontend/public/manifest.json @@ -8,7 +8,6 @@ "orientation": "any", "background_color": "#ffffff", "theme_color": "#1a73e8", - "gcm_sender_id": "126479377334", "icons": [ { "src": "/icons/icon-192.png", @@ -23,11 +22,18 @@ "purpose": "maskable" }, { - "purpose": "any maskable", + "purpose": "maskable", "src": "/icons/icon-512-maskable.png", "sizes": "512x512", "type": "image/png" + }, + { + "purpose": "any", + "src": "/icons/icon-512.png", + "sizes": "512x512", + "type": "image/png" + } ], "min_width": "320px" diff --git a/frontend/public/manifest.json.copy b/frontend/public/manifest.json.copy deleted file mode 100644 index 5a0334f..0000000 --- a/frontend/public/manifest.json.copy +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "jama", - "short_name": "jama", - "description": "Modern team messaging application", - "start_url": "/", - "scope": "/", - "display": "standalone", - "orientation": "any", - "background_color": "#ffffff", - "theme_color": "#1a73e8", - "icons": [ - { - "src": "/icons/icon-192.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "any" - }, - { - "src": "/icons/icon-192-maskable.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "maskable" - }, - { - "purpose": "maskable", - "src": "/icons/icon-512-maskable.png", - "sizes": "512x512", - "type": "image/png" - }, - { - "src": "/icons/icon-512.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "any" - } - - ], - "min_width": "320px" -} \ No newline at end of file diff --git a/frontend/public/manifest.json.web b/frontend/public/manifest.json.web deleted file mode 100644 index 833095d..0000000 --- a/frontend/public/manifest.json.web +++ /dev/null @@ -1,20 +0,0 @@ -[ - { - "purpose": "maskable", - "sizes": "96x96", - "src": "maskable_icon_x96.png", - "type": "image/png" - }, - { - "purpose": "maskable", - "sizes": "192x192", - "src": "maskable_icon_x192.png", - "type": "image/png" - }, - { - "purpose": "maskable", - "sizes": "512x512", - "src": "maskable_icon_x512.png", - "type": "image/png" - } -] \ No newline at end of file diff --git a/frontend/public/sw copy.js b/frontend/public/sw copy.js deleted file mode 100644 index 1300512..0000000 --- a/frontend/public/sw copy.js +++ /dev/null @@ -1,126 +0,0 @@ -// ── Firebase Messaging (background push for Android PWA) ────────────────────── -// Fill in the values below from Firebase Console → Project Settings → General → Your apps -// Leave apiKey as '__FIREBASE_API_KEY__' if not using FCM (push will be disabled). -importScripts('https://www.gstatic.com/firebasejs/10.14.1/firebase-app-compat.js'); -importScripts('https://www.gstatic.com/firebasejs/10.14.1/firebase-messaging-compat.js'); - -const FIREBASE_CONFIG = { - apiKey: "AIzaSyDx191unzXFT4WA1OvkdbrIY_c57kgruAU", - authDomain: "rosterchirp-push.firebaseapp.com", - projectId: "rosterchirp-push", - storageBucket: "rosterchirp-push.firebasestorage.app", - messagingSenderId: "126479377334", - appId: "1:126479377334:web:280abdd135cf7e0c50d717" -}; - -// Only initialise Firebase if the config has been filled in -let messaging = null; -if (FIREBASE_CONFIG.apiKey !== '__FIREBASE_API_KEY__') { - firebase.initializeApp(FIREBASE_CONFIG); - messaging = firebase.messaging(); -} - -// ── Cache ───────────────────────────────────────────────────────────────────── -const CACHE_NAME = 'rosterchirp-v1'; -const STATIC_ASSETS = ['/']; - -self.addEventListener('install', (event) => { - event.waitUntil( - caches.open(CACHE_NAME).then((cache) => cache.addAll(STATIC_ASSETS)) - ); - self.skipWaiting(); -}); - -self.addEventListener('activate', (event) => { - event.waitUntil( - caches.keys().then((keys) => - Promise.all(keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k))) - ) - ); - self.clients.claim(); -}); - -self.addEventListener('fetch', (event) => { - const url = event.request.url; - if (url.includes('/api/') || url.includes('/socket.io/') || url.includes('/manifest.json')) { - return; - } - event.respondWith( - fetch(event.request).catch(() => caches.match(event.request)) - ); -}); - -// ── Badge counter ───────────────────────────────────────────────────────────── -let badgeCount = 0; - -function showRosterChirpNotification(data) { - console.log('[SW] showRosterChirpNotification:', JSON.stringify(data)); - badgeCount++; - if (self.navigator?.setAppBadge) self.navigator.setAppBadge(badgeCount).catch(() => {}); - - return self.registration.showNotification(data.title || 'New Message', { - body: data.body || '', - icon: '/icons/icon-192.png', - badge: '/icons/icon-192-maskable.png', - data: { url: data.url || '/' }, - tag: data.groupId ? `rosterchirp-group-${data.groupId}` : 'rosterchirp-message', - renotify: true, - vibrate: [200, 100, 200], - }); -} - -// ── FCM background messages ─────────────────────────────────────────────────── -if (messaging) { - messaging.onBackgroundMessage((payload) => { - console.log('[SW] onBackgroundMessage received, data:', JSON.stringify(payload.data)); - return showRosterChirpNotification(payload.data || {}); - }); -} else { - console.warn('[SW] Firebase messaging not initialised — push notifications disabled'); -} - -// ── Raw push event (fallback diagnostic) ───────────────────────────────────── -// Fires for every push event BEFORE the Firebase SDK handles it. -// Log it so chrome://inspect shows whether the SW is even waking up. -self.addEventListener('push', (event) => { - console.log('[SW] push event received, hasData:', !!event.data, 'text:', event.data?.text?.()?.slice(0, 120)); - // Note: Firebase compat SDK registers its own push listener and handles display. - // This listener is diagnostic only — do not call showNotification() here. -}); - -// ── Notification click ──────────────────────────────────────────────────────── -self.addEventListener('notificationclick', (event) => { - event.notification.close(); - badgeCount = 0; - if (self.navigator?.clearAppBadge) self.navigator.clearAppBadge().catch(() => {}); - event.waitUntil( - clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clientList) => { - const url = event.notification.data?.url || '/'; - for (const client of clientList) { - if (client.url.includes(self.location.origin) && 'focus' in client) { - client.focus(); - return; - } - } - return clients.openWindow(url); - }) - ); -}); - -// ── Badge control messages from main thread ─────────────────────────────────── -self.addEventListener('message', (event) => { - if (event.data?.type === 'CLEAR_BADGE') { - badgeCount = 0; - if (self.navigator?.clearAppBadge) self.navigator.clearAppBadge().catch(() => {}); - } - if (event.data?.type === 'SET_BADGE') { - badgeCount = event.data.count || 0; - if (self.navigator?.setAppBadge) { - if (badgeCount > 0) { - self.navigator.setAppBadge(badgeCount).catch(() => {}); - } else { - self.navigator.clearAppBadge().catch(() => {}); - } - } - } -});