From 59b8bded9c17ced15524bc0be01e7e66a124d8dc Mon Sep 17 00:00:00 2001 From: JoaoVSouto Date: Sat, 11 Jul 2020 16:01:44 -0300 Subject: [PATCH 1/4] feat: receives text, title and icon colors from URL --- api/index.js | 14 +++++++++++++- src/renderStatsCard.js | 18 ++++++++++++++---- src/utils.js | 8 +++++++- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/api/index.js b/api/index.js index 22019cd..4625379 100644 --- a/api/index.js +++ b/api/index.js @@ -4,7 +4,16 @@ const fetchStats = require("../src/fetchStats"); const renderStatsCard = require("../src/renderStatsCard"); module.exports = async (req, res) => { - const { username, hide, hide_border, show_icons, line_height } = req.query; + const { + username, + hide, + hide_border, + show_icons, + line_height, + title_color, + icon_color, + text_color, + } = req.query; let stats; res.setHeader("Content-Type", "image/svg+xml"); @@ -20,6 +29,9 @@ module.exports = async (req, res) => { show_icons, hide_border, line_height, + title_color, + icon_color, + text_color, }) ); }; diff --git a/src/renderStatsCard.js b/src/renderStatsCard.js index 98d73b3..0791014 100644 --- a/src/renderStatsCard.js +++ b/src/renderStatsCard.js @@ -1,11 +1,11 @@ -const { kFormatter } = require("../src/utils"); +const { kFormatter, isValidHexColor } = require("../src/utils"); const createTextNode = ({ icon, label, value, lineHeight, id }) => { const classname = icon === "★" && "star-icon"; const kValue = kFormatter(value); return ` - ${icon} ${label}: + ${icon} ${label}: ${kValue} `; }; @@ -24,10 +24,19 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { show_icons = false, hide_border = false, line_height = 25, + title_color, + icon_color, + text_color, } = options; const lheight = parseInt(line_height); + const titleColor = + (isValidHexColor(title_color) && `#${title_color}`) || "#2f80ed"; + const iconColor = + (isValidHexColor(icon_color) && `#${icon_color}`) || "#4c71f2"; + const textColor = (isValidHexColor(text_color) && `#${text_color}`) || "#333"; + const STAT_MAP = { stars: createTextNode({ icon: "★", @@ -76,11 +85,12 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { return ` diff --git a/src/utils.js b/src/utils.js index 2b7168e..6cd2b50 100644 --- a/src/utils.js +++ b/src/utils.js @@ -25,4 +25,10 @@ function kFormatter(num) { : Math.sign(num) * Math.abs(num); } -module.exports = { renderError, kFormatter, encodeHTML }; +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); +} + +module.exports = { renderError, kFormatter, encodeHTML, isValidHexColor }; From 61a0f517db9567e24266e1c6a2bbc22087cded34 Mon Sep 17 00:00:00 2001 From: JoaoVSouto Date: Sat, 11 Jul 2020 23:28:28 -0300 Subject: [PATCH 2/4] test: adds colors checking tests --- package.json | 1 + tests/renderStatsCard.test.js | 37 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/package.json b/package.json index 1d3b262..4a95aa8 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@testing-library/jest-dom": "^5.11.0", "axios": "^0.19.2", "axios-mock-adapter": "^1.18.1", + "css-to-object": "^1.1.0", "jest": "^26.1.0" }, "dependencies": { diff --git a/tests/renderStatsCard.test.js b/tests/renderStatsCard.test.js index d7bc8d2..541a89f 100644 --- a/tests/renderStatsCard.test.js +++ b/tests/renderStatsCard.test.js @@ -1,4 +1,5 @@ require("@testing-library/jest-dom"); +const cssToObject = require("css-to-object"); const renderStatsCard = require("../src/renderStatsCard"); const { getByTestId, queryByTestId } = require("@testing-library/dom"); @@ -51,4 +52,40 @@ describe("Test renderStatsCard", () => { expect(queryByTestId(document.body, "card-border")).not.toBeInTheDocument(); }); + + it("should render default colors properly", () => { + document.body.innerHTML = renderStatsCard(stats); + + const styleTag = document.querySelector("style"); + const stylesObject = cssToObject(styleTag.innerHTML); + + const headerClassStyles = stylesObject[".header"]; + const statClassStyles = stylesObject[".stat"]; + const iconClassStyles = stylesObject[".icon"]; + + expect(headerClassStyles.fill).toBe("#2f80ed"); + expect(statClassStyles.fill).toBe("#333"); + expect(iconClassStyles.fill).toBe("#4c71f2"); + }); + + it("should render custom colors properly", () => { + const customColors = { + title_color: "5a0", + icon_color: "1b998b", + text_color: "9991", + }; + + document.body.innerHTML = renderStatsCard(stats, { ...customColors }); + + const styleTag = document.querySelector("style"); + const stylesObject = cssToObject(styleTag.innerHTML); + + const headerClassStyles = stylesObject[".header"]; + const statClassStyles = stylesObject[".stat"]; + const iconClassStyles = stylesObject[".icon"]; + + expect(headerClassStyles.fill).toBe(`#${customColors.title_color}`); + expect(statClassStyles.fill).toBe(`#${customColors.text_color}`); + expect(iconClassStyles.fill).toBe(`#${customColors.icon_color}`); + }); }); From 9af56df2c122e76f38994f572ac114bbbeaafbd8 Mon Sep 17 00:00:00 2001 From: anuraghazra Date: Sun, 12 Jul 2020 12:46:08 +0530 Subject: [PATCH 3/4] feat: added bg_color options, added RepoCard color options too --- api/index.js | 2 ++ api/pin.js | 18 +++++++++++-- src/renderRepoCard.js | 32 ++++++++++++++--------- src/renderStatsCard.js | 5 +++- tests/renderRepoCard.test.js | 48 +++++++++++++++++++++++++++++++++++ tests/renderStatsCard.test.js | 9 +++++++ 6 files changed, 99 insertions(+), 15 deletions(-) diff --git a/api/index.js b/api/index.js index 4625379..e6684f2 100644 --- a/api/index.js +++ b/api/index.js @@ -13,6 +13,7 @@ module.exports = async (req, res) => { title_color, icon_color, text_color, + bg_color, } = req.query; let stats; @@ -32,6 +33,7 @@ module.exports = async (req, res) => { title_color, icon_color, text_color, + bg_color, }) ); }; diff --git a/api/pin.js b/api/pin.js index c509fe2..2d69c0e 100644 --- a/api/pin.js +++ b/api/pin.js @@ -4,7 +4,14 @@ const fetchRepo = require("../src/fetchRepo"); const renderRepoCard = require("../src/renderRepoCard"); module.exports = async (req, res) => { - const { username, repo } = req.query; + const { + username, + repo, + title_color, + icon_color, + text_color, + bg_color, + } = req.query; let repoData; res.setHeader("Content-Type", "image/svg+xml"); @@ -16,5 +23,12 @@ module.exports = async (req, res) => { return res.send(renderError(err.message)); } - res.send(renderRepoCard(repoData)); + res.send( + renderRepoCard(repoData, { + title_color, + icon_color, + text_color, + bg_color, + }) + ); }; diff --git a/src/renderRepoCard.js b/src/renderRepoCard.js index 97412c3..a228866 100644 --- a/src/renderRepoCard.js +++ b/src/renderRepoCard.js @@ -1,7 +1,9 @@ -const { kFormatter, encodeHTML } = require("../src/utils"); +const { kFormatter, encodeHTML, isValidHexColor } = require("../src/utils"); -const renderRepoCard = (repo) => { +const renderRepoCard = (repo, options = {}) => { const { name, description, primaryLanguage, stargazers, forkCount } = repo; + const { title_color, icon_color, text_color, bg_color } = options; + const height = 120; const shiftText = primaryLanguage.name.length > 15 ? 0 : 30; @@ -10,20 +12,26 @@ const renderRepoCard = (repo) => { desc = `${description.slice(0, 55)}..`; } + const titleColor = + (isValidHexColor(title_color) && `#${title_color}`) || "#2f80ed"; + const iconColor = + (isValidHexColor(icon_color) && `#${icon_color}`) || "#586069"; + const bgColor = + (isValidHexColor(bg_color) && `#${bg_color}`) || "rgba(255, 255, 255, 0)"; + const textColor = (isValidHexColor(text_color) && `#${text_color}`) || "#333"; + const totalStars = kFormatter(stargazers.totalCount); const totalForks = kFormatter(forkCount); return ` - - + + @@ -40,14 +48,14 @@ const renderRepoCard = (repo) => { - + ${totalStars} - + ${totalForks} diff --git a/src/renderStatsCard.js b/src/renderStatsCard.js index 0791014..40b03a6 100644 --- a/src/renderStatsCard.js +++ b/src/renderStatsCard.js @@ -27,6 +27,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { title_color, icon_color, text_color, + bg_color, } = options; const lheight = parseInt(line_height); @@ -36,6 +37,8 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { const iconColor = (isValidHexColor(icon_color) && `#${icon_color}`) || "#4c71f2"; const textColor = (isValidHexColor(text_color) && `#${text_color}`) || "#333"; + const bgColor = + (isValidHexColor(bg_color) && `#${bg_color}`) || "rgba(255, 255, 255, 0)"; const STAT_MAP = { stars: createTextNode({ @@ -81,7 +84,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => { const height = 45 + (statItems.length + 1) * lheight; - const border = ``; + const border = ``; return `