Skip to content

Fix inline reader/highlight drifting to wrong article after refresh#205

Merged
disnet merged 1 commit into
mainfrom
radial/3mltqch4/bug-when-reading-an-article-in-the-summa
May 14, 2026
Merged

Fix inline reader/highlight drifting to wrong article after refresh#205
disnet merged 1 commit into
mainfrom
radial/3mltqch4/bug-when-reading-an-article-in-the-summa

Conversation

@disnet
Copy link
Copy Markdown
Owner

@disnet disnet commented May 14, 2026

Summary

  • Track feed-list selection and expansion by FeedDisplayItem.key instead of by array index, so refresh-driven re-sorts no longer move the inline reader / highlight onto a different article.
  • Keep selectedIndex / expandedIndex as derived getters so existing call sites that need an index (scroll-to-center, j/k navigation) keep working.

Why

If you click on an article in a channel and read it inline, then trigger (or auto-receive) a refresh that brings new articles in, the existing index-based selection stays put — but the array has been re-sorted by publishedAt, so the highlighted slot now belongs to a different article. The originally-clicked article appears un-expanded at its new index and is also marked-as-read because of the resolved selection. #204

Changes

  • frontend/src/lib/stores/feedView.svelte.ts
    • Replace selectedIndex / expandedIndex state with selectedKey / expandedKey (string | null).
    • Add selectByKey(key); rewrite select(index) to resolve the index to a key via currentItems.
    • Expose selectedKey / expandedKey and keep selectedIndex / expandedIndex as derived getters (findIndex against currentItems).
  • frontend/src/lib/components/feed/FeedListView.svelte
    • Selected/expanded/highlighted comparisons now compare against displayItem.key.
    • openSelectedReader resolves the item by key.
  • frontend/src/lib/components/feed/SavedListView.svelte
    • Same key-based comparison swap for SavedCard.selected.
    • openSelectedReader resolves by key.
  • frontend/src/lib/hooks/useFeedKeyboardShortcuts.svelte.ts
    • Add a getSelectedItem() helper that looks up the selected item by selectedKey.
    • Next/prev navigation computes the current index via findIndex(i => i.key === selectedKey) to preserve j/k behaviour.
    • hasSelected() now checks selectedKey !== null; the h condition checks expandedKey !== null.

Notes / risks

  • readerItem already stored the item object directly; the fullscreen reader was never affected, only the list highlight and the inline preview.
  • If a refresh removes the selected item entirely, selectedKey will not find a match in currentItems and the derived selectedIndex returns -1 — same observable state as before.
  • FeedDisplayItem.key is already trusted as unique by the keyed #each in both list views; no new uniqueness assumption.

Test plan

  • cd frontend && npm run check (passes, 0 errors)
  • Manual: open a channel with N unread, click the 4th to expand inline, trigger a refresh that brings new items, confirm the originally-clicked article stays expanded at its new index and is the one marked as read.
  • Manual: with an item selected, refresh the list, press j/k and confirm selection moves from the correct current article.
  • Manual: open fullscreen reader on an article, refresh underneath, close reader → list focus returns to the right card.
  • Manual: repeat (2) on the Saved channel via SavedListView.

🤖 Generated with Claude Code

When a refresh re-sorted the visible list (e.g. new articles arrive
during auto-poll), the inline reader / expanded card was tied to the
array index of the originally-selected item. New items pushed the
selected item to a higher index, so the highlight, inline preview,
and mark-as-read all latched onto the wrong card.

Switch the source of truth for selection and expansion from a numeric
index to FeedDisplayItem.key (already the keyed-each key, stable per
item). selectedIndex / expandedIndex are kept as derived getters so
existing call sites that need an index (scrollToCenter, j/k navigation)
keep working.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@disnet disnet merged commit 6a8806b into main May 14, 2026
3 checks passed
@disnet disnet deleted the radial/3mltqch4/bug-when-reading-an-article-in-the-summa branch May 14, 2026 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant