pravic / Github :: issue history

// ==UserScript==
// @name         Github :: issue history
// @description  Shows the history of an issue (i.e. closed/reopened/etc.)
// @namespace    https://openuserjs.org/users/pravic
// @icon         https://www.google.com/s2/favicons?sz=64&domain=github.com
// @author       pravic
// @version      0.8.2
// @license      MIT
// @match        https://github.com/*/*/issues/*
// @match        https://github.com/*/*/pull/*
// @grant        none
// ==/UserScript==

// ==OpenUserJS==
// @author       pravic
// ==/OpenUserJS==

(function () {
    'use strict';

    // The issue header with "$name opened this issue $age days ago",
    // here we're going to insert some more information.
    // `#partial-discussion-header > .gh-header-meta > div[2] > a.author`
    let header = document.querySelector('#partial-discussion-header > .gh-header-meta a.author').parentElement;

    // Some useful addition: let's count how many comments between particular events.
    let comments = 0;
    let changes = 0;

    // Let's iterate over the closed/reopened events.
    // `.js-discussion` - the root timeline board
    // `.js-discussion > .TimelineItem` - the main ticket description
    // `.js-discussion > .js-timeline-item > .TimelineItem` - pull request comments or ticket events
    // `.js-discussion > div > .js-timeline-item > .TimelineItem` - issue comments or ticket events
    //
    // example tickets:
    // * https://github.com/rust-lang/rust/pull/119276
    // * https://github.com/rust-lang/rust/issues/118930
    // * https://github.com/rust-lang/rust/issues/118462
    let root = document.querySelector('.js-discussion');
    let timeline_events = root.querySelectorAll('.js-discussion .js-timeline-item > .TimelineItem');
    timeline_events.forEach(function (latest) {
        let is_comment = latest.classList.contains("js-comment-container");
        if (is_comment) {
            comments += 1;
        } else {
            let body = latest.querySelector('.TimelineItem-body');
            let text = body.innerText;

            var closed = 'closed';
            if (text.includes("closed this")) {
                closed = "closed";
            }
            else if (text.includes("reopened this")) {
                closed = "reopened";
            }
            else if (text.includes("merged commit")) {
                closed = "merged";
            }
            else {
                return;
            }

            let author = body.querySelector('.author').outerHTML;
            let when = body.querySelector('relative-time').parentElement.outerHTML;

            let after = "";
            if (comments > 0) {
                after = ` after ${comments} comments`;
            }

            let info = `<br/> ${author} ${closed} this issue ${when}${after}.`;
            header.insertAdjacentHTML('beforeend', info);

            comments = 0;
            changes += 1;
        }
    });

    // And count some remaining (post-mortem) comments.
    if (changes > 0 && comments > 0) {
        let remain = `<br/> and yet ${comments} comments more.`;
        header.insertAdjacentHTML('beforeend', remain);
    }

})();