Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App Language preference #468

Merged
merged 12 commits into from
Mar 24, 2024
30 changes: 30 additions & 0 deletions Easydict.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,9 @@
62E2BF4B2B4082BA00E42D38 /* AliResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E2BF482B4082BA00E42D38 /* AliResponse.swift */; };
62E2BF4C2B4082BA00E42D38 /* AliTranslateType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62E2BF492B4082BA00E42D38 /* AliTranslateType.swift */; };
62ED29A22B15F1F500901F51 /* EZWrapView.m in Sources */ = {isa = PBXBuildFile; fileRef = 62ED29A12B15F1F500901F51 /* EZWrapView.m */; };
6A8C988E2BAC88B500DB835A /* LanguageState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A8C988C2BAC88B500DB835A /* LanguageState.swift */; };
6A8C988F2BAC88B500DB835A /* EZI18nHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A8C988D2BAC88B500DB835A /* EZI18nHelper.swift */; };
6A8C98932BAC8C0A00DB835A /* EZLocalizedBundle.m in Sources */ = {isa = PBXBuildFile; fileRef = 6A8C98922BAC8C0A00DB835A /* EZLocalizedBundle.m */; };
960835502B6791F200C6A931 /* Shortcut+Validator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9608354F2B6791F200C6A931 /* Shortcut+Validator.swift */; };
96099AE22B5D40330055C4DD /* ShortcutTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96099AE12B5D40330055C4DD /* ShortcutTab.swift */; };
9627F9382B59956800B1E999 /* GlobalShortcutSetting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9627F9352B59956800B1E999 /* GlobalShortcutSetting.swift */; };
Expand Down Expand Up @@ -800,6 +803,10 @@
62ED29A02B15F1F500901F51 /* EZWrapView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZWrapView.h; sourceTree = "<group>"; };
62ED29A12B15F1F500901F51 /* EZWrapView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZWrapView.m; sourceTree = "<group>"; };
6372B33DFF803C7096A82250 /* Pods_Easydict.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Easydict.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6A8C988C2BAC88B500DB835A /* LanguageState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LanguageState.swift; sourceTree = "<group>"; };
6A8C988D2BAC88B500DB835A /* EZI18nHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EZI18nHelper.swift; sourceTree = "<group>"; };
6A8C98912BAC8C0A00DB835A /* EZLocalizedBundle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZLocalizedBundle.h; sourceTree = "<group>"; };
6A8C98922BAC8C0A00DB835A /* EZLocalizedBundle.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZLocalizedBundle.m; sourceTree = "<group>"; };
91E3E579C6DB88658B4BB102 /* Pods-Easydict.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Easydict.release.xcconfig"; path = "Target Support Files/Pods-Easydict/Pods-Easydict.release.xcconfig"; sourceTree = "<group>"; };
9608354F2B6791F200C6A931 /* Shortcut+Validator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Shortcut+Validator.swift"; sourceTree = "<group>"; };
96099AE12B5D40330055C4DD /* ShortcutTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutTab.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1237,6 +1244,7 @@
038954372A25A94E00EFFDC3 /* Utility */ = {
isa = PBXGroup;
children = (
6A8C98902BAC8BDD00DB835A /* LanguagePreference */,
03CF88602B137ECB0030C199 /* Swift */,
03CAB9522ADBEF5000DA94A3 /* SystemUtility */,
030570DF2ADB916E00C9905E /* AppleScript */,
Expand Down Expand Up @@ -2156,6 +2164,7 @@
27FE98032B3DCA9F000AD654 /* NewApp */ = {
isa = PBXGroup;
children = (
6A8C988B2BAC88A600DB835A /* LanguagePreference */,
967712EB2B5B93E200105E0F /* Feature */,
EA9943E12B534C2900EE7B97 /* Model */,
EA9943DD2B534BAE00EE7B97 /* Utility */,
Expand Down Expand Up @@ -2240,6 +2249,24 @@
path = EZWrapView;
sourceTree = "<group>";
};
6A8C988B2BAC88A600DB835A /* LanguagePreference */ = {
isa = PBXGroup;
children = (
6A8C988D2BAC88B500DB835A /* EZI18nHelper.swift */,
6A8C988C2BAC88B500DB835A /* LanguageState.swift */,
);
path = LanguagePreference;
sourceTree = "<group>";
};
6A8C98902BAC8BDD00DB835A /* LanguagePreference */ = {
isa = PBXGroup;
children = (
6A8C98912BAC8C0A00DB835A /* EZLocalizedBundle.h */,
6A8C98922BAC8C0A00DB835A /* EZLocalizedBundle.m */,
);
path = LanguagePreference;
sourceTree = "<group>";
};
713A345D86B5BC86D158B68F /* Frameworks */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2880,6 +2907,7 @@
960835502B6791F200C6A931 /* Shortcut+Validator.swift in Sources */,
03542A522937B69200C34C33 /* EZYoudaoTranslateResponse.m in Sources */,
03B0230129231FA6001C7E63 /* EZQueryView.m in Sources */,
6A8C988E2BAC88B500DB835A /* LanguageState.swift in Sources */,
03542A3D2937AF4F00C34C33 /* EZQueryResult.m in Sources */,
03262C1F29EF8EE500EFECA0 /* EZPrivacyViewController.m in Sources */,
9672D7D22B4008B40023B8FB /* MASShortcutBinder+EZMASShortcutBinder.m in Sources */,
Expand All @@ -2898,6 +2926,7 @@
03B0230429231FA6001C7E63 /* EZHoverButton.m in Sources */,
0342A9812AD64924002A9F5F /* NSString+EZSplit.m in Sources */,
EAED41EF2B54B1430005FE0A /* ConfigurableService.swift in Sources */,
6A8C98932BAC8C0A00DB835A /* EZLocalizedBundle.m in Sources */,
03BD2825294875AE00F5891A /* EZMyLabel.m in Sources */,
03B0233029231FA6001C7E63 /* MMCrashUncaughtExceptionHandler.m in Sources */,
03D5FCFF2A5EF4E400AD26BE /* EZDeviceSystemInfo.m in Sources */,
Expand Down Expand Up @@ -3007,6 +3036,7 @@
03B0232829231FA6001C7E63 /* NSTextView+Height.m in Sources */,
03B0232129231FA6001C7E63 /* NSPasteboard+MM.m in Sources */,
03D043522928935300E7559E /* EZMainQueryWindow.m in Sources */,
6A8C988F2BAC88B500DB835A /* EZI18nHelper.swift in Sources */,
03D8B26E292DBD2000D5A811 /* EZCoordinateUtils.m in Sources */,
03B0232029231FA6001C7E63 /* NSWindow+MM.m in Sources */,
0AC8A8432B6957B0006DA5CC /* BingService+ConfigurableService.swift in Sources */,
Expand Down
51 changes: 34 additions & 17 deletions Easydict/App/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -1761,6 +1761,23 @@
}
}
},
"language_preference" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Display Language"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "显示语言"
}
}
}
},
"large" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -2675,22 +2692,6 @@
}
}
},
"service.configuration.custom_openai.name.title" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Custom Service Name"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "自定义服务名称"
}
}
}
},
"service.configuration.custom_openai.model.placeholder" : {
"localizations" : {
"en" : {
Expand All @@ -2707,6 +2708,22 @@
}
}
},
"service.configuration.custom_openai.name.title" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Custom Service Name"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "自定义服务名称"
}
}
}
},
"service.configuration.custom_openai.supported_models.title" : {
"localizations" : {
"en" : {
Expand Down Expand Up @@ -4634,4 +4651,4 @@
}
},
"version" : "1.0"
}
}
2 changes: 2 additions & 0 deletions Easydict/App/PrefixHeader.pch
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@
#import "EZConst.h"
#import "EZConstKey.h"
#import "NSString+EZConvenience.h"

#import "Easydict-Swift.h"
2 changes: 1 addition & 1 deletion Easydict/Feature/Service/Language/EZLanguageManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ - (NSString *)languageLocalName:(EZLanguage)language {
/// Showing language name according user first language, Chinese: English -> 英语, English: English -> English.
- (NSString *)showingLanguageName:(EZLanguage)language {
NSString *languageName = language ?: EZLanguageAuto;
if ([self isSystemChineseFirstLanguage]) {
if (EZI18nHelper.shared.isSimplifiedChineseLocalize) {
languageName = [self languageChineseName:language];
} else {
if ([language isEqualToString:EZLanguageAuto]) {
Expand Down
6 changes: 3 additions & 3 deletions Easydict/Feature/Utility/EZCategory/NSObject+EZWindowType.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@

#import "NSObject+EZWindowType.h"

static NSString *EZWindowTypeKey = @"EZWindowTypeKey";
static NSString *_EZWindowTypeKey = @"EZWindowTypeKey";

@implementation NSObject (EZWindowType)

- (void)setWindowType:(EZWindowType)windowType {
objc_setAssociatedObject(self, (__bridge const void *)(EZWindowTypeKey), @(windowType), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(self, (__bridge const void *)(_EZWindowTypeKey), @(windowType), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (EZWindowType)windowType {
return [objc_getAssociatedObject(self, (__bridge const void *)(EZWindowTypeKey)) integerValue];
return [objc_getAssociatedObject(self, (__bridge const void *)(_EZWindowTypeKey)) integerValue];
}

@end
17 changes: 17 additions & 0 deletions Easydict/Feature/Utility/LanguagePreference/EZLocalizedBundle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// EZLocalizedBundle.h
// Easydict
//
// Created by choykarl on 2024/3/21.
// Copyright © 2024 izual. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface EZLocalizedBundle : NSBundle

@end

NS_ASSUME_NONNULL_END
43 changes: 43 additions & 0 deletions Easydict/Feature/Utility/LanguagePreference/EZLocalizedBundle.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// EZLocalizedBundle.m
// Easydict
//
// Created by choykarl on 2024/3/21.
// Copyright © 2024 izual. All rights reserved.
//

#import "EZLocalizedBundle.h"
#import <objc/runtime.h>

@implementation NSBundle (localized)

+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
object_setClass([NSBundle mainBundle], [EZLocalizedBundle class]);
});
}

@end

@implementation EZLocalizedBundle
- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName {
NSBundle *localizedBundle = [self localizedBundle];
if (localizedBundle) {
return [localizedBundle localizedStringForKey:key value:value table:tableName];
} else {
return [super localizedStringForKey:key value:value table:tableName];
}
}

- (NSBundle *)localizedBundle {
NSString *localizeCode = EZI18nHelper.shared.localizeCode;
if (localizeCode.length) {
NSString *path = [[NSBundle mainBundle] pathForResource:localizeCode ofType:@"lproj"];
if (path.length) {
return [NSBundle bundleWithPath:path];
}
}
return nil;
}
@end
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ - (void)setupMenu {
NSString *languageFlag = [languageManager languageFlagEmoji:language];

if ([language isEqualToString:EZLanguageAuto]) {
if ([languageManager isSystemChineseFirstLanguage] && self.autoChineseSelectedTitle.length) {
if (EZI18nHelper.shared.isSimplifiedChineseLocalize && self.autoChineseSelectedTitle.length) {
languageName = self.autoChineseSelectedTitle;
}
}
Expand Down Expand Up @@ -170,7 +170,7 @@ - (void)setSelectedLanguage:(EZLanguage)selectedLanguage {
NSString *toolTip = nil;

if ([selectedLanguage isEqualToString:EZLanguageAuto]) {
if ([languageManager isSystemChineseFirstLanguage] && self.autoChineseSelectedTitle.length) {
if (EZI18nHelper.shared.isSimplifiedChineseLocalize && self.autoChineseSelectedTitle.length) {
languageName = self.autoChineseSelectedTitle;
}
languageFlag = [languageManager languageFlagEmoji:self.autoSelectedLanguage];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ - (void)setupUI {
[self updateAllResultCellHeight];
}];
}];

[defaultCenter addObserver:self selector:@selector(modifyLanduage:) name:EZI18nHelper.languagePreferenceChangedNotification object:nil];
}

- (void)modifyLanduage:(NSNotification *)notification {
[self.tableView reloadData];
}


Expand Down
8 changes: 7 additions & 1 deletion Easydict/NewApp/EasydictApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ struct EasydictApp: App {
if #available(macOS 13, *) {
MenuBarExtra(isInserted: $hideMenuBar.toggledValue) {
MenuItemView()
.environmentObject(languageState)
.environment(\.locale, .init(identifier: EZI18nHelper.shared.localizeCode))
} label: {
Label {
Text("Easydict")
Expand Down Expand Up @@ -62,7 +64,10 @@ struct EasydictApp: App {
.windowResizability(.contentSize)

Settings {
SettingView()
SettingView().environmentObject(languageState).environment(
\.locale,
.init(identifier: EZI18nHelper.shared.localizeCode)
)
}
}
}
Expand All @@ -77,6 +82,7 @@ struct EasydictApp: App {
private var hideMenuBar = Defaults.Key<Bool>.hideMenuBarIcon.defaultValue

@Default(.selectedMenuBarIcon) private var menuBarIcon
@StateObject private var languageState = LanguageState()
}

// MARK: - FakeViewToOpenSettingsInSonoma
Expand Down
46 changes: 46 additions & 0 deletions Easydict/NewApp/LanguagePreference/EZI18nHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// EZI18nHelper.swift
// Easydict
//
// Created by choykarl on 2024/3/4.
// Copyright © 2024 izual. All rights reserved.
//

import SwiftUI

var localizedBundle: Bundle {
EZI18nHelper.shared.localizedBundle
}

// MARK: - EZI18nHelper

@objcMembers
class EZI18nHelper: NSObject {
static let languagePreferenceChangedNotification = "EZLanguagePreferenceChangedNotification"
static let shared = EZI18nHelper()

var localizedBundle: Bundle {
let res = localizeCode
let path = Bundle.main.path(forResource: res, ofType: "lproj")
let bundle: Bundle
if let path = path {
bundle = Bundle(path: path) ?? .main
} else {
bundle = .main
}
return bundle
}

var localizeCode: String {
UserDefaults.standard.string(forKey: kEZLanguagePreferenceLocalKey) ?? LanguageState.LanguageType
.simplifiedChinese.rawValue
}

var languageType: LanguageState.LanguageType {
LanguageState.LanguageType(rawValue: localizeCode) ?? .simplifiedChinese
}

var isSimplifiedChineseLocalize: Bool {
localizeCode == LanguageState.LanguageType.simplifiedChinese.rawValue
}
}
Loading