From 9c6eb2286284a44ea3ba983ab4d2d2f8a8c2203e Mon Sep 17 00:00:00 2001 From: Pritam Sharma <119423845+notpritam@users.noreply.github.com> Date: Sun, 29 Oct 2023 01:01:24 +0530 Subject: [PATCH] feature: render error card in same theme as requested card (resolves #3259) (#3298) * Error theme Based on Design * Update src/common/utils.js Co-authored-by: Alexandr Garbuzov * Update src/common/utils.js Co-authored-by: Alexandr Garbuzov --------- Co-authored-by: Alexandr Garbuzov --- api/gist.js | 20 ++++++- api/index.js | 30 +++++++++- api/pin.js | 30 +++++++++- api/top-langs.js | 20 ++++++- api/wakatime.js | 20 ++++++- src/common/utils.js | 130 +++++++++++++++++++++++++------------------- 6 files changed, 183 insertions(+), 67 deletions(-) diff --git a/api/gist.js b/api/gist.js index 1dbc5ae..8821c7b 100644 --- a/api/gist.js +++ b/api/gist.js @@ -27,7 +27,15 @@ export default async (req, res) => { res.setHeader("Content-Type", "image/svg+xml"); if (locale && !isLocaleAvailable(locale)) { - return res.send(renderError("Something went wrong", "Language not found")); + return res.send( + renderError("Something went wrong", "Language not found", { + title_color, + text_color, + bg_color, + border_color, + theme, + }), + ); } try { @@ -83,6 +91,14 @@ export default async (req, res) => { CONSTANTS.ERROR_CACHE_SECONDS }, stale-while-revalidate=${CONSTANTS.ONE_DAY}`, ); // Use lower cache period for errors. - return res.send(renderError(err.message, err.secondaryMessage)); + return res.send( + renderError(err.message, err.secondaryMessage, { + title_color, + text_color, + bg_color, + border_color, + theme, + }), + ); } }; diff --git a/api/index.js b/api/index.js index adfd331..e1e1c27 100644 --- a/api/index.js +++ b/api/index.js @@ -42,11 +42,27 @@ export default async (req, res) => { res.setHeader("Content-Type", "image/svg+xml"); if (blacklist.includes(username)) { - return res.send(renderError("Something went wrong")); + return res.send( + renderError("Something went wrong", "", { + title_color, + text_color, + bg_color, + border_color, + theme, + }), + ); } if (locale && !isLocaleAvailable(locale)) { - return res.send(renderError("Something went wrong", "Language not found")); + return res.send( + renderError("Something went wrong", "Language not found", { + title_color, + text_color, + bg_color, + border_color, + theme, + }), + ); } try { @@ -111,6 +127,14 @@ export default async (req, res) => { CONSTANTS.ERROR_CACHE_SECONDS }, stale-while-revalidate=${CONSTANTS.ONE_DAY}`, ); // Use lower cache period for errors. - return res.send(renderError(err.message, err.secondaryMessage)); + return res.send( + renderError(err.message, err.secondaryMessage, { + title_color, + text_color, + bg_color, + border_color, + theme, + }), + ); } }; diff --git a/api/pin.js b/api/pin.js index 21ecf96..bdad925 100644 --- a/api/pin.js +++ b/api/pin.js @@ -29,11 +29,27 @@ export default async (req, res) => { res.setHeader("Content-Type", "image/svg+xml"); if (blacklist.includes(username)) { - return res.send(renderError("Something went wrong")); + return res.send( + renderError("Something went wrong", "", { + title_color, + text_color, + bg_color, + border_color, + theme, + }), + ); } if (locale && !isLocaleAvailable(locale)) { - return res.send(renderError("Something went wrong", "Language not found")); + return res.send( + renderError("Something went wrong", "Language not found", { + title_color, + text_color, + bg_color, + border_color, + theme, + }), + ); } try { @@ -89,6 +105,14 @@ export default async (req, res) => { CONSTANTS.ERROR_CACHE_SECONDS }, stale-while-revalidate=${CONSTANTS.ONE_DAY}`, ); // Use lower cache period for errors. - return res.send(renderError(err.message, err.secondaryMessage)); + return res.send( + renderError(err.message, err.secondaryMessage, { + title_color, + text_color, + bg_color, + border_color, + theme, + }), + ); } }; diff --git a/api/top-langs.js b/api/top-langs.js index d9bf6b0..0ca96fe 100644 --- a/api/top-langs.js +++ b/api/top-langs.js @@ -37,7 +37,15 @@ export default async (req, res) => { res.setHeader("Content-Type", "image/svg+xml"); if (blacklist.includes(username)) { - return res.send(renderError("Something went wrong")); + return res.send( + renderError("Something went wrong", "", { + title_color, + text_color, + bg_color, + border_color, + theme, + }), + ); } if (locale && !isLocaleAvailable(locale)) { @@ -105,6 +113,14 @@ export default async (req, res) => { CONSTANTS.ERROR_CACHE_SECONDS }, stale-while-revalidate=${CONSTANTS.ONE_DAY}`, ); // Use lower cache period for errors. - return res.send(renderError(err.message, err.secondaryMessage)); + return res.send( + renderError(err.message, err.secondaryMessage, { + title_color, + text_color, + bg_color, + border_color, + theme, + }), + ); } }; diff --git a/api/wakatime.js b/api/wakatime.js index b2582ca..732b05a 100644 --- a/api/wakatime.js +++ b/api/wakatime.js @@ -35,7 +35,15 @@ export default async (req, res) => { res.setHeader("Content-Type", "image/svg+xml"); if (locale && !isLocaleAvailable(locale)) { - return res.send(renderError("Something went wrong", "Language not found")); + return res.send( + renderError("Something went wrong", "Language not found", { + title_color, + text_color, + bg_color, + border_color, + theme, + }), + ); } try { @@ -84,6 +92,14 @@ export default async (req, res) => { CONSTANTS.ERROR_CACHE_SECONDS }, stale-while-revalidate=${CONSTANTS.ONE_DAY}`, ); // Use lower cache period for errors. - return res.send(renderError(err.message, err.secondaryMessage)); + return res.send( + renderError(err.message, err.secondaryMessage, { + title_color, + text_color, + bg_color, + border_color, + theme, + }), + ); } }; diff --git a/src/common/utils.js b/src/common/utils.js index 6792df8..48ea051 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -39,61 +39,6 @@ class CustomError extends Error { static WAKATIME_ERROR = "WAKATIME_ERROR"; } -// Script parameters. -const ERROR_CARD_LENGTH = 576.5; - -/** - * Encode string as HTML. - * - * @see https://stackoverflow.com/a/48073476/10629172 - * - * @param {string} str String to encode. - * @returns {string} Encoded string. - */ -const encodeHTML = (str) => { - return str - .replace(/[\u00A0-\u9999<>&](?!#)/gim, (i) => { - return "&#" + i.charCodeAt(0) + ";"; - }) - .replace(/\u0008/gim, ""); -}; - -const UPSTREAM_API_ERRORS = [ - TRY_AGAIN_LATER, - SECONDARY_ERROR_MESSAGES.MAX_RETRY, -]; - -/** - * Renders error message on the card. - * - * @param {string} message Main error message. - * @param {string} secondaryMessage The secondary error message. - * @returns {string} The SVG markup. - */ -const renderError = (message, secondaryMessage = "") => { - return ` - - - - Something went wrong!${ - UPSTREAM_API_ERRORS.includes(secondaryMessage) - ? "" - : " file an issue at https://tiny.one/readme-stats" - } - - ${encodeHTML(message)} - ${secondaryMessage} - - - `; -}; - /** * Auto layout utility, allows us to layout things vertically or horizontally with * proper gaping. @@ -380,6 +325,81 @@ const getCardColors = ({ return { titleColor, iconColor, textColor, bgColor, borderColor, ringColor }; }; +// Script parameters. +const ERROR_CARD_LENGTH = 576.5; + +/** + * Encode string as HTML. + * + * @see https://stackoverflow.com/a/48073476/10629172 + * + * @param {string} str String to encode. + * @returns {string} Encoded string. + */ +const encodeHTML = (str) => { + return str + .replace(/[\u00A0-\u9999<>&](?!#)/gim, (i) => { + return "&#" + i.charCodeAt(0) + ";"; + }) + .replace(/\u0008/gim, ""); +}; + +const UPSTREAM_API_ERRORS = [ + TRY_AGAIN_LATER, + SECONDARY_ERROR_MESSAGES.MAX_RETRY, +]; + +/** + * Renders error message on the card. + * + * @param {string} message Main error message. + * @param {string} secondaryMessage The secondary error message. + * @param {object} options Function options. + * @returns {string} The SVG markup. + */ +const renderError = (message, secondaryMessage = "", options = {}) => { + const { + title_color, + text_color, + bg_color, + border_color, + theme = "default", + } = options; + + // returns theme based colors with proper overrides and defaults + const { titleColor, textColor, bgColor, borderColor } = getCardColors({ + title_color, + text_color, + icon_color: "", + bg_color, + border_color, + ring_color: "", + theme, + }); + + return ` + + + + Something went wrong!${ + UPSTREAM_API_ERRORS.includes(secondaryMessage) + ? "" + : " file an issue at https://tiny.one/readme-stats" + } + + ${encodeHTML(message)} + ${secondaryMessage} + + + `; +}; + /** * Split text over multiple lines based on the card width. *