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
24 changes: 24 additions & 0 deletions Easydict.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@
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 */; };
6A8C98952BAE841600DB835A /* EZLocalizedBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A8C98942BAE841600DB835A /* EZLocalizedBundle.swift */; };
6ADED1552BAE8809004A15BE /* NSBundle+LanguagePreference.m in Sources */ = {isa = PBXBuildFile; fileRef = 6ADED1542BAE8809004A15BE /* NSBundle+LanguagePreference.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 +804,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>"; };
6A8C98942BAE841600DB835A /* EZLocalizedBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZLocalizedBundle.swift; sourceTree = "<group>"; };
6ADED1542BAE8809004A15BE /* NSBundle+LanguagePreference.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+LanguagePreference.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 @@ -2156,6 +2164,7 @@
27FE98032B3DCA9F000AD654 /* NewApp */ = {
isa = PBXGroup;
children = (
6A8C988B2BAC88A600DB835A /* LanguagePreference */,
967712EB2B5B93E200105E0F /* Feature */,
EA9943E12B534C2900EE7B97 /* Model */,
EA9943DD2B534BAE00EE7B97 /* Utility */,
Expand Down Expand Up @@ -2240,6 +2249,17 @@
path = EZWrapView;
sourceTree = "<group>";
};
6A8C988B2BAC88A600DB835A /* LanguagePreference */ = {
isa = PBXGroup;
children = (
6A8C988D2BAC88B500DB835A /* EZI18nHelper.swift */,
6A8C988C2BAC88B500DB835A /* LanguageState.swift */,
6A8C98942BAE841600DB835A /* EZLocalizedBundle.swift */,
6ADED1542BAE8809004A15BE /* NSBundle+LanguagePreference.m */,
);
path = LanguagePreference;
sourceTree = "<group>";
};
713A345D86B5BC86D158B68F /* Frameworks */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2880,6 +2900,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 Down Expand Up @@ -2927,6 +2948,7 @@
03B0230229231FA6001C7E63 /* EZWordResultView.m in Sources */,
0399C6A529A747E600B4AFCC /* EZDeepLTranslateResponse.m in Sources */,
17BCAEF82B0DFF9000A7D372 /* EZNiuTransTranslate.m in Sources */,
6A8C98952BAE841600DB835A /* EZLocalizedBundle.swift in Sources */,
039F5506294B6E29004AB940 /* EZSettingViewController.m in Sources */,
03BD281E29481C0400F5891A /* EZAudioPlayer.m in Sources */,
0A8685C82B552A590022534F /* DisabledAppTab.swift in Sources */,
Expand Down Expand Up @@ -3004,9 +3026,11 @@
03B0231729231FA6001C7E63 /* Snip.m in Sources */,
03BFFC6E295FE59C004E033E /* EZQueryResult+EZYoudaoDictModel.m in Sources */,
DC3C643F2B187119008EEDD8 /* ChangeFontSizeView.swift in Sources */,
6ADED1552BAE8809004A15BE /* NSBundle+LanguagePreference.m in Sources */,
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
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];
choykarl marked this conversation as resolved.
Show resolved Hide resolved
}

- (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
42 changes: 42 additions & 0 deletions Easydict/NewApp/LanguagePreference/EZI18nHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// EZI18nHelper.swift
// Easydict
//
// Created by choykarl on 2024/3/4.
// Copyright © 2024 izual. All rights reserved.
//

import SwiftUI

// MARK: - EZI18nHelper

@objcMembers
class EZI18nHelper: NSObject {
choykarl marked this conversation as resolved.
Show resolved Hide resolved
static let languagePreferenceChangedNotification = "EZLanguagePreferenceChangedNotification"
choykarl marked this conversation as resolved.
Show resolved Hide resolved
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
}
choykarl marked this conversation as resolved.
Show resolved Hide resolved
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
}
}
15 changes: 15 additions & 0 deletions Easydict/NewApp/LanguagePreference/EZLocalizedBundle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// EZLocalizedBundle.swift
// Easydict
//
// Created by choykarl on 2024/3/23.
// Copyright © 2024 izual. All rights reserved.
//

import Foundation

class EZLocalizedBundle: Bundle {
choykarl marked this conversation as resolved.
Show resolved Hide resolved
override func localizedString(forKey key: String, value: String?, table tableName: String?) -> String {
EZI18nHelper.shared.localizedBundle.localizedString(forKey: key, value: value, table: tableName)
}
}
44 changes: 44 additions & 0 deletions Easydict/NewApp/LanguagePreference/LanguageState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// LanguageState.swift
// Easydict
//
// Created by choykarl on 2024/3/3.
// Copyright © 2024 izual. All rights reserved.
//

import SwiftUI

// MARK: - LanguageState

let kEZLanguagePreferenceLocalKey = "kEZLanguagePreferenceLocalKey"
choykarl marked this conversation as resolved.
Show resolved Hide resolved

// MARK: - LanguageState

class LanguageState: ObservableObject {
enum LanguageType: String, CaseIterable {
case english = "en"
case simplifiedChinese = "zh-Hans"

// MARK: Internal

var name: String {
switch self {
case .english:
"English"
case .simplifiedChinese:
"简体中文"
}
}
}

@AppStorage(kEZLanguagePreferenceLocalKey) var language: LanguageType = (.init(
rawValue: Locale.current.identifier
) ?? .simplifiedChinese) {
didSet {
NotificationCenter.default.post(
name: NSNotification.Name(rawValue: EZI18nHelper.languagePreferenceChangedNotification),
object: nil
)
}
}
}
20 changes: 20 additions & 0 deletions Easydict/NewApp/LanguagePreference/NSBundle+LanguagePreference.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// LanguagePreference.m
// Easydict
//
// Created by choykarl on 2024/3/23.
// Copyright © 2024 izual. All rights reserved.
//

#import <objc/runtime.h>

@implementation NSBundle (LanguagePreference)

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

@end
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ extension Language {
}

public var localizedName: String {
if EZLanguageManager.shared().isSystemChineseFirstLanguage() {
if EZI18nHelper.shared.isSimplifiedChineseLocalize {
chineseName
} else {
if self == .auto {
Expand Down
Loading