diff --git a/README.md b/README.md index a3ef376..9aa3384 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ Violentmonkey auto-updates from `main` on its own. Open a script's raw URL in Firefox with Violentmonkey installed — it detects the `==UserScript==` header and prompts to install. -| Script | Install | Description | -| ---------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `gitlab-mark-viewed.user.js` | [install](https://raw.githubusercontent.com/solcik/userscripts/main/gitlab-mark-viewed.user.js) | Press `v` on a GitLab MR page to toggle the focused file's "Viewed" checkbox. Marking one viewed advances to the next file (GitLab's own `j`); un-viewing stays put so you can read it. Matches `gitlab.com` and `git.vs-point.cz`. | -| `gitlab-commit-nav.user.js` | [install](https://raw.githubusercontent.com/solcik/userscripts/main/gitlab-commit-nav.user.js) | Press `x` / `c` on a GitLab MR single-commit diff to go to the previous / next commit. Restores the built-in shortcut broken on GitLab < 17.10 ([#499143](https://gitlab.com/gitlab-org/gitlab/-/issues/499143)). | -| `github-mark-viewed.user.js` | [install](https://raw.githubusercontent.com/solcik/userscripts/main/github-mark-viewed.user.js) | Press `v` on a GitHub PR page to toggle the focused file's "Viewed" button. Marking one viewed scrolls the next file up under the header (GitHub has no next-file shortcut of its own); un-viewing stays put so you can read it. | +| Script | Install | Description | +| ---------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `gitlab-mark-viewed.user.js` | [install](https://raw.githubusercontent.com/solcik/userscripts/main/gitlab-mark-viewed.user.js) | Press `v` on a GitLab MR page to toggle the focused file's "Viewed" checkbox. Marking one viewed advances to the next file (GitLab's own `j`) and pins it under the sticky header, so a long commit message no longer sits above the diff; un-viewing stays put so you can read it. Matches `gitlab.com` and `git.vs-point.cz`. | +| `gitlab-commit-nav.user.js` | [install](https://raw.githubusercontent.com/solcik/userscripts/main/gitlab-commit-nav.user.js) | Press `x` / `c` on a GitLab MR single-commit diff to go to the previous / next commit. Restores the built-in shortcut broken on GitLab < 17.10 ([#499143](https://gitlab.com/gitlab-org/gitlab/-/issues/499143)). | +| `github-mark-viewed.user.js` | [install](https://raw.githubusercontent.com/solcik/userscripts/main/github-mark-viewed.user.js) | Press `v` on a GitHub PR page to toggle the focused file's "Viewed" button. Marking one viewed scrolls the next file up under the header (GitHub has no next-file shortcut of its own); un-viewing stays put so you can read it. | ## Authoring diff --git a/gitlab-mark-viewed.user.js b/gitlab-mark-viewed.user.js index b8b30b7..f825853 100644 --- a/gitlab-mark-viewed.user.js +++ b/gitlab-mark-viewed.user.js @@ -1,8 +1,8 @@ // ==UserScript== // @name GitLab — mark file as Viewed with "v" // @namespace https://github.com/solcik/userscripts -// @version 0.4.0 -// @description In a GitLab merge request diff, press "v" to toggle the focused file's "Viewed" checkbox, advancing to the next file only when marking one viewed. +// @version 0.5.0 +// @description In a GitLab merge request diff, press "v" to toggle the focused file's "Viewed" checkbox, advancing to the next file — pinned under the sticky header — only when marking one viewed. // @author David Solc // @match https://gitlab.com/*/-/merge_requests/* // @match https://git.vs-point.cz/*/-/merge_requests/* @@ -25,6 +25,7 @@ const REVIEW_CHECKBOX = "[data-testid='fileReviewCheckbox']"; const NEXT_FILE_KEY = 'j'; const EDGE = 4; + const SETTLE_MS = 400; function topChrome() { let bottom = 0; @@ -68,6 +69,30 @@ document.body.dispatchEvent(event); } + function fileKey(file) { + return file ? file.id || file.dataset.path || '' : ''; + } + + // In "show one file at a time" mode GitLab swaps the diff in place and leaves + // the viewport where it was, so a long commit message sits above the file we + // just moved to. The swap also takes a few frames, and the file grows as its + // lines render, so re-pin the new file under the sticky header until the + // layout settles. A key that never changes means there was no next file. + function pinNextFile(previousKey) { + const started = performance.now(); + + (function pin() { + const file = focusedFile(); + if (file && fileKey(file) !== previousKey) { + const top = window.scrollY + file.getBoundingClientRect().top - topChrome(); + if (Math.abs(top - window.scrollY) > 1) { + window.scrollTo({ top: Math.max(top, 0), left: window.scrollX }); + } + } + if (performance.now() - started < SETTLE_MS) requestAnimationFrame(pin); + })(); + } + Mousetrap.bind('v', function () { const file = focusedFile(); const checkbox = file && file.querySelector(REVIEW_CHECKBOX); @@ -78,6 +103,12 @@ const marking = !checkbox.checked; checkbox.click(); - if (marking) requestAnimationFrame(goToNextFile); + if (!marking) return; + + const key = fileKey(file); + requestAnimationFrame(function () { + goToNextFile(); + pinNextFile(key); + }); }); })();