refactor: move wrap text multiline function into fmt module (#4572)

Co-authored-by: Alexandr <qwerty541zxc@gmail.com>
This commit is contained in:
Alexandr GarbuzovandAlexandr authored and GitHub committed 2025-10-14 21:11:23 +03:00
1 parent b9c3bf6251
commit ab53e3052d
8 files changed
+50 -51

No files matched your search

+1 -2
View File
@@ -2,7 +2,6 @@
import { import {
parseEmojis, parseEmojis,
wrapTextMultiline,
encodeHTML, encodeHTML,
measureText, measureText,
flexLayout, flexLayout,
@@ -11,7 +10,7 @@ import {
} from "../common/utils.js"; } from "../common/utils.js";
import Card from "../common/Card.js"; import Card from "../common/Card.js";
import { getCardColors } from "../common/color.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 { icons } from "../common/icons.js";
/** Import language colors. /** Import language colors.
+1 -2
View File
@@ -2,7 +2,7 @@
import { Card } from "../common/Card.js"; import { Card } from "../common/Card.js";
import { getCardColors } from "../common/color.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 { I18n } from "../common/I18n.js";
import { icons } from "../common/icons.js"; import { icons } from "../common/icons.js";
import { import {
@@ -10,7 +10,6 @@ import {
flexLayout, flexLayout,
measureText, measureText,
parseEmojis, parseEmojis,
wrapTextMultiline,
iconWithLabel, iconWithLabel,
createLanguageNode, createLanguageNode,
clampValue, clampValue,
+41 -1
View File
@@ -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. * 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]}`; 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 };
-1
View File
@@ -15,7 +15,6 @@ export {
clampValue, clampValue,
request, request,
flexLayout, flexLayout,
wrapTextMultiline,
logger, logger,
measureText, measureText,
lowercaseTrim, lowercaseTrim,
-37
View File
@@ -2,7 +2,6 @@
import axios from "axios"; import axios from "axios";
import toEmoji from "emoji-name-map"; import toEmoji from "emoji-name-map";
import wrap from "word-wrap";
import { SECONDARY_ERROR_MESSAGES, TRY_AGAIN_LATER } from "./error.js"; import { SECONDARY_ERROR_MESSAGES, TRY_AGAIN_LATER } from "./error.js";
import { getCardColors } from "./color.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 = () => {}; const noop = () => {};
// return console instance based on the environment // return console instance based on the environment
const logger = const logger =
@@ -388,7 +352,6 @@ export {
clampValue, clampValue,
request, request,
flexLayout, flexLayout,
wrapTextMultiline,
logger, logger,
measureText, measureText,
lowercaseTrim, lowercaseTrim,
+2 -1
View File
@@ -5,9 +5,10 @@ import * as dotenv from "dotenv";
import githubUsernameRegex from "github-username-regex"; import githubUsernameRegex from "github-username-regex";
import { calculateRank } from "../calculateRank.js"; import { calculateRank } from "../calculateRank.js";
import { retryer } from "../common/retryer.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 { excludeRepositories } from "../common/envs.js";
import { CustomError, MissingParamError } from "../common/error.js"; import { CustomError, MissingParamError } from "../common/error.js";
import { wrapTextMultiline } from "../common/fmt.js";
dotenv.config(); dotenv.config();
+2 -1
View File
@@ -1,9 +1,10 @@
// @ts-check // @ts-check
import { retryer } from "../common/retryer.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 { excludeRepositories } from "../common/envs.js";
import { CustomError, MissingParamError } from "../common/error.js"; import { CustomError, MissingParamError } from "../common/error.js";
import { wrapTextMultiline } from "../common/fmt.js";
/** /**
* @typedef {import("axios").AxiosRequestHeaders} AxiosRequestHeaders Axios request headers. * @typedef {import("axios").AxiosRequestHeaders} AxiosRequestHeaders Axios request headers.
+3 -6
View File
@@ -3,12 +3,8 @@
import { describe, expect, it } from "@jest/globals"; import { describe, expect, it } from "@jest/globals";
import { queryByTestId } from "@testing-library/dom"; import { queryByTestId } from "@testing-library/dom";
import "@testing-library/jest-dom"; import "@testing-library/jest-dom";
import { import { encodeHTML, parseBoolean, renderError } from "../src/common/utils.js";
encodeHTML, import { wrapTextMultiline } from "../src/common/fmt.js";
parseBoolean,
renderError,
wrapTextMultiline,
} from "../src/common/utils.js";
describe("Test utils.js", () => { describe("Test utils.js", () => {
it("should test parseBoolean", () => { it("should test parseBoolean", () => {
@@ -25,6 +21,7 @@ describe("Test utils.js", () => {
expect(parseBoolean("1")).toBe(undefined); expect(parseBoolean("1")).toBe(undefined);
expect(parseBoolean("0")).toBe(undefined); expect(parseBoolean("0")).toBe(undefined);
expect(parseBoolean("")).toBe(undefined); expect(parseBoolean("")).toBe(undefined);
// @ts-ignore
expect(parseBoolean(undefined)).toBe(undefined); expect(parseBoolean(undefined)).toBe(undefined);
}); });