mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
1cab9dd9a8
* feat(review): mark files viewed as you scroll past them Reviewers reading the all-files diff top to bottom had to check every file off by hand. Now a file marks itself viewed when the reviewer MOVES ON from it, after its content was actually on screen long enough to have been read. Arriving at a file never marks it; leaving it downward does. - All-files surface: a file marks when the reader scrolls past it (its successor has reached the viewport top, so it genuinely scrolled out above) and has accumulated at least 1000ms as the reported reading file. Dwell is cumulative per diff snapshot, so bouncing between two files still accrues, while a momentum flick to the bottom marks nothing. The last file, which can never scroll out above, marks on reaching the end of the diff. - Single-file panel: opening a file never marks it; navigating away after the same dwell floor does. Keyboard file navigation drives the same panel switches, so keyboard-only parity is automatic. - Collapsed cards never mark. Generated files seed collapsed, so nobody reviews a lockfile by scrolling past its folded header. - Un-viewing a file suppresses auto-view for it until it is marked viewed by hand again. That set rides the review draft as an additive optional field. - Inert inside the Guided Review takeover and on a commit detour, where the files on screen are not the change under review. - A viewed file whose patch changes under a refresh loses its checkmark, but only while auto-view is on, so the off state stays byte-identical to today. - PR sessions batch the marks into one /api/pr-viewed request rather than one per file. The setting is reviewAutoViewed, cookie-only and on by default, with two off switches: Settings > Git and a row in the file-list gear popover. The first time auto-view actually fires, a toast says so and offers Turn off; using either switch consumes that one-time notice. The decision core is pure and clock-injected (utils/autoViewed.ts), the binding is a hook (hooks/useAutoViewed.ts), and AllFilesCodeView only gains one optional emission callback on the rAF path it already runs. No server changes in either runtime. AI-assisted (Claude) under maintainer direction. * fix(review): scope auto-mark-viewed to the transitions it was meant for Four review findings on the auto-mark-viewed branch. Rule 5 fired on EVERY applied diff switch, not just the staleness refresh. The review app funnels every transition through one apply path, so entering the Commits detour (the rail auto-opens HEAD), switching base branch, and toggling hide-whitespace all un-viewed files whose per-path patch text legitimately differs, which contradicts both Rule 4's "a commit detour is inert" and Rule 5's own rationale. The apply path now goes through resolveDiffSwitchUnviews, which requires the caller to opt in (`contentRefresh`) and re-checks the identity of the diff on top of that: same selection, same base, and never a commit-family type on either side. Only the staleness refresh and the post-fetch base refresh opt in. The pure delta resolver is unchanged. A source-level test pins which call sites may opt in, since that is where the guarantee actually lives. The at-bottom branch fired on the mount tick. A diff shorter than the viewport is at-bottom from the very first report, and that report is the mount seed, so the file on screen marked itself about a second later with zero interaction and fired the first-time toast at a motionless page. It now requires a real scroll event on the current file set. Staging a file marked it viewed without clearing auto-view suppression, unlike v, the header button and the tree row, so a file the reviewer un-viewed and later staged stayed permanently off-limits to auto-view. Dwell accrued while the setting was off, so enabling mid-read could mark the current file instantly on time the reviewer spent with the feature deliberately disabled. Disabled is now fully inert: the clock does not accrue, and enabling starts a fresh one rather than replaying the gap. AI-assisted (Claude) under maintainer direction. * chore: refresh pinned guide viewer manifest after merging main