forked from mirrored/github-readme-stats
Compare commits
70
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5ba3238ab | ||
|
|
f4e731ee09 | ||
|
|
6f07b51c00 | ||
|
|
6e0522cdd9 | ||
|
|
4ce744f7b5 | ||
|
|
3565f25c46 | ||
|
|
a5114d12d0 | ||
|
|
20914797b0 | ||
|
|
11cb8dffc1 | ||
|
|
a885425b52 | ||
|
|
017e3ba180 | ||
|
|
03465922b0 | ||
|
|
9829ab990d | ||
|
|
6243c702c3 | ||
|
|
97cef21e4e | ||
|
|
55a3cecd49 | ||
|
|
e245941e5a | ||
|
|
04ed2bdd3f | ||
|
|
c33f3f617a | ||
|
|
589badc483 | ||
|
|
05b611ad58 | ||
|
|
bf0a15f94f | ||
|
|
b8425d36c8 | ||
|
|
866e509d07 | ||
|
|
c1e2858330 | ||
|
|
01f726c316 | ||
|
|
2770161e33 | ||
|
|
b320054e90 | ||
|
|
5675ce77b1 | ||
|
|
27029cd565 | ||
|
|
df42981d34 | ||
|
|
4ecebbca94 | ||
|
|
80e6d0acc5 | ||
|
|
0adcb158f9 | ||
|
|
2cb4861b24 | ||
|
|
3cebd8907b | ||
|
|
42503cf90c | ||
|
|
2466713261 | ||
|
|
9c08efedbf | ||
|
|
af36d0b2e1 | ||
|
|
1689ca6feb | ||
|
|
642d63d4f0 | ||
|
|
2a1d255e45 | ||
|
|
114225e72e | ||
|
|
cc558e4d7c | ||
|
|
6738c6db5f | ||
|
|
ede2574b13 | ||
|
|
c6ca64551e | ||
|
|
5448a611ba | ||
|
|
22aa6887f9 | ||
|
|
ffd927af6d | ||
|
|
f02186908d | ||
|
|
8f63eaeef9 | ||
|
|
70b0d025f8 | ||
|
|
dc95c44c22 | ||
|
|
adbc7a36c9 | ||
|
|
1651db55ec | ||
|
|
e40f214a76 | ||
|
|
88aa6fe30c | ||
|
|
ad731cdfcb | ||
|
|
237942c234 | ||
|
|
d505580a4f | ||
|
|
4dbab9a2a3 | ||
|
|
d8af18e465 | ||
|
|
1af63921b5 | ||
|
|
9ff83e0855 | ||
|
|
6349ec8f32 | ||
|
|
31f2920c09 | ||
|
|
19cf691983 | ||
|
|
36e838da62 |
-15
@@ -1,15 +0,0 @@
|
||||
import statsCard from './api/index.js'
|
||||
import repoCard from './api/pin.js'
|
||||
import langCard from './api/top-langs.js'
|
||||
import wakatimeCard from './api/wakatime.js'
|
||||
import express from 'express'
|
||||
import dotenv from 'dotenv'
|
||||
|
||||
dotenv.config()
|
||||
const app = express()
|
||||
app.listen(process.env.port || 9000)
|
||||
|
||||
app.get('/', statsCard)
|
||||
app.get('/pin', repoCard)
|
||||
app.get('/top-langs', langCard)
|
||||
app.get('/wakatime', wakatimeCard)
|
||||
@@ -92,9 +92,7 @@ Visit <https://indiafightscorona.giveindia.org> and make a small donation to hel
|
||||
- [Repo Card Exclusive Options](#repo-card-exclusive-options)
|
||||
- [Language Card Exclusive Options](#language-card-exclusive-options)
|
||||
- [Wakatime Card Exclusive Option](#wakatime-card-exclusive-options)
|
||||
- [Deploy Yourself](#deploy-on-your-own)
|
||||
- [On Vercel](#on-vercel)
|
||||
- [On other platforms](#on-other-platforms)
|
||||
- [Deploy Yourself](#deploy-on-your-own-vercel-instance)
|
||||
- [Keep your fork up to date](#keep-your-fork-up-to-date)
|
||||
|
||||
# GitHub Stats Card
|
||||
@@ -511,9 +509,7 @@ By default, GitHub does not lay out the cards side by side. To do that, you can
|
||||
</a>
|
||||
```
|
||||
|
||||
## Deploy on your own
|
||||
|
||||
### On Vercel
|
||||
## Deploy on your own Vercel instance
|
||||
|
||||
#### :film_projector: [Check Out Step By Step Video Tutorial By @codeSTACKr](https://youtu.be/n6d4KHSKqGk?t=107)
|
||||
|
||||
@@ -550,23 +546,6 @@ Since the GitHub API only allows 5k requests per hour, my `https://github-readme
|
||||
|
||||
</details>
|
||||
|
||||
### On other platforms
|
||||
|
||||
> **Warning**
|
||||
> This way of using GRS is not officially supported and was added to cater to some particular use cases where Vercel could not be used (e.g. #2341). The support for this method, therefore, is limited.
|
||||
|
||||
<details>
|
||||
<summary><b>:hammer_and_wrench: Step-by-step guide for deploying on other platforms</b></summary>
|
||||
|
||||
1. Fork or clone this repo as per your needs
|
||||
2. Add `express` to the dependencies section of `package.json`
|
||||
https://github.com/anuraghazra/github-readme-stats/blob/ba7c2f8b55eac8452e479c8bd38b044d204d0424/package.json#L54-L61
|
||||
3. Run `npm i` if needed (initial setup)
|
||||
4. Run `node express.js` to start the server, or set the entry point to `express.js` in `package.json` if you're deploying on a managed service
|
||||
https://github.com/anuraghazra/github-readme-stats/blob/ba7c2f8b55eac8452e479c8bd38b044d204d0424/package.json#L11
|
||||
5. You're done 🎉
|
||||
</details>
|
||||
|
||||
### Keep your fork up to date
|
||||
|
||||
You can keep your fork, and thus your private Vercel instance up to date with the upstream using GitHubs' [Sync Fork button](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork). You can also use the [pull](https://github.com/wei/pull) package created by [@wei](https://github.com/wei) to automate this process.
|
||||
|
||||
+51
-35
@@ -87,16 +87,6 @@ const iconWithLabel = (icon, label, testid) => {
|
||||
* @returns {string} Repository card SVG object.
|
||||
*/
|
||||
const renderRepoCard = (repo, options = {}) => {
|
||||
const {
|
||||
name,
|
||||
nameWithOwner,
|
||||
description,
|
||||
primaryLanguage,
|
||||
isArchived,
|
||||
isTemplate,
|
||||
starCount,
|
||||
forkCount,
|
||||
} = repo;
|
||||
const {
|
||||
hide_border = false,
|
||||
title_color,
|
||||
@@ -109,6 +99,42 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
border_color,
|
||||
locale,
|
||||
} = options;
|
||||
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: repoCardLocales,
|
||||
});
|
||||
|
||||
const colors = getCardColors({
|
||||
title_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
});
|
||||
|
||||
const {
|
||||
name,
|
||||
nameWithOwner,
|
||||
description,
|
||||
primaryLanguage,
|
||||
isArchived,
|
||||
isTemplate,
|
||||
starCount,
|
||||
forkCount,
|
||||
} = repo;
|
||||
|
||||
const highlight = repo.highlight
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(repo.highlight, colors.textColor)
|
||||
: isTemplate
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(i18n.t("repocard.template"), colors.textColor)
|
||||
: isArchived
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(i18n.t("repocard.archived"), colors.textColor)
|
||||
: ""
|
||||
|
||||
const lineHeight = 10;
|
||||
const header = show_owner ? nameWithOwner : name;
|
||||
@@ -125,27 +151,25 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
const height =
|
||||
(descriptionLines > 1 ? 120 : 110) + descriptionLines * lineHeight;
|
||||
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: repoCardLocales,
|
||||
});
|
||||
|
||||
// returns theme based colors with proper overrides and defaults
|
||||
const colors = getCardColors({
|
||||
title_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
border_color,
|
||||
theme,
|
||||
});
|
||||
|
||||
const svgLanguage = primaryLanguage
|
||||
? createLanguageNode(langName, langColor)
|
||||
: "";
|
||||
|
||||
const totalStars = kFormatter(starCount);
|
||||
const totalForks = kFormatter(forkCount);
|
||||
|
||||
let totalStars
|
||||
let totalForks
|
||||
if (isNaN(starCount)) {
|
||||
totalStars = starCount;
|
||||
} else {
|
||||
totalStars = kFormatter(starCount);
|
||||
}
|
||||
if (isNaN(forkCount)) {
|
||||
totalForks = forkCount;
|
||||
} else {
|
||||
totalForks = kFormatter(forkCount);
|
||||
}
|
||||
|
||||
const svgStars = iconWithLabel(icons.star, totalStars, "stargazers");
|
||||
const svgForks = iconWithLabel(icons.fork, totalForks, "forkcount");
|
||||
|
||||
@@ -180,15 +204,7 @@ const renderRepoCard = (repo, options = {}) => {
|
||||
`);
|
||||
|
||||
return card.render(`
|
||||
${
|
||||
isTemplate
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(i18n.t("repocard.template"), colors.textColor)
|
||||
: isArchived
|
||||
? // @ts-ignore
|
||||
getBadgeSVG(i18n.t("repocard.archived"), colors.textColor)
|
||||
: ""
|
||||
}
|
||||
${highlight}
|
||||
|
||||
<text class="description" x="25" y="-5">
|
||||
${descriptionSvg}
|
||||
|
||||
+44
-32
@@ -40,7 +40,12 @@ const createTextNode = ({
|
||||
shiftValuePos,
|
||||
bold,
|
||||
}) => {
|
||||
const kValue = kFormatter(value);
|
||||
let kValue
|
||||
if (isNaN(value)) {
|
||||
kValue = value;
|
||||
} else {
|
||||
kValue = kFormatter(value);
|
||||
}
|
||||
const staggerDelay = (index + 3) * 150;
|
||||
|
||||
const labelOffset = showIcons ? `x="25"` : "";
|
||||
@@ -75,15 +80,6 @@ const createTextNode = ({
|
||||
* @returns {string} The stats card SVG object.
|
||||
*/
|
||||
const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
const {
|
||||
name,
|
||||
totalStars,
|
||||
totalCommits,
|
||||
totalIssues,
|
||||
totalPRs,
|
||||
contributedTo,
|
||||
rank,
|
||||
} = stats;
|
||||
const {
|
||||
hide = [],
|
||||
show_icons = false,
|
||||
@@ -106,6 +102,37 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
locale,
|
||||
disable_animations = false,
|
||||
} = options;
|
||||
|
||||
const name = stats.name || "GitHub User"
|
||||
|
||||
const apostrophe = ["x", "s"].includes(name.slice(-1).toLocaleLowerCase())
|
||||
? ""
|
||||
: "s";
|
||||
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: statCardLocales({ name, apostrophe }),
|
||||
});
|
||||
|
||||
const {
|
||||
totalStars = "2018",
|
||||
totalCommits = "29019",
|
||||
totalIssues = "203",
|
||||
totalPRs = "127",
|
||||
contributedTo = "232",
|
||||
rank = {
|
||||
level: "S",
|
||||
score: 10
|
||||
},
|
||||
starsTitle = i18n.t("statcard.totalstars"),
|
||||
commitsTitle = `${i18n.t("statcard.commits")}${
|
||||
include_all_commits ? "" : ` (${new Date().getFullYear()})`
|
||||
}`,
|
||||
issuesTitle = i18n.t("statcard.issues"),
|
||||
PRsTitle = i18n.t("statcard.prs"),
|
||||
contribsTitle = i18n.t("statcard.contribs") + " (last year)",
|
||||
title = i18n.t("statcard.title"),
|
||||
} = stats;
|
||||
|
||||
const lheight = parseInt(String(line_height), 10);
|
||||
|
||||
@@ -121,45 +148,35 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
theme,
|
||||
});
|
||||
|
||||
const apostrophe = ["x", "s"].includes(name.slice(-1).toLocaleLowerCase())
|
||||
? ""
|
||||
: "s";
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: statCardLocales({ name, apostrophe }),
|
||||
});
|
||||
|
||||
// Meta data for creating text nodes with createTextNode function
|
||||
const STATS = {
|
||||
stars: {
|
||||
icon: icons.star,
|
||||
label: i18n.t("statcard.totalstars"),
|
||||
label: starsTitle,
|
||||
value: totalStars,
|
||||
id: "stars",
|
||||
},
|
||||
commits: {
|
||||
icon: icons.commits,
|
||||
label: `${i18n.t("statcard.commits")}${
|
||||
include_all_commits ? "" : ` (${new Date().getFullYear()})`
|
||||
}`,
|
||||
label: commitsTitle,
|
||||
value: totalCommits,
|
||||
id: "commits",
|
||||
},
|
||||
prs: {
|
||||
icon: icons.prs,
|
||||
label: i18n.t("statcard.prs"),
|
||||
label: PRsTitle,
|
||||
value: totalPRs,
|
||||
id: "prs",
|
||||
},
|
||||
issues: {
|
||||
icon: icons.issues,
|
||||
label: i18n.t("statcard.issues"),
|
||||
label: issuesTitle,
|
||||
value: totalIssues,
|
||||
id: "issues",
|
||||
},
|
||||
contribs: {
|
||||
icon: icons.contribs,
|
||||
label: i18n.t("statcard.contribs") + " (last year)",
|
||||
label: contribsTitle,
|
||||
value: contributedTo,
|
||||
id: "contribs",
|
||||
},
|
||||
@@ -215,7 +232,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
});
|
||||
|
||||
const calculateTextWidth = () => {
|
||||
return measureText(custom_title ? custom_title : i18n.t("statcard.title"));
|
||||
return measureText(custom_title ? custom_title : title);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -241,7 +258,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
|
||||
const card = new Card({
|
||||
customTitle: custom_title,
|
||||
defaultTitle: i18n.t("statcard.title"),
|
||||
defaultTitle: title,
|
||||
width,
|
||||
height,
|
||||
border_radius,
|
||||
@@ -306,11 +323,6 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
|
||||
const labels = Object.keys(STATS)
|
||||
.filter((key) => !hide.includes(key))
|
||||
.map((key) => {
|
||||
if (key === "commits") {
|
||||
return `${i18n.t("statcard.commits")} ${
|
||||
include_all_commits ? "" : `in ${new Date().getFullYear()}`
|
||||
} : ${totalStars}`;
|
||||
}
|
||||
return `${STATS[key].label}: ${STATS[key].value}`;
|
||||
})
|
||||
.join(", ");
|
||||
|
||||
@@ -47,6 +47,7 @@ const getLongestLang = (arr) =>
|
||||
* @param {number} props.index Index of the programming language.
|
||||
* @returns {string} Programming language SVG node.
|
||||
*/
|
||||
|
||||
const createProgressTextNode = ({ width, color, name, progress, index }) => {
|
||||
const staggerDelay = (index + 3) * 150;
|
||||
const paddingRight = 95;
|
||||
@@ -56,7 +57,7 @@ const createProgressTextNode = ({ width, color, name, progress, index }) => {
|
||||
return `
|
||||
<g class="stagger" style="animation-delay: ${staggerDelay}ms">
|
||||
<text data-testid="lang-name" x="2" y="15" class="lang-name">${name}</text>
|
||||
<text x="${progressTextX}" y="34" class="lang-name">${progress}%</text>
|
||||
<text x="${progressTextX}" y="34" class="lang-name">${text || `${progress}%`}</text>
|
||||
${createProgressNode({
|
||||
x: 0,
|
||||
y: 25,
|
||||
@@ -89,7 +90,7 @@ const createCompactLangNode = ({ lang, totalSize, hideProgress, index }) => {
|
||||
<g class="stagger" style="animation-delay: ${staggerDelay}ms">
|
||||
<circle cx="5" cy="6" r="5" fill="${color}" />
|
||||
<text data-testid="lang-name" x="15" y="10" class='lang-name'>
|
||||
${lang.name} ${hideProgress ? "" : percentage + "%"}
|
||||
${lang.name} ${hideProgress ? "" : (lang.text || `${percentage}%`)}
|
||||
</text>
|
||||
</g>
|
||||
`;
|
||||
@@ -126,7 +127,7 @@ const createLanguageTextNode = ({ langs, totalSize, hideProgress }) => {
|
||||
|
||||
const percent = ((longestLang.size / totalSize) * 100).toFixed(2);
|
||||
const minGap = 150;
|
||||
const maxGap = 20 + measureText(`${longestLang.name} ${percent}%`, 11);
|
||||
const maxGap = 20 + measureText(`${longestLang.name} ${longestLang.text || `${percent}%`}`, 11);
|
||||
return flexLayout({
|
||||
items: layouts,
|
||||
gap: maxGap < minGap ? minGap : maxGap,
|
||||
@@ -149,6 +150,7 @@ const renderNormalLayout = (langs, width, totalLanguageSize) => {
|
||||
name: lang.name,
|
||||
color: lang.color || DEFAULT_LANG_COLOR,
|
||||
progress: ((lang.size / totalLanguageSize) * 100).toFixed(2),
|
||||
text: lang.text,
|
||||
index,
|
||||
});
|
||||
}),
|
||||
@@ -278,6 +280,12 @@ const useLanguages = (topLangs, hide, langs_count) => {
|
||||
* @returns {string} Language card SVG object.
|
||||
*/
|
||||
const renderTopLanguages = (topLangs, options = {}) => {
|
||||
const locale = options.locale
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: langCardLocales,
|
||||
});
|
||||
|
||||
const {
|
||||
hide_title = false,
|
||||
hide_border,
|
||||
@@ -290,18 +298,13 @@ const renderTopLanguages = (topLangs, options = {}) => {
|
||||
theme,
|
||||
layout,
|
||||
custom_title,
|
||||
locale,
|
||||
langs_count = DEFAULT_LANGS_COUNT,
|
||||
border_radius,
|
||||
border_color,
|
||||
title = i18n.t("langcard.title"),
|
||||
disable_animations,
|
||||
} = options;
|
||||
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: langCardLocales,
|
||||
});
|
||||
|
||||
const { langs, totalLanguageSize } = useLanguages(
|
||||
topLangs,
|
||||
hide,
|
||||
@@ -342,7 +345,7 @@ const renderTopLanguages = (topLangs, options = {}) => {
|
||||
|
||||
const card = new Card({
|
||||
customTitle: custom_title,
|
||||
defaultTitle: i18n.t("langcard.title"),
|
||||
defaultTitle: title,
|
||||
width,
|
||||
height,
|
||||
border_radius,
|
||||
|
||||
Reference in New Issue
Block a user