Introduce Intl.ListFormat (#16857)

Co-authored-by: Steve Repsher <steverep@users.noreply.github.com>
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Simon Lamon 2023-06-13 15:22:23 +02:00 committed by GitHub
parent 49fa7ec4ed
commit 5fc4e7a95d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 86 additions and 69 deletions

View File

@ -17,6 +17,7 @@ const modules = {
"intl-datetimeformat": "DateTimeFormat",
"intl-numberformat": "NumberFormat",
"intl-displaynames": "DisplayNames",
"intl-listformat": "ListFormat",
};
gulp.task("create-locale-data", (done) => {

View File

@ -38,6 +38,7 @@
"@formatjs/intl-datetimeformat": "6.9.0",
"@formatjs/intl-displaynames": "6.4.0",
"@formatjs/intl-getcanonicallocales": "2.2.1",
"@formatjs/intl-listformat": "7.3.0",
"@formatjs/intl-locale": "3.3.1",
"@formatjs/intl-numberformat": "8.6.0",
"@formatjs/intl-pluralrules": "5.2.3",

View File

@ -21,6 +21,7 @@ import {
localizeDeviceAutomationTrigger,
} from "./device_automation";
import { EntityRegistryEntry } from "./entity_registry";
import "../resources/intl-polyfill";
import { FrontendLocaleData } from "./translation";
const describeDuration = (forTime: number | string | ForDict) => {
@ -82,6 +83,11 @@ export const describeTrigger = (
return trigger.alias;
}
const disjunctionFormatter = new Intl.ListFormat("en", {
style: "long",
type: "disjunction",
});
// Event Trigger
if (trigger.platform === "event" && trigger.event_type) {
let eventTypes = "";
@ -489,51 +495,43 @@ export const describeTrigger = (
// Zone Trigger
if (trigger.platform === "zone" && trigger.entity_id && trigger.zone) {
let entities = "";
let zones = "";
let zonesPlural = false;
const entities: string[] = [];
const zones: string[] = [];
const states = hass.states;
if (Array.isArray(trigger.entity_id)) {
for (const [index, entity] of trigger.entity_id.entries()) {
for (const [entity] of trigger.entity_id.entries()) {
if (states[entity]) {
entities += `${index > 0 ? "," : ""} ${
trigger.entity_id.length > 1 &&
index === trigger.entity_id.length - 1
? "or"
: ""
} ${computeStateName(states[entity]) || entity}`;
entities.push(`${computeStateName(states[entity]) || entity}`);
}
}
} else {
entities = states[trigger.entity_id]
? computeStateName(states[trigger.entity_id])
: trigger.entity_id;
entities.push(
states[trigger.entity_id]
? computeStateName(states[trigger.entity_id])
: trigger.entity_id
);
}
if (Array.isArray(trigger.zone)) {
if (trigger.zone.length > 1) {
zonesPlural = true;
}
for (const [index, zone] of trigger.zone.entries()) {
for (const [zone] of trigger.zone.entries()) {
if (states[zone]) {
zones += `${index > 0 ? "," : ""} ${
trigger.zone.length > 1 && index === trigger.zone.length - 1
? "or"
: ""
} ${computeStateName(states[zone]) || zone}`;
zones.push(`${computeStateName(states[zone]) || zone}`);
}
}
} else {
zones = states[trigger.zone]
? computeStateName(states[trigger.zone])
: trigger.zone;
zones.push(
states[trigger.zone]
? computeStateName(states[trigger.zone])
: trigger.zone
);
}
return `When ${entities} ${trigger.event}s ${zones} ${
zonesPlural ? "zones" : "zone"
const entitiesString = disjunctionFormatter.format(entities);
const zonesString = disjunctionFormatter.format(zones);
return `When ${entitiesString} ${trigger.event}s ${zonesString} ${
zones.length > 1 ? "zones" : "zone"
}`;
}
@ -636,6 +634,11 @@ export const describeCondition = (
return condition.alias;
}
const disjunctionFormatter = new Intl.ListFormat("en", {
style: "long",
type: "disjunction",
});
if (!condition.condition) {
const shorthands: Array<"and" | "or" | "not"> = ["and", "or", "not"];
for (const key of shorthands) {
@ -938,56 +941,44 @@ export const describeCondition = (
// Zone condition
if (condition.condition === "zone" && condition.entity_id && condition.zone) {
let entities = "";
let entitiesPlural = false;
let zones = "";
let zonesPlural = false;
const entities: string[] = [];
const zones: string[] = [];
const states = hass.states;
if (Array.isArray(condition.entity_id)) {
if (condition.entity_id.length > 1) {
entitiesPlural = true;
}
for (const [index, entity] of condition.entity_id.entries()) {
for (const [entity] of condition.entity_id.entries()) {
if (states[entity]) {
entities += `${index > 0 ? "," : ""} ${
condition.entity_id.length > 1 &&
index === condition.entity_id.length - 1
? "or"
: ""
} ${computeStateName(states[entity]) || entity}`;
entities.push(`${computeStateName(states[entity]) || entity}`);
}
}
} else {
entities = states[condition.entity_id]
? computeStateName(states[condition.entity_id])
: condition.entity_id;
entities.push(
states[condition.entity_id]
? computeStateName(states[condition.entity_id])
: condition.entity_id
);
}
if (Array.isArray(condition.zone)) {
if (condition.zone.length > 1) {
zonesPlural = true;
}
for (const [index, zone] of condition.zone.entries()) {
for (const [zone] of condition.zone.entries()) {
if (states[zone]) {
zones += `${index > 0 ? "," : ""} ${
condition.zone.length > 1 && index === condition.zone.length - 1
? "or"
: ""
} ${computeStateName(states[zone]) || zone}`;
zones.push(`${computeStateName(states[zone]) || zone}`);
}
}
} else {
zones = states[condition.zone]
? computeStateName(states[condition.zone])
: condition.zone;
zones.push(
states[condition.zone]
? computeStateName(states[condition.zone])
: condition.zone
);
}
return `Confirm ${entities} ${entitiesPlural ? "are" : "is"} in ${zones} ${
zonesPlural ? "zones" : "zone"
}`;
const entitiesString = disjunctionFormatter.format(entities);
const zonesString = disjunctionFormatter.format(zones);
return `Confirm ${entitiesString} ${
entities.length > 1 ? "are" : "is"
} in ${zonesString} ${zones.length > 1 ? "zones" : "zone"}`;
}
if (condition.condition === "device") {

View File

@ -15,3 +15,5 @@ import "@formatjs/intl-datetimeformat/locale-data/en";
import "@formatjs/intl-datetimeformat/add-all-tz";
import "@formatjs/intl-displaynames/polyfill";
import "@formatjs/intl-displaynames/locale-data/en";
import "@formatjs/intl-listformat/polyfill";
import "@formatjs/intl-listformat/locale-data/en";

View File

@ -3,6 +3,7 @@ import { shouldPolyfill as shouldPolyfillDisplayName } from "@formatjs/intl-disp
import { shouldPolyfill as shouldPolyfillLocale } from "@formatjs/intl-locale/should-polyfill";
import { shouldPolyfill as shouldPolyfillPluralRules } from "@formatjs/intl-pluralrules/should-polyfill";
import { shouldPolyfill as shouldPolyfillRelativeTime } from "@formatjs/intl-relativetimeformat/should-polyfill";
import { shouldPolyfill as shouldPolyfillListFormat } from "@formatjs/intl-listformat/should-polyfill";
import { getLocalLanguage } from "../util/common-translation";
import { polyfillLocaleData } from "./locale-data-polyfill";
@ -29,6 +30,9 @@ const polyfillIntl = async () => {
if (shouldPolyfillDisplayName(locale)) {
polyfills.push(import("@formatjs/intl-displaynames/polyfill-force"));
}
if (shouldPolyfillListFormat(locale)) {
polyfills.push(import("@formatjs/intl-listformat/polyfill-force"));
}
if (polyfills.length === 0) {
return;
}

View File

@ -53,6 +53,17 @@ export const polyfillLocaleData = async (language: string) => {
// @ts-ignore
Intl.DisplayNames.__addLocaleData(await result.json());
}
if (
Intl.ListFormat &&
// @ts-ignore
typeof Intl.ListFormat.__addLocaleData === "function"
) {
const result = await fetch(
`${__STATIC_PATH__}locale-data/intl-listformat/${language}.json`
);
// @ts-ignore
Intl.ListFormat.__addLocaleData(await result.json());
}
} catch (e) {
// Ignore
}

View File

@ -1,13 +1,8 @@
{
"compilerOptions": {
// Language Options
"target": "ES2017",
"lib": [
"ES2017",
"DOM",
"DOM.Iterable",
"WebWorker"
],
"target": "ES2021",
"lib": ["ES2021", "DOM", "DOM.Iterable", "WebWorker"],
"experimentalDecorators": true,
// Modules
"module": "ESNext",
@ -43,4 +38,4 @@
}
]
}
}
}

View File

@ -1669,6 +1669,17 @@ __metadata:
languageName: node
linkType: hard
"@formatjs/intl-listformat@npm:7.3.0":
version: 7.3.0
resolution: "@formatjs/intl-listformat@npm:7.3.0"
dependencies:
"@formatjs/ecma402-abstract": 1.16.0
"@formatjs/intl-localematcher": 0.3.0
tslib: ^2.4.0
checksum: 6638e6a3cad750ac5199cf293c549c4048f0de240762dd98c61cece645091f19262ef64c1fb2f7a44b5bb3e5c168a8f53e9aa604b4867290981c30baf8635c0d
languageName: node
linkType: hard
"@formatjs/intl-locale@npm:3.3.1":
version: 3.3.1
resolution: "@formatjs/intl-locale@npm:3.3.1"
@ -9620,6 +9631,7 @@ __metadata:
"@formatjs/intl-datetimeformat": 6.9.0
"@formatjs/intl-displaynames": 6.4.0
"@formatjs/intl-getcanonicallocales": 2.2.1
"@formatjs/intl-listformat": 7.3.0
"@formatjs/intl-locale": 3.3.1
"@formatjs/intl-numberformat": 8.6.0
"@formatjs/intl-pluralrules": 5.2.3