diff --git a/Ice/MenuBar/ControlItem/ControlItem.swift b/Ice/MenuBar/ControlItem/ControlItem.swift index d35f356c..1a4830fa 100644 --- a/Ice/MenuBar/ControlItem/ControlItem.swift +++ b/Ice/MenuBar/ControlItem/ControlItem.swift @@ -422,10 +422,10 @@ final class ControlItem { return hotkeySettingsManager.hotkey(withAction: action) } - let menu = NSMenu(title: "Ice") + let menu = NSMenu(title: NSLocalizedString("Ice", comment: "Menu title")) let settingsItem = NSMenuItem( - title: "Ice Settings…", + title: NSLocalizedString("Ice Settings…", comment: "Menu item"), action: #selector(AppDelegate.openSettingsWindow), keyEquivalent: "," ) @@ -435,7 +435,7 @@ final class ControlItem { menu.addItem(.separator()) let searchItem = NSMenuItem( - title: "Search Menu Bar Items", + title: NSLocalizedString("Search Menu Bar Items", comment: "Menu item"), action: #selector(showSearchPanel), keyEquivalent: "" ) @@ -462,7 +462,15 @@ final class ControlItem { continue } let item = NSMenuItem( - title: "\(section.isHidden ? "Show" : "Hide") the \(name.displayString) Section", + title: section.isHidden + ? String( + format: NSLocalizedString("Show the %@ Section", comment: "Menu item"), + name.displayString + ) + : String( + format: NSLocalizedString("Hide the %@ Section", comment: "Menu item"), + name.displayString + ), action: #selector(toggleMenuBarSection), keyEquivalent: "" ) @@ -494,7 +502,7 @@ final class ControlItem { menu.addItem(.separator()) let checkForUpdatesItem = NSMenuItem( - title: "Check for Updates…", + title: NSLocalizedString("Check for Updates…", comment: "Menu item"), action: #selector(checkForUpdates), keyEquivalent: "" ) @@ -504,7 +512,7 @@ final class ControlItem { menu.addItem(.separator()) let quitItem = NSMenuItem( - title: "Quit Ice", + title: NSLocalizedString("Quit Ice", comment: "Menu item"), action: #selector(NSApp.terminate), keyEquivalent: "q" ) diff --git a/Ice/MenuBar/MenuBarItems/MenuBarItem.swift b/Ice/MenuBar/MenuBarItems/MenuBarItem.swift index 4d68bd44..a3f4df38 100644 --- a/Ice/MenuBar/MenuBarItems/MenuBarItem.swift +++ b/Ice/MenuBar/MenuBarItems/MenuBarItem.swift @@ -68,7 +68,7 @@ struct MenuBarItem { /// A name associated with the item that is suited for display to /// the user. var displayName: String { - var fallback: String { "Unknown" } + var fallback: String { NSLocalizedString("Unknown", comment: "Fallback menu bar item name") } guard let owningApplication else { return ownerName ?? title ?? fallback } @@ -85,24 +85,35 @@ struct MenuBarItem { return switch MenuBarItemInfo.Namespace(owningApplication.bundleIdentifier) { case .controlCenter: switch title { - case "AccessibilityShortcuts": "Accessibility Shortcuts" + case "AccessibilityShortcuts": + NSLocalizedString("Accessibility Shortcuts", comment: "Control Center item") case "BentoBox": bestName // Control Center - case "FocusModes": "Focus" - case "KeyboardBrightness": "Keyboard Brightness" - case "MusicRecognition": "Music Recognition" - case "NowPlaying": "Now Playing" - case "ScreenMirroring": "Screen Mirroring" - case "StageManager": "Stage Manager" - case "UserSwitcher": "Fast User Switching" - case "WiFi": "Wi-Fi" + case "FocusModes": + NSLocalizedString("Focus", comment: "Control Center item") + case "KeyboardBrightness": + NSLocalizedString("Keyboard Brightness", comment: "Control Center item") + case "MusicRecognition": + NSLocalizedString("Music Recognition", comment: "Control Center item") + case "NowPlaying": + NSLocalizedString("Now Playing", comment: "Control Center item") + case "ScreenMirroring": + NSLocalizedString("Screen Mirroring", comment: "Control Center item") + case "StageManager": + NSLocalizedString("Stage Manager", comment: "Control Center item") + case "UserSwitcher": + NSLocalizedString("Fast User Switching", comment: "Control Center item") + case "WiFi": + NSLocalizedString("Wi-Fi", comment: "Control Center item") default: title } case .systemUIServer: switch title { - case "TimeMachine.TMMenuExtraHost"/*Sonoma*/, "TimeMachineMenuExtra.TMMenuExtraHost"/*Sequoia*/: "Time Machine" + case "TimeMachine.TMMenuExtraHost"/*Sonoma*/, "TimeMachineMenuExtra.TMMenuExtraHost"/*Sequoia*/: + NSLocalizedString("Time Machine", comment: "System menu bar item") default: title } - case MenuBarItemInfo.Namespace("com.apple.Passwords.MenuBarExtra"): "Passwords" + case MenuBarItemInfo.Namespace("com.apple.Passwords.MenuBarExtra"): + NSLocalizedString("Passwords", comment: "System menu bar item") default: bestName } diff --git a/Ice/MenuBar/MenuBarItems/MenuBarItemManager.swift b/Ice/MenuBar/MenuBarItems/MenuBarItemManager.swift index 68694d0d..b53b9a54 100644 --- a/Ice/MenuBar/MenuBarItems/MenuBarItemManager.swift +++ b/Ice/MenuBar/MenuBarItems/MenuBarItemManager.swift @@ -1350,7 +1350,10 @@ extension MenuBarItemManager { guard let targetItem = items.first else { let alert = NSAlert() - alert.messageText = "Not enough room to show \"\(item.displayName)\"" + alert.messageText = String( + format: NSLocalizedString("Not enough room to show \"%@\"", comment: "Alert title"), + item.displayName + ) alert.runModal() return } diff --git a/Ice/MenuBar/MenuBarManager.swift b/Ice/MenuBar/MenuBarManager.swift index 5feed0ac..79af4cf6 100644 --- a/Ice/MenuBar/MenuBarManager.swift +++ b/Ice/MenuBar/MenuBarManager.swift @@ -327,10 +327,10 @@ final class MenuBarManager: ObservableObject { /// Shows the right-click menu. func showRightClickMenu(at point: CGPoint) { - let menu = NSMenu(title: "Ice") + let menu = NSMenu(title: NSLocalizedString("Ice", comment: "Menu title")) let editItem = NSMenuItem( - title: "Edit Menu Bar Appearance…", + title: NSLocalizedString("Edit Menu Bar Appearance…", comment: "Menu item"), action: #selector(showAppearanceEditorPopover), keyEquivalent: "" ) @@ -340,7 +340,7 @@ final class MenuBarManager: ObservableObject { menu.addItem(.separator()) let settingsItem = NSMenuItem( - title: "Ice Settings…", + title: NSLocalizedString("Ice Settings…", comment: "Menu item"), action: #selector(AppDelegate.openSettingsWindow), keyEquivalent: "," ) diff --git a/Ice/MenuBar/MenuBarSection.swift b/Ice/MenuBar/MenuBarSection.swift index b1157d37..2e962046 100644 --- a/Ice/MenuBar/MenuBarSection.swift +++ b/Ice/MenuBar/MenuBarSection.swift @@ -17,9 +17,9 @@ final class MenuBarSection { /// A string to show in the interface. var displayString: String { switch self { - case .visible: "Visible" - case .hidden: "Hidden" - case .alwaysHidden: "Always-Hidden" + case .visible: NSLocalizedString("Visible", comment: "Menu bar section name") + case .hidden: NSLocalizedString("Hidden", comment: "Menu bar section name") + case .alwaysHidden: NSLocalizedString("Always-Hidden", comment: "Menu bar section name") } } diff --git a/Ice/Permissions/Permission.swift b/Ice/Permissions/Permission.swift index dd82abd1..f1df248e 100644 --- a/Ice/Permissions/Permission.swift +++ b/Ice/Permissions/Permission.swift @@ -118,10 +118,10 @@ class Permission: ObservableObject, Identifiable { final class AccessibilityPermission: Permission { init() { super.init( - title: "Accessibility", + title: NSLocalizedString("Accessibility", comment: "Permission title"), details: [ - "Get real-time information about the menu bar.", - "Arrange menu bar items.", + NSLocalizedString("Get real-time information about the menu bar.", comment: "Permission detail"), + NSLocalizedString("Arrange menu bar items.", comment: "Permission detail"), ], isRequired: true, settingsURL: nil, @@ -140,10 +140,10 @@ final class AccessibilityPermission: Permission { final class ScreenRecordingPermission: Permission { init() { super.init( - title: "Screen Recording", + title: NSLocalizedString("Screen Recording", comment: "Permission title"), details: [ - "Edit the menu bar's appearance.", - "Display images of individual menu bar items.", + NSLocalizedString("Edit the menu bar's appearance.", comment: "Permission detail"), + NSLocalizedString("Display images of individual menu bar items.", comment: "Permission detail"), ], isRequired: false, settingsURL: URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture"), diff --git a/Ice/Resources/zh-Hans.lproj/Localizable.strings b/Ice/Resources/zh-Hans.lproj/Localizable.strings new file mode 100644 index 00000000..79e0d031 --- /dev/null +++ b/Ice/Resources/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,206 @@ +"Ice" = "Ice"; +"BETA" = "测试版"; + +"Edit Menu Bar Appearance…" = "编辑菜单栏外观…"; +"Ice Settings…" = "Ice 设置…"; +"Search Menu Bar Items" = "搜索菜单栏项目"; +"Search menu bar items" = "搜索菜单栏项目"; +"Search menu bar items…" = "搜索菜单栏项目…"; +"Check for Updates" = "检查更新"; +"Check for Updates…" = "检查更新…"; +"Quit Ice" = "退出 Ice"; +"Quit" = "退出"; +"Open Ice Settings" = "打开 Ice 设置"; +"Show the %@ Section" = "显示%@分区"; +"Hide the %@ Section" = "隐藏%@分区"; +"%@ Section" = "%@ 分区"; + +"Visible" = "可见"; +"Hidden" = "隐藏"; +"Always-Hidden" = "始终隐藏"; + +"Permissions" = "权限"; +"Permission Granted" = "已授予权限"; +"Grant Permission" = "授予权限"; +"Ice needs this to:" = "Ice 需要此权限以:"; +"Ice needs permission to manage the menu bar." = "Ice 需要权限来管理菜单栏。"; +"Absolutely no personal information is collected or stored." = "不会收集或存储任何个人信息。"; +"Continue" = "继续"; +"Continue in Limited Mode" = "以受限模式继续"; + +"Accessibility" = "辅助功能"; +"Get real-time information about the menu bar." = "获取菜单栏的实时信息。"; +"Arrange menu bar items." = "排列菜单栏项目。"; +"Screen Recording" = "屏幕录制"; +"Edit the menu bar's appearance." = "编辑菜单栏外观。"; +"Display images of individual menu bar items." = "显示各个菜单栏项目的图像。"; + +"Menu bar item is not movable." = "菜单栏项目不可移动。"; +"macOS prohibits \"%@\" from being moved." = "macOS 不允许移动“%@”。"; +"%@ is unresponsive. Until it is restarted, it cannot be moved. Movement of other menu bar items may also be affected until this is resolved." = "“%@”无响应。在它重新启动之前,无法移动。其他菜单栏项目的移动也可能受影响,直到问题解决。"; +"Not enough room to show \"%@\"" = "没有足够空间显示“%@”。"; + +"Checking for updates is not supported in debug mode." = "调试模式下不支持检查更新。"; +"A new update is available" = "有新更新可用"; +"Version %@ is now available" = "版本 %@ 现已可用"; + +"Due to a bug in the 0.10.0 release, the data for Ice's menu bar items was corrupted and their positions had to be reset." = "由于 0.10.0 版本中的一个问题,Ice 的菜单栏项目数据被损坏,其位置已被重置。"; +"Our sincerest apologies for the inconvenience." = "对此带来的不便,我们深表歉意。"; + +"Unknown" = "未知"; +"Accessibility Shortcuts" = "辅助功能快捷方式"; +"Focus" = "专注"; +"Keyboard Brightness" = "键盘亮度"; +"Music Recognition" = "音乐识别"; +"Now Playing" = "正在播放"; +"Screen Mirroring" = "屏幕镜像"; +"Stage Manager" = "台前调度"; +"Fast User Switching" = "快速用户切换"; +"Wi-Fi" = "Wi‑Fi"; +"Time Machine" = "时间机器"; +"Passwords" = "密码"; + +"left click" = "左键点击"; +"right click" = "右键点击"; + +"Arrow" = "箭头"; +"Chevron" = "人字"; +"Door" = "门"; +"Dot" = "圆点"; +"Ellipsis" = "省略号"; +"Ice Cube" = "冰块"; +"Sunglasses" = "墨镜"; +"Custom" = "自定义"; + +"General" = "通用"; +"Menu Bar Layout" = "菜单栏布局"; +"Menu Bar Appearance" = "菜单栏外观"; +"Hotkeys" = "快捷键"; +"Advanced" = "高级"; +"About" = "关于"; + +"Acknowledgements" = "致谢"; +"Contribute" = "参与贡献"; +"Report a Bug" = "报告问题"; +"Support Ice" = "支持 Ice"; +"Automatically check for updates" = "自动检查更新"; +"Automatically download updates" = "自动下载更新"; +"Last checked: %@" = "上次检查:%@"; +"Version %@" = "版本 %@"; +"Never" = "从不"; + +"Show Ice icon" = "显示 Ice 图标"; +"You can still access Ice's settings by right-clicking an empty area in the menu bar" = "你仍可以在菜单栏空白处右键打开 Ice 设置"; +"Ice icon" = "Ice 图标"; +"Choose image…" = "选择图像…"; +"Choose a custom icon to show in the menu bar" = "选择自定义图标显示在菜单栏"; +"Apply system theme to icon" = "将系统主题应用到图标"; +"Display the icon as a monochrome image matching the system appearance" = "将图标显示为与系统外观一致的单色图像"; +"Use Ice Bar" = "使用 Ice Bar"; +"Show hidden menu bar items in a separate bar below the menu bar" = "在菜单栏下方的单独栏中显示隐藏的菜单栏项目"; +"Location" = "位置"; +"The Ice Bar's location changes based on context" = "Ice Bar 的位置会根据上下文变化"; +"The Ice Bar is centered below the mouse pointer" = "Ice Bar 会居中显示在鼠标指针下方"; +"The Ice Bar is centered below the Ice icon" = "Ice Bar 会居中显示在 Ice 图标下方"; +"Show on click" = "点击时显示"; +"Click inside an empty area of the menu bar to show hidden menu bar items" = "点击菜单栏空白处以显示隐藏的菜单栏项目"; +"Show on hover" = "悬停时显示"; +"Hover over an empty area of the menu bar to show hidden menu bar items" = "将鼠标悬停在菜单栏空白处以显示隐藏的菜单栏项目"; +"Show on scroll" = "滚动时显示"; +"Scroll or swipe in the menu bar to toggle hidden menu bar items" = "在菜单栏中滚动或滑动以切换隐藏的菜单栏项目"; +"Apply" = "应用"; +"Apply the current spacing" = "应用当前间距"; +"Reset to the default spacing" = "恢复默认间距"; +"Menu bar item spacing" = "菜单栏项目间距"; +"Applying this setting will relaunch all apps with menu bar items. Some apps may need to be manually relaunched." = "应用此设置将重新启动所有带有菜单栏项目的应用。有些应用可能需要手动重新启动。"; +"Note: You may need to log out and back in for this setting to apply properly." = "注意:可能需要注销并重新登录才能正确应用此设置。"; +"Automatically rehide" = "自动重新隐藏"; +"Strategy" = "策略"; +"Menu bar items are rehidden using a smart algorithm" = "菜单栏项目会使用智能算法重新隐藏"; +"Menu bar items are rehidden after a fixed amount of time" = "菜单栏项目会在固定时间后重新隐藏"; +"Menu bar items are rehidden when the focused app changes" = "焦点应用变化时重新隐藏菜单栏项目"; + +"Hide application menus when showing menu bar items" = "显示菜单栏项目时隐藏应用菜单"; +"Make more room in the menu bar by hiding the left application menus if needed" = "需要时通过隐藏左侧应用菜单为菜单栏腾出空间"; +"Show section dividers" = "显示分区分隔符"; +"Insert divider items" = "插入分隔项"; +"between sections" = "在分区之间"; +"Enable always-hidden section" = "启用始终隐藏分区"; +"Always-hidden section can be shown" = "允许显示始终隐藏分区"; +"Option + click one of Ice's menu bar items, or inside an empty area of the menu bar to show the section" = "按住 Option 并点击 Ice 的某个菜单栏项目,或点击菜单栏空白处以显示该分区"; +"Option + click one of Ice's menu bar items to show the section" = "按住 Option 并点击 Ice 的某个菜单栏项目以显示该分区"; +"Show on hover delay" = "悬停显示延迟"; +"The amount of time to wait before showing on hover" = "悬停后显示前的等待时间"; +"Temporarily shown item delay" = "临时显示项目延迟"; +"The amount of time to wait before hiding temporarily shown menu bar items" = "临时显示的菜单栏项目在隐藏前的等待时间"; +"Show all sections when Command + dragging menu bar items" = "按住 Command 拖动菜单栏项目时显示所有分区"; +"Show context menu on right click" = "右键显示上下文菜单"; + +"Drag to arrange your menu bar items" = "拖动以排列菜单栏项目"; +"Tip: you can also arrange menu bar items by Command + dragging them in the menu bar" = "提示:也可以在菜单栏中按住 Command 并拖动来排列菜单栏项目"; +"Menu bar layout requires screen recording permissions" = "菜单栏布局需要屏幕录制权限"; +"Go to Advanced Settings" = "前往高级设置"; +"Ice cannot arrange menu bar items in automatically hidden menu bars" = "Ice 无法在自动隐藏的菜单栏中排列菜单栏项目"; + +"Menu Bar Shape" = "菜单栏形状"; +"Shape Kind" = "形状类型"; +"No shape kind selected" = "未选择形状类型"; +"None" = "无"; +"Full" = "完整"; +"Split" = "分割"; +"Square Cap" = "方形端帽"; +"Round Cap" = "圆角端帽"; +"Leading End Cap" = "前端端帽"; +"Trailing End Cap" = "后端端帽"; +"Tint" = "着色"; +"Shadow" = "阴影"; +"Border" = "边框"; +"Border Color" = "边框颜色"; +"Border Width" = "边框宽度"; +"Hold to Preview" = "按住预览"; +"Tip: you can also edit these settings by right-clicking in an empty area of the menu bar" = "提示:也可以在菜单栏空白处右键编辑这些设置"; +"Reset" = "重置"; +"Done" = "完成"; +"Use dynamic appearance" = "使用动态外观"; +"Apply different settings based on the current system appearance" = "根据当前系统外观应用不同设置"; +"Ice cannot edit the appearance of automatically hidden menu bars" = "Ice 无法编辑自动隐藏的菜单栏外观"; +"Use inset shape on screens with notch" = "在带刘海的屏幕上使用内嵌形状"; +"The Ice Bar requires screen recording permissions." = "Ice Bar 需要屏幕录制权限。"; +"Unable to display menu bar items" = "无法显示菜单栏项目"; + +"Solid" = "纯色"; +"Gradient" = "渐变"; + +"Dynamic" = "动态"; +"Mouse pointer" = "鼠标指针"; + +"Smart" = "智能"; +"Timed" = "定时"; +"Focused app" = "聚焦的应用"; + +"Menu Bar Sections" = "菜单栏分区"; +"Menu Bar Items" = "菜单栏项目"; +"Other" = "其他"; +"Toggle the hidden section" = "切换隐藏分区"; +"Toggle the always-hidden section" = "切换始终隐藏分区"; +"Enable the Ice Bar" = "启用 Ice Bar"; +"Toggle application menus" = "切换应用菜单"; +"Record Hotkey" = "录制快捷键"; +"Type Hotkey" = "输入快捷键"; +"ERROR" = "错误"; +"Hotkey is reserved by macOS" = "该快捷键被 macOS 保留"; +"OK" = "好"; + +"%@ second" = "%@ 秒"; +"%@ seconds" = "%@ 秒"; + +"none" = "无"; +"default" = "默认"; +"max" = "最大"; + + +"Ice can work in a limited mode without this permission." = "没有此权限时,Ice 仍可在受限模式下运行。"; +"Ice cannot display menu bar items for automatically hidden menu bars" = "Ice 无法在自动隐藏的菜单栏中显示菜单栏项目"; + + + diff --git a/Ice/Settings/SettingsPanes/AdvancedSettingsPane.swift b/Ice/Settings/SettingsPanes/AdvancedSettingsPane.swift index 47d19e5a..6c43481d 100644 --- a/Ice/Settings/SettingsPanes/AdvancedSettingsPane.swift +++ b/Ice/Settings/SettingsPanes/AdvancedSettingsPane.swift @@ -19,11 +19,12 @@ struct AdvancedSettingsPane: View { private func formattedToSeconds(_ interval: TimeInterval) -> LocalizedStringKey { let formatted = interval.formatted() - return if interval == 1 { - LocalizedStringKey(formatted + " second") + let localized = if interval == 1 { + String(format: NSLocalizedString("%@ second", comment: "Time interval (singular)"), formatted) } else { - LocalizedStringKey(formatted + " seconds") + String(format: NSLocalizedString("%@ seconds", comment: "Time interval (plural)"), formatted) } + return LocalizedStringKey(localized) } var body: some View { diff --git a/Ice/Settings/SettingsPanes/GeneralSettingsPane.swift b/Ice/Settings/SettingsPanes/GeneralSettingsPane.swift index 7991e003..ea63a766 100644 --- a/Ice/Settings/SettingsPanes/GeneralSettingsPane.swift +++ b/Ice/Settings/SettingsPanes/GeneralSettingsPane.swift @@ -37,11 +37,12 @@ struct GeneralSettingsPane: View { private var rehideIntervalKey: LocalizedStringKey { let formatted = manager.rehideInterval.formatted() - if manager.rehideInterval == 1 { - return LocalizedStringKey(formatted + " second") + let localized = if manager.rehideInterval == 1 { + String(format: NSLocalizedString("%@ second", comment: "Time interval (singular)"), formatted) } else { - return LocalizedStringKey(formatted + " seconds") + String(format: NSLocalizedString("%@ seconds", comment: "Time interval (plural)"), formatted) } + return LocalizedStringKey(localized) } private var hasSpacingSliderValueChanged: Bool { @@ -91,7 +92,7 @@ struct GeneralSettingsPane: View { @ViewBuilder private func menuItem(for imageSet: ControlItemImageSet) -> some View { Label { - Text(imageSet.name.rawValue) + Text(LocalizedStringKey(imageSet.name.rawValue)) } icon: { if let nsImage = imageSet.hidden.nsImage(for: appState) { switch imageSet.name { diff --git a/Ice/UI/IceBar/IceBar.swift b/Ice/UI/IceBar/IceBar.swift index 40c68982..8d8e7610 100644 --- a/Ice/UI/IceBar/IceBar.swift +++ b/Ice/UI/IceBar/IceBar.swift @@ -404,8 +404,14 @@ private struct IceBarItemView: View { IceBarItemClickView(item: item, leftClickAction: leftClickAction, rightClickAction: rightClickAction) } .accessibilityLabel(item.displayName) - .accessibilityAction(named: "left click", leftClickAction) - .accessibilityAction(named: "right click", rightClickAction) + .accessibilityAction( + named: NSLocalizedString("left click", comment: "Accessibility action"), + leftClickAction + ) + .accessibilityAction( + named: NSLocalizedString("right click", comment: "Accessibility action"), + rightClickAction + ) } } } diff --git a/Ice/UI/LayoutBar/LayoutBarItemView.swift b/Ice/UI/LayoutBar/LayoutBarItemView.swift index 74cb6f81..4b293e42 100644 --- a/Ice/UI/LayoutBar/LayoutBarItemView.swift +++ b/Ice/UI/LayoutBar/LayoutBarItemView.swift @@ -109,15 +109,24 @@ final class LayoutBarItemView: NSView { /// Provides an alert to display when the item view is disabled. func provideAlertForDisabledItem() -> NSAlert { let alert = NSAlert() - alert.messageText = "Menu bar item is not movable." - alert.informativeText = "macOS prohibits \"\(item.displayName)\" from being moved." + alert.messageText = NSLocalizedString("Menu bar item is not movable.", comment: "Alert title") + alert.informativeText = String( + format: NSLocalizedString("macOS prohibits \"%@\" from being moved.", comment: "Alert message"), + item.displayName + ) return alert } /// Provides an alert to display when a menu bar item is unresponsive. func provideAlertForUnresponsiveItem() -> NSAlert { let alert = provideAlertForDisabledItem() - alert.informativeText = "\(item.displayName) is unresponsive. Until it is restarted, it cannot be moved. Movement of other menu bar items may also be affected until this is resolved." + alert.informativeText = String( + format: NSLocalizedString( + "%@ is unresponsive. Until it is restarted, it cannot be moved. Movement of other menu bar items may also be affected until this is resolved.", + comment: "Alert message" + ), + item.displayName + ) return alert } diff --git a/Ice/Updates/UpdatesManager.swift b/Ice/Updates/UpdatesManager.swift index ee5f80d7..3caa5e10 100644 --- a/Ice/Updates/UpdatesManager.swift +++ b/Ice/Updates/UpdatesManager.swift @@ -77,7 +77,10 @@ final class UpdatesManager: NSObject, ObservableObject { #if DEBUG // Checking for updates hangs in debug mode. let alert = NSAlert() - alert.messageText = "Checking for updates is not supported in debug mode." + alert.messageText = NSLocalizedString( + "Checking for updates is not supported in debug mode.", + comment: "Alert title" + ) alert.runModal() #else guard let appState else { @@ -127,8 +130,11 @@ extension UpdatesManager: @preconcurrency SPUStandardUserDriverDelegate { if !state.userInitiated { appState.userNotificationManager.addRequest( with: .updateCheck, - title: "A new update is available", - body: "Version \(update.displayVersionString) is now available" + title: NSLocalizedString("A new update is available", comment: "Notification title"), + body: String( + format: NSLocalizedString("Version %@ is now available", comment: "Notification body"), + update.displayVersionString + ) ) } } diff --git a/Ice/Utilities/MigrationManager.swift b/Ice/Utilities/MigrationManager.swift index 0141e0bf..e6f3afe2 100644 --- a/Ice/Utilities/MigrationManager.swift +++ b/Ice/Utilities/MigrationManager.swift @@ -242,8 +242,14 @@ extension MigrationManager { } let alert = NSAlert() - alert.messageText = "Due to a bug in the 0.10.0 release, the data for Ice's menu bar items was corrupted and their positions had to be reset." - alert.informativeText = "Our sincerest apologies for the inconvenience." + alert.messageText = NSLocalizedString( + "Due to a bug in the 0.10.0 release, the data for Ice's menu bar items was corrupted and their positions had to be reset.", + comment: "Alert title" + ) + alert.informativeText = NSLocalizedString( + "Our sincerest apologies for the inconvenience.", + comment: "Alert message" + ) return .successButShowAlert(alert) } diff --git a/README.md b/README.md index efde40fb..0b45919a 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@

Ice

-Ice is a powerful menu bar management tool. While its primary function is hiding and showing menu bar items, it aims to cover a wide variety of additional features to make it one of the most versatile menu bar tools available. +Ice 是一款强大的菜单栏管理工具。它的核心能力是隐藏与显示菜单栏项目,同时也提供丰富的外观与交互选项,目标是成为最灵活的菜单栏工具之一。 -![Banner](https://github.com/user-attachments/assets/4423085c-4e4b-4f3d-ad0f-90a217c03470) +![Banner](docs/images/banner-zh.png) [![Download](https://img.shields.io/badge/download-latest-brightgreen?style=flat-square)](https://github.com/jordanbaird/Ice/releases/latest) ![Platform](https://img.shields.io/badge/platform-macOS-blue?style=flat-square) @@ -14,99 +14,104 @@ Ice is a powerful menu bar management tool. While its primary function is hiding [![Website](https://img.shields.io/badge/Website-015FBA?style=flat-square)](https://icemenubar.app) [![License](https://img.shields.io/github/license/jordanbaird/Ice?style=flat-square)](LICENSE) -> [!NOTE] -> Ice is currently in active development. Some features have not yet been implemented. Download the latest release [here](https://github.com/jordanbaird/Ice/releases/latest) and see the roadmap below for upcoming features. +English README → https://github.com/jordanbaird/Ice#readme - - Buy Me A Coffee - +## 中文说明 -## Install +Ice 是一款强大的菜单栏管理工具。它的核心能力是隐藏与显示菜单栏项目,同时也提供丰富的外观与交互选项,目标是成为最灵活的菜单栏工具之一。 -### Manual Installation +### 安装 -Download the "Ice.zip" file from the [latest release](https://github.com/jordanbaird/Ice/releases/latest) and move the unzipped app into your `Applications` folder. +#### 手动安装 -### Homebrew +从 [原版英文最新版本](https://github.com/jordanbaird/Ice/releases/latest) 下载 `Ice.zip`,或从 [简体中文汉化版](https://github.com/mianm1986/Ice/releases/tag/v0.11.12-zh) 下载 `Ice.zip`。解压后将 `Ice.app` 拖到 `Applications` 文件夹。 -Install Ice using the following command: +#### Homebrew ```sh brew install --cask jordanbaird-ice ``` -## Features/Roadmap +说明:Homebrew 安装的是原版英文版本。 -### Menu bar item management +### 功能/路线图 -- [x] Hide menu bar items -- [x] "Always-hidden" menu bar section -- [x] Show hidden menu bar items when hovering over the menu bar -- [x] Show hidden menu bar items when an empty area in the menu bar is clicked -- [x] Show hidden menu bar items by scrolling or swiping in the menu bar -- [x] Automatically rehide menu bar items -- [x] Hide application menus when they overlap with shown menu bar items -- [x] Drag and drop interface to arrange individual menu bar items -- [x] Display hidden menu bar items in a separate bar (e.g. for MacBooks with the notch) -- [x] Search menu bar items -- [x] Menu bar item spacing (BETA) -- [ ] Profiles for menu bar layout -- [ ] Individual spacer items -- [ ] Menu bar item groups -- [ ] Show menu bar items when trigger conditions are met +#### 菜单栏项目管理 -### Menu bar appearance +- [x] 隐藏菜单栏项目 +- [x] “始终隐藏”分区 +- [x] 鼠标悬停时显示隐藏项目 +- [x] 点击菜单栏空白处显示隐藏项目 +- [x] 滚动或滑动显示隐藏项目 +- [x] 自动重新隐藏 +- [x] 隐藏会与菜单栏项目重叠的应用菜单 +- [x] 拖拽排序菜单栏项目 +- [x] 在独立栏中显示隐藏项目(例如带刘海的 Mac) +- [x] 搜索菜单栏项目 +- [x] 菜单栏项目间距(测试版) +- [ ] 菜单栏布局配置文件 +- [ ] 独立分隔项 +- [ ] 菜单栏项目分组 +- [ ] 满足触发条件时显示项目 -- [x] Menu bar tint (solid and gradient) -- [x] Menu bar shadow -- [x] Menu bar border -- [x] Custom menu bar shapes (rounded and/or split) -- [ ] Remove background behind menu bar -- [ ] Rounded screen corners -- [ ] Different settings for light/dark mode +#### 菜单栏外观 -### Hotkeys +- [x] 菜单栏着色(纯色与渐变) +- [x] 菜单栏阴影 +- [x] 菜单栏边框 +- [x] 自定义菜单栏形状(圆角与分割) +- [ ] 移除菜单栏背景 +- [ ] 屏幕圆角 +- [ ] 深色/浅色模式分别配置 -- [x] Toggle individual menu bar sections -- [x] Show the search panel -- [x] Enable/disable the Ice Bar -- [x] Show/hide section divider icons -- [x] Toggle application menus -- [ ] Enable/disable auto rehide -- [ ] Temporarily show individual menu bar items +#### 快捷键 -### Other +- [x] 切换各菜单栏分区 +- [x] 打开搜索面板 +- [x] 启用/停用 Ice Bar +- [x] 显示/隐藏分区分隔图标 +- [x] 切换应用菜单 +- [ ] 启用/停用自动重新隐藏 +- [ ] 临时显示单个菜单栏项目 -- [x] Launch at login -- [x] Automatic updates -- [ ] Menu bar widgets +#### 其他 -## Why does Ice only support macOS 14 and later? +- [x] 开机自启 +- [x] 自动更新 +- [ ] 菜单栏小组件 -Ice uses a number of system APIs that are available starting in macOS 14. As such, there are no plans to support earlier versions of macOS. +### 为什么只支持 macOS 14 及以上? -## Gallery +Ice 使用了从 macOS 14 开始提供的一些系统 API,因此目前没有支持更早版本的计划。 -#### Show hidden menu bar items below the menu bar +### 截图 + +#### 在菜单栏下方显示隐藏项目 ![Ice Bar](https://github.com/user-attachments/assets/f1429589-6186-4e1b-8aef-592219d49b9b) -#### Drag-and-drop interface to arrange menu bar items +#### 拖拽排序菜单栏项目 -![Menu Bar Layout](https://github.com/user-attachments/assets/095442ba-f2d0-4bb4-9632-91e26ef8d45b) +![Menu Bar Layout](docs/images/menu-bar-layout-zh.png) -#### Customize the menu bar's appearance +#### 自定义菜单栏外观 ![Menu Bar Appearance](https://github.com/user-attachments/assets/8c22c185-c3d2-49bb-971e-e1fc17df04b3) -#### Menu bar item search +#### 菜单栏项目搜索 ![Menu Bar Item Search](https://github.com/user-attachments/assets/d1a7df3a-4989-4077-a0b1-8e7d5a1ba5b8) -#### Custom menu bar item spacing +#### 菜单栏项目间距 ![Menu Bar Item Spacing](https://github.com/user-attachments/assets/b196aa7e-184a-4d4c-b040-502f4aae40a6) -## License +### 许可协议 + +Ice 使用 [GPL-3.0 license](LICENSE) 许可发布。 -Ice is available under the [GPL-3.0 license](LICENSE). +### 赞助 + + + Buy Me A Coffee + diff --git a/docs/images/banner-zh.png b/docs/images/banner-zh.png new file mode 100644 index 00000000..aa947ba6 Binary files /dev/null and b/docs/images/banner-zh.png differ diff --git a/docs/images/menu-bar-layout-zh.png b/docs/images/menu-bar-layout-zh.png new file mode 100644 index 00000000..f33e5504 Binary files /dev/null and b/docs/images/menu-bar-layout-zh.png differ