Weekdays that fit the weather columns, the top bar's own abbreviation, tile texts that fit, and a check that measures them
- The CYD's weather columns hold two letters beside the icon: every language has its own two-letter days (the CLDR's short width, Polish nd pn wt); French mar became nar there. check fails on a longer one. - The top bar takes the language's abbreviation (sam. 19 sept., Sa., 19. Sept.), English keeps Sa 19 Sep. - The editor's clock and date follow the screens: 7:05 PM in the top bar, 7:05 on the clock card. - A long weather word ends in an ellipsis before the days. - Tile lines that were cut on a screen are shorter (Zum Öffnen, Ouvrir, Otwórz, Sin imagen, ...); check measures them with the screens' font against the tile width of both boards. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,7 @@ import type { HeaderItem } from "../types";
|
||||
const query = ref("");
|
||||
const taken = computed(() => new Set(topbarItems().map(itemKey)));
|
||||
const samples = computed(() => ({
|
||||
clock: clockText(clock24.value, new Date(state.now)),
|
||||
clock: clockText(clock24.value, new Date(state.now), screenLanguage.value),
|
||||
analog: t("editor.topbar.analog_sample"),
|
||||
date: dateText(new Date(state.now), screenLanguage.value),
|
||||
} as Record<string, string>));
|
||||
|
||||
@@ -51,7 +51,7 @@ const liveNote = computed(() => {
|
||||
return !view.shown ? t("editor.topbar.live.hidden") : overflow.value.has(props.index) ? t("editor.topbar.live.overflow") : t("editor.topbar.live.looks");
|
||||
});
|
||||
const samples = computed(() => ({
|
||||
clock: clockText(clock24.value, new Date(state.now)),
|
||||
clock: clockText(clock24.value, new Date(state.now), screenLanguage.value),
|
||||
analog: t("editor.topbar.analog_sample"),
|
||||
date: dateText(new Date(state.now), screenLanguage.value),
|
||||
} as Record<string, string>));
|
||||
|
||||
+10
-6
@@ -12,14 +12,18 @@ export const BUILTIN_ICONS: Record<string, string> = { clock: "clock-outline", a
|
||||
export const itemKey = (item: HeaderItem) => JSON.stringify(item);
|
||||
export const glyph = (cp: string) => String.fromCodePoint(parseInt(cp, 16));
|
||||
|
||||
export function clockText(clock24: boolean, now = new Date()) {
|
||||
let hours = now.getHours();
|
||||
// The screen formats with %I:%M when the 24-hour clock is off.
|
||||
if (!clock24) hours = hours % 12 || 12;
|
||||
return `${String(hours).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`;
|
||||
// The time as the screens write it (screen_text::clock_text): "07:12" on 24 hours; on 12 "7:12 PM" in the top bar, with
|
||||
// the language's day periods, and "7:12" in the clock card's big digits, which have no letters.
|
||||
export function clockText(clock24: boolean, now = new Date(), locale?: string) {
|
||||
const minutes = String(now.getMinutes()).padStart(2, "0");
|
||||
if (clock24) return `${String(now.getHours()).padStart(2, "0")}:${minutes}`;
|
||||
const time = `${now.getHours() % 12 || 12}:${minutes}`;
|
||||
return locale ? `${time} ${t(`screen.time.${now.getHours() < 12 ? "am" : "pm"}`, {}, { locale })}` : time;
|
||||
}
|
||||
// "Sa 19 Sep", "za 19 sep", "sam. 19 sept.": the language's pattern with its abbreviation or its two letters.
|
||||
export const dateText = (now = new Date(), locale = "en") => t("screen.date.top_bar", {
|
||||
weekday: t(`screen.date.weekdays_min.${now.getDay()}`, {}, { locale }),
|
||||
weekday: t(`screen.date.weekdays_short.${now.getDay()}`, {}, { locale }),
|
||||
weekday_min: t(`screen.date.weekdays_min.${now.getDay()}`, {}, { locale }),
|
||||
day: now.getDate(),
|
||||
month: t(`screen.date.months_short.${now.getMonth()}`, {}, { locale }),
|
||||
}, { locale });
|
||||
|
||||
+1
-1
@@ -583,7 +583,7 @@ export function topbarLabel(item: HeaderItem) {
|
||||
// What the item shows right now: { icon, text, color, shown }. Entities wait for the add-on's preview.
|
||||
export function topbarView(item: HeaderItem): ItemView {
|
||||
const now = new Date(state.now);
|
||||
if (item.type === "clock") return { text: clockText(clock24.value, now), shown: true };
|
||||
if (item.type === "clock") return { text: clockText(clock24.value, now, screenLanguage.value), shown: true };
|
||||
if (item.type === "date") return { text: dateText(now, screenLanguage.value), shown: true };
|
||||
if (item.type === "analog") return { analog: true, shown: true };
|
||||
const p = state.topbarPreviews[itemKey(item)];
|
||||
|
||||
@@ -175,7 +175,8 @@ describe("the mockup speaks the screens' language", () => {
|
||||
ha: { unavailable: "Nicht verfügbar", on: "An", weather: { windy: "Windig" }, binary: { door_on: "Offen" }, button: { run: "Ausführen" } },
|
||||
tile: { page: "Seite {n}" },
|
||||
time: { hours_ago: "Vor 1 Stunde | Vor {n} Stunden", just_now: "Gerade eben" },
|
||||
date: { weekdays_min: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], months_short: ["Jan.", "Feb.", "März", "Apr.", "Mai", "Juni", "Juli", "Aug.", "Sept.", "Okt.", "Nov.", "Dez."], top_bar: "{weekday}., {day}. {month}" },
|
||||
date: { weekdays_min: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], weekdays_short: ["So.", "Mo.", "Di.", "Mi.", "Do.", "Fr.", "Sa."],
|
||||
months_short: ["Jan.", "Feb.", "März", "Apr.", "Mai", "Juni", "Juli", "Aug.", "Sept.", "Okt.", "Nov.", "Dez."], top_bar: "{weekday}, {day}. {month}" },
|
||||
number: { decimal: ",", group: ".", group_min: "2" },
|
||||
},
|
||||
}, meta("one_other"));
|
||||
|
||||
@@ -28,8 +28,13 @@ describe("clock and date", () => {
|
||||
const evening = new Date(2026, 8, 15, 19, 5);
|
||||
it("formats the clock the way the screen does", () => {
|
||||
expect(clockText(true, evening)).toBe("19:05");
|
||||
expect(clockText(false, evening)).toBe("07:05");
|
||||
// The clock card's big digits: no leading zero, no day period (its font has no letters).
|
||||
expect(clockText(false, evening)).toBe("7:05");
|
||||
expect(clockText(false, new Date(2026, 8, 15, 0, 30))).toBe("12:30");
|
||||
// The top bar: with the language's day period, as screen_text::clock_text writes it.
|
||||
expect(clockText(false, evening, "en")).toBe("7:05 PM");
|
||||
expect(clockText(false, new Date(2026, 8, 15, 0, 30), "en")).toBe("12:30 AM");
|
||||
expect(clockText(true, evening, "en")).toBe("19:05");
|
||||
});
|
||||
it("writes the date short", () => {
|
||||
expect(dateText(evening)).toBe("Tu 15 Sep");
|
||||
|
||||
Reference in New Issue
Block a user