Skip to content

Commit

Permalink
Merge branch 'anuraghazra:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
developStorm authored Jul 11, 2021
2 parents 0d54ba6 + 112efb4 commit b07ce83
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 117 deletions.
2 changes: 1 addition & 1 deletion api/top-langs.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module.exports = async (req, res) => {
}

if (locale && !isLocaleAvailable(locale)) {
return res.send(renderError("Something went wrong", "Language not found"));
return res.send(renderError("Something went wrong", "Locale not found"));
}

try {
Expand Down
245 changes: 143 additions & 102 deletions src/cards/top-languages-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ const { langCardLocales } = require("../translations");
const { createProgressNode } = require("../common/createProgressNode");
const { clampValue, getCardColors, flexLayout } = require("../common/utils");

const DEFAULT_CARD_WIDTH = 300;
const DEFAULT_LANGS_COUNT = 5;
const DEFAULT_LANG_COLOR = "#858585";
const CARD_PADDING = 25;

const lowercaseTrim = (name) => name.toLowerCase().trim();

const createProgressTextNode = ({ width, color, name, progress }) => {
const paddingRight = 95;
const progressTextX = width - paddingRight + 10;
Expand Down Expand Up @@ -58,35 +65,99 @@ const createLanguageTextNode = ({ langs, totalSize, x, y }) => {
});
};

const lowercaseTrim = (name) => name.toLowerCase().trim();
/**
*
* @param {any[]} langs
* @param {number} width
* @param {number} totalLanguageSize
* @returns {string}
*/
const renderNormalLayout = (langs, width, totalLanguageSize) => {
return flexLayout({
items: langs.map((lang) => {
return createProgressTextNode({
width: width,
name: lang.name,
color: lang.color || DEFAULT_LANG_COLOR,
progress: ((lang.size / totalLanguageSize) * 100).toFixed(2),
});
}),
gap: 40,
direction: "column",
}).join("");
};

const renderTopLanguages = (topLangs, options = {}) => {
const {
hide_title,
hide_border,
card_width,
title_color,
text_color,
bg_color,
hide,
theme,
layout,
custom_title,
locale,
langs_count = 5,
border_radius,
border_color,
} = options;
/**
*
* @param {any[]} langs
* @param {number} width
* @param {number} totalLanguageSize
* @returns {string}
*/
const renderCompactLayout = (langs, width, totalLanguageSize) => {
const paddingRight = 50;
const offsetWidth = width - paddingRight;
// progressOffset holds the previous language's width and used to offset the next language
// so that we can stack them one after another, like this: [--][----][---]
let progressOffset = 0;
const compactProgressBar = langs
.map((lang) => {
const percentage = parseFloat(
((lang.size / totalLanguageSize) * offsetWidth).toFixed(2),
);

const i18n = new I18n({
locale,
translations: langCardLocales,
});
const progress = percentage < 10 ? percentage + 10 : percentage;

const output = `
<rect
mask="url(#rect-mask)"
data-testid="lang-progress"
x="${progressOffset}"
y="0"
width="${progress}"
height="8"
fill="${lang.color || "#858585"}"
/>
`;
progressOffset += percentage;
return output;
})
.join("");

return `
<mask id="rect-mask">
<rect x="0" y="0" width="${offsetWidth}" height="8" fill="white" rx="5" />
</mask>
${compactProgressBar}
${createLanguageTextNode({
x: 0,
y: 25,
langs,
totalSize: totalLanguageSize,
}).join("")}
`;
};

/**
* @param {number} totalLangs
* @returns {number}
*/
const calculateCompactLayoutHeight = (totalLangs) => {
return 90 + Math.round(totalLangs / 2) * 25;
};

/**
* @param {number} totalLangs
* @returns {number}
*/
const calculateNormalLayoutHeight = (totalLangs) => {
return 45 + (totalLangs + 1) * 40;
};

const useLanguages = (topLangs, hide, langs_count) => {
let langs = Object.values(topLangs);
let langsToHide = {};

langsCount = clampValue(parseInt(langs_count), 1, 10);
let langsCount = clampValue(parseInt(langs_count), 1, 10);

// populate langsToHide map for quick lookup
// while filtering out
Expand All @@ -104,110 +175,80 @@ const renderTopLanguages = (topLangs, options = {}) => {
})
.slice(0, langsCount);

const totalLanguageSize = langs.reduce((acc, curr) => {
return acc + curr.size;
}, 0);
const totalLanguageSize = langs.reduce((acc, curr) => acc + curr.size, 0);

// returns theme based colors with proper overrides and defaults
const { titleColor, textColor, bgColor, borderColor } = getCardColors({
return { langs, totalLanguageSize };
};

const renderTopLanguages = (topLangs, options = {}) => {
const {
hide_title,
hide_border,
card_width,
title_color,
text_color,
bg_color,
border_color,
hide,
theme,
layout,
custom_title,
locale,
langs_count = DEFAULT_LANGS_COUNT,
border_radius,
border_color,
} = options;

const i18n = new I18n({
locale,
translations: langCardLocales,
});

let width = isNaN(card_width) ? 300 : card_width;
let height = 45 + (langs.length + 1) * 40;
const { langs, totalLanguageSize } = useLanguages(
topLangs,
hide,
langs_count,
);

let finalLayout = "";
let width = isNaN(card_width) ? DEFAULT_CARD_WIDTH : card_width;
let height = calculateNormalLayoutHeight(langs.length);

// RENDER COMPACT LAYOUT
let finalLayout = "";
if (layout === "compact") {
width = width + 50;
height = 90 + Math.round(langs.length / 2) * 25;

// progressOffset holds the previous language's width and used to offset the next language
// so that we can stack them one after another, like this: [--][----][---]
let progressOffset = 0;
const compactProgressBar = langs
.map((lang) => {
const percentage = (
(lang.size / totalLanguageSize) *
(width - 50)
).toFixed(2);

const progress =
percentage < 10 ? parseFloat(percentage) + 10 : percentage;

const output = `
<rect
mask="url(#rect-mask)"
data-testid="lang-progress"
x="${progressOffset}"
y="0"
width="${progress}"
height="8"
fill="${lang.color || "#858585"}"
/>
`;
progressOffset += parseFloat(percentage);
return output;
})
.join("");

finalLayout = `
<mask id="rect-mask">
<rect x="0" y="0" width="${
width - 50
}" height="8" fill="white" rx="5" />
</mask>
${compactProgressBar}
${createLanguageTextNode({
x: 0,
y: 25,
langs,
totalSize: totalLanguageSize,
}).join("")}
`;
width = width + 50; // padding
height = calculateCompactLayoutHeight(langs.length);

finalLayout = renderCompactLayout(langs, width, totalLanguageSize);
} else {
finalLayout = flexLayout({
items: langs.map((lang) => {
return createProgressTextNode({
width: width,
name: lang.name,
color: lang.color || "#858585",
progress: ((lang.size / totalLanguageSize) * 100).toFixed(2),
});
}),
gap: 40,
direction: "column",
}).join("");
finalLayout = renderNormalLayout(langs, width, totalLanguageSize);
}

// returns theme based colors with proper overrides and defaults
const colors = getCardColors({
title_color,
text_color,
bg_color,
border_color,
theme,
});

const card = new Card({
customTitle: custom_title,
defaultTitle: i18n.t("langcard.title"),
width,
height,
border_radius,
colors: {
titleColor,
textColor,
bgColor,
borderColor,
},
colors,
});

card.disableAnimations();
card.setHideBorder(hide_border);
card.setHideTitle(hide_title);
card.setCSS(`
.lang-name { font: 400 11px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
`);
card.setCSS(
`.lang-name { font: 400 11px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${colors.textColor} }`,
);

return card.render(`
<svg data-testid="lang-items" x="25">
<svg data-testid="lang-items" x="${CARD_PADDING}">
${finalLayout}
</svg>
`);
Expand Down
2 changes: 1 addition & 1 deletion src/common/Card.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class Card {
}

renderGradient() {
if (typeof this.colors.bgColor !== "object") return;
if (typeof this.colors.bgColor !== "object") return "";

const gradients = this.colors.bgColor.slice(1);
return typeof this.colors.bgColor === "object"
Expand Down
6 changes: 6 additions & 0 deletions src/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const statCardLocales = ({ name, apostrophe }) => {
cs: `GitHub statistiky uživatele ${encodedName}`,
de: `${encodedName + apostrophe} GitHub-Statistiken`,
en: `${encodedName}'${apostrophe} GitHub Stats`,
bn: `${encodedName} এর GitHub পরিসংখ্যান`,
es: `Estadísticas de GitHub de ${encodedName}`,
fr: `Statistiques GitHub de ${encodedName}`,
hu: `${encodedName} GitHub statisztika`,
Expand All @@ -34,6 +35,7 @@ const statCardLocales = ({ name, apostrophe }) => {
cs: "Celkem hvězd",
de: "Sterne Insgesamt",
en: "Total Stars",
bn: "সর্বমোট Stars",
es: "Estrellas totales",
fr: "Total d'étoiles",
hu: "Csillagok",
Expand All @@ -59,6 +61,7 @@ const statCardLocales = ({ name, apostrophe }) => {
cs: "Celkem commitů",
de: "Anzahl Commits",
en: "Total Commits",
bn: "সর্বমোট Commits",
es: "Commits totales",
fr: "Total des validations",
hu: "Összes commit",
Expand All @@ -84,6 +87,7 @@ const statCardLocales = ({ name, apostrophe }) => {
cs: "Celkem PRs",
de: "PRs Insgesamt",
en: "Total PRs",
bn: "সর্বমোট PRs",
es: "PRs totales",
fr: "Total des PR",
hu: "Összes PR",
Expand All @@ -109,6 +113,7 @@ const statCardLocales = ({ name, apostrophe }) => {
cs: "Celkem problémů",
de: "Anzahl Issues",
en: "Total Issues",
bn: "সর্বমোট Issues",
es: "Issues totales",
fr: "Nombre total d'incidents",
hu: "Összes hibajegy",
Expand All @@ -134,6 +139,7 @@ const statCardLocales = ({ name, apostrophe }) => {
cs: "Přispěl k",
de: "Beigetragen zu",
en: "Contributed to",
bn: "অবদান রেখেছেন",
es: "Contribuciones en",
fr: "Contribué à",
hu: "Hozzájárulások",
Expand Down
4 changes: 2 additions & 2 deletions tests/__snapshots__/renderWakatimeCard.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ exports[`Test Render Wakatime Card should render correctly 1`] = `
</style>
undefined
<rect
data-testid=\\"card-bg\\"
Expand Down Expand Up @@ -212,7 +212,7 @@ exports[`Test Render Wakatime Card should render correctly with compact layout 1
</style>
undefined
<rect
data-testid=\\"card-bg\\"
Expand Down
Loading

0 comments on commit b07ce83

Please sign in to comment.