Second pass: four dialogs that were never wrapped #258

Closed
opened 2026-09-03 18:58:15 +00:00 by jcoffey-dev · 0 comments
Owner

A sweep for UI text still rendering in English, after the nine catalogues were brought up to date.

What was still hardcoded

Where What
MailView delete confirmation entirely — both titles, both messages, the confirm label
FilesTree Rename
ContactsSidebar New address book, and its Name placeholder
CalendarSettings New category, and its Name placeholder

The delete confirmation is the notable one. Its counts read "message(s)" — a parenthesis standing in for grammatical agreement, so every language that inflects got the wrong form regardless of catalogue coverage. Those are plural() calls now.

The New category case shows how these hide: the button that opens the dialog was already translated, so the label read correctly and the dialog it opened did not.

Strings

Rename, New address book, New category, Name and Delete are already in all nine catalogues, so those are fixed by this PR alone. Delete?, Delete forever? and the two plural forms are new and land with each language PR.

Still outstanding — two sentence builders

The sweep found a larger class this PR does not fix, because it needs a design decision rather than a wrapper:

  • lib/sieve.ts describeRule() builds the Sieve rule summaries by string concatenation — `${t.header} ${op} "${t.value}"` joined by " and " / " or ", with actions like move to, forward to, delete. This is exactly the "Sieve rule list — all the summaries" item in #247.
  • lib/recurrence.ts describeRule() does the same for recurrence — Every {n} days, on the ${ordinal}${Weekday}, , {n} times, , until {date} — with English ordinals (1st, 2nd, last) and English weekday names.

Neither is translatable as written: the sentence is assembled from fragments, and word order is not the same in German, Japanese or Ukrainian. Fixing them properly means whole sentences with placeholders rather than concatenation, which changes the string inventory and so needs another pass over all nine catalogues.

WEEKDAYS in recurrence.ts is related: its short forms cannot be catalogue keys because T covers both Tuesday and Thursday and S both Saturday and Sunday. Intl.DateTimeFormat with weekday: "narrow" is the right answer, and lib/datetime.ts already has a locale-aware formatter cache to hang it on.

Checks

Typecheck clean, 99 test files / 1000 tests pass.

Merged 2026-09-03 as coffey-labs/ihasmail@bf60fe6157

Rebuilt from: git history, session transcript.

A sweep for UI text still rendering in English, after the nine catalogues were brought up to date. ## What was still hardcoded | Where | What | |---|---| | `MailView` delete confirmation | **entirely** — both titles, both messages, the confirm label | | `FilesTree` | `Rename` | | `ContactsSidebar` | `New address book`, and its `Name` placeholder | | `CalendarSettings` | `New category`, and its `Name` placeholder | The delete confirmation is the notable one. Its counts read `"message(s)"` — a parenthesis standing in for grammatical agreement, so every language that inflects got the wrong form regardless of catalogue coverage. Those are `plural()` calls now. The `New category` case shows how these hide: the button that opens the dialog was already translated, so the label read correctly and the dialog it opened did not. ## Strings `Rename`, `New address book`, `New category`, `Name` and `Delete` are already in all nine catalogues, so those are fixed by this PR alone. `Delete?`, `Delete forever?` and the two plural forms are new and land with each language PR. ## Still outstanding — two sentence builders The sweep found a larger class this PR does **not** fix, because it needs a design decision rather than a wrapper: - **`lib/sieve.ts` `describeRule()`** builds the Sieve rule summaries by string concatenation — `` `${t.header} ${op} "${t.value}"` `` joined by `" and "` / `" or "`, with actions like `move to`, `forward to`, `delete`. This is exactly the "Sieve rule list — all the summaries" item in #247. - **`lib/recurrence.ts` `describeRule()`** does the same for recurrence — `Every {n} days`, `` on the ${ordinal}${Weekday} ``, `, {n} times`, `, until {date}` — with English ordinals (`1st`, `2nd`, `last`) and English weekday names. Neither is translatable as written: the sentence is assembled from fragments, and word order is not the same in German, Japanese or Ukrainian. Fixing them properly means whole sentences with placeholders rather than concatenation, which changes the string inventory and so needs another pass over all nine catalogues. `WEEKDAYS` in `recurrence.ts` is related: its `short` forms cannot be catalogue keys because `T` covers both Tuesday and Thursday and `S` both Saturday and Sunday. `Intl.DateTimeFormat` with `weekday: "narrow"` is the right answer, and `lib/datetime.ts` already has a locale-aware formatter cache to hang it on. ## Checks Typecheck clean, 99 test files / 1000 tests pass. **Merged** 2026-09-03 as coffey-labs/ihasmail@bf60fe6157e7 <sub>Rebuilt from: git history, session transcript.</sub>
This repo is archived. You cannot comment on issues.