Skip to content

feat: infinite scroll for the project asset grid - #155

Merged
vishwajeet-13 merged 2 commits into
developfrom
feat/asset-grid-infinite-scroll
Sep 6, 2026
Merged

feat: infinite scroll for the project asset grid#155
vishwajeet-13 merged 2 commits into
developfrom
feat/asset-grid-infinite-scroll

Conversation

@vishwajeet-13

Copy link
Copy Markdown
Collaborator

Replace the "Load more" button on the project/folder view with scroll-driven loading. The grid now fetches assets a page at a time and appends them as an IntersectionObserver sentinel nears the viewport; a skeleton row shows only while a page fetch is in flight. Mutation/realtime/poll refreshes re-pull just the rows already loaded so scroll position holds.

Thumbnails in the grid and list views get loading="lazy" + decoding="async" so off-screen images no longer download up front.

Claude-Session: https://claude.ai/code/session_01X3AbSPmfhePLsKb2FC6HXe

Replace the "Load more" button on the project/folder view with scroll-driven
loading. The grid now fetches assets a page at a time and appends them as an
IntersectionObserver sentinel nears the viewport; a skeleton row shows only
while a page fetch is in flight. Mutation/realtime/poll refreshes re-pull just
the rows already loaded so scroll position holds.

Thumbnails in the grid and list views get loading="lazy" + decoding="async"
so off-screen images no longer download up front.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X3AbSPmfhePLsKb2FC6HXe
@greptile-apps

greptile-apps Bot commented Sep 5, 2026

Copy link
Copy Markdown

Greptile Summary

This PR replaces button-driven asset pagination with a cumulative, scroll-driven query and adds lazy thumbnail decoding.

  • Adds a reusable IntersectionObserver composable and project-page sentinel.
  • Reloads the currently requested asset range to preserve scroll position during refreshes.
  • Adds native lazy loading and asynchronous decoding to grid and list thumbnails.
  • The new end-of-list calculation currently prevents retrying a failed expansion request.

Confidence Score: 4/5

The PR is not yet safe to merge because a transient load-more failure can permanently disable further scrolling for the current browser state.

The cumulative page-1 approach fixes the two resolved pagination-state findings from the previous review, but the new loading watcher derives end-of-list state after unsuccessful requests from stale rows and an increased limit, removing the only retry trigger.

Files Needing Attention: frontend/src/components/projects/useProjectBrowser.ts

Important Files Changed

Filename Overview
frontend/src/components/projects/useProjectBrowser.ts Reworks pagination around a cumulative page-1 limit, but failed expansion requests can incorrectly terminate infinite scrolling.
frontend/src/composables/useInfiniteScroll.ts Adds a scoped IntersectionObserver that loads repeatedly while the sentinel remains near the viewport.
frontend/src/pages/ProjectDetailPage.vue Replaces the load-more button with an observer sentinel and fetch-specific skeleton placeholders.
frontend/src/components/assets/AssetCard.vue Adds native lazy loading and asynchronous decoding to asset-card thumbnails.
frontend/src/components/common/FileTypeIcon.vue Adds native lazy loading and asynchronous decoding to list-style thumbnail images.

Fix all with Greploop Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
### Issue 1
frontend/src/components/projects/useProjectBrowser.ts:153-160
**Failed Loads Disable Scrolling**

When a load-more request fails, `staleOnError` keeps the previously loaded rows while `limit` has already increased. When loading finishes, this watcher compares that stale row count with the new limit and marks the list as complete. This makes `hasMore` false and removes the only infinite-scroll sentinel even though `total` still indicates that more assets exist, so scrolling cannot retry the failed request.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (2): Last reviewed commit: "fix: keep asset pagination consistent ac..." | Re-trigger Greptile

Comment thread frontend/src/components/projects/useProjectBrowser.ts Outdated
Comment thread frontend/src/components/projects/useProjectBrowser.ts Outdated
Greptile flagged that the page-offset bookkeeping could skip assets: after a
refresh replaced the loaded rows, the retained page number no longer matched
the row count, so the next scroll fetched from the wrong offset. A failed
refresh also left the request stuck in refresh mode.

Drop the offset model entirely. The grid keeps requesting [0, limit) from the
top (the same approach the old "Load more" button used) and grows limit by a
page on scroll; refetches stay consistent by construction. reachedEnd stops
the observer once the API row cap or the true end is hit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X3AbSPmfhePLsKb2FC6HXe
Comment on lines +153 to +160
watch(
() => assetsCall.loading,
(loading) => {
if (loading) return
loadingMore.value = false
reachedEnd.value = assets.value.length < limit.value
},
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Failed Loads Disable Scrolling

When a load-more request fails, staleOnError keeps the previously loaded rows while limit has already increased. When loading finishes, this watcher compares that stale row count with the new limit and marks the list as complete. This makes hasMore false and removes the only infinite-scroll sentinel even though total still indicates that more assets exist, so scrolling cannot retry the failed request.

Prompt To Fix With AI
This is a comment left during a code review.
Path: frontend/src/components/projects/useProjectBrowser.ts
Line: 153-160

Comment:
**Failed Loads Disable Scrolling**

When a load-more request fails, `staleOnError` keeps the previously loaded rows while `limit` has already increased. When loading finishes, this watcher compares that stale row count with the new limit and marks the list as complete. This makes `hasMore` false and removes the only infinite-scroll sentinel even though `total` still indicates that more assets exist, so scrolling cannot retry the failed request.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

@vishwajeet-13
vishwajeet-13 merged commit be20d8c into develop Sep 6, 2026
4 of 5 checks passed
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