refactor: jsdoc in utils & minor changes (#1377)

* refactor: jsdoc in utils & minor changes

* chore: jsdoc Card class

* chore: jsdoc for getStyles
This commit is contained in:
Anurag Hazra 2021-10-10 20:41:40 +05:30 committed by GitHub
parent d0ab2ff030
commit 02ebd3243b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 143 additions and 41 deletions

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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)
: ""
}

View file

@ -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<import('../common/utils').getCardColors>?=} 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 `
<svg

View file

@ -1,8 +1,14 @@
// @ts-check
const axios = require("axios");
const wrap = require("word-wrap");
const themes = require("../../themes");
const toEmoji = require("emoji-name-map");
/**
* @param {string} message
* @param {string} secondaryMessage
* @returns {string}
*/
const renderError = (message, secondaryMessage = "") => {
return `
<svg width="495" height="120" viewBox="0 0 495 120" fill="none" xmlns="http://www.w3.org/2000/svg">
@ -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();
/**

View file

@ -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,