fix: improve image cache resilience for offline viewing

- Clean up stale metadata when Cache API doesn't have cached data
- Handle online/offline state properly in image loading
- Show original URL when online, blob URL from cache when offline
- Prevent cache misses when browser clears Cache API on hard reload
This commit is contained in:
Gigi
2025-10-09 18:15:30 +01:00
parent 60975b449d
commit b20a67d4d0
2 changed files with 53 additions and 42 deletions

View File

@@ -31,51 +31,54 @@ export function useImageCache(
// Store imageUrl in local variable for closure
const urlToCache = imageUrl
// Check if image is in cache metadata (fast synchronous check)
const isCached = getCachedImage(urlToCache)
const isOffline = !navigator.onLine
if (isCached) {
// Load the cached image asynchronously
loadCachedImage(urlToCache)
.then(blobUrl => {
if (blobUrl) {
console.log('📦 Using cached image:', urlToCache.substring(0, 50))
setCachedUrl(blobUrl)
} else {
// Not actually cached, fall through to caching logic
setCachedUrl(urlToCache)
cacheInBackground()
}
})
.catch(err => {
console.error('Failed to load cached image:', err)
setCachedUrl(urlToCache)
})
} else {
// Not cached, show original and cache in background
// When online: show original URL first for immediate display
// When offline: don't show anything until we load from cache
if (!isOffline) {
setCachedUrl(urlToCache)
cacheInBackground()
}
function cacheInBackground() {
if (!isLoading) {
setIsLoading(true)
const maxSize = settings?.imageCacheSizeMB ?? 210
cacheImage(urlToCache, maxSize)
.then(blobUrl => {
setCachedUrl(blobUrl)
})
.catch(err => {
console.error('Failed to cache image:', err)
// Keep using original URL on error
})
.finally(() => {
setIsLoading(false)
})
}
}
// Try to load from cache asynchronously
loadCachedImage(urlToCache)
.then(blobUrl => {
if (blobUrl) {
console.log('📦 Using cached image:', urlToCache.substring(0, 50))
setCachedUrl(blobUrl)
} else if (!isOffline) {
// Not cached and online - cache it now
if (!isLoading) {
setIsLoading(true)
const maxSize = settings?.imageCacheSizeMB ?? 210
cacheImage(urlToCache, maxSize)
.then(newBlobUrl => {
// Only update if we got a blob URL back
if (newBlobUrl && newBlobUrl.startsWith('blob:')) {
setCachedUrl(newBlobUrl)
}
})
.catch(err => {
console.error('Failed to cache image:', err)
// Keep using original URL on error
})
.finally(() => {
setIsLoading(false)
})
}
} else {
// Offline and not cached - no image available
console.warn('⚠️ Image not available offline:', urlToCache.substring(0, 50))
setCachedUrl(undefined)
}
})
.catch(err => {
console.error('Failed to load cached image:', err)
// If online, fall back to original URL
if (!isOffline) {
setCachedUrl(urlToCache)
}
})
// Cleanup: revoke blob URLs when component unmounts or URL changes
return () => {