key缺少,添加权限多语言

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

View File

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

View File

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

View File

@@ -54,7 +54,7 @@
}
#endif
if (mode == KBKeyboardPanelModeFunction && !islogin) {
[KBHUD showInfo:KBLocalized(@"请先登录后使用AI功能")];
[KBHUD showInfo:KBLocalized(@"Please sign in before using AI features")];
NSURL *ul = [NSURL URLWithString:[NSString stringWithFormat:@"%@?src=keyboard", KB_UL_LOGIN]];
NSURL *scheme =
[NSURL URLWithString:[NSString stringWithFormat:@"%@://login?src=keyboard", KB_APP_SCHEME]];
@@ -68,7 +68,7 @@
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
[KBHUD showInfo:KBLocalized(@"请回到桌面手动打开App登录")];
[KBHUD showInfo:KBLocalized(@"Please return to the Home screen and open the app to sign in")];
});
}];
return;

View File

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

View File

@@ -7,6 +7,7 @@
#import "NetworkStreamHandler.h"
#import <Security/Security.h>
#import "KBLocalizationManager.h"
@interface NetworkStreamHandler ()
@@ -101,7 +102,11 @@
//
[request setValue:@"text/html, application/xhtml+xml, application/xml; q=0.9, image/avif, image/webp, image/apng, */*; q=0.8, application/signed-exchange; v=b3; q=0.7" forHTTPHeaderField:@"Accept"];
[request setValue:@"gzip, deflate" forHTTPHeaderField:@"Accept-Encoding"];
[request setValue:@"zh-CN, zh; q=0.9, ko; q=0.8, ja; q=0.7" forHTTPHeaderField:@"Accept-Language"];
NSString *lang = [[KBLocalizationManager shared] currentLanguageHeaderValue];
if (lang.length == 0) {
lang = @"en";
}
[request setValue:lang forHTTPHeaderField:@"Accept-Language"];
[request setValue:@"keep-alive" forHTTPHeaderField:@"Connection"];
[request setValue:@"1" forHTTPHeaderField:@"Upgrade-Insecure-Requests"];

View File

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

View File

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

View File

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

View File

@@ -161,7 +161,7 @@
- (void)onTapGoEnable {
UIInputViewController *ivc = self.ivc ?: KBFindInputViewController(self);
if (!ivc) {
NSString *showInfo = [NSString stringWithFormat:KBLocalized(@"Follow: Settings General Keyboard Keyboards %@ Allow Full Access"), AppName];
NSString *showInfo = [NSString stringWithFormat:KBLocalized(@"Follow: Settings -> General -> Keyboard -> Keyboards -> %@ -> Allow Full Access"), AppName];
[KBHUD showInfo:showInfo];
return;
}
@@ -183,7 +183,7 @@
if (success) {
[self dismiss];
} else {
NSString *showInfo = [NSString stringWithFormat:KBLocalized(@"Follow: Settings General Keyboard Keyboards %@ Allow Full Access"), AppName];
NSString *showInfo = [NSString stringWithFormat:KBLocalized(@"Follow: Settings -> General -> Keyboard -> Keyboards -> %@ -> Allow Full Access"), AppName];
[KBHUD showInfo:showInfo];
}
});

View File

@@ -60,7 +60,6 @@
// if (!_placeholderLabelInternal) {
// _placeholderLabelInternal = [[UILabel alloc] init];
// // 稿
// _placeholderLabelInternal.text = KBLocalized(@"Paste Ta's Words");
// _placeholderLabelInternal.textColor = [UIColor colorWithRed:0.20 green:0.64 blue:0.54 alpha:1.0];
// _placeholderLabelInternal.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
// }

View File

@@ -277,13 +277,8 @@
// self.itemsInternal = @[KBLocalized(@"Warm hearted man"),
// KBLocalized(@"Warm2 hearted man"),
// KBLocalized(@"Warm3 hearted man"),
// KBLocalized(@"撩女生啊u发顺丰大师傅"),
// KBLocalized(@"Warm = man"),
// KBLocalized(@"Warm hearted man"),
// KBLocalized(@"一枚暖男发放"),
// KBLocalized(@"聊天搭子"),
// KBLocalized(@"表达爱意"),
// KBLocalized(@"更多话术")];
// [self.tagListView setItems:self.itemsInternal];
//}
@@ -516,7 +511,7 @@
}
BOOL shouldShowError = (error != nil);
if (shouldShowError) {
[KBHUD showInfo:error.localizedDescription ?: KBLocalized(@"拉取失败")];
[KBHUD showInfo:error.localizedDescription ?: KBLocalized(@"Fetch failed")];
}
if (self.streamOverlay) {
[self.streamOverlay finish];
@@ -533,7 +528,7 @@
BOOL needSubscriptionGuide = (code == KBBizCodeQuotaExhausted);
NSString *msg = KBBizMessageFromJSONObject(payload);
if (msg.length == 0) {
msg = KBLocalized(@"拉取失败");
msg = KBLocalized(@"Fetch failed");
}
NSError *bizError =
[NSError errorWithDomain:@"KBStreamBizError"
@@ -721,7 +716,7 @@
// 1) 访
if (![[KBFullAccessManager shared] hasFullAccess]) {
// 访
[KBHUD showInfo:KBLocalized(@"处理中…")];
[KBHUD showInfo:KBLocalized(@"Processing...")];
[[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self];
return;
}
@@ -732,7 +727,7 @@
UIInputViewController *ivc = KBFindInputViewController(self);
if (!ivc) {
[KBHUD showInfo:KBLocalized(@"请回到桌面手动打开App登录")];
[KBHUD showInfo:KBLocalized(@"Please return to the Home screen and open the app to sign in")];
return;
}
@@ -749,7 +744,7 @@
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
[KBHUD showInfo:KBLocalized(@"请回到桌面手动打开App登录")];
[KBHUD showInfo:KBLocalized(@"Please return to the Home screen and open the app to sign in")];
});
}];
return;
@@ -781,7 +776,6 @@
// [ivc dismissKeyboard];
// BOOL ok = [KBHostAppLauncher openHostAppURL:scheme
// fromResponder:start]; if (!ok) {
// [KBHUD showInfo:KBLocalized(@"请切换到主App完成登录")];
// }else{
//
// }
@@ -829,7 +823,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer,
return;
}
[KBHUD showInfo:KBLocalized(@"处理中…")];
[KBHUD showInfo:KBLocalized(@"Processing...")];
UIInputViewController *ivc = KBFindInputViewController(self);
if (!ivc)