From cb6e71d75e526f207b0c4a8f08d660fdde3e7e98 Mon Sep 17 00:00:00 2001
From: Adam Mathes <adam@adammathes.com>
Date: Sat, 14 Feb 2026 12:36:04 -0800
Subject: fix: auto-load more items when pressing 'j' on last
 item\n\nPreviously, if you were focused on the last loaded item and that item
 was\nvery long (extending past the viewport), pressing 'j' would do
 nothing\nbecause there were no more items loaded yet.\n\nNow, when the user
 presses 'j' and lands on the last item, we automatically\ntrigger loading
 more items (if available), ensuring that the next 'j' press\nwill work as
 expected.\n\nAdded test to verify this behavior works correctly.

---
 frontend/src/components/FeedItems.test.tsx | 39 ++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

(limited to 'frontend/src/components/FeedItems.test.tsx')

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());
+    });
+  });
 });
-- 
cgit v1.2.3

