diff --git a/images/icon-128x128.webp b/images/icon-128x128.webp new file mode 100644 index 0000000..79c9116 Binary files /dev/null and b/images/icon-128x128.webp differ diff --git a/images/icon-144x144.webp b/images/icon-144x144.webp new file mode 100644 index 0000000..6293629 Binary files /dev/null and b/images/icon-144x144.webp differ diff --git a/images/icon-152x152.webp b/images/icon-152x152.webp new file mode 100644 index 0000000..146782f Binary files /dev/null and b/images/icon-152x152.webp differ diff --git a/images/icon-192x192.webp b/images/icon-192x192.webp new file mode 100644 index 0000000..05f4bd8 Binary files /dev/null and b/images/icon-192x192.webp differ diff --git a/images/icon-256x256.webp b/images/icon-256x256.webp new file mode 100644 index 0000000..efdc18b Binary files /dev/null and b/images/icon-256x256.webp differ diff --git a/images/icon-384x384.webp b/images/icon-384x384.webp new file mode 100644 index 0000000..4c0c9ba Binary files /dev/null and b/images/icon-384x384.webp differ diff --git a/images/icon-48x48.webp b/images/icon-48x48.webp new file mode 100644 index 0000000..4ac09a1 Binary files /dev/null and b/images/icon-48x48.webp differ diff --git a/images/icon-512.png b/images/icon-512.png deleted file mode 100644 index 4f90024..0000000 Binary files a/images/icon-512.png and /dev/null differ diff --git a/images/icon-512x512.webp b/images/icon-512x512.webp new file mode 100644 index 0000000..fef87c1 Binary files /dev/null and b/images/icon-512x512.webp differ diff --git a/images/icon-72x72.webp b/images/icon-72x72.webp new file mode 100644 index 0000000..5ff0e59 Binary files /dev/null and b/images/icon-72x72.webp differ diff --git a/images/icon-96x96.webp b/images/icon-96x96.webp new file mode 100644 index 0000000..f639674 Binary files /dev/null and b/images/icon-96x96.webp differ diff --git a/public/js/main.js b/public/js/main.js index 5caf147..110bbcf 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -279,5 +279,20 @@ document.addEventListener('visibilitychange', () => { } }); +if ('serviceWorker' in navigator) { + window.addEventListener('load', () => { + navigator.serviceWorker.register('/service-worker.js') + .then(registration => { + console.log('Service Worker registered! Scope: ', registration.scope); + }) + .catch(err => { + console.error('Service Worker registration failed: ', err); + }); + }); +} + +// Attach global listeners that are always present on the page. +document.getElementById('sign-out-btn').addEventListener('click', () => handleSignOut('You have been signed out.')); + // Initial call to start the app on page load. initializeApp(); \ No newline at end of file diff --git a/public/manifest.json b/public/manifest.json index f122983..e216d17 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,21 +1,60 @@ { - "name": "TimeTracker", - "short_name": "TimeTracker", - "start_url": "/", - "display": "standalone", - "background_color": "#f3f4f6", - "theme_color": "#4f46e5", - "description": "A simple time tracking application.", + "name": "Time Pulse", + "short_name": "Time Pulse", "icons": [ { - "src": "/images/icon-192.png", - "sizes": "192x192", - "type": "image/png" + "src": "icons/icon-48x48.webp", + "sizes": "48x48", + "type": "image/webp" }, { - "src": "/images/icon-512.png", + "src": "icons/icon-72x72.webp", + "sizes": "72x72", + "type": "image/webp" + }, + { + "src": "icons/icon-96x96.webp", + "sizes": "96x96", + "type": "image/webp" + }, + { + "src": "icons/icon-128x128.webp", + "sizes": "128x128", + "type": "image/webp" + }, + { + "src": "icons/icon-144x144.webp", + "sizes": "144x144", + "type": "image/webp" + }, + { + "src": "icons/icon-152x152.webp", + "sizes": "152x152", + "type": "image/webp" + }, + { + "src": "icons/icon-192x192.webp", + "sizes": "192x192", + "type": "image/webp" + }, + { + "src": "icons/icon-256x256.webp", + "sizes": "256x256", + "type": "image/webp" + }, + { + "src": "icons/icon-384x384.webp", + "sizes": "384x384", + "type": "image/webp" + }, + { + "src": "icons/icon-512x512.webp", "sizes": "512x512", - "type": "image/png" + "type": "image/webp" } - ] -} + ], + "start_url": "/", + "display": "standalone", + "background_color": "#ffffff", + "theme_color": "#000000" +} \ No newline at end of file diff --git a/public/sw.js b/public/sw.js index 3f5324c..5f87129 100644 --- a/public/sw.js +++ b/public/sw.js @@ -1,63 +1,42 @@ -const CACHE_NAME = 'timetracker-debug-v1'; -const urlsToCache = ['/', '/index.html', '/manifest.json']; +const CACHE_NAME = 'timetracker-v1'; +// This list should include all the essential files for your app's shell. +const filesToCache = [ + '/', + '/index.html', + '/style/style.css', + '/js/main.js', + '/js/ui.js', + '/js/api.js', + '/js/utils.js', + '/images/icon-192x192.png', + '/images/icon-512x512.png' +]; -self.addEventListener('install', (event) => { - console.log('[SW] Install event triggered'); +// The install event runs when the service worker is first installed. +self.addEventListener('install', event => { + console.log('Service worker install event!'); event.waitUntil( caches.open(CACHE_NAME) .then(cache => { - console.log('[SW] Caching:', urlsToCache); - return cache.addAll(urlsToCache); - }) - .catch(err => { - console.error('[SW] Install failed:', err); + console.log('Caching app shell'); + return cache.addAll(filesToCache); }) ); }); -self.addEventListener('activate', (event) => { - console.log('[SW] Activate event'); - event.waitUntil( - caches.keys().then(keys => - Promise.all( - keys.map(key => { - if (key !== CACHE_NAME) { - console.log('[SW] Deleting old cache:', key); - return caches.delete(key); - } - }) - ) - ) - ); -}); - -self.addEventListener('fetch', (event) => { - if (event.request.method !== 'GET') return; - - console.log('[SW] Fetching:', event.request.url); - +// The fetch event runs for every network request the page makes. +self.addEventListener('fetch', event => { + // We only want to handle GET requests. + if (event.request.method !== 'GET' || event.request.url.includes('/api/')) { + return; + } + event.respondWith( - caches.match(event.request).then(cached => { - if (cached) { - console.log('[SW] Serving from cache:', event.request.url); - return cached; - } - - return fetch(event.request) - .then(response => { - if ( - response && - response.status === 200 && - response.type === 'basic' - ) { - const cloned = response.clone(); - caches.open(CACHE_NAME).then(cache => { - cache.put(event.request, cloned); - }); - } - return response; - }) - .catch(() => new Response('You are offline.', { status: 503 })); - }) + caches.match(event.request) + .then(response => { + // If we have a cached version, return it. + // Otherwise, fetch it from the network. + return response || fetch(event.request); + }) ); -}); +}); \ No newline at end of file