Greasy Fork镜像 User Statistics+

shows user statistics as total installs, total scripts and etc.

目前为 2022-10-31 提交的版本。查看 最新版本

// ==UserScript==
// @name Greasy Fork镜像 User Statistics+
// @namespace -
// @version 1.0.0
// @description shows user statistics as total installs, total scripts and etc.
// @author NotYou
// @include *gf.qytechs.cn/*/users/*
// @include *sleazyfork.org/*/users/*
// @license GPL-3.0-or-later
// @run-at document-end
// @grant none
// ==/UserScript==

(function() {
    let translations = {
        'ar': {
            stats: 'إحصائيات المستخدم',
            works: 'يعمل المستخدم',
        },
        'bg': {
            stats: 'Потребителска статистика',
            works: 'Потребителят работи',
        },
        'cs': {
            stats: 'Statistiky uživatelů',
            works: 'Uživatel pracuje',
        },
        'da': {
            stats: 'Brugerstatistik',
            works: 'Brugeren fungerer',
        },
        'de': {
            stats: 'Benutzerstatistiken',
            works: 'Benutzer funktioniert',
        },
        'el': {
            stats: 'Στατιστικά στοιχεία χρηστών',
            works: 'Ο χρήστης λειτουργεί',
        },
        'en': {
            stats: 'User statistics',
            works: 'User works',
        },
        'eo': {
            stats: 'Statistiko de uzantoj',
            works: 'Uzanto funkcias',
        },
        'es': {
            stats: 'Estadísticas de usuario',
            works: 'El usuario trabaja',
        },
        'fi': {
            stats: 'Käyttäjätilastot',
            works: 'Käyttäjä toimii',
        },
        'fr': {
            stats: 'Statistiques d\'utilisateurs',
            works: 'L\'utilisateur travaille',
        },
        'he': {
            stats: 'סטטיסטיקות משתמשים',
            works: 'משתמש עובד',
        },
        'hu': {
            stats: 'Felhasználói statisztikák',
            works: 'Felhasználó működik',
        },
        'id': {
            stats: 'Statistik pengguna',
            works: 'Pengguna bekerja',
        },
        'it': {
            stats: 'Statistiche utente',
            works: 'L\'utente lavora',
        },
        'ja': {
            stats: 'ユーザー統計',
            works: 'ユーザーは動作します',
        },
        'ko': {
            stats: '사용자 통계',
            works: '사용자 작품',
        },
        'ne': {
            stats: 'Gebruikersstatistieken',
            works: 'Gebruiker werkt',
        },
        'pl': {
            stats: 'Statystyki użytkowników',
            works: 'Użytkownik pracuje',
        },
        'ro': {
            stats: 'Statistici utilizatori',
            works: 'Utilizatorul lucrează',
        },
        'ru': {
            stats: 'Статистика пользователей',
            works: 'Пользовательские работы',
        },
        'tr': {
            stats: 'Kullanıcı istatistikleri',
            works: 'Kullanıcı işleri',
        },
        'uk': {
            stats: 'Статистика користувачів',
            works: 'Користувач працює',
        },
        'vi': {
            stats: 'Thống kê người dùng',
            works: 'Người dùng hoạt động',
        },
        'zh-CN': {
            stats: '用户统计',
            works: '用户作品',
        },
        'zh-TW': {
            stats: '用戶統計',
            works: '用戶作品',
        },
    }

    let currentTranslation = translations[document.querySelector('#language-selector-locale').value] || translations.en
    let i = 0

    let data = new Proxy({
        total: 0,
        daily: 0,
        scripts: 0,
        styles: 0,
        libraries: 0,

        stats: 0,
        works: 0,
    }, {
        set(target, prop, value) {
            let t = target

            t[prop] = value

            t.stats = t.total + t.daily
            t.works = t.scripts + t.styles + t.libraries
        }
    })

    let stats = document.createElement('div')

    stats.id = 'user-statistics'

    addStyle({
        '.statistics-bar': {
            width: 'calc(100% - 2.4vw)',
            margin: '1em',
        },

        '.statistics-bar div': {
            height: '20px',
            borderRadius: '4px',
            padding: '3px',
        },

        '.statistics-bar span': {
            position: 'relative',
            bottom: '23px',
            zIndex: '50',
            height: '0',
            display: 'block',
            left: '5px',
        },

        '.statistics-bar div[style*=" 0%"]': {
            padding: '0',
        },

        '.statistics-bar div[style*=" 0%"] + span': {
            color: 'unset !important',
        },
    })

    document.querySelectorAll('.script-list > li').forEach(e => {
        let dataset = e.dataset

        data.total += +dataset.scriptTotalInstalls
        data.daily += +dataset.scriptDailyInstalls

        if(dataset.scriptType === 'library') {
            data.libraries++
        } else {
            data[dataset.scriptLanguage === 'js' ? 'scripts' : 'styles']++
        }
    })

    createStat({
        title: 'stats',
        values: [
            'total',
            'daily',
        ]
    })

    createStat({
        title: 'works',
        values: [
            'scripts',
            'styles',
            'libraries',
        ]
    })

    function createStat(input) {
        let { values, title } = input
        let titleEl = document.createElement('h3')
        titleEl.textContent = currentTranslation[title]
        stats.appendChild(titleEl)

        values.forEach(e => {
            let value = data[e]
            let total = data[title] === 0 ? 1 : data[title]

            createBar(value / total * 100, e, value)
        })

        i++
    }

    function createBar(width, name, value) {
        let bar = document.createElement('div')
        let barActual = document.createElement('div')
        let text = document.createElement('span')
        let bg = '128, 128, 128'

        bar.className = 'statistics-bar'

        switch (name) {
            case 'total':
                bg = '255, 28, 28'
                break
            case 'daily':
                bg = '255, 58, 58'
                break
            case 'styles':
                bg = '50, 149, 208'
                break
            case 'scripts':
                bg = '236, 203, 27'
                break
            case 'libraries':
                bg = '221, 102, 15'
                break
        }
        barActual.style.width = width + '%'
        barActual.style.backgroundColor = 'rgba(' + bg + ', .7)'

        if(i > 0) {
            text.style.color = 'rgb(0, 0, 0)'
        }

        text.textContent = capitalize(name) + ` (${value})`

        bar.appendChild(barActual)
        bar.appendChild(text)
        stats.appendChild(bar)
    }

    function addStyle(css) {
        let keys = Object.keys(css)
        let cssActual = ''
        let style = document.createElement('style')

        keys.forEach(e => {
            let _keys = Object.keys(css[e])

            cssActual += e + '{'

            _keys.forEach(r => {
                cssActual += r.replace(/[A-Z]/, m => `-${m.toLowerCase()}`) + ':' + css[e][r] + ';'
            })

            cssActual += '}'
        })

        style.textContent = cssActual
        document.querySelector('head').appendChild(style)
    }

    function capitalize(str) {
        return str[0].toUpperCase() + str.slice(1)
    }

    document.querySelector('#about-user').appendChild(stats)
})()















QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址