feat(i18n): complete internationalization for iOS + watchOS across all views
Migrate every hardcoded Text("...") string to the L10n / LocalizedStringResource
type-safe key system with full en/fr/de/es translations (4 languages).
iOS changes (TabataGo target):
- Strings.swift: ~90 new L10n keys across 13 groups (action, tab, home, zone,
level, programs, programDetail, player, profile, settings, policy, paywall,
health, complete, activity, onboarding, goal)
- Localizable.xcstrings: 145 → 245+ keys with fr/de/es translations
- Model enums: FitnessLevel.label & FitnessGoal.label changed from String to
LocalizedStringResource, backed by L10n.level/goal keys
- Component param types changed to LocalizedStringResource: StatBadge,
SectionHeader, ProfileRow, PolicySection, CompletionStat, FeatureRow,
OnboardingHeader, PrimaryButton, SelectionCard
- All 18 view files updated: HomeTab, ActivityTab, ProgramsTab, ProfileTab,
MainTabView, SettingsView, PolicyViews, CompletionView, BodyZoneView,
ProgramDetailView, PaywallView, OnboardingView, PlayerView
Watch changes (TabataGoWatch target):
- New Localizable.xcstrings: 23 keys with en/fr/de/es (phase labels, idle
state, activity rings, complication strings)
- New WatchL10n.swift: type-safe enum (needs manual Xcode target membership)
- Updated: WatchPlayerView, WatchIdleView, WatchActivityView,
TabataGoComplication (inline LocalizedStringResource for widget target)
Both iOS and watchOS targets build with zero errors.
This commit is contained in:
54
tabatago-swift/TabataGoWatch/Utilities/WatchL10n.swift
Normal file
54
tabatago-swift/TabataGoWatch/Utilities/WatchL10n.swift
Normal file
@@ -0,0 +1,54 @@
|
||||
import Foundation
|
||||
|
||||
/// Type-safe string keys for the Watch target's `Localizable.xcstrings`.
|
||||
/// Usage: Text(WatchL10n.phase.work) or String(localized: WatchL10n.idle.connected)
|
||||
enum WatchL10n {
|
||||
|
||||
enum phase {
|
||||
static let getReady = LocalizedStringResource("watch.phase.getReady")
|
||||
static let warmUp = LocalizedStringResource("watch.phase.warmUp")
|
||||
static let work = LocalizedStringResource("watch.phase.work")
|
||||
static let rest = LocalizedStringResource("watch.phase.rest")
|
||||
static let `break` = LocalizedStringResource("watch.phase.break")
|
||||
static let coolDown = LocalizedStringResource("watch.phase.coolDown")
|
||||
static let done = LocalizedStringResource("watch.phase.done")
|
||||
|
||||
static func label(for phase: WatchPhase) -> LocalizedStringResource {
|
||||
switch phase {
|
||||
case .prep: return getReady
|
||||
case .warmup: return warmUp
|
||||
case .work: return work
|
||||
case .rest: return rest
|
||||
case .interBlockRest: return `break`
|
||||
case .cooldown: return coolDown
|
||||
case .complete: return done
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum idle {
|
||||
static let startOnPhone = LocalizedStringResource("watch.idle.startOnPhone")
|
||||
static let connected = LocalizedStringResource("watch.idle.connected")
|
||||
static let noPhone = LocalizedStringResource("watch.idle.noPhone")
|
||||
}
|
||||
|
||||
enum activity {
|
||||
static let today = LocalizedStringResource("watch.activity.today")
|
||||
static let move = LocalizedStringResource("watch.activity.move")
|
||||
static let exercise = LocalizedStringResource("watch.activity.exercise")
|
||||
static let stand = LocalizedStringResource("watch.activity.stand")
|
||||
static let streak = LocalizedStringResource("watch.activity.streak")
|
||||
}
|
||||
|
||||
enum complication {
|
||||
static let notStarted = LocalizedStringResource("watch.complication.notStarted")
|
||||
static let today = LocalizedStringResource("watch.complication.today")
|
||||
static let yesterday = LocalizedStringResource("watch.complication.yesterday")
|
||||
/// printf format: takes one Int (number of days). e.g. "%d days ago"
|
||||
static let daysAgoFmt = LocalizedStringResource("watch.complication.daysAgoFmt")
|
||||
/// printf format: takes one Int (streak count). e.g. "%d day streak"
|
||||
static let dayStreakFmt = LocalizedStringResource("watch.complication.dayStreakFmt")
|
||||
static let openApp = LocalizedStringResource("watch.complication.openApp")
|
||||
static let description = LocalizedStringResource("watch.complication.description")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user