diff options
| author | Adam Mathes <adam@adammathes.com> | 2026-02-16 08:59:56 -0800 |
|---|---|---|
| committer | Adam Mathes <adam@adammathes.com> | 2026-02-16 08:59:56 -0800 |
| commit | 1bed4bbd9a0606f9d3edfbf0ccfd1499793f8712 (patch) | |
| tree | 07c7665ff374892f75fab8fcb4932936ef252a18 /frontend/src/components | |
| parent | 466804699bf42e403913d2fb435327b554d537d1 (diff) | |
| download | neko-1bed4bbd9a0606f9d3edfbf0ccfd1499793f8712.tar.gz neko-1bed4bbd9a0606f9d3edfbf0ccfd1499793f8712.tar.bz2 neko-1bed4bbd9a0606f9d3edfbf0ccfd1499793f8712.zip | |
Fix v3 theme contrast and sync with v2 colors, add v3 logo, and fix v2 test stability
- Sync v3 dark/light theme colors with v2 defaults
- Fix v3 settings input/select contrast in dark mode
- Add logo emoji to v3 sidebar
- Fix duplicate key warnings and side-effect issues in FeedItems.tsx (v2)
- Rebuild production assets
Diffstat (limited to 'frontend/src/components')
| -rw-r--r-- | frontend/src/components/FeedItems.tsx | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/frontend/src/components/FeedItems.tsx b/frontend/src/components/FeedItems.tsx index dc94cfd..2c3253b 100644 --- a/frontend/src/components/FeedItems.tsx +++ b/frontend/src/components/FeedItems.tsx @@ -89,9 +89,13 @@ export default function FeedItems() { } return res.json(); }) - .then((data) => { + .then((data: Item[]) => { if (maxId) { - setItems((prev) => [...prev, ...data]); + setItems((prev) => { + const existingIds = new Set(prev.map(i => i._id)); + const newItems = data.filter(i => !existingIds.has(i._id)); + return [...prev, ...newItems]; + }); } else { setItems(data); } @@ -148,49 +152,43 @@ export default function FeedItems() { useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { - // Use ref to get latest items without effect re-running const currentItems = itemsRef.current; if (currentItems.length === 0) return; if (e.key === 'j') { - setSelectedIndex((prev) => { - const nextIndex = Math.min(prev + 1, currentItems.length - 1); - if (nextIndex !== prev) { - const item = currentItems[nextIndex]; - if (!item.read) { - markAsRead(item); - } - scrollToItem(nextIndex); + const nextIndex = Math.min(selectedIndex + 1, currentItems.length - 1); + if (nextIndex !== selectedIndex) { + setSelectedIndex(nextIndex); + const item = currentItems[nextIndex]; + if (!item.read) { + markAsRead(item); } + scrollToItem(nextIndex); // Trigger load more if needed if (nextIndex === currentItems.length - 1 && hasMoreRef.current && !loadingMoreRef.current) { fetchItems(String(currentItems[currentItems.length - 1]._id)); } - - return nextIndex; - }); + } else if (hasMoreRef.current && !loadingMoreRef.current) { + // Already at last item, but more can be loaded + fetchItems(String(currentItems[currentItems.length - 1]._id)); + } } else if (e.key === 'k') { - setSelectedIndex((prev) => { - const nextIndex = Math.max(prev - 1, 0); - if (nextIndex !== prev) { - scrollToItem(nextIndex); - } - return nextIndex; - }); + const nextIndex = Math.max(selectedIndex - 1, 0); + if (nextIndex !== selectedIndex) { + setSelectedIndex(nextIndex); + scrollToItem(nextIndex); + } } else if (e.key === 's') { - setSelectedIndex((currentIndex) => { - if (currentIndex >= 0 && currentIndex < currentItems.length) { - toggleStar(currentItems[currentIndex]); - } - return currentIndex; - }); + if (selectedIndex >= 0 && selectedIndex < currentItems.length) { + toggleStar(currentItems[selectedIndex]); + } } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); - }, [markAsRead, scrollToItem, toggleStar, fetchItems]); + }, [markAsRead, scrollToItem, toggleStar, fetchItems, selectedIndex]); // Stable Observer |
