Logo für Webseiten-Tab implementiert

Dieser Commit ist enthalten in:
hendrik_gebhardt@gmx.de
2026-01-10 16:47:02 +00:00
committet von Server Deploy
Ursprung ef153789cc
Commit 5b1f8b1cfe
53 geänderte Dateien mit 2377 neuen und 46 gelöschten Zeilen

Datei anzeigen

@ -4,7 +4,7 @@
* Offline support and caching
*/
const CACHE_VERSION = '292';
const CACHE_VERSION = '297';
const CACHE_NAME = 'taskmate-v' + CACHE_VERSION;
const STATIC_CACHE_NAME = 'taskmate-static-v' + CACHE_VERSION;
const DYNAMIC_CACHE_NAME = 'taskmate-dynamic-v' + CACHE_VERSION;
@ -43,6 +43,7 @@ const STATIC_ASSETS = [
'/js/mobile.js',
'/js/reminders.js',
'/js/contacts.js',
'/js/pwa.js',
'/css/list.css',
'/css/mobile.css',
'/css/admin.css',
@ -52,13 +53,31 @@ const STATIC_ASSETS = [
'/css/knowledge.css',
'/css/coding.css',
'/css/reminders.css',
'/css/contacts.css'
'/css/contacts.css',
'/css/pwa.css',
'/manifest.json'
];
// API routes to cache
const API_CACHE_ROUTES = [
'/api/projects',
'/api/auth/users'
'/api/auth/users',
'/api/columns',
'/api/tasks',
'/api/labels',
'/api/proposals',
'/api/knowledge',
'/api/reminders',
'/api/contacts'
];
// Assets to skip caching
const SKIP_CACHE_PATTERNS = [
/\/api\/auth\/login/,
/\/api\/auth\/logout/,
/\/api\/files\//,
/\/uploads\//,
/socket\.io/
];
// Install event - cache static assets
@ -121,42 +140,88 @@ self.addEventListener('fetch', (event) => {
event.respondWith(handleStaticRequest(event.request));
});
// Handle static asset requests - Network First strategy
// Handle static asset requests - Cache First for assets, Network First for HTML
async function handleStaticRequest(request) {
// Try network first to always get fresh content
try {
const networkResponse = await fetch(request);
// Cache successful responses
if (networkResponse.ok) {
const cache = await caches.open(STATIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
// If network fails, try cache
const cachedResponse = await caches.match(request);
if (cachedResponse) {
console.log('[SW] Serving from cache (offline):', request.url);
return cachedResponse;
}
// Return offline page if available for navigation
if (request.mode === 'navigate') {
const url = new URL(request.url);
// Check if should skip caching
if (SKIP_CACHE_PATTERNS.some(pattern => pattern.test(url.pathname))) {
return fetch(request);
}
// For HTML files, use Network First
if (request.mode === 'navigate' || url.pathname.endsWith('.html') || url.pathname === '/') {
try {
const networkResponse = await fetch(request);
if (networkResponse.ok) {
const cache = await caches.open(STATIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
const cachedResponse = await caches.match(request);
if (cachedResponse) {
console.log('[SW] Serving HTML from cache (offline):', request.url);
return cachedResponse;
}
// Return offline page
const offlinePage = await caches.match('/index.html');
if (offlinePage) {
return offlinePage;
}
throw error;
}
}
// For static assets (CSS, JS, images), use Cache First
const cachedResponse = await caches.match(request);
if (cachedResponse) {
// Update cache in background
fetchAndCache(request);
return cachedResponse;
}
// If not in cache, fetch from network
try {
const networkResponse = await fetch(request);
if (networkResponse.ok) {
const cache = await caches.open(STATIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
console.error('[SW] Network failed for:', request.url);
throw error;
}
}
// Background cache update
async function fetchAndCache(request) {
try {
const networkResponse = await fetch(request);
if (networkResponse.ok) {
const cache = await caches.open(STATIC_CACHE_NAME);
cache.put(request, networkResponse);
}
} catch (error) {
// Silently fail - we already served from cache
}
}
// Handle API requests
async function handleApiRequest(request) {
const url = new URL(request.url);
// Check if should skip caching
if (SKIP_CACHE_PATTERNS.some(pattern => pattern.test(url.pathname))) {
return fetch(request);
}
// Check if this is a cacheable API route
const isCacheable = API_CACHE_ROUTES.some(route =>
@ -180,13 +245,22 @@ async function handleApiRequest(request) {
const cachedResponse = await caches.match(request);
if (cachedResponse) {
console.log('[SW] Serving cached API response:', request.url);
return cachedResponse;
// Add offline header to indicate cached response
const headers = new Headers(cachedResponse.headers);
headers.set('X-From-Cache', 'true');
return new Response(cachedResponse.body, {
status: cachedResponse.status,
statusText: cachedResponse.statusText,
headers: headers
});
}
}
// Return error response
return new Response(
JSON.stringify({
success: false,
error: 'Keine Internetverbindung',
offline: true
}),