github commits { display: calendar; }

show github commits as calendar

目前為 2024-06-12 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        github commits { display: calendar; }
// @namespace   leizingyiu.net
// @include     /^https:\/\/github.com\/[^/]+\/[^/]+\/(commits|commit)\/.*/
// @grant        GM_xmlhttpRequest
// @run-at       document-idle
// @version     2024.06.12.17:44
// @author      leizingyiu
// @license      GNU GPLv3
// @description show github commits as calendar
// ==/UserScript==

/* 
history : 2024.06.04.01.26.04 : init
2024.06.12.17:44: add zh support ; fixed margin style ;
*/
const is_zh = detectBrowserLanguage().indexOf('zh') != -1;

function detectBrowserLanguage() {
    var language;

    if (navigator.languages && navigator.languages.length) { // Chrome, Firefox, IE11+
        language = navigator.languages[0];
    } else if (navigator.language) { // Modern browsers
        language = navigator.language;
    } else if (navigator.userLanguage) { // IE11-
        language = navigator.userLanguage;
    }

    return language;
}


function getDayOfWeek(dateString) {
    const days = [0, 1, 2, 3, 4, 5, 6];
    const date = new Date(dateString);
    const dayIndex = date.getDay();
    return (days[dayIndex] + 6) % 7;
}


function addCSS(url, id, removeReg) {
    'use strict';

    if (document.getElementById(id) !== null) { return; }
    GM_xmlhttpRequest({
        method: 'GET',
        url: url,
        onload: function (response) {
            if (response.status === 200) {
                var style = document.createElement('style');
                style.id = id;
                style.textContent = response.responseText.replace(removeReg, '');
                document.head.appendChild(style);
            } else {
                console.error('Failed to load CSS file:', response.statusText);
            }
        },
        onerror: function (error) {
            console.error('Error loading CSS file:', error);
        }
    });
}

function yiu_github_commits_calendar() {


    console.log('yiu-github-calendar start');

    addCSS('https://userstyles.world/api/style/16743.user.css', 'yiu-github-commits-calendar-style', /(@[^{\n]*\{\n)|(\}(?![\n\r]))/g);

    let vIdx = 0, phIdx = 7, nowHIdx = 0, startHIdx = 7;
    [...document.querySelectorAll(".mb-3 .Timeline-Item")].map((item, idx, arr) => {
        const days = is_zh ?
            ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"] :
            ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];

        let date = item.querySelector("h3").innerText.replace("Commits on ", "");

        let hIdx = getDayOfWeek(date); // 横向序号

        if (hIdx >= phIdx) { // 如果当前序号大于上一个  , 说明这里换行

            vIdx += 1;
            nowHIdx = 0;
            item.classList.add("clearFloat");

            startHIdx = 7;
        }

        startHIdx = hIdx < startHIdx ? hIdx : startHIdx;




        item.querySelector("h3").innerText =
            item.querySelector("h3").innerText.replace("Commits on ", "");
        item.setAttribute('yiu-github-calendar-day', `${days[hIdx]}`);
        item.querySelector("h3").setAttribute('yiu-github-calendar-day', `${days[hIdx]}`);


        Object.entries({
            "--yiu-github-calendar-offset": hIdx - nowHIdx,
            "--yiu-github-calendar-day": hIdx
        }).map(([k, v], _idx, _arr) => {
            item.style.setProperty(k, v);
            item.nextElementSibling.style.setProperty(k, v);
        });

        item.setAttribute("yiu-github-calendar-row", vIdx);

        nowHIdx += 1;

        phIdx = hIdx;


        if (idx == arr.length - 1) {
            [...document.querySelectorAll(`[yiu-github-calendar-row="${vIdx}"]`)].map(
                (i) => {
                    i.style.setProperty("--yiu-github-calendar-move", nowHIdx);
                    i.nextElementSibling.style.setProperty("--yiu-github-calendar-move", nowHIdx);
                },
            );
        }

    });
    console.log('yiu-github-calendar end ');
}





const main = () => {
    yiu_github_commits_calendar();
};

(function () {
    /* from https://greasyfork.org/zh-CN/scripts/434592 */
    'use strict';
    /**
     * 在浏览器窗口大小改变时自动重新定位设置菜单
     */
    window.onresize = function () {
        // 监听窗口大小改变
        main();
    }
    let oldPushState = history.pushState;
    history.pushState = function pushState() {
        let ret = oldPushState.apply(this, arguments);
        window.dispatchEvent(new Event('pushstate'));
        window.dispatchEvent(new Event('locationchange'));
        return ret;
    };

    let oldReplaceState = history.replaceState;
    history.replaceState = function replaceState() {
        let ret = oldReplaceState.apply(this, arguments);
        window.dispatchEvent(new Event('replacestate'));
        window.dispatchEvent(new Event('locationchange'));
        return ret;
    };

    window.addEventListener('popstate', () => {
        window.dispatchEvent(new Event('locationchange'));
    });

    document.addEventListener('pjax:success', function () {
        // 由于 GitHub 使用 pjax 而不是页面跳转的方式在仓库内导航,因此将 main 函数绑定到 pjax 监听器上
        window.dispatchEvent(new Event('locationchange'));
    });
    window.addEventListener('locationchange', function () {
        console.log('locationchange!');
        main();
    });
    main();
})();