import React, { useState, useEffect } from 'react'; import { Link } from 'react-router-dom'; import { Helmet } from 'react-helmet'; import localForage from 'localforage'; import { sourceLink, infoLine, logos } from './utils.js'; function Feed({ updateCache }) { const [stories, setStories] = useState(() => JSON.parse(localStorage.getItem('stories')) || false); const [error, setError] = useState(false); useEffect(() => { fetch('/api') .then(res => res.json()) .then( async (result) => { const newApiStories = result.stories; const updated = !stories || !stories.length || stories[0].id !== newApiStories[0].id; console.log('New stories available:', updated); if (!updated) return; const existingStoryIds = new Set(stories ? stories.map(s => s.id) : []); for (const newStory of [...newApiStories].reverse()) { if (existingStoryIds.has(newStory.id)) { continue; } try { const storyRes = await fetch('/api/' + newStory.id); if (!storyRes.ok) throw new Error('Story fetch failed'); const storyResult = await storyRes.json(); const fullStory = storyResult.story; await localForage.setItem(fullStory.id, fullStory); console.log('preloaded', fullStory.id, fullStory.title); updateCache(fullStory.id, fullStory); setStories(prevStories => { const currentStories = Array.isArray(prevStories) ? prevStories : []; const updatedStories = [newStory, ...currentStories]; const poppedStory = updatedStories.pop(); if (poppedStory) { localForage.removeItem(poppedStory.id); } localStorage.setItem('stories', JSON.stringify(updatedStories)); return updatedStories; }); } catch (error) { console.log('Skipping story due to fetch error', newStory.id, error); } } }, (error) => { setError(true); } ); }, [updateCache]); return (
Connection error?
} {stories ?loading...
}