Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/pixel-profile/src/cards/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ import { getThemeOptions } from '../theme'
import { getBase64FromPixels, getPixelsFromPngBuffer, getPngBufferFromPixels, kFormatter, Rank } from '../utils'
import { getPngBufferFromURL } from '../utils/converter'
import { filterNotEmpty } from '../utils/filter'
import { getTopLanguages } from '../utils/top-languages' // import top-languages
import { fontBuffer } from './PressStart2P-Regular'
import { Resvg } from '@resvg/resvg-js'
import satori from 'satori'

export type Stats = {
name: string
username: string
topLanguages: string // add top languages stat
totalStars: number
totalCommits: number
totalIssues: number
Expand Down Expand Up @@ -60,6 +62,9 @@ export async function renderStats(stats: Stats, options: Options = {}): Promise<
dithering = false
} = options

const token = process.env.PAT_1 || '' // add token for topLanguages
const topLanguages = await getTopLanguages(username, token) // add const topLanguages

const applyAvatarBorder = avatarBorder !== undefined ? avatarBorder : theme !== ''

if (hiddenStatsKeys.includes('avatar')) {
Expand All @@ -76,6 +81,7 @@ export async function renderStats(stats: Stats, options: Options = {}): Promise<
const _stats = {
name,
avatar,
topLanguages, // add top languages to _stats
stars: kFormatter(totalStars),
commits: kFormatter(totalCommits),
issues: kFormatter(totalIssues),
Expand Down
19 changes: 18 additions & 1 deletion packages/pixel-profile/src/templates/github-stats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export type Stats = {
prs: string
rank: Rank['level']
stars: string
topLanguages: string // add top languages stat
}

export type TemplateOptions = {
Expand Down Expand Up @@ -43,7 +44,7 @@ export const AVATAR_SIZE = {
AVATAR_HEIGHT: 280
}

const mainStatsItems = ['stars', 'commits', 'issues', 'prs', 'contributions']
const mainStatsItems = ['stars', 'commits', 'issues', 'prs', 'contributions', 'topLanguages'] // add top languages

const getVisibleMainStatsCount = (hiddenStatsKeys: string[]) =>
mainStatsItems.filter((stat) => !hiddenStatsKeys.includes(stat)).length
Expand Down Expand Up @@ -110,6 +111,22 @@ export function makeGithubStats(stats: Stats, options: TemplateOptions) {
paddingRight: avatar ? 40 : 0
}}
>
{isVisible('topLanguages') && (
<div
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'flex-start',
width: '100%',
maxWidth: isVisible('avatar') ? '700px' : '100%',
wordBreak: 'keep-all',
whiteSpace: 'pre-wrap'
}}
>
<div>Top Languages:</div>
<div style={{ marginTop: '4px' }}>{stats.topLanguages}</div>
</div>
)}
{isVisible('stars') && (
<div
style={{
Expand Down
24 changes: 24 additions & 0 deletions packages/pixel-profile/src/utils/top-languages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import axios from 'axios'

export async function getTopLanguages(username: string, token?: string): Promise<string> {
const headers = token ? { Authorization: `token ${token}` } : {}
const reposRes = await axios.get(`https://api.github.com/users/${username}/repos?per_page=100`, { headers })
const repos = reposRes.data

const languageStats: Record<string, number> = {}

for (const repo of repos) {
if (repo.fork) continue
const langRes = await axios.get(repo.languages_url, { headers })
const langs = langRes.data
for (const [lang, bytes] of Object.entries(langs)) {
languageStats[lang] = (languageStats[lang] || 0) + (bytes as number)
}
}

const sorted = Object.entries(languageStats).sort((a, b) => b[1] - a[1])
const top3 = sorted.slice(0, 3)
const total = top3.reduce((sum, [, bytes]) => sum + bytes, 0)

return top3.map(([lang, bytes]) => `${lang} ${Math.round((bytes / total) * 100)}%`).join(', ')
}
Loading