Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(progress-bar-border): implement progress bar border options for cards with lang progress bar #3831

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
7 changes: 7 additions & 0 deletions api/top-langs.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export default async (req, res) => {
border_color,
disable_animations,
hide_progress,
progress_bar_border_color,
progress_bar_border_thickness,
} = req.query;
res.setHeader("Content-Type", "image/svg+xml");

Expand Down Expand Up @@ -104,6 +106,11 @@ export default async (req, res) => {
locale: locale ? locale.toLowerCase() : null,
disable_animations: parseBoolean(disable_animations),
hide_progress: parseBoolean(hide_progress),
progress_bar_border_color,
progress_bar_border_thickness: parseInt(
progress_bar_border_thickness || "1",
10,
),
}),
);
} catch (err) {
Expand Down
7 changes: 7 additions & 0 deletions api/wakatime.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export default async (req, res) => {
cache_seconds,
hide_title,
hide_progress,
progress_bar_border_color,
progress_bar_border_thickness,
custom_title,
locale,
layout,
Expand Down Expand Up @@ -80,6 +82,11 @@ export default async (req, res) => {
bg_color,
theme,
hide_progress,
progress_bar_border_color,
progress_bar_border_thickness: parseInt(
progress_bar_border_thickness || "1",
10,
),
border_radius,
border_color,
locale: locale ? locale.toLowerCase() : null,
Expand Down
4 changes: 4 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,8 @@ If we don't support your language, please consider contributing! You can find mo
| `custom_title` | Sets a custom title for the card. | string | `Most Used Languages` |
| `disable_animations` | Disables all animations in the card. | boolean | `false` |
| `hide_progress` | Uses the compact layout option, hides percentages, and removes the bars. | boolean | `false` |
| `progress_bar_border_color` | Sets the border color for the progress bar. | string (hex color or none for no border) | `none` |
| `progress_bar_border_thickness` | Sets the border thickness for the progress bar. Does not apply when `progress_bar_border_color` is `none`. | number | `1` |
| `size_weight` | Configures language stats algorithm (see [Language stats algorithm](#language-stats-algorithm)). | integer | `1` |
| `count_weight` | Configures language stats algorithm (see [Language stats algorithm](#language-stats-algorithm)). | integer | `0` |

Expand All @@ -429,6 +431,8 @@ If we don't support your language, please consider contributing! You can find mo
| `hide_title` | Hides the title of your card. | boolean | `false` |
| `line_height` | Sets the line height between text. | integer | `25` |
| `hide_progress` | Hides the progress bar and percentage. | boolean | `false` |
| `progress_bar_border_color` | Sets the border color for the progress bar. | string (hex color or none for no border) | `none` |
| `progress_bar_border_thickness` | Sets the border thickness for the progress bar. Does not apply when `progress_bar_border_color` is `none`. | number | `1` |
| `custom_title` | Sets a custom title for the card. | string | `WakaTime Stats` |
| `layout` | Switches between two available layouts `default` & `compact`. | enum | `default` |
| `langs_count` | Limits the number of languages on the card, defaults to all reported languages. | integer | `null` |
Expand Down
62 changes: 57 additions & 5 deletions src/cards/top-languages-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,19 @@ const trimTopLanguages = (topLangs, langs_count, hide) => {
* @param {string} props.name Name of the programming language.
* @param {number} props.progress Usage of the programming language in percentage.
* @param {number} props.index Index of the programming language.
* @param {string} props.progressBarBorderColor Border color of the progress bar.
* @param {number} props.progressBarBorderThickness Border thickness of the progress bar.
* @returns {string} Programming language SVG node.
*/
const createProgressTextNode = ({ width, color, name, progress, index }) => {
const createProgressTextNode = ({
width,
color,
name,
progress,
index,
progressBarBorderColor,
progressBarBorderThickness,
}) => {
const staggerDelay = (index + 3) * 150;
const paddingRight = 95;
const progressTextX = width - paddingRight + 10;
Expand All @@ -224,6 +234,8 @@ const createProgressTextNode = ({ width, color, name, progress, index }) => {
width: progressWidth,
progress,
progressBarBackgroundColor: "#ddd",
progressBarBorderColor,
progressBarBorderThickness,
delay: staggerDelay + 300,
})}
</g>
Expand Down Expand Up @@ -322,9 +334,17 @@ const createDonutLanguagesNode = ({ langs, totalSize }) => {
* @param {Lang[]} langs Array of programming languages.
* @param {number} width Card width.
* @param {number} totalLanguageSize Total size of all languages.
* @param {string} progressBarBorderColor Border color of progress bar.
* @param {number} progressBarBorderThickness Border thickness of progress bar.
* @returns {string} Normal layout card SVG object.
*/
const renderNormalLayout = (langs, width, totalLanguageSize) => {
const renderNormalLayout = (
langs,
width,
totalLanguageSize,
progressBarBorderColor,
progressBarBorderThickness,
) => {
return flexLayout({
items: langs.map((lang, index) => {
return createProgressTextNode({
Expand All @@ -335,6 +355,8 @@ const renderNormalLayout = (langs, width, totalLanguageSize) => {
((lang.size / totalLanguageSize) * 100).toFixed(2),
),
index,
progressBarBorderColor,
progressBarBorderThickness,
});
}),
gap: 40,
Expand All @@ -348,10 +370,19 @@ const renderNormalLayout = (langs, width, totalLanguageSize) => {
* @param {Lang[]} langs Array of programming languages.
* @param {number} width Card width.
* @param {number} totalLanguageSize Total size of all languages.
* @param {number} progressBarBorderThickness Border thickness of the progress bar
* @param {string} progressBarBorderColor Border color of the progress bar
* @param {boolean=} hideProgress Whether to hide progress bar.
* @returns {string} Compact layout card SVG object.
*/
const renderCompactLayout = (langs, width, totalLanguageSize, hideProgress) => {
const renderCompactLayout = (
langs,
width,
totalLanguageSize,
progressBarBorderThickness,
progressBarBorderColor,
hideProgress,
) => {
const paddingRight = 50;
const offsetWidth = width - paddingRight;
// progressOffset holds the previous language's width and used to offset the next language
Expand Down Expand Up @@ -386,10 +417,20 @@ const renderCompactLayout = (langs, width, totalLanguageSize, hideProgress) => {
hideProgress
? ""
: `
<mask id="rect-mask">
<mask id="rect-mask">
<rect x="0" y="0" width="${offsetWidth}" height="8" fill="white" rx="5"/>
</mask>
${compactProgressBar}
<rect
x="${progressBarBorderThickness / 2}"
y="${progressBarBorderThickness / 2}"
width="${offsetWidth - progressBarBorderThickness}"
height="${8 - progressBarBorderThickness}"
stroke="${progressBarBorderColor}"
stroke-width="${progressBarBorderThickness}"
fill="none"
rx="${5 - progressBarBorderThickness}"
/>
`
}
<g transform="translate(0, ${hideProgress ? "0" : "25"})">
Expand Down Expand Up @@ -730,6 +771,8 @@ const renderTopLanguages = (topLangs, options = {}) => {
bg_color,
hide,
hide_progress,
progress_bar_border_color,
progress_bar_border_thickness = 1,
theme,
layout,
custom_title,
Expand Down Expand Up @@ -766,6 +809,7 @@ const renderTopLanguages = (topLangs, options = {}) => {
text_color,
bg_color,
border_color,
progress_bar_border_color,
theme,
});

Expand All @@ -791,14 +835,22 @@ const renderTopLanguages = (topLangs, options = {}) => {
langs,
width,
totalLanguageSize,
progress_bar_border_thickness,
colors.progressBarBorderColor,
hide_progress,
);
} else if (layout === "donut") {
height = calculateDonutLayoutHeight(langs.length);
width = width + 50; // padding
finalLayout = renderDonutLayout(langs, width, totalLanguageSize);
} else {
finalLayout = renderNormalLayout(langs, width, totalLanguageSize);
finalLayout = renderNormalLayout(
langs,
width,
totalLanguageSize,
colors.progressBarBorderColor,
progress_bar_border_thickness,
);
}

const card = new Card({
Expand Down
49 changes: 28 additions & 21 deletions src/cards/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ export type CommonOptions = {
hide_border: boolean;
};

export type ProgressOptions = {
hide_progress: boolean;
progress_bar_border_color: string;
progress_bar_border_thickness: number;
};

export type StatCardOptions = CommonOptions & {
hide: string[];
show_icons: boolean;
Expand All @@ -35,28 +41,29 @@ export type RepoCardOptions = CommonOptions & {
description_lines_count: number;
};

export type TopLangOptions = CommonOptions & {
hide_title: boolean;
card_width: number;
hide: string[];
layout: "compact" | "normal" | "donut" | "donut-vertical" | "pie";
custom_title: string;
langs_count: number;
disable_animations: boolean;
hide_progress: boolean;
};
export type TopLangOptions = CommonOptions &
ProgressOptions & {
hide_title: boolean;
card_width: number;
hide: string[];
layout: "compact" | "normal" | "donut" | "donut-vertical" | "pie";
custom_title: string;
langs_count: number;
disable_animations: boolean;
};

export type WakaTimeOptions = CommonOptions & {
hide_title: boolean;
hide: string[];
line_height: string;
hide_progress: boolean;
custom_title: string;
layout: "compact" | "normal";
langs_count: number;
display_format: "time" | "percent";
disable_animations: boolean;
};
export type WakaTimeOptions = CommonOptions &
ProgressOptions & {
hide_title: boolean;
hide: string[];
line_height: string;
hide_progress: boolean;
custom_title: string;
layout: "compact" | "normal";
langs_count: number;
display_format: "time" | "percent";
disable_animations: boolean;
};

export type GistCardOptions = CommonOptions & {
show_owner: boolean;
Expand Down
54 changes: 44 additions & 10 deletions src/cards/wakatime-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ const createLanguageTextNode = ({ langs, y, display_format }) => {
* @param {boolean=} args.hideProgress Whether to hide the progress bar.
* @param {string} args.progressBarColor The color of the progress bar.
* @param {string} args.progressBarBackgroundColor The color of the progress bar background.
* @param {string} args.progressBarBorderColor The color of the progress bar border.
* @param {number} args.progressBarBorderThickness The thickness of the progress bar border.
* @returns {string} The text SVG node.
*/
const createTextNode = ({
Expand All @@ -128,6 +130,8 @@ const createTextNode = ({
hideProgress,
progressBarColor,
progressBarBackgroundColor,
progressBarBorderColor,
progressBarBorderThickness,
}) => {
const staggerDelay = (index + 3) * 150;

Expand All @@ -142,6 +146,8 @@ const createTextNode = ({
// @ts-ignore
name: label,
progressBarBackgroundColor,
progressBarBorderColor,
progressBarBorderThickness,
delay: staggerDelay + 300,
});

Expand Down Expand Up @@ -231,6 +237,8 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
bg_color,
theme = "default",
hide_progress,
progress_bar_border_color,
progress_bar_border_thickness = 1,
custom_title,
locale,
layout,
Expand Down Expand Up @@ -264,15 +272,22 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
const langsCount = clampValue(langs_count, 1, langs_count);

// returns theme based colors with proper overrides and defaults
const { titleColor, textColor, iconColor, bgColor, borderColor } =
getCardColors({
title_color,
icon_color,
text_color,
bg_color,
border_color,
theme,
});
const {
titleColor,
textColor,
iconColor,
bgColor,
borderColor,
progressBarBorderColor,
} = getCardColors({
title_color,
icon_color,
text_color,
bg_color,
border_color,
progress_bar_border_color,
theme,
});

const filteredLanguages = languages
.filter((language) => language.hours || language.minutes)
Expand Down Expand Up @@ -322,6 +337,23 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
})
.join("");

const hasProgressBarBorder = progressBarBorderColor !== "none";
const progressBarBorder = hasProgressBarBorder
? `
<rect
data-testid="lang-progress-border"
x="${25 - progress_bar_border_thickness / 2}"
y="${progress_bar_border_thickness / 2}"
width="${width - 50}"
height="${8 - progress_bar_border_thickness}"
stroke="${progressBarBorderColor}"
stroke-width="${progress_bar_border_thickness}"
fill="none"
rx="${5 - progress_bar_border_thickness}"
/>
`
: "";

finalLayout = `
<mask id="rect-mask">
<rect x="25" y="0" width="${width - 50}" height="8" fill="white" rx="5" />
Expand All @@ -343,7 +375,7 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
: i18n.t("wakatimecard.nocodedetails")
: i18n.t("wakatimecard.notpublic"),
})
}
}${progressBarBorder}
`;
} else {
finalLayout = flexLayout({
Expand All @@ -359,6 +391,8 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
progressBarColor: titleColor,
// @ts-ignore
progressBarBackgroundColor: textColor,
progressBarBorderColor,
progressBarBorderThickness: progress_bar_border_thickness,
hideProgress: hide_progress,
});
})
Expand Down
Loading