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

Co-authored-by: Alexandr <qwerty541zxc@gmail.com>
This commit is contained in:
Alexandr Garbuzov
2025-10-14 21:11:23 +03:00
committed by GitHub
co-authored by Alexandr
parent b9c3bf6251
commit ab53e3052d
8 changed files with 50 additions and 51 deletions
+1 -2
View File
@@ -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.
+1 -2
View File
@@ -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,
+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.
*
@@ -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 };
-1
View File
@@ -15,7 +15,6 @@ export {
clampValue,
request,
flexLayout,
wrapTextMultiline,
logger,
measureText,
lowercaseTrim,
-37
View File
@@ -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,
+2 -1
View File
@@ -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();
+2 -1
View File
@@ -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.
+3 -6
View File
@@ -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);
});