Skip to content
Merged
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
2 changes: 2 additions & 0 deletions api/top-langs.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export default async (req, res) => {
locale,
border_radius,
border_color,
disable_animations,
} = req.query;
res.setHeader("Content-Type", "image/svg+xml");

Expand Down Expand Up @@ -75,6 +76,7 @@ export default async (req, res) => {
border_radius,
border_color,
locale: locale ? locale.toLowerCase() : null,
disable_animations: parseBoolean(disable_animations),
}),
);
} catch (err) {
Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ You can provide multiple comma-separated values in the bg_color option to render
- `langs_count` - Show more languages on the card, between 1-10 _(number)_. Default `5`.
- `exclude_repo` - Exclude specified repositories _(Comma-separated values)_. Default: `[] (blank array)`.
- `custom_title` - Sets a custom title for the card _(string)_. Default `Most Used Languages`.
- `disable_animations` - Disables all animations in the card _(boolean)_. Default: `false`.

> **Warning**
> Language names should be URI-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding)
Expand Down
2 changes: 1 addition & 1 deletion scripts/push-theme-readme.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ git config --global user.name "GitHub Readme Stats Bot"
git branch -d $BRANCH_NAME || true
git checkout -b $BRANCH_NAME
git add --all
git commit --message "docs(theme): Auto update theme readme" || exit 0
git commit --no-verify --message "docs(theme): Auto update theme readme"
git remote add origin-$BRANCH_NAME https://${PERSONAL_TOKEN}@github.com/${GH_REPO}.git
git push --force --quiet --set-upstream origin-$BRANCH_NAME $BRANCH_NAME
82 changes: 61 additions & 21 deletions src/cards/top-languages-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,46 +39,53 @@ const getLongestLang = (arr) =>
* Creates a node to display usage of a programming language in percentage
* using text and a horizontal progress bar.
*
* @param {object[]} props Function properties.
* @param {object} props Function properties.
* @param {number} props.width The card width
* @param {string} props.name Name of the programming language.
* @param {string} props.color Color of the programming language.
* @param {string} props.progress Usage of the programming language in percentage.
* @param {number} props.index Index of the programming language.
* @returns {string} Programming language SVG node.
*/
const createProgressTextNode = ({ width, color, name, progress }) => {
const createProgressTextNode = ({ width, color, name, progress, index }) => {
const staggerDelay = (index + 3) * 150;
const paddingRight = 95;
const progressTextX = width - paddingRight + 10;
const progressWidth = width - paddingRight;

return `
<text data-testid="lang-name" x="2" y="15" class="lang-name">${name}</text>
<text x="${progressTextX}" y="34" class="lang-name">${progress}%</text>
${createProgressNode({
x: 0,
y: 25,
color,
width: progressWidth,
progress,
progressBarBackgroundColor: "#ddd",
})}
<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>
${createProgressNode({
x: 0,
y: 25,
color,
width: progressWidth,
progress,
progressBarBackgroundColor: "#ddd",
delay: staggerDelay + 300,
})}
</g>
`;
};

/**
* Creates a text only node to display usage of a programming language in percentage.
*
* @param {object[]} props Function properties.
* @param {object} props Function properties.
* @param {Lang} props.lang Programming language object.
* @param {number} props.totalSize Total size of all languages.
* @param {number} props.index Index of the programming language.
* @returns {string} Compact layout programming language SVG node.
*/
const createCompactLangNode = ({ lang, totalSize }) => {
const createCompactLangNode = ({ lang, totalSize, index }) => {
const percentage = ((lang.size / totalSize) * 100).toFixed(2);
const staggerDelay = (index + 3) * 150;
const color = lang.color || "#858585";

return `
<g>
<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} ${percentage}%
Expand All @@ -104,7 +111,6 @@ const createLanguageTextNode = ({ langs, totalSize }) => {
createCompactLangNode({
lang,
totalSize,
// @ts-ignore
index,
}),
);
Expand Down Expand Up @@ -134,12 +140,13 @@ const createLanguageTextNode = ({ langs, totalSize }) => {
*/
const renderNormalLayout = (langs, width, totalLanguageSize) => {
return flexLayout({
items: langs.map((lang) => {
items: langs.map((lang, index) => {
return createProgressTextNode({
width: width,
width,
name: lang.name,
color: lang.color || DEFAULT_LANG_COLOR,
progress: ((lang.size / totalLanguageSize) * 100).toFixed(2),
index,
});
}),
gap: 40,
Expand Down Expand Up @@ -187,7 +194,7 @@ const renderCompactLayout = (langs, width, totalLanguageSize) => {

return `
<mask id="rect-mask">
<rect x="0" y="0" width="${offsetWidth}" height="8" fill="white" rx="5" />
<rect x="0" y="0" width="${offsetWidth}" height="8" fill="white" rx="5"/>
</mask>
${compactProgressBar}

Expand Down Expand Up @@ -276,6 +283,7 @@ const renderTopLanguages = (topLangs, options = {}) => {
langs_count = DEFAULT_LANGS_COUNT,
border_radius,
border_color,
disable_animations,
} = options;

const i18n = new I18n({
Expand Down Expand Up @@ -324,11 +332,43 @@ const renderTopLanguages = (topLangs, options = {}) => {
colors,
});

card.disableAnimations();
if (disable_animations) card.disableAnimations();

card.setHideBorder(hide_border);
card.setHideTitle(hide_title);
card.setCSS(
`.lang-name { font: 400 11px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${colors.textColor} }`,
`
@keyframes slideInAnimation {
from {
width: 0;
}
to {
width: calc(100%-100px);
}
}
@keyframes growWidthAnimation {
from {
width: 0;
}
to {
width: 100%;
}
}
.lang-name {
font: 400 11px "Segoe UI", Ubuntu, Sans-Serif;
fill: ${colors.textColor};
}
.stagger {
opacity: 0;
animation: fadeInAnimation 0.3s ease-in-out forwards;
}
#rect-mask rect{
animation: slideInAnimation 1s ease-in-out forwards;
}
.lang-progress{
animation: growWidthAnimation 0.6s ease-in-out forwards;
}
`,
);

return card.render(`
Expand Down
1 change: 1 addition & 0 deletions src/cards/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export type TopLangOptions = CommonOptions & {
layout: "compact" | "normal";
custom_title: string;
langs_count: number;
disable_animations: boolean;
};

type WakaTimeOptions = CommonOptions & {
Expand Down
19 changes: 11 additions & 8 deletions src/common/createProgressNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { clampValue } from "./utils.js";
* @param {string} createProgressNodeParams.color Progress color.
* @param {string} createProgressNodeParams.progress Progress value.
* @param {string} createProgressNodeParams.progressBarBackgroundColor Progress bar bg color.
* @param {number} createProgressNodeParams.delay Delay before animation starts.
* @returns {string} Progress node.
*/
const createProgressNode = ({
Expand All @@ -19,20 +20,22 @@ const createProgressNode = ({
color,
progress,
progressBarBackgroundColor,
delay,
}) => {
const progressPercentage = clampValue(progress, 2, 100);

return `
<svg width="${width}" x="${x}" y="${y}">
<rect rx="5" ry="5" x="0" y="0" width="${width}" height="8" fill="${progressBarBackgroundColor}"></rect>
<rect
height="8"
fill="${color}"
rx="5" ry="5" x="0" y="0"
data-testid="lang-progress"
width="${progressPercentage}%"
>
</rect>
<svg data-testid="lang-progress" width="${progressPercentage}%">
<rect
height="8"
fill="${color}"
rx="5" ry="5" x="0" y="0"
class="lang-progress"
style="animation-delay: ${delay}ms;"
/>
</svg>
</svg>
`;
};
Expand Down
5 changes: 4 additions & 1 deletion src/common/retryer.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ const retryer = async (fetcher, variables, retries = 0) => {
// prettier-ignore
// also checking for bad credentials if any tokens gets invalidated
const isBadCredential = err.response.data && err.response.data.message === "Bad credentials";
const isAccountSuspended =
err.response.data &&
err.response.data.message === "Sorry. Your account was suspended.";

if (isBadCredential) {
if (isBadCredential || isAccountSuspended) {
logger.log(`PAT_${retries + 1} Failed`);
retries++;
// directly return from the function
Expand Down
2 changes: 1 addition & 1 deletion tests/renderStatsCard.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ describe("Test renderStatsCard", () => {
document.querySelector(
'g[transform="translate(0, 25)"]>.stagger>.stat.bold',
).textContent,
).toMatchInlineSnapshot(`"累计提交数(commit) (2022):"`);
).toMatchInlineSnapshot(`"累计提交数(commit) (2023):"`);
expect(
document.querySelector(
'g[transform="translate(0, 50)"]>.stagger>.stat.bold',
Expand Down