limit notifications for low battery

This commit is contained in:
cpu
2025-03-29 07:05:55 +01:00
parent 8261ee3326
commit eb427d7fdd
2 changed files with 177 additions and 12 deletions

119
sw.js
View File

@@ -2,6 +2,56 @@
const CACHE_VERSION = 'v1.0.2';
const CACHE_NAME = `game-timer-${CACHE_VERSION}`;
// Store last battery warning timestamp to prevent repeated notifications
let lastBatteryWarningTimestamp = 0;
const FOUR_HOURS_MS = 4 * 60 * 60 * 1000; // 4 hours in milliseconds
// Settings cache for storing timestamps
const SETTINGS_CACHE = 'settings-cache-v1';
const TIMESTAMP_URL = new Request('/_timestamp/battery-warning');
// Function to load the timestamp from cache
async function loadTimestamp() {
try {
const cache = await caches.open(SETTINGS_CACHE);
const response = await cache.match(TIMESTAMP_URL);
if (response) {
const data = await response.json();
lastBatteryWarningTimestamp = data.timestamp;
console.log('[ServiceWorker] Loaded battery warning timestamp:', new Date(lastBatteryWarningTimestamp));
} else {
console.log('[ServiceWorker] No saved timestamp found');
}
return true;
} catch (error) {
console.error('[ServiceWorker] Error loading timestamp:', error);
return false;
}
}
// Function to save the timestamp to cache
async function saveTimestamp(timestamp) {
try {
const cache = await caches.open(SETTINGS_CACHE);
const response = new Response(JSON.stringify({ timestamp }), {
headers: { 'Content-Type': 'application/json' }
});
await cache.put(TIMESTAMP_URL, response);
console.log('[ServiceWorker] Saved battery warning timestamp:', new Date(timestamp));
return true;
} catch (error) {
console.error('[ServiceWorker] Error saving timestamp:', error);
return false;
}
}
// Initialize and load data when the service worker starts
loadTimestamp().then(success => {
console.log('[ServiceWorker] Timestamp loading ' + (success ? 'successful' : 'failed'));
});
// Files to cache
const CACHE_FILES = [
'/',
@@ -136,14 +186,32 @@ 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
const batteryLevel = messagePayload.batteryLevel;
const isBatteryLow = batteryLevel !== undefined && 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.`;
// Determine if we should show a battery notification (throttle to once every 4 hours)
let shouldShowBatteryNotification = false;
if (isBatteryLow) {
const now = Date.now();
if (now - lastBatteryWarningTimestamp > FOUR_HOURS_MS) {
// It's been more than 4 hours since the last battery notification
console.log(`[ServiceWorker] Low battery (${batteryLevel}%) - showing notification`);
lastBatteryWarningTimestamp = now;
// Save the timestamp to cache
saveTimestamp(now).catch(error => {
console.warn('[ServiceWorker] Failed to save battery warning timestamp:', error);
});
shouldShowBatteryNotification = true;
// Change notification title/body for battery alerts
pushData.title = 'Flic Button Low Battery';
pushData.body = `Battery level is ${batteryLevel}%. Please replace batteries soon.`;
} else {
console.log(`[ServiceWorker] Low battery (${batteryLevel}%) - suppressing notification (shown recently)`);
}
}
// Send message to all open PWA windows controlled by this SW
@@ -154,8 +222,8 @@ 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 AND this is a battery alert, show a notification
if (isBatteryAlert) {
// If no window is open AND this is a battery alert that should be shown, show a notification
if (shouldShowBatteryNotification) {
return self.registration.showNotification(pushData.title, {
body: pushData.body,
icon: '/icons/android-chrome-192x192.png', // Updated path
@@ -184,21 +252,48 @@ self.addEventListener('push', event => {
});
return Promise.all(sendPromises).then(() => {
// Only show a notification if this is a battery alert
if (isBatteryAlert) {
// Only show a notification if this is a battery alert that should be shown
if (shouldShowBatteryNotification) {
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
// For regular button presses or throttled battery alerts, don't show notifications
return Promise.resolve();
});
})
);
});
// Listen for messages from client
self.addEventListener('message', event => {
const message = event.data;
if (!message || typeof message !== 'object') {
return;
}
// Handle get timestamp request
if (message.type === 'get-battery-timestamp') {
console.log('[ServiceWorker] Client requested battery warning timestamp');
event.source.postMessage({
type: 'battery-timestamp',
timestamp: lastBatteryWarningTimestamp
});
}
// Handle update timestamp request
if (message.type === 'update-battery-timestamp' && message.timestamp) {
console.log('[ServiceWorker] Updating battery warning timestamp to:', new Date(message.timestamp));
lastBatteryWarningTimestamp = message.timestamp;
saveTimestamp(message.timestamp).catch(error => {
console.warn('[ServiceWorker] Failed to save updated battery warning timestamp:', error);
});
}
});
// This helps with navigation after app is installed
self.addEventListener('notificationclick', event => {
console.log('[ServiceWorker] Notification click received');