diff --git a/src/js/services/pushFlicIntegration.js b/src/js/services/pushFlicIntegration.js index 459dd66..310eaa0 100644 --- a/src/js/services/pushFlicIntegration.js +++ b/src/js/services/pushFlicIntegration.js @@ -82,14 +82,53 @@ function showBatteryWarning(batteryLevel) { lastBatteryWarningTimestamp = now; // Show the notification - const message = `Flic button battery is low (${batteryLevel}%). Please replace the battery soon.`; + console.log(`[PushFlic] Low battery detected: ${batteryLevel}%`); - // Show browser notification if permission granted - if (Notification.permission === 'granted') { - new Notification('Flic Button Low Battery', { - body: message, - icon: '/public/favicon.ico' + // Create an alert or toast in the UI instead of a system notification + // System notifications for battery will be handled by the service worker + try { + // Create a temporary toast notification in the UI + const toast = document.createElement('div'); + toast.className = 'battery-warning-toast'; + toast.innerHTML = ` +
+ + `; + + // Style the toast + Object.assign(toast.style, { + position: 'fixed', + bottom: '20px', + right: '20px', + backgroundColor: '#ff9800', + color: 'white', + padding: '15px', + borderRadius: '4px', + boxShadow: '0 2px 5px rgba(0,0,0,0.2)', + zIndex: '9999', + display: 'flex', + alignItems: 'center', + maxWidth: '300px' }); + + // Add to document + document.body.appendChild(toast); + + // Remove after 5 seconds + setTimeout(() => { + toast.style.opacity = '0'; + toast.style.transition = 'opacity 0.5s ease'; + setTimeout(() => { + if (toast.parentNode) { + document.body.removeChild(toast); + } + }, 500); + }, 5000); + } catch (error) { + console.error('[PushFlic] Error showing battery warning toast:', error); } } diff --git a/sw.js b/sw.js index c722146..d1e9086 100644 --- a/sw.js +++ b/sw.js @@ -134,6 +134,17 @@ self.addEventListener('push', event => { }; console.log('[ServiceWorker] Preparing message payload:', messagePayload); + + // Check if this is a low battery alert that needs a notification + const isBatteryAlert = messagePayload.batteryLevel !== undefined && + messagePayload.batteryLevel < 50; // Use the same threshold as in the app + + if (isBatteryAlert) { + console.log(`[ServiceWorker] Low battery alert detected: ${messagePayload.batteryLevel}%`); + // Change notification title/body for battery alerts + pushData.title = 'Flic Button Low Battery'; + pushData.body = `Battery level is ${messagePayload.batteryLevel}%. Please replace batteries soon.`; + } // Send message to all open PWA windows controlled by this SW event.waitUntil( @@ -143,12 +154,16 @@ self.addEventListener('push', event => { }).then(clientList => { if (!clientList || clientList.length === 0) { console.log('[ServiceWorker] No client windows found to send message to.'); - // If no window is open, we MUST show a notification - return self.registration.showNotification(pushData.title, { - body: pushData.body, - icon: '/icons/android-chrome-192x192.png', // Updated path - data: pushData.data // Pass data if needed when notification is clicked - }); + // If no window is open AND this is a battery alert, show a notification + if (isBatteryAlert) { + return self.registration.showNotification(pushData.title, { + body: pushData.body, + icon: '/icons/android-chrome-192x192.png', // Updated path + data: pushData.data // Pass data if needed when notification is clicked + }); + } + // Otherwise, don't show notification for regular button presses + return Promise.resolve(); } // Post message to each client with improved reliability @@ -160,7 +175,6 @@ self.addEventListener('push', event => { client.postMessage(messagePayload); messageSent = true; - // REMOVED: Don't try to focus the client as it causes errors // Just return true to indicate message was sent return Promise.resolve(true); } catch (error) { @@ -170,32 +184,19 @@ self.addEventListener('push', event => { }); return Promise.all(sendPromises).then(() => { - // Always show a notification unless we're sure the app can handle it visibly - // This ensures the user gets notified even if the app doesn't process the message - return self.registration.showNotification(pushData.title, { - body: pushData.body, - icon: '/icons/android-chrome-192x192.png', - data: pushData.data - }); + // Only show a notification if this is a battery alert + if (isBatteryAlert) { + return self.registration.showNotification(pushData.title, { + body: pushData.body, + icon: '/icons/android-chrome-192x192.png', + data: pushData.data + }); + } + // For regular button presses, don't show notifications + return Promise.resolve(); }); }) ); - - // --- Show a notification (Important!) --- - // Push notifications generally REQUIRE showing a notification to the user - // unless the PWA is already in the foreground AND handles the event visually. - // It's safer to always show one unless you have complex foreground detection. - /* This part is now handled inside the clients.matchAll promise */ - /* - const notificationOptions = { - body: pushData.body, - icon: './icons/android-chrome-192x192.png', // Optional: path to an icon - data: pushData.data // Attach data if needed when notification is clicked - }; - event.waitUntil( - self.registration.showNotification(pushData.title, notificationOptions) - ); - */ }); // This helps with navigation after app is installed