aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src')
-rw-r--r--frontend/src/components/FeedItems.test.tsx39
-rw-r--r--frontend/src/components/FeedItems.tsx9
2 files changed, 47 insertions, 1 deletions
diff --git a/frontend/src/components/FeedItems.test.tsx b/frontend/src/components/FeedItems.test.tsx
index 555d8a2..cf1e708 100644
--- a/frontend/src/components/FeedItems.test.tsx
+++ b/frontend/src/components/FeedItems.test.tsx
@@ -256,4 +256,43 @@ describe('FeedItems Component', () => {
expect(global.fetch).toHaveBeenCalledWith(`/api/stream?${params.toString()}`, expect.anything());
});
});
+
+ it('loads more items when pressing j on last item', async () => {
+ const initialItems = [
+ { _id: 103, title: 'Item 3', url: 'u3', read: true, starred: false },
+ { _id: 102, title: 'Item 2', url: 'u2', read: true, starred: false },
+ { _id: 101, title: 'Item 1', url: 'u1', read: true, starred: false },
+ ];
+ const moreItems = [
+ { _id: 100, title: 'Item 0', url: 'u0', read: true, starred: false },
+ ];
+
+ (global.fetch as any)
+ .mockResolvedValueOnce({ ok: true, json: async () => initialItems })
+ .mockResolvedValueOnce({ ok: true, json: async () => moreItems });
+
+ render(
+ <MemoryRouter>
+ <FeedItems />
+ </MemoryRouter>
+ );
+
+ await waitFor(() => {
+ expect(screen.getByText('Item 1')).toBeInTheDocument();
+ });
+
+ // Navigate to the last item by pressing 'j' multiple times
+ fireEvent.keyDown(window, { key: 'j' }); // index 0
+ fireEvent.keyDown(window, { key: 'j' }); // index 1
+ fireEvent.keyDown(window, { key: 'j' }); // index 2 (last item)
+
+ // Pressing 'j' on the last item should trigger loading more
+ await waitFor(() => {
+ expect(screen.getByText('Item 0')).toBeInTheDocument();
+ const params = new URLSearchParams();
+ params.append('max_id', '101');
+ params.append('read_filter', 'unread');
+ expect(global.fetch).toHaveBeenCalledWith(`/api/stream?${params.toString()}`, expect.anything());
+ });
+ });
});
diff --git a/frontend/src/components/FeedItems.tsx b/frontend/src/components/FeedItems.tsx
index a058b70..f43852b 100644
--- a/frontend/src/components/FeedItems.tsx
+++ b/frontend/src/components/FeedItems.tsx
@@ -137,6 +137,13 @@ export default function FeedItems() {
}
scrollToItem(nextIndex);
}
+
+ // If we're now on the last item and there are more items to load,
+ // trigger loading them so the next 'j' press will work
+ if (nextIndex === items.length - 1 && hasMore && !loadingMore) {
+ fetchItems(String(items[items.length - 1]._id));
+ }
+
return nextIndex;
});
} else if (e.key === 'k') {
@@ -159,7 +166,7 @@ export default function FeedItems() {
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
- }, [items]);
+ }, [items, hasMore, loadingMore]);