From 1c1232608168d33d69ed3ee98f78f943ad5327be Mon Sep 17 00:00:00 2001 From: Anurag Hazra Date: Sun, 13 Dec 2020 20:15:00 +0530 Subject: [PATCH] feat: auto resize card if rank is hidden (#721) --- readme.md | 2 +- src/cards/stats-card.js | 22 +++++++++++++++++++-- src/common/utils.js | 36 +++++++++++++++++++++++++++++++++++ tests/renderStatsCard.test.js | 21 ++++++++++++++++++++ 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 79965485..7a9515f8 100644 --- a/readme.md +++ b/readme.md @@ -156,7 +156,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)_ -- `hide_rank` - _(boolean)_ +- `hide_rank` - _(boolean)_ hides the rank and automatically resizes the card width - `hide_border` - _(boolean)_ - `show_icons` - _(boolean)_ - `include_all_commits` - Count total commits instead of just the current year commits _(boolean)_ diff --git a/src/cards/stats-card.js b/src/cards/stats-card.js index 189709ee..692ccc2c 100644 --- a/src/cards/stats-card.js +++ b/src/cards/stats-card.js @@ -3,7 +3,13 @@ const Card = require("../common/Card"); const icons = require("../common/icons"); const { getStyles } = require("../getStyles"); const { statCardLocales } = require("../translations"); -const { kFormatter, getCardColors, FlexLayout } = require("../common/utils"); +const { + kFormatter, + FlexLayout, + clampValue, + measureText, + getCardColors, +} = require("../common/utils"); const createTextNode = ({ icon, @@ -176,10 +182,22 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { progress, }); + const calculateTextWidth = () => { + return measureText(custom_title ? custom_title : i18n.t("statcard.title")); + }; + + const width = hide_rank + ? clampValue( + 50 /* padding */ + calculateTextWidth() * 2, + 270 /* min */, + Infinity, + ) + : 495; + const card = new Card({ customTitle: custom_title, defaultTitle: i18n.t("statcard.title"), - width: 495, + width, height, colors: { titleColor, diff --git a/src/common/utils.js b/src/common/utils.js index d0911721..a2260da0 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -188,6 +188,41 @@ class CustomError extends Error { static USER_NOT_FOUND = "USER_NOT_FOUND"; } +// https://stackoverflow.com/a/48172630/10629172 +function measureText(str, fontSize = 10) { + // prettier-ignore + const widths = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0.2796875, 0.2765625, + 0.3546875, 0.5546875, 0.5546875, 0.8890625, 0.665625, 0.190625, + 0.3328125, 0.3328125, 0.3890625, 0.5828125, 0.2765625, 0.3328125, + 0.2765625, 0.3015625, 0.5546875, 0.5546875, 0.5546875, 0.5546875, + 0.5546875, 0.5546875, 0.5546875, 0.5546875, 0.5546875, 0.5546875, + 0.2765625, 0.2765625, 0.584375, 0.5828125, 0.584375, 0.5546875, + 1.0140625, 0.665625, 0.665625, 0.721875, 0.721875, 0.665625, + 0.609375, 0.7765625, 0.721875, 0.2765625, 0.5, 0.665625, + 0.5546875, 0.8328125, 0.721875, 0.7765625, 0.665625, 0.7765625, + 0.721875, 0.665625, 0.609375, 0.721875, 0.665625, 0.94375, + 0.665625, 0.665625, 0.609375, 0.2765625, 0.3546875, 0.2765625, + 0.4765625, 0.5546875, 0.3328125, 0.5546875, 0.5546875, 0.5, + 0.5546875, 0.5546875, 0.2765625, 0.5546875, 0.5546875, 0.221875, + 0.240625, 0.5, 0.221875, 0.8328125, 0.5546875, 0.5546875, + 0.5546875, 0.5546875, 0.3328125, 0.5, 0.2765625, 0.5546875, + 0.5, 0.721875, 0.5, 0.5, 0.5, 0.3546875, 0.259375, 0.353125, 0.5890625, + ]; + + const avg = 0.5279276315789471; + return ( + str + .split("") + .map((c) => + c.charCodeAt(0) < widths.length ? widths[c.charCodeAt(0)] : avg, + ) + .reduce((cur, acc) => acc + cur) * fontSize + ); +} + module.exports = { renderError, kFormatter, @@ -201,6 +236,7 @@ module.exports = { getCardColors, clampValue, wrapTextMultiline, + measureText, logger, CONSTANTS, CustomError, diff --git a/tests/renderStatsCard.test.js b/tests/renderStatsCard.test.js index 8f6109a0..f5ea16a9 100644 --- a/tests/renderStatsCard.test.js +++ b/tests/renderStatsCard.test.js @@ -210,6 +210,27 @@ describe("Test renderStatsCard", () => { ).not.toHaveAttribute("x"); }); + it("should auto resize if hide_rank is true", () => { + document.body.innerHTML = renderStatsCard(stats, { + hide_rank: true, + }); + + expect( + document.body.getElementsByTagName("svg")[0].getAttribute("width"), + ).toBe("305.81250000000006"); + }); + + it("should auto resize if hide_rank is true & custom_title is set", () => { + document.body.innerHTML = renderStatsCard(stats, { + hide_rank: true, + custom_title: "Hello world", + }); + + expect( + document.body.getElementsByTagName("svg")[0].getAttribute("width"), + ).toBe("270"); + }); + it("should render translations", () => { document.body.innerHTML = renderStatsCard(stats, { locale: "cn" }); expect(document.getElementsByClassName("header")[0].textContent).toBe(