mirror of
https://github.com/anuraghazra/github-readme-stats.git
synced 2025-01-30 14:08:14 +08:00
feat: hide wakatime languages (#1212)
* feat: added option to hide languages * feat: recalculate percentages for hidden languages * refactor: reverted langs_count and did some formatting * doc: added hide to readme * feat: make languages var mutable and improve filter logic Co-authored-by: Adrian Kunz <clashsoft@hotmail.com> * refactor: improve code and added tests Co-authored-by: Adrian Kunz <clashsoft@hotmail.com> Co-authored-by: Anurag <hazru.anurag@gmail.com>
This commit is contained in:
parent
8f316346c1
commit
1a3edcaae0
@ -3,6 +3,7 @@ const {
|
||||
renderError,
|
||||
parseBoolean,
|
||||
clampValue,
|
||||
parseArray,
|
||||
CONSTANTS,
|
||||
isLocaleAvailable,
|
||||
} = require("../src/common/utils");
|
||||
@ -26,6 +27,7 @@ module.exports = async (req, res) => {
|
||||
locale,
|
||||
layout,
|
||||
langs_count,
|
||||
hide,
|
||||
api_domain,
|
||||
range,
|
||||
border_radius,
|
||||
@ -58,6 +60,7 @@ module.exports = async (req, res) => {
|
||||
custom_title,
|
||||
hide_title: parseBoolean(hide_title),
|
||||
hide_border: parseBoolean(hide_border),
|
||||
hide: parseArray(hide),
|
||||
line_height,
|
||||
title_color,
|
||||
icon_color,
|
||||
|
@ -212,6 +212,7 @@ You can provide multiple comma-separated values in bg_color option to render a g
|
||||
|
||||
#### Wakatime Card Exclusive Options:
|
||||
|
||||
- `hide` - Hide the languages specified from the card _(Comma-separated values)_
|
||||
- `hide_title` - _(boolean)_
|
||||
- `line_height` - Sets the line-height between text _(number)_
|
||||
- `hide_progress` - Hides the progress bar and percentage _(boolean)_
|
||||
|
@ -2,15 +2,18 @@ const Card = require("../common/Card");
|
||||
const I18n = require("../common/I18n");
|
||||
const { langCardLocales } = require("../translations");
|
||||
const { createProgressNode } = require("../common/createProgressNode");
|
||||
const { clampValue, getCardColors, flexLayout } = require("../common/utils");
|
||||
const {
|
||||
clampValue,
|
||||
getCardColors,
|
||||
flexLayout,
|
||||
lowercaseTrim,
|
||||
} = 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;
|
||||
|
@ -4,7 +4,12 @@ const { getStyles } = require("../getStyles");
|
||||
const { wakatimeCardLocales } = require("../translations");
|
||||
const languageColors = require("../common/languageColors.json");
|
||||
const { createProgressNode } = require("../common/createProgressNode");
|
||||
const { clampValue, getCardColors, flexLayout } = require("../common/utils");
|
||||
const {
|
||||
clampValue,
|
||||
getCardColors,
|
||||
flexLayout,
|
||||
lowercaseTrim,
|
||||
} = require("../common/utils");
|
||||
|
||||
const noCodingActivityNode = ({ color, text }) => {
|
||||
return `
|
||||
@ -61,34 +66,47 @@ const createTextNode = ({
|
||||
const cardProgress = hideProgress
|
||||
? null
|
||||
: createProgressNode({
|
||||
x: 110,
|
||||
y: 4,
|
||||
progress: percent,
|
||||
color: progressBarColor,
|
||||
width: 220,
|
||||
name: label,
|
||||
progressBarBackgroundColor,
|
||||
});
|
||||
x: 110,
|
||||
y: 4,
|
||||
progress: percent,
|
||||
color: progressBarColor,
|
||||
width: 220,
|
||||
name: label,
|
||||
progressBarBackgroundColor,
|
||||
});
|
||||
|
||||
return `
|
||||
<g class="stagger" style="animation-delay: ${staggerDelay}ms" transform="translate(25, 0)">
|
||||
<text class="stat bold" y="12.5">${label}:</text>
|
||||
<text class="stat bold" y="12.5" data-testid="${id}">${label}:</text>
|
||||
<text
|
||||
class="stat"
|
||||
x="${hideProgress ? 170 : 350}"
|
||||
y="12.5"
|
||||
data-testid="${id}"
|
||||
>${value}</text>
|
||||
${cardProgress}
|
||||
</g>
|
||||
`;
|
||||
};
|
||||
|
||||
const recalculatePercentages = (languages) => {
|
||||
// recalculating percentages so that,
|
||||
// compact layout's progress bar does not break when hiding languages
|
||||
const totalSum = languages.reduce(
|
||||
(totalSum, language) => totalSum + language.percent,
|
||||
0,
|
||||
);
|
||||
const weight = (100 / totalSum).toFixed(2);
|
||||
languages.forEach((language) => {
|
||||
language.percent = (language.percent * weight).toFixed(2);
|
||||
});
|
||||
};
|
||||
|
||||
const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
const { languages } = stats;
|
||||
let { languages } = stats;
|
||||
const {
|
||||
hide_title = false,
|
||||
hide_border = false,
|
||||
hide,
|
||||
line_height = 25,
|
||||
title_color,
|
||||
icon_color,
|
||||
@ -104,6 +122,15 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
border_color,
|
||||
} = options;
|
||||
|
||||
const shouldHideLangs = Array.isArray(hide) && hide.length > 0;
|
||||
if (shouldHideLangs) {
|
||||
const languagesToHide = new Set(hide.map((lang) => lowercaseTrim(lang)));
|
||||
languages = languages.filter(
|
||||
(lang) => !languagesToHide.has(lowercaseTrim(lang.name)),
|
||||
);
|
||||
recalculatePercentages(languages);
|
||||
}
|
||||
|
||||
const i18n = new I18n({
|
||||
locale,
|
||||
translations: wakatimeCardLocales,
|
||||
@ -131,8 +158,8 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
|
||||
const filteredLanguages = languages
|
||||
? languages
|
||||
.filter((language) => language.hours || language.minutes)
|
||||
.slice(0, langsCount)
|
||||
.filter((language) => language.hours || language.minutes)
|
||||
.slice(0, langsCount)
|
||||
: [];
|
||||
|
||||
// Calculate the card height depending on how many items there are
|
||||
@ -186,17 +213,16 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
</mask>
|
||||
${compactProgressBar}
|
||||
${createLanguageTextNode({
|
||||
x: 0,
|
||||
y: 25,
|
||||
langs: filteredLanguages,
|
||||
totalSize: 100,
|
||||
}).join("")}
|
||||
x: 0,
|
||||
y: 25,
|
||||
langs: filteredLanguages,
|
||||
totalSize: 100,
|
||||
}).join("")}
|
||||
`;
|
||||
} else {
|
||||
finalLayout = flexLayout({
|
||||
items: filteredLanguages.length
|
||||
? filteredLanguages
|
||||
.map((language) => {
|
||||
? filteredLanguages.map((language) => {
|
||||
return createTextNode({
|
||||
id: language.name,
|
||||
label: language.name,
|
||||
@ -208,11 +234,11 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
});
|
||||
})
|
||||
: [
|
||||
noCodingActivityNode({
|
||||
color: textColor,
|
||||
text: i18n.t("wakatimecard.nocodingactivity"),
|
||||
}),
|
||||
],
|
||||
noCodingActivityNode({
|
||||
color: textColor,
|
||||
text: i18n.t("wakatimecard.nocodingactivity"),
|
||||
}),
|
||||
],
|
||||
gap: lheight,
|
||||
direction: "column",
|
||||
}).join("");
|
||||
|
@ -230,6 +230,7 @@ function measureText(str, fontSize = 10) {
|
||||
.reduce((cur, acc) => acc + cur) * fontSize
|
||||
);
|
||||
}
|
||||
const lowercaseTrim = (name) => name.toLowerCase().trim();
|
||||
|
||||
module.exports = {
|
||||
renderError,
|
||||
@ -248,4 +249,5 @@ module.exports = {
|
||||
logger,
|
||||
CONSTANTS,
|
||||
CustomError,
|
||||
lowercaseTrim,
|
||||
};
|
||||
|
@ -99,12 +99,11 @@ exports[`Test Render Wakatime Card should render correctly 1`] = `
|
||||
<svg x=\\"0\\" y=\\"0\\" width=\\"100%\\">
|
||||
<g transform=\\"translate(0, 0)\\">
|
||||
<g class=\\"stagger\\" style=\\"animation-delay: NaNms\\" transform=\\"translate(25, 0)\\">
|
||||
<text class=\\"stat bold\\" y=\\"12.5\\">Other:</text>
|
||||
<text class=\\"stat bold\\" y=\\"12.5\\" data-testid=\\"Other\\">Other:</text>
|
||||
<text
|
||||
class=\\"stat\\"
|
||||
x=\\"350\\"
|
||||
y=\\"12.5\\"
|
||||
data-testid=\\"Other\\"
|
||||
>19 mins</text>
|
||||
|
||||
<svg width=\\"220\\" x=\\"110\\" y=\\"4\\">
|
||||
@ -122,12 +121,11 @@ exports[`Test Render Wakatime Card should render correctly 1`] = `
|
||||
</g>
|
||||
</g><g transform=\\"translate(0, 25)\\">
|
||||
<g class=\\"stagger\\" style=\\"animation-delay: NaNms\\" transform=\\"translate(25, 0)\\">
|
||||
<text class=\\"stat bold\\" y=\\"12.5\\">TypeScript:</text>
|
||||
<text class=\\"stat bold\\" y=\\"12.5\\" data-testid=\\"TypeScript\\">TypeScript:</text>
|
||||
<text
|
||||
class=\\"stat\\"
|
||||
x=\\"350\\"
|
||||
y=\\"12.5\\"
|
||||
data-testid=\\"TypeScript\\"
|
||||
>1 min</text>
|
||||
|
||||
<svg width=\\"220\\" x=\\"110\\" y=\\"4\\">
|
||||
|
@ -1,6 +1,5 @@
|
||||
require("@testing-library/jest-dom");
|
||||
const cssToObject = require("css-to-object");
|
||||
const fetchTopLanguages = require("../src/fetchers/top-languages-fetcher");
|
||||
const renderTopLanguages = require("../src/cards/top-languages-card");
|
||||
|
||||
const { queryByTestId, queryAllByTestId } = require("@testing-library/dom");
|
||||
|
@ -1,6 +1,7 @@
|
||||
require("@testing-library/jest-dom");
|
||||
const renderWakatimeCard = require("../src/cards/wakatime-card");
|
||||
const { queryByTestId } = require("@testing-library/dom");
|
||||
|
||||
const renderWakatimeCard = require("../src/cards/wakatime-card");
|
||||
const { wakaTimeData } = require("./fetchWakatime.test");
|
||||
|
||||
describe("Test Render Wakatime Card", () => {
|
||||
@ -16,6 +17,16 @@ describe("Test Render Wakatime Card", () => {
|
||||
expect(card).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should hide languages when hide is passed", () => {
|
||||
document.body.innerHTML = renderWakatimeCard(wakaTimeData.data, {
|
||||
hide: ["YAML", "Other"],
|
||||
});
|
||||
|
||||
expect(queryByTestId(document.body, /YAML/i)).toBeNull();
|
||||
expect(queryByTestId(document.body, /Other/i)).toBeNull();
|
||||
expect(queryByTestId(document.body, /TypeScript/i)).not.toBeNull();
|
||||
});
|
||||
|
||||
it("should render translations", () => {
|
||||
document.body.innerHTML = renderWakatimeCard({}, { locale: "cn" });
|
||||
expect(document.getElementsByClassName("header")[0].textContent).toBe(
|
||||
@ -28,9 +39,11 @@ describe("Test Render Wakatime Card", () => {
|
||||
});
|
||||
|
||||
it("should render without rounding", () => {
|
||||
document.body.innerHTML = renderWakatimeCard(wakaTimeData.data, { border_radius: "0" });
|
||||
document.body.innerHTML = renderWakatimeCard(wakaTimeData.data, {
|
||||
border_radius: "0",
|
||||
});
|
||||
expect(document.querySelector("rect")).toHaveAttribute("rx", "0");
|
||||
document.body.innerHTML = renderWakatimeCard(wakaTimeData.data, { });
|
||||
document.body.innerHTML = renderWakatimeCard(wakaTimeData.data, {});
|
||||
expect(document.querySelector("rect")).toHaveAttribute("rx", "4.5");
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user