diff --git a/src/cards/gist.js b/src/cards/gist.js index 3c3d059d..2deaf448 100644 --- a/src/cards/gist.js +++ b/src/cards/gist.js @@ -2,7 +2,6 @@ import { parseEmojis, - wrapTextMultiline, encodeHTML, measureText, flexLayout, @@ -11,7 +10,7 @@ import { } from "../common/utils.js"; import Card from "../common/Card.js"; import { getCardColors } from "../common/color.js"; -import { kFormatter } from "../common/fmt.js"; +import { kFormatter, wrapTextMultiline } from "../common/fmt.js"; import { icons } from "../common/icons.js"; /** Import language colors. diff --git a/src/cards/repo.js b/src/cards/repo.js index 6ebabeab..ccf42645 100644 --- a/src/cards/repo.js +++ b/src/cards/repo.js @@ -2,7 +2,7 @@ import { Card } from "../common/Card.js"; import { getCardColors } from "../common/color.js"; -import { kFormatter } from "../common/fmt.js"; +import { kFormatter, wrapTextMultiline } from "../common/fmt.js"; import { I18n } from "../common/I18n.js"; import { icons } from "../common/icons.js"; import { @@ -10,7 +10,6 @@ import { flexLayout, measureText, parseEmojis, - wrapTextMultiline, iconWithLabel, createLanguageNode, clampValue, diff --git a/src/common/fmt.js b/src/common/fmt.js index 2d40378a..ca86f3cf 100644 --- a/src/common/fmt.js +++ b/src/common/fmt.js @@ -1,3 +1,8 @@ +// @ts-check + +import wrap from "word-wrap"; +import { encodeHTML } from "./utils.js"; + /** * Retrieves num with suffix k(thousands) precise to given decimal places. * @@ -47,4 +52,39 @@ const formatBytes = (bytes) => { return `${(bytes / Math.pow(base, i)).toFixed(1)} ${sizes[i]}`; }; -export { kFormatter, formatBytes }; +/** + * Split text over multiple lines based on the card width. + * + * @param {string} text Text to split. + * @param {number} width Line width in number of characters. + * @param {number} maxLines Maximum number of lines. + * @returns {string[]} Array of lines. + */ +const wrapTextMultiline = (text, width = 59, maxLines = 3) => { + const fullWidthComma = ","; + const encoded = encodeHTML(text); + const isChinese = encoded.includes(fullWidthComma); + + let wrapped = []; + + if (isChinese) { + wrapped = encoded.split(fullWidthComma); // Chinese full punctuation + } else { + wrapped = wrap(encoded, { + width, + }).split("\n"); // Split wrapped lines to get an array of lines + } + + const lines = wrapped.map((line) => line.trim()).slice(0, maxLines); // Only consider maxLines lines + + // Add "..." to the last line if the text exceeds maxLines + if (wrapped.length > maxLines) { + lines[maxLines - 1] += "..."; + } + + // Remove empty lines if text fits in less than maxLines lines + const multiLineText = lines.filter(Boolean); + return multiLineText; +}; + +export { kFormatter, formatBytes, wrapTextMultiline }; diff --git a/src/common/index.js b/src/common/index.js index 93b50cc0..3a61fead 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -15,7 +15,6 @@ export { clampValue, request, flexLayout, - wrapTextMultiline, logger, measureText, lowercaseTrim, diff --git a/src/common/utils.js b/src/common/utils.js index 2d865998..6ce2741c 100644 --- a/src/common/utils.js +++ b/src/common/utils.js @@ -2,7 +2,6 @@ import axios from "axios"; import toEmoji from "emoji-name-map"; -import wrap from "word-wrap"; import { SECONDARY_ERROR_MESSAGES, TRY_AGAIN_LATER } from "./error.js"; import { getCardColors } from "./color.js"; @@ -234,41 +233,6 @@ const renderError = ({ `; }; -/** - * Split text over multiple lines based on the card width. - * - * @param {string} text Text to split. - * @param {number} width Line width in number of characters. - * @param {number} maxLines Maximum number of lines. - * @returns {string[]} Array of lines. - */ -const wrapTextMultiline = (text, width = 59, maxLines = 3) => { - const fullWidthComma = ","; - const encoded = encodeHTML(text); - const isChinese = encoded.includes(fullWidthComma); - - let wrapped = []; - - if (isChinese) { - wrapped = encoded.split(fullWidthComma); // Chinese full punctuation - } else { - wrapped = wrap(encoded, { - width, - }).split("\n"); // Split wrapped lines to get an array of lines - } - - const lines = wrapped.map((line) => line.trim()).slice(0, maxLines); // Only consider maxLines lines - - // Add "..." to the last line if the text exceeds maxLines - if (wrapped.length > maxLines) { - lines[maxLines - 1] += "..."; - } - - // Remove empty lines if text fits in less than maxLines lines - const multiLineText = lines.filter(Boolean); - return multiLineText; -}; - const noop = () => {}; // return console instance based on the environment const logger = @@ -388,7 +352,6 @@ export { clampValue, request, flexLayout, - wrapTextMultiline, logger, measureText, lowercaseTrim, diff --git a/src/fetchers/stats.js b/src/fetchers/stats.js index f22dfaf6..37ce591f 100644 --- a/src/fetchers/stats.js +++ b/src/fetchers/stats.js @@ -5,9 +5,10 @@ import * as dotenv from "dotenv"; import githubUsernameRegex from "github-username-regex"; import { calculateRank } from "../calculateRank.js"; import { retryer } from "../common/retryer.js"; -import { logger, request, wrapTextMultiline } from "../common/utils.js"; +import { logger, request } from "../common/utils.js"; import { excludeRepositories } from "../common/envs.js"; import { CustomError, MissingParamError } from "../common/error.js"; +import { wrapTextMultiline } from "../common/fmt.js"; dotenv.config(); diff --git a/src/fetchers/top-languages.js b/src/fetchers/top-languages.js index 9542678e..9e711b0d 100644 --- a/src/fetchers/top-languages.js +++ b/src/fetchers/top-languages.js @@ -1,9 +1,10 @@ // @ts-check import { retryer } from "../common/retryer.js"; -import { logger, request, wrapTextMultiline } from "../common/utils.js"; +import { logger, request } from "../common/utils.js"; import { excludeRepositories } from "../common/envs.js"; import { CustomError, MissingParamError } from "../common/error.js"; +import { wrapTextMultiline } from "../common/fmt.js"; /** * @typedef {import("axios").AxiosRequestHeaders} AxiosRequestHeaders Axios request headers. diff --git a/tests/utils.test.js b/tests/utils.test.js index 9be0ae2f..92b12f7c 100644 --- a/tests/utils.test.js +++ b/tests/utils.test.js @@ -3,12 +3,8 @@ import { describe, expect, it } from "@jest/globals"; import { queryByTestId } from "@testing-library/dom"; import "@testing-library/jest-dom"; -import { - encodeHTML, - parseBoolean, - renderError, - wrapTextMultiline, -} from "../src/common/utils.js"; +import { encodeHTML, parseBoolean, renderError } from "../src/common/utils.js"; +import { wrapTextMultiline } from "../src/common/fmt.js"; describe("Test utils.js", () => { it("should test parseBoolean", () => { @@ -25,6 +21,7 @@ describe("Test utils.js", () => { expect(parseBoolean("1")).toBe(undefined); expect(parseBoolean("0")).toBe(undefined); expect(parseBoolean("")).toBe(undefined); + // @ts-ignore expect(parseBoolean(undefined)).toBe(undefined); });