fix: preload images when loading articles from cache

When loading articles from localStorage cache, images aren't automatically
cached by the Service Worker because they're not fetched until the <img> tag
renders. If the user goes offline before that, images won't be available.

Now we:
1. Added preloadImage() function to explicitly fetch images via Image() and fetch()
2. Preload images when loading from localStorage cache
3. Preload images when receiving first event from relays

This ensures images are cached by Service Worker before going offline,
making them available on refresh when offline.
This commit is contained in:
Gigi
2025-10-31 00:50:52 +01:00
parent 6f5b87136b
commit aeedc622b1
2 changed files with 35 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ import { Helpers } from 'applesauce-core'
import { queryEvents } from '../services/dataFetch'
import { fetchArticleByNaddr, getFromCache, saveToCache } from '../services/articleService'
import { fetchHighlightsForArticle } from '../services/highlightService'
import { preloadImage } from './useImageCache'
import { ReadableContent } from '../services/readerService'
import { Highlight } from '../types/highlights'
import { NostrEvent } from 'nostr-tools'
@@ -111,6 +112,13 @@ export function useArticleLoader({
setSelectedUrl(`nostr:${naddr}`)
setIsCollapsed(true)
// Preload image if available to ensure it's cached by Service Worker
// This ensures images are available when offline
if (cachedArticle.image) {
console.log('[article-loader] Preloading image for offline access:', cachedArticle.image)
preloadImage(cachedArticle.image)
}
// Store in EventStore for future lookups
if (eventStore) {
try {
@@ -353,6 +361,12 @@ export function useArticleLoader({
}
saveToCache(naddr, articleContent)
// Preload image to ensure it's cached by Service Worker
if (image) {
console.log('[article-loader] Preloading image for offline access:', image)
preloadImage(image)
}
console.log('[article-loader] UI updated with first event and saved to cache')
}
}

View File

@@ -28,3 +28,24 @@ export function useCacheImageOnLoad(
void imageUrl
}
/**
* Preload an image URL to ensure it's cached by the Service Worker
* This is useful when loading content from cache - we want to ensure
* images are cached before going offline
*/
export function preloadImage(imageUrl: string | undefined): void {
if (!imageUrl) return
// Create a link element with rel=prefetch or use Image object to trigger fetch
// Service Worker will intercept and cache the request
const img = new Image()
img.src = imageUrl
// Also try using fetch to explicitly trigger Service Worker
// This ensures the image is cached even if <img> tag hasn't rendered yet
fetch(imageUrl, { mode: 'no-cors' }).catch(() => {
// Ignore errors - image might not be CORS-enabled, but SW will still cache it
// The Image() approach above will work for most cases
})
}