Commit graph

3 commits

Author SHA1 Message Date
screentinker 0511e9b5bb
Let a locale ship without every string translated (#286)
Follow-up to #285. Three corrections that rode in with the Japanese locale.

1. The ja key-parity check failed the build whenever en.js had a key ja.js
   lacked. i18n.js lookup() is already
   `registry[lang]?.[key] ?? fallback[key] ?? key`, so an untranslated string
   renders in English and nothing is broken by a gap - the only effect was
   that adding any English string blocked CI until a Japanese translation
   existed. It also singled out one locale; es/fr/de/pt/hi/it were never held
   to it, and hi.js is a deliberate skeleton whose own header explains that
   every key falls back to English on purpose.

   Replaced with two checks over EVERY locale: a locale may not define a key
   that English does not (dead weight after a rename, and fixable by whoever
   touched the file, whatever language they speak), and coverage is printed
   rather than gated. Help tips still have to exist everywhere - that test is
   unchanged and still fails.

   Current coverage: ja 100%, es 65.5%, fr/de/pt 63.7%, it 59.5%, hi 0%.

2. Applying the strict half to all locales immediately found
   add_display.smart_tv_note living in fr, pt, it and de but not in en.js and
   referenced by no view - a string dropped from English that left four
   translations behind. Removed.

3. The new timezone test restored process.env.TZ by assigning the saved value
   back. When TZ was not set to begin with - which is the case in CI - that
   assigns undefined, which writes the STRING "undefined"; Node cannot parse
   it and silently falls back to UTC for the rest of the process. Every test
   after it in that file is date arithmetic. It now deletes the key when it
   was previously unset.

4. package-lock.json removed from .gitignore. server/package-lock.json is
   tracked, so the rule was inert, but it would silently prevent a future
   lockfile and works against the SBOM and reproducible-install setup added
   in #282.


Claude-Session: https://claude.ai/code/session_014kfhrUPit5MCqxeTQyqr56

Co-authored-by: Dan Walters <dan.walters@bytetinker.net>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 09:37:56 -05:00
screentinker 70af0d0194
Merge Japanese localisation (#283) (#285)
* Add complete Japanese localization

* Checked and fixed translations

* Preserve selected calendar dates across timezones

---------

Co-authored-by: giyokun <gproux@gmail.com>
Co-authored-by: Dan Walters <dan.walters@bytetinker.net>
Co-authored-by: giyokun <giyokun@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 09:23:28 -05:00
Claude 416984d56b Draw a recurring schedule on every day it actually fires
The calendar is the operator's only view of what is scheduled, and it disagreed with the engine in
both directions for the two most-used repeat presets.

The expansion stepped by the recurrence unit from the schedule's original start:

  - WEEKLY advanced a whole week at a time, so dayOfWeek never changed and a
    FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR rule could only ever match its start day. Created on a Monday
    it drew one event a week; created on a Saturday it drew nothing at all.
  - The walk began at the original start under a 366-iteration cap, so a schedule begun more than a
    year ago never reached the current week and drew nothing.

The engine evaluates day-of-week directly, so those schedules were running Mon-Fri the whole time.
Screens switched content the calendar said was not scheduled.

The expansion now walks the visible range day by day and applies the same rule the engine does, so
the drawing follows what actually happens. Cost is bounded by the window being displayed rather than
by how long ago the schedule was created, and the loop re-anchors the time of day on each step so a
DST boundary does not drift the instances.

Overlap is left to resolve as it already does: a shorter, higher-priority schedule takes over while
it is active and the recurring one resumes underneath when it ends. Nothing here changes what fires
— only what is shown — so this cannot alter live screens.

8 tests: five events for a Mon-Fri rule whichever day it was created on, a two-year-old daily
schedule drawing again, WEEKLY-without-byDay still meaning the start's weekday, INTERVAL honoured,
recurrence_end stopping the drawing, one-offs unaffected, and durations preserved.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
2026-07-30 22:18:29 -05:00