From fede678fa250e17682f66340fb2166d30add5fba Mon Sep 17 00:00:00 2001 From: OldWizard209 <68309049+OldWizard209@users.noreply.github.com> Date: Tue, 20 Jul 2021 03:19:21 -0400 Subject: [PATCH 01/53] docs: better navigation in readme (#1196) --- readme.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/readme.md b/readme.md index 068e39789a71c..f33b605c40370 100644 --- a/readme.md +++ b/readme.md @@ -83,6 +83,11 @@ Your small help goes a long way. :heart: - [Wakatime Week Stats](#wakatime-week-stats) - [Themes](#themes) - [Customization](#customization) + - [Common Options](#common-options) + - [Stats Card Exclusive Options](#stats-card-exclusive-options) + - [Repo Card Exclusive Options](#repo-card-exclusive-options) + - [Language Card Exclusive Options](#language-card-exclusive-options) + - [Wakatime Card Exclusive Option](#wakatime-card-exclusive-options) - [Deploy Yourself](#deploy-on-your-own-vercel-instance) # GitHub Stats Card From 2ea5f09a2ee448e292de0ac8dfdf714bdd9142e7 Mon Sep 17 00:00:00 2001 From: XUQING Date: Thu, 29 Jul 2021 23:03:30 +0800 Subject: [PATCH 02/53] docs(cn): replace error picture (#1217) env name should be PAT_1, but on the picture is GITHUB_TOKEN --- docs/readme_cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/readme_cn.md b/docs/readme_cn.md index 60a7d26c036f4..36a5ff9359454 100644 --- a/docs/readme_cn.md +++ b/docs/readme_cn.md @@ -325,7 +325,7 @@ _注意:热门语言并不表示我的技能水平或类似的水平,它是 1. 选择 `Import Git Repository` ![](https://files.catbox.moe/pqub9q.png) 1. 选择 root 并将所有内容保持不变,并且只需添加名为 PAT_1 的环境变量(如图所示),其中将包含一个个人访问令牌(PAT),你可以在[这里](https://github.com/settings/tokens/new)轻松创建(保留默认,并且只需要命名下,名字随便) - ![](https://files.catbox.moe/caem5b.png) + ![](https://files.catbox.moe/0ez4g7.png) 1. 点击 deploy,这就完成了,查看你的域名就可使用 API 了! From ae6b56bf7fd1707c877735278f6b598a6afa8053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=98=88=ED=99=98=20Ye-Hwan=20Kim=20=28Sam=29?= <43813340+yehwankim23@users.noreply.github.com> Date: Sun, 15 Aug 2021 00:07:36 +0900 Subject: [PATCH 03/53] docs: fix grammar (#1242) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index f33b605c40370..ebc0e8eb6a38c 100644 --- a/readme.md +++ b/readme.md @@ -118,7 +118,7 @@ To hide any specific stats, you can pass a query parameter `?hide=` with comma-s You can add the count of all your private contributions to the total commits count by using the query parameter `?count_private=true`. -_Note: If you are deploying this project yourself, the private contributions will be counted by default otherwise you need to chose to share your private contribution counts._ +_Note: If you are deploying this project yourself, the private contributions will be counted by default. Otherwise, you need to choose to share your private contribution counts._ > Options: `&count_private=true` From 7907a5d33892bdfd4af707fd670f9b364bc8e17f Mon Sep 17 00:00:00 2001 From: Alexandro Perez Date: Sat, 14 Aug 2021 10:09:09 -0500 Subject: [PATCH 04/53] fix: subfolder support for api_domain wakatime api (#1235) --- src/fetchers/wakatime-fetcher.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fetchers/wakatime-fetcher.js b/src/fetchers/wakatime-fetcher.js index 55809e2a0ab7b..92371ff52fb07 100644 --- a/src/fetchers/wakatime-fetcher.js +++ b/src/fetchers/wakatime-fetcher.js @@ -4,7 +4,7 @@ const fetchWakatimeStats = async ({ username, api_domain, range }) => { try { const { data } = await axios.get( `https://${ - api_domain ? api_domain.replace(/[^a-z-.0-9]/gi, "") : "wakatime.com" + api_domain ? api_domain.replace(/\/$/gi, "") : "wakatime.com" }/api/v1/users/${username}/stats/${range || ''}?is_including_today=true`, ); From 8f316346c1e8c0352b6f3900a0a618fd899b5719 Mon Sep 17 00:00:00 2001 From: Masahiro Furudate <178inaba.git@gmail.com> Date: Wed, 25 Aug 2021 00:53:31 +0900 Subject: [PATCH 05/53] docs(theme): Auto update theme readme (#1263) --- themes/README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/themes/README.md b/themes/README.md index f6f299ff24d1e..54acc51e38ea0 100644 --- a/themes/README.md +++ b/themes/README.md @@ -30,7 +30,9 @@ Use `?theme=THEME_NAME` parameter like so :- | `calm` ![calm][calm] | `flag-india` ![flag-india][flag-india] | `omni` ![omni][omni] | | `react` ![react][react] | `jolly` ![jolly][jolly] | `maroongold` ![maroongold][maroongold] | | `yeblu` ![yeblu][yeblu] | `blueberry` ![blueberry][blueberry] | `slateorange` ![slateorange][slateorange] | -| `kacho_ga` ![kacho_ga][kacho_ga] | `outrun` ![outrun][outrun] | [Add your theme][add-theme] | +| `kacho_ga` ![kacho_ga][kacho_ga] | `outrun` ![outrun][outrun] | `ocean_dark` ![ocean_dark][ocean_dark] | +| `city_lights` ![city_lights][city_lights] | `github_dark` ![github_dark][github_dark] | `discord_old_blurple` ![discord_old_blurple][discord_old_blurple] | +| [Add your theme][add-theme] | | | ## Repo Card @@ -52,7 +54,9 @@ Use `?theme=THEME_NAME` parameter like so :- | `calm` ![calm][calm_repo] | `flag-india` ![flag-india][flag-india_repo] | `omni` ![omni][omni_repo] | | `react` ![react][react_repo] | `jolly` ![jolly][jolly_repo] | `maroongold` ![maroongold][maroongold_repo] | | `yeblu` ![yeblu][yeblu_repo] | `blueberry` ![blueberry][blueberry_repo] | `slateorange` ![slateorange][slateorange_repo] | -| `kacho_ga` ![kacho_ga][kacho_ga_repo] | `outrun` ![outrun][outrun_repo] | [Add your theme][add-theme] | +| `kacho_ga` ![kacho_ga][kacho_ga_repo] | `outrun` ![outrun][outrun_repo] | `ocean_dark` ![ocean_dark][ocean_dark_repo] | +| `city_lights` ![city_lights][city_lights_repo] | `github_dark` ![github_dark][github_dark_repo] | `discord_old_blurple` ![discord_old_blurple][discord_old_blurple_repo] | +| [Add your theme][add-theme] | | | [default]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=default @@ -100,6 +104,10 @@ Use `?theme=THEME_NAME` parameter like so :- [slateorange]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=slateorange [kacho_ga]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=kacho_ga [outrun]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=outrun +[ocean_dark]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=ocean_dark +[city_lights]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=city_lights +[github_dark]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=github_dark +[discord_old_blurple]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=discord_old_blurple [default_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=default @@ -147,6 +155,10 @@ Use `?theme=THEME_NAME` parameter like so :- [slateorange_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=slateorange [kacho_ga_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=kacho_ga [outrun_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=outrun +[ocean_dark_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=ocean_dark +[city_lights_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=city_lights +[github_dark_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=github_dark +[discord_old_blurple_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=discord_old_blurple [add-theme]: https://github.com/anuraghazra/github-readme-stats/edit/master/themes/index.js From 1a3edcaae05a2afa7d9ada4477fd6fa75c2f56f5 Mon Sep 17 00:00:00 2001 From: Julian Holfeld Date: Fri, 27 Aug 2021 21:05:10 +0200 Subject: [PATCH 06/53] 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 * refactor: improve code and added tests Co-authored-by: Adrian Kunz Co-authored-by: Anurag --- api/wakatime.js | 3 + readme.md | 1 + src/cards/top-languages-card.js | 9 ++- src/cards/wakatime-card.js | 78 ++++++++++++------- src/common/utils.js | 2 + .../renderWakatimeCard.test.js.snap | 6 +- tests/renderTopLanguages.test.js | 1 - tests/renderWakatimeCard.test.js | 19 ++++- 8 files changed, 82 insertions(+), 37 deletions(-) diff --git a/api/wakatime.js b/api/wakatime.js index 4bb8fca5d16c0..ebfea81fd79bf 100644 --- a/api/wakatime.js +++ b/api/wakatime.js @@ -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, diff --git a/readme.md b/readme.md index ebc0e8eb6a38c..68265513ccb96 100644 --- a/readme.md +++ b/readme.md @@ -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)_ diff --git a/src/cards/top-languages-card.js b/src/cards/top-languages-card.js index f281b12567239..701c8c0d46bb9 100644 --- a/src/cards/top-languages-card.js +++ b/src/cards/top-languages-card.js @@ -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; diff --git a/src/cards/wakatime-card.js b/src/cards/wakatime-card.js index 5e12cf3910d19..54093ec0302e3 100644 --- a/src/cards/wakatime-card.js +++ b/src/cards/wakatime-card.js @@ -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 ` - ${label}: + ${label}: ${value} ${cardProgress} `; }; +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: [] }) => { ${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(""); diff --git a/src/common/utils.js b/src/common/utils.js index 64cc75658bf1c..e9beb54b36c82 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -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, }; diff --git a/tests/__snapshots__/renderWakatimeCard.test.js.snap b/tests/__snapshots__/renderWakatimeCard.test.js.snap index c46f950c40dfe..c651c62a69ccd 100644 --- a/tests/__snapshots__/renderWakatimeCard.test.js.snap +++ b/tests/__snapshots__/renderWakatimeCard.test.js.snap @@ -99,12 +99,11 @@ exports[`Test Render Wakatime Card should render correctly 1`] = ` - Other: + Other: 19 mins @@ -122,12 +121,11 @@ exports[`Test Render Wakatime Card should render correctly 1`] = ` - TypeScript: + TypeScript: 1 min diff --git a/tests/renderTopLanguages.test.js b/tests/renderTopLanguages.test.js index 66946ce56e1c8..3591bc504a8af 100644 --- a/tests/renderTopLanguages.test.js +++ b/tests/renderTopLanguages.test.js @@ -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"); diff --git a/tests/renderWakatimeCard.test.js b/tests/renderWakatimeCard.test.js index 47f718cb33b07..658c52df4e9a9 100644 --- a/tests/renderWakatimeCard.test.js +++ b/tests/renderWakatimeCard.test.js @@ -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"); }); }); From d790404c766d2b62c6911bd2d1f88e59d4420aac Mon Sep 17 00:00:00 2001 From: Julian Holfeld Date: Thu, 2 Sep 2021 19:29:39 +0200 Subject: [PATCH 07/53] fix: text overlap (#1207) * feat(statCard): added more concise description * fix: removed isLongLocale param * Revert "fix: removed isLongLocale param" This reverts commit 55f1e2d8c2c063476c591714146aa82003cddbfd. * feat: add de and nl to longLocal to fix padding --- src/cards/stats-card.js | 2 ++ src/translations.js | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index 99582e0abe2a8..345c2a42b5a53 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -147,6 +147,8 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { "id", "my", "pl", + "de", + "nl", ]; const isLongLocale = longLocales.includes(locale) === true; diff --git a/src/translations.js b/src/translations.js index 7f3a0f1f7dff5..c6f39986421c5 100644 --- a/src/translations.js +++ b/src/translations.js @@ -33,8 +33,8 @@ const statCardLocales = ({ name, apostrophe }) => { ar: "مجموع النجوم", cn: "获标星数(star)", cs: "Celkem hvězd", - de: "Sterne Insgesamt", - en: "Total Stars", + de: "Insgesamt erhaltene Sterne", + en: "Total stars received", bn: "সর্বমোট Stars", es: "Estrellas totales", fr: "Total d'étoiles", @@ -42,7 +42,7 @@ const statCardLocales = ({ name, apostrophe }) => { it: "Stelle totali", ja: "スターされた数", kr: "받은 스타 수", - nl: "Totale Sterren", + nl: "Totaal sterren ontvangen", "pt-pt": "Total de estrelas", "pt-br": "Total de estrelas", np: "कुल ताराहरू", @@ -53,7 +53,7 @@ const statCardLocales = ({ name, apostrophe }) => { my: "Jumlah Bintang", sk: "Hviezdy", tr: "Toplam Yıldız", - pl: "Liczba Gwiazdek", + pl: "Liczba Gwiazdek dostanych", }, "statcard.commits": { ar: "مجموع الحفظ", From eb98a21e4274ee4388be4ac4885aff0e9c2b0276 Mon Sep 17 00:00:00 2001 From: Philip Jake Date: Thu, 2 Sep 2021 19:41:18 +0200 Subject: [PATCH 08/53] chore: grammar error on CONTRIBUTING.md (#1272) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 04528df1566a8..d65420692accd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,7 +71,7 @@ We use GitHub issues to track public bugs. Report a bug by [opening a new issue] **Q:** How to count private stats? -> **Ans:** We can only count private commits & we cannot access any other private info of any users, so it's not possible. only way is to deploy on your own instance & use your own PAT (Personal Access Token) +> **Ans:** We can only count public commits & we cannot access any other private info of any users, so it's not possible. The only way to count your personal private stats is to deploy on your own instance & use your own PAT (Personal Access Token) ### Bug Reports From 653fb387c6f809c7626c83c06ae657cb92fcb972 Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Sat, 4 Sep 2021 14:34:01 +0530 Subject: [PATCH 09/53] chore: update funding link (#1289) --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 71b71275a2510..fa7228a6af615 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,6 +1,6 @@ # These are supported funding model platforms -github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +github: [anuraghazra] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: # Replace with a single Patreon username open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username From 98ceb7568894e28bbd8b0d9fbe588f5c12b540c4 Mon Sep 17 00:00:00 2001 From: Anurag Date: Sat, 4 Sep 2021 19:59:21 +0530 Subject: [PATCH 10/53] chore: revert total stars naming --- src/translations.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations.js b/src/translations.js index c6f39986421c5..edfa30b34e417 100644 --- a/src/translations.js +++ b/src/translations.js @@ -34,7 +34,7 @@ const statCardLocales = ({ name, apostrophe }) => { cn: "获标星数(star)", cs: "Celkem hvězd", de: "Insgesamt erhaltene Sterne", - en: "Total stars received", + en: "Total Stars", bn: "সর্বমোট Stars", es: "Estrellas totales", fr: "Total d'étoiles", From c3ecd0cea3fabdad764159286c763c58c61d0d0e Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Mon, 6 Sep 2021 00:29:18 +0530 Subject: [PATCH 11/53] chore: change `total stars` to `total stars earned` (#1293) --- src/cards/stats-card.js | 25 ++++++++++--------------- src/translations.js | 2 +- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index 345c2a42b5a53..22e4be765c749 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -78,20 +78,15 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { const lheight = parseInt(line_height, 10); // 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 } = + getCardColors({ + title_color, + icon_color, + text_color, + bg_color, + border_color, + theme, + }); const apostrophe = ["x", "s"].includes(name.slice(-1).toLocaleLowerCase()) ? "" @@ -162,7 +157,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { index, showIcons: show_icons, shiftValuePos: - (!include_all_commits ? 50 : 20) + (isLongLocale ? 50 : 0), + (!include_all_commits ? 50 : 35) + (isLongLocale ? 50 : 0), }), ); diff --git a/src/translations.js b/src/translations.js index edfa30b34e417..e8a85bd773524 100644 --- a/src/translations.js +++ b/src/translations.js @@ -34,7 +34,7 @@ const statCardLocales = ({ name, apostrophe }) => { cn: "获标星数(star)", cs: "Celkem hvězd", de: "Insgesamt erhaltene Sterne", - en: "Total Stars", + en: "Total Stars Earned", bn: "সর্বমোট Stars", es: "Estrellas totales", fr: "Total d'étoiles", From c7fd3ed8f2e79e214be89aacc481a5fe71f5a5f9 Mon Sep 17 00:00:00 2001 From: Moe Bachrouch <54571275+moebachrouch@users.noreply.github.com> Date: Sun, 12 Sep 2021 12:12:07 -0400 Subject: [PATCH 12/53] docs: replace '?theme' with '&theme' (#1307) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 68265513ccb96..b06fd64c17e24 100644 --- a/readme.md +++ b/readme.md @@ -138,7 +138,7 @@ To enable icons, you can pass `show_icons=true` in the query param, like so: With inbuilt themes, you can customize the look of the card without doing any [manual customization](#customization). -Use `?theme=THEME_NAME` parameter like so :- +Use `&theme=THEME_NAME` parameter like so :- ```md ![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&theme=radical) From 4dbb9e93b9be070169228d89bff9a82342587a81 Mon Sep 17 00:00:00 2001 From: Horeb Parraud <44978959+HorebParraud@users.noreply.github.com> Date: Wed, 15 Sep 2021 16:13:31 +0200 Subject: [PATCH 13/53] style(theme): added aura_dark themes (#1312) --- themes/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/themes/index.js b/themes/index.js index 046ef47cd8739..9d3440f21bc46 100644 --- a/themes/index.js +++ b/themes/index.js @@ -294,6 +294,12 @@ const themes = { text_color: "FFFFFF", bg_color: "2C2F33", }, + aura_dark: { + title_color: "ff7372", + icon_color: "6cffd0", + text_color: "dbdbdb", + bg_color: "252334", + }, }; module.exports = themes; From 97690e173d6c68c7f294b5890d7b95424ff0326b Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Sat, 18 Sep 2021 22:39:28 +0530 Subject: [PATCH 14/53] feat(layout): improve flexLayout & fixed layout overlaps (#1314) * feat(layout): improve flexLayout & fixed layout overlaps * chore: fix vercel build --- src/cards/repo-card.js | 55 ++++++++++++++-------------- src/cards/top-languages-card.js | 63 +++++++++++++++++++++------------ src/common/utils.js | 36 ++++++++++++++++--- tests/flexLayout.test.js | 46 ++++++++++++++++++++++++ tests/renderRepoCard.test.js | 38 +++----------------- tests/utils.test.js | 21 ----------- 6 files changed, 148 insertions(+), 111 deletions(-) create mode 100644 tests/flexLayout.test.js diff --git a/src/cards/repo-card.js b/src/cards/repo-card.js index 9a21fcbdeb358..b1112d64c8f34 100644 --- a/src/cards/repo-card.js +++ b/src/cards/repo-card.js @@ -5,6 +5,7 @@ const { getCardColors, flexLayout, wrapTextMultiline, + measureText, } = require("../common/utils"); const I18n = require("../common/I18n"); const Card = require("../common/Card"); @@ -61,20 +62,15 @@ const renderRepoCard = (repo, options = {}) => { }); // 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 } = + getCardColors({ + title_color, + icon_color, + text_color, + bg_color, + border_color, + theme, + }); const totalStars = kFormatter(stargazers.totalCount); const totalForks = kFormatter(forkCount); @@ -96,21 +92,24 @@ const renderRepoCard = (repo, options = {}) => { const svgLanguage = primaryLanguage ? ` - + ${langName} ` : ""; + const iconSize = 16; const iconWithLabel = (icon, label, testid) => { - return ` - + const iconSvg = ` + ${icon} - ${label} `; + const text = `${label}`; + return flexLayout({ items: [iconSvg, text], gap: 20 }).join(""); }; + const svgStars = stargazers.totalCount > 0 && iconWithLabel(icons.star, totalStars, "stargazers"); @@ -118,8 +117,13 @@ const renderRepoCard = (repo, options = {}) => { forkCount > 0 && iconWithLabel(icons.fork, totalForks, "forkcount"); const starAndForkCount = flexLayout({ - items: [svgStars, svgForks], - gap: 65, + items: [svgLanguage, svgStars, svgForks], + sizes: [ + measureText(langName, 12), + iconSize + measureText(`${totalStars}`, 12), + iconSize + measureText(`${totalForks}`, 12), + ], + gap: 25, }).join(""); const card = new Card({ @@ -163,15 +167,8 @@ const renderRepoCard = (repo, options = {}) => { .join("")} - - ${svgLanguage} - - - ${starAndForkCount} - + + ${starAndForkCount} `); }; diff --git a/src/cards/top-languages-card.js b/src/cards/top-languages-card.js index 701c8c0d46bb9..c8109f36d6955 100644 --- a/src/cards/top-languages-card.js +++ b/src/cards/top-languages-card.js @@ -7,6 +7,8 @@ const { getCardColors, flexLayout, lowercaseTrim, + measureText, + chunkArray, } = require("../common/utils"); const DEFAULT_CARD_WIDTH = 300; @@ -33,12 +35,12 @@ const createProgressTextNode = ({ width, color, name, progress }) => { `; }; -const createCompactLangNode = ({ lang, totalSize, x, y }) => { +const createCompactLangNode = ({ lang, totalSize }) => { const percentage = ((lang.size / totalSize) * 100).toFixed(2); const color = lang.color || "#858585"; return ` - + ${lang.name} ${percentage}% @@ -47,25 +49,38 @@ const createCompactLangNode = ({ lang, totalSize, x, y }) => { `; }; -const createLanguageTextNode = ({ langs, totalSize, x, y }) => { - return langs.map((lang, index) => { - if (index % 2 === 0) { - return createCompactLangNode({ +const getLongestLang = (arr) => + arr.reduce( + (savedLang, lang) => + lang.name.length > savedLang.name.length ? lang : savedLang, + { name: "" }, + ); + +const createLanguageTextNode = ({ langs, totalSize }) => { + const longestLang = getLongestLang(langs); + const chunked = chunkArray(langs, langs.length / 2); + const layouts = chunked.map((array) => { + const items = array.map((lang, index) => + createCompactLangNode({ lang, - x, - y: 12.5 * index + y, totalSize, index, - }); - } - return createCompactLangNode({ - lang, - x: 150, - y: 12.5 + 12.5 * index, - totalSize, - index, - }); + }), + ); + return flexLayout({ + items, + gap: 25, + direction: "column", + }).join(""); }); + + const percent = ((longestLang.size / totalSize) * 100).toFixed(2); + const minGap = 150; + const maxGap = 20 + measureText(`${longestLang.name} ${percent}%`, 11); + return flexLayout({ + items: layouts, + gap: maxGap < minGap ? minGap : maxGap, + }).join(""); }; /** @@ -132,12 +147,14 @@ const renderCompactLayout = (langs, width, totalLanguageSize) => { ${compactProgressBar} - ${createLanguageTextNode({ - x: 0, - y: 25, - langs, - totalSize: totalLanguageSize, - }).join("")} + + + ${createLanguageTextNode({ + langs, + totalSize: totalLanguageSize, + width, + })} + `; }; diff --git a/src/common/utils.js b/src/common/utils.js index e9beb54b36c82..f14e8cc65f4f0 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -89,21 +89,26 @@ function request(data, headers) { /** * - * @param {String[]} items + * @param {string[]} items * @param {Number} gap - * @param {string} direction + * @param {"column" | "row"} direction + * + * @returns {string[]} * * @description * Auto layout utility, allows us to layout things * vertically or horizontally with proper gaping */ -function flexLayout({ items, gap, direction }) { +function flexLayout({ items, gap, direction, sizes = [] }) { + let lastSize = 0; // filter() for filtering out empty strings return items.filter(Boolean).map((item, i) => { - let transform = `translate(${gap * i}, 0)`; + const size = sizes[i] || 0; + let transform = `translate(${lastSize}, 0)`; if (direction === "column") { - transform = `translate(0, ${gap * i})`; + transform = `translate(0, ${lastSize})`; } + lastSize += size + gap; return `${item}`; }); } @@ -232,6 +237,26 @@ function measureText(str, fontSize = 10) { } const lowercaseTrim = (name) => name.toLowerCase().trim(); +/** + * @template T + * @param {Array} arr + * @param {number} perChunk + * @returns {Array} + */ +function chunkArray(arr, perChunk) { + return arr.reduce((resultArray, item, index) => { + const chunkIndex = Math.floor(index / perChunk); + + if (!resultArray[chunkIndex]) { + resultArray[chunkIndex] = []; // start a new chunk + } + + resultArray[chunkIndex].push(item); + + return resultArray; + }, []); +} + module.exports = { renderError, kFormatter, @@ -250,4 +275,5 @@ module.exports = { CONSTANTS, CustomError, lowercaseTrim, + chunkArray, }; diff --git a/tests/flexLayout.test.js b/tests/flexLayout.test.js new file mode 100644 index 0000000000000..5f2defd6ea805 --- /dev/null +++ b/tests/flexLayout.test.js @@ -0,0 +1,46 @@ +const { flexLayout } = require("../src/common/utils"); + +describe("flexLayout", () => { + it("should work with row & col layouts", () => { + const layout = flexLayout({ + items: ["1", "2"], + gap: 60, + }); + + expect(layout).toStrictEqual([ + `1`, + `2`, + ]); + + const columns = flexLayout({ + items: ["1", "2"], + gap: 60, + direction: "column", + }); + + expect(columns).toStrictEqual([ + `1`, + `2`, + ]); + }); + + it("should work with sizes", () => { + const layout = flexLayout({ + items: [ + "1", + "2", + "3", + "4", + ], + gap: 20, + sizes: [200, 100, 55, 25], + }); + + expect(layout).toStrictEqual([ + `1`, + `2`, + `3`, + `4`, + ]); + }); +}); diff --git a/tests/renderRepoCard.test.js b/tests/renderRepoCard.test.js index e375d35383ca5..a6d249821dee1 100644 --- a/tests/renderRepoCard.test.js +++ b/tests/renderRepoCard.test.js @@ -89,36 +89,6 @@ describe("Test renderRepoCard", () => { ); }); - it("should shift the text position depending on language length", () => { - document.body.innerHTML = renderRepoCard({ - ...data_repo.repository, - primaryLanguage: { - ...data_repo.repository.primaryLanguage, - name: "Jupyter Notebook", - }, - }); - - expect(queryByTestId(document.body, "primary-lang")).toBeInTheDocument(); - expect(queryByTestId(document.body, "star-fork-group")).toHaveAttribute( - "transform", - "translate(155, 0)", - ); - - // Small lang - document.body.innerHTML = renderRepoCard({ - ...data_repo.repository, - primaryLanguage: { - ...data_repo.repository.primaryLanguage, - name: "Ruby", - }, - }); - - expect(queryByTestId(document.body, "star-fork-group")).toHaveAttribute( - "transform", - "translate(125, 0)", - ); - }); - it("should hide language if primaryLanguage is null & fallback to correct values", () => { document.body.innerHTML = renderRepoCard({ ...data_repo.repository, @@ -332,11 +302,13 @@ describe("Test renderRepoCard", () => { ); expect(queryByTestId(document.body, "badge")).toHaveTextContent("模板"); }); - + it("should render without rounding", () => { - document.body.innerHTML = renderRepoCard(data_repo.repository, { border_radius: "0" }); + document.body.innerHTML = renderRepoCard(data_repo.repository, { + border_radius: "0", + }); expect(document.querySelector("rect")).toHaveAttribute("rx", "0"); - document.body.innerHTML = renderRepoCard(data_repo.repository, { }); + document.body.innerHTML = renderRepoCard(data_repo.repository, {}); expect(document.querySelector("rect")).toHaveAttribute("rx", "4.5"); }); }); diff --git a/tests/utils.test.js b/tests/utils.test.js index 66f55d5d25129..15c4d97481590 100644 --- a/tests/utils.test.js +++ b/tests/utils.test.js @@ -44,27 +44,6 @@ describe("Test utils.js", () => { ).toHaveTextContent(/Secondary Message/gim); }); - it("should test flexLayout", () => { - const layout = flexLayout({ - items: ["1", "2"], - gap: 60, - }).join(""); - - expect(layout).toBe( - `12`, - ); - - const columns = flexLayout({ - items: ["1", "2"], - gap: 60, - direction: "column", - }).join(""); - - expect(columns).toBe( - `12`, - ); - }); - it("getCardColors: should return expected values", () => { let colors = getCardColors({ title_color: "f00", From ded06f2fab6136cf60cafaf86f31e80e22a48c51 Mon Sep 17 00:00:00 2001 From: Anurag Date: Wed, 22 Sep 2021 22:07:12 +0530 Subject: [PATCH 15/53] chore: added under-the-hood blogpost link in contributing.md --- CONTRIBUTING.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d65420692accd..35bfdbd1f2b2b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,6 +17,15 @@ Pull requests are the best way to propose changes. We actively welcome your pull 1. If you've changed APIs, update the documentation. 1. Issue that pull request! +## Under the hood of github-readme-stats + +Interested in diving deeper into understanding how github-readme-stats works? + +[Bohdan](https://github.com/Bogdan-Lyashenko) wrote an amazing in-depth post about it, check it out: + +**[Under the hood of github-readme-stats project](https://codecrumbs.io/library/github-readme-stats)** + + ## Local Development To run & test github-readme-stats you need to follow few simple steps :- From ec8eb0c893cc360583339fd8550a92de9a6ad3f3 Mon Sep 17 00:00:00 2001 From: Chandrika Deb Date: Sun, 26 Sep 2021 20:23:12 +0530 Subject: [PATCH 16/53] style(theme): added panda theme (#1319) --- themes/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/themes/index.js b/themes/index.js index 9d3440f21bc46..e5e311d05a9f5 100644 --- a/themes/index.js +++ b/themes/index.js @@ -300,6 +300,12 @@ const themes = { text_color: "dbdbdb", bg_color: "252334", }, + panda: { + title_color: "19f9d899", + icon_color: "19f9d899", + text_color: "FF75B5", + bg_color: "31353a", + }, }; module.exports = themes; From 62d65ab483fedbcf9499d57ab8ccef0df9f85165 Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Sun, 26 Sep 2021 21:02:27 +0530 Subject: [PATCH 17/53] refactor: refactor repo card (#1325) * refactor: refactored repo-card * test: fix tests * test: fixed tests * fix: unprovided description error --- api/pin.js | 2 +- src/cards/repo-card.js | 129 +++++++++++++++++++---------------- src/common/utils.js | 23 +++++-- src/fetchers/repo-fetcher.js | 10 ++- tests/fetchRepo.test.js | 15 ++-- tests/pin.test.js | 19 +++++- tests/renderRepoCard.test.js | 19 ++++-- 7 files changed, 140 insertions(+), 77 deletions(-) diff --git a/api/pin.js b/api/pin.js index 7fad6c09f3746..65d09f0ec36e8 100644 --- a/api/pin.js +++ b/api/pin.js @@ -53,7 +53,7 @@ module.exports = async (req, res) => { and if both are zero we are not showing the stats so we can just make the cache longer, since there is no need to frequent updates */ - const stars = repoData.stargazers.totalCount; + const stars = repoData.starCount; const forks = repoData.forkCount; const isBothOver1K = stars > 1000 && forks > 1000; const isBothUnder1 = stars < 1 && forks < 1; diff --git a/src/cards/repo-card.js b/src/cards/repo-card.js index b1112d64c8f34..4573fcf6a2a94 100644 --- a/src/cards/repo-card.js +++ b/src/cards/repo-card.js @@ -1,4 +1,3 @@ -const toEmoji = require("emoji-name-map"); const { kFormatter, encodeHTML, @@ -6,21 +5,75 @@ const { flexLayout, wrapTextMultiline, measureText, + parseEmojis, } = require("../common/utils"); const I18n = require("../common/I18n"); const Card = require("../common/Card"); const icons = require("../common/icons"); const { repoCardLocales } = require("../translations"); +/** + * @param {string} label + * @param {string} textColor + * @returns {string} + */ +const getBadgeSVG = (label, textColor) => ` + + + + ${label} + + +`; + +/** + * @param {string} langName + * @param {string} langColor + * @returns {string} + */ +const createLanguageNode = (langName, langColor) => { + return ` + + + ${langName} + + `; +}; + +const ICON_SIZE = 16; +const iconWithLabel = (icon, label, testid) => { + if (label <= 0) return ""; + const iconSvg = ` + + ${icon} + + `; + const text = `${label}`; + return flexLayout({ items: [iconSvg, text], gap: 20 }).join(""); +}; + const renderRepoCard = (repo, options = {}) => { const { name, nameWithOwner, description, primaryLanguage, - stargazers, isArchived, isTemplate, + starCount, forkCount, } = repo; const { @@ -36,22 +89,17 @@ const renderRepoCard = (repo, options = {}) => { locale, } = options; + const lineHeight = 10; const header = show_owner ? nameWithOwner : name; const langName = (primaryLanguage && primaryLanguage.name) || "Unspecified"; const langColor = (primaryLanguage && primaryLanguage.color) || "#333"; - const shiftText = langName.length > 15 ? 0 : 30; - - let desc = description || "No description provided"; - - // parse emojis to unicode - desc = desc.replace(/:\w+:/gm, (emoji) => { - return toEmoji.get(emoji) || ""; - }); - + const desc = parseEmojis(description || "No description provided"); const multiLineDescription = wrapTextMultiline(desc); const descriptionLines = multiLineDescription.length; - const lineHeight = 10; + const descriptionSvg = multiLineDescription + .map((line) => `${encodeHTML(line)}`) + .join(""); const height = (descriptionLines > 1 ? 120 : 110) + descriptionLines * lineHeight; @@ -72,56 +120,21 @@ const renderRepoCard = (repo, options = {}) => { theme, }); - const totalStars = kFormatter(stargazers.totalCount); - const totalForks = kFormatter(forkCount); - - const getBadgeSVG = (label) => ` - - - - ${label} - - - `; - const svgLanguage = primaryLanguage - ? ` - - - ${langName} - - ` + ? createLanguageNode(langName, langColor) : ""; - const iconSize = 16; - const iconWithLabel = (icon, label, testid) => { - const iconSvg = ` - - ${icon} - - `; - const text = `${label}`; - return flexLayout({ items: [iconSvg, text], gap: 20 }).join(""); - }; - - const svgStars = - stargazers.totalCount > 0 && - iconWithLabel(icons.star, totalStars, "stargazers"); - const svgForks = - forkCount > 0 && iconWithLabel(icons.fork, totalForks, "forkcount"); + const totalStars = kFormatter(starCount); + const totalForks = kFormatter(forkCount); + const svgStars = iconWithLabel(icons.star, totalStars, "stargazers"); + const svgForks = iconWithLabel(icons.fork, totalForks, "forkcount"); const starAndForkCount = flexLayout({ items: [svgLanguage, svgStars, svgForks], sizes: [ measureText(langName, 12), - iconSize + measureText(`${totalStars}`, 12), - iconSize + measureText(`${totalForks}`, 12), + ICON_SIZE + measureText(`${totalStars}`, 12), + ICON_SIZE + measureText(`${totalForks}`, 12), ], gap: 25, }).join(""); @@ -155,16 +168,14 @@ const renderRepoCard = (repo, options = {}) => { return card.render(` ${ isTemplate - ? getBadgeSVG(i18n.t("repocard.template")) + ? getBadgeSVG(i18n.t("repocard.template"), textColor) : isArchived - ? getBadgeSVG(i18n.t("repocard.archived")) + ? getBadgeSVG(i18n.t("repocard.archived"), textColor) : "" } - ${multiLineDescription - .map((line) => `${encodeHTML(line)}`) - .join("")} + ${descriptionSvg} diff --git a/src/common/utils.js b/src/common/utils.js index f14e8cc65f4f0..7834dbae2cb0e 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -1,6 +1,7 @@ const axios = require("axios"); const wrap = require("word-wrap"); const themes = require("../../themes"); +const toEmoji = require("emoji-name-map"); const renderError = (message, secondaryMessage = "") => { return ` @@ -88,10 +89,11 @@ function request(data, headers) { } /** - * - * @param {string[]} items - * @param {Number} gap - * @param {"column" | "row"} direction + * @param {object} props + * @param {string[]} props.items + * @param {number} props.gap + * @param {number[]} props.sizes + * @param {"column" | "row"} props.direction * * @returns {string[]} * @@ -257,6 +259,18 @@ function chunkArray(arr, perChunk) { }, []); } +/** + * + * @param {string} str + * @returns {string} + */ +function parseEmojis(str) { + if (!str) throw new Error("[parseEmoji]: str argument not provided"); + return str.replace(/:\w+:/gm, (emoji) => { + return toEmoji.get(emoji) || ""; + }); +} + module.exports = { renderError, kFormatter, @@ -276,4 +290,5 @@ module.exports = { CustomError, lowercaseTrim, chunkArray, + parseEmojis, }; diff --git a/src/fetchers/repo-fetcher.js b/src/fetchers/repo-fetcher.js index 7e441084618f6..07e9a4c8b2ba4 100644 --- a/src/fetchers/repo-fetcher.js +++ b/src/fetchers/repo-fetcher.js @@ -63,7 +63,10 @@ async function fetchRepo(username, reponame) { if (!data.user.repository || data.user.repository.isPrivate) { throw new Error("User Repository Not found"); } - return data.user.repository; + return { + ...data.user.repository, + starCount: data.user.repository.stargazers.totalCount, + }; } if (isOrg) { @@ -73,7 +76,10 @@ async function fetchRepo(username, reponame) { ) { throw new Error("Organization Repository Not found"); } - return data.organization.repository; + return { + ...data.organization.repository, + starCount: data.organization.repository.stargazers.totalCount, + }; } } diff --git a/tests/fetchRepo.test.js b/tests/fetchRepo.test.js index 891cb4af296bf..277d627043ace 100644 --- a/tests/fetchRepo.test.js +++ b/tests/fetchRepo.test.js @@ -19,14 +19,14 @@ const data_repo = { const data_user = { data: { - user: { repository: data_repo }, + user: { repository: data_repo.repository }, organization: null, }, }; const data_org = { data: { user: null, - organization: { repository: data_repo }, + organization: { repository: data_repo.repository }, }, }; @@ -41,14 +41,21 @@ describe("Test fetchRepo", () => { mock.onPost("https://api.github.com/graphql").reply(200, data_user); let repo = await fetchRepo("anuraghazra", "convoychat"); - expect(repo).toStrictEqual(data_repo); + + expect(repo).toStrictEqual({ + ...data_repo.repository, + starCount: data_repo.repository.stargazers.totalCount, + }); }); it("should fetch correct org repo", async () => { mock.onPost("https://api.github.com/graphql").reply(200, data_org); let repo = await fetchRepo("anuraghazra", "convoychat"); - expect(repo).toStrictEqual(data_repo); + expect(repo).toStrictEqual({ + ...data_repo.repository, + starCount: data_repo.repository.stargazers.totalCount, + }); }); it("should throw error if user is found but repo is null", async () => { diff --git a/tests/pin.test.js b/tests/pin.test.js index 8abad44e1619c..29c19c63480fc 100644 --- a/tests/pin.test.js +++ b/tests/pin.test.js @@ -9,7 +9,9 @@ const data_repo = { repository: { username: "anuraghazra", name: "convoychat", - stargazers: { totalCount: 38000 }, + stargazers: { + totalCount: 38000, + }, description: "Help us take over the world! React + TS + GraphQL Chat App", primaryLanguage: { color: "#2b7489", @@ -51,7 +53,12 @@ describe("Test /api/pin", () => { await pin(req, res); expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml"); - expect(res.send).toBeCalledWith(renderRepoCard(data_repo.repository)); + expect(res.send).toBeCalledWith( + renderRepoCard({ + ...data_repo.repository, + starCount: data_repo.repository.stargazers.totalCount, + }), + ); }); it("should get the query options", async () => { @@ -76,7 +83,13 @@ describe("Test /api/pin", () => { expect(res.setHeader).toBeCalledWith("Content-Type", "image/svg+xml"); expect(res.send).toBeCalledWith( - renderRepoCard(data_repo.repository, { ...req.query }), + renderRepoCard( + { + ...data_repo.repository, + starCount: data_repo.repository.stargazers.totalCount, + }, + { ...req.query }, + ), ); }); diff --git a/tests/renderRepoCard.test.js b/tests/renderRepoCard.test.js index a6d249821dee1..4b7060a1f88f1 100644 --- a/tests/renderRepoCard.test.js +++ b/tests/renderRepoCard.test.js @@ -9,13 +9,13 @@ const data_repo = { repository: { nameWithOwner: "anuraghazra/convoychat", name: "convoychat", - stargazers: { totalCount: 38000 }, description: "Help us take over the world! React + TS + GraphQL Chat App", primaryLanguage: { color: "#2b7489", id: "MDg6TGFuZ3VhZ2UyODc=", name: "TypeScript", }, + starCount: 38000, forkCount: 100, }, }; @@ -231,7 +231,7 @@ describe("Test renderRepoCard", () => { it("should not render star count or fork count if either of the are zero", () => { document.body.innerHTML = renderRepoCard({ ...data_repo.repository, - stargazers: { totalCount: 0 }, + starCount: 0, }); expect(queryByTestId(document.body, "stargazers")).toBeNull(); @@ -239,7 +239,7 @@ describe("Test renderRepoCard", () => { document.body.innerHTML = renderRepoCard({ ...data_repo.repository, - stargazers: { totalCount: 1 }, + starCount: 1, forkCount: 0, }); @@ -248,7 +248,7 @@ describe("Test renderRepoCard", () => { document.body.innerHTML = renderRepoCard({ ...data_repo.repository, - stargazers: { totalCount: 0 }, + starCount: 0, forkCount: 0, }); @@ -311,4 +311,15 @@ describe("Test renderRepoCard", () => { document.body.innerHTML = renderRepoCard(data_repo.repository, {}); expect(document.querySelector("rect")).toHaveAttribute("rx", "4.5"); }); + + it("should fallback to default description", () => { + document.body.innerHTML = renderRepoCard({ + ...data_repo.repository, + description: undefined, + isArchived: true, + }); + expect(document.getElementsByClassName("description")[0]).toHaveTextContent( + "No description provided", + ); + }); }); From b9230cd946190dcca5d6d70cd83de23b1b3b772d Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Sun, 26 Sep 2021 21:16:20 +0530 Subject: [PATCH 18/53] chore: update theme preview bot content (#1326) --- scripts/preview-theme.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js index e809777b16e6a..9b62e8d732d9a 100644 --- a/scripts/preview-theme.js +++ b/scripts/preview-theme.js @@ -13,12 +13,10 @@ function getPrNumber() { } const themeContribGuidelines = ` - \r> Hi thanks for the theme contribution, please read our theme contribution guidelines - - \r> We are currently only accepting color combinations from any vscode theme or which has good color combination to minimize bloating the themes collection. + \rHi thanks for the theme contribution, please read our theme [contribution guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution). + \rWe are currently only accepting color combinations from any vscode theme or which has good color combination to minimize bloating the themes collection. \r> Also note that if this theme is exclusively for your personal use then instead of adding it to our theme collection you can use card [customization options](https://github.com/anuraghazra/github-readme-stats#customization) - \r> Read our [contribution guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md) for more info `; async function run() { @@ -56,7 +54,7 @@ async function run() { owner: "anuraghazra", repo: "github-readme-stats", body: ` - \rTheme preview (bot) + \r**Automated Theme preview** \rCannot create theme preview @@ -80,11 +78,11 @@ async function run() { owner: "anuraghazra", repo: "github-readme-stats", body: ` - \rTheme preview (bot) + \r**Automated Theme preview** \ntitle_color: #${titleColor} | icon_color: #${iconColor} | text_color: #${textColor} | bg_color: #${bgColor} - \rLink: ${url} + \r[Preview Link](${url}) \r[![](${url})](${url}) From f9c0e0bff64f325235ccbf936c9d5f7a918ac790 Mon Sep 17 00:00:00 2001 From: Artem Kostiuk Date: Tue, 28 Sep 2021 10:42:59 +0300 Subject: [PATCH 19/53] Change default stats card width with hide rank --- api/index.js | 2 ++ src/cards/stats-card.js | 61 ++++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/api/index.js b/api/index.js index 0cda587ea02fe..8c4c6714d4307 100644 --- a/api/index.js +++ b/api/index.js @@ -17,6 +17,7 @@ module.exports = async (req, res) => { hide, hide_title, hide_border, + card_width, hide_rank, show_icons, count_private, @@ -67,6 +68,7 @@ module.exports = async (req, res) => { show_icons: parseBoolean(show_icons), hide_title: parseBoolean(hide_title), hide_border: parseBoolean(hide_border), + card_width: parseInt(card_width, 10), hide_rank: parseBoolean(hide_rank), include_all_commits: parseBoolean(include_all_commits), line_height, diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index 22e4be765c749..32f71134f1986 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -60,6 +60,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { show_icons = false, hide_title = false, hide_border = false, + card_width, hide_rank = false, include_all_commits = false, line_height = 25, @@ -75,6 +76,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { disable_animations = false, } = options; + const lheight = parseInt(line_height, 10); // returns theme based colors with proper overrides and defaults @@ -168,26 +170,6 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { hide_rank ? 0 : 150, ); - // Conditionally rendered elements - const rankCircle = hide_rank - ? "" - : ` - - - - - ${rank.level} - - - `; - // the better user's score the the rank will be closer to zero so // subtracting 100 to get the progress in 100% const progress = 100 - rank.score; @@ -203,13 +185,22 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { return measureText(custom_title ? custom_title : i18n.t("statcard.title")); }; - const width = hide_rank + /* + When hide_rank=true, minimum card width is max of 270 and length of title + paddings. + When hide_rank=false, minimum card_width is 340. + Numbers are picked by looking at existing dimensions on production. + */ + const minCardWidth = hide_rank ? clampValue( 50 /* padding */ + calculateTextWidth() * 2, - 270 /* min */, - Infinity, - ) - : 495; + 270, + Infinity) + : 340 + const defaultCardWidth = hide_rank ? 270 : 495 + let width = isNaN(card_width) ? defaultCardWidth : card_width + if (width < minCardWidth) { + width = minCardWidth + } const card = new Card({ customTitle: custom_title, @@ -232,6 +223,26 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { if (disable_animations) card.disableAnimations(); + // Conditionally rendered elements + const rankCircle = hide_rank + ? "" + : ` + + + + + ${rank.level} + + + `; + return card.render(` ${rankCircle} From cc282739341953858711800a0f8dba9e1d88a329 Mon Sep 17 00:00:00 2001 From: Artem Kostiuk Date: Tue, 28 Sep 2021 10:43:19 +0300 Subject: [PATCH 20/53] Add tests for stats card with card_width --- tests/renderStatsCard.test.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/renderStatsCard.test.js b/tests/renderStatsCard.test.js index 96a48d1a9d7bd..fc0d4fab6e498 100644 --- a/tests/renderStatsCard.test.js +++ b/tests/renderStatsCard.test.js @@ -75,6 +75,22 @@ describe("Test renderStatsCard", () => { expect(queryByTestId(document.body, "rank-circle")).not.toBeInTheDocument(); }); + it("should render with custom width set", () => { + document.body.innerHTML = renderStatsCard(stats); + expect(document.querySelector("svg")).toHaveAttribute("width", "495"); + + document.body.innerHTML = renderStatsCard(stats, { card_width: 400 }); + expect(document.querySelector("svg")).toHaveAttribute("width", "400"); + }); + + it("should render with custom width set and limit minimum width", () => { + document.body.innerHTML = renderStatsCard(stats, { card_width: 1 }); + expect(document.querySelector("svg")).toHaveAttribute("width", "340"); + + document.body.innerHTML = renderStatsCard(stats, { card_width: 1, hide_rank: true }); + expect(document.querySelector("svg")).toHaveAttribute("width", "305.81250000000006"); + }); + it("should render default colors properly", () => { document.body.innerHTML = renderStatsCard(stats); From dc78bad925e57ac875e9da435c546c1c4a63ab97 Mon Sep 17 00:00:00 2001 From: Artem Kostiuk Date: Tue, 28 Sep 2021 10:48:53 +0300 Subject: [PATCH 21/53] Add card_width Stats Card description to readme --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index b06fd64c17e24..9d7a088963c34 100644 --- a/readme.md +++ b/readme.md @@ -183,6 +183,7 @@ You can provide multiple comma-separated values in bg_color option to render a g - `hide` - Hides the specified items from stats _(Comma-separated values)_ - `hide_title` - _(boolean)_ +- `card_width` - Set the card's width manually _(number)_ - `hide_rank` - _(boolean)_ hides the rank and automatically resizes the card width - `show_icons` - _(boolean)_ - `include_all_commits` - Count total commits instead of just the current year commits _(boolean)_ From 927e87d416be902d3dbea6a06404341ecb0e142a Mon Sep 17 00:00:00 2001 From: Danix <78866931+Danix421@users.noreply.github.com> Date: Fri, 1 Oct 2021 09:56:02 -0400 Subject: [PATCH 22/53] docs: match link with section title (#1341) * Match link with section title Match the link of Top Languages Card with the title of his section ("Tarjeta de Lenguajes Principales"). * Fix typo --- docs/readme_es.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/readme_es.md b/docs/readme_es.md index ae0cc830f0e8e..b35e89c12c323 100644 --- a/docs/readme_es.md +++ b/docs/readme_es.md @@ -64,7 +64,7 @@ - [Tarjeta de estadísticas de GitHub](#tarjeta-de-estadísticas-de-github) - [Pins adicionales de GitHub](#pines-adicionales-de-github) -- [Top Languages Card](#tarjeta-de-lenguajes-principales) +- [Tarjeta de Lenguajes Principales](#tarjeta-de-lenguajes-principales) - [Wakatime Week Stats](#estadísticas-de-la-semana-de-wakatime) - [Temas](#temas) - [Personalización](#personalización) From ab4876aa354b6bbb2cab801f73232cbd088c9af0 Mon Sep 17 00:00:00 2001 From: Red Headphone <55500003+RedHeadphone@users.noreply.github.com> Date: Fri, 1 Oct 2021 19:35:48 +0530 Subject: [PATCH 23/53] style(theme): added cobalt2 theme (#1343) --- themes/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/themes/index.js b/themes/index.js index e5e311d05a9f5..132924b8fd217 100644 --- a/themes/index.js +++ b/themes/index.js @@ -306,6 +306,12 @@ const themes = { text_color: "FF75B5", bg_color: "31353a", }, + cobalt2: { + title_color: "ffc600", + icon_color: "ffffff", + text_color: "0088ff", + bg_color: "193549", + }, }; module.exports = themes; From efd0a8bc4fa90a6d316e5f7981a95f5a5e3d7d5e Mon Sep 17 00:00:00 2001 From: Anant Mishra <84588156+Anant-mishra1729@users.noreply.github.com> Date: Fri, 1 Oct 2021 20:01:36 +0530 Subject: [PATCH 24/53] style(theme): added noctis minimus theme (#1342) * Add Noctis minimus theme * Add Noctis minimus theme Co-authored-by: Anurag Hazra --- themes/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/themes/index.js b/themes/index.js index 132924b8fd217..3c212ab152289 100644 --- a/themes/index.js +++ b/themes/index.js @@ -306,6 +306,12 @@ const themes = { text_color: "FF75B5", bg_color: "31353a", }, + noctis_minimus: { + title_color: "d3b692", + icon_color: "72b7c0", + text_color: "c5cdd3", + bg_color: "1b2932", + }, cobalt2: { title_color: "ffc600", icon_color: "ffffff", From 7d1c9b0b964c16fe512bbb4074025ebfc2e5d1de Mon Sep 17 00:00:00 2001 From: CleanMachine1 <78213164+CleanMachine1@users.noreply.github.com> Date: Fri, 1 Oct 2021 21:14:10 +0100 Subject: [PATCH 25/53] chore: fix grammatical errors in the scripts (#1346) * Fix grammatical errors * Fix grammatical errors --- scripts/generate-theme-doc.js | 4 ++-- scripts/preview-theme.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/generate-theme-doc.js b/scripts/generate-theme-doc.js index 806b2cc3fc2b4..fcb3c5eee705c 100644 --- a/scripts/generate-theme-doc.js +++ b/scripts/generate-theme-doc.js @@ -12,7 +12,7 @@ const THEME_TEMPLATE = `## Available Themes -With inbuilt themes you can customize the look of the card without doing any manual customization. +With inbuilt themes, you can customize the look of the card without doing any manual customization. Use \`?theme=THEME_NAME\` parameter like so :- @@ -43,7 +43,7 @@ ${REPO_CARD_LINKS_FLAG} [add-theme]: https://github.com/anuraghazra/github-readme-stats/edit/master/themes/index.js -Wanted to add a new theme? Consider reading the [contribution guidelines](../CONTRIBUTING.md#themes-contribution) :D +Want to add a new theme? Consider reading the [contribution guidelines](../CONTRIBUTING.md#themes-contribution) :D `; const createRepoMdLink = (theme) => { diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js index 9b62e8d732d9a..31622c6a7d400 100644 --- a/scripts/preview-theme.js +++ b/scripts/preview-theme.js @@ -13,10 +13,10 @@ function getPrNumber() { } const themeContribGuidelines = ` - \rHi thanks for the theme contribution, please read our theme [contribution guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution). - \rWe are currently only accepting color combinations from any vscode theme or which has good color combination to minimize bloating the themes collection. + \rHi, thanks for the theme contribution, please read our theme [contribution guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution). + \rWe are currently only accepting color combinations from any VSCode theme or themes which have good color combination to minimize bloating the themes collection. - \r> Also note that if this theme is exclusively for your personal use then instead of adding it to our theme collection you can use card [customization options](https://github.com/anuraghazra/github-readme-stats#customization) + \r> Also note that if this theme is exclusively for your personal use, then instead of adding it to our theme collection you can use card [customization options](https://github.com/anuraghazra/github-readme-stats#customization) `; async function run() { From 81b6593b06a3c10e80a0aa8da0a2ca7730d5121b Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Wed, 6 Oct 2021 22:43:23 +0530 Subject: [PATCH 26/53] chore: reduce vercel memory & timeout duration (#1366) * fix: change serverless function memory to 128mb * chore: change maxDuration --- vercel.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vercel.json b/vercel.json index 8306d9f7896bb..aee61ce054fd0 100644 --- a/vercel.json +++ b/vercel.json @@ -1,4 +1,10 @@ { + "functions": { + "api/*.js": { + "memory": 128, + "maxDuration": 30 + } + }, "redirects": [ { "source": "/", From d0ab2ff030edfecf74373de8ca16e9d09a273afa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Sanmartino?= Date: Wed, 6 Oct 2021 14:39:43 -0300 Subject: [PATCH 27/53] fix: wakatime card translations (#1363) --- api/wakatime.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/wakatime.js b/api/wakatime.js index ebfea81fd79bf..d585c4a025f09 100644 --- a/api/wakatime.js +++ b/api/wakatime.js @@ -5,8 +5,8 @@ const { clampValue, parseArray, CONSTANTS, - isLocaleAvailable, } = require("../src/common/utils"); +const { isLocaleAvailable } = require("../src/translations"); const { fetchWakatimeStats } = require("../src/fetchers/wakatime-fetcher"); const wakatimeCard = require("../src/cards/wakatime-card"); From 02ebd3243b4dc1aba224c7c75c23ebd3e4867ed2 Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Sun, 10 Oct 2021 20:41:40 +0530 Subject: [PATCH 28/53] refactor: jsdoc in utils & minor changes (#1377) * refactor: jsdoc in utils & minor changes * chore: jsdoc Card class * chore: jsdoc for getStyles --- api/index.js | 4 +- api/pin.js | 4 +- api/top-langs.js | 4 +- src/cards/repo-card.js | 35 +++++++---------- src/common/Card.js | 25 ++++++++++++ src/common/utils.js | 88 ++++++++++++++++++++++++++++++++++++++---- src/getStyles.js | 24 ++++++++++-- 7 files changed, 143 insertions(+), 41 deletions(-) diff --git a/api/index.js b/api/index.js index 0cda587ea02fe..c983b436bffb6 100644 --- a/api/index.js +++ b/api/index.js @@ -34,8 +34,6 @@ module.exports = async (req, res) => { border_radius, border_color, } = req.query; - let stats; - res.setHeader("Content-Type", "image/svg+xml"); if (blacklist.includes(username)) { @@ -47,7 +45,7 @@ module.exports = async (req, res) => { } try { - stats = await fetchStats( + const stats = await fetchStats( username, parseBoolean(count_private), parseBoolean(include_all_commits), diff --git a/api/pin.js b/api/pin.js index 65d09f0ec36e8..1df7fd0780f8b 100644 --- a/api/pin.js +++ b/api/pin.js @@ -27,8 +27,6 @@ module.exports = async (req, res) => { border_color, } = req.query; - let repoData; - res.setHeader("Content-Type", "image/svg+xml"); if (blacklist.includes(username)) { @@ -40,7 +38,7 @@ module.exports = async (req, res) => { } try { - repoData = await fetchRepo(username, repo); + const repoData = await fetchRepo(username, repo); let cacheSeconds = clampValue( parseInt(cache_seconds || CONSTANTS.TWO_HOURS, 10), diff --git a/api/top-langs.js b/api/top-langs.js index 89306fa257f5e..52ac593af9de2 100644 --- a/api/top-langs.js +++ b/api/top-langs.js @@ -31,8 +31,6 @@ module.exports = async (req, res) => { border_radius, border_color, } = req.query; - let topLangs; - res.setHeader("Content-Type", "image/svg+xml"); if (blacklist.includes(username)) { @@ -44,7 +42,7 @@ module.exports = async (req, res) => { } try { - topLangs = await fetchTopLanguages( + const topLangs = await fetchTopLanguages( username, parseArray(exclude_repo), parseArray(hide), diff --git a/src/cards/repo-card.js b/src/cards/repo-card.js index 4573fcf6a2a94..5e6a28dd6d998 100644 --- a/src/cards/repo-card.js +++ b/src/cards/repo-card.js @@ -110,15 +110,14 @@ const renderRepoCard = (repo, options = {}) => { }); // 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 colors = getCardColors({ + title_color, + icon_color, + text_color, + bg_color, + border_color, + theme, + }); const svgLanguage = primaryLanguage ? createLanguageNode(langName, langColor) @@ -145,22 +144,16 @@ const renderRepoCard = (repo, options = {}) => { width: 400, height, border_radius, - colors: { - titleColor, - textColor, - iconColor, - bgColor, - borderColor, - }, + colors, }); card.disableAnimations(); card.setHideBorder(hide_border); card.setHideTitle(false); card.setCSS(` - .description { font: 400 13px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} } - .gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} } - .icon { fill: ${iconColor} } + .description { font: 400 13px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${colors.textColor} } + .gray { font: 400 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${colors.textColor} } + .icon { fill: ${colors.iconColor} } .badge { font: 600 11px 'Segoe UI', Ubuntu, Sans-Serif; } .badge rect { opacity: 0.2 } `); @@ -168,9 +161,9 @@ const renderRepoCard = (repo, options = {}) => { return card.render(` ${ isTemplate - ? getBadgeSVG(i18n.t("repocard.template"), textColor) + ? getBadgeSVG(i18n.t("repocard.template"), colors.textColor) : isArchived - ? getBadgeSVG(i18n.t("repocard.archived"), textColor) + ? getBadgeSVG(i18n.t("repocard.archived"), colors.textColor) : "" } diff --git a/src/common/Card.js b/src/common/Card.js index 520560f94d24d..fd1fa77d09c61 100644 --- a/src/common/Card.js +++ b/src/common/Card.js @@ -2,6 +2,16 @@ const { getAnimations } = require("../getStyles"); const { flexLayout, encodeHTML } = require("../common/utils"); class Card { + /** + * @param {object} args + * @param {number?=} args.width + * @param {number?=} args.height + * @param {number?=} args.border_radius + * @param {string?=} args.customTitle + * @param {string?=} args.defaultTitle + * @param {string?=} args.titlePrefixIcon + * @param {ReturnType?=} args.colors + */ constructor({ width = 100, height = 100, @@ -38,14 +48,23 @@ class Card { this.animations = false; } + /** + * @param {string} value + */ setCSS(value) { this.css = value; } + /** + * @param {boolean} value + */ setHideBorder(value) { this.hideBorder = value; } + /** + * @param {boolean} value + */ setHideTitle(value) { this.hideTitle = value; if (value) { @@ -53,6 +72,9 @@ class Card { } } + /** + * @param {string} text + */ setTitle(text) { this.title = text; } @@ -114,6 +136,9 @@ class Card { : ""; } + /** + * @param {string} body + */ render(body) { return ` { return ` @@ -21,7 +27,11 @@ const renderError = (message, secondaryMessage = "") => { `; }; -// https://stackoverflow.com/a/48073476/10629172 +/** + * @see https://stackoverflow.com/a/48073476/10629172 + * @param {string} str + * @returns {string} + */ function encodeHTML(str) { return str .replace(/[\u00A0-\u9999<>&](?!#)/gim, (i) => { @@ -30,18 +40,29 @@ function encodeHTML(str) { .replace(/\u0008/gim, ""); } +/** + * @param {number} num + */ function kFormatter(num) { return Math.abs(num) > 999 - ? Math.sign(num) * (Math.abs(num) / 1000).toFixed(1) + "k" + ? Math.sign(num) * parseFloat((Math.abs(num) / 1000).toFixed(1)) + "k" : Math.sign(num) * Math.abs(num); } +/** + * @param {string} hexColor + * @returns {boolean} + */ function isValidHexColor(hexColor) { return new RegExp( /^([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{4})$/, ).test(hexColor); } +/** + * @param {string} value + * @returns {boolean | string} + */ function parseBoolean(value) { if (value === "true") { return true; @@ -52,19 +73,37 @@ function parseBoolean(value) { } } +/** + * @param {string} str + */ function parseArray(str) { if (!str) return []; return str.split(","); } +/** + * @param {number} number + * @param {number} min + * @param {number} max + */ function clampValue(number, min, max) { + // @ts-ignore + if (Number.isNaN(parseInt(number))) return min; return Math.max(min, Math.min(number, max)); } +/** + * @param {string[]} colors + */ function isValidGradient(colors) { return isValidHexColor(colors[1]) && isValidHexColor(colors[2]); } +/** + * @param {string} color + * @param {string} fallbackColor + * @returns {string | string[]} + */ function fallbackColor(color, fallbackColor) { let colors = color.split(","); let gradient = null; @@ -79,7 +118,12 @@ function fallbackColor(color, fallbackColor) { ); } +/** + * @param {import('axios').AxiosRequestConfig['data']} data + * @param {import('axios').AxiosRequestConfig['headers']} headers + */ function request(data, headers) { + // @ts-ignore return axios({ url: "https://api.github.com/graphql", method: "post", @@ -92,8 +136,8 @@ function request(data, headers) { * @param {object} props * @param {string[]} props.items * @param {number} props.gap - * @param {number[]} props.sizes - * @param {"column" | "row"} props.direction + * @param {number[]?=} props.sizes + * @param {"column" | "row"?=} props.direction * * @returns {string[]} * @@ -115,14 +159,27 @@ function flexLayout({ items, gap, direction, sizes = [] }) { }); } -// returns theme based colors with proper overrides and defaults +/** + * @typedef {object} CardColors + * @prop {string} title_color + * @prop {string} text_color + * @prop {string} icon_color + * @prop {string} bg_color + * @prop {string} border_color + * @prop {keyof typeof import('../../themes')?=} fallbackTheme + * @prop {keyof typeof import('../../themes')?=} theme + */ +/** + * returns theme based colors with proper overrides and defaults + * @param {CardColors} options + */ function getCardColors({ title_color, text_color, icon_color, bg_color, - theme, border_color, + theme, fallbackTheme = "default", }) { const defaultTheme = themes[fallbackTheme]; @@ -157,6 +214,12 @@ function getCardColors({ return { titleColor, iconColor, textColor, bgColor, borderColor }; } +/** + * @param {string} text + * @param {number} width + * @param {number} maxLines + * @returns {string[]} + */ function wrapTextMultiline(text, width = 60, maxLines = 3) { const wrapped = wrap(encodeHTML(text), { width }) .split("\n") // Split wrapped lines to get an array of lines @@ -193,6 +256,10 @@ const SECONDARY_ERROR_MESSAGES = { }; class CustomError extends Error { + /** + * @param {string} message + * @param {string} type + */ constructor(message, type) { super(message); this.type = type; @@ -203,7 +270,12 @@ class CustomError extends Error { static USER_NOT_FOUND = "USER_NOT_FOUND"; } -// https://stackoverflow.com/a/48172630/10629172 +/** + * @see https://stackoverflow.com/a/48172630/10629172 + * @param {string} str + * @param {number} fontSize + * @returns + */ function measureText(str, fontSize = 10) { // prettier-ignore const widths = [ @@ -237,6 +309,8 @@ function measureText(str, fontSize = 10) { .reduce((cur, acc) => acc + cur) * fontSize ); } + +/** @param {string} name */ const lowercaseTrim = (name) => name.toLowerCase().trim(); /** diff --git a/src/getStyles.js b/src/getStyles.js index b15f46d09be08..fd70c249865b9 100644 --- a/src/getStyles.js +++ b/src/getStyles.js @@ -1,14 +1,21 @@ +/** + * @param {number} value + */ const calculateCircleProgress = (value) => { - let radius = 40; - let c = Math.PI * (radius * 2); + const radius = 40; + const c = Math.PI * (radius * 2); if (value < 0) value = 0; if (value > 100) value = 100; - let percentage = ((100 - value) / 100) * c; - return percentage; + return ((100 - value) / 100) * c; }; +/** + * + * @param {{progress: number}} param0 + * @returns + */ const getProgressAnimation = ({ progress }) => { return ` @keyframes rankAnimation { @@ -44,6 +51,15 @@ const getAnimations = () => { `; }; +/** + * @param {{ + * titleColor: string; + * textColor: string; + * iconColor: string; + * show_icons: boolean; + * progress: number; + * }} args + */ const getStyles = ({ titleColor, textColor, From 2723f00cb8bf069d3b9b4c8482df042482e9c8de Mon Sep 17 00:00:00 2001 From: Oscar Dominguez Date: Wed, 13 Oct 2021 17:01:39 +0200 Subject: [PATCH 29/53] ci(workflow): add 'npm' cache for actions/setup-node in .github/workflows (#1382) --- .github/workflows/generate-theme-doc.yml | 3 ++- .github/workflows/test.yml | 14 ++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/.github/workflows/generate-theme-doc.yml b/.github/workflows/generate-theme-doc.yml index 9028044d97e27..2ff488a1dbf65 100644 --- a/.github/workflows/generate-theme-doc.yml +++ b/.github/workflows/generate-theme-doc.yml @@ -14,9 +14,10 @@ jobs: steps: - uses: actions/checkout@v1 - name: setup node - uses: actions/setup-node@v1 + uses: actions/setup-node@v2 with: node-version: "12.x" + cache: npm - name: npm install, generate readme run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0eb02215f0312..95eacb1ba5393 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,20 +16,10 @@ jobs: - uses: actions/checkout@v2 - name: Setup Node - uses: actions/setup-node@v1 + uses: actions/setup-node@v2 with: node-version: "12.x" - - - name: Cache node modules - uses: actions/cache@v2 - env: - cache-name: cache-node-modules - with: - path: ~/.npm - key: - ${{ runner.os }}-npm-cache-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-npm-cache- + cache: npm - name: Install & Test run: | From 596a4eccc12adeadb85815ce6a314785e3153741 Mon Sep 17 00:00:00 2001 From: Anurag Date: Wed, 13 Oct 2021 20:39:13 +0530 Subject: [PATCH 30/53] Revert "ci(workflow): add 'npm' cache for actions/setup-node in .github/workflows (#1382)" This reverts commit 2723f00cb8bf069d3b9b4c8482df042482e9c8de. --- .github/workflows/generate-theme-doc.yml | 3 +-- .github/workflows/test.yml | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/generate-theme-doc.yml b/.github/workflows/generate-theme-doc.yml index 2ff488a1dbf65..9028044d97e27 100644 --- a/.github/workflows/generate-theme-doc.yml +++ b/.github/workflows/generate-theme-doc.yml @@ -14,10 +14,9 @@ jobs: steps: - uses: actions/checkout@v1 - name: setup node - uses: actions/setup-node@v2 + uses: actions/setup-node@v1 with: node-version: "12.x" - cache: npm - name: npm install, generate readme run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 95eacb1ba5393..0eb02215f0312 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,10 +16,20 @@ jobs: - uses: actions/checkout@v2 - name: Setup Node - uses: actions/setup-node@v2 + uses: actions/setup-node@v1 with: node-version: "12.x" - cache: npm + + - name: Cache node modules + uses: actions/cache@v2 + env: + cache-name: cache-node-modules + with: + path: ~/.npm + key: + ${{ runner.os }}-npm-cache-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-npm-cache- - name: Install & Test run: | From 300ee853e7ba93ed5b481b9b762140596c7b68ef Mon Sep 17 00:00:00 2001 From: Anurag Date: Wed, 13 Oct 2021 20:52:35 +0530 Subject: [PATCH 31/53] chore: remove action cache --- .github/workflows/test.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0eb02215f0312..89df34e6006e6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,17 +20,6 @@ jobs: with: node-version: "12.x" - - name: Cache node modules - uses: actions/cache@v2 - env: - cache-name: cache-node-modules - with: - path: ~/.npm - key: - ${{ runner.os }}-npm-cache-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-npm-cache- - - name: Install & Test run: | npm install From 7072a238084612b4a418f2f89ce8fe16f59ab481 Mon Sep 17 00:00:00 2001 From: Michael Schnerring <3743342+schnerring@users.noreply.github.com> Date: Wed, 13 Oct 2021 17:50:22 +0200 Subject: [PATCH 32/53] style(theme): add gruvbox_light theme (#1379) --- themes/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/themes/index.js b/themes/index.js index 3c212ab152289..c30646cf7e3d9 100644 --- a/themes/index.js +++ b/themes/index.js @@ -36,6 +36,12 @@ const themes = { text_color: "8ec07c", bg_color: "282828", }, + gruvbox_light: { + title_color: "b57614", + icon_color: "af3a03", + text_color: "427b58", + bg_color: "fbf1c7", + }, tokyonight: { title_color: "70a5fd", icon_color: "bf91f3", From ded7e8aff8716b3684df7c2fe147d746ba77647d Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Wed, 13 Oct 2021 21:30:13 +0530 Subject: [PATCH 33/53] docs(theme): Auto update theme readme (#1384) Co-authored-by: Github Readme Stats Bot --- themes/README.md | 80 ++++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/themes/README.md b/themes/README.md index 54acc51e38ea0..fc5970081c1b8 100644 --- a/themes/README.md +++ b/themes/README.md @@ -2,7 +2,7 @@ -With inbuilt themes you can customize the look of the card without doing any manual customization. +With inbuilt themes, you can customize the look of the card without doing any manual customization. Use `?theme=THEME_NAME` parameter like so :- @@ -17,22 +17,23 @@ Use `?theme=THEME_NAME` parameter like so :- | | | | | :--: | :--: | :--: | | `default` ![default][default] | `dark` ![dark][dark] | `radical` ![radical][radical] | -| `merko` ![merko][merko] | `gruvbox` ![gruvbox][gruvbox] | `tokyonight` ![tokyonight][tokyonight] | -| `onedark` ![onedark][onedark] | `cobalt` ![cobalt][cobalt] | `synthwave` ![synthwave][synthwave] | -| `highcontrast` ![highcontrast][highcontrast] | `dracula` ![dracula][dracula] | `prussian` ![prussian][prussian] | -| `monokai` ![monokai][monokai] | `vue` ![vue][vue] | `vue-dark` ![vue-dark][vue-dark] | -| `shades-of-purple` ![shades-of-purple][shades-of-purple] | `nightowl` ![nightowl][nightowl] | `buefy` ![buefy][buefy] | -| `blue-green` ![blue-green][blue-green] | `algolia` ![algolia][algolia] | `great-gatsby` ![great-gatsby][great-gatsby] | -| `darcula` ![darcula][darcula] | `bear` ![bear][bear] | `solarized-dark` ![solarized-dark][solarized-dark] | -| `solarized-light` ![solarized-light][solarized-light] | `chartreuse-dark` ![chartreuse-dark][chartreuse-dark] | `nord` ![nord][nord] | -| `gotham` ![gotham][gotham] | `material-palenight` ![material-palenight][material-palenight] | `graywhite` ![graywhite][graywhite] | -| `vision-friendly-dark` ![vision-friendly-dark][vision-friendly-dark] | `ayu-mirage` ![ayu-mirage][ayu-mirage] | `midnight-purple` ![midnight-purple][midnight-purple] | -| `calm` ![calm][calm] | `flag-india` ![flag-india][flag-india] | `omni` ![omni][omni] | -| `react` ![react][react] | `jolly` ![jolly][jolly] | `maroongold` ![maroongold][maroongold] | -| `yeblu` ![yeblu][yeblu] | `blueberry` ![blueberry][blueberry] | `slateorange` ![slateorange][slateorange] | -| `kacho_ga` ![kacho_ga][kacho_ga] | `outrun` ![outrun][outrun] | `ocean_dark` ![ocean_dark][ocean_dark] | -| `city_lights` ![city_lights][city_lights] | `github_dark` ![github_dark][github_dark] | `discord_old_blurple` ![discord_old_blurple][discord_old_blurple] | -| [Add your theme][add-theme] | | | +| `merko` ![merko][merko] | `gruvbox` ![gruvbox][gruvbox] | `gruvbox_light` ![gruvbox_light][gruvbox_light] | +| `tokyonight` ![tokyonight][tokyonight] | `onedark` ![onedark][onedark] | `cobalt` ![cobalt][cobalt] | +| `synthwave` ![synthwave][synthwave] | `highcontrast` ![highcontrast][highcontrast] | `dracula` ![dracula][dracula] | +| `prussian` ![prussian][prussian] | `monokai` ![monokai][monokai] | `vue` ![vue][vue] | +| `vue-dark` ![vue-dark][vue-dark] | `shades-of-purple` ![shades-of-purple][shades-of-purple] | `nightowl` ![nightowl][nightowl] | +| `buefy` ![buefy][buefy] | `blue-green` ![blue-green][blue-green] | `algolia` ![algolia][algolia] | +| `great-gatsby` ![great-gatsby][great-gatsby] | `darcula` ![darcula][darcula] | `bear` ![bear][bear] | +| `solarized-dark` ![solarized-dark][solarized-dark] | `solarized-light` ![solarized-light][solarized-light] | `chartreuse-dark` ![chartreuse-dark][chartreuse-dark] | +| `nord` ![nord][nord] | `gotham` ![gotham][gotham] | `material-palenight` ![material-palenight][material-palenight] | +| `graywhite` ![graywhite][graywhite] | `vision-friendly-dark` ![vision-friendly-dark][vision-friendly-dark] | `ayu-mirage` ![ayu-mirage][ayu-mirage] | +| `midnight-purple` ![midnight-purple][midnight-purple] | `calm` ![calm][calm] | `flag-india` ![flag-india][flag-india] | +| `omni` ![omni][omni] | `react` ![react][react] | `jolly` ![jolly][jolly] | +| `maroongold` ![maroongold][maroongold] | `yeblu` ![yeblu][yeblu] | `blueberry` ![blueberry][blueberry] | +| `slateorange` ![slateorange][slateorange] | `kacho_ga` ![kacho_ga][kacho_ga] | `outrun` ![outrun][outrun] | +| `ocean_dark` ![ocean_dark][ocean_dark] | `city_lights` ![city_lights][city_lights] | `github_dark` ![github_dark][github_dark] | +| `discord_old_blurple` ![discord_old_blurple][discord_old_blurple] | `aura_dark` ![aura_dark][aura_dark] | `panda` ![panda][panda] | +| `noctis_minimus` ![noctis_minimus][noctis_minimus] | `cobalt2` ![cobalt2][cobalt2] | [Add your theme][add-theme] | ## Repo Card @@ -41,22 +42,23 @@ Use `?theme=THEME_NAME` parameter like so :- | | | | | :--: | :--: | :--: | | `default_repocard` ![default_repocard][default_repocard_repo] | `dark` ![dark][dark_repo] | `radical` ![radical][radical_repo] | -| `merko` ![merko][merko_repo] | `gruvbox` ![gruvbox][gruvbox_repo] | `tokyonight` ![tokyonight][tokyonight_repo] | -| `onedark` ![onedark][onedark_repo] | `cobalt` ![cobalt][cobalt_repo] | `synthwave` ![synthwave][synthwave_repo] | -| `highcontrast` ![highcontrast][highcontrast_repo] | `dracula` ![dracula][dracula_repo] | `prussian` ![prussian][prussian_repo] | -| `monokai` ![monokai][monokai_repo] | `vue` ![vue][vue_repo] | `vue-dark` ![vue-dark][vue-dark_repo] | -| `shades-of-purple` ![shades-of-purple][shades-of-purple_repo] | `nightowl` ![nightowl][nightowl_repo] | `buefy` ![buefy][buefy_repo] | -| `blue-green` ![blue-green][blue-green_repo] | `algolia` ![algolia][algolia_repo] | `great-gatsby` ![great-gatsby][great-gatsby_repo] | -| `darcula` ![darcula][darcula_repo] | `bear` ![bear][bear_repo] | `solarized-dark` ![solarized-dark][solarized-dark_repo] | -| `solarized-light` ![solarized-light][solarized-light_repo] | `chartreuse-dark` ![chartreuse-dark][chartreuse-dark_repo] | `nord` ![nord][nord_repo] | -| `gotham` ![gotham][gotham_repo] | `material-palenight` ![material-palenight][material-palenight_repo] | `graywhite` ![graywhite][graywhite_repo] | -| `vision-friendly-dark` ![vision-friendly-dark][vision-friendly-dark_repo] | `ayu-mirage` ![ayu-mirage][ayu-mirage_repo] | `midnight-purple` ![midnight-purple][midnight-purple_repo] | -| `calm` ![calm][calm_repo] | `flag-india` ![flag-india][flag-india_repo] | `omni` ![omni][omni_repo] | -| `react` ![react][react_repo] | `jolly` ![jolly][jolly_repo] | `maroongold` ![maroongold][maroongold_repo] | -| `yeblu` ![yeblu][yeblu_repo] | `blueberry` ![blueberry][blueberry_repo] | `slateorange` ![slateorange][slateorange_repo] | -| `kacho_ga` ![kacho_ga][kacho_ga_repo] | `outrun` ![outrun][outrun_repo] | `ocean_dark` ![ocean_dark][ocean_dark_repo] | -| `city_lights` ![city_lights][city_lights_repo] | `github_dark` ![github_dark][github_dark_repo] | `discord_old_blurple` ![discord_old_blurple][discord_old_blurple_repo] | -| [Add your theme][add-theme] | | | +| `merko` ![merko][merko_repo] | `gruvbox` ![gruvbox][gruvbox_repo] | `gruvbox_light` ![gruvbox_light][gruvbox_light_repo] | +| `tokyonight` ![tokyonight][tokyonight_repo] | `onedark` ![onedark][onedark_repo] | `cobalt` ![cobalt][cobalt_repo] | +| `synthwave` ![synthwave][synthwave_repo] | `highcontrast` ![highcontrast][highcontrast_repo] | `dracula` ![dracula][dracula_repo] | +| `prussian` ![prussian][prussian_repo] | `monokai` ![monokai][monokai_repo] | `vue` ![vue][vue_repo] | +| `vue-dark` ![vue-dark][vue-dark_repo] | `shades-of-purple` ![shades-of-purple][shades-of-purple_repo] | `nightowl` ![nightowl][nightowl_repo] | +| `buefy` ![buefy][buefy_repo] | `blue-green` ![blue-green][blue-green_repo] | `algolia` ![algolia][algolia_repo] | +| `great-gatsby` ![great-gatsby][great-gatsby_repo] | `darcula` ![darcula][darcula_repo] | `bear` ![bear][bear_repo] | +| `solarized-dark` ![solarized-dark][solarized-dark_repo] | `solarized-light` ![solarized-light][solarized-light_repo] | `chartreuse-dark` ![chartreuse-dark][chartreuse-dark_repo] | +| `nord` ![nord][nord_repo] | `gotham` ![gotham][gotham_repo] | `material-palenight` ![material-palenight][material-palenight_repo] | +| `graywhite` ![graywhite][graywhite_repo] | `vision-friendly-dark` ![vision-friendly-dark][vision-friendly-dark_repo] | `ayu-mirage` ![ayu-mirage][ayu-mirage_repo] | +| `midnight-purple` ![midnight-purple][midnight-purple_repo] | `calm` ![calm][calm_repo] | `flag-india` ![flag-india][flag-india_repo] | +| `omni` ![omni][omni_repo] | `react` ![react][react_repo] | `jolly` ![jolly][jolly_repo] | +| `maroongold` ![maroongold][maroongold_repo] | `yeblu` ![yeblu][yeblu_repo] | `blueberry` ![blueberry][blueberry_repo] | +| `slateorange` ![slateorange][slateorange_repo] | `kacho_ga` ![kacho_ga][kacho_ga_repo] | `outrun` ![outrun][outrun_repo] | +| `ocean_dark` ![ocean_dark][ocean_dark_repo] | `city_lights` ![city_lights][city_lights_repo] | `github_dark` ![github_dark][github_dark_repo] | +| `discord_old_blurple` ![discord_old_blurple][discord_old_blurple_repo] | `aura_dark` ![aura_dark][aura_dark_repo] | `panda` ![panda][panda_repo] | +| `noctis_minimus` ![noctis_minimus][noctis_minimus_repo] | `cobalt2` ![cobalt2][cobalt2_repo] | [Add your theme][add-theme] | [default]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=default @@ -65,6 +67,7 @@ Use `?theme=THEME_NAME` parameter like so :- [radical]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=radical [merko]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=merko [gruvbox]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=gruvbox +[gruvbox_light]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=gruvbox_light [tokyonight]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=tokyonight [onedark]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=onedark [cobalt]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=cobalt @@ -108,6 +111,10 @@ Use `?theme=THEME_NAME` parameter like so :- [city_lights]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=city_lights [github_dark]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=github_dark [discord_old_blurple]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=discord_old_blurple +[aura_dark]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=aura_dark +[panda]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=panda +[noctis_minimus]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=noctis_minimus +[cobalt2]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=cobalt2 [default_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=default @@ -116,6 +123,7 @@ Use `?theme=THEME_NAME` parameter like so :- [radical_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=radical [merko_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=merko [gruvbox_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=gruvbox +[gruvbox_light_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=gruvbox_light [tokyonight_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=tokyonight [onedark_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=onedark [cobalt_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=cobalt @@ -159,8 +167,12 @@ Use `?theme=THEME_NAME` parameter like so :- [city_lights_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=city_lights [github_dark_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=github_dark [discord_old_blurple_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=discord_old_blurple +[aura_dark_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=aura_dark +[panda_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=panda +[noctis_minimus_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=noctis_minimus +[cobalt2_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=cobalt2 [add-theme]: https://github.com/anuraghazra/github-readme-stats/edit/master/themes/index.js -Wanted to add a new theme? Consider reading the [contribution guidelines](../CONTRIBUTING.md#themes-contribution) :D +Want to add a new theme? Consider reading the [contribution guidelines](../CONTRIBUTING.md#themes-contribution) :D From 02e714aeb441de64ab4df271491db145d69c4d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Tyrkk=C3=B6?= Date: Mon, 18 Oct 2021 16:41:50 +0300 Subject: [PATCH 34/53] fix: word-wrap bug (#1378) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixed word-wrap bug * ci(workflow): add 'npm' cache for actions/setup-node in .github/workflows (#1382) * Revert "ci(workflow): add 'npm' cache for actions/setup-node in .github/workflows (#1382)" This reverts commit 2723f00cb8bf069d3b9b4c8482df042482e9c8de. * chore: remove action cache * chore: minor change Co-authored-by: Markus Tyrkkö Co-authored-by: Oscar Dominguez Co-authored-by: Anurag --- src/cards/repo-card.js | 2 +- src/common/utils.js | 20 +++++++++++++++----- tests/renderRepoCard.test.js | 11 +++++++++++ tests/utils.test.js | 7 +++++++ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/cards/repo-card.js b/src/cards/repo-card.js index 5e6a28dd6d998..5295b174735a5 100644 --- a/src/cards/repo-card.js +++ b/src/cards/repo-card.js @@ -139,7 +139,7 @@ const renderRepoCard = (repo, options = {}) => { }).join(""); const card = new Card({ - defaultTitle: header, + defaultTitle: header.length > 35 ? `${header.slice(0, 35)}...` : header, titlePrefixIcon: icons.contribs, width: 400, height, diff --git a/src/common/utils.js b/src/common/utils.js index 79d6af0f90628..92018a63176c1 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -220,12 +220,22 @@ function getCardColors({ * @param {number} maxLines * @returns {string[]} */ -function wrapTextMultiline(text, width = 60, maxLines = 3) { - const wrapped = wrap(encodeHTML(text), { width }) - .split("\n") // Split wrapped lines to get an array of lines - .map((line) => line.trim()); // Remove leading and trailing whitespace of each line +function wrapTextMultiline(text, width = 59, maxLines = 3) { + const fullWidthComma = ","; + const encoded = encodeHTML(text); + const isChinese = encoded.includes(fullWidthComma); - const lines = wrapped.slice(0, maxLines); // Only consider maxLines lines + let wrapped = []; + + if (isChinese) { + wrapped = encoded.split(fullWidthComma); // Chinese full punctuation + } else { + wrapped = wrap(encoded, { + width, + }).split("\n"); // Split wrapped lines to get an array of lines + } + + const lines = wrapped.map((line) => line.trim()).slice(0, maxLines); // Only consider maxLines lines // Add "..." to the last line if the text exceeds maxLines if (wrapped.length > maxLines) { diff --git a/tests/renderRepoCard.test.js b/tests/renderRepoCard.test.js index 4b7060a1f88f1..8f1d6ef44a3b4 100644 --- a/tests/renderRepoCard.test.js +++ b/tests/renderRepoCard.test.js @@ -51,6 +51,17 @@ describe("Test renderRepoCard", () => { ); }); + it("should trim header", () => { + document.body.innerHTML = renderRepoCard({ + ...data_repo.repository, + name: "some-really-long-repo-name-for-test-purposes", + }); + + expect(document.getElementsByClassName("header")[0].textContent).toBe( + "some-really-long-repo-name-for-test...", + ); + }); + it("should trim description", () => { document.body.innerHTML = renderRepoCard({ ...data_repo.repository, diff --git a/tests/utils.test.js b/tests/utils.test.js index 15c4d97481590..4fdd6a8e8b12b 100644 --- a/tests/utils.test.js +++ b/tests/utils.test.js @@ -117,4 +117,11 @@ describe("wrapTextMultiline", () => { ); expect(multiLineText).toEqual(["Hello", "world long..."]); }); + it("should wrap chinese by punctuation", () => { + let multiLineText = wrapTextMultiline( + "专门为刚开始刷题的同学准备的算法基地,没有最细只有更细,立志用动画将晦涩难懂的算法说的通俗易懂!", + ); + expect(multiLineText.length).toEqual(3); + expect(multiLineText[0].length).toEqual(18 * 8); // &#xxxxx; x 8 + }); }); From d049f0688d851c7da3d97d98af72c45b7c283337 Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Sat, 23 Oct 2021 13:50:33 +0530 Subject: [PATCH 35/53] fix: hotfix for graphql api error (#1409) --- src/fetchers/stats-fetcher.js | 7 +++++-- tests/api.test.js | 3 ++- tests/fetchStats.test.js | 3 ++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index ce5a4af7fad8a..b0636d1b29ce2 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -25,7 +25,10 @@ const fetcher = (variables, token) => { pullRequests(first: 1) { totalCount } - issues(first: 1) { + openIssues: issues(states: OPEN) { + totalCount + } + closedIssues: issues(states: CLOSED) { totalCount } followers { @@ -114,7 +117,7 @@ async function fetchStats( const user = res.data.data.user; stats.name = user.name || user.login; - stats.totalIssues = user.issues.totalCount; + stats.totalIssues = user.openIssues.totalCount + user.closedIssues.totalCount; // normal commits stats.totalCommits = user.contributionsCollection.totalCommitContributions; diff --git a/tests/api.test.js b/tests/api.test.js index a468d5f57c9cd..ffdf5e1948597 100644 --- a/tests/api.test.js +++ b/tests/api.test.js @@ -35,7 +35,8 @@ const data = { restrictedContributionsCount: 100, }, pullRequests: { totalCount: stats.totalPRs }, - issues: { totalCount: stats.totalIssues }, + openIssues: { totalCount: stats.totalIssues }, + closedIssues: { totalCount: 0 }, followers: { totalCount: 0 }, repositories: { totalCount: 1, diff --git a/tests/fetchStats.test.js b/tests/fetchStats.test.js index e627e498a3535..f732182f8fe5a 100644 --- a/tests/fetchStats.test.js +++ b/tests/fetchStats.test.js @@ -14,7 +14,8 @@ const data = { restrictedContributionsCount: 50, }, pullRequests: { totalCount: 300 }, - issues: { totalCount: 200 }, + openIssues: { totalCount: 100 }, + closedIssues: { totalCount: 100 }, followers: { totalCount: 100 }, repositories: { totalCount: 5, From bc6c22ea1727987542eef29f57b890f3a678a769 Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Mon, 25 Oct 2021 23:29:04 +0530 Subject: [PATCH 36/53] docs: add fork instructions (#1418) * docs: add fork instructions * chore: revert toc --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index b06fd64c17e24..a6dab596f87b9 100644 --- a/readme.md +++ b/readme.md @@ -411,6 +411,7 @@ NOTE: Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) we ![](https://files.catbox.moe/btd78j.jpeg) 1. Sign into GitHub and allow access to all repositories, if prompted 1. Fork this repo +1. After forking the repo, open the [`vercel.json`](https://github.com/anuraghazra/github-readme-stats/blob/master/vercel.json#L5) file and change the `maxDuration` field to `10` 1. Go back to your [Vercel dashboard](https://vercel.com/dashboard) 1. Select `Import Project` ![](https://files.catbox.moe/qckos0.png) From f6426274927906414f8a0d3266ee9115cf388e20 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Thu, 4 Nov 2021 17:56:59 +0100 Subject: [PATCH 37/53] fix: add icon width to stats-card min width calculation --- src/cards/stats-card.js | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index 32f71134f1986..fafbd39058769 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -35,10 +35,10 @@ const createTextNode = ({ ${iconSvg} ${label}: - ${kValue} @@ -76,7 +76,6 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { disable_animations = false, } = options; - const lheight = parseInt(line_height, 10); // returns theme based colors with proper overrides and defaults @@ -186,20 +185,18 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { }; /* - When hide_rank=true, minimum card width is max of 270 and length of title + paddings. - When hide_rank=false, minimum card_width is 340. + When hide_rank=true, the minimum card width is 270 px + the title length and padding. + When hide_rank=false, the minimum card_width is 340 px + the icon width (if show_icons=true). Numbers are picked by looking at existing dimensions on production. */ + const iconWidth = show_icons ? 16 : 0; const minCardWidth = hide_rank - ? clampValue( - 50 /* padding */ + calculateTextWidth() * 2, - 270, - Infinity) - : 340 - const defaultCardWidth = hide_rank ? 270 : 495 - let width = isNaN(card_width) ? defaultCardWidth : card_width + ? clampValue(50 /* padding */ + calculateTextWidth() * 2, 270, Infinity) + : 340 + iconWidth; + const defaultCardWidth = hide_rank ? 270 : 495; + let width = isNaN(card_width) ? defaultCardWidth : card_width; if (width < minCardWidth) { - width = minCardWidth + width = minCardWidth; } const card = new Card({ @@ -226,7 +223,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { // Conditionally rendered elements const rankCircle = hide_rank ? "" - : ` @@ -252,7 +249,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { gap: lheight, direction: "column", }).join("")} - + `); }; From 34d642356f14a267ca8cc0d03effcb602fe4c34f Mon Sep 17 00:00:00 2001 From: rickstaa Date: Thu, 4 Nov 2021 18:00:07 +0100 Subject: [PATCH 38/53] fix: fixes rank circle padding problem This commit fixes a padding problem that was introduced in f9c0e0bff64f325235ccbf936c9d5f7a918ac790. In the new code, the padding around the rank circle will be 50 when the stats card is bigger than 450. When it is smaller than 450 the left and right padding will shrink equally. --- src/cards/stats-card.js | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index fafbd39058769..9388d3a6492f6 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -220,11 +220,30 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { if (disable_animations) card.disableAnimations(); + /** + * Calculates the right rank circle translation values such that the rank circle + * keeps respecting the padding. + * + * width > 450: The default left padding of 50 px will be used. + * width < 450: The left and right padding will shrink equally. + * + * @returns {number} - Rank circle translation value. + */ + const calculateRankXTranslation = () => { + if (width < 450) { + return width - 95 + (45 * (450 - 340)) / 110; + } else { + return width - 95; + } + }; + // Conditionally rendered elements const rankCircle = hide_rank ? "" : ` + transform="translate(${calculateRankXTranslation()}, ${ + height / 2 - 50 + })"> From 28fa0b8877ab0dd7a220440d2a2508245f403959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Tyrkk=C3=B6?= Date: Fri, 5 Nov 2021 16:19:51 +0200 Subject: [PATCH 39/53] fix: bug where wakatime api returns undefined languages (#1403) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Markus Tyrkkö --- src/cards/wakatime-card.js | 4 ++-- tests/renderWakatimeCard.test.js | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cards/wakatime-card.js b/src/cards/wakatime-card.js index 54093ec0302e3..905e40a08fefc 100644 --- a/src/cards/wakatime-card.js +++ b/src/cards/wakatime-card.js @@ -123,7 +123,7 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => { } = options; const shouldHideLangs = Array.isArray(hide) && hide.length > 0; - if (shouldHideLangs) { + if (shouldHideLangs && languages !== undefined) { const languagesToHide = new Set(hide.map((lang) => lowercaseTrim(lang))); languages = languages.filter( (lang) => !languagesToHide.has(lowercaseTrim(lang.name)), @@ -138,7 +138,7 @@ const renderWakatimeCard = (stats = {}, options = { hide: [] }) => { const lheight = parseInt(line_height, 10); - langsCount = clampValue(parseInt(langs_count), 1, langs_count); + const langsCount = clampValue(parseInt(langs_count), 1, langs_count); // returns theme based colors with proper overrides and defaults const { diff --git a/tests/renderWakatimeCard.test.js b/tests/renderWakatimeCard.test.js index 658c52df4e9a9..51d63e6cf14c1 100644 --- a/tests/renderWakatimeCard.test.js +++ b/tests/renderWakatimeCard.test.js @@ -46,4 +46,12 @@ describe("Test Render Wakatime Card", () => { document.body.innerHTML = renderWakatimeCard(wakaTimeData.data, {}); expect(document.querySelector("rect")).toHaveAttribute("rx", "4.5"); }); + + it('should show "no coding activitiy this week" message when there hasn not been activity', () => { + document.body.innerHTML = renderWakatimeCard({ + ...wakaTimeData.data, + languages: undefined + }, {}); + expect(document.querySelector(".stat").textContent).toBe("No coding activity this week") + }) }); From 53acb536f814641ad1656a538657f2def702ebeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tuhana=20GAYRETL=C4=B0?= Date: Fri, 5 Nov 2021 17:24:30 +0300 Subject: [PATCH 40/53] style(themes): aura theme (#1423) --- themes/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/themes/index.js b/themes/index.js index c30646cf7e3d9..296540d9deaf2 100644 --- a/themes/index.js +++ b/themes/index.js @@ -324,6 +324,12 @@ const themes = { text_color: "0088ff", bg_color: "193549", }, + aura: { + title_color: "a277ff", + icon_color: "ffca85", + text_color: "61ffca", + bg_color: "15141b", + }, }; module.exports = themes; From 22ab081cee1162148aef2e67c380888d0acd0f29 Mon Sep 17 00:00:00 2001 From: Eduardo Santi Date: Fri, 5 Nov 2021 14:28:01 +0000 Subject: [PATCH 41/53] style(theme): added swift theme (#1395) Co-authored-by: Anurag Hazra --- themes/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/themes/index.js b/themes/index.js index 296540d9deaf2..e92139c1b9a81 100644 --- a/themes/index.js +++ b/themes/index.js @@ -324,6 +324,12 @@ const themes = { text_color: "0088ff", bg_color: "193549", }, + swift: { + title_color: "000000", + icon_color: "f05237", + text_color: "000000", + bg_color: "f7f7f7", + }, aura: { title_color: "a277ff", icon_color: "ffca85", From 2249bf4a22f06082c879a894f65eb0070c3124f5 Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Fri, 5 Nov 2021 21:00:20 +0530 Subject: [PATCH 42/53] docs(theme): Auto update theme readme (#1440) Co-authored-by: Github Readme Stats Bot --- themes/README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/themes/README.md b/themes/README.md index fc5970081c1b8..ca34155db3fbf 100644 --- a/themes/README.md +++ b/themes/README.md @@ -33,7 +33,8 @@ Use `?theme=THEME_NAME` parameter like so :- | `slateorange` ![slateorange][slateorange] | `kacho_ga` ![kacho_ga][kacho_ga] | `outrun` ![outrun][outrun] | | `ocean_dark` ![ocean_dark][ocean_dark] | `city_lights` ![city_lights][city_lights] | `github_dark` ![github_dark][github_dark] | | `discord_old_blurple` ![discord_old_blurple][discord_old_blurple] | `aura_dark` ![aura_dark][aura_dark] | `panda` ![panda][panda] | -| `noctis_minimus` ![noctis_minimus][noctis_minimus] | `cobalt2` ![cobalt2][cobalt2] | [Add your theme][add-theme] | +| `noctis_minimus` ![noctis_minimus][noctis_minimus] | `cobalt2` ![cobalt2][cobalt2] | `swift` ![swift][swift] | +| `aura` ![aura][aura] | | [Add your theme][add-theme] | ## Repo Card @@ -58,7 +59,8 @@ Use `?theme=THEME_NAME` parameter like so :- | `slateorange` ![slateorange][slateorange_repo] | `kacho_ga` ![kacho_ga][kacho_ga_repo] | `outrun` ![outrun][outrun_repo] | | `ocean_dark` ![ocean_dark][ocean_dark_repo] | `city_lights` ![city_lights][city_lights_repo] | `github_dark` ![github_dark][github_dark_repo] | | `discord_old_blurple` ![discord_old_blurple][discord_old_blurple_repo] | `aura_dark` ![aura_dark][aura_dark_repo] | `panda` ![panda][panda_repo] | -| `noctis_minimus` ![noctis_minimus][noctis_minimus_repo] | `cobalt2` ![cobalt2][cobalt2_repo] | [Add your theme][add-theme] | +| `noctis_minimus` ![noctis_minimus][noctis_minimus_repo] | `cobalt2` ![cobalt2][cobalt2_repo] | `swift` ![swift][swift_repo] | +| `aura` ![aura][aura_repo] | | [Add your theme][add-theme] | [default]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=default @@ -115,6 +117,8 @@ Use `?theme=THEME_NAME` parameter like so :- [panda]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=panda [noctis_minimus]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=noctis_minimus [cobalt2]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=cobalt2 +[swift]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=swift +[aura]: https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true&hide=contribs,prs&cache_seconds=86400&theme=aura [default_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=default @@ -171,6 +175,8 @@ Use `?theme=THEME_NAME` parameter like so :- [panda_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=panda [noctis_minimus_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=noctis_minimus [cobalt2_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=cobalt2 +[swift_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=swift +[aura_repo]: https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats&cache_seconds=86400&theme=aura [add-theme]: https://github.com/anuraghazra/github-readme-stats/edit/master/themes/index.js From 42e9b78db04c1260bf904732d93c906fc9d7fb89 Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Fri, 5 Nov 2021 21:01:46 +0530 Subject: [PATCH 43/53] feat(script): improved theme preview script (#1439) * feat: improved theme preview script * chore: add getPRNumber --- package.json | 3 +++ scripts/preview-theme.js | 54 ++++++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 0cb50dc167e6e..b615a2ace3363 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,12 @@ "@testing-library/jest-dom": "^5.11.0", "axios": "^0.19.2", "axios-mock-adapter": "^1.18.1", + "color-contrast-checker": "^2.1.0", "css-to-object": "^1.1.0", + "hjson": "^3.2.2", "husky": "^4.2.5", "jest": "^26.1.0", + "lodash.snakecase": "^4.1.1", "parse-diff": "^0.7.0" }, "dependencies": { diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js index 31622c6a7d400..f9be3f99989b8 100644 --- a/scripts/preview-theme.js +++ b/scripts/preview-theme.js @@ -1,6 +1,10 @@ const core = require("@actions/core"); const github = require("@actions/github"); const parse = require("parse-diff"); +const Hjson = require("hjson"); +const snakeCase = require("lodash.snakecase"); +const ColorContrastChecker = require("color-contrast-checker"); + require("dotenv").config(); function getPrNumber() { @@ -21,6 +25,8 @@ const themeContribGuidelines = ` async function run() { try { + const ccc = new ColorContrastChecker(); + const warnings = []; const token = core.getInput("token"); const octokit = github.getOctokit(token || process.env.PERSONAL_TOKEN); const pullRequestId = getPrNumber(); @@ -30,7 +36,7 @@ async function run() { return; } - let res = await octokit.pulls.get({ + const res = await octokit.pulls.get({ owner: "anuraghazra", repo: "github-readme-stats", pull_number: pullRequestId, @@ -39,15 +45,20 @@ async function run() { }, }); - let diff = parse(res.data); - let colorStrings = diff + const diff = parse(res.data); + const content = diff .find((file) => file.to === "themes/index.js") .chunks[0].changes.filter((c) => c.type === "add") .map((c) => c.content.replace("+", "")) .join(""); - let matches = colorStrings.match(/(title_color:.*bg_color.*\")/); - let colors = matches && matches[0].split(","); + const themeObject = Hjson.parse(content); + const themeName = Object.keys(themeObject)[0]; + const colors = themeObject[themeName]; + + if (themeName !== snakeCase(themeName)) { + warnings.push("Theme name isn't in snake_case"); + } if (!colors) { await octokit.issues.createComment({ @@ -64,22 +75,39 @@ async function run() { }); return; } - colors = colors.map((color) => - color.replace(/.*\:\s/, "").replace(/\"/g, ""), - ); - - const titleColor = colors[0]; - const iconColor = colors[1]; - const textColor = colors[2]; - const bgColor = colors[3]; + + const titleColor = colors.title_color; + const iconColor = colors.icon_color; + const textColor = colors.text_color; + const bgColor = colors.bg_color; const url = `https://github-readme-stats.vercel.app/api?username=anuraghazra&title_color=${titleColor}&icon_color=${iconColor}&text_color=${textColor}&bg_color=${bgColor}&show_icons=true`; + const colorPairs = { + title_color: [titleColor, bgColor], + icon_color: [iconColor, bgColor], + text_color: [textColor, bgColor], + }; + + // check color contrast + Object.keys(colorPairs).forEach((key) => { + const color1 = colorPairs[key][0]; + const color2 = colorPairs[key][1]; + if (!ccc.isLevelAA(`#${color1}`, `#${color2}`)) { + const permalink = `https://webaim.org/resources/contrastchecker/?fcolor=${color1}&bcolor=${color2}`; + warnings.push( + `\`${key}\` does not passes [AA contrast ratio](${permalink})`, + ); + } + }); + await octokit.issues.createComment({ owner: "anuraghazra", repo: "github-readme-stats", body: ` \r**Automated Theme preview** + \r${warnings.map((warning) => `- :warning: ${warning}\n`).join("")} + \ntitle_color: #${titleColor} | icon_color: #${iconColor} | text_color: #${textColor} | bg_color: #${bgColor} \r[Preview Link](${url}) From 563dc7c8980cb8ae9de53b149ea256166409a5e9 Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Sat, 6 Nov 2021 20:05:35 +0530 Subject: [PATCH 44/53] feat(theme-preview): added ability to upsert comments (#1442) * chore: added ability upsert comments * chore: new event --- .github/workflows/preview-theme.yml | 6 ++ scripts/preview-theme.js | 90 ++++++++++++++++++++++++----- 2 files changed, 82 insertions(+), 14 deletions(-) diff --git a/.github/workflows/preview-theme.yml b/.github/workflows/preview-theme.yml index f102b59c07eba..687543b5a189e 100644 --- a/.github/workflows/preview-theme.yml +++ b/.github/workflows/preview-theme.yml @@ -7,6 +7,12 @@ on: - master - theme-preview-script - "themes/index.js" + issue_comment: + types: [edited] + branches: + - master + - theme-preview-script + - "themes/index.js" jobs: build: diff --git a/scripts/preview-theme.js b/scripts/preview-theme.js index f9be3f99989b8..ca9effae79cc0 100644 --- a/scripts/preview-theme.js +++ b/scripts/preview-theme.js @@ -7,6 +7,10 @@ const ColorContrastChecker = require("color-contrast-checker"); require("dotenv").config(); +const OWNER = "anuraghazra"; +const REPO = "github-readme-stats"; +const COMMENT_TITLE = "Automated Theme Preview"; + function getPrNumber() { const pullRequest = github.context.payload.pull_request; if (!pullRequest) { @@ -16,6 +20,61 @@ function getPrNumber() { return pullRequest.number; } +function findCommentPredicate(inputs, comment) { + return ( + (inputs.commentAuthor && comment.user + ? comment.user.login === inputs.commentAuthor + : true) && + (inputs.bodyIncludes && comment.body + ? comment.body.includes(inputs.bodyIncludes) + : true) + ); +} + +async function findComment(octokit, issueNumber) { + const parameters = { + owner: OWNER, + repo: REPO, + issue_number: issueNumber, + }; + const inputs = { + commentAuthor: OWNER, + bodyIncludes: COMMENT_TITLE, + }; + + for await (const { data: comments } of octokit.paginate.iterator( + octokit.rest.issues.listComments, + parameters, + )) { + // Search each page for the comment + const comment = comments.find((comment) => + findCommentPredicate(inputs, comment), + ); + if (comment) return comment; + } +} + +async function upsertComment(octokit, props) { + if (props.comment_id !== undefined) { + await octokit.issues.updateComment(props); + } else { + await octokit.issues.createComment(props); + } +} + +function getWebAimLink(color1, color2) { + return `https://webaim.org/resources/contrastchecker/?fcolor=${color1}&bcolor=${color2}`; +} + +function getGrsLink(colors) { + const url = `https://github-readme-stats.vercel.app/api?username=anuraghazra`; + const colorString = Object.keys(colors) + .map((colorKey) => `${colorKey}=${colors[colorKey]}`) + .join("&"); + + return `${url}&${colorString}&show_icons=true`; +} + const themeContribGuidelines = ` \rHi, thanks for the theme contribution, please read our theme [contribution guidelines](https://github.com/anuraghazra/github-readme-stats/blob/master/CONTRIBUTING.md#themes-contribution). \rWe are currently only accepting color combinations from any VSCode theme or themes which have good color combination to minimize bloating the themes collection. @@ -37,13 +96,14 @@ async function run() { } const res = await octokit.pulls.get({ - owner: "anuraghazra", - repo: "github-readme-stats", + owner: OWNER, + repo: REPO, pull_number: pullRequestId, mediaType: { format: "diff", }, }); + const comment = await findComment(octokit, pullRequestId); const diff = parse(res.data); const content = diff @@ -61,17 +121,18 @@ async function run() { } if (!colors) { - await octokit.issues.createComment({ - owner: "anuraghazra", - repo: "github-readme-stats", + await upsertComment({ + comment_id: comment?.id, + owner: OWNER, + repo: REPO, + issue_number: pullRequestId, body: ` - \r**Automated Theme preview** + \r**${COMMENT_TITLE}** \rCannot create theme preview ${themeContribGuidelines} `, - issue_number: pullRequestId, }); return; } @@ -80,7 +141,7 @@ async function run() { const iconColor = colors.icon_color; const textColor = colors.text_color; const bgColor = colors.bg_color; - const url = `https://github-readme-stats.vercel.app/api?username=anuraghazra&title_color=${titleColor}&icon_color=${iconColor}&text_color=${textColor}&bg_color=${bgColor}&show_icons=true`; + const url = getGrsLink(colors); const colorPairs = { title_color: [titleColor, bgColor], @@ -93,18 +154,20 @@ async function run() { const color1 = colorPairs[key][0]; const color2 = colorPairs[key][1]; if (!ccc.isLevelAA(`#${color1}`, `#${color2}`)) { - const permalink = `https://webaim.org/resources/contrastchecker/?fcolor=${color1}&bcolor=${color2}`; + const permalink = getWebAimLink(color1, color2); warnings.push( `\`${key}\` does not passes [AA contrast ratio](${permalink})`, ); } }); - await octokit.issues.createComment({ - owner: "anuraghazra", - repo: "github-readme-stats", + await upsertComment(octokit, { + comment_id: comment?.id, + issue_number: pullRequestId, + owner: OWNER, + repo: REPO, body: ` - \r**Automated Theme preview** + \r**${COMMENT_TITLE}** \r${warnings.map((warning) => `- :warning: ${warning}\n`).join("")} @@ -116,7 +179,6 @@ async function run() { ${themeContribGuidelines} `, - issue_number: pullRequestId, }); } catch (error) { console.log(error); From 7eade85f18941822cb97e6565636bf5d758623a8 Mon Sep 17 00:00:00 2001 From: Anurag Date: Sat, 6 Nov 2021 20:17:14 +0530 Subject: [PATCH 45/53] chore: update github action trigger --- .github/workflows/preview-theme.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/preview-theme.yml b/.github/workflows/preview-theme.yml index 687543b5a189e..2e2fbb913fe34 100644 --- a/.github/workflows/preview-theme.yml +++ b/.github/workflows/preview-theme.yml @@ -9,16 +9,19 @@ on: - "themes/index.js" issue_comment: types: [edited] - branches: - - master - - theme-preview-script - - "themes/index.js" jobs: + comment: + if: contains(github.event.comment.html_url, '/pull/') + runs-on: ubuntu-latest + steps: + - name: say hello + if: contains(github.event.comment.body, 'Automated Theme Preview') + run: | + echo say hello build: runs-on: ubuntu-latest name: Install & Preview - steps: - uses: actions/checkout@v1 - uses: bahmutov/npm-install@v1 From 77d016f6480536178f1dc46271600e4d9913c621 Mon Sep 17 00:00:00 2001 From: Anurag Date: Sat, 6 Nov 2021 20:28:39 +0530 Subject: [PATCH 46/53] chore: remove edit event from action --- .github/workflows/preview-theme.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/preview-theme.yml b/.github/workflows/preview-theme.yml index 2e2fbb913fe34..f102b59c07eba 100644 --- a/.github/workflows/preview-theme.yml +++ b/.github/workflows/preview-theme.yml @@ -7,21 +7,12 @@ on: - master - theme-preview-script - "themes/index.js" - issue_comment: - types: [edited] jobs: - comment: - if: contains(github.event.comment.html_url, '/pull/') - runs-on: ubuntu-latest - steps: - - name: say hello - if: contains(github.event.comment.body, 'Automated Theme Preview') - run: | - echo say hello build: runs-on: ubuntu-latest name: Install & Preview + steps: - uses: actions/checkout@v1 - uses: bahmutov/npm-install@v1 From 1cef6aca1b5ba2ccc7ecdef6d144c23fc225d223 Mon Sep 17 00:00:00 2001 From: Abhijith N T Date: Mon, 8 Nov 2021 21:10:59 +0530 Subject: [PATCH 47/53] chore(deps): update axios to 0.24.0 (https://github.com/axios/axios/pull/3410) (#1446) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b615a2ace3363..345388f9714b1 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@actions/github": "^4.0.0", "@testing-library/dom": "^7.20.0", "@testing-library/jest-dom": "^5.11.0", - "axios": "^0.19.2", + "axios": "^0.24.0", "axios-mock-adapter": "^1.18.1", "color-contrast-checker": "^2.1.0", "css-to-object": "^1.1.0", From 709a65a998fd037cc45a60217079a8d80a43640b Mon Sep 17 00:00:00 2001 From: rickstaa Date: Tue, 9 Nov 2021 11:13:40 +0100 Subject: [PATCH 48/53] style: improve code structure --- api/index.js | 2 +- api/top-langs.js | 2 +- src/fetchers/stats-fetcher.js | 2 +- src/fetchers/top-languages-fetcher.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/index.js b/api/index.js index 235065bbde86b..d1dffcd0d3e3c 100644 --- a/api/index.js +++ b/api/index.js @@ -50,9 +50,9 @@ module.exports = async (req, res) => { try { stats = await fetchStats( username, + parseArray(role), parseBoolean(count_private), parseBoolean(include_all_commits), - parseArray(role), ); const cacheSeconds = clampValue( diff --git a/api/top-langs.js b/api/top-langs.js index 6d0e089d1c384..21970518b5614 100644 --- a/api/top-langs.js +++ b/api/top-langs.js @@ -47,8 +47,8 @@ module.exports = async (req, res) => { try { topLangs = await fetchTopLanguages( username, - parseArray(exclude_repo), parseArray(role), + parseArray(exclude_repo), parseArray(hide), ); diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index 3fafe96b9b339..8e9beeeae7728 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -86,9 +86,9 @@ const totalCommitsFetcher = async (username) => { async function fetchStats( username, + ownerAffiliations, count_private = false, include_all_commits = false, - ownerAffiliations, ) { if (!username) throw Error("Invalid username"); diff --git a/src/fetchers/top-languages-fetcher.js b/src/fetchers/top-languages-fetcher.js index 92443ada0fbe1..1a959aed7596a 100644 --- a/src/fetchers/top-languages-fetcher.js +++ b/src/fetchers/top-languages-fetcher.js @@ -34,7 +34,7 @@ const fetcher = (variables, token) => { ); }; -async function fetchTopLanguages(username, exclude_repo = [], ownerAffiliations) { +async function fetchTopLanguages(username, ownerAffiliations, exclude_repo = []) { if (!username) throw Error("Invalid username"); // Set default value for ownerAffiliations in GraphQL query won't work because From 741f8bdacf2fd86b65840eaaf44985aa560f5e93 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Tue, 9 Nov 2021 11:14:37 +0100 Subject: [PATCH 49/53] fix: fix stats and language tests --- tests/fetchStats.test.js | 8 ++++---- tests/fetchTopLanguages.test.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/fetchStats.test.js b/tests/fetchStats.test.js index e627e498a3535..c6afae9089d5a 100644 --- a/tests/fetchStats.test.js +++ b/tests/fetchStats.test.js @@ -51,7 +51,7 @@ describe("Test fetchStats", () => { it("should fetch correct stats", async () => { mock.onPost("https://api.github.com/graphql").reply(200, data); - let stats = await fetchStats("anuraghazra"); + let stats = await fetchStats("anuraghazra", []); const rank = calculateRank({ totalCommits: 100, totalRepos: 5, @@ -76,7 +76,7 @@ describe("Test fetchStats", () => { it("should throw error", async () => { mock.onPost("https://api.github.com/graphql").reply(200, error); - await expect(fetchStats("anuraghazra")).rejects.toThrow( + await expect(fetchStats("anuraghazra", [])).rejects.toThrow( "Could not resolve to a User with the login of 'noname'.", ); }); @@ -84,7 +84,7 @@ describe("Test fetchStats", () => { it("should fetch and add private contributions", async () => { mock.onPost("https://api.github.com/graphql").reply(200, data); - let stats = await fetchStats("anuraghazra", true); + let stats = await fetchStats("anuraghazra", [], true); const rank = calculateRank({ totalCommits: 150, totalRepos: 5, @@ -112,7 +112,7 @@ describe("Test fetchStats", () => { .onGet("https://api.github.com/search/commits?q=author:anuraghazra") .reply(200, { total_count: 1000 }); - let stats = await fetchStats("anuraghazra", true, true); + let stats = await fetchStats("anuraghazra", [], true, true); const rank = calculateRank({ totalCommits: 1050, totalRepos: 5, diff --git a/tests/fetchTopLanguages.test.js b/tests/fetchTopLanguages.test.js index f9aaa024390e5..2df977f1a9c90 100644 --- a/tests/fetchTopLanguages.test.js +++ b/tests/fetchTopLanguages.test.js @@ -59,7 +59,7 @@ describe("FetchTopLanguages", () => { it("should fetch correct language data", async () => { mock.onPost("https://api.github.com/graphql").reply(200, data_langs); - let repo = await fetchTopLanguages("anuraghazra"); + let repo = await fetchTopLanguages("anuraghazra", []); expect(repo).toStrictEqual({ HTML: { color: "#0f0", @@ -77,7 +77,7 @@ describe("FetchTopLanguages", () => { it("should throw error", async () => { mock.onPost("https://api.github.com/graphql").reply(200, error); - await expect(fetchTopLanguages("anuraghazra")).rejects.toThrow( + await expect(fetchTopLanguages("anuraghazra", [])).rejects.toThrow( "Could not resolve to a User with the login of 'noname'.", ); }); From ecd7d98a3c5ab9f50706458065a314b2c4f7f98e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87=C4=B1nar=20Y=C4=B1lmaz?= <79412062+Camroku@users.noreply.github.com> Date: Mon, 22 Nov 2021 20:23:12 +0300 Subject: [PATCH 50/53] style(theme): add apprentice theme (#1466) --- themes/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/themes/index.js b/themes/index.js index e92139c1b9a81..c727cf9333068 100644 --- a/themes/index.js +++ b/themes/index.js @@ -336,6 +336,12 @@ const themes = { text_color: "61ffca", bg_color: "15141b", }, + apprentice: { + title_color: "ffffff", + icon_color: "ffffaf", + text_color: "bcbcbc", + bg_color: "262626", + }, }; module.exports = themes; From 798bf72deea7a19a67c074e1d835eb7098f62220 Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Thu, 25 Nov 2021 21:12:27 +0530 Subject: [PATCH 51/53] fix: auth token header (#1474) --- src/fetchers/repo-fetcher.js | 2 +- src/fetchers/stats-fetcher.js | 2 +- src/fetchers/top-languages-fetcher.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fetchers/repo-fetcher.js b/src/fetchers/repo-fetcher.js index 07e9a4c8b2ba4..9ddaadfcdc30b 100644 --- a/src/fetchers/repo-fetcher.js +++ b/src/fetchers/repo-fetcher.js @@ -38,7 +38,7 @@ const fetcher = (variables, token) => { variables, }, { - Authorization: `bearer ${token}`, + Authorization: `token ${token}`, }, ); }; diff --git a/src/fetchers/stats-fetcher.js b/src/fetchers/stats-fetcher.js index b0636d1b29ce2..1a03b46671ef2 100644 --- a/src/fetchers/stats-fetcher.js +++ b/src/fetchers/stats-fetcher.js @@ -69,7 +69,7 @@ const totalCommitsFetcher = async (username) => { headers: { "Content-Type": "application/json", Accept: "application/vnd.github.cloak-preview", - Authorization: `bearer ${token}`, + Authorization: `token ${token}`, }, }); }; diff --git a/src/fetchers/top-languages-fetcher.js b/src/fetchers/top-languages-fetcher.js index 7e248fb1e03cc..cd02e64761a7f 100644 --- a/src/fetchers/top-languages-fetcher.js +++ b/src/fetchers/top-languages-fetcher.js @@ -29,7 +29,7 @@ const fetcher = (variables, token) => { variables, }, { - Authorization: `bearer ${token}`, + Authorization: `token ${token}`, }, ); }; From 0637911873b434641d0d521e985992e16552a9c6 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Mon, 22 Nov 2021 16:58:03 +0100 Subject: [PATCH 52/53] feat(stats): add 'not_bold' option to stats card --- api/index.js | 2 ++ readme.md | 2 ++ src/cards/stats-card.js | 19 +++++++++++-------- src/getStyles.js | 1 + .../renderWakatimeCard.test.js.snap | 2 ++ 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/api/index.js b/api/index.js index 8d50f60009832..ccab9655ffa69 100644 --- a/api/index.js +++ b/api/index.js @@ -25,6 +25,7 @@ module.exports = async (req, res) => { title_color, icon_color, text_color, + text_bold, bg_color, theme, cache_seconds, @@ -73,6 +74,7 @@ module.exports = async (req, res) => { title_color, icon_color, text_color, + text_bold: parseBoolean(text_bold), bg_color, theme, custom_title, diff --git a/readme.md b/readme.md index a6dab596f87b9..6c10610eebe9b 100644 --- a/readme.md +++ b/readme.md @@ -189,6 +189,7 @@ You can provide multiple comma-separated values in bg_color option to render a g - `count_private` - Count private commits _(boolean)_ - `line_height` - Sets the line-height between text _(number)_ - `custom_title` - Sets a custom title for the card +- `text_bold` - Use bold text _(boolean)_ - `disable_animations` - Disables all animations in the card _(boolean)_ #### Repo Card Exclusive Options: @@ -444,3 +445,4 @@ Thanks! :heart: Contributions are welcome! <3 Made with :heart: and JavaScript. + diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index 22e4be765c749..503e0187f1802 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -19,6 +19,7 @@ const createTextNode = ({ index, showIcons, shiftValuePos, + bold, }) => { const kValue = kFormatter(value); const staggerDelay = (index + 3) * 150; @@ -34,18 +35,18 @@ const createTextNode = ({ return ` ${iconSvg} - ${label}: - ${label}: + ${kValue} `; }; -const renderStatsCard = (stats = {}, options = { hide: [] }) => { +const renderStatsCard = (stats = {}, options = { hide: []}) => { const { name, totalStars, @@ -66,6 +67,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { title_color, icon_color, text_color, + text_bold = true, bg_color, theme = "default", custom_title, @@ -158,6 +160,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { showIcons: show_icons, shiftValuePos: (!include_all_commits ? 50 : 35) + (isLongLocale ? 50 : 0), + bold: text_bold, }), ); @@ -171,7 +174,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { // Conditionally rendered elements const rankCircle = hide_rank ? "" - : ` @@ -241,7 +244,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { gap: lheight, direction: "column", }).join("")} - + `); }; diff --git a/src/getStyles.js b/src/getStyles.js index fd70c249865b9..37a41290732aa 100644 --- a/src/getStyles.js +++ b/src/getStyles.js @@ -80,6 +80,7 @@ const getStyles = ({ animation: scaleInAnimation 0.3s ease-in-out forwards; } + .not_bold { font-weight: 400 } .bold { font-weight: 700 } .icon { fill: ${iconColor}; diff --git a/tests/__snapshots__/renderWakatimeCard.test.js.snap b/tests/__snapshots__/renderWakatimeCard.test.js.snap index c651c62a69ccd..0f1a7bfbf295b 100644 --- a/tests/__snapshots__/renderWakatimeCard.test.js.snap +++ b/tests/__snapshots__/renderWakatimeCard.test.js.snap @@ -29,6 +29,7 @@ exports[`Test Render Wakatime Card should render correctly 1`] = ` animation: scaleInAnimation 0.3s ease-in-out forwards; } + .not_bold { font-weight: 400 } .bold { font-weight: 700 } .icon { fill: #4c71f2; @@ -178,6 +179,7 @@ exports[`Test Render Wakatime Card should render correctly with compact layout 1 animation: scaleInAnimation 0.3s ease-in-out forwards; } + .not_bold { font-weight: 400 } .bold { font-weight: 700 } .icon { fill: #4c71f2; From 33ac565564d4c262c84e18386d538f841fc6a960 Mon Sep 17 00:00:00 2001 From: rickstaa Date: Wed, 1 Dec 2021 17:28:03 +0100 Subject: [PATCH 53/53] fix: decrease maxduration --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index aee61ce054fd0..ddf82eb15666f 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "functions": { "api/*.js": { "memory": 128, - "maxDuration": 30 + "maxDuration": 10 } }, "redirects": [