94b320074d
- The page takes the screens' words its mockup draws from their own texts: screen.ha (Home Assistant's words, filled from Home Assistant), screen.time, screen.date, screen.number and screen.tile.page, per language next to _meta and editor. The copies under editor.mockup go; the rest of `screen` and all of `addon` stay out of the build. - Numbers in the mockup follow the screens' language (screen.number, with its minimum grouping) or the chosen style, as the firmware writes them. - @intlify/unplugin-vue-i18n compiles every text at build time, so the page runs vue-i18n's runtime-only build without the message compiler; every language's _meta comes with the page. Empty texts stay out while building. - The live updates carry the editor's language (api/events?language=), as an EventSource sends no headers. - web/ needs Node 22.13 or newer: vue-i18n 11.4, Vite 7 and the unplugin ask for it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
26 lines
1.7 KiB
TypeScript
26 lines
1.7 KiB
TypeScript
// What the page takes from the translations (app 0.2.90), for vite.config.ts and the tests. Every language is one file
|
|
// in screen_manager/translations, shared with the firmware and the add-on.
|
|
import { join } from "node:path";
|
|
|
|
export const TRANSLATIONS = join(__dirname, "..", "screen_manager", "translations");
|
|
// Of the screens' texts the page takes the ones its mockup draws: Home Assistant's words, times, dates, numbers and the
|
|
// page label. The rest of `screen` and all of `addon` stay out.
|
|
const SCREEN_PARTS = ["ha", "time", "date", "number"];
|
|
|
|
// An empty text is one the language doesn't have yet: it stays out, so English shows, as on the screens. A space is
|
|
// a text (French writes 1 234,5).
|
|
function filled(node: unknown): unknown {
|
|
if (typeof node === "string") return node === "" ? undefined : node;
|
|
if (Array.isArray(node)) return node.every((item) => typeof item === "string" && item !== "") ? node : undefined;
|
|
if (!node || typeof node !== "object") return undefined;
|
|
const kept = Object.entries(node).map(([key, value]) => [key, filled(value)]).filter(([, value]) => value !== undefined);
|
|
return kept.length ? Object.fromEntries(kept) : undefined;
|
|
}
|
|
/** The part of a language's file the page takes: the editor's texts and the screens' words its mockup draws. */
|
|
export function pageTexts(data: any) {
|
|
const screen = data?.screen || {};
|
|
const words: Record<string, unknown> = Object.fromEntries(SCREEN_PARTS.filter((part) => part in screen).map((part) => [part, screen[part]]));
|
|
if (screen.tile?.page !== undefined) words.tile = { page: screen.tile.page };
|
|
return (filled({ editor: data?.editor, screen: words }) || {}) as Record<string, unknown>;
|
|
}
|