NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name GitHub mark as viewed
// @namespace http://tampermonkey.net/
// @version 1.0.2
// @description marks GitHub PR files as "viewed" when clicking Alt+V
// @author Kageetai
// @homepageUrl https://github.com/Kageetai/TamperMonkey
// @contributionUrl https://github.com/Kageetai/TamperMonkey
// @supportUrl https://github.com/Kageetai/TamperMonkey/issues
// @updateURL https://openuserjs.org/meta/Kageetai/github-mark-viewed.meta.js
// @match https://github.com/*/pull/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=github.com
// @grant none
// @license MIT
// @copyright 2023, Kageetai (https://openuserjs.org/users/Kageetai)
// ==/UserScript==
(() => {
'use strict';
// IntersectionObserver to detect when a button is visible and add class to it
const observer = new IntersectionObserver(entries => entries.forEach(entry => {
const elem = entry.target;
if (entry.isIntersecting && entry.intersectionRatio >= 1) {
elem.classList.add('isVisible');
} else {
elem.classList.remove('isVisible');
}
}), {threshold: 1});
const observeButtons = () => {
// wait if GitHub is still loading more diffs
if (document.querySelector('.diff-progressive-loader') !== null) {
setTimeout(observeButtons, 1000);
} else {
document
.querySelectorAll('input[value="viewed"]:not(:checked)')
.forEach(button => observer.observe(button));
}
};
window.addEventListener('load', observeButtons)
// keyboard shortcut event listener
document.addEventListener('keyup', event => {
if (event.altKey && event.code === 'KeyV') {
const e = document.querySelector('input[value="viewed"]:not(:checked).isVisible:first-child');
if (e !== null) {
e.click();
e.scrollIntoView({block: "start", behavior: "smooth"});
observer.unobserve(e);
}
}
});
})();