From c2adcfd6fe5442c4c6dbbded64b91ec6548cab60 Mon Sep 17 00:00:00 2001 From: Arjun Mahishi Date: Thu, 23 Jul 2020 19:47:04 +0530 Subject: [PATCH] feat: hide specific languages in "Top languages" card (#150) * add new query param to hide specific languages in top languages card * [top-langs] add function to clean out the provided lang name * [top-langs] rename 'hide_lang' => 'hide', refactor logic for parsing the list of provided languages to hide * [top-langs] take list of languages to hide, as a json array * chore: minor changes * docs: added docs for hide lang Co-authored-by: anuraghazra --- api/index.js | 3 ++- api/top-langs.js | 5 +++-- readme.md | 36 ++++++++++++++++---------------- src/renderTopLanguages.js | 24 ++++++++++++++------- src/utils.js | 12 ++++++++++- tests/renderTopLanguages.test.js | 18 +++++++++++----- 6 files changed, 64 insertions(+), 34 deletions(-) diff --git a/api/index.js b/api/index.js index 30834fcc0a8cc..2939bba4bedd8 100644 --- a/api/index.js +++ b/api/index.js @@ -2,6 +2,7 @@ require("dotenv").config(); const { renderError, parseBoolean, + parseJSON, clampValue, CONSTANTS, } = require("../src/utils"); @@ -44,7 +45,7 @@ module.exports = async (req, res) => { res.send( renderStatsCard(stats, { - hide: JSON.parse(hide || "[]"), + hide: parseJSON(hide), show_icons: parseBoolean(show_icons), hide_title: parseBoolean(hide_title), hide_border: parseBoolean(hide_border), diff --git a/api/top-langs.js b/api/top-langs.js index 026705cf1b1c7..f0db2af5792ce 100644 --- a/api/top-langs.js +++ b/api/top-langs.js @@ -3,6 +3,7 @@ const { renderError, clampValue, parseBoolean, + parseJSON, CONSTANTS, } = require("../src/utils"); const fetchTopLanguages = require("../src/fetchTopLanguages"); @@ -11,7 +12,7 @@ const renderTopLanguages = require("../src/renderTopLanguages"); module.exports = async (req, res) => { const { username, - hide_langs_below, + hide, hide_title, card_width, title_color, @@ -43,7 +44,7 @@ module.exports = async (req, res) => { theme, hide_title: parseBoolean(hide_title), card_width: parseInt(card_width, 10), - hide_langs_below: parseFloat(hide_langs_below, 10), + hide: parseJSON(hide), title_color, text_color, bg_color, diff --git a/readme.md b/readme.md index 3140b13868b79..51f57e0984d18 100644 --- a/readme.md +++ b/readme.md @@ -97,21 +97,21 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you Customization Options: -| Option | type | description | Stats Card (default) | Repo Card (default) | Top Lang Card (default) | -| ---------------- | --------- | ---------------------------------------------- | -------------------- | ------------------- | ----------------------- | -| title_color | hex color | title color | 2f80ed | 2f80ed | 2f80ed | -| text_color | hex color | body color | 333 | 333 | 333 | -| icon_color | hex color | icon color | 4c71f2 | 586069 | 586069 | -| bg_color | hex color | card bg color | FFFEFE | FFFEFE | FFFEFE | -| line_height | number | control the line-height between text | 30 | N/A | N/A | -| hide_rank | boolean | hides the ranking | false | N/A | N/A | -| hide_title | boolean | hides the stats title | false | N/A | false | -| hide_border | boolean | hides the stats card border | false | N/A | N/A | -| show_owner | boolean | shows owner name in repo card | N/A | false | N/A | -| show_icons | boolean | shows icons | false | N/A | N/A | -| theme | string | sets inbuilt theme | 'default' | 'default_repocard' | 'default | -| cache_seconds | number | manually set custom cache control | 1800 | 1800 | '1800' | -| hide_langs_below | number | hide langs below certain threshold (lang card) | N/A | N/A | undefined | +| Option | type | description | Stats Card (default) | Repo Card (default) | Top Lang Card (default) | +| ------------- | ---------- | -------------------------------------- | -------------------- | ------------------- | ----------------------- | +| title_color | hex color | title color | 2f80ed | 2f80ed | 2f80ed | +| text_color | hex color | body color | 333 | 333 | 333 | +| icon_color | hex color | icon color | 4c71f2 | 586069 | 586069 | +| bg_color | hex color | card bg color | FFFEFE | FFFEFE | FFFEFE | +| line_height | number | control the line-height between text | 30 | N/A | N/A | +| hide | JSON array | hides the items specified on the array | [] | N/A | [] | +| hide_rank | boolean | hides the ranking | false | N/A | N/A | +| hide_title | boolean | hides the stats title | false | N/A | false | +| hide_border | boolean | hides the stats card border | false | N/A | N/A | +| show_owner | boolean | shows owner name in repo card | N/A | false | N/A | +| show_icons | boolean | shows icons | false | N/A | N/A | +| theme | string | sets inbuilt theme | 'default' | 'default_repocard' | 'default | +| cache_seconds | number | manually set custom cache control | 1800 | 1800 | '1800' | > Note on cache: Repo cards have default cache of 30mins (1800 seconds) if the fork count & star count is less than 1k otherwise it's 2hours (7200). Also note that cache is clamped to minimum of 30min and maximum of 24hours @@ -155,12 +155,12 @@ Endpoint: `api/top-langs?username=anuraghazra` [![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra)](https://github.com/anuraghazra/github-readme-stats) ``` -### Hide languages below certain threshold +### Hide individual languages -You can use `?hide_langs_below=NUMBER` parameter to hide languages below a specified threshold percentage. +You can use `?hide=["language1","language2"]` parameter to hide languages below a specified threshold percentage. ```md -[![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra&hide_langs_below=1)](https://github.com/anuraghazra/github-readme-stats) +[![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra&hide=["javascript","html"])](https://github.com/anuraghazra/github-readme-stats) ``` ### Demo diff --git a/src/renderTopLanguages.js b/src/renderTopLanguages.js index 25987a2f6f8a0..ae07cf1e382f0 100644 --- a/src/renderTopLanguages.js +++ b/src/renderTopLanguages.js @@ -23,6 +23,8 @@ const createProgressNode = ({ width, color, name, progress }) => { `; }; +const lowercaseTrim = (name) => name.toLowerCase().trim(); + const renderTopLanguages = (topLangs, options = {}) => { const { hide_title, @@ -30,24 +32,32 @@ const renderTopLanguages = (topLangs, options = {}) => { title_color, text_color, bg_color, - hide_langs_below, + hide, theme, } = options; let langs = Object.values(topLangs); + let langsToHide = {}; - const totalSize = langs.reduce((acc, curr) => { - return acc + curr.size; - }, 0); + // populate langsToHide map for quick lookup + // while filtering out + if (hide) { + hide.forEach((langName) => { + langsToHide[lowercaseTrim(langName)] = true; + }); + } - // hide langs + // filter out langauges to be hidden langs = langs .sort((a, b) => b.size - a.size) .filter((lang) => { - if (!hide_langs_below) return true; - return (lang.size / totalSize) * 100 > hide_langs_below; + return !langsToHide[lowercaseTrim(lang.name)]; }); + const totalSize = langs.reduce((acc, curr) => { + return acc + curr.size; + }, 0); + // returns theme based colors with proper overrides and defaults const { titleColor, textColor, bgColor } = getCardColors({ title_color, diff --git a/src/utils.js b/src/utils.js index e03f37b3eb893..38ad27f603b94 100644 --- a/src/utils.js +++ b/src/utils.js @@ -44,6 +44,14 @@ function parseBoolean(value) { } } +function parseJSON(str) { + try { + return JSON.parse(str); + } catch (err) { + return []; + } +} + function clampValue(number, min, max) { return Math.max(min, Math.min(number, max)); } @@ -118,7 +126,8 @@ function getCardColors({ const fn = () => {}; // return console instance based on the environment -const logger = process.env.NODE_ENV !== "test" ? console : { log: fn, error: fn }; +const logger = + process.env.NODE_ENV !== "test" ? console : { log: fn, error: fn }; const CONSTANTS = { THIRTY_MINUTES: 1800, @@ -132,6 +141,7 @@ module.exports = { encodeHTML, isValidHexColor, request, + parseJSON, parseBoolean, fallbackColor, FlexLayout, diff --git a/tests/renderTopLanguages.test.js b/tests/renderTopLanguages.test.js index 17e07c554e3dc..1b697461723c9 100644 --- a/tests/renderTopLanguages.test.js +++ b/tests/renderTopLanguages.test.js @@ -58,18 +58,26 @@ describe("Test renderTopLanguages", () => { ); }); - it("should hide_langs_below", () => { + it("should hide languages when hide is passed", () => { document.body.innerHTML = renderTopLanguages(langs, { - hide_langs_below: 34, + hide: ["HTML"], }); - expect(queryAllByTestId(document.body, "lang-name")[0]).toBeInTheDocument( - "HTML" + "javascript" ); expect(queryAllByTestId(document.body, "lang-name")[1]).toBeInTheDocument( - "javascript" + "css" ); expect(queryAllByTestId(document.body, "lang-name")[2]).not.toBeDefined(); + + // multiple languages passed + document.body.innerHTML = renderTopLanguages(langs, { + hide: ["HTML","css"], + }); + expect(queryAllByTestId(document.body, "lang-name")[0]).toBeInTheDocument( + "javascript" + ); + expect(queryAllByTestId(document.body, "lang-name")[1]).not.toBeDefined(); }); it("should resize the height correctly depending on langs", () => {