mirror of
https://github.com/tiennm99/github-readme-stats.git
synced 2026-08-05 16:24:44 +00:00
feat: add wakatime card (#392)
* Adds wakatime card route * Adds language progress on wakatime card * Adds wakatime card on README * Adds no coding activity node * Remove percent displayed on wakatime's card * Update readme * refactor: refactored code & added tests Co-authored-by: Anurag <hazru.anurag@gmail.com>
This commit is contained in:
co-authored by
Anurag
parent
e377770a71
commit
6e73a0035d
@@ -0,0 +1,156 @@
|
||||
const { getCardColors, FlexLayout, clampValue } = require("../common/utils");
|
||||
const { getStyles } = require("../getStyles");
|
||||
const icons = require("../common/icons");
|
||||
const Card = require("../common/Card");
|
||||
|
||||
const noCodingActivityNode = ({ color }) => {
|
||||
return `
|
||||
<text x="25" y="11" class="stat bold" fill="${color}">No coding activity this week</text>
|
||||
`;
|
||||
};
|
||||
|
||||
const createProgressNode = ({
|
||||
width,
|
||||
color,
|
||||
progress,
|
||||
progressBarBackgroundColor,
|
||||
}) => {
|
||||
const progressPercentage = clampValue(progress, 2, 100);
|
||||
|
||||
return `
|
||||
<svg width="${width}" overflow="auto">
|
||||
<rect rx="5" ry="5" x="110" y="4" width="${width}" height="8" fill="${progressBarBackgroundColor}"></rect>
|
||||
<rect
|
||||
height="8"
|
||||
fill="${color}"
|
||||
rx="5" ry="5" x="110" y="4"
|
||||
data-testid="lang-progress"
|
||||
width="${progressPercentage}%"
|
||||
>
|
||||
</rect>
|
||||
</svg>
|
||||
`;
|
||||
};
|
||||
|
||||
const createTextNode = ({
|
||||
id,
|
||||
label,
|
||||
value,
|
||||
index,
|
||||
percent,
|
||||
hideProgress,
|
||||
progressBarColor,
|
||||
progressBarBackgroundColor,
|
||||
}) => {
|
||||
const staggerDelay = (index + 3) * 150;
|
||||
|
||||
const cardProgress = hideProgress
|
||||
? null
|
||||
: createProgressNode({
|
||||
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"
|
||||
x="${hideProgress ? 170 : 350}"
|
||||
y="12.5"
|
||||
data-testid="${id}"
|
||||
>${value}</text>
|
||||
${cardProgress}
|
||||
</g>
|
||||
`;
|
||||
};
|
||||
|
||||
const renderWakatimeCard = (stats = {}, options = { hide: [] }) => {
|
||||
const { languages } = stats;
|
||||
const {
|
||||
hide_title = false,
|
||||
hide_border = false,
|
||||
line_height = 25,
|
||||
title_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
theme = "default",
|
||||
hide_progress,
|
||||
} = options;
|
||||
|
||||
const lheight = parseInt(line_height, 10);
|
||||
|
||||
// returns theme based colors with proper overrides and defaults
|
||||
const { titleColor, textColor, iconColor, bgColor } = getCardColors({
|
||||
title_color,
|
||||
icon_color,
|
||||
text_color,
|
||||
bg_color,
|
||||
theme,
|
||||
});
|
||||
|
||||
const statItems = languages
|
||||
? languages
|
||||
.filter((language) => language.hours || language.minutes)
|
||||
.map((language) => {
|
||||
return createTextNode({
|
||||
id: language.name,
|
||||
label: language.name,
|
||||
value: language.text,
|
||||
percent: language.percent,
|
||||
progressBarColor: titleColor,
|
||||
progressBarBackgroundColor: textColor,
|
||||
hideProgress: hide_progress,
|
||||
});
|
||||
})
|
||||
: [];
|
||||
|
||||
// Calculate the card height depending on how many items there are
|
||||
// but if rank circle is visible clamp the minimum height to `150`
|
||||
let height = Math.max(45 + (statItems.length + 1) * lheight, 150);
|
||||
|
||||
const cssStyles = getStyles({
|
||||
titleColor,
|
||||
textColor,
|
||||
iconColor,
|
||||
});
|
||||
|
||||
const card = new Card({
|
||||
title: "Wakatime week stats",
|
||||
width: 495,
|
||||
height,
|
||||
colors: {
|
||||
titleColor,
|
||||
textColor,
|
||||
iconColor,
|
||||
bgColor,
|
||||
},
|
||||
});
|
||||
|
||||
card.setHideBorder(hide_border);
|
||||
card.setHideTitle(hide_title);
|
||||
card.setCSS(
|
||||
`
|
||||
${cssStyles}
|
||||
.lang-name { font: 400 11px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
|
||||
`
|
||||
);
|
||||
|
||||
return card.render(`
|
||||
<svg x="0" y="0" width="100%">
|
||||
${FlexLayout({
|
||||
items: statItems.length
|
||||
? statItems
|
||||
: [noCodingActivityNode({ color: textColor })],
|
||||
gap: lheight,
|
||||
direction: "column",
|
||||
}).join("")}
|
||||
</svg>
|
||||
`);
|
||||
};
|
||||
|
||||
module.exports = renderWakatimeCard;
|
||||
@@ -0,0 +1,13 @@
|
||||
const axios = require("axios");
|
||||
|
||||
const fetchLast7Days = async ({ username }) => {
|
||||
const { data } = await axios.get(
|
||||
`https://wakatime.com/api/v1/users/${username}/stats/last_7_days?is_including_today=true`
|
||||
);
|
||||
|
||||
return data.data;
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
fetchLast7Days,
|
||||
};
|
||||
Reference in New Issue
Block a user