feat: commit plotting mechanism update#1854
Conversation
Add global.first, global.newer, and global.older i18n keys to support the upcoming commit history graph navigation controls.
Introduce a commit buffer that accumulates data from the backend and a sliding window of 4 commits over it. When the user navigates past the buffer boundary, a new fetch is triggered using the oldest known commit as anchor, and results are merged with deduplication. Navigation callbacks (goOlder, goNewer, goOldest, goNewest) are wired but not yet exposed in the UI — buttons come in the next commit.
Add first/prev/next/last buttons below the commit history chart, allowing users to navigate through older commits one at a time. Uses MdFirstPage, MdArrowBackIos, MdArrowForwardIos, MdLastPage icons consistent with existing pagination controls.
…rnelci#1840) When navigating past the initial 6-commit batch, the graph would flash back to the newest commits and get stuck because: 1. Changing the fetch anchor reset the TanStack Query status to 'pending', causing QuerySwitcher to replace the chart with a loading skeleton — even though we had buffered data to display. 2. setWindowEnd was called inside setAllCommits's updater function, which is a side effect in a pure function with undefined behavior in React, leading to inconsistent window positioning after merge. 3. Two competing effects (merge + init) both set windowEnd, creating race conditions on the window position. Refactored to: use a ref mirror (allCommitsRef) for synchronous buffer access, a single merge effect that handles both initial load and subsequent merges, and an effectiveStatus that keeps the chart visible during background fetches. Navigation buttons are disabled while a fetch is in flight to prevent double-triggers.
00dd255 to
6aeddb5
Compare
| } | ||
|
|
||
| // Data from API is newest-first; reverse to get chronological (oldest-first) | ||
| const newCommits = [...data].reverse(); |
There was a problem hiding this comment.
nice touch, more sane
| const newCommits = [...data].reverse(); | ||
| const prev = allCommitsRef.current; | ||
|
|
||
| if (prev.length === 0) { |
There was a problem hiding this comment.
do we really need to have a special case for when prev is empty?
cant we just make prev an empty list, and let the usual flow of merging?
| c => !existingHashes.has(c.git_commit_hash), | ||
| ); | ||
|
|
||
| if (uniqueNew.length === 0) { |
There was a problem hiding this comment.
again, if no new unique elements are added, do we need to have a special case for it?
| setWindowEnd(WINDOW_SIZE - 1); | ||
| } else if (allCommits.length > 0) { | ||
| // Flag the merge effect to position window at oldest end after fetch | ||
| jumpToOldestRef.current = true; |
There was a problem hiding this comment.
if we are more than one page of distance from the oldest, this would need to recursively trigger the fetches, making this a slow fetching, and also more complicated.
I think we better keep only single page distance navigation, unless we do some changes on the backend to better suit this kind of navigation.
What you think of it?
There was a problem hiding this comment.
If we do need faster navigation, a simpler solution right now, could be updating the end in steps of 3 (or 5)
There was a problem hiding this comment.
Go newest seems to be safe to keep. And can help if you navigated to deep in the abyss.
Summary
Details
The Build History graph previously showed only the latest 6 commits with no way to access older ones. This change introduces:
How to test
Related Issue
Closes #1840