mirror of
https://github.com/wu736139669/hapi.git
synced 2026-10-08 19:19:42 +00:00
Part 1 — Simplified Chinese localization of the iOS app layer: - ios/Hapi/Resources/Localizable.xcstrings: hand-authored String Catalog (395 keys, zh-Hans; en implicit as source). Terminology mined from web/src/lib/locales/zh-CN.ts (会话/新建会话/权限模式/允许/拒绝/工作树/ 机器/语音输入/用量/草稿夹 …). - Mechanical edits only: merged multi-part string concatenations into single LocalizedStringKey literals, converted ternary/plain-String user copy to String(localized:), switched helper params (detailRow, DashboardCard, optionPicker, notice) to LocalizedStringKey. - LocalizedNoticeMapper (app layer): display-point translation of the 27 known HapiKit-emitted strings (ChatInteractor notices, dictation errors, window-sync warnings, files fallbacks, worktree-name validation) with verbatim passthrough for server-originated text; package stays language-free. - Deliberately untranslated (web parity / non-copy): event rows (EventPresentation — web renders presentation.ts verbatim), catalog option labels (Default/Auto/Sonnet/permission modes — web shows them verbatim), tool names, code-like titles (grep(pattern:), MCP:, Skill, Task), unit suffixes (B/KB/MB, m/h/d/w), decorative separators. - Language row wired: AppLanguage gains .system (follow system, new default); explicit picks write the AppleLanguages override, Follow system removes it; footer notes a relaunch applies it (no supported in-place SwiftUI locale swap). - project.pbxproj: zh-Hans added to knownRegions. Part 2 — #39 catalog dedupe (HapiProtocol): - NewSessionCatalogs.claudeModels/claudeEfforts now derive from ClaudeModels/ClaudeEfforts (single source shared with ModelCatalog); codexReasoningEfforts stays own data (web CODEX_REASONING_EFFORT_OPTIONS minus max); effortLabel delegates to ModelCatalog.capitalizedFirst. - New CatalogTests lock test for the derived option lists. Gate: bash ios/scripts/linux-test.sh — 459 tests green.
56 lines
2.2 KiB
Swift
56 lines
2.2 KiB
Swift
import Foundation
|
|
|
|
/// Display-point localization for user-facing strings emitted by HapiKit
|
|
/// (the package layer stays language-free, A-M5): a known package-produced
|
|
/// notice maps to its `Localizable.xcstrings` entry, everything else
|
|
/// (server-originated errors, dynamic content) passes through verbatim.
|
|
///
|
|
/// Covered sources: `ChatInteractor` notices, `DictationController` errors,
|
|
/// `MessageWindowController` tail-sync warnings, and the files models'
|
|
/// fallback errors. Low-value/debug package strings are deliberately not
|
|
/// mapped.
|
|
enum LocalizedNoticeMapper {
|
|
static func map(_ message: String) -> String {
|
|
guard knownMessages.contains(message) else { return message }
|
|
return String(localized: String.LocalizationValue(message))
|
|
}
|
|
|
|
/// Exact strings the package can emit — each is a key in
|
|
/// `Localizable.xcstrings` (hand-authored; runtime-built keys are not
|
|
/// extracted by the compiler).
|
|
private static let knownMessages: Set<String> = [
|
|
// ChatInteractor
|
|
"Attachments are still uploading — wait, or retry/remove the failed ones",
|
|
"Failed to abort",
|
|
"Session is inactive and could not be resumed",
|
|
"Failed to cancel queued message",
|
|
"Message cancelled — kept your current draft",
|
|
"Already delivered to the agent",
|
|
"Failed to steer message",
|
|
"Request was already handled",
|
|
"Request failed",
|
|
"Failed to load models",
|
|
"Failed to update session",
|
|
"Draft parked to scratchlist",
|
|
"Scratchlist is full (200 entries)",
|
|
"Couldn't park the draft — check the hub connection",
|
|
// DictationController
|
|
"Could not start recording",
|
|
"Could not reach the hub",
|
|
"Audio recording failed",
|
|
"No audio was recorded",
|
|
"Transcription failed",
|
|
// NewSessionLogic
|
|
"Name needs at least one letter or digit",
|
|
// MessageWindowController (degraded-sync banner)
|
|
"Failed to synchronize messages",
|
|
"Failed to load older messages",
|
|
// FilesModel / FileViewerModel fallbacks
|
|
"Git status unavailable",
|
|
"Failed to list directory",
|
|
"Failed to search files",
|
|
"Failed to read file",
|
|
"Failed to load diff",
|
|
]
|
|
}
|