UNPKG

matrix-react-sdk

Version:
129 lines (118 loc) 15.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.formatBytes = formatBytes; exports.formatCount = formatCount; exports.formatCountLong = formatCountLong; exports.formatCryptoKey = formatCryptoKey; exports.formatList = formatList; exports.getUserNameColorClass = getUserNameColorClass; var _compoundWeb = require("@vector-im/compound-web"); var _languageHandler = require("../languageHandler"); var _ReactUtils = require("./ReactUtils"); /* Copyright 2024 New Vector Ltd. Copyright 2019, 2020 The Matrix.org Foundation C.I.C. Copyright 2016 OpenMarket Ltd SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ const locale = (0, _languageHandler.getCurrentLanguage)(); // It's quite costly to instanciate `Intl.NumberFormat`, hence why we do not do // it in every function call const compactFormatter = new Intl.NumberFormat(locale, { notation: "compact" }); /** * formats and rounds numbers to fit into ~3 characters, suitable for badge counts * e.g: 999, 10K, 99K, 1M, 10M, 99M, 1B, 10B, ... */ function formatCount(count) { return compactFormatter.format(count); } // It's quite costly to instanciate `Intl.NumberFormat`, hence why we do not do // it in every function call const formatter = new Intl.NumberFormat(locale); /** * Format a count showing the whole number but making it a bit more readable. * e.g: 1000 => 1,000 */ function formatCountLong(count) { return formatter.format(count); } /** * format a size in bytes into a human readable form * e.g: 1024 -> 1.00 KB */ function formatBytes(bytes, decimals = 2) { if (bytes === 0) return "0 Bytes"; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; } /** * format a key into groups of 4 characters, for easier visual inspection * * @param {string} key key to format * * @return {string} */ function formatCryptoKey(key) { return key.match(/.{1,4}/g).join(" "); } function getUserNameColorClass(userId) { // eslint-disable-next-line react-hooks/rules-of-hooks const number = (0, _compoundWeb.useIdColorHash)(userId); return `mx_Username_color${number}`; } /** * Constructs a written English string representing `items`, with an optional * limit on the number of items included in the result. If specified and if the * length of `items` is greater than the limit, the string "and n others" will * be appended onto the result. If `items` is empty, returns the empty string. * If there is only one item, return it. * @param {string[]} items the items to construct a string from. * @param {number?} itemLimit the number by which to limit the list. * @returns {string} a string constructed by joining `items` with a comma * between each item, but with the last item appended as " and [lastItem]". */ function formatList(items, itemLimit = items.length, includeCount = false) { let remaining = Math.max(items.length - itemLimit, 0); if (items.length <= 1) { return items[0] ?? ""; } const formatter = new Intl.ListFormat((0, _languageHandler.getUserLanguage)(), { style: "long", type: "conjunction" }); if (remaining > 0) { if (includeCount) { itemLimit--; remaining++; } items = items.slice(0, itemLimit); let joinedItems; if (items.every(e => typeof e === "string")) { joinedItems = items.join(", "); } else { joinedItems = (0, _ReactUtils.jsxJoin)(items, ", "); } return (0, _languageHandler._t)("items_and_n_others", { count: remaining }, { Items: () => joinedItems }); } if (items.every(e => typeof e === "string")) { return formatter.format(items); } const parts = formatter.formatToParts(items.map((_, i) => `${i}`)); return (0, _ReactUtils.jsxJoin)(parts.map(part => { if (part.type === "literal") return part.value; return items[parseInt(part.value, 10)]; })); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29tcG91bmRXZWIiLCJyZXF1aXJlIiwiX2xhbmd1YWdlSGFuZGxlciIsIl9SZWFjdFV0aWxzIiwibG9jYWxlIiwiZ2V0Q3VycmVudExhbmd1YWdlIiwiY29tcGFjdEZvcm1hdHRlciIsIkludGwiLCJOdW1iZXJGb3JtYXQiLCJub3RhdGlvbiIsImZvcm1hdENvdW50IiwiY291bnQiLCJmb3JtYXQiLCJmb3JtYXR0ZXIiLCJmb3JtYXRDb3VudExvbmciLCJmb3JtYXRCeXRlcyIsImJ5dGVzIiwiZGVjaW1hbHMiLCJrIiwiZG0iLCJzaXplcyIsImkiLCJNYXRoIiwiZmxvb3IiLCJsb2ciLCJwYXJzZUZsb2F0IiwicG93IiwidG9GaXhlZCIsImZvcm1hdENyeXB0b0tleSIsImtleSIsIm1hdGNoIiwiam9pbiIsImdldFVzZXJOYW1lQ29sb3JDbGFzcyIsInVzZXJJZCIsIm51bWJlciIsInVzZUlkQ29sb3JIYXNoIiwiZm9ybWF0TGlzdCIsIml0ZW1zIiwiaXRlbUxpbWl0IiwibGVuZ3RoIiwiaW5jbHVkZUNvdW50IiwicmVtYWluaW5nIiwibWF4IiwiTGlzdEZvcm1hdCIsImdldFVzZXJMYW5ndWFnZSIsInN0eWxlIiwidHlwZSIsInNsaWNlIiwiam9pbmVkSXRlbXMiLCJldmVyeSIsImUiLCJqc3hKb2luIiwiX3QiLCJJdGVtcyIsInBhcnRzIiwiZm9ybWF0VG9QYXJ0cyIsIm1hcCIsIl8iLCJwYXJ0IiwidmFsdWUiLCJwYXJzZUludCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9Gb3JtYXR0aW5nVXRpbHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMTksIDIwMjAgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cbkNvcHlyaWdodCAyMDE2IE9wZW5NYXJrZXQgTHRkXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCB7IFJlYWN0RWxlbWVudCwgUmVhY3ROb2RlIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VJZENvbG9ySGFzaCB9IGZyb20gXCJAdmVjdG9yLWltL2NvbXBvdW5kLXdlYlwiO1xuXG5pbXBvcnQgeyBfdCwgZ2V0Q3VycmVudExhbmd1YWdlLCBnZXRVc2VyTGFuZ3VhZ2UgfSBmcm9tIFwiLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgeyBqc3hKb2luIH0gZnJvbSBcIi4vUmVhY3RVdGlsc1wiO1xuY29uc3QgbG9jYWxlID0gZ2V0Q3VycmVudExhbmd1YWdlKCk7XG5cbi8vIEl0J3MgcXVpdGUgY29zdGx5IHRvIGluc3RhbmNpYXRlIGBJbnRsLk51bWJlckZvcm1hdGAsIGhlbmNlIHdoeSB3ZSBkbyBub3QgZG9cbi8vIGl0IGluIGV2ZXJ5IGZ1bmN0aW9uIGNhbGxcbmNvbnN0IGNvbXBhY3RGb3JtYXR0ZXIgPSBuZXcgSW50bC5OdW1iZXJGb3JtYXQobG9jYWxlLCB7XG4gICAgbm90YXRpb246IFwiY29tcGFjdFwiLFxufSk7XG5cbi8qKlxuICogZm9ybWF0cyBhbmQgcm91bmRzIG51bWJlcnMgdG8gZml0IGludG8gfjMgY2hhcmFjdGVycywgc3VpdGFibGUgZm9yIGJhZGdlIGNvdW50c1xuICogZS5nOiA5OTksIDEwSywgOTlLLCAxTSwgMTBNLCA5OU0sIDFCLCAxMEIsIC4uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0Q291bnQoY291bnQ6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNvbXBhY3RGb3JtYXR0ZXIuZm9ybWF0KGNvdW50KTtcbn1cblxuLy8gSXQncyBxdWl0ZSBjb3N0bHkgdG8gaW5zdGFuY2lhdGUgYEludGwuTnVtYmVyRm9ybWF0YCwgaGVuY2Ugd2h5IHdlIGRvIG5vdCBkb1xuLy8gaXQgaW4gZXZlcnkgZnVuY3Rpb24gY2FsbFxuY29uc3QgZm9ybWF0dGVyID0gbmV3IEludGwuTnVtYmVyRm9ybWF0KGxvY2FsZSk7XG5cbi8qKlxuICogRm9ybWF0IGEgY291bnQgc2hvd2luZyB0aGUgd2hvbGUgbnVtYmVyIGJ1dCBtYWtpbmcgaXQgYSBiaXQgbW9yZSByZWFkYWJsZS5cbiAqIGUuZzogMTAwMCA9PiAxLDAwMFxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0Q291bnRMb25nKGNvdW50OiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBmb3JtYXR0ZXIuZm9ybWF0KGNvdW50KTtcbn1cblxuLyoqXG4gKiBmb3JtYXQgYSBzaXplIGluIGJ5dGVzIGludG8gYSBodW1hbiByZWFkYWJsZSBmb3JtXG4gKiBlLmc6IDEwMjQgLT4gMS4wMCBLQlxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0Qnl0ZXMoYnl0ZXM6IG51bWJlciwgZGVjaW1hbHMgPSAyKTogc3RyaW5nIHtcbiAgICBpZiAoYnl0ZXMgPT09IDApIHJldHVybiBcIjAgQnl0ZXNcIjtcblxuICAgIGNvbnN0IGsgPSAxMDI0O1xuICAgIGNvbnN0IGRtID0gZGVjaW1hbHMgPCAwID8gMCA6IGRlY2ltYWxzO1xuICAgIGNvbnN0IHNpemVzID0gW1wiQnl0ZXNcIiwgXCJLQlwiLCBcIk1CXCIsIFwiR0JcIiwgXCJUQlwiLCBcIlBCXCIsIFwiRUJcIiwgXCJaQlwiLCBcIllCXCJdO1xuXG4gICAgY29uc3QgaSA9IE1hdGguZmxvb3IoTWF0aC5sb2coYnl0ZXMpIC8gTWF0aC5sb2coaykpO1xuXG4gICAgcmV0dXJuIHBhcnNlRmxvYXQoKGJ5dGVzIC8gTWF0aC5wb3coaywgaSkpLnRvRml4ZWQoZG0pKSArIFwiIFwiICsgc2l6ZXNbaV07XG59XG5cbi8qKlxuICogZm9ybWF0IGEga2V5IGludG8gZ3JvdXBzIG9mIDQgY2hhcmFjdGVycywgZm9yIGVhc2llciB2aXN1YWwgaW5zcGVjdGlvblxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkga2V5IHRvIGZvcm1hdFxuICpcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdENyeXB0b0tleShrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGtleS5tYXRjaCgvLnsxLDR9L2cpIS5qb2luKFwiIFwiKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFVzZXJOYW1lQ29sb3JDbGFzcyh1c2VySWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL3J1bGVzLW9mLWhvb2tzXG4gICAgY29uc3QgbnVtYmVyID0gdXNlSWRDb2xvckhhc2godXNlcklkKTtcbiAgICByZXR1cm4gYG14X1VzZXJuYW1lX2NvbG9yJHtudW1iZXJ9YDtcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3RzIGEgd3JpdHRlbiBFbmdsaXNoIHN0cmluZyByZXByZXNlbnRpbmcgYGl0ZW1zYCwgd2l0aCBhbiBvcHRpb25hbFxuICogbGltaXQgb24gdGhlIG51bWJlciBvZiBpdGVtcyBpbmNsdWRlZCBpbiB0aGUgcmVzdWx0LiBJZiBzcGVjaWZpZWQgYW5kIGlmIHRoZVxuICogbGVuZ3RoIG9mIGBpdGVtc2AgaXMgZ3JlYXRlciB0aGFuIHRoZSBsaW1pdCwgdGhlIHN0cmluZyBcImFuZCBuIG90aGVyc1wiIHdpbGxcbiAqIGJlIGFwcGVuZGVkIG9udG8gdGhlIHJlc3VsdC4gSWYgYGl0ZW1zYCBpcyBlbXB0eSwgcmV0dXJucyB0aGUgZW1wdHkgc3RyaW5nLlxuICogSWYgdGhlcmUgaXMgb25seSBvbmUgaXRlbSwgcmV0dXJuIGl0LlxuICogQHBhcmFtIHtzdHJpbmdbXX0gaXRlbXMgdGhlIGl0ZW1zIHRvIGNvbnN0cnVjdCBhIHN0cmluZyBmcm9tLlxuICogQHBhcmFtIHtudW1iZXI/fSBpdGVtTGltaXQgdGhlIG51bWJlciBieSB3aGljaCB0byBsaW1pdCB0aGUgbGlzdC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IGEgc3RyaW5nIGNvbnN0cnVjdGVkIGJ5IGpvaW5pbmcgYGl0ZW1zYCB3aXRoIGEgY29tbWFcbiAqIGJldHdlZW4gZWFjaCBpdGVtLCBidXQgd2l0aCB0aGUgbGFzdCBpdGVtIGFwcGVuZGVkIGFzIFwiIGFuZCBbbGFzdEl0ZW1dXCIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRMaXN0KGl0ZW1zOiBzdHJpbmdbXSwgaXRlbUxpbWl0PzogbnVtYmVyLCBpbmNsdWRlQ291bnQ/OiBib29sZWFuKTogc3RyaW5nO1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdExpc3QoaXRlbXM6IFJlYWN0RWxlbWVudFtdLCBpdGVtTGltaXQ/OiBudW1iZXIsIGluY2x1ZGVDb3VudD86IGJvb2xlYW4pOiBSZWFjdEVsZW1lbnQ7XG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0TGlzdChpdGVtczogUmVhY3ROb2RlW10sIGl0ZW1MaW1pdD86IG51bWJlciwgaW5jbHVkZUNvdW50PzogYm9vbGVhbik6IFJlYWN0Tm9kZTtcbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRMaXN0KGl0ZW1zOiBSZWFjdE5vZGVbXSwgaXRlbUxpbWl0ID0gaXRlbXMubGVuZ3RoLCBpbmNsdWRlQ291bnQgPSBmYWxzZSk6IFJlYWN0Tm9kZSB7XG4gICAgbGV0IHJlbWFpbmluZyA9IE1hdGgubWF4KGl0ZW1zLmxlbmd0aCAtIGl0ZW1MaW1pdCwgMCk7XG4gICAgaWYgKGl0ZW1zLmxlbmd0aCA8PSAxKSB7XG4gICAgICAgIHJldHVybiBpdGVtc1swXSA/PyBcIlwiO1xuICAgIH1cblxuICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBJbnRsLkxpc3RGb3JtYXQoZ2V0VXNlckxhbmd1YWdlKCksIHsgc3R5bGU6IFwibG9uZ1wiLCB0eXBlOiBcImNvbmp1bmN0aW9uXCIgfSk7XG4gICAgaWYgKHJlbWFpbmluZyA+IDApIHtcbiAgICAgICAgaWYgKGluY2x1ZGVDb3VudCkge1xuICAgICAgICAgICAgaXRlbUxpbWl0LS07XG4gICAgICAgICAgICByZW1haW5pbmcrKztcbiAgICAgICAgfVxuXG4gICAgICAgIGl0ZW1zID0gaXRlbXMuc2xpY2UoMCwgaXRlbUxpbWl0KTtcbiAgICAgICAgbGV0IGpvaW5lZEl0ZW1zOiBSZWFjdE5vZGU7XG4gICAgICAgIGlmIChpdGVtcy5ldmVyeSgoZSkgPT4gdHlwZW9mIGUgPT09IFwic3RyaW5nXCIpKSB7XG4gICAgICAgICAgICBqb2luZWRJdGVtcyA9IGl0ZW1zLmpvaW4oXCIsIFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGpvaW5lZEl0ZW1zID0ganN4Sm9pbihpdGVtcywgXCIsIFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBfdChcIml0ZW1zX2FuZF9uX290aGVyc1wiLCB7IGNvdW50OiByZW1haW5pbmcgfSwgeyBJdGVtczogKCkgPT4gam9pbmVkSXRlbXMgfSk7XG4gICAgfVxuXG4gICAgaWYgKGl0ZW1zLmV2ZXJ5KChlKSA9PiB0eXBlb2YgZSA9PT0gXCJzdHJpbmdcIikpIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdHRlci5mb3JtYXQoaXRlbXMgYXMgc3RyaW5nW10pO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcnRzID0gZm9ybWF0dGVyLmZvcm1hdFRvUGFydHMoaXRlbXMubWFwKChfLCBpKSA9PiBgJHtpfWApKTtcbiAgICByZXR1cm4ganN4Sm9pbihcbiAgICAgICAgcGFydHMubWFwKChwYXJ0KSA9PiB7XG4gICAgICAgICAgICBpZiAocGFydC50eXBlID09PSBcImxpdGVyYWxcIikgcmV0dXJuIHBhcnQudmFsdWU7XG4gICAgICAgICAgICByZXR1cm4gaXRlbXNbcGFyc2VJbnQocGFydC52YWx1ZSwgMTApXTtcbiAgICAgICAgfSksXG4gICAgKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFVQSxJQUFBQSxZQUFBLEdBQUFDLE9BQUE7QUFFQSxJQUFBQyxnQkFBQSxHQUFBRCxPQUFBO0FBQ0EsSUFBQUUsV0FBQSxHQUFBRixPQUFBO0FBYkE7QUFDQTtB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