Shows a user's total downloads.
// ==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_installsacc.daily += curr.daily_installsreturn 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.groupsreturn 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 + ' ' + textconst circle = document.createElement('span')circle.style.width = '8px'circle.style.height = '8px'circle.style.borderRadius = '50%'circle.style.background = colornode.prepend(circle)return node}}class Data {static async getData() {const { href } = locationconst $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 } = installsDataconst $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)