Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ 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`) 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-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. The script advances after you mark a file viewed. It supports rapid diffs and the legacy viewer. Unmarking a viewed file keeps that file selected. 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) | Keyboard review flow for a GitHub PR diff. `v` marks the focused file viewed and pins the next file under the header; un-viewing stays put so you can read it. The first `v` on a PR only unticks "Viewed files" in the file filter, so only unviewed files remain. `j` / `k` go to the next / previous file; an outline marks the current file, so this also works at the end of the page where the diff cannot scroll further. `u` un-marks the last file `v` marked and jumps to it (undo stack per PR in `sessionStorage`). `Shift+V` shows or hides viewed files without changing review state. |

Expand Down
83 changes: 56 additions & 27 deletions gitlab-mark-viewed.user.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// ==UserScript==
// @name GitLab — mark file as Viewed with "v"
// @namespace https://github.com/solcik/userscripts
// @version 0.5.2
// @description In a GitLab merge request diff, press "v" (GitLab toggles the focused file's "Viewed" checkbox) and advance to the next file — pinned under the sticky header — only when marking one viewed.
// @version 0.5.3
// @description Press "v" to toggle the current GitLab diff file as viewed. Marking a file viewed advances to the next file.
// @author David Solc
// @match https://gitlab.com/*/-/merge_requests/*
// @match https://git.vs-point.cz/*/-/merge_requests/*
Expand All @@ -11,7 +11,6 @@
// @supportURL https://github.com/solcik/userscripts/issues
// @updateURL https://raw.githubusercontent.com/solcik/userscripts/main/gitlab-mark-viewed.user.js
// @downloadURL https://raw.githubusercontent.com/solcik/userscripts/main/gitlab-mark-viewed.user.js
// @require https://cdn.jsdelivr.net/npm/mousetrap@1.6.5/mousetrap.min.js
// @grant none
// @license MIT
// ==/UserScript==
Expand Down Expand Up @@ -63,12 +62,23 @@
return files.find((file) => file.getBoundingClientRect().bottom > edge) || files.at(-1);
}

// GitLab's own "next file" shortcut already knows about lazily rendered files,
// the sticky header offset and the file tree selection, so trigger it instead
// of scrolling ourselves. Its Mousetrap handler reads the legacy `which`, and
// its stopCallback expects an element target — dispatching on `document` is
// silently dropped.
function goToNextFile() {
// Use the viewer's navigation button in single-file mode.
// Select the next rapid diff directly in multi-file mode.
// The legacy viewer still handles the "j" shortcut.
function goToNextFile(file) {
const navigation = document.querySelector('[data-testid="file-by-file-navigation"]');
if (navigation) {
const next = navigation.querySelector('[data-testid="nextButton"]');
if (next && !next.disabled && next.getAttribute('aria-disabled') !== 'true') next.click();
return;
}

if (file.matches('diff-file')) {
const files = [...document.querySelectorAll('diff-file')];
files[files.indexOf(file) + 1]?.selectFile();
return;
}

const event = new KeyboardEvent('keypress', {
key: NEXT_FILE_KEY,
bubbles: true,
Expand Down Expand Up @@ -108,22 +118,41 @@
})();
}

// GitLab now binds "v" ("Viewed by me") itself. Clicking the checkbox here
// too would toggle it twice, so let GitLab toggle and only watch the result.
Mousetrap.bind('v', function () {
const file = focusedFile();
const checkbox = file && file.querySelector(REVIEW_CHECKBOX);
if (!checkbox) return;

const was = checkbox.checked;
const key = fileKey(file);

setTimeout(function () {
// Un-reviewing expands the file again, which is the whole point of
// pressing "v" on an already-viewed file — stay put so it can be read.
if (was || !checkbox.checked) return;
goToNextFile();
pinNextFile(key);
}, 50);
});
// Capture "v" before GitLab handles it. One owner prevents duplicate toggles.
document.addEventListener(
'keydown',
function (event) {
if (
event.key !== 'v' ||
event.ctrlKey ||
event.altKey ||
event.metaKey ||
event.shiftKey ||
event.isComposing ||
event.target.closest(
'input, textarea, select, [contenteditable]:not([contenteditable="false"]), [role="textbox"]',
)
)
return;

const file = focusedFile();
const checkbox = file && file.querySelector(REVIEW_CHECKBOX);
if (!checkbox || checkbox.disabled) return;

event.preventDefault();
event.stopImmediatePropagation();
if (event.repeat) return;

const marking = !checkbox.checked;
const key = fileKey(file);
checkbox.click();
if (!marking || !checkbox.checked) return;

requestAnimationFrame(function () {
goToNextFile(file);
pinNextFile(key);
});
},
true,
);
})();
Loading