only show notifications for low battery

This commit is contained in:
cpu
2025-03-29 06:48:06 +01:00
parent 7b06d7f3ea
commit 8261ee3326
2 changed files with 76 additions and 36 deletions

View File

@@ -82,14 +82,53 @@ function showBatteryWarning(batteryLevel) {
lastBatteryWarningTimestamp = now; lastBatteryWarningTimestamp = now;
// Show the notification // 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 // Create an alert or toast in the UI instead of a system notification
if (Notification.permission === 'granted') { // System notifications for battery will be handled by the service worker
new Notification('Flic Button Low Battery', { try {
body: message, // Create a temporary toast notification in the UI
icon: '/public/favicon.ico' const toast = document.createElement('div');
toast.className = 'battery-warning-toast';
toast.innerHTML = `
<div class="toast-icon">⚠️</div>
<div class="toast-message">
<strong>Flic Button Low Battery</strong>
<p>Battery level is ${batteryLevel}%. Please replace soon.</p>
</div>
`;
// 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);
} }
} }

61
sw.js
View File

@@ -135,6 +135,17 @@ self.addEventListener('push', event => {
console.log('[ServiceWorker] Preparing message payload:', messagePayload); 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 // Send message to all open PWA windows controlled by this SW
event.waitUntil( event.waitUntil(
self.clients.matchAll({ self.clients.matchAll({
@@ -143,12 +154,16 @@ self.addEventListener('push', event => {
}).then(clientList => { }).then(clientList => {
if (!clientList || clientList.length === 0) { if (!clientList || clientList.length === 0) {
console.log('[ServiceWorker] No client windows found to send message to.'); console.log('[ServiceWorker] No client windows found to send message to.');
// If no window is open, we MUST show a notification // If no window is open AND this is a battery alert, show a notification
return self.registration.showNotification(pushData.title, { if (isBatteryAlert) {
body: pushData.body, return self.registration.showNotification(pushData.title, {
icon: '/icons/android-chrome-192x192.png', // Updated path body: pushData.body,
data: pushData.data // Pass data if needed when notification is clicked 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 // Post message to each client with improved reliability
@@ -160,7 +175,6 @@ self.addEventListener('push', event => {
client.postMessage(messagePayload); client.postMessage(messagePayload);
messageSent = true; messageSent = true;
// REMOVED: Don't try to focus the client as it causes errors
// Just return true to indicate message was sent // Just return true to indicate message was sent
return Promise.resolve(true); return Promise.resolve(true);
} catch (error) { } catch (error) {
@@ -170,32 +184,19 @@ self.addEventListener('push', event => {
}); });
return Promise.all(sendPromises).then(() => { return Promise.all(sendPromises).then(() => {
// Always show a notification unless we're sure the app can handle it visibly // Only show a notification if this is a battery alert
// This ensures the user gets notified even if the app doesn't process the message if (isBatteryAlert) {
return self.registration.showNotification(pushData.title, { return self.registration.showNotification(pushData.title, {
body: pushData.body, body: pushData.body,
icon: '/icons/android-chrome-192x192.png', icon: '/icons/android-chrome-192x192.png',
data: pushData.data 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 // This helps with navigation after app is installed