feat: add Japanese localization with String Catalog (#819)
* Add i18n infrastructure with String Catalog and Japanese translations Introduce String Catalog (.xcstrings) for localization support: - Localizable.xcstrings: 195 UI string entries with en and ja translations - InfoPlist.xcstrings: Info.plist strings (microphone usage, Finder menu items) - project.pbxproj: add xcstrings to build phase and ja to knownRegions * Replace hardcoded UI strings with String(localized:defaultValue:) Migrate all user-facing strings across 11 source files to use String(localized:defaultValue:) API (macOS 13+). Each string references a key in Localizable.xcstrings, with the English text preserved as defaultValue for fallback. Files modified: - KeyboardShortcutSettings: 28 shortcut labels - SocketControlSettings: mode names and descriptions - TabManager: placement labels, color names, close dialogs - BrowserPanel/BrowserPanelView: error pages, context menus, tooltips - UpdateViewModel/UpdatePopoverView/UpdatePill: update UI states - NotificationsPage: notification panel labels - SurfaceSearchOverlay: search bar placeholder and tooltips - AppDelegate: menus, dialogs, command palette items * Fix localization gaps from review feedback Address review comments from CodeRabbit, Greptile, and Cubic Dev AI: - Use interpolated String(localized:) instead of concatenation for version/progress strings in UpdateViewModel - Localize remaining hardcoded strings in AppDelegate: window labels, rename dialog, status menu items, unread notification count - Localize insecure HTTP alert body in BrowserPanel - Add 12 new entries to Localizable.xcstrings with Japanese translations * Fix String(localized:defaultValue:) keys to use StaticString The localized: parameter requires StaticString when defaultValue: is used. Move string interpolation from the key to defaultValue only, and revert maxWidthText to plain strings since they are only used for layout width calculation. * Localize remaining UI strings across all source files Add String(localized:defaultValue:) to all user-facing strings in: - cmuxApp.swift: settings screen, menus, about panel, dialogs (~180 strings) - ContentView.swift: command palette, sidebar context menu, dialogs (~200 strings) - Workspace.swift: rename/move/close tab dialogs, tooltips (~20 strings) - UpdateTitlebarAccessory.swift: titlebar tooltips, notifications popover (~10 strings) - TerminalNotificationStore.swift: notification permission dialog (4 strings) - CmuxWebView.swift: browser context menu items (2 strings) - AppDelegate.swift: CLI install/uninstall alerts (6 strings) Add 418 new entries to Localizable.xcstrings with Japanese translations. Extract sidebar context menu into separate @ViewBuilder to fix Swift type-checker timeout in large body. Fix xcstrings format specifiers for interpolated strings (%lld, %@). Total: 624 localization entries covering the full UI. * Address review feedback: fix missing localizations and terminology - Localize javaScriptDialogTitle URL branch in BrowserPanel - Localize cantReach error message in BrowserPanel - Localize close other tabs dialog message in TabManager - Localize workspace accessibility label in ContentView - Fix unread notification singular/plural (split into two keys) - Fix insecure connection apostrophe inconsistency (unify to U+2019) - Rename socketControl.fullOpen.description to socketControl.allowAll.description - Remove dead code: renameTargetNoun function - Fix terminology inconsistencies in xcstrings: - Unify "Developer Tools" to デベロッパツール - Unify "Jump to Latest Unread" phrasing - Unify "Flash Focused Panel" terminology - Fix dialog.enableNotifications.notNow translation * fix: address remaining PR 819 review feedback * fix: use a single localized key for close-other-tabs * fix: avoid inflection markup in close-other-tabs message * Address review feedback: localize tooltip, fix subtitle concat, unify keys - Localize menubar tooltip unread count (hardcoded English -> localized) - Replace subtitle string concatenation anti-pattern with single localized keys containing interpolation placeholders - Unify workspace fallback key to workspace.displayName.fallback - Remove unused workspace.defaultName key from xcstrings - Add Japanese translations for new tooltip and subtitle keys
This commit is contained in:
parent
422c86e822
commit
2c330efb8a
20 changed files with 11643 additions and 789 deletions
|
|
@ -45,35 +45,35 @@ enum KeyboardShortcutSettings {
|
|||
|
||||
var label: String {
|
||||
switch self {
|
||||
case .toggleSidebar: return "Toggle Sidebar"
|
||||
case .newTab: return "New Workspace"
|
||||
case .newWindow: return "New Window"
|
||||
case .closeWindow: return "Close Window"
|
||||
case .openFolder: return "Open Folder"
|
||||
case .showNotifications: return "Show Notifications"
|
||||
case .jumpToUnread: return "Jump to Latest Unread"
|
||||
case .triggerFlash: return "Flash Focused Panel"
|
||||
case .nextSurface: return "Next Surface"
|
||||
case .prevSurface: return "Previous Surface"
|
||||
case .nextSidebarTab: return "Next Workspace"
|
||||
case .prevSidebarTab: return "Previous Workspace"
|
||||
case .renameTab: return "Rename Tab"
|
||||
case .renameWorkspace: return "Rename Workspace"
|
||||
case .closeWorkspace: return "Close Workspace"
|
||||
case .newSurface: return "New Surface"
|
||||
case .toggleTerminalCopyMode: return "Toggle Terminal Copy Mode"
|
||||
case .focusLeft: return "Focus Pane Left"
|
||||
case .focusRight: return "Focus Pane Right"
|
||||
case .focusUp: return "Focus Pane Up"
|
||||
case .focusDown: return "Focus Pane Down"
|
||||
case .splitRight: return "Split Right"
|
||||
case .splitDown: return "Split Down"
|
||||
case .toggleSplitZoom: return "Toggle Pane Zoom"
|
||||
case .splitBrowserRight: return "Split Browser Right"
|
||||
case .splitBrowserDown: return "Split Browser Down"
|
||||
case .openBrowser: return "Open Browser"
|
||||
case .toggleBrowserDeveloperTools: return "Toggle Browser Developer Tools"
|
||||
case .showBrowserJavaScriptConsole: return "Show Browser JavaScript Console"
|
||||
case .toggleSidebar: return String(localized: "shortcut.toggleSidebar.label", defaultValue: "Toggle Sidebar")
|
||||
case .newTab: return String(localized: "shortcut.newWorkspace.label", defaultValue: "New Workspace")
|
||||
case .newWindow: return String(localized: "shortcut.newWindow.label", defaultValue: "New Window")
|
||||
case .closeWindow: return String(localized: "shortcut.closeWindow.label", defaultValue: "Close Window")
|
||||
case .openFolder: return String(localized: "shortcut.openFolder.label", defaultValue: "Open Folder")
|
||||
case .showNotifications: return String(localized: "shortcut.showNotifications.label", defaultValue: "Show Notifications")
|
||||
case .jumpToUnread: return String(localized: "shortcut.jumpToUnread.label", defaultValue: "Jump to Latest Unread")
|
||||
case .triggerFlash: return String(localized: "shortcut.flashFocusedPanel.label", defaultValue: "Flash Focused Panel")
|
||||
case .nextSurface: return String(localized: "shortcut.nextSurface.label", defaultValue: "Next Surface")
|
||||
case .prevSurface: return String(localized: "shortcut.previousSurface.label", defaultValue: "Previous Surface")
|
||||
case .nextSidebarTab: return String(localized: "shortcut.nextWorkspace.label", defaultValue: "Next Workspace")
|
||||
case .prevSidebarTab: return String(localized: "shortcut.previousWorkspace.label", defaultValue: "Previous Workspace")
|
||||
case .renameTab: return String(localized: "shortcut.renameTab.label", defaultValue: "Rename Tab")
|
||||
case .renameWorkspace: return String(localized: "shortcut.renameWorkspace.label", defaultValue: "Rename Workspace")
|
||||
case .closeWorkspace: return String(localized: "shortcut.closeWorkspace.label", defaultValue: "Close Workspace")
|
||||
case .newSurface: return String(localized: "shortcut.newSurface.label", defaultValue: "New Surface")
|
||||
case .toggleTerminalCopyMode: return String(localized: "shortcut.toggleTerminalCopyMode.label", defaultValue: "Toggle Terminal Copy Mode")
|
||||
case .focusLeft: return String(localized: "shortcut.focusPaneLeft.label", defaultValue: "Focus Pane Left")
|
||||
case .focusRight: return String(localized: "shortcut.focusPaneRight.label", defaultValue: "Focus Pane Right")
|
||||
case .focusUp: return String(localized: "shortcut.focusPaneUp.label", defaultValue: "Focus Pane Up")
|
||||
case .focusDown: return String(localized: "shortcut.focusPaneDown.label", defaultValue: "Focus Pane Down")
|
||||
case .splitRight: return String(localized: "shortcut.splitRight.label", defaultValue: "Split Right")
|
||||
case .splitDown: return String(localized: "shortcut.splitDown.label", defaultValue: "Split Down")
|
||||
case .toggleSplitZoom: return String(localized: "shortcut.togglePaneZoom.label", defaultValue: "Toggle Pane Zoom")
|
||||
case .splitBrowserRight: return String(localized: "shortcut.splitBrowserRight.label", defaultValue: "Split Browser Right")
|
||||
case .splitBrowserDown: return String(localized: "shortcut.splitBrowserDown.label", defaultValue: "Split Browser Down")
|
||||
case .openBrowser: return String(localized: "shortcut.openBrowser.label", defaultValue: "Open Browser")
|
||||
case .toggleBrowserDeveloperTools: return String(localized: "shortcut.toggleBrowserDevTools.label", defaultValue: "Toggle Browser Developer Tools")
|
||||
case .showBrowserJavaScriptConsole: return String(localized: "shortcut.showBrowserJSConsole.label", defaultValue: "Show Browser JavaScript Console")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -474,7 +474,7 @@ private class ShortcutRecorderNSButton: NSButton {
|
|||
|
||||
func updateTitle() {
|
||||
if isRecording {
|
||||
title = "Press shortcut…"
|
||||
title = String(localized: "shortcut.pressShortcut.prompt", defaultValue: "Press shortcut…")
|
||||
} else {
|
||||
title = shortcut.displayString
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue