mirror of
https://github.com/dergigi/boris.git
synced 2025-12-17 14:44:26 +01:00
feat: implement robust highlight loading with fallback mechanisms
- Add detailed logging to track highlight loading process - Implement fallback timeout mechanism to retry highlight loading after 2 seconds - Add backup effect that triggers when article coordinate changes - Ensure highlights are loaded reliably after article content is fully loaded - Add console logging to help debug highlight loading issues
This commit is contained in:
@@ -246,7 +246,10 @@ const Bookmarks: React.FC<BookmarksProps> = ({
|
|||||||
setCurrentArticleCoordinate,
|
setCurrentArticleCoordinate,
|
||||||
setCurrentArticleEventId,
|
setCurrentArticleEventId,
|
||||||
setCurrentArticle,
|
setCurrentArticle,
|
||||||
settings
|
settings,
|
||||||
|
currentArticleCoordinate,
|
||||||
|
currentArticleEventId,
|
||||||
|
highlightsLoading
|
||||||
})
|
})
|
||||||
|
|
||||||
// Load external URL if /r/* route is used
|
// Load external URL if /r/* route is used
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ interface UseArticleLoaderProps {
|
|||||||
setCurrentArticleEventId: (id: string | undefined) => void
|
setCurrentArticleEventId: (id: string | undefined) => void
|
||||||
setCurrentArticle?: (article: NostrEvent) => void
|
setCurrentArticle?: (article: NostrEvent) => void
|
||||||
settings?: UserSettings
|
settings?: UserSettings
|
||||||
|
currentArticleCoordinate?: string
|
||||||
|
currentArticleEventId?: string
|
||||||
|
highlightsLoading?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useArticleLoader({
|
export function useArticleLoader({
|
||||||
@@ -49,7 +52,10 @@ export function useArticleLoader({
|
|||||||
setCurrentArticleCoordinate,
|
setCurrentArticleCoordinate,
|
||||||
setCurrentArticleEventId,
|
setCurrentArticleEventId,
|
||||||
setCurrentArticle,
|
setCurrentArticle,
|
||||||
settings
|
settings,
|
||||||
|
currentArticleCoordinate,
|
||||||
|
currentArticleEventId,
|
||||||
|
highlightsLoading
|
||||||
}: UseArticleLoaderProps) {
|
}: UseArticleLoaderProps) {
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const mountedRef = useRef(true)
|
const mountedRef = useRef(true)
|
||||||
@@ -230,8 +236,8 @@ export function useArticleLoader({
|
|||||||
setCurrentArticle?.(article.event)
|
setCurrentArticle?.(article.event)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch highlights after content is shown
|
// Fetch highlights after content is shown - ensure this happens reliably
|
||||||
try {
|
const fetchHighlightsForCurrentArticle = async () => {
|
||||||
if (!mountedRef.current) return
|
if (!mountedRef.current) return
|
||||||
|
|
||||||
const le = latestEvent as NostrEvent | null
|
const le = latestEvent as NostrEvent | null
|
||||||
@@ -240,6 +246,7 @@ export function useArticleLoader({
|
|||||||
const eventId = le ? le.id : undefined
|
const eventId = le ? le.id : undefined
|
||||||
|
|
||||||
if (coord && eventId) {
|
if (coord && eventId) {
|
||||||
|
console.log('Loading highlights for article:', coord, eventId)
|
||||||
setHighlightsLoading(true)
|
setHighlightsLoading(true)
|
||||||
// Clear highlights that don't belong to this article coordinate
|
// Clear highlights that don't belong to this article coordinate
|
||||||
setHighlights((prev) => {
|
setHighlights((prev) => {
|
||||||
@@ -248,28 +255,41 @@ export function useArticleLoader({
|
|||||||
return h.eventReference === coord || h.eventReference === eventId
|
return h.eventReference === coord || h.eventReference === eventId
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
await fetchHighlightsForArticle(
|
|
||||||
relayPool,
|
try {
|
||||||
coord,
|
await fetchHighlightsForArticle(
|
||||||
eventId,
|
relayPool,
|
||||||
(highlight) => {
|
coord,
|
||||||
if (!mountedRef.current) return
|
eventId,
|
||||||
if (currentRequestIdRef.current !== requestId) return
|
(highlight) => {
|
||||||
setHighlights((prev: Highlight[]) => {
|
if (!mountedRef.current) return
|
||||||
if (prev.some((h: Highlight) => h.id === highlight.id)) return prev
|
if (currentRequestIdRef.current !== requestId) return
|
||||||
const next = [highlight, ...prev]
|
console.log('Received highlight:', highlight.id, highlight.content.substring(0, 50))
|
||||||
return next.sort((a, b) => b.created_at - a.created_at)
|
setHighlights((prev: Highlight[]) => {
|
||||||
})
|
if (prev.some((h: Highlight) => h.id === highlight.id)) return prev
|
||||||
},
|
const next = [highlight, ...prev]
|
||||||
settingsRef.current,
|
return next.sort((a, b) => b.created_at - a.created_at)
|
||||||
false, // force
|
})
|
||||||
eventStore || undefined
|
},
|
||||||
)
|
settingsRef.current,
|
||||||
|
false, // force
|
||||||
|
eventStore || undefined
|
||||||
|
)
|
||||||
|
console.log('Finished loading highlights for article:', coord)
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to fetch highlights for article:', coord, err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
console.log('No article coordinate or event ID available for highlights')
|
||||||
// No article event to fetch highlights for - clear and don't show loading
|
// No article event to fetch highlights for - clear and don't show loading
|
||||||
setHighlights([])
|
setHighlights([])
|
||||||
setHighlightsLoading(false)
|
setHighlightsLoading(false)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always try to fetch highlights, even if we don't have the latest event yet
|
||||||
|
try {
|
||||||
|
await fetchHighlightsForCurrentArticle()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to fetch highlights:', err)
|
console.error('Failed to fetch highlights:', err)
|
||||||
} finally {
|
} finally {
|
||||||
@@ -277,6 +297,24 @@ export function useArticleLoader({
|
|||||||
setHighlightsLoading(false)
|
setHighlightsLoading(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a fallback mechanism to ensure highlights are loaded
|
||||||
|
// This helps with cases where the initial highlight loading might fail
|
||||||
|
const fallbackTimeout = setTimeout(async () => {
|
||||||
|
if (mountedRef.current && currentRequestIdRef.current === requestId) {
|
||||||
|
console.log('Fallback: Attempting to load highlights again...')
|
||||||
|
try {
|
||||||
|
await fetchHighlightsForCurrentArticle()
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Fallback highlight loading failed:', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 2000) // Retry after 2 seconds
|
||||||
|
|
||||||
|
// Clean up timeout if component unmounts or new article loads
|
||||||
|
return () => {
|
||||||
|
clearTimeout(fallbackTimeout)
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to load article:', err)
|
console.error('Failed to load article:', err)
|
||||||
if (mountedRef.current && currentRequestIdRef.current === requestId) {
|
if (mountedRef.current && currentRequestIdRef.current === requestId) {
|
||||||
@@ -310,4 +348,44 @@ export function useArticleLoader({
|
|||||||
setCurrentArticleEventId,
|
setCurrentArticleEventId,
|
||||||
setCurrentArticle
|
setCurrentArticle
|
||||||
])
|
])
|
||||||
|
|
||||||
|
// Additional effect to ensure highlights are loaded when article coordinate changes
|
||||||
|
// This provides a backup mechanism in case the main loading doesn't work
|
||||||
|
useEffect(() => {
|
||||||
|
if (!relayPool || !eventStore) return
|
||||||
|
|
||||||
|
const loadHighlightsIfNeeded = async () => {
|
||||||
|
// Only load if we have a coordinate but no highlights are loading
|
||||||
|
if (currentArticleCoordinate && currentArticleEventId && !highlightsLoading) {
|
||||||
|
console.log('Backup: Loading highlights for coordinate:', currentArticleCoordinate)
|
||||||
|
try {
|
||||||
|
setHighlightsLoading(true)
|
||||||
|
await fetchHighlightsForArticle(
|
||||||
|
relayPool,
|
||||||
|
currentArticleCoordinate,
|
||||||
|
currentArticleEventId,
|
||||||
|
(highlight) => {
|
||||||
|
setHighlights((prev: Highlight[]) => {
|
||||||
|
if (prev.some((h: Highlight) => h.id === highlight.id)) return prev
|
||||||
|
const next = [highlight, ...prev]
|
||||||
|
return next.sort((a, b) => b.created_at - a.created_at)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
settingsRef.current,
|
||||||
|
false, // force
|
||||||
|
eventStore
|
||||||
|
)
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Backup highlight loading failed:', err)
|
||||||
|
} finally {
|
||||||
|
setHighlightsLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Small delay to ensure the main loading has a chance to work first
|
||||||
|
const timeout = setTimeout(loadHighlightsIfNeeded, 1000)
|
||||||
|
|
||||||
|
return () => clearTimeout(timeout)
|
||||||
|
}, [currentArticleCoordinate, currentArticleEventId, relayPool, eventStore, highlightsLoading])
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user