key缺少,添加权限多语言

This commit is contained in:
2026-03-07 13:29:29 +08:00
parent e03287605c
commit cbcf8c4197
47 changed files with 986 additions and 225 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -19,7 +19,7 @@
// 1) 访
if (![[KBFullAccessManager shared] hasFullAccess]) {
// 访
// [KBHUD showInfo:KBLocalized(@"处理中…")];
// [KBHUD showInfo:KBLocalized(@"Processing...")];
[[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self.view];
return;
}

View File

@@ -7,6 +7,7 @@
#import "NetworkStreamHandler.h"
#import <Security/Security.h>
#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"];

View File

@@ -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];
}

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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];
}
});

View File

@@ -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];
// }

View File

@@ -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)

View File

@@ -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.";

View File

@@ -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";

View File

@@ -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.";

View File

@@ -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";

View File

@@ -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.";

View File

@@ -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";

View File

@@ -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.";

View File

@@ -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";

View File

@@ -0,0 +1,3 @@
"NSMicrophoneUsageDescription" = "需要使用麥克風進行語音輸入。";
"NSPhotoLibraryUsageDescription" = "更換頭像需要存取你的相簿。";
"NSPhotoLibraryAddUsageDescription" = "儲存圖片需要寫入你的相簿。";

View File

@@ -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" = "發送訊息";

View File

@@ -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 = "<group>"; };
04837AE62F5848680012BDE2 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Main.strings; sourceTree = "<group>"; };
04837AE72F5848680012BDE2 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Localizable.strings; sourceTree = "<group>"; };
04837AE82F5848820012BDE2 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/LaunchScreen.strings"; sourceTree = "<group>"; };
04837AE92F5848820012BDE2 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Main.strings"; sourceTree = "<group>"; };
04837AEA2F5848820012BDE2 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Localizable.strings"; sourceTree = "<group>"; };
048908BA2EBE1FCB00FABA60 /* BaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseViewController.h; sourceTree = "<group>"; };
04837AE82F5848820012BDE2 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/LaunchScreen.strings"; sourceTree = "<group>"; };
04837AE92F5848820012BDE2 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Main.strings"; sourceTree = "<group>"; };
04837AEA2F5848820012BDE2 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/Localizable.strings"; sourceTree = "<group>"; };
E0A100022F60000100ABCDEF /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
E0A100032F60000100ABCDEF /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
E0A100042F60000100ABCDEF /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/InfoPlist.strings; sourceTree = "<group>"; };
E0A100052F60000100ABCDEF /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
048908BA2EBE1FCB00FABA60 /* BaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseViewController.h; sourceTree = "<group>"; };
048908BB2EBE1FCB00FABA60 /* BaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseViewController.m; sourceTree = "<group>"; };
048908C12EBE32B800FABA60 /* KBSearchVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSearchVC.h; sourceTree = "<group>"; };
048908C22EBE32B800FABA60 /* KBSearchVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSearchVC.m; sourceTree = "<group>"; };
@@ -723,10 +729,11 @@
04A9FE112EB4D0D20020DB6D /* KBFullAccessManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBFullAccessManager.m; sourceTree = "<group>"; };
04A9FE142EB873C80020DB6D /* UIViewController+Extension.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIViewController+Extension.h"; sourceTree = "<group>"; };
04A9FE152EB873C80020DB6D /* UIViewController+Extension.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+Extension.m"; sourceTree = "<group>"; };
04A9FE182EB892460020DB6D /* KBLocalizationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBLocalizationManager.h; sourceTree = "<group>"; };
04A9FE192EB892460020DB6D /* KBLocalizationManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBLocalizationManager.m; sourceTree = "<group>"; };
04A9FE1C2EB893F10020DB6D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
04B5A1A02EEFA12300AAAAAA /* KBPayProductModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBPayProductModel.h; sourceTree = "<group>"; };
04A9FE182EB892460020DB6D /* KBLocalizationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBLocalizationManager.h; sourceTree = "<group>"; };
04A9FE192EB892460020DB6D /* KBLocalizationManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBLocalizationManager.m; sourceTree = "<group>"; };
04A9FE1C2EB893F10020DB6D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
E0A100012F60000100ABCDEF /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
04B5A1A02EEFA12300AAAAAA /* KBPayProductModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBPayProductModel.h; sourceTree = "<group>"; };
04B5A1A12EEFA12300AAAAAA /* KBPayProductModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPayProductModel.m; sourceTree = "<group>"; };
04BBF8992F3ACD8800B1FBB2 /* KBKeyboardStressTestVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKeyboardStressTestVC.h; sourceTree = "<group>"; };
04BBF89A2F3ACD8800B1FBB2 /* KBKeyboardStressTestVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKeyboardStressTestVC.m; sourceTree = "<group>"; };
@@ -1690,14 +1697,15 @@
path = Manager;
sourceTree = "<group>";
};
04A9FE1F2EB893F10020DB6D /* Localization */ = {
isa = PBXGroup;
children = (
04A9FE1E2EB893F10020DB6D /* Localizable.strings */,
);
path = Localization;
sourceTree = "<group>";
};
04A9FE1F2EB893F10020DB6D /* Localization */ = {
isa = PBXGroup;
children = (
04A9FE1E2EB893F10020DB6D /* Localizable.strings */,
E0A100002F60000100ABCDEF /* InfoPlist.strings */,
);
path = Localization;
sourceTree = "<group>";
};
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 = "<group>";
};
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 = "<group>";
};
E0A100002F60000100ABCDEF /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
E0A100012F60000100ABCDEF /* en */,
E0A100022F60000100ABCDEF /* zh-Hant */,
E0A100032F60000100ABCDEF /* es */,
E0A100042F60000100ABCDEF /* id */,
E0A100052F60000100ABCDEF /* pt-PT */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
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;

View File

@@ -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;
}

View File

@@ -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];

View File

@@ -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];
}

View File

@@ -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

View File

@@ -8,6 +8,7 @@
#import "KBVoiceToTextManager.h"
#import "DeepgramStreamingManager.h"
#import "KBVoiceInputBar.h"
#import "KBLocalizationManager.h"
@interface KBVoiceToTextManager () <KBVoiceInputBarDelegate,
DeepgramStreamingManagerDelegate>
@@ -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];

View File

@@ -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];

View File

@@ -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];

View File

@@ -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"],

View File

@@ -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.")];
}
}

View File

@@ -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];
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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));

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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]; //

View File

@@ -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];
}

View File

@@ -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];

View File

@@ -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];

View File

@@ -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")},

View File

@@ -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 {

View File

@@ -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")];
}
}];
});

View File

@@ -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];