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) { if (trim.length == 0) {
[KBHUD showInfo:KBLocalized(@"请输入内容")]; [KBHUD showInfo:KBLocalized(@"Please enter content")];
return; return;
} }
[self kb_sendChatText:trim]; [self kb_sendChatText:trim];
@@ -128,7 +128,7 @@ static const NSUInteger kKBChatMessageLimit = 6;
[self kb_prefetchAvatarForMessage:outgoing]; [self kb_prefetchAvatarForMessage:outgoing];
if (![[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self.view]) { if (![[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self.view]) {
[KBHUD showInfo:KBLocalized(@"请开启完全访问后使用")]; [KBHUD showInfo:KBLocalized(@"Please enable Full Access to continue")];
return; return;
} }
@@ -259,12 +259,12 @@ static const NSUInteger kKBChatMessageLimit = 6;
if (mockPath.length > 0) { if (mockPath.length > 0) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.35 * NSEC_PER_SEC)), dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.35 * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{ dispatch_get_main_queue(), ^{
NSString *displayText = KBLocalized(@"语音回复"); NSString *displayText = KBLocalized(@"Voice reply");
KBChatMessage *incoming = KBChatMessage *incoming =
[KBChatMessage messageWithText:displayText [KBChatMessage messageWithText:displayText
outgoing:NO outgoing:NO
audioFilePath:mockPath]; audioFilePath:mockPath];
incoming.displayName = KBLocalized(@"AI助手"); incoming.displayName = KBLocalized(@"AI Assistant");
[self kb_appendChatMessage:incoming]; [self kb_appendChatMessage:incoming];
[self kb_playChatAudioAtPath:mockPath]; [self kb_playChatAudioAtPath:mockPath];
}); });
@@ -284,7 +284,7 @@ static const NSUInteger kKBChatMessageLimit = 6;
} }
if (error) { if (error) {
NSString *tip = error.localizedDescription NSString *tip = error.localizedDescription
?: KBLocalized(@"请求失败"); ?: KBLocalized(@"Request failed");
[KBHUD showInfo:tip]; [KBHUD showInfo:tip];
return; return;
} }
@@ -304,7 +304,7 @@ static const NSUInteger kKBChatMessageLimit = 6;
initWithBase64EncodedString:audioBase64 initWithBase64EncodedString:audioBase64
options:0]; options:0];
if (data.length == 0) { if (data.length == 0) {
[KBHUD showInfo:KBLocalized(@"音频数据解析失败")]; [KBHUD showInfo:KBLocalized(@"Failed to parse audio data")];
return; return;
} }
[self kb_handleChatAudioData:data [self kb_handleChatAudioData:data
@@ -312,7 +312,7 @@ static const NSUInteger kKBChatMessageLimit = 6;
displayText:displayText]; displayText:displayText];
return; return;
} }
[KBHUD showInfo:KBLocalized(@"未获取到音频文件")]; [KBHUD showInfo:KBLocalized(@"No audio file received")];
}); });
}]; }];
} }
@@ -352,7 +352,7 @@ static const NSUInteger kKBChatMessageLimit = 6;
[self.chatPanelView [self.chatPanelView
kb_removeLoadingAssistantMessage]; kb_removeLoadingAssistantMessage];
[KBHUD showInfo:response.message [KBHUD showInfo:response.message
?: KBLocalized(@"请求失败")]; ?: KBLocalized(@"Request failed")];
return; return;
} }
@@ -362,7 +362,7 @@ static const NSUInteger kKBChatMessageLimit = 6;
if (response.data.aiResponse.length == 0) { if (response.data.aiResponse.length == 0) {
[self.chatPanelView [self.chatPanelView
kb_removeLoadingAssistantMessage]; kb_removeLoadingAssistantMessage];
[KBHUD showInfo:KBLocalized(@"未获取到回复内容")]; [KBHUD showInfo:KBLocalized(@"No reply content received")];
return; return;
} }
@@ -450,13 +450,13 @@ static const NSUInteger kKBChatMessageLimit = 6;
if (!response.success) { if (!response.success) {
[KBHUD showInfo:response.errorMessage [KBHUD showInfo:response.errorMessage
?: KBLocalized(@"下载失败")]; ?: KBLocalized(@"Download failed")];
return; return;
} }
if (!response.audioData || if (!response.audioData ||
response.audioData.length == 0) { response.audioData.length == 0) {
[KBHUD showInfo:KBLocalized(@"未获取到音频数据")]; [KBHUD showInfo:KBLocalized(@"No audio data received")];
return; return;
} }
@@ -475,7 +475,7 @@ static const NSUInteger kKBChatMessageLimit = 6;
fileExtension:(NSString *)extension fileExtension:(NSString *)extension
displayText:(NSString *)displayText { displayText:(NSString *)displayText {
if (data.length == 0) { if (data.length == 0) {
[KBHUD showInfo:KBLocalized(@"音频数据为空")]; [KBHUD showInfo:KBLocalized(@"Audio data is empty")];
return; return;
} }
NSString *ext = extension.length > 0 ? extension : @"m4a"; NSString *ext = extension.length > 0 ? extension : @"m4a";
@@ -487,14 +487,14 @@ static const NSUInteger kKBChatMessageLimit = 6;
NSString *filePath = NSString *filePath =
[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]; [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
if (![data writeToFile:filePath atomically:YES]) { if (![data writeToFile:filePath atomically:YES]) {
[KBHUD showInfo:KBLocalized(@"音频保存失败")]; [KBHUD showInfo:KBLocalized(@"Failed to save audio")];
return; return;
} }
NSString *text = NSString *text =
displayText.length > 0 ? displayText : KBLocalized(@"语音消息"); displayText.length > 0 ? displayText : KBLocalized(@"Voice message");
KBChatMessage *incoming = KBChatMessage *incoming =
[KBChatMessage messageWithText:text outgoing:NO audioFilePath:filePath]; [KBChatMessage messageWithText:text outgoing:NO audioFilePath:filePath];
incoming.displayName = KBLocalized(@"AI助手"); incoming.displayName = KBLocalized(@"AI Assistant");
[self kb_appendChatMessage:incoming]; [self kb_appendChatMessage:incoming];
} }
@@ -594,7 +594,7 @@ static const NSUInteger kKBChatMessageLimit = 6;
} }
NSURL *url = [NSURL fileURLWithPath:path]; NSURL *url = [NSURL fileURLWithPath:path];
if (![NSFileManager.defaultManager fileExistsAtPath:path]) { if (![NSFileManager.defaultManager fileExistsAtPath:path]) {
[KBHUD showInfo:KBLocalized(@"音频文件不存在")]; [KBHUD showInfo:KBLocalized(@"Audio file does not exist")];
return; return;
} }
@@ -624,7 +624,7 @@ static const NSUInteger kKBChatMessageLimit = 6;
AVAudioPlayer *player = AVAudioPlayer *player =
[[AVAudioPlayer alloc] initWithContentsOfURL:url error:&playerError]; [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&playerError];
if (playerError || !player) { if (playerError || !player) {
[KBHUD showInfo:KBLocalized(@"音频播放失败")]; [KBHUD showInfo:KBLocalized(@"Audio playback failed")];
return; return;
} }
self.chatAudioPlayer = player; self.chatAudioPlayer = player;
@@ -664,7 +664,7 @@ static const NSUInteger kKBChatMessageLimit = 6;
if (playerError || !player) { if (playerError || !player) {
NSLog(@"[Keyboard] 音频播放器初始化失败: %@", NSLog(@"[Keyboard] 音频播放器初始化失败: %@",
playerError.localizedDescription); playerError.localizedDescription);
[KBHUD showInfo:KBLocalized(@"音频播放失败")]; [KBHUD showInfo:KBLocalized(@"Audio playback failed")];
return; return;
} }

View File

@@ -758,7 +758,7 @@ static NSString *KBFormatMB(uint64_t bytes) {
// 1) 访 // 1) 访
if (![[KBFullAccessManager shared] hasFullAccess]) { if (![[KBFullAccessManager shared] hasFullAccess]) {
// 访 // 访
// [KBHUD showInfo:KBLocalized(@"处理中…")]; // [KBHUD showInfo:KBLocalized(@"Processing...")];
[[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self.view]; [[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self.view];
return; return;
} }
@@ -1109,7 +1109,7 @@ static NSString *KBFormatMB(uint64_t bytes) {
[rawText stringByTrimmingCharactersInSet: [rawText stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]]; [NSCharacterSet whitespaceAndNewlineCharacterSet]];
if (trim.length == 0) { if (trim.length == 0) {
[KBHUD showInfo:KBLocalized(@"请输入内容")]; [KBHUD showInfo:KBLocalized(@"Please enter content")];
return; return;
} }
[self kb_sendChatText:trim]; [self kb_sendChatText:trim];
@@ -1129,7 +1129,7 @@ static NSString *KBFormatMB(uint64_t bytes) {
[self kb_prefetchAvatarForMessage:outgoing]; [self kb_prefetchAvatarForMessage:outgoing];
if (![[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self.view]) { if (![[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self.view]) {
[KBHUD showInfo:KBLocalized(@"请开启完全访问后使用")]; [KBHUD showInfo:KBLocalized(@"Please enable Full Access to continue")];
return; return;
} }
@@ -1258,12 +1258,12 @@ static NSString *KBFormatMB(uint64_t bytes) {
if (mockPath.length > 0) { if (mockPath.length > 0) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.35 * NSEC_PER_SEC)), dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.35 * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{ dispatch_get_main_queue(), ^{
NSString *displayText = KBLocalized(@"语音回复"); NSString *displayText = KBLocalized(@"Voice reply");
KBChatMessage *incoming = KBChatMessage *incoming =
[KBChatMessage messageWithText:displayText [KBChatMessage messageWithText:displayText
outgoing:NO outgoing:NO
audioFilePath:mockPath]; audioFilePath:mockPath];
incoming.displayName = KBLocalized(@"AI助手"); incoming.displayName = KBLocalized(@"AI Assistant");
[self kb_appendChatMessage:incoming]; [self kb_appendChatMessage:incoming];
[self kb_playChatAudioAtPath:mockPath]; [self kb_playChatAudioAtPath:mockPath];
}); });
@@ -1283,7 +1283,7 @@ static NSString *KBFormatMB(uint64_t bytes) {
} }
if (error) { if (error) {
NSString *tip = error.localizedDescription NSString *tip = error.localizedDescription
?: KBLocalized(@"请求失败"); ?: KBLocalized(@"Request failed");
[KBHUD showInfo:tip]; [KBHUD showInfo:tip];
return; return;
} }
@@ -1303,7 +1303,7 @@ static NSString *KBFormatMB(uint64_t bytes) {
initWithBase64EncodedString:audioBase64 initWithBase64EncodedString:audioBase64
options:0]; options:0];
if (data.length == 0) { if (data.length == 0) {
[KBHUD showInfo:KBLocalized(@"音频数据解析失败")]; [KBHUD showInfo:KBLocalized(@"Failed to parse audio data")];
return; return;
} }
[self kb_handleChatAudioData:data [self kb_handleChatAudioData:data
@@ -1311,7 +1311,7 @@ static NSString *KBFormatMB(uint64_t bytes) {
displayText:displayText]; displayText:displayText];
return; 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); NSLog(@"[KB] ❌ 请求失败: %@", response.message);
[self.chatPanelView kb_removeLoadingAssistantMessage]; [self.chatPanelView kb_removeLoadingAssistantMessage];
[KBHUD showInfo:response.message ?: KBLocalized(@"请求失败")]; [KBHUD showInfo:response.message ?: KBLocalized(@"Request failed")];
return; return;
} }
@@ -1352,7 +1352,7 @@ static NSString *KBFormatMB(uint64_t bytes) {
if (response.data.aiResponse.length == 0) { if (response.data.aiResponse.length == 0) {
[self.chatPanelView kb_removeLoadingAssistantMessage]; [self.chatPanelView kb_removeLoadingAssistantMessage];
[KBHUD showInfo:KBLocalized(@"未获取到回复内容")]; [KBHUD showInfo:KBLocalized(@"No reply content received")];
return; return;
} }
@@ -1420,12 +1420,12 @@ static NSString *KBFormatMB(uint64_t bytes) {
if (!self) return; if (!self) return;
if (!response.success) { if (!response.success) {
[KBHUD showInfo:response.errorMessage ?: KBLocalized(@"下载失败")]; [KBHUD showInfo:response.errorMessage ?: KBLocalized(@"Download failed")];
return; return;
} }
if (!response.audioData || response.audioData.length == 0) { if (!response.audioData || response.audioData.length == 0) {
[KBHUD showInfo:KBLocalized(@"未获取到音频数据")]; [KBHUD showInfo:KBLocalized(@"No audio data received")];
return; return;
} }
@@ -1444,7 +1444,7 @@ static NSString *KBFormatMB(uint64_t bytes) {
fileExtension:(NSString *)extension fileExtension:(NSString *)extension
displayText:(NSString *)displayText { displayText:(NSString *)displayText {
if (data.length == 0) { if (data.length == 0) {
[KBHUD showInfo:KBLocalized(@"音频数据为空")]; [KBHUD showInfo:KBLocalized(@"Audio data is empty")];
return; return;
} }
NSString *ext = extension.length > 0 ? extension : @"m4a"; NSString *ext = extension.length > 0 ? extension : @"m4a";
@@ -1456,15 +1456,15 @@ static NSString *KBFormatMB(uint64_t bytes) {
NSString *filePath = NSString *filePath =
[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]; [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
if (![data writeToFile:filePath atomically:YES]) { if (![data writeToFile:filePath atomically:YES]) {
[KBHUD showInfo:KBLocalized(@"音频保存失败")]; [KBHUD showInfo:KBLocalized(@"Failed to save audio")];
return; return;
} }
NSString *text = displayText.length > 0 ? displayText : KBLocalized(@"语音消息"); NSString *text = displayText.length > 0 ? displayText : KBLocalized(@"Voice message");
KBChatMessage *incoming = KBChatMessage *incoming =
[KBChatMessage messageWithText:text [KBChatMessage messageWithText:text
outgoing:NO outgoing:NO
audioFilePath:filePath]; audioFilePath:filePath];
incoming.displayName = KBLocalized(@"AI助手"); incoming.displayName = KBLocalized(@"AI Assistant");
[self kb_appendChatMessage:incoming]; [self kb_appendChatMessage:incoming];
} }
@@ -1566,7 +1566,7 @@ static NSString *KBFormatMB(uint64_t bytes) {
} }
NSURL *url = [NSURL fileURLWithPath:path]; NSURL *url = [NSURL fileURLWithPath:path];
if (![NSFileManager.defaultManager fileExistsAtPath:path]) { if (![NSFileManager.defaultManager fileExistsAtPath:path]) {
[KBHUD showInfo:KBLocalized(@"音频文件不存在")]; [KBHUD showInfo:KBLocalized(@"Audio file does not exist")];
return; return;
} }
@@ -1596,7 +1596,7 @@ static NSString *KBFormatMB(uint64_t bytes) {
AVAudioPlayer *player = AVAudioPlayer *player =
[[AVAudioPlayer alloc] initWithContentsOfURL:url error:&playerError]; [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&playerError];
if (playerError || !player) { if (playerError || !player) {
[KBHUD showInfo:KBLocalized(@"音频播放失败")]; [KBHUD showInfo:KBLocalized(@"Audio playback failed")];
return; return;
} }
self.chatAudioPlayer = player; self.chatAudioPlayer = player;
@@ -1634,7 +1634,7 @@ static NSString *KBFormatMB(uint64_t bytes) {
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithData:audioData error:&playerError]; AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithData:audioData error:&playerError];
if (playerError || !player) { if (playerError || !player) {
NSLog(@"[Keyboard] 音频播放器初始化失败: %@", playerError.localizedDescription); NSLog(@"[Keyboard] 音频播放器初始化失败: %@", playerError.localizedDescription);
[KBHUD showInfo:KBLocalized(@"音频播放失败")]; [KBHUD showInfo:KBLocalized(@"Audio playback failed")];
return; return;
} }

View File

@@ -54,7 +54,7 @@
} }
#endif #endif
if (mode == KBKeyboardPanelModeFunction && !islogin) { 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 *ul = [NSURL URLWithString:[NSString stringWithFormat:@"%@?src=keyboard", KB_UL_LOGIN]];
NSURL *scheme = NSURL *scheme =
[NSURL URLWithString:[NSString stringWithFormat:@"%@://login?src=keyboard", KB_APP_SCHEME]]; [NSURL URLWithString:[NSString stringWithFormat:@"%@://login?src=keyboard", KB_APP_SCHEME]];
@@ -68,7 +68,7 @@
return; return;
} }
dispatch_async(dispatch_get_main_queue(), ^{ 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; return;

View File

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

View File

@@ -7,6 +7,7 @@
#import "NetworkStreamHandler.h" #import "NetworkStreamHandler.h"
#import <Security/Security.h> #import <Security/Security.h>
#import "KBLocalizationManager.h"
@interface NetworkStreamHandler () @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:@"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:@"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:@"keep-alive" forHTTPHeaderField:@"Connection"];
[request setValue:@"1" forHTTPHeaderField:@"Upgrade-Insecure-Requests"]; [request setValue:@"1" forHTTPHeaderField:@"Upgrade-Insecure-Requests"];

View File

@@ -157,7 +157,7 @@ static id KBKeyboardSubscriptionSanitizeJSON(id obj) {
- (void)setupFeatureItems { - (void)setupFeatureItems {
NSArray *titles = @[ NSArray *titles = @[
KBLocalized(@"Wireless Sub-ai\nDialogue"), KBLocalized(@"Wireless Sub-ai Dialogue"),
KBLocalized(@"Personalized\nKeyboard"), KBLocalized(@"Personalized\nKeyboard"),
KBLocalized(@"Chat\nPersona"), KBLocalized(@"Chat\nPersona"),
KBLocalized(@"Emotional\nCounseling") KBLocalized(@"Emotional\nCounseling")
@@ -200,7 +200,7 @@ static id KBKeyboardSubscriptionSanitizeJSON(id obj) {
- (void)fetchProducts { - (void)fetchProducts {
if (self.isLoading) { return; } if (self.isLoading) { return; }
if (![[KBFullAccessManager shared] hasFullAccess]) { if (![[KBFullAccessManager shared] hasFullAccess]) {
[KBHUD showInfo:KBLocalized(@"Enable Full Access to continue")]; [KBHUD showInfo:KBLocalized(@"Please enable Full Access to continue")];
return; return;
} }
self.loading = YES; self.loading = YES;
@@ -405,7 +405,7 @@ static id KBKeyboardSubscriptionSanitizeJSON(id obj) {
- (UILabel *)agreementLabel { - (UILabel *)agreementLabel {
if (!_agreementLabel) { if (!_agreementLabel) {
_agreementLabel = [[UILabel alloc] init]; _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.font = [UIFont systemFontOfSize:11];
_agreementLabel.textColor = [UIColor colorWithHex:0x4A4A4A]; _agreementLabel.textColor = [UIColor colorWithHex:0x4A4A4A];
} }

View File

@@ -118,7 +118,7 @@ static const NSUInteger kKBChatMessageLimit = 10;
// AI // AI
KBChatMessage *msg = [KBChatMessage assistantMessageWithText:text audioId:audioId]; KBChatMessage *msg = [KBChatMessage assistantMessageWithText:text audioId:audioId];
msg.displayName = KBLocalized(@"AI助手"); msg.displayName = KBLocalized(@"AI Assistant");
NSLog(@"[Panel] 创建 AI 消息needsTypewriter: %d", msg.needsTypewriterEffect); NSLog(@"[Panel] 创建 AI 消息needsTypewriter: %d", msg.needsTypewriterEffect);
// 使 // 使
@@ -323,7 +323,7 @@ static const NSUInteger kKBChatMessageLimit = 10;
_titleLabel.textColor = _titleLabel.textColor =
[UIColor kb_dynamicColorWithLightColor:[UIColor colorWithHex:0x1B1F1A] [UIColor kb_dynamicColorWithLightColor:[UIColor colorWithHex:0x1B1F1A]
darkColor:[UIColor whiteColor]]; darkColor:[UIColor whiteColor]];
_titleLabel.text = KBLocalized(@"AI对话"); _titleLabel.text = KBLocalized(@"AI Chat");
} }
return _titleLabel; return _titleLabel;
} }

View File

@@ -79,7 +79,7 @@
self.audioLabel.textColor = textColor; self.audioLabel.textColor = textColor;
self.audioIconView.tintColor = textColor; self.audioIconView.tintColor = textColor;
self.audioLabel.text = self.audioLabel.text =
(message.text.length > 0) ? message.text : KBLocalized(@"语音回复"); (message.text.length > 0) ? message.text : KBLocalized(@"Voice reply");
self.messageLabel.hidden = audioMessage; self.messageLabel.hidden = audioMessage;
self.audioIconView.hidden = !audioMessage; self.audioIconView.hidden = !audioMessage;
self.audioLabel.hidden = !audioMessage; self.audioLabel.hidden = !audioMessage;
@@ -94,7 +94,7 @@
self.nameLabel.hidden = outgoing; self.nameLabel.hidden = outgoing;
self.nameLabel.textColor = nameColor; self.nameLabel.textColor = nameColor;
self.nameLabel.text = self.nameLabel.text =
(message.displayName.length > 0) ? message.displayName : KBLocalized(@"AI助手"); (message.displayName.length > 0) ? message.displayName : KBLocalized(@"AI Assistant");
// loading // loading
if (message.isLoading && !outgoing) { if (message.isLoading && !outgoing) {

View File

@@ -161,7 +161,7 @@
- (void)onTapGoEnable { - (void)onTapGoEnable {
UIInputViewController *ivc = self.ivc ?: KBFindInputViewController(self); UIInputViewController *ivc = self.ivc ?: KBFindInputViewController(self);
if (!ivc) { 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]; [KBHUD showInfo:showInfo];
return; return;
} }
@@ -183,7 +183,7 @@
if (success) { if (success) {
[self dismiss]; [self dismiss];
} else { } 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]; [KBHUD showInfo:showInfo];
} }
}); });

View File

@@ -60,7 +60,6 @@
// if (!_placeholderLabelInternal) { // if (!_placeholderLabelInternal) {
// _placeholderLabelInternal = [[UILabel alloc] init]; // _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.textColor = [UIColor colorWithRed:0.20 green:0.64 blue:0.54 alpha:1.0];
// _placeholderLabelInternal.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium]; // _placeholderLabelInternal.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
// } // }

View File

@@ -277,13 +277,8 @@
// self.itemsInternal = @[KBLocalized(@"Warm hearted man"), // self.itemsInternal = @[KBLocalized(@"Warm hearted man"),
// KBLocalized(@"Warm2 hearted man"), // KBLocalized(@"Warm2 hearted man"),
// KBLocalized(@"Warm3 hearted man"), // KBLocalized(@"Warm3 hearted man"),
// KBLocalized(@"撩女生啊u发顺丰大师傅"),
// KBLocalized(@"Warm = man"), // KBLocalized(@"Warm = man"),
// KBLocalized(@"Warm hearted man"), // KBLocalized(@"Warm hearted man"),
// KBLocalized(@"一枚暖男发放"),
// KBLocalized(@"聊天搭子"),
// KBLocalized(@"表达爱意"),
// KBLocalized(@"更多话术")];
// [self.tagListView setItems:self.itemsInternal]; // [self.tagListView setItems:self.itemsInternal];
//} //}
@@ -516,7 +511,7 @@
} }
BOOL shouldShowError = (error != nil); BOOL shouldShowError = (error != nil);
if (shouldShowError) { if (shouldShowError) {
[KBHUD showInfo:error.localizedDescription ?: KBLocalized(@"拉取失败")]; [KBHUD showInfo:error.localizedDescription ?: KBLocalized(@"Fetch failed")];
} }
if (self.streamOverlay) { if (self.streamOverlay) {
[self.streamOverlay finish]; [self.streamOverlay finish];
@@ -533,7 +528,7 @@
BOOL needSubscriptionGuide = (code == KBBizCodeQuotaExhausted); BOOL needSubscriptionGuide = (code == KBBizCodeQuotaExhausted);
NSString *msg = KBBizMessageFromJSONObject(payload); NSString *msg = KBBizMessageFromJSONObject(payload);
if (msg.length == 0) { if (msg.length == 0) {
msg = KBLocalized(@"拉取失败"); msg = KBLocalized(@"Fetch failed");
} }
NSError *bizError = NSError *bizError =
[NSError errorWithDomain:@"KBStreamBizError" [NSError errorWithDomain:@"KBStreamBizError"
@@ -721,7 +716,7 @@
// 1) 访 // 1) 访
if (![[KBFullAccessManager shared] hasFullAccess]) { if (![[KBFullAccessManager shared] hasFullAccess]) {
// 访 // 访
[KBHUD showInfo:KBLocalized(@"处理中…")]; [KBHUD showInfo:KBLocalized(@"Processing...")];
[[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self]; [[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self];
return; return;
} }
@@ -732,7 +727,7 @@
UIInputViewController *ivc = KBFindInputViewController(self); UIInputViewController *ivc = KBFindInputViewController(self);
if (!ivc) { if (!ivc) {
[KBHUD showInfo:KBLocalized(@"请回到桌面手动打开App登录")]; [KBHUD showInfo:KBLocalized(@"Please return to the Home screen and open the app to sign in")];
return; return;
} }
@@ -749,7 +744,7 @@
return; return;
} }
dispatch_async(dispatch_get_main_queue(), ^{ 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; return;
@@ -781,7 +776,6 @@
// [ivc dismissKeyboard]; // [ivc dismissKeyboard];
// BOOL ok = [KBHostAppLauncher openHostAppURL:scheme // BOOL ok = [KBHostAppLauncher openHostAppURL:scheme
// fromResponder:start]; if (!ok) { // fromResponder:start]; if (!ok) {
// [KBHUD showInfo:KBLocalized(@"请切换到主App完成登录")];
// }else{ // }else{
// //
// } // }
@@ -829,7 +823,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer,
return; return;
} }
[KBHUD showInfo:KBLocalized(@"处理中…")]; [KBHUD showInfo:KBLocalized(@"Processing...")];
UIInputViewController *ivc = KBFindInputViewController(self); UIInputViewController *ivc = KBFindInputViewController(self);
if (!ivc) 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."; "Unable to obtain transaction payload." = "Unable to obtain transaction payload.";
"Resume Purchase" = "Resume Purchase"; "Resume Purchase" = "Resume Purchase";
"Downloading..." = "Downloading..."; "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: %@"; "无效响应\nURL: %@\n说明: %@" = "Respuesta no válida\nURL: %@\nDetalle: %@";
"暂无数据" = "Sin datos"; "暂无数据" = "Sin datos";
"请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@" = "Solicitud fallida\nURL: %@\nEstado: %ld\nError: %@\nUserInfo: %@"; "请求失败\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"; "暂无数据" = "Tidak ada data";
"请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@" = "Permintaan gagal\nURL: %@\nStatus: %ld\nError: %@\nUserInfo: %@"; "请求失败\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"; "暂无数据" = "Sem dados";
"请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@" = "Pedido falhou\nURL: %@\nEstado: %ld\nErro: %@\nUserInfo: %@"; "请求失败\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说明: %@" = "無效回應\nURL: %@\n說明: %@";
"暂无数据" = "暫無資料"; "暂无数据" = "暫無資料";
"请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@" = "請求失敗\nURL: %@\n狀態: %ld\n錯誤: %@\nUserInfo: %@"; "请求失败\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 */; }; 04A9FE0F2EB481100020DB6D /* KBHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC97082EB31B14007BD342 /* KBHUD.m */; };
04A9FE132EB4D0D20020DB6D /* KBFullAccessManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE112EB4D0D20020DB6D /* KBFullAccessManager.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 */; }; 04A9FE162EB873C80020DB6D /* UIViewController+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE152EB873C80020DB6D /* UIViewController+Extension.m */; };
04A9FE1A2EB892460020DB6D /* KBLocalizationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE192EB892460020DB6D /* KBLocalizationManager.m */; }; 04A9FE1A2EB892460020DB6D /* KBLocalizationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE192EB892460020DB6D /* KBLocalizationManager.m */; };
04A9FE1B2EB892460020DB6D /* 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 */; }; 04A9FE202EB893F10020DB6D /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 04A9FE1E2EB893F10020DB6D /* Localizable.strings */; };
04A9FE212EB893F10020DB6D /* 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 */; }; 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 */; }; 04BBF89D2F3ACD8800B1FBB2 /* KBKeyboardStressTestVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BBF89A2F3ACD8800B1FBB2 /* KBKeyboardStressTestVC.m */; };
04BBF89E2F3ACD8800B1FBB2 /* KBTestVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BBF89C2F3ACD8800B1FBB2 /* KBTestVC.m */; }; 04BBF89E2F3ACD8800B1FBB2 /* KBTestVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BBF89C2F3ACD8800B1FBB2 /* KBTestVC.m */; };
04BBF9002F3C97CB00B1FBB2 /* DeepgramWebSocketClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 04BBF8FF2F3C97CB00B1FBB2 /* DeepgramWebSocketClient.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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 04BBF89A2F3ACD8800B1FBB2 /* KBKeyboardStressTestVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKeyboardStressTestVC.m; sourceTree = "<group>"; };
@@ -1690,14 +1697,15 @@
path = Manager; path = Manager;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
04A9FE1F2EB893F10020DB6D /* Localization */ = { 04A9FE1F2EB893F10020DB6D /* Localization */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
04A9FE1E2EB893F10020DB6D /* Localizable.strings */, 04A9FE1E2EB893F10020DB6D /* Localizable.strings */,
); E0A100002F60000100ABCDEF /* InfoPlist.strings */,
path = Localization; );
sourceTree = "<group>"; path = Localization;
}; sourceTree = "<group>";
};
04C6EAB92EAF86530089C901 /* keyBoard */ = { 04C6EAB92EAF86530089C901 /* keyBoard */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -2391,9 +2399,10 @@
04C6EAC42EAF87020089C901 /* Resources */ = { 04C6EAC42EAF87020089C901 /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
04A9FE202EB893F10020DB6D /* Localizable.strings in Resources */, 04A9FE202EB893F10020DB6D /* Localizable.strings in Resources */,
041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */, E0A100102F60000100ABCDEF /* InfoPlist.strings in Resources */,
041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */,
04E2277F2F516ED3001A8F14 /* PrivacyInfo.xcprivacy in Resources */, 04E2277F2F516ED3001A8F14 /* PrivacyInfo.xcprivacy in Resources */,
A1B2C3ED2F20000000000001 /* kb_words.txt in Resources */, A1B2C3ED2F20000000000001 /* kb_words.txt in Resources */,
A1B2C3F12F20000000000002 /* kb_keyboard_layout_config.json in Resources */, A1B2C3F12F20000000000002 /* kb_keyboard_layout_config.json in Resources */,
@@ -2424,10 +2433,11 @@
043213C62F56F5280065C888 /* 台湾省初始皮肤注音.zip in Resources */, 043213C62F56F5280065C888 /* 台湾省初始皮肤注音.zip in Resources */,
04E038D82F20BFFB002CA5A0 /* websocket-api.md in Resources */, 04E038D82F20BFFB002CA5A0 /* websocket-api.md in Resources */,
0479200B2ED87CEE004E8522 /* permiss_video.mp4 in Resources */, 0479200B2ED87CEE004E8522 /* permiss_video.mp4 in Resources */,
04E2277D2F516EBD001A8F14 /* PrivacyInfo.xcprivacy in Resources */, 04E2277D2F516EBD001A8F14 /* PrivacyInfo.xcprivacy in Resources */,
04C6EABA2EAF86530089C901 /* Assets.xcassets in Resources */, 04C6EABA2EAF86530089C901 /* Assets.xcassets in Resources */,
04A9FE212EB893F10020DB6D /* Localizable.strings in Resources */, 04A9FE212EB893F10020DB6D /* Localizable.strings in Resources */,
047920072ED86ABC004E8522 /* kb_guide_keyboard.gif in Resources */, E0A100112F60000100ABCDEF /* InfoPlist.strings in Resources */,
047920072ED86ABC004E8522 /* kb_guide_keyboard.gif in Resources */,
046086752F191CC700757C95 /* AI技术分析.txt in Resources */, 046086752F191CC700757C95 /* AI技术分析.txt in Resources */,
047920112ED98E7D004E8522 /* permiss_video_2.mp4 in Resources */, 047920112ED98E7D004E8522 /* permiss_video_2.mp4 in Resources */,
04C6EABC2EAF86530089C901 /* LaunchScreen.storyboard in Resources */, 04C6EABC2EAF86530089C901 /* LaunchScreen.storyboard in Resources */,
@@ -2827,19 +2837,31 @@
/* End PBXTargetDependency section */ /* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */ /* Begin PBXVariantGroup section */
04A9FE1E2EB893F10020DB6D /* Localizable.strings */ = { 04A9FE1E2EB893F10020DB6D /* Localizable.strings */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
children = ( children = (
04A9FE1C2EB893F10020DB6D /* en */, 04A9FE1C2EB893F10020DB6D /* en */,
04837AE12F5848050012BDE2 /* zh-Hant */, 04837AE12F5848050012BDE2 /* zh-Hant */,
04837AE42F58485A0012BDE2 /* es */, 04837AE42F58485A0012BDE2 /* es */,
04837AE72F5848680012BDE2 /* id */, 04837AE72F5848680012BDE2 /* id */,
04837AEA2F5848820012BDE2 /* pt-PT */, 04837AEA2F5848820012BDE2 /* pt-PT */,
); );
name = Localizable.strings; name = Localizable.strings;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
04C6EAB12EAF86530089C901 /* LaunchScreen.storyboard */ = { 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; isa = PBXVariantGroup;
children = ( children = (
04C6EAB02EAF86530089C901 /* Base */, 04C6EAB02EAF86530089C901 /* Base */,
@@ -2881,10 +2903,13 @@
"$(inherited)", "$(inherited)",
"KB_KEYCHAIN_ACCESS_GROUP=@\\\"$(AppIdentifierPrefix)com.loveKey.nyx.shared\\\"", "KB_KEYCHAIN_ACCESS_GROUP=@\\\"$(AppIdentifierPrefix)com.loveKey.nyx.shared\\\"",
); );
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = CustomKeyboard/Info.plist; INFOPLIST_FILE = CustomKeyboard/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Key of Love"; INFOPLIST_KEY_CFBundleDisplayName = "Key of Love";
INFOPLIST_KEY_NSHumanReadableCopyright = ""; 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; IPHONEOS_DEPLOYMENT_TARGET = 15;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@@ -2915,10 +2940,13 @@
"$(inherited)", "$(inherited)",
"KB_KEYCHAIN_ACCESS_GROUP=@\\\"$(AppIdentifierPrefix)com.loveKey.nyx.shared\\\"", "KB_KEYCHAIN_ACCESS_GROUP=@\\\"$(AppIdentifierPrefix)com.loveKey.nyx.shared\\\"",
); );
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = CustomKeyboard/Info.plist; INFOPLIST_FILE = CustomKeyboard/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Key of Love"; INFOPLIST_KEY_CFBundleDisplayName = "Key of Love";
INFOPLIST_KEY_NSHumanReadableCopyright = ""; 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; IPHONEOS_DEPLOYMENT_TARGET = 15;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@@ -2955,9 +2983,9 @@
INFOPLIST_FILE = keyBoard/Info.plist; INFOPLIST_FILE = keyBoard/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Key of Love"; INFOPLIST_KEY_CFBundleDisplayName = "Key of Love";
INFOPLIST_KEY_CFBundleURLTypes = "{\n CFBundleURLName = \"com.loveKey.nyx.keyboard\";\n CFBundleURLSchemes = (\n kbkeyboardAppExtension\n );\n}"; INFOPLIST_KEY_CFBundleURLTypes = "{\n CFBundleURLName = \"com.loveKey.nyx.keyboard\";\n CFBundleURLSchemes = (\n kbkeyboardAppExtension\n );\n}";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "需要使用麦克风进行语音输入"; INFOPLIST_KEY_NSMicrophoneUsageDescription = "Microphone access is required for voice input.";
INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "保存图片需要写入您的相册"; INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Photo library write access is required to save images.";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "更换头像需要访问您的相册"; INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Photo library access is required to change your avatar.";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UIMainStoryboardFile = Main;
@@ -3006,9 +3034,9 @@
INFOPLIST_FILE = keyBoard/Info.plist; INFOPLIST_FILE = keyBoard/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "Key of Love"; INFOPLIST_KEY_CFBundleDisplayName = "Key of Love";
INFOPLIST_KEY_CFBundleURLTypes = "{\n CFBundleURLName = \"com.loveKey.nyx.keyboard\";\n CFBundleURLSchemes = (\n kbkeyboardAppExtension\n );\n}"; INFOPLIST_KEY_CFBundleURLTypes = "{\n CFBundleURLName = \"com.loveKey.nyx.keyboard\";\n CFBundleURLSchemes = (\n kbkeyboardAppExtension\n );\n}";
INFOPLIST_KEY_NSMicrophoneUsageDescription = "需要使用麦克风进行语音输入"; INFOPLIST_KEY_NSMicrophoneUsageDescription = "Microphone access is required for voice input.";
INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "保存图片需要写入您的相册"; INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = "Photo library write access is required to save images.";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "更换头像需要访问您的相册"; INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Photo library access is required to change your avatar.";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main; INFOPLIST_KEY_UIMainStoryboardFile = Main;

View File

@@ -940,7 +940,7 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
case KBChatMessageActionTypeCopy: { case KBChatMessageActionTypeCopy: {
if (message.text.length > 0) { if (message.text.length > 0) {
[UIPasteboard generalPasteboard].string = message.text; [UIPasteboard generalPasteboard].string = message.text;
[KBHUD showSuccess:KBLocalized(@"复制成功")]; [KBHUD showSuccess:KBLocalized(@"Copied")];
} }
} break; } break;
case KBChatMessageActionTypeDelete: { case KBChatMessageActionTypeDelete: {
@@ -973,7 +973,7 @@ static NSString * const KBChatSessionDidResetNotification = @"KBChatSessionDidRe
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[KBHUD dismiss]; [KBHUD dismiss];
if (!success || error) { if (!success || error) {
NSString *msg = error.localizedDescription ?: KBLocalized(@"删除失败,请重试"); NSString *msg = error.localizedDescription ?: KBLocalized(@"Delete failed, please try again");
[KBHUD showError:msg]; [KBHUD showError:msg];
return; return;
} }

View File

@@ -349,7 +349,7 @@
_goChatButton.layer.cornerRadius = 25; _goChatButton.layer.cornerRadius = 25;
} }
[_goChatButton setTitle:KBLocalized(@"Go Chatting") forState:UIControlStateNormal]; [_goChatButton setTitle:KBLocalized(@"Chatting") forState:UIControlStateNormal];
[_goChatButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [_goChatButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
_goChatButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; _goChatButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
[_goChatButton addTarget:self action:@selector(goChatButtonTapped) forControlEvents:UIControlEventTouchUpInside]; [_goChatButton addTarget:self action:@selector(goChatButtonTapped) forControlEvents:UIControlEventTouchUpInside];

View File

@@ -548,7 +548,7 @@
- (UILabel *)contentTitleLabel { - (UILabel *)contentTitleLabel {
if (!_contentTitleLabel) { if (!_contentTitleLabel) {
_contentTitleLabel = [[UILabel alloc] init]; _contentTitleLabel = [[UILabel alloc] init];
_contentTitleLabel.text = KBLocalized(@"selection content"); _contentTitleLabel.text = KBLocalized(@"Selection Content");
_contentTitleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium]; _contentTitleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
_contentTitleLabel.textColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1.0]; _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); NSLog(@"[KBAIHomeVC] 语音转文字失败:%@", error.localizedDescription);
[KBHUD showError:KBLocalized(@"语音转文字失败,请重试")]; [KBHUD showError:KBLocalized(@"Voice-to-text failed, please try again")];
if (cell) { if (cell) {
[cell updateLastUserMessage:KBLocalized(@"语音识别失败")]; [cell updateLastUserMessage:KBLocalized(@"Voice recognition failed")];
} }
strongSelf.isVoiceProcessing = NO; strongSelf.isVoiceProcessing = NO;
[strongSelf updateCollectionViewScrollState]; [strongSelf updateCollectionViewScrollState];
@@ -1284,7 +1284,7 @@ static void KBChatUpdatedDarwinCallback(CFNotificationCenterRef center,
NSString *transcript = response.data.transcript ?: @""; NSString *transcript = response.data.transcript ?: @"";
if (transcript.length == 0) { if (transcript.length == 0) {
NSLog(@"[KBAIHomeVC] 语音转文字结果为空"); NSLog(@"[KBAIHomeVC] 语音转文字结果为空");
[KBHUD showError:KBLocalized(@"未识别到语音内容")]; [KBHUD showError:KBLocalized(@"No speech content recognized")];
if (cell) { if (cell) {
[cell removeLoadingUserMessage]; [cell removeLoadingUserMessage];
} }
@@ -1305,7 +1305,7 @@ static void KBChatUpdatedDarwinCallback(CFNotificationCenterRef center,
- (void)voiceRecordManagerDidRecordTooShort:(KBVoiceRecordManager *)manager { - (void)voiceRecordManagerDidRecordTooShort:(KBVoiceRecordManager *)manager {
NSLog(@"[KBAIHomeVC] 录音过短,已忽略"); NSLog(@"[KBAIHomeVC] 录音过短,已忽略");
[KBHUD showError:KBLocalized(@"录音时间过短,请重新录音")]; [KBHUD showError:KBLocalized(@"Recording too short, please try again")];
} }
- (void)voiceRecordManager:(KBVoiceRecordManager *)manager - (void)voiceRecordManager:(KBVoiceRecordManager *)manager

View File

@@ -8,6 +8,7 @@
#import "KBVoiceToTextManager.h" #import "KBVoiceToTextManager.h"
#import "DeepgramStreamingManager.h" #import "DeepgramStreamingManager.h"
#import "KBVoiceInputBar.h" #import "KBVoiceInputBar.h"
#import "KBLocalizationManager.h"
@interface KBVoiceToTextManager () <KBVoiceInputBarDelegate, @interface KBVoiceToTextManager () <KBVoiceInputBarDelegate,
DeepgramStreamingManagerDelegate> DeepgramStreamingManagerDelegate>
@@ -55,6 +56,7 @@
if (!self.deepgramEnabled) { if (!self.deepgramEnabled) {
return; return;
} }
[self kb_refreshDeepgramLanguage];
[self.deepgramManager prepareConnection]; [self.deepgramManager prepareConnection];
} }
@@ -72,7 +74,7 @@
self.deepgramManager.delegate = self; self.deepgramManager.delegate = self;
self.deepgramManager.serverURL = @"wss://api.deepgram.com/v1/listen"; self.deepgramManager.serverURL = @"wss://api.deepgram.com/v1/listen";
self.deepgramManager.apiKey = @"9c792eb63a65d644cbc95785155754cd1e84f8cf"; self.deepgramManager.apiKey = @"9c792eb63a65d644cbc95785155754cd1e84f8cf";
self.deepgramManager.language = @"en"; [self kb_refreshDeepgramLanguage];
self.deepgramManager.model = @"nova-3"; self.deepgramManager.model = @"nova-3";
self.deepgramManager.punctuate = YES; self.deepgramManager.punctuate = YES;
self.deepgramManager.smartFormat = YES; self.deepgramManager.smartFormat = YES;
@@ -86,15 +88,35 @@
[self.fullText setString:@""]; [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 #pragma mark - KBVoiceInputBarDelegate
- (void)voiceInputBarDidBeginRecording:(KBVoiceInputBar *)inputBar { - (void)voiceInputBarDidBeginRecording:(KBVoiceInputBar *)inputBar {
[self resetTranscript]; [self resetTranscript];
if (self.deepgramEnabled) { if (self.deepgramEnabled) {
inputBar.statusText = @"正在连接..."; [self kb_refreshDeepgramLanguage];
inputBar.statusText = KBLocalized(@"Voice Connecting...");
[self.deepgramManager start]; [self.deepgramManager start];
} else { } else {
inputBar.statusText = @"正在录音..."; inputBar.statusText = KBLocalized(@"Voice Recording...");
} }
if ([self.delegate respondsToSelector:@selector if ([self.delegate respondsToSelector:@selector
@@ -105,10 +127,10 @@
- (void)voiceInputBarDidEndRecording:(KBVoiceInputBar *)inputBar { - (void)voiceInputBarDidEndRecording:(KBVoiceInputBar *)inputBar {
if (self.deepgramEnabled) { if (self.deepgramEnabled) {
inputBar.statusText = @"正在识别..."; inputBar.statusText = KBLocalized(@"Voice Recognizing...");
[self.deepgramManager stopAndFinalize]; [self.deepgramManager stopAndFinalize];
} else { } else {
inputBar.statusText = @"录音结束"; inputBar.statusText = KBLocalized(@"Voice Recording Ended");
} }
if ([self.delegate respondsToSelector:@selector if ([self.delegate respondsToSelector:@selector
@@ -118,7 +140,7 @@
} }
- (void)voiceInputBarDidCancelRecording:(KBVoiceInputBar *)inputBar { - (void)voiceInputBarDidCancelRecording:(KBVoiceInputBar *)inputBar {
inputBar.statusText = @"已取消"; inputBar.statusText = KBLocalized(@"Voice Cancelled");
[self resetTranscript]; [self resetTranscript];
if (self.deepgramEnabled) { if (self.deepgramEnabled) {
[self.deepgramManager cancel]; [self.deepgramManager cancel];
@@ -136,7 +158,7 @@
if (!self.deepgramEnabled) { if (!self.deepgramEnabled) {
return; return;
} }
self.inputBar.statusText = @"正在聆听..."; self.inputBar.statusText = KBLocalized(@"Voice Listening...");
} }
- (void)deepgramStreamingManagerDidDisconnect:(NSError *_Nullable)error { - (void)deepgramStreamingManagerDidDisconnect:(NSError *_Nullable)error {
@@ -147,7 +169,7 @@
return; return;
} }
self.inputBar.statusText = @"识别失败"; self.inputBar.statusText = KBLocalized(@"Voice Recognition Failed");
if ([self.delegate respondsToSelector:@selector if ([self.delegate respondsToSelector:@selector
(voiceToTextManager:didFailWithError:)]) { (voiceToTextManager:didFailWithError:)]) {
[self.delegate voiceToTextManager:self didFailWithError:error]; [self.delegate voiceToTextManager:self didFailWithError:error];
@@ -174,7 +196,7 @@
} }
self.inputBar.statusText = self.inputBar.statusText =
displayText.length > 0 ? displayText : @"正在识别..."; displayText.length > 0 ? displayText : KBLocalized(@"Voice Recognizing...");
if ([self.delegate respondsToSelector:@selector if ([self.delegate respondsToSelector:@selector
(voiceToTextManager:didUpdateInterimText:)]) { (voiceToTextManager:didUpdateInterimText:)]) {
@@ -195,7 +217,7 @@
NSString *finalText = [self.fullText copy]; NSString *finalText = [self.fullText copy];
self.inputBar.statusText = self.inputBar.statusText =
finalText.length > 0 ? finalText : @"识别完成"; finalText.length > 0 ? finalText : KBLocalized(@"Voice Recognition Completed");
if (finalText.length > 0 && if (finalText.length > 0 &&
[self.delegate respondsToSelector:@selector [self.delegate respondsToSelector:@selector
@@ -208,7 +230,7 @@
if (!self.deepgramEnabled) { if (!self.deepgramEnabled) {
return; return;
} }
self.inputBar.statusText = @"识别失败"; self.inputBar.statusText = KBLocalized(@"Voice Recognition Failed");
if ([self.delegate respondsToSelector:@selector if ([self.delegate respondsToSelector:@selector
(voiceToTextManager:didFailWithError:)]) { (voiceToTextManager:didFailWithError:)]) {
[self.delegate voiceToTextManager:self didFailWithError:error]; [self.delegate voiceToTextManager:self didFailWithError:error];

View File

@@ -102,15 +102,13 @@
} }
- (void)applyDefaultTexts { - (void)applyDefaultTexts {
self.titleText = KBLocalized(@""); self.titleText = @"";
self.versionText = @"V1.1.4"; self.versionText = @"V1.1.4";
self.contentTitleText = KBLocalized(@"Ver. Update Content"); self.contentTitleText = KBLocalized(@"Update content");
self.contentItems = @[ self.contentItems = @[
KBLocalized(@"AAAAAAAAAAAAAAAAAAA"), ];
KBLocalized(@"SSSSSSSSSSSSSSSSSSS") self.upgradeButtonTitle = KBLocalized(@"Upgrade now");
]; self.cancelButtonTitle = KBLocalized(@"Cancel");
self.upgradeButtonTitle = KBLocalized(@"立即升级");
self.cancelButtonTitle = KBLocalized(@"取消");
self.showsCancelButton = NO; self.showsCancelButton = NO;
} }
@@ -179,10 +177,10 @@
if (!updateInfo) { return; } if (!updateInfo) { return; }
self.showsCancelButton = !updateInfo.forceUpdate; self.showsCancelButton = !updateInfo.forceUpdate;
if (!updateInfo.forceUpdate) { if (!updateInfo.forceUpdate) {
self.cancelButtonTitle = KBLocalized(@"取消"); self.cancelButtonTitle = KBLocalized(@"Cancel");
} }
self.upgradeButtonTitle = KBLocalized(@"更新"); self.upgradeButtonTitle = KBLocalized(@"Update");
self.contentTitleText = KBLocalized(@"更新内容"); self.contentTitleText = KBLocalized(@"Update content");
NSString *versionName = updateInfo.latestVersionName ?: @""; NSString *versionName = updateInfo.latestVersionName ?: @"";
if (versionName.length > 0 && ![versionName hasPrefix:@"V"] && ![versionName hasPrefix:@"v"]) { if (versionName.length > 0 && ![versionName hasPrefix:@"V"] && ![versionName hasPrefix:@"v"]) {
versionName = [NSString stringWithFormat:@"V%@", versionName]; versionName = [NSString stringWithFormat:@"V%@", versionName];

View File

@@ -284,7 +284,7 @@ typedef NS_ENUM(NSInteger, KBSexOption) {
- (UILabel *)titleLabel { - (UILabel *)titleLabel {
if (!_titleLabel) { if (!_titleLabel) {
_titleLabel = [UILabel new]; _titleLabel = [UILabel new];
_titleLabel.text = @"Please Select Your Gender"; _titleLabel.text = KBLocalized(@"Please Select Your Gender");
_titleLabel.font = [KBFont medium:20]; _titleLabel.font = [KBFont medium:20];
_titleLabel.textColor = [UIColor colorWithHex:KBBlackValue]; _titleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
_titleLabel.numberOfLines = 1; _titleLabel.numberOfLines = 1;
@@ -305,7 +305,7 @@ typedef NS_ENUM(NSInteger, KBSexOption) {
- (UIButton *)skipButton { - (UIButton *)skipButton {
if (!_skipButton) { if (!_skipButton) {
_skipButton = [UIButton buttonWithType:UIButtonTypeCustom]; _skipButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_skipButton setTitle:@"Skip" forState:UIControlStateNormal]; [_skipButton setTitle:KBLocalized(@"Skip") forState:UIControlStateNormal];
[_skipButton setTitleColor:[UIColor colorWithHex:KBBlackValue] forState:UIControlStateNormal]; [_skipButton setTitleColor:[UIColor colorWithHex:KBBlackValue] forState:UIControlStateNormal];
_skipButton.titleLabel.font = [KBFont medium:12]; _skipButton.titleLabel.font = [KBFont medium:12];
_skipButton.backgroundColor = [UIColor colorWithHex:0xE9F7F4]; _skipButton.backgroundColor = [UIColor colorWithHex:0xE9F7F4];
@@ -341,7 +341,7 @@ typedef NS_ENUM(NSInteger, KBSexOption) {
- (UILabel *)maleLabel { - (UILabel *)maleLabel {
if (!_maleLabel) { if (!_maleLabel) {
_maleLabel = [UILabel new]; _maleLabel = [UILabel new];
_maleLabel.text = @"Male"; _maleLabel.text = KBLocalized(@"Male");
_maleLabel.font = [KBFont medium:20]; _maleLabel.font = [KBFont medium:20];
_maleLabel.textColor = [UIColor colorWithHex:KBBlackValue]; _maleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
} }
@@ -369,7 +369,7 @@ typedef NS_ENUM(NSInteger, KBSexOption) {
- (UILabel *)femaleLabel { - (UILabel *)femaleLabel {
if (!_femaleLabel) { if (!_femaleLabel) {
_femaleLabel = [UILabel new]; _femaleLabel = [UILabel new];
_femaleLabel.text = @"Female"; _femaleLabel.text = KBLocalized(@"Female");
_femaleLabel.font = [KBFont medium:20]; _femaleLabel.font = [KBFont medium:20];
_femaleLabel.textColor = [UIColor colorWithHex:KBBlackValue]; _femaleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
} }
@@ -405,7 +405,7 @@ typedef NS_ENUM(NSInteger, KBSexOption) {
- (UILabel *)otherLabel { - (UILabel *)otherLabel {
if (!_otherLabel) { if (!_otherLabel) {
_otherLabel = [UILabel new]; _otherLabel = [UILabel new];
_otherLabel.text = @"The Third Gender"; _otherLabel.text = KBLocalized(@"The Third Gender");
_otherLabel.font = [KBFont medium:20]; _otherLabel.font = [KBFont medium:20];
_otherLabel.textColor = [UIColor colorWithHex:KBBlackValue]; _otherLabel.textColor = [UIColor colorWithHex:KBBlackValue];
} }
@@ -415,7 +415,7 @@ typedef NS_ENUM(NSInteger, KBSexOption) {
- (UIButton *)confirmButton { - (UIButton *)confirmButton {
if (!_confirmButton) { if (!_confirmButton) {
_confirmButton = [UIButton buttonWithType:UIButtonTypeCustom]; _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 setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
_confirmButton.titleLabel.font = [KBFont bold:16]; _confirmButton.titleLabel.font = [KBFont bold:16];
_confirmButton.backgroundColor = [UIColor blackColor]; _confirmButton.backgroundColor = [UIColor blackColor];

View File

@@ -133,13 +133,13 @@
- (void)defaultData { - (void)defaultData {
// 使便 // 使便
self.titleLabel.text = @"Become A Member Of Love Key"; self.titleLabel.text = KBLocalized(@"Become A Member Of Love Key");
self.subTitleLabel.text = @"Unlock All Functions"; self.subTitleLabel.text = KBLocalized(@"Unlock All Functions");
NSArray *titles = @[@"Wireless Sub-ai Dialogue", NSArray *titles = @[KBLocalized(@"Wireless Sub-ai Dialogue"),
@"Personalized\nKeyboard", KBLocalized(@"Personalized\nKeyboard"),
@"Chat\nPersona", KBLocalized(@"Chat\nPersona"),
@"Emotional\nCounseling"]; KBLocalized(@"Emotional\nCounseling")];
NSArray *images = @[[UIImage imageNamed:@"home_ai_icon"], NSArray *images = @[[UIImage imageNamed:@"home_ai_icon"],
[UIImage imageNamed:@"home_keyboard_icon"], [UIImage imageNamed:@"home_keyboard_icon"],
[UIImage imageNamed:@"home_chat_icon"], [UIImage imageNamed:@"home_chat_icon"],

View File

@@ -45,12 +45,12 @@
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
// self.title = KBLocalized(@"皮肤中心"); // self.title = KBLocalized(@"Skin Center");
self.view.backgroundColor = [UIColor whiteColor]; self.view.backgroundColor = [UIColor whiteColor];
self.skins = @[ self.skins = @[
@{ @{
@"id": @"local本地", @"id": @"local本地",
@"name": KBLocalized(@"粉色皮肤"), @"name": KBLocalized(@"Pink skin"),
// zip_url bundle:// + // zip_url bundle:// +
@"zip_url": @"bundle://fense.zip", @"zip_url": @"bundle://fense.zip",
@@ -64,7 +64,7 @@
}, },
@{ @{
@"id": @"remote002", @"id": @"remote002",
@"name": KBLocalized(@"远程皮肤"), @"name": KBLocalized(@"Remote skin"),
// zip_url bundle:// + // zip_url bundle:// +
@"zip_url": @"http://gx.zhukeping.com/download/Christmas.zip", @"zip_url": @"http://gx.zhukeping.com/download/Christmas.zip",
@@ -85,7 +85,7 @@
// //
UIButton *reset = [UIButton buttonWithType:UIButtonTypeSystem]; 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.titleLabel.font = [UIFont systemFontOfSize:15 weight:UIFontWeightMedium];
reset.layer.cornerRadius = 8.0; reset.layer.cornerRadius = 8.0;
reset.layer.borderWidth = 1.0; reset.layer.borderWidth = 1.0;
@@ -138,14 +138,13 @@
NSDictionary *skin = self.skins[idx]; NSDictionary *skin = self.skins[idx];
if (!skin) return; if (!skin) return;
if (idx == 0) { if (idx == 0) {
// NSString *title = (indexPath.item < self.dataSource.count) ? self.dataSource[indexPath.item] : KBLocalized(@"专属皮肤002");
// 002.zip id便 // 002.zip id便
static NSString * const kKBBundleSkinId002 = @"bundle_skin_fense"; static NSString * const kKBBundleSkinId002 = @"bundle_skin_fense";
[KBSkinInstallBridge publishBundleSkinRequestWithId:kKBBundleSkinId002 [KBSkinInstallBridge publishBundleSkinRequestWithId:kKBBundleSkinId002
name:@"" ?: kKBBundleSkinId002 name:@"" ?: kKBBundleSkinId002
zipName:@"fense.zip" zipName:@"fense.zip"
iconShortNames:nil]; 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){ }else if (idx == 1){
[[KBSkinService shared] applySkinWithJSON:skin [[KBSkinService shared] applySkinWithJSON:skin
fromViewController:self fromViewController:self
@@ -161,7 +160,7 @@
name:@"" ?: kKBBundleSkinId002 name:@"" ?: kKBBundleSkinId002
zipName:@"Christmas.zip" zipName:@"Christmas.zip"
iconShortNames:nil]; 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.tableView.tableHeaderView = header;
[self.view addSubview:self.tableView]; [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]; }); dispatch_async(dispatch_get_main_queue(), ^{ [self.textView becomeFirstResponder]; });
@@ -52,7 +52,7 @@
- (void)viewWillAppear:(BOOL)animated{ - (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated]; [super viewWillAppear:animated];
self.title = KBLocalized(@"Test"); 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]; [self.tableView reloadData];
} }

View File

@@ -71,7 +71,7 @@
}]; }];
} else { } else {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem]; 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.enabled = NO;
btn.layer.cornerRadius = 8.0; btn.layer.cornerRadius = 8.0;
btn.layer.borderWidth = 1.0; btn.layer.borderWidth = 1.0;

View File

@@ -304,8 +304,10 @@
NSUInteger charIndex = [layoutManager characterIndexForGlyphAtIndex:glyphIndex]; NSUInteger charIndex = [layoutManager characterIndexForGlyphAtIndex:glyphIndex];
NSString *lowerFull = textView.text.lowercaseString ?: @""; NSString *lowerFull = textView.text.lowercaseString ?: @"";
NSRange termsRange = [lowerFull rangeOfString:@"terms of service"]; NSString *termsText = [KBLocalized(@"terms of service") lowercaseString];
NSRange privacyRange = [lowerFull rangeOfString:@"privacy policy"]; 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 hitTerms = (termsRange.location != NSNotFound && NSLocationInRange(charIndex, termsRange));
BOOL hitPrivacy = (privacyRange.location != NSNotFound && NSLocationInRange(charIndex, privacyRange)); BOOL hitPrivacy = (privacyRange.location != NSNotFound && NSLocationInRange(charIndex, privacyRange));
@@ -513,9 +515,9 @@
_agreementTextView.textContainerInset = UIEdgeInsetsZero; _agreementTextView.textContainerInset = UIEdgeInsetsZero;
_agreementTextView.textContainer.lineFragmentPadding = 0; _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 *fullText = KBLocalized(@"By continuing, you agree to our terms of service and confirm that you have read our privacy policy");
NSString *termsText = @"terms of service"; NSString *termsText = KBLocalized(@"terms of service");
NSString *privacyText = @"privacy policy"; NSString *privacyText = KBLocalized(@"privacy policy");
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.alignment = NSTextAlignmentCenter; paragraph.alignment = NSTextAlignmentCenter;

View File

@@ -386,19 +386,17 @@
NSUInteger charIndex = [layoutManager characterIndexForGlyphAtIndex:glyphIndex]; NSUInteger charIndex = [layoutManager characterIndexForGlyphAtIndex:glyphIndex];
NSString *lowerFull = textView.text.lowercaseString ?: @""; NSString *lowerFull = textView.text.lowercaseString ?: @"";
NSRange termsRange = [lowerFull rangeOfString:@"terms of service"]; NSString *termsText = [KBLocalized(@"terms of service") lowercaseString];
NSRange privacyRange = [lowerFull rangeOfString:@"privacy policy"]; 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 hitTerms = (termsRange.location != NSNotFound && NSLocationInRange(charIndex, termsRange));
BOOL hitPrivacy = (privacyRange.location != NSNotFound && NSLocationInRange(charIndex, privacyRange)); BOOL hitPrivacy = (privacyRange.location != NSNotFound && NSLocationInRange(charIndex, privacyRange));
if (hitTerms || hitPrivacy) { if (hitTerms || hitPrivacy) {
KBLOG(@"tap policy in KBEmailRegistVC"); KBLOG(@"tap policy in KBEmailRegistVC");
// //
if (hitTerms == true) { [KBHUD showInfo:KBLocalized(@"Open agreement")];
[KBHUD showInfo:@"hitTerms"];
}else{
[KBHUD showInfo:@"hitPrivacy"];
}
} }
} }
@@ -723,9 +721,9 @@
_agreementTextView.textContainerInset = UIEdgeInsetsZero; _agreementTextView.textContainerInset = UIEdgeInsetsZero;
_agreementTextView.textContainer.lineFragmentPadding = 0; _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 *fullText = KBLocalized(@"By continuing, you agree to our terms of service and confirm that you have read our privacy policy");
NSString *termsText = @"terms of service"; NSString *termsText = KBLocalized(@"terms of service");
NSString *privacyText = @"privacy policy"; NSString *privacyText = KBLocalized(@"privacy policy");
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.alignment = NSTextAlignmentCenter; paragraph.alignment = NSTextAlignmentCenter;

View File

@@ -372,9 +372,9 @@
_agreementTextView.textContainer.lineFragmentPadding = 0; _agreementTextView.textContainer.lineFragmentPadding = 0;
// terms of service / privacy policy #717171 // 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 *fullText = KBLocalized(@"By continuing, you agree to our terms of service and confirm that you have read our privacy policy");
NSString *termsText = @"terms of service"; NSString *termsText = KBLocalized(@"terms of service");
NSString *privacyText = @"privacy policy"; NSString *privacyText = KBLocalized(@"privacy policy");
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.alignment = NSTextAlignmentCenter; // paragraph.alignment = NSTextAlignmentCenter; //
@@ -488,8 +488,10 @@
NSUInteger charIndex = [layoutManager characterIndexForGlyphAtIndex:glyphIndex]; NSUInteger charIndex = [layoutManager characterIndexForGlyphAtIndex:glyphIndex];
NSString *lowerFull = textView.text.lowercaseString ?: @""; NSString *lowerFull = textView.text.lowercaseString ?: @"";
NSRange termsRange = [lowerFull rangeOfString:@"terms of service"]; NSString *termsText = [KBLocalized(@"terms of service") lowercaseString];
NSRange privacyRange = [lowerFull rangeOfString:@"privacy policy"]; 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 hitTerms = (termsRange.location != NSNotFound && NSLocationInRange(charIndex, termsRange));
BOOL hitPrivacy = (privacyRange.location != NSNotFound && NSLocationInRange(charIndex, privacyRange)); BOOL hitPrivacy = (privacyRange.location != NSNotFound && NSLocationInRange(charIndex, privacyRange));

View File

@@ -107,7 +107,7 @@
- (UIButton *)compatHintButton { - (UIButton *)compatHintButton {
if (!_compatHintButton) { if (!_compatHintButton) {
_compatHintButton = [UIButton buttonWithType:UIButtonTypeSystem]; _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; _compatHintButton.enabled = NO;
} }
return _compatHintButton; return _compatHintButton;

View File

@@ -34,7 +34,7 @@
if (mode == KBSkinSourceModeResetToDefault) { if (mode == KBSkinSourceModeResetToDefault) {
[[KBSkinManager shared] resetToDefault]; [[KBSkinManager shared] resetToDefault];
if (completion) completion(YES); if (completion) completion(YES);
[KBHUD showInfo:KBLocalized(@"已恢复默认键盘皮肤")]; [KBHUD showInfo:KBLocalized(@"Default keyboard skin restored")];
return; return;
} }
@@ -70,7 +70,6 @@
// [perm presentPermissionIfNeededFrom:presenting]; // [perm presentPermissionIfNeededFrom:presenting];
// //
// // 访 App Group // // 访 App Group
// [KBHUD showInfo:KBLocalized(@"皮肤已应用,键盘需开启“允许完全访问”后才能显示图片")];
// } // }
switch (mode) { switch (mode) {
@@ -106,9 +105,9 @@
message = KBLocalized(@"Applied. Switch to the keyboard to view."); message = KBLocalized(@"Applied. Switch to the keyboard to view.");
} else if ([error.domain isEqualToString:KBSkinBridgeErrorDomain] && } else if ([error.domain isEqualToString:KBSkinBridgeErrorDomain] &&
error.code == KBSkinBridgeErrorContainerUnavailable) { error.code == KBSkinBridgeErrorContainerUnavailable) {
message = KBLocalized(@"无法访问共享容器,应用皮肤失败"); message = KBLocalized(@"Unable to access shared container, failed to apply skin");
} else { } else {
message = KBLocalized(@"应用皮肤失败"); message = KBLocalized(@"Failed to apply skin");
} }
[KBHUD showInfo:message]; [KBHUD showInfo:message];
}]; }];
@@ -132,7 +131,7 @@
NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:AppGroup]; NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:AppGroup];
if (!containerURL) { if (!containerURL) {
if (completion) completion(NO); if (completion) completion(NO);
[KBHUD showInfo:KBLocalized(@"无法访问共享容器,应用皮肤失败")]; [KBHUD showInfo:KBLocalized(@"Unable to access shared container, failed to apply skin")];
return; return;
} }

View File

@@ -21,7 +21,7 @@
} }
- (void)config:(NSString *)title { - (void)config:(NSString *)title {
self.titleLabel.text = title ?: @"Recommended Skin"; self.titleLabel.text = title ?: KBLocalized(@"Recommended Skin");
} }
- (UILabel *)titleLabel { - (UILabel *)titleLabel {
@@ -29,7 +29,7 @@
_titleLabel = [UILabel new]; _titleLabel = [UILabel new];
_titleLabel.textColor = [UIColor colorWithHex:0x1B1F1A]; _titleLabel.textColor = [UIColor colorWithHex:0x1B1F1A];
_titleLabel.font = [KBFont medium:14]; _titleLabel.font = [KBFont medium:14];
_titleLabel.text = @"Recommended Skin"; _titleLabel.text = KBLocalized(@"Recommended Skin");
} }
return _titleLabel; return _titleLabel;
} }

View File

@@ -68,7 +68,7 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
[self.collectionView kb_makeDefaultEmptyViewWithImage:nil [self.collectionView kb_makeDefaultEmptyViewWithImage:nil
title:KBLocalized(@"No data") title:KBLocalized(@"No data")
detail:KBLocalized(@"Pull down to refresh") detail:KBLocalized(@"Pull down to refresh")
buttonTitle:KBLocalized(@"") buttonTitle:@""
tapHandler:nil tapHandler:nil
buttonHandler:^{ [weakSelf.collectionView.mj_header beginRefreshing]; }]; buttonHandler:^{ [weakSelf.collectionView.mj_header beginRefreshing]; }];
[self.collectionView kb_setLYAutoShowEnabled:NO]; // [self.collectionView kb_setLYAutoShowEnabled:NO]; //

View File

@@ -74,7 +74,7 @@
} }
- (void)configTitle:(NSString *)title price:(NSString *)price strike:(nullable NSString *)strike { - (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.priceLabel.text = price.length ? price : @"$4.49";
self.strikeLabel.hidden = (strike.length == 0); self.strikeLabel.hidden = (strike.length == 0);
if (strike.length) { if (strike.length) {
@@ -115,7 +115,7 @@
- (UILabel *)titleLabel { - (UILabel *)titleLabel {
if (!_titleLabel) { if (!_titleLabel) {
_titleLabel = [UILabel new]; _titleLabel = [UILabel new];
_titleLabel.text = @"Monthly Subscription"; _titleLabel.text = KBLocalized(@"Monthly Subscription");
_titleLabel.textColor = [UIColor colorWithHex:KBBlackValue]; _titleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
_titleLabel.font = [KBFont medium:13]; _titleLabel.font = [KBFont medium:13];
} }

View File

@@ -466,7 +466,7 @@ static NSString * const kKBJfPayCellId = @"kKBJfPayCellId";
- (UIButton *)agreementButton { - (UIButton *)agreementButton {
if (!_agreementButton) { if (!_agreementButton) {
_agreementButton = [UIButton buttonWithType:UIButtonTypeCustom]; _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 setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal];
// _agreementButton.titleLabel.font = [UIFont systemFontOfSize:10 weight:UIFontWeightSemibold]; // _agreementButton.titleLabel.font = [UIFont systemFontOfSize:10 weight:UIFontWeightSemibold];
_agreementButton.titleLabel.font = [KBFont regular:12]; _agreementButton.titleLabel.font = [KBFont regular:12];

View File

@@ -425,7 +425,7 @@ static const CGFloat JXheightForHeaderInSection = 39;
- (UILabel *)agreementLabel { - (UILabel *)agreementLabel {
if (!_agreementLabel) { if (!_agreementLabel) {
_agreementLabel = [UILabel new]; _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.font = [KBFont regular:12];
_agreementLabel.textColor = [UIColor colorWithHex:KBBlackValue]; _agreementLabel.textColor = [UIColor colorWithHex:KBBlackValue];
} }
@@ -435,7 +435,7 @@ static const CGFloat JXheightForHeaderInSection = 39;
- (UIButton *)agreementButton { - (UIButton *)agreementButton {
if (!_agreementButton) { if (!_agreementButton) {
_agreementButton = [UIButton buttonWithType:UIButtonTypeCustom]; _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 setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal];
_agreementButton.titleLabel.font = [KBFont regular:12]; _agreementButton.titleLabel.font = [KBFont regular:12];
[_agreementButton addTarget:self action:@selector(onTapAgreementButton) forControlEvents:UIControlEventTouchUpInside]; [_agreementButton addTarget:self action:@selector(onTapAgreementButton) forControlEvents:UIControlEventTouchUpInside];

View File

@@ -69,9 +69,9 @@ static NSString * const kKBSvipBenefitHeaderId = @"kKBSvipBenefitHeaderId";
// 使 // 使
self.benefits = @[ self.benefits = @[
@{@"icon": @"pay_ais_icon", @"title": KBLocalized(@"Wireless Sub-ai Dialogue")}, @{@"icon": @"pay_ais_icon", @"title": KBLocalized(@"Wireless Sub-ai Dialogue")},
@{@"icon": @"pay_keyboards_icon", @"title": KBLocalized(@"Personalized Keyboard")}, @{@"icon": @"pay_keyboards_icon", @"title": KBLocalized(@"Personalized\nKeyboard")},
@{@"icon": @"pay_person_icon", @"title": KBLocalized(@"Chat Persona")}, @{@"icon": @"pay_person_icon", @"title": KBLocalized(@"Chat\nPersona")},
@{@"icon": @"pay_phone_icon", @"title": KBLocalized(@"Emotional Counseling")}, @{@"icon": @"pay_phone_icon", @"title": KBLocalized(@"Emotional\nCounseling")},
@{@"icon": @"pay_history_icon", @"title": KBLocalized(@"Longer Chat History")}, @{@"icon": @"pay_history_icon", @"title": KBLocalized(@"Longer Chat History")},
@{@"icon": @"pay_chats_icon", @"title": KBLocalized(@"Unlimited Chatting")}, @{@"icon": @"pay_chats_icon", @"title": KBLocalized(@"Unlimited Chatting")},
@{@"icon": @"pay_speed_icon", @"title": KBLocalized(@"Chat Without Speed Limits")}, @{@"icon": @"pay_speed_icon", @"title": KBLocalized(@"Chat Without Speed Limits")},

View File

@@ -186,16 +186,6 @@
KBSkinDetailVC *vc = [[KBSkinDetailVC alloc] init]; KBSkinDetailVC *vc = [[KBSkinDetailVC alloc] init];
vc.themeId = selTheme.themeId; vc.themeId = selTheme.themeId;
[self.navigationController pushViewController:vc animated:true]; [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 { - (void)setStyle:(KBShopStyleModel *)style {

View File

@@ -105,7 +105,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) {
} }
case KBSkinDetailSectionTitle: { case KBSkinDetailSectionTitle: {
KBSkinSectionTitleCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kSectionTitleCellId forIndexPath:indexPath]; KBSkinSectionTitleCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kSectionTitleCellId forIndexPath:indexPath];
[cell config:@"Recommended Skin"]; [cell config:KBLocalized(@"Recommended Skin")];
return cell; return cell;
} }
case KBSkinDetailSectionGrid: { case KBSkinDetailSectionGrid: {
@@ -248,11 +248,11 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) {
- (void)handleDownloadAction { - (void)handleDownloadAction {
// if (self.isProcessingAction) { return; } // if (self.isProcessingAction) { return; }
if (self.themeId.length == 0) { if (self.themeId.length == 0) {
[KBHUD showInfo:KBLocalized(@"主题信息缺失")]; [KBHUD showInfo:KBLocalized(@"Theme information missing")];
return; return;
} }
if (!self.detailModel) { if (!self.detailModel) {
[KBHUD showInfo:KBLocalized(@"正在加载主题详情")]; [KBHUD showInfo:KBLocalized(@"Loading theme details")];
return; return;
} }
@@ -283,7 +283,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) {
// weakSelf.isProcessingAction = NO; // weakSelf.isProcessingAction = NO;
[KBHUD dismiss]; [KBHUD dismiss];
if (error || !success) { if (error || !success) {
NSString *msg = error.localizedDescription ?: KBLocalized(@"购买失败"); NSString *msg = error.localizedDescription ?: KBLocalized(@"Purchase failed");
[KBHUD showInfo:msg]; [KBHUD showInfo:msg];
return; return;
} }
@@ -310,7 +310,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) {
NSString *zipURL = [skin[@"zip_url"] isKindOfClass:NSString.class] ? skin[@"zip_url"] : @""; NSString *zipURL = [skin[@"zip_url"] isKindOfClass:NSString.class] ? skin[@"zip_url"] : @"";
if (skin.count == 0 || zipURL.length == 0) { if (skin.count == 0 || zipURL.length == 0) {
[KBHUD dismiss]; [KBHUD dismiss];
[KBHUD showInfo:KBLocalized(@"下载信息缺失")]; [KBHUD showInfo:KBLocalized(@"Download information missing")];
return; return;
} }
NSLog(@"⬇️[SkinDetail] download request id=%@ zip=%@ force=YES", NSLog(@"⬇️[SkinDetail] download request id=%@ zip=%@ force=YES",
@@ -329,7 +329,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) {
[strongSelf.shopVM restoreThemeWithId:themeId completion:nil]; [strongSelf.shopVM restoreThemeWithId:themeId completion:nil];
} }
} else { } else {
[KBHUD showInfo:KBLocalized(@"下载失败")]; [KBHUD showInfo:KBLocalized(@"Download failed")];
} }
}]; }];
}); });

View File

@@ -311,7 +311,7 @@ static void *KBPermPlayerPresentationSizeContext = &KBPermPlayerPresentationSize
- (UILabel *)titleLabel { - (UILabel *)titleLabel {
if (!_titleLabel) { if (!_titleLabel) {
_titleLabel = [UILabel new]; _titleLabel = [UILabel new];
_titleLabel.text = (@"key of love keyboard"); _titleLabel.text = KBLocalized(@"key of love keyboard");
_titleLabel.font = [UIFont systemFontOfSize:20 weight:UIFontWeightSemibold]; _titleLabel.font = [UIFont systemFontOfSize:20 weight:UIFontWeightSemibold];
_titleLabel.textColor = [UIColor blackColor]; _titleLabel.textColor = [UIColor blackColor];
_titleLabel.textAlignment = NSTextAlignmentCenter; _titleLabel.textAlignment = NSTextAlignmentCenter;
@@ -322,7 +322,7 @@ static void *KBPermPlayerPresentationSizeContext = &KBPermPlayerPresentationSize
- (UILabel *)tipsLabel { - (UILabel *)tipsLabel {
if (!_tipsLabel) { if (!_tipsLabel) {
_tipsLabel = [UILabel new]; _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.font = [UIFont systemFontOfSize:14];
_tipsLabel.textColor = [UIColor darkGrayColor]; _tipsLabel.textColor = [UIColor darkGrayColor];
_tipsLabel.textAlignment = NSTextAlignmentCenter; _tipsLabel.textAlignment = NSTextAlignmentCenter;
@@ -333,7 +333,7 @@ static void *KBPermPlayerPresentationSizeContext = &KBPermPlayerPresentationSize
- (UIButton *)openButton { - (UIButton *)openButton {
if (!_openButton) { if (!_openButton) {
_openButton = [UIButton buttonWithType:UIButtonTypeCustom]; _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.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
[_openButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [_openButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
_openButton.backgroundColor = [UIColor colorWithHex:KBBlackValue]; _openButton.backgroundColor = [UIColor colorWithHex:KBBlackValue];