Skip to content

fix: dashboard infinite scroll re-appending the same batch of items#369

Open
builtbyproxy wants to merge 1 commit into
jon4hz:mainfrom
builtbyproxy:fix/dashboard-infinite-scroll-duplicate-items
Open

fix: dashboard infinite scroll re-appending the same batch of items#369
builtbyproxy wants to merge 1 commit into
jon4hz:mainfrom
builtbyproxy:fix/dashboard-infinite-scroll-duplicate-items

Conversation

@builtbyproxy

Copy link
Copy Markdown

Summary

Fixes #352. The media dashboard's infinite scroll can get stuck repeating the same batch of items indefinitely while scrolling.

Root cause

MediaGridManager.loadMore() (web/templates/components/media-grid.templ) only advanced its rendering cursor (this.renderedItems) and reset this.isLoading inside the setTimeout(..., delay) callback that kicks off renderItems(). But renderItems() itself staggers each card's skeleton-to-content swap with its own per-item setTimeout (index * 50ms), so the grid keeps growing/reflowing well after loadMore()'s own callback has already returned and cleared isLoading.

Any layout reflow during that window (for example, the dashboard's default request-status filter running ~10ms after load, which briefly empties the grid via clearGrid()) can nudge the scroll sentinel back into the IntersectionObserver's rootMargin and fire loadMore() again. Since the cursor hadn't advanced yet, the re-entrant call computes the exact same startIndex/endIndex, re-slices the same items from filteredItems, and appends them again. If the reflow keeps happening (it does, since every subsequent stagger-swap reflows too), the same batch repeats indefinitely.

Fix

Advance renderedItems and hasMoreData synchronously as soon as loadMore() decides which slice to load, before the render setTimeout. Any re-entrant call (spurious or otherwise) then always sees the next slice instead of the stale one, so it moves forward instead of repeating.

Verification

  • Confirmed via direct sqlite3 inspection of a running instance's jellysweep.db that the underlying media table had zero duplicate rows (active row count, COUNT(DISTINCT jellyfin_id), and COUNT(DISTINCT title) all matched) — the bug is purely in the frontend rendering cursor, not the data layer.
  • go tool templ generate regenerates media-grid_templ.go cleanly from the patched .templ source.
  • go build ./... and go vet ./... pass.
  • No existing automated test covers this inline dashboard JS (no JS test harness in the repo), so verification here is via build/vet plus the logical trace above.

Test plan

  • Load the dashboard with 100+ scheduled items and scroll continuously; confirm each batch of cards appears exactly once with no repeats
  • Confirm the default "Unrequested" filter (which re-renders shortly after initial load) doesn't reintroduce the repeat
  • go build ./... / go vet ./... clean

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.

Media Dashboard scrolling endlessly

1 participant