Draw the mockup with the screens' own words, compile every text while building, and send the language with the live updates

- 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>
This commit is contained in:
Max Gramser
2026-09-19 14:59:02 +02:00
parent 1dc2eab0cf
commit 94b320074d
34 changed files with 2491 additions and 292 deletions
+4 -1
View File
@@ -1,10 +1,11 @@
// Language & region (app 0.2.90): one place for every screen's language, clock and numbers, the update it takes, and
// the top bar that points there.
import { flushPromises, mount } from "@vue/test-utils";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import AppSettingsView from "../src/components/AppSettingsView.vue";
import Sidebar from "../src/components/Sidebar.vue";
import TopbarInspector from "../src/components/TopbarInspector.vue";
import { loadLanguage } from "../src/i18n";
import { state } from "../src/store";
import type { Languages } from "../src/types";
@@ -33,6 +34,8 @@ function addOn(answer: (body: any) => Response) {
}
const options = (view: ReturnType<typeof mount>, id: string) => view.findAll(`#${id} option`).map((o) => o.text());
// The screens' language here is Dutch: its own number marks come with its file.
beforeAll(() => loadLanguage("nl"));
beforeEach(() => {
vi.unstubAllGlobals();
state.inventory = { screens: [], entities: [], updates: { target: "0.2.80", pending: 0 }, language: language() } as any;