Consolidate conjugation i18n strings (#11660)
This commit is contained in:
parent
f841757906
commit
0f59298f30
59 changed files with 371 additions and 283 deletions
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
import { ReactElement, ReactNode } from "react";
|
||||
import { useIdColorHash } from "@vector-im/compound-web";
|
||||
|
||||
import { _t, getCurrentLanguage } from "../languageHandler";
|
||||
import { _t, getCurrentLanguage, getUserLanguage } from "../languageHandler";
|
||||
import { jsxJoin } from "./ReactUtils";
|
||||
const locale = getCurrentLanguage();
|
||||
|
||||
|
@ -92,34 +92,42 @@ export function getUserNameColorClass(userId: string): string {
|
|||
* @returns {string} a string constructed by joining `items` with a comma
|
||||
* between each item, but with the last item appended as " and [lastItem]".
|
||||
*/
|
||||
export function formatCommaSeparatedList(items: string[], itemLimit?: number): string;
|
||||
export function formatCommaSeparatedList(items: ReactElement[], itemLimit?: number): ReactElement;
|
||||
export function formatCommaSeparatedList(items: ReactNode[], itemLimit?: number): ReactNode;
|
||||
export function formatCommaSeparatedList(items: ReactNode[], itemLimit?: number): ReactNode {
|
||||
const remaining = itemLimit === undefined ? 0 : Math.max(items.length - itemLimit, 0);
|
||||
if (items.length === 0) {
|
||||
return "";
|
||||
} else if (items.length === 1) {
|
||||
return items[0];
|
||||
} else {
|
||||
let lastItem;
|
||||
if (remaining > 0) {
|
||||
items = items.slice(0, itemLimit);
|
||||
} else {
|
||||
lastItem = items.pop();
|
||||
export function formatList(items: string[], itemLimit?: number, includeCount?: boolean): string;
|
||||
export function formatList(items: ReactElement[], itemLimit?: number, includeCount?: boolean): ReactElement;
|
||||
export function formatList(items: ReactNode[], itemLimit?: number, includeCount?: boolean): ReactNode;
|
||||
export function formatList(items: ReactNode[], itemLimit = items.length, includeCount = false): ReactNode {
|
||||
let remaining = Math.max(items.length - itemLimit, 0);
|
||||
if (items.length <= 1) {
|
||||
return items[0] ?? "";
|
||||
}
|
||||
|
||||
const formatter = new Intl.ListFormat(getUserLanguage(), { style: "long", type: "conjunction" });
|
||||
if (remaining > 0) {
|
||||
if (includeCount) {
|
||||
itemLimit--;
|
||||
remaining++;
|
||||
}
|
||||
|
||||
let joinedItems;
|
||||
items = items.slice(0, itemLimit);
|
||||
let joinedItems: ReactNode;
|
||||
if (items.every((e) => typeof e === "string")) {
|
||||
joinedItems = items.join(", ");
|
||||
} else {
|
||||
joinedItems = jsxJoin(items, ", ");
|
||||
}
|
||||
|
||||
if (remaining > 0) {
|
||||
return _t("%(items)s and %(count)s others", { items: joinedItems, count: remaining });
|
||||
} else {
|
||||
return _t("%(items)s and %(lastItem)s", { items: joinedItems, lastItem });
|
||||
}
|
||||
return _t("<Items/> and %(count)s others", { count: remaining }, { Items: () => joinedItems });
|
||||
}
|
||||
|
||||
if (items.every((e) => typeof e === "string")) {
|
||||
return formatter.format(items as string[]);
|
||||
}
|
||||
|
||||
const parts = formatter.formatToParts(items.map((_, i) => `${i}`));
|
||||
return jsxJoin(
|
||||
parts.map((part) => {
|
||||
if (part.type === "literal") return part.value;
|
||||
return items[parseInt(part.value, 10)];
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue