// ==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)
})()