uttrflow / uttrflow/uttrflow-swift
Localisation readiness: no localisable strings, English-only plurals, and layouts sized to English
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 3h 32m
- Merged PRs (30d)
- 277
Description
## What happens
Uttrflow can't be translated as it stands, and its layouts assume English string lengths. Measured on `main`:
**No localisable strings.**
- `Package.swift` declares no `defaultLocalization`, and there is no `.xcstrings` or `.strings` file anywhere in the repository.
- `String(localized:)`, `LocalizedStringResource` and `NSLocalizedString` appear **0** times in `Sources/`.
- Nearly every user-facing string is built as a plain Swift `String` in `UttrflowUX` presenters and passed to `Text(_: String)`, which doesn't look strings up. Examples: the menu (`Sources/UttrflowUX/MenuBarPresentation.swift:382-412`, `:447-489`), every Settings label (`Sources/UttrflowUX/SettingsPresenter.swift`), failure messages (`Sources/UttrflowCore/Errors/*.swift`) and the app menu (`Sources/Uttrflow/MainMenu.swift`).
**English-only grammar in code.**
- `MainFormatting.count(_:_:_:)` (`Sources/UttrflowUX/MainPresentation.swift:249-252`, documented as "English-only") picks singular or plural with `number == 1`, and is used in 16 places. Hindi, Russian, Arabic and others have other plural rules.
- `HomePresentation.swift:453` and `InsightsPresentation.swift:293`, `:361` interpolate numbers into English sentences ("\(n) a day", "Charts appear on \(weekday)").
- `FailurePresenter.splitIntoSentences` (`Sources/UttrflowUX/ErrorPresentation.swift:80-85`) splits a message into headline and detail at the first `". "`, which Hindi (`।`) and CJK (`。`) text doesn't contain.
- Six `.uppercased()` calls on labels (for example `MainWindowView.swift:185`, `MainPieces.swift:462`, `SettingsPaneView.swift:67`) ignore the locale, which matters for Turkish dotted and dotless i.
**Layouts sized to English.** German runs about 30% longer than English, and Hindi labels are often longer too.
- The onboarding window is a fixed 760 × 520 that "clips rather than scrolls" (`Sources/Uttrflow/Onboarding/OnboardingView.swift:57`, `:168-170`, and `hosting.sizingOptions = []` in `OnboardingWindowController.swift:91`).
- Fixed widths: editor captions 88 pt (`MainPieces.swift:428`), the page search field 200 pt (`MainWindowView.swift:237`), the Diagnostics "typical" and "slowest" columns 120 pt each (`DiagnosticsPageView.swift:74-80`), and the Insights app column 92 pt (`InsightsPageView.swift:58`).
Number and date formatting is already locale-aware (`MainFormatting` takes a `Locale`, apart from `seconds`, which is #529), so that half is in good shape.
## Why it matters
The product dictates Hindi and other languages, but its interface is English-only. Fixing this after more UI has been written with plain `String`s costs more every week. It's also a prerequisite for a contributor offering a translation.
## Decision needed
Whether and when to localise is a product decision, so this is `needs-info`. If the answer is yes, a reasonable first milestone is:
- `defaultLocalization: "en"` and a String Catalog for the `Uttrflow` and `UttrflowUX` targets.
- Presenters return `LocalizedStringResource` (or call `String(localized:)`), keeping the presenter tests meaningful by comparing against the English catalogue.
- `count` is replaced by automatic grammar agreement or a stringsdict plural.
- The onboarding window scrolls or grows when content doesn't fit, and the fixed widths become minimum widths.
- A pseudo-localisation run (double-length strings) shows no clipped text in onboarding, Settings or the main window.
## Acceptance criteria (for the first milestone)
- No user-facing string literal is shown without going through a localisation lookup. A lint in `make verify` could flag `Text(` with a non-literal `String` argument in `Sources/Uttrflow`.
- Running with `-NSDoubleLocalizedStrings YES` shows every string doubled and nothing clipped in the onboarding, Settings or main windows.
Contributor guide
Research direction
Start with Package.swift and the cited UttrflowUX presenters, views, error files, and onboarding window controller to map the existing strings and fixed layouts. Confirm the product decision and first-milestone scope before changing implementation, then inspect presenter tests and the make verify entry point. Done means the agreed milestone passes its localization and pseudo-localization acceptance criteria without clipped UI.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- desktop, internationalization, localization
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100