From cbcf8c419761ad5220740d1338949b96f3870446 Mon Sep 17 00:00:00 2001 From: CodeST <694468528@qq.com> Date: Sat, 7 Mar 2026 13:29:29 +0800 Subject: [PATCH] =?UTF-8?q?key=E7=BC=BA=E5=B0=91=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=9D=83=E9=99=90=E5=A4=9A=E8=AF=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../KeyboardViewController+Chat.m | 36 ++--- .../KeyboardViewController+Legacy.m | 38 ++--- .../KeyboardViewController+Panels.m | 4 +- .../KeyboardViewController+Subscription.m | 2 +- CustomKeyboard/Network/NetworkStreamHandler.m | 7 +- .../View/Buy/KBKeyboardSubscriptionView.m | 6 +- CustomKeyboard/View/Chat/KBChatPanelView.m | 4 +- CustomKeyboard/View/KBChatMessageCell.m | 4 +- CustomKeyboard/View/KBFullAccessGuideView.m | 4 +- CustomKeyboard/View/KBFunctionPasteView.m | 1 - CustomKeyboard/View/KBFunctionView.m | 18 +-- .../Localization/en.lproj/InfoPlist.strings | 3 + .../Localization/en.lproj/Localizable.strings | 142 ++++++++++++++++++ .../Localization/es.lproj/InfoPlist.strings | 3 + .../Localization/es.lproj/Localizable.strings | 142 ++++++++++++++++++ .../Localization/id.lproj/InfoPlist.strings | 3 + .../Localization/id.lproj/Localizable.strings | 142 ++++++++++++++++++ .../pt-PT.lproj/InfoPlist.strings | 3 + .../pt-PT.lproj/Localizable.strings | 142 ++++++++++++++++++ .../zh-Hant.lproj/InfoPlist.strings | 3 + .../zh-Hant.lproj/Localizable.strings | 142 ++++++++++++++++++ keyBoard.xcodeproj/project.pbxproj | 138 ++++++++++------- .../Class/AiTalk/V/Chat/KBPersonaChatCell.m | 4 +- keyBoard/Class/AiTalk/VC/AIPersonInfoVC.m | 2 +- keyBoard/Class/AiTalk/VC/AIReportVC.m | 2 +- keyBoard/Class/AiTalk/VC/KBAIHomeVC.m | 8 +- .../Class/AiTalk/VM/KBVoiceToTextManager.m | 44 ++++-- keyBoard/Class/Common/V/KBAppUpdateView.m | 18 +-- keyBoard/Class/Guard/VC/KBSexSelVC.m | 12 +- keyBoard/Class/Home/V/HomeHeadView.m | 12 +- .../Home/VC/FunctionTest/KBSkinCenterVC.m | 13 +- .../Class/Home/VC/FunctionTest/KBTestVC.m | 4 +- keyBoard/Class/Login/V/KBLoginPopView.m | 2 +- keyBoard/Class/Login/VC/KBEmailLoginVC.m | 12 +- keyBoard/Class/Login/VC/KBEmailRegistVC.m | 18 +-- keyBoard/Class/Login/VC/KBLoginVC.m | 12 +- keyBoard/Class/Login/VC/LoginViewController.m | 2 +- keyBoard/Class/Manager/KBSkinService.m | 9 +- keyBoard/Class/Me/V/KBSkinSectionTitleCell.m | 4 +- keyBoard/Class/Me/VC/MySkinVC.m | 2 +- keyBoard/Class/Pay/V/KBVipSubscribeCell.m | 4 +- keyBoard/Class/Pay/VC/KBJfPay.m | 2 +- keyBoard/Class/Pay/VC/KBPayMainVC.m | 4 +- keyBoard/Class/Pay/VC/KBPaySvipVC.m | 6 +- keyBoard/Class/Shop/VC/KBShopItemVC.m | 10 -- keyBoard/Class/Shop/VC/KBSkinDetailVC.m | 12 +- keyBoard/VC/KBPermissionViewController.m | 6 +- 47 files changed, 986 insertions(+), 225 deletions(-) create mode 100644 Shared/Localization/en.lproj/InfoPlist.strings create mode 100644 Shared/Localization/es.lproj/InfoPlist.strings create mode 100644 Shared/Localization/id.lproj/InfoPlist.strings create mode 100644 Shared/Localization/pt-PT.lproj/InfoPlist.strings create mode 100644 Shared/Localization/zh-Hant.lproj/InfoPlist.strings diff --git a/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Chat.m b/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Chat.m index f63f0ee..b333d0f 100644 --- a/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Chat.m +++ b/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Chat.m @@ -106,7 +106,7 @@ static const NSUInteger kKBChatMessageLimit = 6; } } if (trim.length == 0) { - [KBHUD showInfo:KBLocalized(@"请输入内容")]; + [KBHUD showInfo:KBLocalized(@"Please enter content")]; return; } [self kb_sendChatText:trim]; @@ -128,7 +128,7 @@ static const NSUInteger kKBChatMessageLimit = 6; [self kb_prefetchAvatarForMessage:outgoing]; if (![[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self.view]) { - [KBHUD showInfo:KBLocalized(@"请开启完全访问后使用")]; + [KBHUD showInfo:KBLocalized(@"Please enable Full Access to continue")]; return; } @@ -259,12 +259,12 @@ static const NSUInteger kKBChatMessageLimit = 6; if (mockPath.length > 0) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.35 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - NSString *displayText = KBLocalized(@"语音回复"); + NSString *displayText = KBLocalized(@"Voice reply"); KBChatMessage *incoming = [KBChatMessage messageWithText:displayText outgoing:NO audioFilePath:mockPath]; - incoming.displayName = KBLocalized(@"AI助手"); + incoming.displayName = KBLocalized(@"AI Assistant"); [self kb_appendChatMessage:incoming]; [self kb_playChatAudioAtPath:mockPath]; }); @@ -284,7 +284,7 @@ static const NSUInteger kKBChatMessageLimit = 6; } if (error) { NSString *tip = error.localizedDescription - ?: KBLocalized(@"请求失败"); + ?: KBLocalized(@"Request failed"); [KBHUD showInfo:tip]; return; } @@ -304,7 +304,7 @@ static const NSUInteger kKBChatMessageLimit = 6; initWithBase64EncodedString:audioBase64 options:0]; if (data.length == 0) { - [KBHUD showInfo:KBLocalized(@"音频数据解析失败")]; + [KBHUD showInfo:KBLocalized(@"Failed to parse audio data")]; return; } [self kb_handleChatAudioData:data @@ -312,7 +312,7 @@ static const NSUInteger kKBChatMessageLimit = 6; displayText:displayText]; return; } - [KBHUD showInfo:KBLocalized(@"未获取到音频文件")]; + [KBHUD showInfo:KBLocalized(@"No audio file received")]; }); }]; } @@ -352,7 +352,7 @@ static const NSUInteger kKBChatMessageLimit = 6; [self.chatPanelView kb_removeLoadingAssistantMessage]; [KBHUD showInfo:response.message - ?: KBLocalized(@"请求失败")]; + ?: KBLocalized(@"Request failed")]; return; } @@ -362,7 +362,7 @@ static const NSUInteger kKBChatMessageLimit = 6; if (response.data.aiResponse.length == 0) { [self.chatPanelView kb_removeLoadingAssistantMessage]; - [KBHUD showInfo:KBLocalized(@"未获取到回复内容")]; + [KBHUD showInfo:KBLocalized(@"No reply content received")]; return; } @@ -450,13 +450,13 @@ static const NSUInteger kKBChatMessageLimit = 6; if (!response.success) { [KBHUD showInfo:response.errorMessage - ?: KBLocalized(@"下载失败")]; + ?: KBLocalized(@"Download failed")]; return; } if (!response.audioData || response.audioData.length == 0) { - [KBHUD showInfo:KBLocalized(@"未获取到音频数据")]; + [KBHUD showInfo:KBLocalized(@"No audio data received")]; return; } @@ -475,7 +475,7 @@ static const NSUInteger kKBChatMessageLimit = 6; fileExtension:(NSString *)extension displayText:(NSString *)displayText { if (data.length == 0) { - [KBHUD showInfo:KBLocalized(@"音频数据为空")]; + [KBHUD showInfo:KBLocalized(@"Audio data is empty")]; return; } NSString *ext = extension.length > 0 ? extension : @"m4a"; @@ -487,14 +487,14 @@ static const NSUInteger kKBChatMessageLimit = 6; NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName]; if (![data writeToFile:filePath atomically:YES]) { - [KBHUD showInfo:KBLocalized(@"音频保存失败")]; + [KBHUD showInfo:KBLocalized(@"Failed to save audio")]; return; } NSString *text = - displayText.length > 0 ? displayText : KBLocalized(@"语音消息"); + displayText.length > 0 ? displayText : KBLocalized(@"Voice message"); KBChatMessage *incoming = [KBChatMessage messageWithText:text outgoing:NO audioFilePath:filePath]; - incoming.displayName = KBLocalized(@"AI助手"); + incoming.displayName = KBLocalized(@"AI Assistant"); [self kb_appendChatMessage:incoming]; } @@ -594,7 +594,7 @@ static const NSUInteger kKBChatMessageLimit = 6; } NSURL *url = [NSURL fileURLWithPath:path]; if (![NSFileManager.defaultManager fileExistsAtPath:path]) { - [KBHUD showInfo:KBLocalized(@"音频文件不存在")]; + [KBHUD showInfo:KBLocalized(@"Audio file does not exist")]; return; } @@ -624,7 +624,7 @@ static const NSUInteger kKBChatMessageLimit = 6; AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&playerError]; if (playerError || !player) { - [KBHUD showInfo:KBLocalized(@"音频播放失败")]; + [KBHUD showInfo:KBLocalized(@"Audio playback failed")]; return; } self.chatAudioPlayer = player; @@ -664,7 +664,7 @@ static const NSUInteger kKBChatMessageLimit = 6; if (playerError || !player) { NSLog(@"[Keyboard] 音频播放器初始化失败: %@", playerError.localizedDescription); - [KBHUD showInfo:KBLocalized(@"音频播放失败")]; + [KBHUD showInfo:KBLocalized(@"Audio playback failed")]; return; } diff --git a/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Legacy.m b/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Legacy.m index c7999cb..15f85ee 100644 --- a/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Legacy.m +++ b/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Legacy.m @@ -758,7 +758,7 @@ static NSString *KBFormatMB(uint64_t bytes) { // 1) 先判断权限:未开启“完全访问”则走引导逻辑 if (![[KBFullAccessManager shared] hasFullAccess]) { // 未开启完全访问:保持原有引导路径 - // [KBHUD showInfo:KBLocalized(@"处理中…")]; + // [KBHUD showInfo:KBLocalized(@"Processing...")]; [[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self.view]; return; } @@ -1109,7 +1109,7 @@ static NSString *KBFormatMB(uint64_t bytes) { [rawText stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; if (trim.length == 0) { - [KBHUD showInfo:KBLocalized(@"请输入内容")]; + [KBHUD showInfo:KBLocalized(@"Please enter content")]; return; } [self kb_sendChatText:trim]; @@ -1129,7 +1129,7 @@ static NSString *KBFormatMB(uint64_t bytes) { [self kb_prefetchAvatarForMessage:outgoing]; if (![[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self.view]) { - [KBHUD showInfo:KBLocalized(@"请开启完全访问后使用")]; + [KBHUD showInfo:KBLocalized(@"Please enable Full Access to continue")]; return; } @@ -1258,12 +1258,12 @@ static NSString *KBFormatMB(uint64_t bytes) { if (mockPath.length > 0) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.35 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - NSString *displayText = KBLocalized(@"语音回复"); + NSString *displayText = KBLocalized(@"Voice reply"); KBChatMessage *incoming = [KBChatMessage messageWithText:displayText outgoing:NO audioFilePath:mockPath]; - incoming.displayName = KBLocalized(@"AI助手"); + incoming.displayName = KBLocalized(@"AI Assistant"); [self kb_appendChatMessage:incoming]; [self kb_playChatAudioAtPath:mockPath]; }); @@ -1283,7 +1283,7 @@ static NSString *KBFormatMB(uint64_t bytes) { } if (error) { NSString *tip = error.localizedDescription - ?: KBLocalized(@"请求失败"); + ?: KBLocalized(@"Request failed"); [KBHUD showInfo:tip]; return; } @@ -1303,7 +1303,7 @@ static NSString *KBFormatMB(uint64_t bytes) { initWithBase64EncodedString:audioBase64 options:0]; if (data.length == 0) { - [KBHUD showInfo:KBLocalized(@"音频数据解析失败")]; + [KBHUD showInfo:KBLocalized(@"Failed to parse audio data")]; return; } [self kb_handleChatAudioData:data @@ -1311,7 +1311,7 @@ static NSString *KBFormatMB(uint64_t bytes) { displayText:displayText]; return; } - [KBHUD showInfo:KBLocalized(@"未获取到音频文件")]; + [KBHUD showInfo:KBLocalized(@"No audio file received")]; }); }]; } @@ -1344,7 +1344,7 @@ static NSString *KBFormatMB(uint64_t bytes) { } NSLog(@"[KB] ❌ 请求失败: %@", response.message); [self.chatPanelView kb_removeLoadingAssistantMessage]; - [KBHUD showInfo:response.message ?: KBLocalized(@"请求失败")]; + [KBHUD showInfo:response.message ?: KBLocalized(@"Request failed")]; return; } @@ -1352,7 +1352,7 @@ static NSString *KBFormatMB(uint64_t bytes) { if (response.data.aiResponse.length == 0) { [self.chatPanelView kb_removeLoadingAssistantMessage]; - [KBHUD showInfo:KBLocalized(@"未获取到回复内容")]; + [KBHUD showInfo:KBLocalized(@"No reply content received")]; return; } @@ -1420,12 +1420,12 @@ static NSString *KBFormatMB(uint64_t bytes) { if (!self) return; if (!response.success) { - [KBHUD showInfo:response.errorMessage ?: KBLocalized(@"下载失败")]; + [KBHUD showInfo:response.errorMessage ?: KBLocalized(@"Download failed")]; return; } if (!response.audioData || response.audioData.length == 0) { - [KBHUD showInfo:KBLocalized(@"未获取到音频数据")]; + [KBHUD showInfo:KBLocalized(@"No audio data received")]; return; } @@ -1444,7 +1444,7 @@ static NSString *KBFormatMB(uint64_t bytes) { fileExtension:(NSString *)extension displayText:(NSString *)displayText { if (data.length == 0) { - [KBHUD showInfo:KBLocalized(@"音频数据为空")]; + [KBHUD showInfo:KBLocalized(@"Audio data is empty")]; return; } NSString *ext = extension.length > 0 ? extension : @"m4a"; @@ -1456,15 +1456,15 @@ static NSString *KBFormatMB(uint64_t bytes) { NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName]; if (![data writeToFile:filePath atomically:YES]) { - [KBHUD showInfo:KBLocalized(@"音频保存失败")]; + [KBHUD showInfo:KBLocalized(@"Failed to save audio")]; return; } - NSString *text = displayText.length > 0 ? displayText : KBLocalized(@"语音消息"); + NSString *text = displayText.length > 0 ? displayText : KBLocalized(@"Voice message"); KBChatMessage *incoming = [KBChatMessage messageWithText:text outgoing:NO audioFilePath:filePath]; - incoming.displayName = KBLocalized(@"AI助手"); + incoming.displayName = KBLocalized(@"AI Assistant"); [self kb_appendChatMessage:incoming]; } @@ -1566,7 +1566,7 @@ static NSString *KBFormatMB(uint64_t bytes) { } NSURL *url = [NSURL fileURLWithPath:path]; if (![NSFileManager.defaultManager fileExistsAtPath:path]) { - [KBHUD showInfo:KBLocalized(@"音频文件不存在")]; + [KBHUD showInfo:KBLocalized(@"Audio file does not exist")]; return; } @@ -1596,7 +1596,7 @@ static NSString *KBFormatMB(uint64_t bytes) { AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&playerError]; if (playerError || !player) { - [KBHUD showInfo:KBLocalized(@"音频播放失败")]; + [KBHUD showInfo:KBLocalized(@"Audio playback failed")]; return; } self.chatAudioPlayer = player; @@ -1634,7 +1634,7 @@ static NSString *KBFormatMB(uint64_t bytes) { AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithData:audioData error:&playerError]; if (playerError || !player) { NSLog(@"[Keyboard] 音频播放器初始化失败: %@", playerError.localizedDescription); - [KBHUD showInfo:KBLocalized(@"音频播放失败")]; + [KBHUD showInfo:KBLocalized(@"Audio playback failed")]; return; } diff --git a/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Panels.m b/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Panels.m index e87dc51..a69e4d6 100644 --- a/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Panels.m +++ b/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Panels.m @@ -54,7 +54,7 @@ } #endif if (mode == KBKeyboardPanelModeFunction && !islogin) { - [KBHUD showInfo:KBLocalized(@"请先登录后使用AI功能")]; + [KBHUD showInfo:KBLocalized(@"Please sign in before using AI features")]; NSURL *ul = [NSURL URLWithString:[NSString stringWithFormat:@"%@?src=keyboard", KB_UL_LOGIN]]; NSURL *scheme = [NSURL URLWithString:[NSString stringWithFormat:@"%@://login?src=keyboard", KB_APP_SCHEME]]; @@ -68,7 +68,7 @@ return; } dispatch_async(dispatch_get_main_queue(), ^{ - [KBHUD showInfo:KBLocalized(@"请回到桌面手动打开App登录")]; + [KBHUD showInfo:KBLocalized(@"Please return to the Home screen and open the app to sign in")]; }); }]; return; diff --git a/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Subscription.m b/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Subscription.m index 33aa13e..d8fa290 100644 --- a/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Subscription.m +++ b/CustomKeyboard/KeyboardViewControllerHelp/KeyboardViewController+Subscription.m @@ -19,7 +19,7 @@ // 1) 先判断权限:未开启“完全访问”则走引导逻辑 if (![[KBFullAccessManager shared] hasFullAccess]) { // 未开启完全访问:保持原有引导路径 - // [KBHUD showInfo:KBLocalized(@"处理中…")]; + // [KBHUD showInfo:KBLocalized(@"Processing...")]; [[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self.view]; return; } diff --git a/CustomKeyboard/Network/NetworkStreamHandler.m b/CustomKeyboard/Network/NetworkStreamHandler.m index b0f48ce..da9fd0a 100644 --- a/CustomKeyboard/Network/NetworkStreamHandler.m +++ b/CustomKeyboard/Network/NetworkStreamHandler.m @@ -7,6 +7,7 @@ #import "NetworkStreamHandler.h" #import +#import "KBLocalizationManager.h" @interface NetworkStreamHandler () @@ -101,7 +102,11 @@ // 设置常见的请求头(根据您的截图) [request setValue:@"text/html, application/xhtml+xml, application/xml; q=0.9, image/avif, image/webp, image/apng, */*; q=0.8, application/signed-exchange; v=b3; q=0.7" forHTTPHeaderField:@"Accept"]; [request setValue:@"gzip, deflate" forHTTPHeaderField:@"Accept-Encoding"]; - [request setValue:@"zh-CN, zh; q=0.9, ko; q=0.8, ja; q=0.7" forHTTPHeaderField:@"Accept-Language"]; + NSString *lang = [[KBLocalizationManager shared] currentLanguageHeaderValue]; + if (lang.length == 0) { + lang = @"en"; + } + [request setValue:lang forHTTPHeaderField:@"Accept-Language"]; [request setValue:@"keep-alive" forHTTPHeaderField:@"Connection"]; [request setValue:@"1" forHTTPHeaderField:@"Upgrade-Insecure-Requests"]; diff --git a/CustomKeyboard/View/Buy/KBKeyboardSubscriptionView.m b/CustomKeyboard/View/Buy/KBKeyboardSubscriptionView.m index d8add92..bc0540d 100644 --- a/CustomKeyboard/View/Buy/KBKeyboardSubscriptionView.m +++ b/CustomKeyboard/View/Buy/KBKeyboardSubscriptionView.m @@ -157,7 +157,7 @@ static id KBKeyboardSubscriptionSanitizeJSON(id obj) { - (void)setupFeatureItems { NSArray *titles = @[ - KBLocalized(@"Wireless Sub-ai\nDialogue"), + KBLocalized(@"Wireless Sub-ai Dialogue"), KBLocalized(@"Personalized\nKeyboard"), KBLocalized(@"Chat\nPersona"), KBLocalized(@"Emotional\nCounseling") @@ -200,7 +200,7 @@ static id KBKeyboardSubscriptionSanitizeJSON(id obj) { - (void)fetchProducts { if (self.isLoading) { return; } if (![[KBFullAccessManager shared] hasFullAccess]) { - [KBHUD showInfo:KBLocalized(@"Enable Full Access to continue")]; + [KBHUD showInfo:KBLocalized(@"Please enable Full Access to continue")]; return; } self.loading = YES; @@ -405,7 +405,7 @@ static id KBKeyboardSubscriptionSanitizeJSON(id obj) { - (UILabel *)agreementLabel { if (!_agreementLabel) { _agreementLabel = [[UILabel alloc] init]; - _agreementLabel.text = KBLocalized(@"By clicking \"pay\", you agree to the"); + _agreementLabel.text = KBLocalized(@"By clicking Pay, you indicate your agreement to the"); _agreementLabel.font = [UIFont systemFontOfSize:11]; _agreementLabel.textColor = [UIColor colorWithHex:0x4A4A4A]; } diff --git a/CustomKeyboard/View/Chat/KBChatPanelView.m b/CustomKeyboard/View/Chat/KBChatPanelView.m index faf8fb2..196c49b 100644 --- a/CustomKeyboard/View/Chat/KBChatPanelView.m +++ b/CustomKeyboard/View/Chat/KBChatPanelView.m @@ -118,7 +118,7 @@ static const NSUInteger kKBChatMessageLimit = 10; // 创建 AI 消息 KBChatMessage *msg = [KBChatMessage assistantMessageWithText:text audioId:audioId]; - msg.displayName = KBLocalized(@"AI助手"); + msg.displayName = KBLocalized(@"AI Assistant"); NSLog(@"[Panel] 创建 AI 消息,needsTypewriter: %d", msg.needsTypewriterEffect); // 使用批量更新,避免界面跳动 @@ -323,7 +323,7 @@ static const NSUInteger kKBChatMessageLimit = 10; _titleLabel.textColor = [UIColor kb_dynamicColorWithLightColor:[UIColor colorWithHex:0x1B1F1A] darkColor:[UIColor whiteColor]]; - _titleLabel.text = KBLocalized(@"AI对话"); + _titleLabel.text = KBLocalized(@"AI Chat"); } return _titleLabel; } diff --git a/CustomKeyboard/View/KBChatMessageCell.m b/CustomKeyboard/View/KBChatMessageCell.m index 88d348f..19d0a0f 100644 --- a/CustomKeyboard/View/KBChatMessageCell.m +++ b/CustomKeyboard/View/KBChatMessageCell.m @@ -79,7 +79,7 @@ self.audioLabel.textColor = textColor; self.audioIconView.tintColor = textColor; self.audioLabel.text = - (message.text.length > 0) ? message.text : KBLocalized(@"语音回复"); + (message.text.length > 0) ? message.text : KBLocalized(@"Voice reply"); self.messageLabel.hidden = audioMessage; self.audioIconView.hidden = !audioMessage; self.audioLabel.hidden = !audioMessage; @@ -94,7 +94,7 @@ self.nameLabel.hidden = outgoing; self.nameLabel.textColor = nameColor; self.nameLabel.text = - (message.displayName.length > 0) ? message.displayName : KBLocalized(@"AI助手"); + (message.displayName.length > 0) ? message.displayName : KBLocalized(@"AI Assistant"); // 处理 loading 状态 if (message.isLoading && !outgoing) { diff --git a/CustomKeyboard/View/KBFullAccessGuideView.m b/CustomKeyboard/View/KBFullAccessGuideView.m index 9325915..f206a37 100644 --- a/CustomKeyboard/View/KBFullAccessGuideView.m +++ b/CustomKeyboard/View/KBFullAccessGuideView.m @@ -161,7 +161,7 @@ - (void)onTapGoEnable { UIInputViewController *ivc = self.ivc ?: KBFindInputViewController(self); if (!ivc) { - NSString *showInfo = [NSString stringWithFormat:KBLocalized(@"Follow: Settings → General → Keyboard → Keyboards → %@ → Allow Full Access"), AppName]; + NSString *showInfo = [NSString stringWithFormat:KBLocalized(@"Follow: Settings -> General -> Keyboard -> Keyboards -> %@ -> Allow Full Access"), AppName]; [KBHUD showInfo:showInfo]; return; } @@ -183,7 +183,7 @@ if (success) { [self dismiss]; } else { - NSString *showInfo = [NSString stringWithFormat:KBLocalized(@"Follow: Settings → General → Keyboard → Keyboards → %@ → Allow Full Access"), AppName]; + NSString *showInfo = [NSString stringWithFormat:KBLocalized(@"Follow: Settings -> General -> Keyboard -> Keyboards -> %@ -> Allow Full Access"), AppName]; [KBHUD showInfo:showInfo]; } }); diff --git a/CustomKeyboard/View/KBFunctionPasteView.m b/CustomKeyboard/View/KBFunctionPasteView.m index 368ef70..ea5551a 100644 --- a/CustomKeyboard/View/KBFunctionPasteView.m +++ b/CustomKeyboard/View/KBFunctionPasteView.m @@ -60,7 +60,6 @@ // if (!_placeholderLabelInternal) { // _placeholderLabelInternal = [[UILabel alloc] init]; // // 文案改为更贴近设计稿 -// _placeholderLabelInternal.text = KBLocalized(@"Paste Ta's Words"); // _placeholderLabelInternal.textColor = [UIColor colorWithRed:0.20 green:0.64 blue:0.54 alpha:1.0]; // _placeholderLabelInternal.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium]; // } diff --git a/CustomKeyboard/View/KBFunctionView.m b/CustomKeyboard/View/KBFunctionView.m index 5312698..4741211 100644 --- a/CustomKeyboard/View/KBFunctionView.m +++ b/CustomKeyboard/View/KBFunctionView.m @@ -277,13 +277,8 @@ // self.itemsInternal = @[KBLocalized(@"Warm hearted man"), // KBLocalized(@"Warm2 hearted man"), // KBLocalized(@"Warm3 hearted man"), -// KBLocalized(@"撩女生啊u发顺丰大师傅"), // KBLocalized(@"Warm = man"), // KBLocalized(@"Warm hearted man"), -// KBLocalized(@"一枚暖男发放"), -// KBLocalized(@"聊天搭子"), -// KBLocalized(@"表达爱意"), -// KBLocalized(@"更多话术")]; // [self.tagListView setItems:self.itemsInternal]; //} @@ -516,7 +511,7 @@ } BOOL shouldShowError = (error != nil); if (shouldShowError) { - [KBHUD showInfo:error.localizedDescription ?: KBLocalized(@"拉取失败")]; + [KBHUD showInfo:error.localizedDescription ?: KBLocalized(@"Fetch failed")]; } if (self.streamOverlay) { [self.streamOverlay finish]; @@ -533,7 +528,7 @@ BOOL needSubscriptionGuide = (code == KBBizCodeQuotaExhausted); NSString *msg = KBBizMessageFromJSONObject(payload); if (msg.length == 0) { - msg = KBLocalized(@"拉取失败"); + msg = KBLocalized(@"Fetch failed"); } NSError *bizError = [NSError errorWithDomain:@"KBStreamBizError" @@ -721,7 +716,7 @@ // 1) 先判断权限:未开启“完全访问”则走引导逻辑 if (![[KBFullAccessManager shared] hasFullAccess]) { // 未开启完全访问:保持原有引导路径 - [KBHUD showInfo:KBLocalized(@"处理中…")]; + [KBHUD showInfo:KBLocalized(@"Processing...")]; [[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self]; return; } @@ -732,7 +727,7 @@ UIInputViewController *ivc = KBFindInputViewController(self); if (!ivc) { - [KBHUD showInfo:KBLocalized(@"请回到桌面手动打开App登录")]; + [KBHUD showInfo:KBLocalized(@"Please return to the Home screen and open the app to sign in")]; return; } @@ -749,7 +744,7 @@ return; } dispatch_async(dispatch_get_main_queue(), ^{ - [KBHUD showInfo:KBLocalized(@"请回到桌面手动打开App登录")]; + [KBHUD showInfo:KBLocalized(@"Please return to the Home screen and open the app to sign in")]; }); }]; return; @@ -781,7 +776,6 @@ // [ivc dismissKeyboard]; // BOOL ok = [KBHostAppLauncher openHostAppURL:scheme // fromResponder:start]; if (!ok) { - // [KBHUD showInfo:KBLocalized(@"请切换到主App完成登录")]; // }else{ // // } @@ -829,7 +823,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, return; } - [KBHUD showInfo:KBLocalized(@"处理中…")]; + [KBHUD showInfo:KBLocalized(@"Processing...")]; UIInputViewController *ivc = KBFindInputViewController(self); if (!ivc) diff --git a/Shared/Localization/en.lproj/InfoPlist.strings b/Shared/Localization/en.lproj/InfoPlist.strings new file mode 100644 index 0000000..72c9b1c --- /dev/null +++ b/Shared/Localization/en.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +"NSMicrophoneUsageDescription" = "Microphone access is required for voice input."; +"NSPhotoLibraryUsageDescription" = "Photo library access is required to change your avatar."; +"NSPhotoLibraryAddUsageDescription" = "Photo library write access is required to save images."; diff --git a/Shared/Localization/en.lproj/Localizable.strings b/Shared/Localization/en.lproj/Localizable.strings index 3b2812f..6da1220 100644 --- a/Shared/Localization/en.lproj/Localizable.strings +++ b/Shared/Localization/en.lproj/Localizable.strings @@ -215,3 +215,145 @@ "Unable to obtain transaction payload." = "Unable to obtain transaction payload."; "Resume Purchase" = "Resume Purchase"; "Downloading..." = "Downloading..."; +"Please Select Your Gender" = "Please Select Your Gender"; +"Skip" = "Skip"; +"Turn On The Keyboard" = "Turn On The Keyboard"; +"key of love keyboard" = "key of love keyboard"; +"One-click to find a partner" = "One-click to find a partner"; +"Turn on the keyboard" = "Turn on the keyboard"; +"Report reason" = "Report reason"; +"Report description" = "Report description"; +"Report submitted" = "Report submitted"; +"Please describe the specific reason for your report." = "Please describe the specific reason for your report."; +"Pornographic And Vulgar" = "Pornographic And Vulgar"; +"Politically Sensitive" = "Politically Sensitive"; +"Insult Attacks" = "Insult Attacks"; +"Bloody Violence" = "Bloody Violence"; +"Suicide And Self Harm" = "Suicide And Self Harm"; +"Plagiarism Infringement" = "Plagiarism Infringement"; +"Invasion Of Privacy" = "Invasion Of Privacy"; +"False Rumor" = "False Rumor"; +"Other Harmful Information" = "Other Harmful Information"; +"Character Name And Description" = "Character Name And Description"; +"Picture" = "Picture"; +"Timbre" = "Timbre"; +"Please select at least one report reason" = "Please select at least one report reason"; +"Please select at least one content type" = "Please select at least one content type"; +"Submit" = "Submit"; +"Selection Content" = "Selection Content"; +"Voice Connecting..." = "Connecting..."; +"Voice Recording..." = "Recording..."; +"Voice Recognizing..." = "Recognizing..."; +"Voice Recording Ended" = "Recording ended"; +"Voice Cancelled" = "Cancelled"; +"Voice Listening..." = "Listening..."; +"Voice Recognition Failed" = "Recognition failed"; +"Voice Recognition Completed" = "Recognition completed"; +"By continuing, you agree to our terms of service and confirm that you have read our privacy policy" = "By continuing, you agree to our terms of service and confirm that you have read our privacy policy"; +"terms of service" = "terms of service"; +"privacy policy" = "privacy policy"; +"Become A Member Of Love Key" = "Become A Member Of Love Key"; +"Unlock All Functions" = "Unlock All Functions"; +"Wireless Sub-ai Dialogue" = "Wireless Sub-ai Dialogue"; +"Personalized\nKeyboard" = "Personalized\nKeyboard"; +"Chat\nPersona" = "Chat\nPersona"; +"Emotional\nCounseling" = "Emotional\nCounseling"; +"Monthly Subscription" = "Monthly Subscription"; + +"AI Assistant" = "AI Assistant"; +"AI Chat" = "AI Chat"; +"Membership Agreement" = "《Embership Agreement》"; +"Download information missing" = "Download information missing"; +"Download failed" = "Download failed"; +"Theme information missing" = "Theme information missing"; +"Delete failed, please try again" = "Delete failed, please try again"; +"Processing..." = "Processing..."; +"Copied" = "Copied"; +"Default keyboard skin restored" = "Default keyboard skin restored"; +"Keyboard has been notified to unzip. Switch to the custom keyboard to apply." = "Keyboard has been notified to unzip. Switch to the custom keyboard to apply."; +"Failed to apply skin" = "Failed to apply skin"; +"Recording too short, please try again" = "Recording too short, please try again"; +"Restore default skin" = "Restore default skin"; +"Fetch failed" = "Fetch failed"; +"Unable to access shared container, failed to apply skin" = "Unable to access shared container, failed to apply skin"; +"Update" = "Update"; +"Update content" = "Update content"; +"No reply content received" = "No reply content received"; +"No audio data received" = "No audio data received"; +"No audio file received" = "No audio file received"; +"No speech content recognized" = "No speech content recognized"; +"Loading theme details" = "Loading theme details"; +"Upgrade now" = "Upgrade now"; +"Pink skin" = "Pink skin"; +"Sign in with Apple" = "Sign in with Apple"; +"Voice reply" = "Voice reply"; +"Voice message" = "Voice message"; +"Voice recognition failed" = "Voice recognition failed"; +"Voice-to-text failed, please try again" = "Voice-to-text failed, please try again"; +"Please sign in before using AI features" = "Please sign in before using AI features"; +"Please return to the Home screen and open the app to sign in" = "Please return to the Home screen and open the app to sign in"; +"Please enable Full Access to continue" = "Please enable Full Access to continue"; +"Request failed" = "Request failed"; +"Please enter content" = "Please enter content"; +"Purchase failed" = "Purchase failed"; +"Remote skin" = "Remote skin"; +"Sign in with Apple requires iOS 13+" = "Sign in with Apple requires iOS 13+"; +"Failed to save audio" = "Failed to save audio"; +"Audio playback failed" = "Audio playback failed"; +"Audio data is empty" = "Audio data is empty"; +"Failed to parse audio data" = "Failed to parse audio data"; +"Audio file does not exist" = "Audio file does not exist"; + +"Follow: Settings -> General -> Keyboard -> Keyboards -> %@ -> Allow Full Access" = "Follow: Settings → General → Keyboard → Keyboards → %@ → Allow Full Access"; + +"Agreement coming soon" = "Agreement coming soon"; +"Application to the skin failed" = "Application to the skin failed"; +"Are you sure to delete?" = "Are you sure to delete?"; +"Chat Without Speed Limits" = "Chat Without Speed Limits"; +"Choose" = "Choose"; +"Click \"copy Any Conversation\", \"paste\"\nAnd Try Replying Using The Keyboard\n[persona] Method" = "Click \"copy Any Conversation\", \"paste\"\nAnd Try Replying Using The Keyboard\n[persona] Method"; +"Clipboard is empty" = "Clipboard is empty"; +"Coming Soon" = "Coming Soon"; +"Consumption" = "Consumption"; +"Download" = "Download"; +"Download again" = "Download again"; +"Due On" = "Due On"; +"Empty file data" = "Empty file data"; +"Failed to load products" = "Failed to load products"; +"Free" = "Free"; +"Go To Recharge" = "Go To Recharge"; +"I Miss You" = "I Miss You"; +"I'm Going To Take A Bath" = "I'm Going To Take A Bath"; +"Invalid file" = "Invalid file"; +"Invalid parameter" = "Invalid parameter"; +"Invalid upload request" = "Invalid upload request"; +"Loading..." = "Loading..."; +"Longer Chat History" = "Longer Chat History"; +"Member recharge" = "Member recharge"; +"Membership Benefits" = "Membership Benefits"; +"No more data" = "No more data"; +"No products available" = "No products available"; +"Operation failed" = "Operation failed"; +"Payload missing" = "Payload missing"; +"Please open the App to finish purchase" = "Please open the App to finish purchase"; +"Please select a product" = "Please select a product"; +"Product unavailable" = "Product unavailable"; +"Receipt missing" = "Receipt missing"; +"Search Role" = "Search Role"; +"Search coming soon" = "Search coming soon"; +"Search result" = "Search result"; +"Server error" = "Server error"; +"Subscription" = "Subscription"; +"The existing conversation history will be cleared." = "The existing conversation history will be cleared."; +"The skin in use cannot be deleted" = "The skin in use cannot be deleted"; +"Themes" = "Themes"; +"Think Again" = "Think Again"; +"Unlimited Chatting" = "Unlimited Chatting"; +"Warm = man" = "Warm = man"; +"Warm hearted man" = "Warm hearted man"; +"Warm2 hearted man" = "Warm2 hearted man"; +"Warm3 hearted man" = "Warm3 hearted man"; +"Welcome To Use The [key Of Love] Keyboard" = "Welcome To Use The [key Of Love] Keyboard"; +"Welcome to use the [key of love] keyboard" = "Welcome to use the [key of love] keyboard"; +"Your session has expired. Please sign in again." = "Your session has expired. Please sign in again."; +"send a message" = "send a message"; diff --git a/Shared/Localization/es.lproj/InfoPlist.strings b/Shared/Localization/es.lproj/InfoPlist.strings new file mode 100644 index 0000000..fc889ba --- /dev/null +++ b/Shared/Localization/es.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +"NSMicrophoneUsageDescription" = "Se requiere acceso al micrófono para la entrada por voz."; +"NSPhotoLibraryUsageDescription" = "Se requiere acceso a la fototeca para cambiar tu avatar."; +"NSPhotoLibraryAddUsageDescription" = "Se requiere permiso de escritura en la fototeca para guardar imágenes."; diff --git a/Shared/Localization/es.lproj/Localizable.strings b/Shared/Localization/es.lproj/Localizable.strings index 9ef402c..0aef210 100644 --- a/Shared/Localization/es.lproj/Localizable.strings +++ b/Shared/Localization/es.lproj/Localizable.strings @@ -224,3 +224,145 @@ "无效响应\nURL: %@\n说明: %@" = "Respuesta no válida\nURL: %@\nDetalle: %@"; "暂无数据" = "Sin datos"; "请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@" = "Solicitud fallida\nURL: %@\nEstado: %ld\nError: %@\nUserInfo: %@"; +"Please Select Your Gender" = "Por favor, selecciona tu género"; +"Skip" = "Omitir"; +"Turn On The Keyboard" = "Activar el teclado"; +"key of love keyboard" = "teclado key of love"; +"One-click to find a partner" = "Un clic para encontrar pareja"; +"Turn on the keyboard" = "Activar el teclado"; +"Report reason" = "Motivo del reporte"; +"Report description" = "Descripción del reporte"; +"Report submitted" = "Reporte enviado"; +"Please describe the specific reason for your report." = "Describe el motivo específico de tu reporte."; +"Pornographic And Vulgar" = "Pornográfico y vulgar"; +"Politically Sensitive" = "Políticamente sensible"; +"Insult Attacks" = "Insultos y ataques"; +"Bloody Violence" = "Violencia sangrienta"; +"Suicide And Self Harm" = "Suicidio y autolesión"; +"Plagiarism Infringement" = "Plagio e infracción"; +"Invasion Of Privacy" = "Invasión de privacidad"; +"False Rumor" = "Rumor falso"; +"Other Harmful Information" = "Otra información perjudicial"; +"Character Name And Description" = "Nombre y descripción del personaje"; +"Picture" = "Imagen"; +"Timbre" = "Timbre de voz"; +"Please select at least one report reason" = "Selecciona al menos un motivo de reporte"; +"Please select at least one content type" = "Selecciona al menos un tipo de contenido"; +"Submit" = "Enviar"; +"Selection Content" = "Seleccionar contenido"; +"Voice Connecting..." = "Conectando..."; +"Voice Recording..." = "Grabando..."; +"Voice Recognizing..." = "Reconociendo..."; +"Voice Recording Ended" = "Grabación finalizada"; +"Voice Cancelled" = "Cancelado"; +"Voice Listening..." = "Escuchando..."; +"Voice Recognition Failed" = "Reconocimiento fallido"; +"Voice Recognition Completed" = "Reconocimiento completado"; +"By continuing, you agree to our terms of service and confirm that you have read our privacy policy" = "Al continuar, aceptas nuestros términos del servicio y confirmas que has leído nuestra política de privacidad"; +"terms of service" = "términos del servicio"; +"privacy policy" = "política de privacidad"; +"Become A Member Of Love Key" = "Hazte miembro de Love Key"; +"Unlock All Functions" = "Desbloquea todas las funciones"; +"Wireless Sub-ai Dialogue" = "Diálogo sub-IA sin límites"; +"Personalized\nKeyboard" = "Teclado\npersonalizado"; +"Chat\nPersona" = "Persona de\nchat"; +"Emotional\nCounseling" = "Asesoramiento\nemocional"; +"Monthly Subscription" = "Suscripción mensual"; + +"AI Assistant" = "AI Assistant"; +"AI Chat" = "AI Chat"; +"Membership Agreement" = "《Acuerdo de membresía》"; +"Download information missing" = "Download information missing"; +"Download failed" = "Download failed"; +"Theme information missing" = "Theme information missing"; +"Delete failed, please try again" = "Delete failed, please try again"; +"Processing..." = "Processing..."; +"Copied" = "Copied"; +"Default keyboard skin restored" = "Default keyboard skin restored"; +"Keyboard has been notified to unzip. Switch to the custom keyboard to apply." = "Keyboard has been notified to unzip. Switch to the custom keyboard to apply."; +"Failed to apply skin" = "Failed to apply skin"; +"Recording too short, please try again" = "Recording too short, please try again"; +"Restore default skin" = "Restore default skin"; +"Fetch failed" = "Fetch failed"; +"Unable to access shared container, failed to apply skin" = "Unable to access shared container, failed to apply skin"; +"Update" = "Update"; +"Update content" = "Update content"; +"No reply content received" = "No reply content received"; +"No audio data received" = "No audio data received"; +"No audio file received" = "No audio file received"; +"No speech content recognized" = "No speech content recognized"; +"Loading theme details" = "Loading theme details"; +"Upgrade now" = "Upgrade now"; +"Pink skin" = "Pink skin"; +"Sign in with Apple" = "Sign in with Apple"; +"Voice reply" = "Voice reply"; +"Voice message" = "Voice message"; +"Voice recognition failed" = "Voice recognition failed"; +"Voice-to-text failed, please try again" = "Voice-to-text failed, please try again"; +"Please sign in before using AI features" = "Please sign in before using AI features"; +"Please return to the Home screen and open the app to sign in" = "Please return to the Home screen and open the app to sign in"; +"Please enable Full Access to continue" = "Please enable Full Access to continue"; +"Request failed" = "Request failed"; +"Please enter content" = "Please enter content"; +"Purchase failed" = "Purchase failed"; +"Remote skin" = "Remote skin"; +"Sign in with Apple requires iOS 13+" = "Sign in with Apple requires iOS 13+"; +"Failed to save audio" = "Failed to save audio"; +"Audio playback failed" = "Audio playback failed"; +"Audio data is empty" = "Audio data is empty"; +"Failed to parse audio data" = "Failed to parse audio data"; +"Audio file does not exist" = "Audio file does not exist"; + +"Follow: Settings -> General -> Keyboard -> Keyboards -> %@ -> Allow Full Access" = "Sigue: Ajustes → General → Teclado → Teclados → %@ → Permitir acceso total"; + +"Agreement coming soon" = "Acuerdo próximamente"; +"Application to the skin failed" = "No se pudo aplicar el skin"; +"Are you sure to delete?" = "¿Seguro que deseas eliminar?"; +"Chat Without Speed Limits" = "Chat sin límites de velocidad"; +"Choose" = "Elegir"; +"Click \"copy Any Conversation\", \"paste\"\nAnd Try Replying Using The Keyboard\n[persona] Method" = "Haz clic en \"copiar cualquier conversación\", \"pegar\"\\ny prueba a responder con el teclado\\n[método de persona]"; +"Clipboard is empty" = "El portapapeles está vacío"; +"Coming Soon" = "Próximamente"; +"Consumption" = "Consumo"; +"Download" = "Descargar"; +"Download again" = "Descargar de nuevo"; +"Due On" = "Vence el"; +"Empty file data" = "Datos de archivo vacíos"; +"Failed to load products" = "Error al cargar productos"; +"Free" = "Gratis"; +"Go To Recharge" = "Ir a recargar"; +"I Miss You" = "Te extraño"; +"I'm Going To Take A Bath" = "Voy a darme un baño"; +"Invalid file" = "Archivo inválido"; +"Invalid parameter" = "Parámetro inválido"; +"Invalid upload request" = "Solicitud de subida inválida"; +"Loading..." = "Cargando..."; +"Longer Chat History" = "Historial de chat más largo"; +"Member recharge" = "Recarga de membresía"; +"Membership Benefits" = "Beneficios de membresía"; +"No more data" = "No hay más datos"; +"No products available" = "No hay productos disponibles"; +"Operation failed" = "Operación fallida"; +"Payload missing" = "Falta payload"; +"Please open the App to finish purchase" = "Abre la app para finalizar la compra"; +"Please select a product" = "Por favor, selecciona un producto"; +"Product unavailable" = "Producto no disponible"; +"Receipt missing" = "Falta el recibo"; +"Search Role" = "Buscar rol"; +"Search coming soon" = "Búsqueda próximamente"; +"Search result" = "Resultado de búsqueda"; +"Server error" = "Error del servidor"; +"Subscription" = "Suscripción"; +"The existing conversation history will be cleared." = "Se borrará el historial de conversación existente."; +"The skin in use cannot be deleted" = "No se puede eliminar el skin en uso"; +"Themes" = "Temas"; +"Think Again" = "Piénsalo de nuevo"; +"Unlimited Chatting" = "Chat ilimitado"; +"Warm = man" = "Cálido = hombre"; +"Warm hearted man" = "Hombre de corazón cálido"; +"Warm2 hearted man" = "Hombre de corazón cálido 2"; +"Warm3 hearted man" = "Hombre de corazón cálido 3"; +"Welcome To Use The [key Of Love] Keyboard" = "Bienvenido a usar el teclado [key Of Love]"; +"Welcome to use the [key of love] keyboard" = "Bienvenido a usar el teclado [key of love]"; +"Your session has expired. Please sign in again." = "Tu sesión ha expirado. Inicia sesión de nuevo."; +"send a message" = "enviar un mensaje"; diff --git a/Shared/Localization/id.lproj/InfoPlist.strings b/Shared/Localization/id.lproj/InfoPlist.strings new file mode 100644 index 0000000..4427ed7 --- /dev/null +++ b/Shared/Localization/id.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +"NSMicrophoneUsageDescription" = "Akses mikrofon diperlukan untuk input suara."; +"NSPhotoLibraryUsageDescription" = "Akses galeri foto diperlukan untuk mengganti avatar Anda."; +"NSPhotoLibraryAddUsageDescription" = "Izin menulis ke galeri foto diperlukan untuk menyimpan gambar."; diff --git a/Shared/Localization/id.lproj/Localizable.strings b/Shared/Localization/id.lproj/Localizable.strings index 0ffad09..deade39 100644 --- a/Shared/Localization/id.lproj/Localizable.strings +++ b/Shared/Localization/id.lproj/Localizable.strings @@ -225,3 +225,145 @@ "暂无数据" = "Tidak ada data"; "请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@" = "Permintaan gagal\nURL: %@\nStatus: %ld\nError: %@\nUserInfo: %@"; +"Please Select Your Gender" = "Silakan pilih gender Anda"; +"Skip" = "Lewati"; +"Turn On The Keyboard" = "Aktifkan keyboard"; +"key of love keyboard" = "key of love keyboard"; +"One-click to find a partner" = "Satu klik untuk menemukan pasangan"; +"Turn on the keyboard" = "Aktifkan keyboard"; +"Report reason" = "Alasan laporan"; +"Report description" = "Deskripsi laporan"; +"Report submitted" = "Laporan berhasil dikirim"; +"Please describe the specific reason for your report." = "Jelaskan alasan spesifik laporan Anda."; +"Pornographic And Vulgar" = "Pornografi dan vulgar"; +"Politically Sensitive" = "Sensitif secara politik"; +"Insult Attacks" = "Penghinaan dan serangan"; +"Bloody Violence" = "Kekerasan berdarah"; +"Suicide And Self Harm" = "Bunuh diri dan melukai diri"; +"Plagiarism Infringement" = "Plagiarisme dan pelanggaran"; +"Invasion Of Privacy" = "Pelanggaran privasi"; +"False Rumor" = "Rumor palsu"; +"Other Harmful Information" = "Informasi berbahaya lainnya"; +"Character Name And Description" = "Nama dan deskripsi karakter"; +"Picture" = "Gambar"; +"Timbre" = "Timbre suara"; +"Please select at least one report reason" = "Pilih setidaknya satu alasan laporan"; +"Please select at least one content type" = "Pilih setidaknya satu jenis konten"; +"Submit" = "Kirim"; +"Selection Content" = "Pilih konten"; +"Voice Connecting..." = "Menghubungkan..."; +"Voice Recording..." = "Merekam..."; +"Voice Recognizing..." = "Mengenali..."; +"Voice Recording Ended" = "Rekaman selesai"; +"Voice Cancelled" = "Dibatalkan"; +"Voice Listening..." = "Mendengarkan..."; +"Voice Recognition Failed" = "Pengenalan gagal"; +"Voice Recognition Completed" = "Pengenalan selesai"; +"By continuing, you agree to our terms of service and confirm that you have read our privacy policy" = "Dengan melanjutkan, Anda menyetujui ketentuan layanan kami dan mengonfirmasi bahwa Anda telah membaca kebijakan privasi kami"; +"terms of service" = "ketentuan layanan"; +"privacy policy" = "kebijakan privasi"; +"Become A Member Of Love Key" = "Menjadi Anggota Love Key"; +"Unlock All Functions" = "Buka Semua Fitur"; +"Wireless Sub-ai Dialogue" = "Dialog Sub-AI Tanpa Batas"; +"Personalized\nKeyboard" = "Keyboard\nPersonalisasi"; +"Chat\nPersona" = "Persona\nChat"; +"Emotional\nCounseling" = "Konseling\nEmosional"; +"Monthly Subscription" = "Langganan Bulanan"; + +"AI Assistant" = "AI Assistant"; +"AI Chat" = "AI Chat"; +"Membership Agreement" = "《Perjanjian Keanggotaan》"; +"Download information missing" = "Download information missing"; +"Download failed" = "Download failed"; +"Theme information missing" = "Theme information missing"; +"Delete failed, please try again" = "Delete failed, please try again"; +"Processing..." = "Processing..."; +"Copied" = "Copied"; +"Default keyboard skin restored" = "Default keyboard skin restored"; +"Keyboard has been notified to unzip. Switch to the custom keyboard to apply." = "Keyboard has been notified to unzip. Switch to the custom keyboard to apply."; +"Failed to apply skin" = "Failed to apply skin"; +"Recording too short, please try again" = "Recording too short, please try again"; +"Restore default skin" = "Restore default skin"; +"Fetch failed" = "Fetch failed"; +"Unable to access shared container, failed to apply skin" = "Unable to access shared container, failed to apply skin"; +"Update" = "Update"; +"Update content" = "Update content"; +"No reply content received" = "No reply content received"; +"No audio data received" = "No audio data received"; +"No audio file received" = "No audio file received"; +"No speech content recognized" = "No speech content recognized"; +"Loading theme details" = "Loading theme details"; +"Upgrade now" = "Upgrade now"; +"Pink skin" = "Pink skin"; +"Sign in with Apple" = "Sign in with Apple"; +"Voice reply" = "Voice reply"; +"Voice message" = "Voice message"; +"Voice recognition failed" = "Voice recognition failed"; +"Voice-to-text failed, please try again" = "Voice-to-text failed, please try again"; +"Please sign in before using AI features" = "Please sign in before using AI features"; +"Please return to the Home screen and open the app to sign in" = "Please return to the Home screen and open the app to sign in"; +"Please enable Full Access to continue" = "Please enable Full Access to continue"; +"Request failed" = "Request failed"; +"Please enter content" = "Please enter content"; +"Purchase failed" = "Purchase failed"; +"Remote skin" = "Remote skin"; +"Sign in with Apple requires iOS 13+" = "Sign in with Apple requires iOS 13+"; +"Failed to save audio" = "Failed to save audio"; +"Audio playback failed" = "Audio playback failed"; +"Audio data is empty" = "Audio data is empty"; +"Failed to parse audio data" = "Failed to parse audio data"; +"Audio file does not exist" = "Audio file does not exist"; + +"Follow: Settings -> General -> Keyboard -> Keyboards -> %@ -> Allow Full Access" = "Ikuti: Pengaturan → Umum → Keyboard → Keyboard → %@ → Izinkan Akses Penuh"; + +"Agreement coming soon" = "Perjanjian segera hadir"; +"Application to the skin failed" = "Gagal menerapkan skin"; +"Are you sure to delete?" = "Yakin ingin menghapus?"; +"Chat Without Speed Limits" = "Chat tanpa batas kecepatan"; +"Choose" = "Pilih"; +"Click \"copy Any Conversation\", \"paste\"\nAnd Try Replying Using The Keyboard\n[persona] Method" = "Klik \"salin percakapan apa pun\", \"tempel\"\\ndan coba balas menggunakan keyboard\\n[metode persona]"; +"Clipboard is empty" = "Papan klip kosong"; +"Coming Soon" = "Segera hadir"; +"Consumption" = "Konsumsi"; +"Download" = "Unduh"; +"Download again" = "Unduh lagi"; +"Due On" = "Jatuh tempo pada"; +"Empty file data" = "Data file kosong"; +"Failed to load products" = "Gagal memuat produk"; +"Free" = "Gratis"; +"Go To Recharge" = "Pergi isi ulang"; +"I Miss You" = "Aku merindukanmu"; +"I'm Going To Take A Bath" = "Aku mau mandi"; +"Invalid file" = "File tidak valid"; +"Invalid parameter" = "Parameter tidak valid"; +"Invalid upload request" = "Permintaan unggah tidak valid"; +"Loading..." = "Memuat..."; +"Longer Chat History" = "Riwayat chat lebih panjang"; +"Member recharge" = "Isi ulang anggota"; +"Membership Benefits" = "Manfaat keanggotaan"; +"No more data" = "Tidak ada data lagi"; +"No products available" = "Tidak ada produk tersedia"; +"Operation failed" = "Operasi gagal"; +"Payload missing" = "Payload tidak ada"; +"Please open the App to finish purchase" = "Buka aplikasi untuk menyelesaikan pembelian"; +"Please select a product" = "Silakan pilih produk"; +"Product unavailable" = "Produk tidak tersedia"; +"Receipt missing" = "Bukti transaksi tidak ada"; +"Search Role" = "Cari peran"; +"Search coming soon" = "Fitur pencarian segera hadir"; +"Search result" = "Hasil pencarian"; +"Server error" = "Kesalahan server"; +"Subscription" = "Langganan"; +"The existing conversation history will be cleared." = "Riwayat percakapan yang ada akan dihapus."; +"The skin in use cannot be deleted" = "Skin yang sedang digunakan tidak dapat dihapus"; +"Themes" = "Tema"; +"Think Again" = "Pikirkan lagi"; +"Unlimited Chatting" = "Chat tanpa batas"; +"Warm = man" = "Hangat = pria"; +"Warm hearted man" = "Pria berhati hangat"; +"Warm2 hearted man" = "Pria berhati hangat 2"; +"Warm3 hearted man" = "Pria berhati hangat 3"; +"Welcome To Use The [key Of Love] Keyboard" = "Selamat datang menggunakan keyboard [key Of Love]"; +"Welcome to use the [key of love] keyboard" = "Selamat datang menggunakan keyboard [key of love]"; +"Your session has expired. Please sign in again." = "Sesi Anda telah berakhir. Silakan masuk lagi."; +"send a message" = "kirim pesan"; diff --git a/Shared/Localization/pt-PT.lproj/InfoPlist.strings b/Shared/Localization/pt-PT.lproj/InfoPlist.strings new file mode 100644 index 0000000..ccbd890 --- /dev/null +++ b/Shared/Localization/pt-PT.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +"NSMicrophoneUsageDescription" = "O acesso ao microfone é necessário para entrada por voz."; +"NSPhotoLibraryUsageDescription" = "O acesso à fototeca é necessário para alterar o seu avatar."; +"NSPhotoLibraryAddUsageDescription" = "A permissão de escrita na fototeca é necessária para guardar imagens."; diff --git a/Shared/Localization/pt-PT.lproj/Localizable.strings b/Shared/Localization/pt-PT.lproj/Localizable.strings index 93b2aec..d1bfdb7 100644 --- a/Shared/Localization/pt-PT.lproj/Localizable.strings +++ b/Shared/Localization/pt-PT.lproj/Localizable.strings @@ -225,3 +225,145 @@ "暂无数据" = "Sem dados"; "请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@" = "Pedido falhou\nURL: %@\nEstado: %ld\nErro: %@\nUserInfo: %@"; +"Please Select Your Gender" = "Por favor, selecione o seu género"; +"Skip" = "Ignorar"; +"Turn On The Keyboard" = "Ativar teclado"; +"key of love keyboard" = "teclado key of love"; +"One-click to find a partner" = "Um toque para encontrar um parceiro"; +"Turn on the keyboard" = "Ativar teclado"; +"Report reason" = "Motivo da denúncia"; +"Report description" = "Descrição da denúncia"; +"Report submitted" = "Denúncia enviada"; +"Please describe the specific reason for your report." = "Descreva o motivo específico da sua denúncia."; +"Pornographic And Vulgar" = "Pornográfico e vulgar"; +"Politically Sensitive" = "Politicamente sensível"; +"Insult Attacks" = "Insultos e ataques"; +"Bloody Violence" = "Violência sangrenta"; +"Suicide And Self Harm" = "Suicídio e automutilação"; +"Plagiarism Infringement" = "Plágio e infração"; +"Invasion Of Privacy" = "Invasão de privacidade"; +"False Rumor" = "Rumor falso"; +"Other Harmful Information" = "Outras informações nocivas"; +"Character Name And Description" = "Nome e descrição da personagem"; +"Picture" = "Imagem"; +"Timbre" = "Timbre de voz"; +"Please select at least one report reason" = "Selecione pelo menos um motivo da denúncia"; +"Please select at least one content type" = "Selecione pelo menos um tipo de conteúdo"; +"Submit" = "Enviar"; +"Selection Content" = "Selecionar conteúdo"; +"Voice Connecting..." = "A ligar..."; +"Voice Recording..." = "A gravar..."; +"Voice Recognizing..." = "A reconhecer..."; +"Voice Recording Ended" = "Gravação terminada"; +"Voice Cancelled" = "Cancelado"; +"Voice Listening..." = "A ouvir..."; +"Voice Recognition Failed" = "Falha no reconhecimento"; +"Voice Recognition Completed" = "Reconhecimento concluído"; +"By continuing, you agree to our terms of service and confirm that you have read our privacy policy" = "Ao continuar, concorda com os nossos termos de serviço e confirma que leu a nossa política de privacidade"; +"terms of service" = "termos de serviço"; +"privacy policy" = "política de privacidade"; +"Become A Member Of Love Key" = "Torne-se Membro da Love Key"; +"Unlock All Functions" = "Desbloquear Todas as Funcionalidades"; +"Wireless Sub-ai Dialogue" = "Diálogo Sub-IA Sem Limites"; +"Personalized\nKeyboard" = "Teclado\nPersonalizado"; +"Chat\nPersona" = "Persona de\nChat"; +"Emotional\nCounseling" = "Aconselhamento\nEmocional"; +"Monthly Subscription" = "Subscrição Mensal"; + +"AI Assistant" = "AI Assistant"; +"AI Chat" = "AI Chat"; +"Membership Agreement" = "《Acordo de Associação》"; +"Download information missing" = "Download information missing"; +"Download failed" = "Download failed"; +"Theme information missing" = "Theme information missing"; +"Delete failed, please try again" = "Delete failed, please try again"; +"Processing..." = "Processing..."; +"Copied" = "Copied"; +"Default keyboard skin restored" = "Default keyboard skin restored"; +"Keyboard has been notified to unzip. Switch to the custom keyboard to apply." = "Keyboard has been notified to unzip. Switch to the custom keyboard to apply."; +"Failed to apply skin" = "Failed to apply skin"; +"Recording too short, please try again" = "Recording too short, please try again"; +"Restore default skin" = "Restore default skin"; +"Fetch failed" = "Fetch failed"; +"Unable to access shared container, failed to apply skin" = "Unable to access shared container, failed to apply skin"; +"Update" = "Update"; +"Update content" = "Update content"; +"No reply content received" = "No reply content received"; +"No audio data received" = "No audio data received"; +"No audio file received" = "No audio file received"; +"No speech content recognized" = "No speech content recognized"; +"Loading theme details" = "Loading theme details"; +"Upgrade now" = "Upgrade now"; +"Pink skin" = "Pink skin"; +"Sign in with Apple" = "Sign in with Apple"; +"Voice reply" = "Voice reply"; +"Voice message" = "Voice message"; +"Voice recognition failed" = "Voice recognition failed"; +"Voice-to-text failed, please try again" = "Voice-to-text failed, please try again"; +"Please sign in before using AI features" = "Please sign in before using AI features"; +"Please return to the Home screen and open the app to sign in" = "Please return to the Home screen and open the app to sign in"; +"Please enable Full Access to continue" = "Please enable Full Access to continue"; +"Request failed" = "Request failed"; +"Please enter content" = "Please enter content"; +"Purchase failed" = "Purchase failed"; +"Remote skin" = "Remote skin"; +"Sign in with Apple requires iOS 13+" = "Sign in with Apple requires iOS 13+"; +"Failed to save audio" = "Failed to save audio"; +"Audio playback failed" = "Audio playback failed"; +"Audio data is empty" = "Audio data is empty"; +"Failed to parse audio data" = "Failed to parse audio data"; +"Audio file does not exist" = "Audio file does not exist"; + +"Follow: Settings -> General -> Keyboard -> Keyboards -> %@ -> Allow Full Access" = "Siga: Definições → Geral → Teclado → Teclados → %@ → Permitir Acesso Total"; + +"Agreement coming soon" = "Acordo em breve"; +"Application to the skin failed" = "Falha ao aplicar o tema"; +"Are you sure to delete?" = "Tem a certeza de que quer eliminar?"; +"Chat Without Speed Limits" = "Chat sem limites de velocidade"; +"Choose" = "Escolher"; +"Click \"copy Any Conversation\", \"paste\"\nAnd Try Replying Using The Keyboard\n[persona] Method" = "Toque em \"copiar qualquer conversa\", \"colar\"\\ne tente responder usando o teclado\\n[método persona]"; +"Clipboard is empty" = "A área de transferência está vazia"; +"Coming Soon" = "Em breve"; +"Consumption" = "Consumo"; +"Download" = "Transferir"; +"Download again" = "Transferir novamente"; +"Due On" = "Válido até"; +"Empty file data" = "Dados de ficheiro vazios"; +"Failed to load products" = "Falha ao carregar produtos"; +"Free" = "Grátis"; +"Go To Recharge" = "Ir para recarregar"; +"I Miss You" = "Tenho saudades tuas"; +"I'm Going To Take A Bath" = "Vou tomar banho"; +"Invalid file" = "Ficheiro inválido"; +"Invalid parameter" = "Parâmetro inválido"; +"Invalid upload request" = "Pedido de upload inválido"; +"Loading..." = "A carregar..."; +"Longer Chat History" = "Histórico de chat mais longo"; +"Member recharge" = "Recarga de membro"; +"Membership Benefits" = "Benefícios de membro"; +"No more data" = "Não há mais dados"; +"No products available" = "Não há produtos disponíveis"; +"Operation failed" = "Operação falhada"; +"Payload missing" = "Payload em falta"; +"Please open the App to finish purchase" = "Abra a app para concluir a compra"; +"Please select a product" = "Selecione um produto"; +"Product unavailable" = "Produto indisponível"; +"Receipt missing" = "Recibo em falta"; +"Search Role" = "Pesquisar papel"; +"Search coming soon" = "Pesquisa em breve"; +"Search result" = "Resultado da pesquisa"; +"Server error" = "Erro do servidor"; +"Subscription" = "Subscrição"; +"The existing conversation history will be cleared." = "O histórico de conversas existente será limpo."; +"The skin in use cannot be deleted" = "O tema em uso não pode ser eliminado"; +"Themes" = "Temas"; +"Think Again" = "Pense novamente"; +"Unlimited Chatting" = "Chat ilimitado"; +"Warm = man" = "Quente = homem"; +"Warm hearted man" = "Homem de coração caloroso"; +"Warm2 hearted man" = "Homem de coração caloroso 2"; +"Warm3 hearted man" = "Homem de coração caloroso 3"; +"Welcome To Use The [key Of Love] Keyboard" = "Bem-vindo a usar o teclado [key Of Love]"; +"Welcome to use the [key of love] keyboard" = "Bem-vindo a usar o teclado [key of love]"; +"Your session has expired. Please sign in again." = "A sua sessão expirou. Inicie sessão novamente."; +"send a message" = "enviar uma mensagem"; diff --git a/Shared/Localization/zh-Hant.lproj/InfoPlist.strings b/Shared/Localization/zh-Hant.lproj/InfoPlist.strings new file mode 100644 index 0000000..aa12ff4 --- /dev/null +++ b/Shared/Localization/zh-Hant.lproj/InfoPlist.strings @@ -0,0 +1,3 @@ +"NSMicrophoneUsageDescription" = "需要使用麥克風進行語音輸入。"; +"NSPhotoLibraryUsageDescription" = "更換頭像需要存取你的相簿。"; +"NSPhotoLibraryAddUsageDescription" = "儲存圖片需要寫入你的相簿。"; diff --git a/Shared/Localization/zh-Hant.lproj/Localizable.strings b/Shared/Localization/zh-Hant.lproj/Localizable.strings index 07cbe59..54840e2 100644 --- a/Shared/Localization/zh-Hant.lproj/Localizable.strings +++ b/Shared/Localization/zh-Hant.lproj/Localizable.strings @@ -224,3 +224,145 @@ "无效响应\nURL: %@\n说明: %@" = "無效回應\nURL: %@\n說明: %@"; "暂无数据" = "暫無資料"; "请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@" = "請求失敗\nURL: %@\n狀態: %ld\n錯誤: %@\nUserInfo: %@"; +"Please Select Your Gender" = "請選擇你的性別"; +"Skip" = "跳過"; +"Turn On The Keyboard" = "開啟鍵盤"; +"key of love keyboard" = "key of love 鍵盤"; +"One-click to find a partner" = "一鍵找到心儀對象"; +"Turn on the keyboard" = "開啟鍵盤"; +"Report reason" = "檢舉原因"; +"Report description" = "檢舉描述"; +"Report submitted" = "檢舉已提交"; +"Please describe the specific reason for your report." = "請描述你檢舉的具體原因。"; +"Pornographic And Vulgar" = "色情低俗"; +"Politically Sensitive" = "政治敏感"; +"Insult Attacks" = "辱罵攻擊"; +"Bloody Violence" = "血腥暴力"; +"Suicide And Self Harm" = "自殺與自殘"; +"Plagiarism Infringement" = "抄襲侵權"; +"Invasion Of Privacy" = "侵犯隱私"; +"False Rumor" = "虛假謠言"; +"Other Harmful Information" = "其他有害資訊"; +"Character Name And Description" = "角色名稱與描述"; +"Picture" = "圖片"; +"Timbre" = "音色"; +"Please select at least one report reason" = "請至少選擇一項檢舉原因"; +"Please select at least one content type" = "請至少選擇一項內容類型"; +"Submit" = "提交"; +"Selection Content" = "選擇內容"; +"Voice Connecting..." = "連線中..."; +"Voice Recording..." = "錄音中..."; +"Voice Recognizing..." = "識別中..."; +"Voice Recording Ended" = "錄音結束"; +"Voice Cancelled" = "已取消"; +"Voice Listening..." = "聆聽中..."; +"Voice Recognition Failed" = "識別失敗"; +"Voice Recognition Completed" = "識別完成"; +"By continuing, you agree to our terms of service and confirm that you have read our privacy policy" = "繼續即表示你同意我們的服務條款,並確認你已閱讀隱私政策"; +"terms of service" = "服務條款"; +"privacy policy" = "隱私政策"; +"Become A Member Of Love Key" = "成為 Love Key 會員"; +"Unlock All Functions" = "解鎖全部功能"; +"Wireless Sub-ai Dialogue" = "無限子 AI 對話"; +"Personalized\nKeyboard" = "個人化\n鍵盤"; +"Chat\nPersona" = "聊天\n人設"; +"Emotional\nCounseling" = "情感\n諮詢"; +"Monthly Subscription" = "月度訂閱"; + +"AI Assistant" = "AI Assistant"; +"AI Chat" = "AI Chat"; +"Membership Agreement" = "《會員協議》"; +"Download information missing" = "Download information missing"; +"Download failed" = "Download failed"; +"Theme information missing" = "Theme information missing"; +"Delete failed, please try again" = "Delete failed, please try again"; +"Processing..." = "Processing..."; +"Copied" = "Copied"; +"Default keyboard skin restored" = "Default keyboard skin restored"; +"Keyboard has been notified to unzip. Switch to the custom keyboard to apply." = "Keyboard has been notified to unzip. Switch to the custom keyboard to apply."; +"Failed to apply skin" = "Failed to apply skin"; +"Recording too short, please try again" = "Recording too short, please try again"; +"Restore default skin" = "Restore default skin"; +"Fetch failed" = "Fetch failed"; +"Unable to access shared container, failed to apply skin" = "Unable to access shared container, failed to apply skin"; +"Update" = "Update"; +"Update content" = "Update content"; +"No reply content received" = "No reply content received"; +"No audio data received" = "No audio data received"; +"No audio file received" = "No audio file received"; +"No speech content recognized" = "No speech content recognized"; +"Loading theme details" = "Loading theme details"; +"Upgrade now" = "Upgrade now"; +"Pink skin" = "Pink skin"; +"Sign in with Apple" = "Sign in with Apple"; +"Voice reply" = "Voice reply"; +"Voice message" = "Voice message"; +"Voice recognition failed" = "Voice recognition failed"; +"Voice-to-text failed, please try again" = "Voice-to-text failed, please try again"; +"Please sign in before using AI features" = "Please sign in before using AI features"; +"Please return to the Home screen and open the app to sign in" = "Please return to the Home screen and open the app to sign in"; +"Please enable Full Access to continue" = "Please enable Full Access to continue"; +"Request failed" = "Request failed"; +"Please enter content" = "Please enter content"; +"Purchase failed" = "Purchase failed"; +"Remote skin" = "Remote skin"; +"Sign in with Apple requires iOS 13+" = "Sign in with Apple requires iOS 13+"; +"Failed to save audio" = "Failed to save audio"; +"Audio playback failed" = "Audio playback failed"; +"Audio data is empty" = "Audio data is empty"; +"Failed to parse audio data" = "Failed to parse audio data"; +"Audio file does not exist" = "Audio file does not exist"; + +"Follow: Settings -> General -> Keyboard -> Keyboards -> %@ -> Allow Full Access" = "請依路徑:設定 → 一般 → 鍵盤 → 鍵盤 → %@ → 允許完整存取"; + +"Agreement coming soon" = "協議即將推出"; +"Application to the skin failed" = "套用皮膚失敗"; +"Are you sure to delete?" = "確定要刪除嗎?"; +"Chat Without Speed Limits" = "無限速聊天"; +"Choose" = "選擇"; +"Click \"copy Any Conversation\", \"paste\"\nAnd Try Replying Using The Keyboard\n[persona] Method" = "點擊「複製任一對話」「貼上」,嘗試使用鍵盤「人設」方式回覆"; +"Clipboard is empty" = "剪貼簿為空"; +"Coming Soon" = "即將推出"; +"Consumption" = "消費"; +"Download" = "下載"; +"Download again" = "再次下載"; +"Due On" = "到期於"; +"Empty file data" = "檔案資料為空"; +"Failed to load products" = "載入商品失敗"; +"Free" = "免費"; +"Go To Recharge" = "前往儲值"; +"I Miss You" = "我想你"; +"I'm Going To Take A Bath" = "我要去洗澡了"; +"Invalid file" = "無效檔案"; +"Invalid parameter" = "參數無效"; +"Invalid upload request" = "無效上傳請求"; +"Loading..." = "載入中..."; +"Longer Chat History" = "更長聊天記錄"; +"Member recharge" = "會員儲值"; +"Membership Benefits" = "會員權益"; +"No more data" = "沒有更多資料"; +"No products available" = "沒有可用商品"; +"Operation failed" = "操作失敗"; +"Payload missing" = "缺少 payload"; +"Please open the App to finish purchase" = "請開啟 App 完成購買"; +"Please select a product" = "請選擇商品"; +"Product unavailable" = "商品不可用"; +"Receipt missing" = "缺少收據"; +"Search Role" = "搜尋角色"; +"Search coming soon" = "搜尋功能即將推出"; +"Search result" = "搜尋結果"; +"Server error" = "伺服器錯誤"; +"Subscription" = "訂閱"; +"The existing conversation history will be cleared." = "現有對話記錄將被清除。"; +"The skin in use cannot be deleted" = "使用中的皮膚無法刪除"; +"Themes" = "主題"; +"Think Again" = "再想想"; +"Unlimited Chatting" = "無限聊天"; +"Warm = man" = "暖男 = 男"; +"Warm hearted man" = "暖心男"; +"Warm2 hearted man" = "暖心男2"; +"Warm3 hearted man" = "暖心男3"; +"Welcome To Use The [key Of Love] Keyboard" = "歡迎使用 [key Of Love] 鍵盤"; +"Welcome to use the [key of love] keyboard" = "歡迎使用 [key of love] 鍵盤"; +"Your session has expired. Please sign in again." = "會話已過期,請重新登入。"; +"send a message" = "發送訊息"; diff --git a/keyBoard.xcodeproj/project.pbxproj b/keyBoard.xcodeproj/project.pbxproj index 9cf503a..d832132 100644 --- a/keyBoard.xcodeproj/project.pbxproj +++ b/keyBoard.xcodeproj/project.pbxproj @@ -215,11 +215,13 @@ 04A9FE0F2EB481100020DB6D /* KBHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC97082EB31B14007BD342 /* KBHUD.m */; }; 04A9FE132EB4D0D20020DB6D /* KBFullAccessManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE112EB4D0D20020DB6D /* KBFullAccessManager.m */; }; 04A9FE162EB873C80020DB6D /* UIViewController+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE152EB873C80020DB6D /* UIViewController+Extension.m */; }; - 04A9FE1A2EB892460020DB6D /* KBLocalizationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE192EB892460020DB6D /* KBLocalizationManager.m */; }; - 04A9FE1B2EB892460020DB6D /* KBLocalizationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE192EB892460020DB6D /* KBLocalizationManager.m */; }; - 04A9FE202EB893F10020DB6D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 04A9FE1E2EB893F10020DB6D /* Localizable.strings */; }; - 04A9FE212EB893F10020DB6D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 04A9FE1E2EB893F10020DB6D /* Localizable.strings */; }; - 04B5A1A22EEFA12300AAAAAA /* KBPayProductModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 04B5A1A12EEFA12300AAAAAA /* KBPayProductModel.m */; }; + 04A9FE1A2EB892460020DB6D /* KBLocalizationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE192EB892460020DB6D /* KBLocalizationManager.m */; }; + 04A9FE1B2EB892460020DB6D /* KBLocalizationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE192EB892460020DB6D /* KBLocalizationManager.m */; }; + 04A9FE202EB893F10020DB6D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 04A9FE1E2EB893F10020DB6D /* Localizable.strings */; }; + 04A9FE212EB893F10020DB6D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 04A9FE1E2EB893F10020DB6D /* Localizable.strings */; }; + E0A100102F60000100ABCDEF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E0A100002F60000100ABCDEF /* InfoPlist.strings */; }; + E0A100112F60000100ABCDEF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E0A100002F60000100ABCDEF /* InfoPlist.strings */; }; + 04B5A1A22EEFA12300AAAAAA /* KBPayProductModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 04B5A1A12EEFA12300AAAAAA /* KBPayProductModel.m */; }; 04BBF89D2F3ACD8800B1FBB2 /* KBKeyboardStressTestVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BBF89A2F3ACD8800B1FBB2 /* KBKeyboardStressTestVC.m */; }; 04BBF89E2F3ACD8800B1FBB2 /* KBTestVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BBF89C2F3ACD8800B1FBB2 /* KBTestVC.m */; }; 04BBF9002F3C97CB00B1FBB2 /* DeepgramWebSocketClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BBF8FF2F3C97CB00B1FBB2 /* DeepgramWebSocketClient.m */; }; @@ -549,10 +551,14 @@ 04837AE52F5848680012BDE2 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/LaunchScreen.strings; sourceTree = ""; }; 04837AE62F5848680012BDE2 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Main.strings; sourceTree = ""; }; 04837AE72F5848680012BDE2 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Localizable.strings; sourceTree = ""; }; - 04837AE82F5848820012BDE2 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/LaunchScreen.strings"; sourceTree = ""; }; - 04837AE92F5848820012BDE2 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Main.strings"; sourceTree = ""; }; - 04837AEA2F5848820012BDE2 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Localizable.strings"; sourceTree = ""; }; - 048908BA2EBE1FCB00FABA60 /* BaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseViewController.h; sourceTree = ""; }; + 04837AE82F5848820012BDE2 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/LaunchScreen.strings"; sourceTree = ""; }; + 04837AE92F5848820012BDE2 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Main.strings"; sourceTree = ""; }; + 04837AEA2F5848820012BDE2 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Localizable.strings"; sourceTree = ""; }; + E0A100022F60000100ABCDEF /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/InfoPlist.strings"; sourceTree = ""; }; + E0A100032F60000100ABCDEF /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; + E0A100042F60000100ABCDEF /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/InfoPlist.strings; sourceTree = ""; }; + E0A100052F60000100ABCDEF /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/InfoPlist.strings"; sourceTree = ""; }; + 048908BA2EBE1FCB00FABA60 /* BaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseViewController.h; sourceTree = ""; }; 048908BB2EBE1FCB00FABA60 /* BaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseViewController.m; sourceTree = ""; }; 048908C12EBE32B800FABA60 /* KBSearchVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSearchVC.h; sourceTree = ""; }; 048908C22EBE32B800FABA60 /* KBSearchVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSearchVC.m; sourceTree = ""; }; @@ -723,10 +729,11 @@ 04A9FE112EB4D0D20020DB6D /* KBFullAccessManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBFullAccessManager.m; sourceTree = ""; }; 04A9FE142EB873C80020DB6D /* UIViewController+Extension.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIViewController+Extension.h"; sourceTree = ""; }; 04A9FE152EB873C80020DB6D /* UIViewController+Extension.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+Extension.m"; sourceTree = ""; }; - 04A9FE182EB892460020DB6D /* KBLocalizationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBLocalizationManager.h; sourceTree = ""; }; - 04A9FE192EB892460020DB6D /* KBLocalizationManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBLocalizationManager.m; sourceTree = ""; }; - 04A9FE1C2EB893F10020DB6D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; - 04B5A1A02EEFA12300AAAAAA /* KBPayProductModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBPayProductModel.h; sourceTree = ""; }; + 04A9FE182EB892460020DB6D /* KBLocalizationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBLocalizationManager.h; sourceTree = ""; }; + 04A9FE192EB892460020DB6D /* KBLocalizationManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBLocalizationManager.m; sourceTree = ""; }; + 04A9FE1C2EB893F10020DB6D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + E0A100012F60000100ABCDEF /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; + 04B5A1A02EEFA12300AAAAAA /* KBPayProductModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBPayProductModel.h; sourceTree = ""; }; 04B5A1A12EEFA12300AAAAAA /* KBPayProductModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPayProductModel.m; sourceTree = ""; }; 04BBF8992F3ACD8800B1FBB2 /* KBKeyboardStressTestVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKeyboardStressTestVC.h; sourceTree = ""; }; 04BBF89A2F3ACD8800B1FBB2 /* KBKeyboardStressTestVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKeyboardStressTestVC.m; sourceTree = ""; }; @@ -1690,14 +1697,15 @@ path = Manager; sourceTree = ""; }; - 04A9FE1F2EB893F10020DB6D /* Localization */ = { - isa = PBXGroup; - children = ( - 04A9FE1E2EB893F10020DB6D /* Localizable.strings */, - ); - path = Localization; - sourceTree = ""; - }; + 04A9FE1F2EB893F10020DB6D /* Localization */ = { + isa = PBXGroup; + children = ( + 04A9FE1E2EB893F10020DB6D /* Localizable.strings */, + E0A100002F60000100ABCDEF /* InfoPlist.strings */, + ); + path = Localization; + sourceTree = ""; + }; 04C6EAB92EAF86530089C901 /* keyBoard */ = { isa = PBXGroup; children = ( @@ -2391,9 +2399,10 @@ 04C6EAC42EAF87020089C901 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; - files = ( - 04A9FE202EB893F10020DB6D /* Localizable.strings in Resources */, - 041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */, + files = ( + 04A9FE202EB893F10020DB6D /* Localizable.strings in Resources */, + E0A100102F60000100ABCDEF /* InfoPlist.strings in Resources */, + 041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */, 04E2277F2F516ED3001A8F14 /* PrivacyInfo.xcprivacy in Resources */, A1B2C3ED2F20000000000001 /* kb_words.txt in Resources */, A1B2C3F12F20000000000002 /* kb_keyboard_layout_config.json in Resources */, @@ -2424,10 +2433,11 @@ 043213C62F56F5280065C888 /* 台湾省初始皮肤注音.zip in Resources */, 04E038D82F20BFFB002CA5A0 /* websocket-api.md in Resources */, 0479200B2ED87CEE004E8522 /* permiss_video.mp4 in Resources */, - 04E2277D2F516EBD001A8F14 /* PrivacyInfo.xcprivacy in Resources */, - 04C6EABA2EAF86530089C901 /* Assets.xcassets in Resources */, - 04A9FE212EB893F10020DB6D /* Localizable.strings in Resources */, - 047920072ED86ABC004E8522 /* kb_guide_keyboard.gif in Resources */, + 04E2277D2F516EBD001A8F14 /* PrivacyInfo.xcprivacy in Resources */, + 04C6EABA2EAF86530089C901 /* Assets.xcassets in Resources */, + 04A9FE212EB893F10020DB6D /* Localizable.strings in Resources */, + E0A100112F60000100ABCDEF /* InfoPlist.strings in Resources */, + 047920072ED86ABC004E8522 /* kb_guide_keyboard.gif in Resources */, 046086752F191CC700757C95 /* AI技术分析.txt in Resources */, 047920112ED98E7D004E8522 /* permiss_video_2.mp4 in Resources */, 04C6EABC2EAF86530089C901 /* LaunchScreen.storyboard in Resources */, @@ -2827,19 +2837,31 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ - 04A9FE1E2EB893F10020DB6D /* Localizable.strings */ = { - isa = PBXVariantGroup; - children = ( - 04A9FE1C2EB893F10020DB6D /* en */, - 04837AE12F5848050012BDE2 /* zh-Hant */, - 04837AE42F58485A0012BDE2 /* es */, - 04837AE72F5848680012BDE2 /* id */, - 04837AEA2F5848820012BDE2 /* pt-PT */, - ); - name = Localizable.strings; - sourceTree = ""; - }; - 04C6EAB12EAF86530089C901 /* LaunchScreen.storyboard */ = { + 04A9FE1E2EB893F10020DB6D /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 04A9FE1C2EB893F10020DB6D /* en */, + 04837AE12F5848050012BDE2 /* zh-Hant */, + 04837AE42F58485A0012BDE2 /* es */, + 04837AE72F5848680012BDE2 /* id */, + 04837AEA2F5848820012BDE2 /* pt-PT */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + E0A100002F60000100ABCDEF /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + E0A100012F60000100ABCDEF /* en */, + E0A100022F60000100ABCDEF /* zh-Hant */, + E0A100032F60000100ABCDEF /* es */, + E0A100042F60000100ABCDEF /* id */, + E0A100052F60000100ABCDEF /* pt-PT */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; + 04C6EAB12EAF86530089C901 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 04C6EAB02EAF86530089C901 /* Base */, @@ -2881,10 +2903,13 @@ "$(inherited)", "KB_KEYCHAIN_ACCESS_GROUP=@\\\"$(AppIdentifierPrefix)com.loveKey.nyx.shared\\\"", ); - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = CustomKeyboard/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = "Key of Love"; - INFOPLIST_KEY_NSHumanReadableCopyright = ""; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = CustomKeyboard/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Key of Love"; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Microphone access is required for voice input."; + INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Photo library write access is required to save images."; + INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Photo library access is required to change your avatar."; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; IPHONEOS_DEPLOYMENT_TARGET = 15; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -2915,10 +2940,13 @@ "$(inherited)", "KB_KEYCHAIN_ACCESS_GROUP=@\\\"$(AppIdentifierPrefix)com.loveKey.nyx.shared\\\"", ); - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = CustomKeyboard/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = "Key of Love"; - INFOPLIST_KEY_NSHumanReadableCopyright = ""; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = CustomKeyboard/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Key of Love"; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Microphone access is required for voice input."; + INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Photo library write access is required to save images."; + INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Photo library access is required to change your avatar."; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; IPHONEOS_DEPLOYMENT_TARGET = 15; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -2955,9 +2983,9 @@ INFOPLIST_FILE = keyBoard/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Key of Love"; INFOPLIST_KEY_CFBundleURLTypes = "{\n CFBundleURLName = \"com.loveKey.nyx.keyboard\";\n CFBundleURLSchemes = (\n kbkeyboardAppExtension\n );\n}"; - INFOPLIST_KEY_NSMicrophoneUsageDescription = "需要使用麦克风进行语音输入"; - INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "保存图片需要写入您的相册"; - INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "更换头像需要访问您的相册"; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Microphone access is required for voice input."; + INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Photo library write access is required to save images."; + INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Photo library access is required to change your avatar."; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = Main; @@ -3006,9 +3034,9 @@ INFOPLIST_FILE = keyBoard/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Key of Love"; INFOPLIST_KEY_CFBundleURLTypes = "{\n CFBundleURLName = \"com.loveKey.nyx.keyboard\";\n CFBundleURLSchemes = (\n kbkeyboardAppExtension\n );\n}"; - INFOPLIST_KEY_NSMicrophoneUsageDescription = "需要使用麦克风进行语音输入"; - INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "保存图片需要写入您的相册"; - INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "更换头像需要访问您的相册"; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Microphone access is required for voice input."; + INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Photo library write access is required to save images."; + INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Photo library access is required to change your avatar."; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = Main; diff --git a/keyBoard/Class/AiTalk/V/Chat/KBPersonaChatCell.m b/keyBoard/Class/AiTalk/V/Chat/KBPersonaChatCell.m index 9f346a4..37616e1 100644 --- a/keyBoard/Class/AiTalk/V/Chat/KBPersonaChatCell.m +++ b/keyBoard/Class/AiTalk/V/Chat/KBPersonaChatCell.m @@ -940,7 +940,7 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe case KBChatMessageActionTypeCopy: { if (message.text.length > 0) { [UIPasteboard generalPasteboard].string = message.text; - [KBHUD showSuccess:KBLocalized(@"复制成功")]; + [KBHUD showSuccess:KBLocalized(@"Copied")]; } } break; case KBChatMessageActionTypeDelete: { @@ -973,7 +973,7 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe dispatch_async(dispatch_get_main_queue(), ^{ [KBHUD dismiss]; if (!success || error) { - NSString *msg = error.localizedDescription ?: KBLocalized(@"删除失败,请重试"); + NSString *msg = error.localizedDescription ?: KBLocalized(@"Delete failed, please try again"); [KBHUD showError:msg]; return; } diff --git a/keyBoard/Class/AiTalk/VC/AIPersonInfoVC.m b/keyBoard/Class/AiTalk/VC/AIPersonInfoVC.m index 30b0d77..ccd2f8b 100644 --- a/keyBoard/Class/AiTalk/VC/AIPersonInfoVC.m +++ b/keyBoard/Class/AiTalk/VC/AIPersonInfoVC.m @@ -349,7 +349,7 @@ _goChatButton.layer.cornerRadius = 25; } - [_goChatButton setTitle:KBLocalized(@"Go Chatting") forState:UIControlStateNormal]; + [_goChatButton setTitle:KBLocalized(@"Chatting") forState:UIControlStateNormal]; [_goChatButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; _goChatButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; [_goChatButton addTarget:self action:@selector(goChatButtonTapped) forControlEvents:UIControlEventTouchUpInside]; diff --git a/keyBoard/Class/AiTalk/VC/AIReportVC.m b/keyBoard/Class/AiTalk/VC/AIReportVC.m index 019751b..1852d4f 100644 --- a/keyBoard/Class/AiTalk/VC/AIReportVC.m +++ b/keyBoard/Class/AiTalk/VC/AIReportVC.m @@ -548,7 +548,7 @@ - (UILabel *)contentTitleLabel { if (!_contentTitleLabel) { _contentTitleLabel = [[UILabel alloc] init]; - _contentTitleLabel.text = KBLocalized(@"selection content"); + _contentTitleLabel.text = KBLocalized(@"Selection Content"); _contentTitleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium]; _contentTitleLabel.textColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1.0]; } diff --git a/keyBoard/Class/AiTalk/VC/KBAIHomeVC.m b/keyBoard/Class/AiTalk/VC/KBAIHomeVC.m index 68ea210..a84bc3d 100644 --- a/keyBoard/Class/AiTalk/VC/KBAIHomeVC.m +++ b/keyBoard/Class/AiTalk/VC/KBAIHomeVC.m @@ -1272,9 +1272,9 @@ static void KBChatUpdatedDarwinCallback(CFNotificationCenterRef center, } NSLog(@"[KBAIHomeVC] 语音转文字失败:%@", error.localizedDescription); - [KBHUD showError:KBLocalized(@"语音转文字失败,请重试")]; + [KBHUD showError:KBLocalized(@"Voice-to-text failed, please try again")]; if (cell) { - [cell updateLastUserMessage:KBLocalized(@"语音识别失败")]; + [cell updateLastUserMessage:KBLocalized(@"Voice recognition failed")]; } strongSelf.isVoiceProcessing = NO; [strongSelf updateCollectionViewScrollState]; @@ -1284,7 +1284,7 @@ static void KBChatUpdatedDarwinCallback(CFNotificationCenterRef center, NSString *transcript = response.data.transcript ?: @""; if (transcript.length == 0) { NSLog(@"[KBAIHomeVC] 语音转文字结果为空"); - [KBHUD showError:KBLocalized(@"未识别到语音内容")]; + [KBHUD showError:KBLocalized(@"No speech content recognized")]; if (cell) { [cell removeLoadingUserMessage]; } @@ -1305,7 +1305,7 @@ static void KBChatUpdatedDarwinCallback(CFNotificationCenterRef center, - (void)voiceRecordManagerDidRecordTooShort:(KBVoiceRecordManager *)manager { NSLog(@"[KBAIHomeVC] 录音过短,已忽略"); - [KBHUD showError:KBLocalized(@"录音时间过短,请重新录音")]; + [KBHUD showError:KBLocalized(@"Recording too short, please try again")]; } - (void)voiceRecordManager:(KBVoiceRecordManager *)manager diff --git a/keyBoard/Class/AiTalk/VM/KBVoiceToTextManager.m b/keyBoard/Class/AiTalk/VM/KBVoiceToTextManager.m index c8374cc..b963cab 100644 --- a/keyBoard/Class/AiTalk/VM/KBVoiceToTextManager.m +++ b/keyBoard/Class/AiTalk/VM/KBVoiceToTextManager.m @@ -8,6 +8,7 @@ #import "KBVoiceToTextManager.h" #import "DeepgramStreamingManager.h" #import "KBVoiceInputBar.h" +#import "KBLocalizationManager.h" @interface KBVoiceToTextManager () @@ -55,6 +56,7 @@ if (!self.deepgramEnabled) { return; } + [self kb_refreshDeepgramLanguage]; [self.deepgramManager prepareConnection]; } @@ -72,7 +74,7 @@ self.deepgramManager.delegate = self; self.deepgramManager.serverURL = @"wss://api.deepgram.com/v1/listen"; self.deepgramManager.apiKey = @"9c792eb63a65d644cbc95785155754cd1e84f8cf"; - self.deepgramManager.language = @"en"; + [self kb_refreshDeepgramLanguage]; self.deepgramManager.model = @"nova-3"; self.deepgramManager.punctuate = YES; self.deepgramManager.smartFormat = YES; @@ -86,15 +88,35 @@ [self.fullText setString:@""]; } +- (void)kb_refreshDeepgramLanguage { + self.deepgramManager.language = [self kb_currentDeepgramLanguageCode]; +} + +- (NSString *)kb_currentDeepgramLanguageCode { + NSString *languageCode = [KBLocalizationManager shared].currentLanguageCode ?: @"en"; + NSString *lc = languageCode.lowercaseString; + if ([lc hasPrefix:@"es"]) { return @"es"; } + if ([lc hasPrefix:@"id"]) { return @"id"; } + if ([lc hasPrefix:@"pt"]) { return @"pt"; } + if ([lc hasPrefix:@"zh-hant"] || [lc hasPrefix:@"zh_tw"] || [lc hasPrefix:@"zh-tw"] || [lc hasPrefix:@"zh-hk"]) { + return @"zh-TW"; + } + if ([lc hasPrefix:@"zh-hans"] || [lc hasPrefix:@"zh_cn"] || [lc hasPrefix:@"zh-cn"]) { + return @"zh-CN"; + } + return @"en"; +} + #pragma mark - KBVoiceInputBarDelegate - (void)voiceInputBarDidBeginRecording:(KBVoiceInputBar *)inputBar { [self resetTranscript]; if (self.deepgramEnabled) { - inputBar.statusText = @"正在连接..."; + [self kb_refreshDeepgramLanguage]; + inputBar.statusText = KBLocalized(@"Voice Connecting..."); [self.deepgramManager start]; } else { - inputBar.statusText = @"正在录音..."; + inputBar.statusText = KBLocalized(@"Voice Recording..."); } if ([self.delegate respondsToSelector:@selector @@ -105,10 +127,10 @@ - (void)voiceInputBarDidEndRecording:(KBVoiceInputBar *)inputBar { if (self.deepgramEnabled) { - inputBar.statusText = @"正在识别..."; + inputBar.statusText = KBLocalized(@"Voice Recognizing..."); [self.deepgramManager stopAndFinalize]; } else { - inputBar.statusText = @"录音结束"; + inputBar.statusText = KBLocalized(@"Voice Recording Ended"); } if ([self.delegate respondsToSelector:@selector @@ -118,7 +140,7 @@ } - (void)voiceInputBarDidCancelRecording:(KBVoiceInputBar *)inputBar { - inputBar.statusText = @"已取消"; + inputBar.statusText = KBLocalized(@"Voice Cancelled"); [self resetTranscript]; if (self.deepgramEnabled) { [self.deepgramManager cancel]; @@ -136,7 +158,7 @@ if (!self.deepgramEnabled) { return; } - self.inputBar.statusText = @"正在聆听..."; + self.inputBar.statusText = KBLocalized(@"Voice Listening..."); } - (void)deepgramStreamingManagerDidDisconnect:(NSError *_Nullable)error { @@ -147,7 +169,7 @@ return; } - self.inputBar.statusText = @"识别失败"; + self.inputBar.statusText = KBLocalized(@"Voice Recognition Failed"); if ([self.delegate respondsToSelector:@selector (voiceToTextManager:didFailWithError:)]) { [self.delegate voiceToTextManager:self didFailWithError:error]; @@ -174,7 +196,7 @@ } self.inputBar.statusText = - displayText.length > 0 ? displayText : @"正在识别..."; + displayText.length > 0 ? displayText : KBLocalized(@"Voice Recognizing..."); if ([self.delegate respondsToSelector:@selector (voiceToTextManager:didUpdateInterimText:)]) { @@ -195,7 +217,7 @@ NSString *finalText = [self.fullText copy]; self.inputBar.statusText = - finalText.length > 0 ? finalText : @"识别完成"; + finalText.length > 0 ? finalText : KBLocalized(@"Voice Recognition Completed"); if (finalText.length > 0 && [self.delegate respondsToSelector:@selector @@ -208,7 +230,7 @@ if (!self.deepgramEnabled) { return; } - self.inputBar.statusText = @"识别失败"; + self.inputBar.statusText = KBLocalized(@"Voice Recognition Failed"); if ([self.delegate respondsToSelector:@selector (voiceToTextManager:didFailWithError:)]) { [self.delegate voiceToTextManager:self didFailWithError:error]; diff --git a/keyBoard/Class/Common/V/KBAppUpdateView.m b/keyBoard/Class/Common/V/KBAppUpdateView.m index 1177b0a..8a62f23 100644 --- a/keyBoard/Class/Common/V/KBAppUpdateView.m +++ b/keyBoard/Class/Common/V/KBAppUpdateView.m @@ -102,15 +102,13 @@ } - (void)applyDefaultTexts { - self.titleText = KBLocalized(@""); + self.titleText = @""; self.versionText = @"V1.1.4"; - self.contentTitleText = KBLocalized(@"Ver. Update Content"); + self.contentTitleText = KBLocalized(@"Update content"); self.contentItems = @[ - KBLocalized(@"AAAAAAAAAAAAAAAAAAA"), - KBLocalized(@"SSSSSSSSSSSSSSSSSSS") - ]; - self.upgradeButtonTitle = KBLocalized(@"立即升级"); - self.cancelButtonTitle = KBLocalized(@"取消"); + ]; + self.upgradeButtonTitle = KBLocalized(@"Upgrade now"); + self.cancelButtonTitle = KBLocalized(@"Cancel"); self.showsCancelButton = NO; } @@ -179,10 +177,10 @@ if (!updateInfo) { return; } self.showsCancelButton = !updateInfo.forceUpdate; if (!updateInfo.forceUpdate) { - self.cancelButtonTitle = KBLocalized(@"取消"); + self.cancelButtonTitle = KBLocalized(@"Cancel"); } - self.upgradeButtonTitle = KBLocalized(@"更新"); - self.contentTitleText = KBLocalized(@"更新内容"); + self.upgradeButtonTitle = KBLocalized(@"Update"); + self.contentTitleText = KBLocalized(@"Update content"); NSString *versionName = updateInfo.latestVersionName ?: @""; if (versionName.length > 0 && ![versionName hasPrefix:@"V"] && ![versionName hasPrefix:@"v"]) { versionName = [NSString stringWithFormat:@"V%@", versionName]; diff --git a/keyBoard/Class/Guard/VC/KBSexSelVC.m b/keyBoard/Class/Guard/VC/KBSexSelVC.m index e5fbb8c..7b917fc 100644 --- a/keyBoard/Class/Guard/VC/KBSexSelVC.m +++ b/keyBoard/Class/Guard/VC/KBSexSelVC.m @@ -284,7 +284,7 @@ typedef NS_ENUM(NSInteger, KBSexOption) { - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [UILabel new]; - _titleLabel.text = @"Please Select Your Gender"; + _titleLabel.text = KBLocalized(@"Please Select Your Gender"); _titleLabel.font = [KBFont medium:20]; _titleLabel.textColor = [UIColor colorWithHex:KBBlackValue]; _titleLabel.numberOfLines = 1; @@ -305,7 +305,7 @@ typedef NS_ENUM(NSInteger, KBSexOption) { - (UIButton *)skipButton { if (!_skipButton) { _skipButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [_skipButton setTitle:@"Skip" forState:UIControlStateNormal]; + [_skipButton setTitle:KBLocalized(@"Skip") forState:UIControlStateNormal]; [_skipButton setTitleColor:[UIColor colorWithHex:KBBlackValue] forState:UIControlStateNormal]; _skipButton.titleLabel.font = [KBFont medium:12]; _skipButton.backgroundColor = [UIColor colorWithHex:0xE9F7F4]; @@ -341,7 +341,7 @@ typedef NS_ENUM(NSInteger, KBSexOption) { - (UILabel *)maleLabel { if (!_maleLabel) { _maleLabel = [UILabel new]; - _maleLabel.text = @"Male"; + _maleLabel.text = KBLocalized(@"Male"); _maleLabel.font = [KBFont medium:20]; _maleLabel.textColor = [UIColor colorWithHex:KBBlackValue]; } @@ -369,7 +369,7 @@ typedef NS_ENUM(NSInteger, KBSexOption) { - (UILabel *)femaleLabel { if (!_femaleLabel) { _femaleLabel = [UILabel new]; - _femaleLabel.text = @"Female"; + _femaleLabel.text = KBLocalized(@"Female"); _femaleLabel.font = [KBFont medium:20]; _femaleLabel.textColor = [UIColor colorWithHex:KBBlackValue]; } @@ -405,7 +405,7 @@ typedef NS_ENUM(NSInteger, KBSexOption) { - (UILabel *)otherLabel { if (!_otherLabel) { _otherLabel = [UILabel new]; - _otherLabel.text = @"The Third Gender"; + _otherLabel.text = KBLocalized(@"The Third Gender"); _otherLabel.font = [KBFont medium:20]; _otherLabel.textColor = [UIColor colorWithHex:KBBlackValue]; } @@ -415,7 +415,7 @@ typedef NS_ENUM(NSInteger, KBSexOption) { - (UIButton *)confirmButton { if (!_confirmButton) { _confirmButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [_confirmButton setTitle:@"Turn On The Keyboard" forState:UIControlStateNormal]; + [_confirmButton setTitle:KBLocalized(@"Turn On The Keyboard") forState:UIControlStateNormal]; [_confirmButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; _confirmButton.titleLabel.font = [KBFont bold:16]; _confirmButton.backgroundColor = [UIColor blackColor]; diff --git a/keyBoard/Class/Home/V/HomeHeadView.m b/keyBoard/Class/Home/V/HomeHeadView.m index 3a5ef8c..1e7f53e 100644 --- a/keyBoard/Class/Home/V/HomeHeadView.m +++ b/keyBoard/Class/Home/V/HomeHeadView.m @@ -133,13 +133,13 @@ - (void)defaultData { // 默认文案(使用英文,便于与示例图一致) - self.titleLabel.text = @"Become A Member Of Love Key"; - self.subTitleLabel.text = @"Unlock All Functions"; + self.titleLabel.text = KBLocalized(@"Become A Member Of Love Key"); + self.subTitleLabel.text = KBLocalized(@"Unlock All Functions"); - NSArray *titles = @[@"Wireless Sub-ai Dialogue", - @"Personalized\nKeyboard", - @"Chat\nPersona", - @"Emotional\nCounseling"]; + NSArray *titles = @[KBLocalized(@"Wireless Sub-ai Dialogue"), + KBLocalized(@"Personalized\nKeyboard"), + KBLocalized(@"Chat\nPersona"), + KBLocalized(@"Emotional\nCounseling")]; NSArray *images = @[[UIImage imageNamed:@"home_ai_icon"], [UIImage imageNamed:@"home_keyboard_icon"], [UIImage imageNamed:@"home_chat_icon"], diff --git a/keyBoard/Class/Home/VC/FunctionTest/KBSkinCenterVC.m b/keyBoard/Class/Home/VC/FunctionTest/KBSkinCenterVC.m index 6c85437..79b1a39 100644 --- a/keyBoard/Class/Home/VC/FunctionTest/KBSkinCenterVC.m +++ b/keyBoard/Class/Home/VC/FunctionTest/KBSkinCenterVC.m @@ -45,12 +45,12 @@ - (void)viewDidLoad { [super viewDidLoad]; -// self.title = KBLocalized(@"皮肤中心"); +// self.title = KBLocalized(@"Skin Center"); self.view.backgroundColor = [UIColor whiteColor]; self.skins = @[ @{ @"id": @"local本地", - @"name": KBLocalized(@"粉色皮肤"), + @"name": KBLocalized(@"Pink skin"), // 关键:zip_url 写成 bundle:// 前缀 + 文件名 @"zip_url": @"bundle://fense.zip", @@ -64,7 +64,7 @@ }, @{ @"id": @"remote002", - @"name": KBLocalized(@"远程皮肤"), + @"name": KBLocalized(@"Remote skin"), // 关键:zip_url 写成 bundle:// 前缀 + 文件名 @"zip_url": @"http://gx.zhukeping.com/download/Christmas.zip", @@ -85,7 +85,7 @@ // 底部添加“恢复默认皮肤”测试按钮 UIButton *reset = [UIButton buttonWithType:UIButtonTypeSystem]; - [reset setTitle:KBLocalized(@"恢复默认皮肤") forState:UIControlStateNormal]; + [reset setTitle:KBLocalized(@"Restore default skin") forState:UIControlStateNormal]; reset.titleLabel.font = [UIFont systemFontOfSize:15 weight:UIFontWeightMedium]; reset.layer.cornerRadius = 8.0; reset.layer.borderWidth = 1.0; @@ -138,14 +138,13 @@ NSDictionary *skin = self.skins[idx]; if (!skin) return; if (idx == 0) { -// NSString *title = (indexPath.item < self.dataSource.count) ? self.dataSource[indexPath.item] : KBLocalized(@"专属皮肤002"); // 将需求固定到 002.zip,本地写死皮肤 id,便于键盘扩展识别并解压。 static NSString * const kKBBundleSkinId002 = @"bundle_skin_fense"; [KBSkinInstallBridge publishBundleSkinRequestWithId:kKBBundleSkinId002 name:@"" ?: kKBBundleSkinId002 zipName:@"fense.zip" iconShortNames:nil]; - [KBHUD showInfo:KBLocalized(@"已通知键盘解压,切换到自定义键盘即可生效")]; + [KBHUD showInfo:KBLocalized(@"Keyboard has been notified to unzip. Switch to the custom keyboard to apply.")]; }else if (idx == 1){ [[KBSkinService shared] applySkinWithJSON:skin fromViewController:self @@ -161,7 +160,7 @@ name:@"" ?: kKBBundleSkinId002 zipName:@"Christmas.zip" iconShortNames:nil]; - [KBHUD showInfo:KBLocalized(@"已通知键盘解压,切换到自定义键盘即可生效")]; + [KBHUD showInfo:KBLocalized(@"Keyboard has been notified to unzip. Switch to the custom keyboard to apply.")]; } } diff --git a/keyBoard/Class/Home/VC/FunctionTest/KBTestVC.m b/keyBoard/Class/Home/VC/FunctionTest/KBTestVC.m index 3158db0..7bb9a2a 100644 --- a/keyBoard/Class/Home/VC/FunctionTest/KBTestVC.m +++ b/keyBoard/Class/Home/VC/FunctionTest/KBTestVC.m @@ -40,7 +40,7 @@ self.tableView.tableHeaderView = header; [self.view addSubview:self.tableView]; - self.items = @[ KBLocalized(@"home_item_lang_test"), KBLocalized(@"home_item_keyboard_permission"), KBLocalized(@"皮肤中心"), KBLocalized(@"苹果登录") ]; + self.items = @[ KBLocalized(@"home_item_lang_test"), KBLocalized(@"home_item_keyboard_permission"), KBLocalized(@"Skin Center"), KBLocalized(@"Sign in with Apple") ]; dispatch_async(dispatch_get_main_queue(), ^{ [self.textView becomeFirstResponder]; }); @@ -52,7 +52,7 @@ - (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; self.title = KBLocalized(@"Test"); - self.items = @[ KBLocalized(@"home_item_lang_test"), KBLocalized(@"home_item_keyboard_permission"), KBLocalized(@"皮肤中心"), KBLocalized(@"苹果登录") ]; + self.items = @[ KBLocalized(@"home_item_lang_test"), KBLocalized(@"home_item_keyboard_permission"), KBLocalized(@"Skin Center"), KBLocalized(@"Sign in with Apple") ]; [self.tableView reloadData]; } diff --git a/keyBoard/Class/Login/V/KBLoginPopView.m b/keyBoard/Class/Login/V/KBLoginPopView.m index 74b6b6e..4ab18b4 100644 --- a/keyBoard/Class/Login/V/KBLoginPopView.m +++ b/keyBoard/Class/Login/V/KBLoginPopView.m @@ -71,7 +71,7 @@ }]; } else { UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem]; - [btn setTitle:KBLocalized(@"需要 iOS13+ 才能使用 Apple 登录") forState:UIControlStateNormal]; + [btn setTitle:KBLocalized(@"Sign in with Apple requires iOS 13+") forState:UIControlStateNormal]; btn.enabled = NO; btn.layer.cornerRadius = 8.0; btn.layer.borderWidth = 1.0; diff --git a/keyBoard/Class/Login/VC/KBEmailLoginVC.m b/keyBoard/Class/Login/VC/KBEmailLoginVC.m index 841e315..2c84b67 100644 --- a/keyBoard/Class/Login/VC/KBEmailLoginVC.m +++ b/keyBoard/Class/Login/VC/KBEmailLoginVC.m @@ -304,8 +304,10 @@ NSUInteger charIndex = [layoutManager characterIndexForGlyphAtIndex:glyphIndex]; NSString *lowerFull = textView.text.lowercaseString ?: @""; - NSRange termsRange = [lowerFull rangeOfString:@"terms of service"]; - NSRange privacyRange = [lowerFull rangeOfString:@"privacy policy"]; + NSString *termsText = [KBLocalized(@"terms of service") lowercaseString]; + NSString *privacyText = [KBLocalized(@"privacy policy") lowercaseString]; + NSRange termsRange = [lowerFull rangeOfString:termsText]; + NSRange privacyRange = [lowerFull rangeOfString:privacyText]; BOOL hitTerms = (termsRange.location != NSNotFound && NSLocationInRange(charIndex, termsRange)); BOOL hitPrivacy = (privacyRange.location != NSNotFound && NSLocationInRange(charIndex, privacyRange)); @@ -513,9 +515,9 @@ _agreementTextView.textContainerInset = UIEdgeInsetsZero; _agreementTextView.textContainer.lineFragmentPadding = 0; - NSString *fullText = @"By continuing, you agree to our terms of service and confirm that you have read our privacy policy"; - NSString *termsText = @"terms of service"; - NSString *privacyText = @"privacy policy"; + NSString *fullText = KBLocalized(@"By continuing, you agree to our terms of service and confirm that you have read our privacy policy"); + NSString *termsText = KBLocalized(@"terms of service"); + NSString *privacyText = KBLocalized(@"privacy policy"); NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; paragraph.alignment = NSTextAlignmentCenter; diff --git a/keyBoard/Class/Login/VC/KBEmailRegistVC.m b/keyBoard/Class/Login/VC/KBEmailRegistVC.m index d7726e4..839cc36 100644 --- a/keyBoard/Class/Login/VC/KBEmailRegistVC.m +++ b/keyBoard/Class/Login/VC/KBEmailRegistVC.m @@ -386,19 +386,17 @@ NSUInteger charIndex = [layoutManager characterIndexForGlyphAtIndex:glyphIndex]; NSString *lowerFull = textView.text.lowercaseString ?: @""; - NSRange termsRange = [lowerFull rangeOfString:@"terms of service"]; - NSRange privacyRange = [lowerFull rangeOfString:@"privacy policy"]; + NSString *termsText = [KBLocalized(@"terms of service") lowercaseString]; + NSString *privacyText = [KBLocalized(@"privacy policy") lowercaseString]; + NSRange termsRange = [lowerFull rangeOfString:termsText]; + NSRange privacyRange = [lowerFull rangeOfString:privacyText]; BOOL hitTerms = (termsRange.location != NSNotFound && NSLocationInRange(charIndex, termsRange)); BOOL hitPrivacy = (privacyRange.location != NSNotFound && NSLocationInRange(charIndex, privacyRange)); if (hitTerms || hitPrivacy) { KBLOG(@"tap policy in KBEmailRegistVC"); // 后续可统一跳转到协议页 - if (hitTerms == true) { - [KBHUD showInfo:@"hitTerms"]; - }else{ - [KBHUD showInfo:@"hitPrivacy"]; - } + [KBHUD showInfo:KBLocalized(@"Open agreement")]; } } @@ -723,9 +721,9 @@ _agreementTextView.textContainerInset = UIEdgeInsetsZero; _agreementTextView.textContainer.lineFragmentPadding = 0; - NSString *fullText = @"By continuing, you agree to our terms of service and confirm that you have read our privacy policy"; - NSString *termsText = @"terms of service"; - NSString *privacyText = @"privacy policy"; + NSString *fullText = KBLocalized(@"By continuing, you agree to our terms of service and confirm that you have read our privacy policy"); + NSString *termsText = KBLocalized(@"terms of service"); + NSString *privacyText = KBLocalized(@"privacy policy"); NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; paragraph.alignment = NSTextAlignmentCenter; diff --git a/keyBoard/Class/Login/VC/KBLoginVC.m b/keyBoard/Class/Login/VC/KBLoginVC.m index e591f85..78641bf 100644 --- a/keyBoard/Class/Login/VC/KBLoginVC.m +++ b/keyBoard/Class/Login/VC/KBLoginVC.m @@ -372,9 +372,9 @@ _agreementTextView.textContainer.lineFragmentPadding = 0; // 协议文案:terms of service / privacy policy 为纯黑色并可点击,其余为 #717171 - NSString *fullText = @"By continuing, you agree to our terms of service and confirm that you have read our privacy policy"; - NSString *termsText = @"terms of service"; - NSString *privacyText = @"privacy policy"; + NSString *fullText = KBLocalized(@"By continuing, you agree to our terms of service and confirm that you have read our privacy policy"); + NSString *termsText = KBLocalized(@"terms of service"); + NSString *privacyText = KBLocalized(@"privacy policy"); NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; paragraph.alignment = NSTextAlignmentCenter; // 多行文本整体居中 @@ -488,8 +488,10 @@ NSUInteger charIndex = [layoutManager characterIndexForGlyphAtIndex:glyphIndex]; NSString *lowerFull = textView.text.lowercaseString ?: @""; - NSRange termsRange = [lowerFull rangeOfString:@"terms of service"]; - NSRange privacyRange = [lowerFull rangeOfString:@"privacy policy"]; + NSString *termsText = [KBLocalized(@"terms of service") lowercaseString]; + NSString *privacyText = [KBLocalized(@"privacy policy") lowercaseString]; + NSRange termsRange = [lowerFull rangeOfString:termsText]; + NSRange privacyRange = [lowerFull rangeOfString:privacyText]; BOOL hitTerms = (termsRange.location != NSNotFound && NSLocationInRange(charIndex, termsRange)); BOOL hitPrivacy = (privacyRange.location != NSNotFound && NSLocationInRange(charIndex, privacyRange)); diff --git a/keyBoard/Class/Login/VC/LoginViewController.m b/keyBoard/Class/Login/VC/LoginViewController.m index acbe5ce..4a703c5 100644 --- a/keyBoard/Class/Login/VC/LoginViewController.m +++ b/keyBoard/Class/Login/VC/LoginViewController.m @@ -107,7 +107,7 @@ - (UIButton *)compatHintButton { if (!_compatHintButton) { _compatHintButton = [UIButton buttonWithType:UIButtonTypeSystem]; - [_compatHintButton setTitle:KBLocalized(@"需要 iOS13+ 才能使用 Apple 登录") forState:UIControlStateNormal]; + [_compatHintButton setTitle:KBLocalized(@"Sign in with Apple requires iOS 13+") forState:UIControlStateNormal]; _compatHintButton.enabled = NO; } return _compatHintButton; diff --git a/keyBoard/Class/Manager/KBSkinService.m b/keyBoard/Class/Manager/KBSkinService.m index b873972..3d8a679 100644 --- a/keyBoard/Class/Manager/KBSkinService.m +++ b/keyBoard/Class/Manager/KBSkinService.m @@ -34,7 +34,7 @@ if (mode == KBSkinSourceModeResetToDefault) { [[KBSkinManager shared] resetToDefault]; if (completion) completion(YES); - [KBHUD showInfo:KBLocalized(@"已恢复默认键盘皮肤")]; + [KBHUD showInfo:KBLocalized(@"Default keyboard skin restored")]; return; } @@ -70,7 +70,6 @@ // [perm presentPermissionIfNeededFrom:presenting]; // // // 简单提示:皮肤可以应用,但未开启完全访问时扩展无法读取 App Group 中的图片。 -// [KBHUD showInfo:KBLocalized(@"皮肤已应用,键盘需开启“允许完全访问”后才能显示图片")]; // } switch (mode) { @@ -106,9 +105,9 @@ message = KBLocalized(@"Applied. Switch to the keyboard to view."); } else if ([error.domain isEqualToString:KBSkinBridgeErrorDomain] && error.code == KBSkinBridgeErrorContainerUnavailable) { - message = KBLocalized(@"无法访问共享容器,应用皮肤失败"); + message = KBLocalized(@"Unable to access shared container, failed to apply skin"); } else { - message = KBLocalized(@"应用皮肤失败"); + message = KBLocalized(@"Failed to apply skin"); } [KBHUD showInfo:message]; }]; @@ -132,7 +131,7 @@ NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:AppGroup]; if (!containerURL) { if (completion) completion(NO); - [KBHUD showInfo:KBLocalized(@"无法访问共享容器,应用皮肤失败")]; + [KBHUD showInfo:KBLocalized(@"Unable to access shared container, failed to apply skin")]; return; } diff --git a/keyBoard/Class/Me/V/KBSkinSectionTitleCell.m b/keyBoard/Class/Me/V/KBSkinSectionTitleCell.m index d672097..8399ffe 100644 --- a/keyBoard/Class/Me/V/KBSkinSectionTitleCell.m +++ b/keyBoard/Class/Me/V/KBSkinSectionTitleCell.m @@ -21,7 +21,7 @@ } - (void)config:(NSString *)title { - self.titleLabel.text = title ?: @"Recommended Skin"; + self.titleLabel.text = title ?: KBLocalized(@"Recommended Skin"); } - (UILabel *)titleLabel { @@ -29,7 +29,7 @@ _titleLabel = [UILabel new]; _titleLabel.textColor = [UIColor colorWithHex:0x1B1F1A]; _titleLabel.font = [KBFont medium:14]; - _titleLabel.text = @"Recommended Skin"; + _titleLabel.text = KBLocalized(@"Recommended Skin"); } return _titleLabel; } diff --git a/keyBoard/Class/Me/VC/MySkinVC.m b/keyBoard/Class/Me/VC/MySkinVC.m index eb75e08..45e9738 100644 --- a/keyBoard/Class/Me/VC/MySkinVC.m +++ b/keyBoard/Class/Me/VC/MySkinVC.m @@ -68,7 +68,7 @@ static NSString * const kMySkinCellId = @"kMySkinCellId"; [self.collectionView kb_makeDefaultEmptyViewWithImage:nil title:KBLocalized(@"No data") detail:KBLocalized(@"Pull down to refresh") - buttonTitle:KBLocalized(@"") + buttonTitle:@"" tapHandler:nil buttonHandler:^{ [weakSelf.collectionView.mj_header beginRefreshing]; }]; [self.collectionView kb_setLYAutoShowEnabled:NO]; // 采用手动控制显隐 diff --git a/keyBoard/Class/Pay/V/KBVipSubscribeCell.m b/keyBoard/Class/Pay/V/KBVipSubscribeCell.m index 0daba95..14e3cb6 100644 --- a/keyBoard/Class/Pay/V/KBVipSubscribeCell.m +++ b/keyBoard/Class/Pay/V/KBVipSubscribeCell.m @@ -74,7 +74,7 @@ } - (void)configTitle:(NSString *)title price:(NSString *)price strike:(nullable NSString *)strike { - self.titleLabel.text = title.length ? title : @"Monthly Subscription"; + self.titleLabel.text = title.length ? title : KBLocalized(@"Monthly Subscription"); self.priceLabel.text = price.length ? price : @"$4.49"; self.strikeLabel.hidden = (strike.length == 0); if (strike.length) { @@ -115,7 +115,7 @@ - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [UILabel new]; - _titleLabel.text = @"Monthly Subscription"; + _titleLabel.text = KBLocalized(@"Monthly Subscription"); _titleLabel.textColor = [UIColor colorWithHex:KBBlackValue]; _titleLabel.font = [KBFont medium:13]; } diff --git a/keyBoard/Class/Pay/VC/KBJfPay.m b/keyBoard/Class/Pay/VC/KBJfPay.m index 611709e..5c73616 100644 --- a/keyBoard/Class/Pay/VC/KBJfPay.m +++ b/keyBoard/Class/Pay/VC/KBJfPay.m @@ -466,7 +466,7 @@ static NSString * const kKBJfPayCellId = @"kKBJfPayCellId"; - (UIButton *)agreementButton { if (!_agreementButton) { _agreementButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [_agreementButton setTitle:KBLocalized(@"《Embership Agreement》") forState:UIControlStateNormal]; + [_agreementButton setTitle:KBLocalized(@"Membership Agreement") forState:UIControlStateNormal]; [_agreementButton setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal]; // _agreementButton.titleLabel.font = [UIFont systemFontOfSize:10 weight:UIFontWeightSemibold]; _agreementButton.titleLabel.font = [KBFont regular:12]; diff --git a/keyBoard/Class/Pay/VC/KBPayMainVC.m b/keyBoard/Class/Pay/VC/KBPayMainVC.m index df288e4..3ac0c06 100644 --- a/keyBoard/Class/Pay/VC/KBPayMainVC.m +++ b/keyBoard/Class/Pay/VC/KBPayMainVC.m @@ -425,7 +425,7 @@ static const CGFloat JXheightForHeaderInSection = 39; - (UILabel *)agreementLabel { if (!_agreementLabel) { _agreementLabel = [UILabel new]; - _agreementLabel.text = KBLocalized(@"By Clicking \"pay\", You Indicate Your Agreement To The"); + _agreementLabel.text = KBLocalized(@"By clicking Pay, you indicate your agreement to the"); _agreementLabel.font = [KBFont regular:12]; _agreementLabel.textColor = [UIColor colorWithHex:KBBlackValue]; } @@ -435,7 +435,7 @@ static const CGFloat JXheightForHeaderInSection = 39; - (UIButton *)agreementButton { if (!_agreementButton) { _agreementButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [_agreementButton setTitle:KBLocalized(@"《Embership Agreement》") forState:UIControlStateNormal]; + [_agreementButton setTitle:KBLocalized(@"Membership Agreement") forState:UIControlStateNormal]; [_agreementButton setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal]; _agreementButton.titleLabel.font = [KBFont regular:12]; [_agreementButton addTarget:self action:@selector(onTapAgreementButton) forControlEvents:UIControlEventTouchUpInside]; diff --git a/keyBoard/Class/Pay/VC/KBPaySvipVC.m b/keyBoard/Class/Pay/VC/KBPaySvipVC.m index 9558473..9c50b94 100644 --- a/keyBoard/Class/Pay/VC/KBPaySvipVC.m +++ b/keyBoard/Class/Pay/VC/KBPaySvipVC.m @@ -69,9 +69,9 @@ static NSString * const kKBSvipBenefitHeaderId = @"kKBSvipBenefitHeaderId"; // 权益列表数据(使用现有图标资源) self.benefits = @[ @{@"icon": @"pay_ais_icon", @"title": KBLocalized(@"Wireless Sub-ai Dialogue")}, - @{@"icon": @"pay_keyboards_icon", @"title": KBLocalized(@"Personalized Keyboard")}, - @{@"icon": @"pay_person_icon", @"title": KBLocalized(@"Chat Persona")}, - @{@"icon": @"pay_phone_icon", @"title": KBLocalized(@"Emotional Counseling")}, + @{@"icon": @"pay_keyboards_icon", @"title": KBLocalized(@"Personalized\nKeyboard")}, + @{@"icon": @"pay_person_icon", @"title": KBLocalized(@"Chat\nPersona")}, + @{@"icon": @"pay_phone_icon", @"title": KBLocalized(@"Emotional\nCounseling")}, @{@"icon": @"pay_history_icon", @"title": KBLocalized(@"Longer Chat History")}, @{@"icon": @"pay_chats_icon", @"title": KBLocalized(@"Unlimited Chatting")}, @{@"icon": @"pay_speed_icon", @"title": KBLocalized(@"Chat Without Speed Limits")}, diff --git a/keyBoard/Class/Shop/VC/KBShopItemVC.m b/keyBoard/Class/Shop/VC/KBShopItemVC.m index e6840fb..2d53239 100644 --- a/keyBoard/Class/Shop/VC/KBShopItemVC.m +++ b/keyBoard/Class/Shop/VC/KBShopItemVC.m @@ -186,16 +186,6 @@ KBSkinDetailVC *vc = [[KBSkinDetailVC alloc] init]; vc.themeId = selTheme.themeId; [self.navigationController pushViewController:vc animated:true]; - return; - KBShopThemeModel *theme = (indexPath.item < self.dataSource.count) ? self.dataSource[indexPath.item] : nil; - NSString *title = theme.themeName.length ? theme.themeName : KBLocalized(@"专属皮肤002"); - // 将需求固定到 002.zip,本地写死皮肤 id,便于键盘扩展识别并解压。 - static NSString * const kKBBundleSkinId002 = @"bundle_skin_fense"; - [KBSkinInstallBridge publishBundleSkinRequestWithId:kKBBundleSkinId002 - name:title ?: kKBBundleSkinId002 - zipName:@"fense.zip" - iconShortNames:nil]; - [KBHUD showInfo:KBLocalized(@"已通知键盘解压,切换到自定义键盘即可生效")]; } - (void)setStyle:(KBShopStyleModel *)style { diff --git a/keyBoard/Class/Shop/VC/KBSkinDetailVC.m b/keyBoard/Class/Shop/VC/KBSkinDetailVC.m index 4b5f529..ab5b239 100644 --- a/keyBoard/Class/Shop/VC/KBSkinDetailVC.m +++ b/keyBoard/Class/Shop/VC/KBSkinDetailVC.m @@ -105,7 +105,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { } case KBSkinDetailSectionTitle: { KBSkinSectionTitleCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kSectionTitleCellId forIndexPath:indexPath]; - [cell config:@"Recommended Skin"]; + [cell config:KBLocalized(@"Recommended Skin")]; return cell; } case KBSkinDetailSectionGrid: { @@ -248,11 +248,11 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { - (void)handleDownloadAction { // if (self.isProcessingAction) { return; } if (self.themeId.length == 0) { - [KBHUD showInfo:KBLocalized(@"主题信息缺失")]; + [KBHUD showInfo:KBLocalized(@"Theme information missing")]; return; } if (!self.detailModel) { - [KBHUD showInfo:KBLocalized(@"正在加载主题详情")]; + [KBHUD showInfo:KBLocalized(@"Loading theme details")]; return; } @@ -283,7 +283,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { // weakSelf.isProcessingAction = NO; [KBHUD dismiss]; if (error || !success) { - NSString *msg = error.localizedDescription ?: KBLocalized(@"购买失败"); + NSString *msg = error.localizedDescription ?: KBLocalized(@"Purchase failed"); [KBHUD showInfo:msg]; return; } @@ -310,7 +310,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { NSString *zipURL = [skin[@"zip_url"] isKindOfClass:NSString.class] ? skin[@"zip_url"] : @""; if (skin.count == 0 || zipURL.length == 0) { [KBHUD dismiss]; - [KBHUD showInfo:KBLocalized(@"下载信息缺失")]; + [KBHUD showInfo:KBLocalized(@"Download information missing")]; return; } NSLog(@"⬇️[SkinDetail] download request id=%@ zip=%@ force=YES", @@ -329,7 +329,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) { [strongSelf.shopVM restoreThemeWithId:themeId completion:nil]; } } else { - [KBHUD showInfo:KBLocalized(@"下载失败")]; + [KBHUD showInfo:KBLocalized(@"Download failed")]; } }]; }); diff --git a/keyBoard/VC/KBPermissionViewController.m b/keyBoard/VC/KBPermissionViewController.m index 9e44830..7ecaadf 100644 --- a/keyBoard/VC/KBPermissionViewController.m +++ b/keyBoard/VC/KBPermissionViewController.m @@ -311,7 +311,7 @@ static void *KBPermPlayerPresentationSizeContext = &KBPermPlayerPresentationSize - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [UILabel new]; - _titleLabel.text = (@"key of love keyboard"); + _titleLabel.text = KBLocalized(@"key of love keyboard"); _titleLabel.font = [UIFont systemFontOfSize:20 weight:UIFontWeightSemibold]; _titleLabel.textColor = [UIColor blackColor]; _titleLabel.textAlignment = NSTextAlignmentCenter; @@ -322,7 +322,7 @@ static void *KBPermPlayerPresentationSizeContext = &KBPermPlayerPresentationSize - (UILabel *)tipsLabel { if (!_tipsLabel) { _tipsLabel = [UILabel new]; - _tipsLabel.text = (@"One-click to find a partner"); + _tipsLabel.text = KBLocalized(@"One-click to find a partner"); _tipsLabel.font = [UIFont systemFontOfSize:14]; _tipsLabel.textColor = [UIColor darkGrayColor]; _tipsLabel.textAlignment = NSTextAlignmentCenter; @@ -333,7 +333,7 @@ static void *KBPermPlayerPresentationSizeContext = &KBPermPlayerPresentationSize - (UIButton *)openButton { if (!_openButton) { _openButton = [UIButton buttonWithType:UIButtonTypeCustom]; - [_openButton setTitle:@"Turn on the keyboard" forState:UIControlStateNormal]; + [_openButton setTitle:KBLocalized(@"Turn on the keyboard") forState:UIControlStateNormal]; _openButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; [_openButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; _openButton.backgroundColor = [UIColor colorWithHex:KBBlackValue];