Conversation
Adds LoopFollow/Resources/Localizable.xcstrings (source language en) and registers tr in knownRegions. Keys come from xcodebuild -exportLocalizations plus a scan of SwiftUI LocalizedStringKey call sites (Toggle, Picker, Section, Label, navigationTitle, ...) that the extractor does not emit; those are marked extractionState "manual". No translations yet. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 345c02582e5878ba12922177d89edbf96ef836f7)
Fails until every translatable key has a Turkish value; also checks printf placeholders and stale keys. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 38286cfcb1ae0da53444786b2cc326e75318f23b)
AlarmType.rawValue and the day/night option raw values are persisted, so they must stay English. Add AlarmType.displayName and make DayNightDisplayable.displayName an explicit localized switch; route the tile, editor title, list and add-sheet search, notification title and default alarm name through them. Tests pin the raw values. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit ca2276f80102049c02f5e88cc3b3829725e0c3dc)
Fills the tr locale of Localizable.xcstrings for every extracted key, marks units, symbols and product names as do-not-translate, and adds two small scripts for listing and applying translations from TSV. Two call sites are adjusted so they can be localized at all: the "minute(s) ago" plural suffix becomes a plural variation on a single "%lld minutes ago" key, and three alarm-editor footers that joined two literals with "+" (which selects the non-localized Text overload) are single literals again. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 0f417a115c1b09b3444112935a19b5ee8185b231)
…er don't-translate set
- AlarmSettingsView's day/night footer joined three literals with "+",
which selects the non-localized Text overload; merge into one literal
and translate the whole footer. Drop the dead fragment and "(" keys.
- Add a source lint test that fails on Text("a" + "b") patterns.
- Require positional indexes (%1$@, %2$@) in every multi-placeholder
translation so argument order can be changed safely; update the five
affected Turkish values.
- Keep shouldTranslate=false only for units, symbols, bare specifiers and
hashtags; ordinary terms that happen to match in Turkish get an explicit
translation so other languages can translate them.
- Verify the English plural variation at runtime from en.lproj.
- Fix "Snoozed until %@" (argument is a time, not a date) and refine
"Proactive Low" and the "Remote" title.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… consistency test Scripts/localization/localized_apis.txt names the SwiftUI/Foundation APIs whose first string-literal argument is a catalog key. scan_keys.py adds missing keys to the catalog (or reports them with --check) and the new scannedLiteralsExistInCatalog test enforces the same rule in the test target. Literals followed by "+" are String concatenation and are ignored by both. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…rals QuickPickSectionHeader, QuickSelectButton, InfoBanner, NavigationRow-free helpers, LoadingButtonView, ErrorMessageView, OnboardingStepHeader, HKQuantityInputView, AlarmEnumMenuPicker, CommandButtonView, BGPicker, StatCard, the alarm editor sections (AlarmBGSection, AlarmBGLimitSection, AlarmStepperSection), the welcome primary label and the onboarding footer title now take LocalizedStringKey, so their call sites localize without change. InfoBanner texts that were split across "+" literals are single literals again; the quick-pick info texts are localized at their source. The key scanner and the matching test now collect labeled literal arguments inside each listed call (skipping systemImage/comment/icon style labels, nested calls and arrays), so these keys are covered. Adds the Turkish values for the 188 new keys. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ch titles All displayName/name/title/label/blurb bodies go through String(localized:). SettingsLeaf localizes its title at init so Menu search matches the Turkish labels on screen (a localizedTitle: initializer covers titles that are already localized). AlarmSelectionView reuses AlarmType.displayName instead of its own copy of the 24 names. The key scanner and test now honor "Name(label:" entries, so String(localized:) literals are collected only from their localized: argument. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Every user-facing String literal assigned to a variable, chosen by a ternary or reported as a remote-command status/error goes through String(localized:); server response bodies stay interpolated arguments. The meal confirmation and the scanned-settings prompts are whole sentences instead of concatenated fragments. Adds a lint that rejects raw literal ternaries in String positions, ternary-branch support in the key scanner/test, and an opt-in heuristic (--interpolations) that turns interpolated String(localized:) literals into printf-style keys for review. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Minutes-ago, LOW/HIGH, Not Looping, loading and setup-button strings, UIKit alerts, the log search placeholder, the QR scanner title, the treatment pill details and the suspend/resume chart pills go through String(localized:). The OTP countdown becomes a single interpolated key instead of concatenation. Double amounts keep their compact formatting via an explicit %g specifier. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ago, remaining English sources - NightscoutSettingsViewModel compared the (now localized) status text with the English literal "Checking...", so the onboarding pill lost its checking state in Turkish; the value is a shared constant compared by identity of lookup, with a test that runs in the tr host. - The main screen's minutes-ago text lives in MinAgoTask, not the calendar title; it is now "%@ min ago" (the duration can be "4:35"). - Sensor-age footer key added; chart pill labels (Bolus, Carbs, SMB, BG Check, Sensor Start, Override, Temp Target), Nightscout friendly status and auth level, token-provisioning and Nightscout/Loop APNS/ override-preset error descriptions, TIR titles, info-row color footers, onboarding fast-drop explanation and the update alerts go through String(localized:). - Property initializers drop the explicit String type so SwiftFormat does not rewrite them to .init(localized:), which the scanner cannot see; empty String(localized: "") artifacts and the "(%@)" OTP wrapper key are gone; the meal bolus line matches its siblings; "Est. A1C:" is the single key. - scan_keys.py refuses to add a heuristic key that differs from an existing key only by specifier types. - Turkish: "OK (%@)" → "Bağlı (%@)", clearer time-window messages. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Second of three localization PRs. Builds on #760 (this branch contains its commits; merge that first). Covers what the String Catalog could not reach through SwiftUI literals alone: reusable views, enum display names, string constants, remote-command messages and the UIKit main screen. Opened as a draft while the Turkish copy is reviewed by a native speaker on a TestFlight build.
Changes
LocalizedStringKey(QuickPickSectionHeader, InfoBanner, alarm editor sections, BGPicker, StatCard, onboarding header/footer, …), so their ~130 call sites localize without change. Section footers that were split across"a " + "b"literals are single literals again.InfoType.name, tab names, appearance/prediction/contact modes, Trio commands, treatment types, alarm blurbs, settings screen titles) go throughString(localized:);SettingsLeaflocalizes at init so Menu search matches the Turkish labels;AlarmSelectionViewreusesAlarmType.displayName.String(localized:); server response bodies stay%@arguments."Checking..."was replaced by a shared constant so the onboarding pill keeps its checking state in every language (caught in review, with a test that runs in a Turkish test host).Scripts/localization/localized_apis.txtnames the APIs whose literal arguments are keys;scan_keys.pycollects them (labeled/unlabeled, ternary branches,Name(label:entries, opt-in reviewed--interpolationsheuristic) andscannedLiteralsExistInCatalogenforces the same rule in the test target. A lint rejects raw literal ternaries inStringpositions.Still English (deliberately, PR 3)
UNMutableNotificationContentbodies,BackgroundAlertManagermessages,AlarmManager.sendNotificationand the Live Activity extension /Shareddisplay names, Info.plist usage descriptions.Testing
Teststarget: 115 passed, 0 failed (iOS 27 simulator running in tr-TR).--lintclean.🤖 Generated with Claude Code