Greasy Fork Total Downloads

Shows a user's total downloads.

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name Greasy Fork Total Downloads
// @namespace -
// @version 1.2.2
// @description Shows a user's total downloads.
// @author NotYou
// @match *://greasyfork.org/*/users/*
// @match *://sleazyfork.org/*/users/*
// @license GPL-3.0
// @run-at document-body
// @grant GM_xmlhttpRequest
// @require https://update.greasyfork.org/scripts/445697/1244619/Greasy%20Fork%20API.js
// ==/UserScript==

~function(GreasyFork) {
    class Installs {
        static async getData(userId) {
            const userData = await GreasyFork.getUserData(userId)

            return (userData.all_listable_scripts || userData.scripts).reduce((acc, curr) => {
                acc.total += curr.total_installs
                acc.daily += curr.daily_installs

                return acc
            }, {
                total: 0,
                daily: 0
            })
        }
    }

    class User {
        static getId(url) {
            const match = url.match(/https?:\/\/(greasyfork|sleazyfork)\.org\/[a-zA-Z]+(\-[a-zA-Z]+)?\/users\/(?<userId>\d+)/)

            if (match) {
                const { userId } = match.groups

                return userId
            } else {
                return '1'
            }
        }

        static getLocale($languageSelectorLocale) {
            return $languageSelectorLocale ? $languageSelectorLocale.value || 'en-US' : 'en-US'
        }
    }

    class Stat {
        static createItem(data, text, color) {
            const node = document.createElement('span')
            node.style.fontSize = '15px'
            node.style.borderRadius = '3px'
            node.style.backgroundColor = 'rgb(45, 45, 45)'
            node.style.color = 'rgb(255, 255, 255)'
            node.style.margin = '0 4px'
            node.style.padding = '0 4px'
            node.style.display = 'inline-flex'
            node.style.alignItems = 'center'
            node.style.gap = '4px'
            node.style.boxShadow = `0 0 0 2px ${color}`
            node.textContent = data + ' ' + text

            const circle = document.createElement('span')
            circle.style.width = '8px'
            circle.style.height = '8px'
            circle.style.borderRadius = '50%'
            circle.style.background = color

            node.prepend(circle)

            return node
        }
    }

    class Data {
        static async getData() {
            const { href } = location
            const $languageSelectorLocale = document.querySelector('#language-selector-locale')
            const userLocale = User.getLocale($languageSelectorLocale)
            const userId = User.getId(href)
            const installsData = await Installs.getData(userId)

            return {
                userLocale,
                installsData
            }
        }
    }

    class Main {
        static init() {
            window.addEventListener('DOMContentLoaded', async () => {
                const { userLocale, installsData } = await Data.getData()
                const { total, daily } = installsData
                const $total = Stat.createItem(total.toLocaleString(userLocale), total > 1 ? 'Installs' : 'Install', 'rgb(123, 23, 23)')
                const $daily = Stat.createItem(daily.toLocaleString(userLocale), daily > 1 ? 'Daily Installs' : 'Daily Install', 'rgb(185, 32, 32)')
                const $header = document.querySelector('div.sidebarred-main-content h3:first-child')

                $header.appendChild($total)
                $header.appendChild($daily)
            })
        }
    }

    Main.init()
}(GreasyFork)