GitHub Pulse Sort By

adds sorting option to repo pulse

目前为 2016-01-24 提交的版本,查看 最新版本

// ==UserScript==
// @name        GitHub Pulse Sort By
// @namespace   faleij
// @description adds sorting option to repo pulse
// @include     https://github.com/*
// @version     1.1.0
// @grant       none
// @run-at      document-end
// ==/UserScript==
/* jshint esnext:true, node:true, browser:true */
/* globals $  */
'use strict';

const menuHTML = `
<div class="select-menu js-menu-container js-select-menu faleijs-sort-by-menu">
    <button class="btn btn-sm select-menu-button js-menu-target" type="button" aria-haspopup="true">
      <i>Sort By</i>
    </button>

    <div class="select-menu-modal-holder js-menu-content js-navigation-container" aria-hidden="true">
        <div class="select-menu-modal">
            <div class="select-menu-header">
                <span class="select-menu-title">Sort by</span>
                <span class="octicon octicon-remove-close js-menu-close"></span>
            </div>

            <div class="select-menu-list">
                <div class="select-menu-item js-navigation-item selected">
                    <input checked="checked" id="sort_changed" name="sortBy" value="time" type="radio" />
                    <span class="select-menu-item-icon octicon octicon-check"></span>
                    <div class="select-menu-item-text">
                        Last Changed
                    </div>
                </div>

                <div class="select-menu-item js-navigation-item">
                    <input id="sort_assignee" name="sortBy" value="assignee" type="radio" />
                    <span class="select-menu-item-icon octicon octicon-check"></span>
                    <div class="select-menu-item-text">
                        Assignee
                    </div>
                </div>

                <div class="select-menu-item js-navigation-item">
                    <input id="sort_created" name="sortBy" value="num" type="radio" />
                    <span class="select-menu-item-icon octicon octicon-check"></span>
                    <div class="select-menu-item-text">
                        Created
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
</li>`;

const renderProgressHTML = (total, at) => `
<span class="issue-meta-section task-progress">
    <span aria-hidden="true" class="octicon octicon-checklist"></span>
    <span class="task-progress-counts">${at} of ${total}</span>
    <span class="progress-bar">
        <span class="progress" style="width: ${(at/total)*100}%"></span>
    </span>
</span>
`;

const target = document.querySelector('#js-repo-pjax-container');
const mutationHandler = () => {
    console.log('event handler', location.pathname.endsWith('/pulse'));
    if (/\/pulse\/|$/.test(location.pathname) && !$('.faleijs-sort-by-menu', target).length) create();
};
const observer = new MutationObserver(mutationHandler);

observer.observe(target, {
    childList: true
});

mutationHandler();

function create() {
    // Load assignees and progress
    $('li>.title').each((index, title) => $.get($(title).attr('href')).then(data => {
        data = $(data);
        let total = $('.comment-body:first input[type=checkbox]', data).length;

        if (total) {
            let checked = $('.comment-body:first input[type=checkbox][checked]', data).length;
            $(title).parent().append(renderProgressHTML(total, checked));
        }

        $(title).parent().append($('.assignee', data).parent().css('float', 'right'));
    }));

    $('input:radio[name="sortBy"]', $(menuHTML).prependTo('.header-with-actions')).change(MenuChangeHandler);
}

function MenuChangeHandler() {
    let sort = (a, b) => $(`.${this.value}:first`, a).text().localeCompare($(`.${this.value}:first`, b).text());

    if (this.value === 'num') {
        sort = (a, b) => parseInt($(`.${this.value}:first`, a).text().substr(1)) > parseInt($(`.${this.value}:first`, b).text().substr(1));
    }

    if (this.value === 'time') {
        sort = (a, b) => new Date($(`.${this.value}:first`, a).attr('datetime')) > new Date($(`.${this.value}:first`, b).attr('datetime'));
    }

    $('.repository-content ul').each((index, ul) => $('li', ul).sort(sort).appendTo(ul));
}