fix: check EventStore before setting loading state

- Move EventStore check before setReaderLoading(true) call
- Only show loading skeleton if content not found in store and no preview data
- This prevents loading skeleton from appearing when cached content is available
- Fixes the core issue where offline mode shows loading skeleton with cached content
This commit is contained in:
Gigi
2025-10-30 20:21:59 +01:00
parent 15b3b5b990
commit 35a8411d9b

View File

@@ -85,47 +85,18 @@ export function useArticleLoader({
// when we know the article coordinate // when we know the article coordinate
setHighlightsLoading(false) // Don't show loading yet setHighlightsLoading(false) // Don't show loading yet
// If we have preview data from navigation, show it immediately (no skeleton!)
if (previewData) {
setCurrentTitle(previewData.title)
setReaderContent({
title: previewData.title,
markdown: '', // Will be loaded from store or relay
image: previewData.image,
summary: previewData.summary,
published: previewData.published,
url: `nostr:${naddr}`
})
setReaderLoading(false) // Turn off loading immediately - we have the preview!
} else {
setReaderLoading(true)
setReaderContent(undefined)
}
try {
// Decode naddr to filter
const decoded = nip19.decode(naddr)
if (decoded.type !== 'naddr') {
throw new Error('Invalid naddr format')
}
const pointer = decoded.data as AddressPointer
const filter = {
kinds: [pointer.kind],
authors: [pointer.pubkey],
'#d': [pointer.identifier]
}
let firstEmitted = false
let latestEvent: NostrEvent | null = null
// Check eventStore first for instant load (from bookmark cards, explore, etc.) // Check eventStore first for instant load (from bookmark cards, explore, etc.)
let foundInStore = false
if (eventStore) { if (eventStore) {
try { try {
// Decode naddr to get the coordinate
const decoded = nip19.decode(naddr)
if (decoded.type === 'naddr') {
const pointer = decoded.data as AddressPointer
const coordinate = `${pointer.kind}:${pointer.pubkey}:${pointer.identifier}` const coordinate = `${pointer.kind}:${pointer.pubkey}:${pointer.identifier}`
const storedEvent = eventStore.getEvent?.(coordinate) const storedEvent = eventStore.getEvent?.(coordinate)
if (storedEvent) { if (storedEvent) {
latestEvent = storedEvent as NostrEvent foundInStore = true
firstEmitted = true
const title = Helpers.getArticleTitle(storedEvent) || 'Untitled Article' const title = Helpers.getArticleTitle(storedEvent) || 'Untitled Article'
setCurrentTitle(title) setCurrentTitle(title)
const image = Helpers.getArticleImage(storedEvent) const image = Helpers.getArticleImage(storedEvent)
@@ -150,11 +121,46 @@ export function useArticleLoader({
// This prevents unnecessary relay queries when offline // This prevents unnecessary relay queries when offline
return return
} }
}
} catch (err) { } catch (err) {
// Ignore store errors, fall through to relay query // Ignore store errors, fall through to relay query
} }
} }
// If we have preview data from navigation, show it immediately (no skeleton!)
if (previewData) {
setCurrentTitle(previewData.title)
setReaderContent({
title: previewData.title,
markdown: '', // Will be loaded from store or relay
image: previewData.image,
summary: previewData.summary,
published: previewData.published,
url: `nostr:${naddr}`
})
setReaderLoading(false) // Turn off loading immediately - we have the preview!
} else if (!foundInStore) {
// Only show loading if we didn't find content in store and no preview data
setReaderLoading(true)
setReaderContent(undefined)
}
try {
// Decode naddr to filter
const decoded = nip19.decode(naddr)
if (decoded.type !== 'naddr') {
throw new Error('Invalid naddr format')
}
const pointer = decoded.data as AddressPointer
const filter = {
kinds: [pointer.kind],
authors: [pointer.pubkey],
'#d': [pointer.identifier]
}
let firstEmitted = false
let latestEvent: NostrEvent | null = null
// Stream local-first via queryEvents; rely on EOSE (no timeouts) // Stream local-first via queryEvents; rely on EOSE (no timeouts)
const events = await queryEvents(relayPool, filter, { const events = await queryEvents(relayPool, filter, {
onEvent: (evt) => { onEvent: (evt) => {