2
This commit is contained in:
@@ -52,7 +52,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
|
||||
parameters:parameters
|
||||
error:&serror];
|
||||
if (serror || !req) {
|
||||
if (completion) completion(nil, nil, serror ?: [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey: @"无效的URL"}]);
|
||||
if (completion) completion(nil, nil, serror ?: [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid URL")}]);
|
||||
return nil;
|
||||
}
|
||||
[self applyHeaders:headers toMutableRequest:req contentType:nil];
|
||||
@@ -83,7 +83,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
|
||||
|
||||
- (BOOL)ensureEnabled:(KBNetworkCompletion)completion {
|
||||
if (!self.isEnabled) {
|
||||
NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDisabled userInfo:@{NSLocalizedDescriptionKey: @"网络未启用(可能未开启完全访问)"}];
|
||||
NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDisabled userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Network disabled (Full Access may be off)")}];
|
||||
if (completion) completion(nil, nil, e);
|
||||
return NO;
|
||||
}
|
||||
@@ -127,7 +127,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
|
||||
}
|
||||
NSData *data = (NSData *)responseObject;
|
||||
if (![data isKindOfClass:[NSData class]]) {
|
||||
if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidResponse userInfo:@{NSLocalizedDescriptionKey:@"无数据"}]);
|
||||
if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidResponse userInfo:@{NSLocalizedDescriptionKey:KBLocalized(@"No data")}]);
|
||||
return;
|
||||
}
|
||||
NSString *ct = nil;
|
||||
@@ -150,7 +150,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
|
||||
if (looksJSON) {
|
||||
NSError *jsonErr = nil;
|
||||
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonErr];
|
||||
if (jsonErr) { if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDecodeFailed userInfo:@{NSLocalizedDescriptionKey:@"JSON解析失败"}]); return; }
|
||||
if (jsonErr) { if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDecodeFailed userInfo:@{NSLocalizedDescriptionKey:KBLocalized(@"Failed to parse JSON")}]); return; }
|
||||
if (completion) completion(json, response, nil);
|
||||
} else {
|
||||
if (completion) completion(data, response, nil);
|
||||
@@ -178,12 +178,12 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
|
||||
#pragma mark - Private helpers
|
||||
|
||||
- (void)fail:(KBNetworkError)code completion:(KBNetworkCompletion)completion {
|
||||
NSString *msg = @"网络错误";
|
||||
NSString *msg = KBLocalized(@"Network error");
|
||||
switch (code) {
|
||||
case KBNetworkErrorDisabled: msg = @"网络未启用(可能未开启完全访问)"; break;
|
||||
case KBNetworkErrorInvalidURL: msg = @"无效的URL"; break;
|
||||
case KBNetworkErrorInvalidResponse: msg = @"无效的响应"; break;
|
||||
case KBNetworkErrorDecodeFailed: msg = @"解析失败"; break;
|
||||
case KBNetworkErrorDisabled: msg = KBLocalized(@"Network disabled (Full Access may be off)"); break;
|
||||
case KBNetworkErrorInvalidURL: msg = KBLocalized(@"Invalid URL"); break;
|
||||
case KBNetworkErrorInvalidResponse: msg = KBLocalized(@"Invalid response"); break;
|
||||
case KBNetworkErrorDecodeFailed: msg = KBLocalized(@"Parse failed"); break;
|
||||
default: break;
|
||||
}
|
||||
NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
del.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.35];
|
||||
del.layer.cornerRadius = 14; del.layer.masksToBounds = YES;
|
||||
del.titleLabel.font = [UIFont systemFontOfSize:13 weight:UIFontWeightSemibold];
|
||||
[del setTitle:@"删除" forState:UIControlStateNormal];
|
||||
[del setTitle:KBLocalized(@"Delete") forState:UIControlStateNormal];
|
||||
[del setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||
[del addTarget:self action:@selector(onTapClose) forControlEvents:UIControlEventTouchUpInside];
|
||||
_closeButton = del;
|
||||
@@ -77,4 +77,3 @@
|
||||
- (KBStreamTextView *)textView { return self.textViewInternal; }
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
}];
|
||||
|
||||
UILabel *title = [UILabel new];
|
||||
title.text = @"开启【允许完全访问】,体验完整功能";
|
||||
title.text = KBLocalized(@"Turn on Allow Full Access to experience all features");
|
||||
title.font = [UIFont boldSystemFontOfSize:16];
|
||||
title.textColor = [UIColor blackColor];
|
||||
title.textAlignment = NSTextAlignmentCenter;
|
||||
@@ -70,7 +70,7 @@
|
||||
}];
|
||||
|
||||
UILabel *row1 = [UILabel new]; row1.text = AppName; row1.textColor = [UIColor blackColor];
|
||||
UILabel *row2 = [UILabel new]; row2.text = @"允许完全访问"; row2.textColor = [UIColor blackColor];
|
||||
UILabel *row2 = [UILabel new]; row2.text = KBLocalized(@"Allow Full Access"); row2.textColor = [UIColor blackColor];
|
||||
[box addSubview:row1]; [box addSubview:row2];
|
||||
[row1 mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(box).offset(16); make.top.equalTo(box).offset(14); }];
|
||||
UIView *line = [UIView new]; line.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];
|
||||
@@ -98,7 +98,7 @@
|
||||
|
||||
UIButton *go = [UIButton buttonWithType:UIButtonTypeSystem];
|
||||
go.backgroundColor = [UIColor blackColor];
|
||||
[go setTitle:@"去开启" forState:UIControlStateNormal];
|
||||
[go setTitle:KBLocalized(@"Go enable") forState:UIControlStateNormal];
|
||||
[go setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||
go.titleLabel.font = [UIFont boldSystemFontOfSize:18];
|
||||
go.layer.cornerRadius = 12;
|
||||
@@ -168,10 +168,10 @@
|
||||
// Universal Link(需 AASA/Associated Domains 配置且 KB_UL_BASE 与域名一致)
|
||||
NSURL *ul = [NSURL URLWithString:[NSString stringWithFormat:@"%@?src=kb_extension", KB_UL_SETTINGS]];
|
||||
|
||||
void (^finish)(BOOL) = ^(BOOL ok){
|
||||
void (^finish)(BOOL) = ^(BOOL ok){
|
||||
if (ok) { [self dismiss]; }
|
||||
else {
|
||||
NSString *showInfo = [NSString stringWithFormat:@"请按路径:设置→通用→键盘→键盘→%@→允许完全访问",AppName];
|
||||
NSString *showInfo = [NSString stringWithFormat:KBLocalized(@"Follow: Settings → General → Keyboard → Keyboards → %@ → Allow Full Access"),AppName];
|
||||
[KBHUD showInfo:showInfo];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
- (UILabel *)placeholderLabelInternal {
|
||||
if (!_placeholderLabelInternal) {
|
||||
_placeholderLabelInternal = [[UILabel alloc] init];
|
||||
_placeholderLabelInternal.text = @"点击粘贴TA的话";
|
||||
_placeholderLabelInternal.text = KBLocalized(@"Tap to paste their message");
|
||||
_placeholderLabelInternal.textColor = [UIColor colorWithRed:0.20 green:0.64 blue:0.54 alpha:1.0];
|
||||
_placeholderLabelInternal.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
|
||||
}
|
||||
|
||||
@@ -176,7 +176,16 @@
|
||||
|
||||
- (void)reloadDemoData {
|
||||
// 演示数据(可由外部替换)
|
||||
self.itemsInternal = @[@"高情商", @"暖味拉扯", @"风趣幽默", @"撩女生", @"社交惬匿", @"情场高手", @"一枚暖男", @"聊天搭子", @"表达爱意", @"更多话术"];
|
||||
self.itemsInternal = @[KBLocalized(@"高情商"),
|
||||
KBLocalized(@"暖味拉扯"),
|
||||
KBLocalized(@"风趣幽默"),
|
||||
KBLocalized(@"撩女生"),
|
||||
KBLocalized(@"社交惬匿"),
|
||||
KBLocalized(@"情场高手"),
|
||||
KBLocalized(@"一枚暖男"),
|
||||
KBLocalized(@"聊天搭子"),
|
||||
KBLocalized(@"表达爱意"),
|
||||
KBLocalized(@"更多话术")];
|
||||
[self.tagListView setItems:self.itemsInternal];
|
||||
}
|
||||
|
||||
@@ -257,7 +266,7 @@ static NSString * const kKBStreamDemoURL = @"http://192.168.1.144:7529/api/demo/
|
||||
[self.tagListView setLoading:NO atIndex:self.loadingTagIndex.integerValue];
|
||||
self.loadingTagIndex = nil; self.loadingTagTitle = nil;
|
||||
}
|
||||
if (error) { [KBHUD showInfo:@"拉取失败"]; }
|
||||
if (error) { [KBHUD showInfo:KBLocalized(@"拉取失败")]; }
|
||||
if (self.streamOverlay) { [self.streamOverlay finish]; }
|
||||
};
|
||||
self.streamFetcher = fetcher;
|
||||
@@ -296,7 +305,7 @@ static NSString * const kKBStreamDemoURL = @"http://192.168.1.144:7529/api/demo/
|
||||
// 1) 先判断权限:未开启“完全访问”则走引导逻辑
|
||||
if (![[KBFullAccessManager shared] hasFullAccess]) {
|
||||
// 未开启完全访问:保持原有引导路径
|
||||
[KBHUD showInfo:@"处理中…"];
|
||||
[KBHUD showInfo:KBLocalized(@"处理中…")];
|
||||
[[KBFullAccessManager shared] ensureFullAccessOrGuideInView:self];
|
||||
return;
|
||||
}
|
||||
@@ -330,7 +339,7 @@ static NSString * const kKBStreamDemoURL = @"http://192.168.1.144:7529/api/demo/
|
||||
#pragma clang diagnostic pop
|
||||
} @catch (__unused NSException *e) { bridged = NO; }
|
||||
if (!bridged) {
|
||||
[KBHUD showInfo:@"请切换到主App完成登录"];
|
||||
[KBHUD showInfo:KBLocalized(@"请切换到主App完成登录")];
|
||||
}
|
||||
}];
|
||||
});
|
||||
@@ -362,7 +371,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
|
||||
return;
|
||||
}
|
||||
|
||||
[KBHUD showInfo:@"处理中…"];
|
||||
[KBHUD showInfo:KBLocalized(@"处理中…")];
|
||||
|
||||
UIInputViewController *ivc = KBFindInputViewController(self);
|
||||
if (!ivc) return;
|
||||
@@ -482,13 +491,13 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
|
||||
- (void)kb_fullAccessChanged {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{ [self kb_refreshPasteboardMonitor]; });
|
||||
}
|
||||
- (void)onTapDelete {
|
||||
- (void)onTapDelete {
|
||||
NSLog(@"点击:删除");
|
||||
UIInputViewController *ivc = KBFindInputViewController(self);
|
||||
id<UITextDocumentProxy> proxy = ivc.textDocumentProxy;
|
||||
[proxy deleteBackward];
|
||||
}
|
||||
- (void)onTapClear {
|
||||
- (void)onTapClear {
|
||||
NSLog(@"点击:清空");
|
||||
// 连续删除:仅清空光标之前的输入(不改动 pasteView 的内容)
|
||||
UIInputViewController *ivc = KBFindInputViewController(self);
|
||||
@@ -505,7 +514,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
|
||||
guard += count;
|
||||
}
|
||||
}
|
||||
- (void)onTapSend {
|
||||
- (void)onTapSend {
|
||||
NSLog(@"点击:发送");
|
||||
// 发送:插入换行。大多数聊天类 App 会把回车视为“发送”
|
||||
UIInputViewController *ivc = KBFindInputViewController(self);
|
||||
@@ -572,7 +581,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
|
||||
|
||||
- (UIButton *)pasteButtonInternal {
|
||||
if (!_pasteButtonInternal) {
|
||||
_pasteButtonInternal = [self buildRightButtonWithTitle:@"粘贴" color:[UIColor colorWithRed:0.13 green:0.73 blue:0.60 alpha:1.0]];
|
||||
_pasteButtonInternal = [self buildRightButtonWithTitle:KBLocalized(@"Paste") color:[UIColor colorWithRed:0.13 green:0.73 blue:0.60 alpha:1.0]];
|
||||
[_pasteButtonInternal addTarget:self action:@selector(onTapPaste) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _pasteButtonInternal;
|
||||
@@ -586,7 +595,7 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
|
||||
_deleteButtonInternal.layer.cornerRadius = 12.0;
|
||||
_deleteButtonInternal.layer.masksToBounds = YES;
|
||||
_deleteButtonInternal.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
|
||||
[_deleteButtonInternal setTitle:@"删除" forState:UIControlStateNormal];
|
||||
[_deleteButtonInternal setTitle:KBLocalized(@"删除") forState:UIControlStateNormal];
|
||||
[_deleteButtonInternal setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
|
||||
[_deleteButtonInternal addTarget:self action:@selector(onTapDelete) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
@@ -600,16 +609,16 @@ static void KBULDarwinCallback(CFNotificationCenterRef center, void *observer, C
|
||||
_clearButtonInternal.layer.cornerRadius = 12.0;
|
||||
_clearButtonInternal.layer.masksToBounds = YES;
|
||||
_clearButtonInternal.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
|
||||
[_clearButtonInternal setTitle:@"清空" forState:UIControlStateNormal];
|
||||
[_clearButtonInternal setTitle:KBLocalized(@"Clear") forState:UIControlStateNormal];
|
||||
[_clearButtonInternal setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
|
||||
[_clearButtonInternal addTarget:self action:@selector(onTapClear) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _clearButtonInternal;
|
||||
}
|
||||
|
||||
- (UIButton *)sendButtonInternal {
|
||||
- (UIButton *)sendButtonInternal {
|
||||
if (!_sendButtonInternal) {
|
||||
_sendButtonInternal = [self buildRightButtonWithTitle:@"发送" color:[UIColor colorWithRed:0.13 green:0.73 blue:0.60 alpha:1.0]];
|
||||
_sendButtonInternal = [self buildRightButtonWithTitle:KBLocalized(@"Send") color:[UIColor colorWithRed:0.13 green:0.73 blue:0.60 alpha:1.0]];
|
||||
[_sendButtonInternal addTarget:self action:@selector(onTapSend) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _sendButtonInternal;
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
NSArray *r4 = @[ [KBKey keyWithTitle:@"abc" type:KBKeyTypeModeChange],
|
||||
[KBKey keyWithTitle:@"AI" type:KBKeyTypeCustom],
|
||||
[KBKey keyWithTitle:@"space" type:KBKeyTypeSpace],
|
||||
[KBKey keyWithTitle:@"发送" type:KBKeyTypeReturn] ];
|
||||
[KBKey keyWithTitle:KBLocalized(@"Send") type:KBKeyTypeReturn] ];
|
||||
|
||||
return @[r1, r2, r3, r4];
|
||||
}
|
||||
@@ -159,7 +159,7 @@
|
||||
NSArray *row4 = @[ [KBKey keyWithTitle:@"123" type:KBKeyTypeModeChange],
|
||||
[KBKey keyWithTitle:@"AI" type:KBKeyTypeCustom],
|
||||
[KBKey keyWithTitle:@"space" type:KBKeyTypeSpace],
|
||||
[KBKey keyWithTitle:@"发送" type:KBKeyTypeReturn] ];
|
||||
[KBKey keyWithTitle:KBLocalized(@"Send") type:KBKeyTypeReturn] ];
|
||||
|
||||
return @[row1.copy, row2.copy, row3.copy, row4];
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
}];
|
||||
|
||||
self.titleLabel = [[UILabel alloc] init];
|
||||
self.titleLabel.text = @"设置";
|
||||
self.titleLabel.text = KBLocalized(@"设置");
|
||||
self.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
|
||||
self.titleLabel.textColor = [UIColor blackColor];
|
||||
[self addSubview:self.titleLabel];
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
// 占位内容
|
||||
UILabel *place = [[UILabel alloc] init];
|
||||
place.text = @"这里是设置内容占位";
|
||||
place.text = KBLocalized(@"这里是设置内容占位");
|
||||
place.textColor = [UIColor darkGrayColor];
|
||||
place.font = [UIFont systemFontOfSize:14];
|
||||
[self addSubview:place];
|
||||
@@ -68,4 +68,3 @@
|
||||
- (UIButton *)backButton { return self.backButtonInternal; }
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -18,3 +18,181 @@
|
||||
"lang_toggle" = "Toggle Language";
|
||||
"current_lang" = "Current: %@";
|
||||
"common_back" = "Back";
|
||||
|
||||
// Login & account
|
||||
"Log In" = "Log In";
|
||||
"Signed in successfully" = "Signed in successfully";
|
||||
"Sign-in failed" = "Sign-in failed";
|
||||
"Sign in to unlock all features" = "Sign in to unlock all features";
|
||||
"We'll use Apple for a quick, secure sign-in" = "We'll use Apple for a quick, secure sign-in";
|
||||
"Sign in with Apple requires iOS 13 or later" = "Sign in with Apple requires iOS 13 or later";
|
||||
"需要 iOS13+ 才能使用 Apple 登录" = "Sign in with Apple requires iOS 13 or later";
|
||||
"无效的登录凭证" = "Invalid login credential";
|
||||
"未返回 token" = "No token returned";
|
||||
"保存登录态失败" = "Failed to save login state";
|
||||
"请切换到主App完成登录" = "Please switch to the main app to finish signing in";
|
||||
|
||||
// Generic buttons & tips
|
||||
"好" = "OK";
|
||||
"Confirm" = "Confirm";
|
||||
"Cancel" = "Cancel";
|
||||
"Close" = "Close";
|
||||
"Delete" = "Delete";
|
||||
"Clear" = "Clear";
|
||||
"Paste" = "Paste";
|
||||
"Send" = "Send";
|
||||
"Retry" = "Retry";
|
||||
"Success" = "Success";
|
||||
"Failed" = "Failed";
|
||||
"Network error" = "Network error";
|
||||
"Saved" = "Saved";
|
||||
"Copy Success" = "Copy Success";
|
||||
|
||||
// Network
|
||||
"Network unavailable" = "Network unavailable";
|
||||
"Network disabled (Full Access may be off)" = "Network disabled (Full Access may be off)";
|
||||
"Invalid URL" = "Invalid URL";
|
||||
"Invalid response" = "Invalid response";
|
||||
"No data" = "No data";
|
||||
"Failed to parse JSON" = "Failed to parse JSON";
|
||||
"Parse failed" = "Parse failed";
|
||||
"未获取到数据" = "No data received";
|
||||
"请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@" = "Request failed\nURL: %@\nStatus: %ld\nError: %@\nUserInfo: %@";
|
||||
"响应成功(JSON)\nURL: %@\n状态: %ld\nContent-Type: %@\n数据: %@" = "Response OK (JSON)\nURL: %@\nStatus: %ld\nContent-Type: %@\nData: %@";
|
||||
"响应成功(Data)\nURL: %@\n状态: %ld\nContent-Type: %@\n数据: %@" = "Response OK (Data)\nURL: %@\nStatus: %ld\nContent-Type: %@\nData: %@";
|
||||
"响应解析失败(JSON)\nURL: %@\n错误: %@" = "Response decode failed (JSON)\nURL: %@\nError: %@";
|
||||
"HTTP GET\nURL: %@\nHeaders: %@\n参数: %@" = "HTTP GET\nURL: %@\nHeaders: %@\nParams: %@";
|
||||
"无效响应\nURL: %@\n说明: %@" = "Invalid response\nURL: %@\nReason: %@";
|
||||
"网络不可用\n请在“设置”中检查本应用的无线数据权限或网络连接。" = "Network unavailable\nPlease check this app's wireless-data permission or network connection in Settings.";
|
||||
"Please check this app's wireless-data permission or network connection in Settings." = "Please check this app's wireless-data permission or network connection in Settings.";
|
||||
|
||||
// Permission & guides
|
||||
"使用引导" = "Usage Guide";
|
||||
"Turn on Allow Full Access to experience all features" = "Turn on Allow Full Access to experience all features";
|
||||
"Allow Full Access" = "Allow Full Access";
|
||||
"Follow: Settings → General → Keyboard → Keyboards → %@ → Allow Full Access" = "Follow: Settings → General → Keyboard → Keyboards → %@ → Allow Full Access";
|
||||
"Go enable" = "Go enable";
|
||||
"Open Settings" = "Open Settings";
|
||||
"After pasting the conversation in the keyboard, choose a reply style" = "After pasting the conversation in the keyboard, choose a reply style";
|
||||
"当前:%@" = "Current: %@";
|
||||
|
||||
// Home / Tab labels
|
||||
"Home" = "Home";
|
||||
"Shop" = "Shop";
|
||||
"Circle" = "Circle";
|
||||
"Mine" = "Mine";
|
||||
"热门" = "Hot";
|
||||
"排行" = "Rank";
|
||||
|
||||
// Search & history
|
||||
"Clear history" = "Clear history";
|
||||
"Delete all history?" = "Delete all history?";
|
||||
"Delete this tag?" = "Delete this tag?";
|
||||
"This action cannot be undone" = "This action cannot be undone";
|
||||
"Loaded more successfully" = "Loaded more successfully";
|
||||
|
||||
// Skins & shop
|
||||
"皮肤中心" = "Skin Center";
|
||||
"No skins yet" = "No skins yet";
|
||||
"Pull down to refresh" = "Pull down to refresh";
|
||||
"下载并应用" = "Download & Apply";
|
||||
"已应用,切到键盘查看" = "Applied. Switch to the keyboard to view.";
|
||||
"应用失败" = "Apply failed";
|
||||
"Open agreement" = "Open agreement";
|
||||
"购物商城" = "Shop Mall";
|
||||
|
||||
// Skin sample names
|
||||
"极光" = "Aurora";
|
||||
"雪山" = "Snow Mountain";
|
||||
"湖面" = "Lake";
|
||||
|
||||
// Sample tags & copy
|
||||
"高情商" = "High EQ";
|
||||
"暖味拉扯" = "Ambiguous flirting";
|
||||
"风趣幽默" = "Witty & humorous";
|
||||
"撩女生" = "Flirt with girls";
|
||||
"社交惬匿" = "Relaxed socializing";
|
||||
"情场高手" = "Dating expert";
|
||||
"一枚暖男" = "Warm-hearted guy";
|
||||
"聊天搭子" = "Chat buddy";
|
||||
"表达爱意" = "Express love";
|
||||
"更多话术" = "More prompts";
|
||||
"Tap to paste their message" = "Tap to paste their message";
|
||||
"Tap any conversation to paste, then try any reply style~" = "Tap any conversation to paste, then try any reply style~";
|
||||
"What are you doing?" = "What are you doing?";
|
||||
"I'm going to take a shower." = "I'm going to take a shower.";
|
||||
"🎉 If you run into any other issues, tap Online Support to get help~" = "🎉 If you run into any other issues, tap Online Support to get help~";
|
||||
"👋 Welcome to Key of Love Keyboard" = "👋 Welcome to Key of Love Keyboard";
|
||||
|
||||
// Payment & IAP
|
||||
"Payment successful" = "Payment successful";
|
||||
"Payment failed" = "Payment failed";
|
||||
"购买:%@ Coins %@" = "Purchase: %@ Coins %@";
|
||||
"Pay clicked" = "Pay clicked";
|
||||
|
||||
// Example categories/items
|
||||
"能力" = "Ability";
|
||||
"能力2" = "Ability 2";
|
||||
"爱好" = "Hobby";
|
||||
"爱好2" = "Hobby 2";
|
||||
"队友" = "Teammates";
|
||||
"队友2" = "Teammates 2";
|
||||
"高级能力" = "Advanced abilities";
|
||||
"高级爱好" = "Advanced hobbies";
|
||||
"高级队友" = "Advanced teammates";
|
||||
|
||||
// Example fruits etc.
|
||||
"果冻橙" = "Jelly orange";
|
||||
"芒果" = "Mango";
|
||||
"有机水果卷心菜" = "Organic cabbage";
|
||||
"水果萝卜" = "Fruit radish";
|
||||
"熟冻帝王蟹" = "Cooked king crab";
|
||||
"赣南脐橙" = "Gannan navel orange";
|
||||
"苹果" = "Apple";
|
||||
"胡萝卜" = "Carrot";
|
||||
"葡萄" = "Grape";
|
||||
"西瓜" = "Watermelon";
|
||||
"小龙虾" = "Crawfish";
|
||||
"吃烤肉" = "Eat barbecue";
|
||||
"吃鸡腿肉" = "Eat chicken drumsticks";
|
||||
"吃牛肉" = "Eat beef";
|
||||
"各种肉" = "All kinds of meat";
|
||||
|
||||
// One Piece sample roles
|
||||
"【剑士】罗罗诺亚·索隆" = "[Swordsman] Roronoa Zoro";
|
||||
"【航海士】娜美" = "[Navigator] Nami";
|
||||
"【狙击手】乌索普" = "[Sniper] Usopp";
|
||||
"【厨师】香吉士" = "[Cook] Sanji";
|
||||
"【船医】托尼托尼·乔巴" = "[Doctor] Tony Tony Chopper";
|
||||
"【船匠】 弗兰奇" = "[Shipwright] Franky";
|
||||
"【音乐家】布鲁克" = "[Musician] Brook";
|
||||
"【考古学家】妮可·罗宾" = "[Archaeologist] Nico Robin";
|
||||
|
||||
// Rubber-series sample moves
|
||||
"橡胶火箭" = "Gum-Gum Rocket";
|
||||
"橡胶火箭炮" = "Gum-Gum Bazooka";
|
||||
"橡胶机关枪" = "Gum-Gum Gatling";
|
||||
"橡胶子弹" = "Gum-Gum Bullet";
|
||||
"橡胶攻城炮" = "Gum-Gum Cannon";
|
||||
"橡胶象枪" = "Gum-Gum Elephant Gun";
|
||||
"橡胶象枪乱打" = "Gum-Gum Elephant Gatling";
|
||||
"橡胶灰熊铳" = "Gum-Gum Grizzly Magnum";
|
||||
"橡胶雷神象枪" = "Gum-Gum Thor Elephant Gun";
|
||||
"橡胶猿王枪" = "Gum-Gum King Kong Gun";
|
||||
"橡胶犀·榴弹炮" = "Gum-Gum Rhino Grenade";
|
||||
"橡胶大蛇炮" = "Gum-Gum Great Serpent Cannon";
|
||||
|
||||
// Misc
|
||||
"测试" = "Test";
|
||||
"暂无数据" = "No data yet";
|
||||
"这里是设置内容占位" = "Settings content placeholder";
|
||||
"设置" = "Settings";
|
||||
"使用引导" = "Usage Guide";
|
||||
"螃蟹啊斯柯达积分卡" = "Crab points card";
|
||||
"❎不是自己的键盘" = "❎ Not our keyboard";
|
||||
"是自己的键盘" = "Our keyboard";
|
||||
|
||||
// English-only keys with Chinese equivalents
|
||||
"Change The Nickname" = "Change Nickname";
|
||||
"Please Enter The Modified Nickname" = "Please enter the new nickname";
|
||||
"Save" = "Save";
|
||||
|
||||
@@ -18,3 +18,177 @@
|
||||
"lang_toggle" = "切换语言";
|
||||
"current_lang" = "当前:%@";
|
||||
"common_back" = "返回";
|
||||
|
||||
// 登录与账号
|
||||
"登录" = "登录";
|
||||
"登录成功" = "登录成功";
|
||||
"登录失败" = "登录失败";
|
||||
"登录后可使用全部功能" = "登录后可使用全部功能";
|
||||
"我们将使用 Apple 进行快速安全登录" = "我们将使用 Apple 进行快速安全登录";
|
||||
"Apple 登录需要 iOS 13 及以上版本" = "Apple 登录需要 iOS 13 及以上版本";
|
||||
"需要 iOS13+ 才能使用 Apple 登录" = "需要 iOS13+ 才能使用 Apple 登录";
|
||||
"无效的登录凭证" = "无效的登录凭证";
|
||||
"未返回 token" = "未返回 token";
|
||||
"保存登录态失败" = "保存登录态失败";
|
||||
"请切换到主App完成登录" = "请切换到主App完成登录";
|
||||
|
||||
// 通用按钮与提示
|
||||
"好" = "好";
|
||||
"确定" = "确定";
|
||||
"取消" = "取消";
|
||||
"关闭" = "关闭";
|
||||
"删除" = "删除";
|
||||
"清空" = "清空";
|
||||
"粘贴" = "粘贴";
|
||||
"发送" = "发送";
|
||||
"重试" = "重试";
|
||||
"成功" = "成功";
|
||||
"失败" = "失败";
|
||||
"网络错误" = "网络错误";
|
||||
"已保存" = "已保存";
|
||||
"复制成功" = "复制成功";
|
||||
|
||||
// 网络相关
|
||||
"网络不可用" = "网络不可用";
|
||||
"网络未启用(可能未开启完全访问)" = "网络未启用(可能未开启完全访问)";
|
||||
"无效的URL" = "无效的URL";
|
||||
"无效的响应" = "无效的响应";
|
||||
"无数据" = "无数据";
|
||||
"JSON解析失败" = "JSON解析失败";
|
||||
"解析失败" = "解析失败";
|
||||
"未获取到数据" = "未获取到数据";
|
||||
"请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@" = "请求失败\nURL: %@\n状态: %ld\n错误: %@\nUserInfo: %@";
|
||||
"响应成功(JSON)\nURL: %@\n状态: %ld\nContent-Type: %@\n数据: %@" = "响应成功(JSON)\nURL: %@\n状态: %ld\nContent-Type: %@\n数据: %@";
|
||||
"响应成功(Data)\nURL: %@\n状态: %ld\nContent-Type: %@\n数据: %@" = "响应成功(Data)\nURL: %@\n状态: %ld\nContent-Type: %@\n数据: %@";
|
||||
"响应解析失败(JSON)\nURL: %@\n错误: %@" = "响应解析失败(JSON)\nURL: %@\n错误: %@";
|
||||
"HTTP GET\nURL: %@\nHeaders: %@\n参数: %@" = "HTTP GET\nURL: %@\nHeaders: %@\n参数: %@";
|
||||
"无效响应\nURL: %@\n说明: %@" = "无效响应\nURL: %@\n说明: %@";
|
||||
"网络不可用\n请在“设置”中检查本应用的无线数据权限或网络连接。" = "网络不可用\n请在“设置”中检查本应用的无线数据权限或网络连接。";
|
||||
"请在“设置”中检查本应用的无线数据权限或网络连接。" = "请在“设置”中检查本应用的无线数据权限或网络连接。";
|
||||
|
||||
// 权限与引导
|
||||
"使用引导" = "使用引导";
|
||||
"开启【允许完全访问】,体验完整功能" = "开启【允许完全访问】,体验完整功能";
|
||||
"允许完全访问" = "允许完全访问";
|
||||
"请按路径:设置→通用→键盘→键盘→%@→允许完全访问" = "请按路径:设置→通用→键盘→键盘→%@→允许完全访问";
|
||||
"去开启" = "去开启";
|
||||
"去设置" = "去设置";
|
||||
"网络未启用(可能未开启完全访问)" = "网络未启用(可能未开启完全访问)";
|
||||
"在键盘粘贴对话后,选择回复方式" = "在键盘粘贴对话后,选择回复方式";
|
||||
"当前:%@" = "当前:%@";
|
||||
|
||||
// 首页 / Tab 文案
|
||||
"首页" = "首页";
|
||||
"商城" = "商城";
|
||||
"社区" = "社区";
|
||||
"我的" = "我的";
|
||||
"热门" = "热门";
|
||||
"排行" = "排行";
|
||||
|
||||
// 搜索与历史
|
||||
"清空历史" = "清空历史";
|
||||
"是否删除所有历史记录?" = "是否删除所有历史记录?";
|
||||
"删除该标签?" = "删除该标签?";
|
||||
"删除后不可恢复" = "删除后不可恢复";
|
||||
"加载更多成功" = "加载更多成功";
|
||||
|
||||
// 皮肤与商城
|
||||
"皮肤中心" = "皮肤中心";
|
||||
"暂无皮肤" = "暂无皮肤";
|
||||
"下拉刷新试试" = "下拉刷新试试";
|
||||
"下载并应用" = "下载并应用";
|
||||
"已应用,切到键盘查看" = "已应用,切到键盘查看";
|
||||
"应用失败" = "应用失败";
|
||||
"跳转协议" = "跳转协议";
|
||||
"购物商城" = "购物商城";
|
||||
|
||||
// 皮肤示例名称
|
||||
"极光" = "极光";
|
||||
"雪山" = "雪山";
|
||||
"湖面" = "湖面";
|
||||
|
||||
// 示例标签与文案
|
||||
"高情商" = "高情商";
|
||||
"暖味拉扯" = "暖味拉扯";
|
||||
"风趣幽默" = "风趣幽默";
|
||||
"撩女生" = "撩女生";
|
||||
"社交惬匿" = "社交惬匿";
|
||||
"情场高手" = "情场高手";
|
||||
"一枚暖男" = "一枚暖男";
|
||||
"聊天搭子" = "聊天搭子";
|
||||
"表达爱意" = "表达爱意";
|
||||
"更多话术" = "更多话术";
|
||||
"点击粘贴TA的话" = "点击粘贴TA的话";
|
||||
"点击任一对话去粘贴,选择任意回复方式去试用吧~" = "点击任一对话去粘贴,选择任意回复方式去试用吧~";
|
||||
"在干嘛?" = "在干嘛?";
|
||||
"我去洗澡了" = "我去洗澡了";
|
||||
"🎉 如您遇到其他问题,可点击在线客服帮您解决~" = "🎉 如您遇到其他问题,可点击在线客服帮您解决~";
|
||||
"👋 欢迎使用『Lovekey 键盘』" = "👋 欢迎使用『Lovekey 键盘』";
|
||||
|
||||
// 支付与内购
|
||||
"支付成功" = "支付成功";
|
||||
"支付失败" = "支付失败";
|
||||
"购买:%@ Coins %@" = "购买:%@ Coins %@";
|
||||
"Pay clicked" = "Pay clicked";
|
||||
|
||||
// 示例商品/分类
|
||||
"能力" = "能力";
|
||||
"能力2" = "能力2";
|
||||
"爱好" = "爱好";
|
||||
"爱好2" = "爱好2";
|
||||
"队友" = "队友";
|
||||
"队友2" = "队友2";
|
||||
"高级能力" = "高级能力";
|
||||
"高级爱好" = "高级爱好";
|
||||
"高级队友" = "高级队友";
|
||||
|
||||
// 示例水果等
|
||||
"果冻橙" = "果冻橙";
|
||||
"芒果" = "芒果";
|
||||
"有机水果卷心菜" = "有机水果卷心菜";
|
||||
"水果萝卜" = "水果萝卜";
|
||||
"熟冻帝王蟹" = "熟冻帝王蟹";
|
||||
"赣南脐橙" = "赣南脐橙";
|
||||
"苹果" = "苹果";
|
||||
"胡萝卜" = "胡萝卜";
|
||||
"葡萄" = "葡萄";
|
||||
"西瓜" = "西瓜";
|
||||
"小龙虾" = "小龙虾";
|
||||
"吃烤肉" = "吃烤肉";
|
||||
"吃鸡腿肉" = "吃鸡腿肉";
|
||||
"吃牛肉" = "吃牛肉";
|
||||
"各种肉" = "各种肉";
|
||||
|
||||
// One Piece 示例角色
|
||||
"【剑士】罗罗诺亚·索隆" = "【剑士】罗罗诺亚·索隆";
|
||||
"【航海士】娜美" = "【航海士】娜美";
|
||||
"【狙击手】乌索普" = "【狙击手】乌索普";
|
||||
"【厨师】香吉士" = "【厨师】香吉士";
|
||||
"【船医】托尼托尼·乔巴" = "【船医】托尼托尼·乔巴";
|
||||
"【船匠】 弗兰奇" = "【船匠】 弗兰奇";
|
||||
"【音乐家】布鲁克" = "【音乐家】布鲁克";
|
||||
"【考古学家】妮可·罗宾" = "【考古学家】妮可·罗宾";
|
||||
|
||||
// 橡胶系列示例文案
|
||||
"橡胶火箭" = "橡胶火箭";
|
||||
"橡胶火箭炮" = "橡胶火箭炮";
|
||||
"橡胶机关枪" = "橡胶机关枪";
|
||||
"橡胶子弹" = "橡胶子弹";
|
||||
"橡胶攻城炮" = "橡胶攻城炮";
|
||||
"橡胶象枪" = "橡胶象枪";
|
||||
"橡胶象枪乱打" = "橡胶象枪乱打";
|
||||
"橡胶灰熊铳" = "橡胶灰熊铳";
|
||||
"橡胶雷神象枪" = "橡胶雷神象枪";
|
||||
"橡胶猿王枪" = "橡胶猿王枪";
|
||||
"橡胶犀·榴弹炮" = "橡胶犀·榴弹炮";
|
||||
"橡胶大蛇炮" = "橡胶大蛇炮";
|
||||
|
||||
// 其它
|
||||
"测试" = "测试";
|
||||
"暂无数据" = "暂无数据";
|
||||
"这里是设置内容占位" = "这里是设置内容占位";
|
||||
"设置" = "设置";
|
||||
"使用引导" = "使用引导";
|
||||
"螃蟹啊斯柯达积分卡" = "螃蟹啊斯柯达积分卡";
|
||||
"❎不是自己的键盘" = "❎不是自己的键盘";
|
||||
"是自己的键盘" = "是自己的键盘";
|
||||
|
||||
@@ -174,9 +174,9 @@ static NSString * const kKBKeyboardExtensionBundleId = @"com.loveKey.nyx.CustomK
|
||||
// 交给 VM 统一处理 Apple 登录 + 服务端登录
|
||||
[[KBLoginVM shared] signInWithAppleFromViewController:KB_CURRENT_NAV completion:^(BOOL success, NSError * _Nullable error) {
|
||||
if (success) {
|
||||
[KBHUD showInfo:@"登录成功"];
|
||||
[KBHUD showInfo:KBLocalized(@"Signed in successfully")];
|
||||
} else {
|
||||
NSString *msg = error.localizedDescription ?: @"登录失败";
|
||||
NSString *msg = error.localizedDescription ?: KBLocalized(@"Sign-in failed");
|
||||
[KBHUD showInfo:msg];
|
||||
}
|
||||
}];
|
||||
@@ -281,17 +281,17 @@ static BOOL KBIsKeyboardEnabled(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"网络不可用"
|
||||
message:@"请在“设置”中检查本应用的无线数据权限或网络连接。"
|
||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:KBLocalized(@"Network unavailable")
|
||||
message:KBLocalized(@"Please check this app's wireless-data permission or network connection in Settings.")
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
UIAlertAction *settings = [UIAlertAction actionWithTitle:@"去设置"
|
||||
UIAlertAction *settings = [UIAlertAction actionWithTitle:KBLocalized(@"Open Settings")
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction * _Nonnull action) {
|
||||
[self kb_openAppSettings]; // 你已经实现好的跳设置方法
|
||||
}];
|
||||
|
||||
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消"
|
||||
UIAlertAction *cancel = [UIAlertAction actionWithTitle:KBLocalized(@"Cancel")
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:nil];
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
_useEmptyDataSet = YES; // 默认开启
|
||||
_emptyShouldAllowScroll = YES; // 默认允许滚动
|
||||
_emptyVerticalOffset = 0; // 默认不偏移
|
||||
_emptyTitleText = @"暂无数据"; // 默认标题
|
||||
_emptyTitleText = KBLocalized(@"暂无数据"); // 默认标题
|
||||
|
||||
#if KB_HAS_DZN
|
||||
self.emptyDataSetSource = self;
|
||||
@@ -148,7 +148,7 @@
|
||||
self.useEmptyDataSet = NO;
|
||||
|
||||
// 默认文案
|
||||
NSString *t = title ?: @"暂无数据";
|
||||
NSString *t = title ?: KBLocalized(@"暂无数据");
|
||||
|
||||
LYEmptyView *ev = nil;
|
||||
if (buttonTitle.length > 0) {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
tapHandler:(KBEmptyAction)tapHandler
|
||||
buttonHandler:(KBEmptyAction)buttonHandler {
|
||||
#if KB_HAS_LY
|
||||
NSString *t = title ?: @"暂无数据";
|
||||
NSString *t = title ?: KBLocalized(@"暂无数据");
|
||||
LYEmptyView *ev = nil;
|
||||
|
||||
if (buttonTitle.length > 0) {
|
||||
@@ -87,4 +87,3 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -31,29 +31,29 @@
|
||||
// 首页
|
||||
HomeMainVC *home = [[HomeMainVC alloc] init];
|
||||
BaseNavigationController *navHome = [[BaseNavigationController alloc] initWithRootViewController:home];
|
||||
navHome.tabBarItem = [self tabItemWithTitle:@"首页"
|
||||
navHome.tabBarItem = [self tabItemWithTitle:KBLocalized(@"Home")
|
||||
image:@"tab_home"
|
||||
selectedImg:@"tab_home_selected"];
|
||||
|
||||
// 商城
|
||||
KBShopVC *shop = [[KBShopVC alloc] init];
|
||||
BaseNavigationController *navShop = [[BaseNavigationController alloc] initWithRootViewController:shop];
|
||||
navShop.tabBarItem = [self tabItemWithTitle:@"商城"
|
||||
navShop.tabBarItem = [self tabItemWithTitle:KBLocalized(@"Shop")
|
||||
image:@"tab_shop"
|
||||
selectedImg:@"tab_shop_selected"];
|
||||
|
||||
// 社区
|
||||
KBCommunityVC *community = [[KBCommunityVC alloc] init];
|
||||
community.title = @"社区";
|
||||
community.title = KBLocalized(@"社区");
|
||||
BaseNavigationController *navCommunity = [[BaseNavigationController alloc] initWithRootViewController:community];
|
||||
navCommunity.tabBarItem = [self tabItemWithTitle:@"社区"
|
||||
navCommunity.tabBarItem = [self tabItemWithTitle:KBLocalized(@"Circle")
|
||||
image:@"tab_shequ"
|
||||
selectedImg:@"tab_shequ_selected"];
|
||||
|
||||
// 我的
|
||||
MyVC *my = [[MyVC alloc] init];
|
||||
BaseNavigationController *navMy = [[BaseNavigationController alloc] initWithRootViewController:my];
|
||||
navMy.tabBarItem = [self tabItemWithTitle:@"我的"
|
||||
navMy.tabBarItem = [self tabItemWithTitle:KBLocalized(@"Mine")
|
||||
image:@"tab_my"
|
||||
selectedImg:@"tab_my_selected"];
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ static __weak UIViewController *sDefaultPresenter = nil; // 可选外部指定
|
||||
[self _markFinishedAndContinue];
|
||||
return;
|
||||
}
|
||||
NSString *ok = button ?: (NSLocalizedString(@"OK", nil).length ? NSLocalizedString(@"OK", nil) : @"好");
|
||||
NSString *ok = button ?: (NSLocalizedString(@"OK", nil).length ? NSLocalizedString(@"OK", nil) : KBLocalized(@"好"));
|
||||
UIAlertController *ac = [UIAlertController alertControllerWithTitle:(title ?: @"")
|
||||
message:(message ?: @"")
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
@@ -138,8 +138,8 @@ static inline void KBSetActionTitleColor(UIAlertAction *action, UIColor *color)
|
||||
[self enqueuePresent:^{
|
||||
UIViewController *vc = [self presentingVC];
|
||||
if (!vc) { [self _markFinishedAndContinue]; return; }
|
||||
NSString *ok = okTitle ?: @"确定";
|
||||
NSString *cancel = cancelTitle ?: @"取消";
|
||||
NSString *ok = okTitle ?: KBLocalized(@"Confirm");
|
||||
NSString *cancel = cancelTitle ?: KBLocalized(@"Cancel");
|
||||
UIAlertController *ac = [UIAlertController alertControllerWithTitle:(title ?: @"")
|
||||
message:(message ?: @"")
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
@@ -175,8 +175,8 @@ static inline void KBSetActionTitleColor(UIAlertAction *action, UIColor *color)
|
||||
[self enqueuePresent:^{
|
||||
UIViewController *vc = [self presentingVC];
|
||||
if (!vc) { [self _markFinishedAndContinue]; return; }
|
||||
NSString *ok = okTitle ?: @"确定";
|
||||
NSString *cancel = cancelTitle ?: @"取消";
|
||||
NSString *ok = okTitle ?: KBLocalized(@"Confirm");
|
||||
NSString *cancel = cancelTitle ?: KBLocalized(@"Cancel");
|
||||
UIAlertController *ac = [UIAlertController alertControllerWithTitle:(title ?: @"")
|
||||
message:(message ?: @"")
|
||||
preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
@@ -169,10 +169,10 @@ static __weak UIView *sContainerView = nil; // 缺省承载视图(
|
||||
|
||||
+ (void)showSuccess:(NSString *)status {
|
||||
// 简单起见,使用文字模式;如需图标,可替换为自定义勾勾图片
|
||||
[self _showText:status ?: @"成功" icon:nil];
|
||||
[self _showText:status ?: KBLocalized(@"Success") icon:nil];
|
||||
}
|
||||
|
||||
+ (void)showError:(NSString *)status { [self _showText:status ?: @"失败" icon:nil]; }
|
||||
+ (void)showError:(NSString *)status { [self _showText:status ?: KBLocalized(@"Failed") icon:nil]; }
|
||||
|
||||
+ (void)dismiss { [self onMain:^{ [sHUD hideAnimated:YES]; }]; }
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
_titleLabel.numberOfLines = 0;
|
||||
_titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
|
||||
_titleLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1.0];
|
||||
_titleLabel.text = @"👋 欢迎使用『Lovekey 键盘』";
|
||||
_titleLabel.text = KBLocalized(@"👋 Welcome to Key of Love Keyboard");
|
||||
}
|
||||
return _titleLabel;
|
||||
}
|
||||
@@ -124,7 +124,7 @@
|
||||
_descLabel.numberOfLines = 0;
|
||||
_descLabel.font = [UIFont systemFontOfSize:14];
|
||||
_descLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1.0];
|
||||
_descLabel.text = @"点击任一对话去粘贴,选择任意回复方式去试用吧~";
|
||||
_descLabel.text = KBLocalized(@"Tap any conversation to paste, then try any reply style~");
|
||||
}
|
||||
return _descLabel;
|
||||
}
|
||||
@@ -137,7 +137,7 @@
|
||||
_q1Label = [UILabel new];
|
||||
_q1Label.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
|
||||
_q1Label.textColor = [UIColor blackColor];
|
||||
_q1Label.text = @"在干嘛?";
|
||||
_q1Label.text = KBLocalized(@"What are you doing?");
|
||||
}
|
||||
return _q1Label;
|
||||
}
|
||||
@@ -147,10 +147,9 @@
|
||||
_q2Label = [UILabel new];
|
||||
_q2Label.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
|
||||
_q2Label.textColor = [UIColor blackColor];
|
||||
_q2Label.text = @"我去洗澡了";
|
||||
_q2Label.text = KBLocalized(@"I'm going to take a shower.");
|
||||
}
|
||||
return _q2Label;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) {
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
self.view.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0];
|
||||
self.title = @"使用引导";
|
||||
// self.title = KBLocalized(@"使用引导");
|
||||
|
||||
[self.view addSubview:self.tableView];
|
||||
[self.view addSubview:self.inputBar];
|
||||
@@ -176,7 +176,7 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) {
|
||||
// 1. 插入我方消息
|
||||
[self.items addObject:@{ @"type": @(KBGuideItemTypeUser), @"text": text ?: @"" }];
|
||||
// 2. 紧跟一条固定客服消息
|
||||
NSString *reply = @"🎉 如您遇到其他问题,可点击在线客服帮您解决~";
|
||||
NSString *reply = KBLocalized(@"🎉 If you run into any other issues, tap Online Support to get help~");
|
||||
[self.items addObject:@{ @"type": @(KBGuideItemTypeKF), @"text": reply }];
|
||||
|
||||
// 刷新并滚动到底部
|
||||
@@ -273,7 +273,7 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) {
|
||||
self.kb_lastInputModeIdentifier = currId;
|
||||
|
||||
BOOL isMine = [currId rangeOfString:KB_KEYBOARD_EXTENSION_BUNDLE_ID].location != NSNotFound;
|
||||
[KBHUD showInfo:(isMine ? @"是自己的键盘" : @"❎不是自己的键盘")];
|
||||
[KBHUD showInfo:(isMine ? KBLocalized(@"是自己的键盘") : KBLocalized(@"❎不是自己的键盘"))];
|
||||
}
|
||||
|
||||
/// 当权限满足时,尽力激活输入框,从而触发键盘挂载与输入法检测
|
||||
@@ -368,7 +368,7 @@ typedef NS_ENUM(NSInteger, KBGuideItemType) {
|
||||
_textField.delegate = self;
|
||||
_textField.returnKeyType = UIReturnKeySend; // 回车发送
|
||||
_textField.font = [UIFont systemFontOfSize:15];
|
||||
_textField.placeholder = @"在键盘粘贴对话后,选择回复方式";
|
||||
_textField.placeholder = KBLocalized(@"After pasting the conversation in the keyboard, choose a reply style");
|
||||
_textField.backgroundColor = [UIColor whiteColor];
|
||||
_textField.layer.cornerRadius = 10; _textField.layer.masksToBounds = YES;
|
||||
UIView *pad = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 36)];
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
self.title = KBLocalized(@"lang_test_title");
|
||||
NSString *code = [KBLocalizationManager shared].currentLanguageCode ?: @"";
|
||||
NSString *fmt = KBLocalized(@"current_lang");
|
||||
self.label.text = [NSString stringWithFormat:fmt.length ? fmt : @"当前:%@", code];
|
||||
NSString *fallback = KBLocalized(@"当前:%@");
|
||||
self.label.text = [NSString stringWithFormat:fmt.length ? fmt : fallback, code];
|
||||
[self.toggleBtn setTitle:KBLocalized(@"lang_toggle") forState:UIControlStateNormal];
|
||||
}
|
||||
|
||||
@@ -57,4 +58,3 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
|
||||
self.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
_applyBtn = [UIButton buttonWithType:UIButtonTypeSystem];
|
||||
[_applyBtn setTitle:@"下载并应用" forState:UIControlStateNormal];
|
||||
[_applyBtn setTitle:KBLocalized(@"Download & Apply") forState:UIControlStateNormal];
|
||||
_applyBtn.layer.cornerRadius = 6; _applyBtn.layer.borderWidth = 1;
|
||||
_applyBtn.layer.borderColor = [UIColor colorWithWhite:0.85 alpha:1].CGColor;
|
||||
[self.contentView addSubview:_applyBtn];
|
||||
@@ -41,14 +41,14 @@
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
self.title = @"皮肤中心";
|
||||
self.title = KBLocalized(@"皮肤中心");
|
||||
self.view.backgroundColor = [UIColor whiteColor];
|
||||
// 绝对 URL 的测试皮肤图片(无需 KB_BASE_URL)。
|
||||
// 说明:使用 picsum.photos 的固定 id,稳定可直接访问。
|
||||
self.skins = @[
|
||||
@{ @"id": @"aurora", @"name": @"极光", @"img": @"https://picsum.photos/id/1018/1600/900.jpg" },
|
||||
@{ @"id": @"alps", @"name": @"雪山", @"img": @"https://picsum.photos/id/1016/1600/900.jpg" },
|
||||
@{ @"id": @"lake", @"name": @"湖面", @"img": @"https://picsum.photos/id/1039/1600/900.jpg" },
|
||||
@{ @"id": @"aurora", @"name": KBLocalized(@"极光"), @"img": @"https://picsum.photos/id/1018/1600/900.jpg" },
|
||||
@{ @"id": @"alps", @"name": KBLocalized(@"雪山"), @"img": @"https://picsum.photos/id/1016/1600/900.jpg" },
|
||||
@{ @"id": @"lake", @"name": KBLocalized(@"湖面"), @"img": @"https://picsum.photos/id/1039/1600/900.jpg" },
|
||||
];
|
||||
|
||||
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleInsetGrouped];
|
||||
@@ -124,7 +124,7 @@
|
||||
payload = UIImageJPEGRepresentation(img, 0.9);
|
||||
}
|
||||
BOOL ok = (payload.length > 0) ? [[KBSkinManager shared] applyImageSkinWithData:payload skinId:skin[@"id"] name:skin[@"name"]] : NO;
|
||||
[KBHUD showInfo:(ok ? @"已应用,切到键盘查看" : @"应用失败")];
|
||||
[KBHUD showInfo:(ok ? KBLocalized(@"已应用,切到键盘查看") : KBLocalized(@"应用失败"))];
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
self.tableView.tableHeaderView = header;
|
||||
[self.view addSubview:self.tableView];
|
||||
|
||||
self.items = @[ KBLocalized(@"home_item_lang_test"), KBLocalized(@"home_item_keyboard_permission"), @"皮肤中心" ];
|
||||
self.items = @[ KBLocalized(@"home_item_lang_test"), KBLocalized(@"home_item_keyboard_permission"), KBLocalized(@"皮肤中心") ];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{ [self.textView becomeFirstResponder]; });
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
- (void)viewWillAppear:(BOOL)animated{
|
||||
[super viewWillAppear:animated];
|
||||
self.title = KBLocalized(@"home_title");
|
||||
self.items = @[ KBLocalized(@"home_item_lang_test"), KBLocalized(@"home_item_keyboard_permission"), @"皮肤中心" ];
|
||||
self.items = @[ KBLocalized(@"home_item_lang_test"), KBLocalized(@"home_item_keyboard_permission"), KBLocalized(@"皮肤中心") ];
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,12 @@
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
self.view.backgroundColor = [UIColor clearColor];
|
||||
self.titles = @[@"螃蟹啊斯柯达积分卡", @"小龙虾", @"苹果", @"胡萝卜", @"葡萄", @"西瓜"];
|
||||
self.titles = @[KBLocalized(@"螃蟹啊斯柯达积分卡"),
|
||||
KBLocalized(@"小龙虾"),
|
||||
KBLocalized(@"苹果"),
|
||||
KBLocalized(@"胡萝卜"),
|
||||
KBLocalized(@"葡萄"),
|
||||
KBLocalized(@"西瓜")];
|
||||
[self.view addSubview:self.myCategoryView];
|
||||
[self.view addSubview:self.listContainerView];
|
||||
self.listContainerView.scrollView.scrollEnabled = false;
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
|
||||
// 两个按钮
|
||||
self.hotButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[self.hotButton setTitle:@"热门" forState:UIControlStateNormal];
|
||||
[self.hotButton setTitle:KBLocalized(@"热门") forState:UIControlStateNormal];
|
||||
[self.hotButton setTitleColor:[UIColor darkTextColor] forState:UIControlStateNormal];
|
||||
[self.hotButton setTitleColor:[UIColor blackColor] forState:UIControlStateSelected];
|
||||
self.hotButton.titleLabel.font = [UIFont boldSystemFontOfSize:16];
|
||||
@@ -146,7 +146,7 @@
|
||||
[self.topBar addSubview:self.hotButton];
|
||||
|
||||
self.rankButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[self.rankButton setTitle:@"排行" forState:UIControlStateNormal];
|
||||
[self.rankButton setTitle:KBLocalized(@"排行") forState:UIControlStateNormal];
|
||||
[self.rankButton setTitleColor:[UIColor darkTextColor] forState:UIControlStateNormal];
|
||||
[self.rankButton setTitleColor:[UIColor blackColor] forState:UIControlStateSelected];
|
||||
self.rankButton.titleLabel.font = [UIFont boldSystemFontOfSize:16];
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
}];
|
||||
} else {
|
||||
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
|
||||
[btn setTitle:@"需要 iOS13+ 才能使用 Apple 登录" forState:UIControlStateNormal];
|
||||
[btn setTitle:KBLocalized(@"需要 iOS13+ 才能使用 Apple 登录") forState:UIControlStateNormal];
|
||||
btn.enabled = NO;
|
||||
btn.layer.cornerRadius = 8.0;
|
||||
btn.layer.borderWidth = 1.0;
|
||||
@@ -100,7 +100,7 @@
|
||||
- (UILabel *)titleLabel {
|
||||
if (!_titleLabel) {
|
||||
_titleLabel = [UILabel new];
|
||||
_titleLabel.text = @"登录后可使用全部功能";
|
||||
_titleLabel.text = KBLocalized(@"Sign in to unlock all features");
|
||||
_titleLabel.font = [UIFont boldSystemFontOfSize:18];
|
||||
_titleLabel.textColor = [UIColor blackColor];
|
||||
_titleLabel.textAlignment = NSTextAlignmentCenter;
|
||||
@@ -112,7 +112,7 @@
|
||||
- (UILabel *)descLabel {
|
||||
if (!_descLabel) {
|
||||
_descLabel = [UILabel new];
|
||||
_descLabel.text = @"我们将使用 Apple 进行快速安全登录";
|
||||
_descLabel.text = KBLocalized(@"We'll use Apple for a quick, secure sign-in");
|
||||
_descLabel.font = [UIFont systemFontOfSize:14];
|
||||
_descLabel.textColor = [UIColor colorWithWhite:0.2 alpha:0.8];
|
||||
_descLabel.textAlignment = NSTextAlignmentCenter;
|
||||
@@ -140,4 +140,3 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
- (UILabel *)titleLabel {
|
||||
if (!_titleLabel) {
|
||||
_titleLabel = [UILabel new];
|
||||
_titleLabel.text = @"登录";
|
||||
_titleLabel.text = KBLocalized(@"Log In");
|
||||
_titleLabel.font = [UIFont boldSystemFontOfSize:24];
|
||||
_titleLabel.textAlignment = NSTextAlignmentCenter;
|
||||
}
|
||||
@@ -107,7 +107,7 @@
|
||||
- (UIButton *)compatHintButton {
|
||||
if (!_compatHintButton) {
|
||||
_compatHintButton = [UIButton buttonWithType:UIButtonTypeSystem];
|
||||
[_compatHintButton setTitle:@"需要 iOS13+ 才能使用 Apple 登录" forState:UIControlStateNormal];
|
||||
[_compatHintButton setTitle:KBLocalized(@"需要 iOS13+ 才能使用 Apple 登录") forState:UIControlStateNormal];
|
||||
_compatHintButton.enabled = NO;
|
||||
}
|
||||
return _compatHintButton;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
[[AppleSignInManager shared] signInFromViewController:presenter completion:^(ASAuthorizationAppleIDCredential * _Nullable credential, NSError * _Nullable error) {
|
||||
if (error) { if (completion) completion(NO, error); return; }
|
||||
if (![credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
|
||||
if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-1 userInfo:@{NSLocalizedDescriptionKey: @"无效的登录凭证"}]);
|
||||
if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-1 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"无效的登录凭证")}]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
self.currentUser = user;
|
||||
NSString *token = user.token ?: [self.class tokenFromResponseObject:jsonOrData];
|
||||
if (token.length == 0) {
|
||||
if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-2 userInfo:@{NSLocalizedDescriptionKey: @"未返回 token"}]);
|
||||
if (completion) completion(NO, [NSError errorWithDomain:@"KBLogin" code:-2 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"未返回 token")}]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
refreshToken:nil
|
||||
expiryDate:nil
|
||||
userIdentifier:cred.user];
|
||||
if (completion) completion(ok, ok ? nil : [NSError errorWithDomain:@"KBLogin" code:-3 userInfo:@{NSLocalizedDescriptionKey: @"保存登录态失败"}]);
|
||||
if (completion) completion(ok, ok ? nil : [NSError errorWithDomain:@"KBLogin" code:-3 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"保存登录态失败")}]);
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ static NSString * const kKBAppleUserIdentifierKey = @"com.company.keyboard.apple
|
||||
[controller performRequests];
|
||||
} else {
|
||||
if (completion) {
|
||||
NSError *err = [NSError errorWithDomain:@"AppleSignIn" code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Apple 登录需要 iOS 13 及以上版本"}];
|
||||
NSError *err = [NSError errorWithDomain:@"AppleSignIn" code:-1 userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Sign in with Apple requires iOS 13 or later")}];
|
||||
completion(nil, err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
- (UILabel *)titleLabel {
|
||||
if (!_titleLabel) {
|
||||
_titleLabel = [UILabel new];
|
||||
_titleLabel.text = @"Change The Nickname";
|
||||
_titleLabel.text = KBLocalized(@"Change The Nickname");
|
||||
_titleLabel.textColor = [UIColor blackColor];
|
||||
_titleLabel.font = [UIFont systemFontOfSize:22 weight:UIFontWeightBold];
|
||||
}
|
||||
@@ -141,7 +141,7 @@
|
||||
[_closeButton setTitleColor:[UIColor colorWithWhite:0.3 alpha:1] forState:UIControlStateNormal];
|
||||
_closeButton.tintColor = [UIColor colorWithWhite:0.3 alpha:1];
|
||||
[_closeButton addTarget:self action:@selector(onTapClose) forControlEvents:UIControlEventTouchUpInside];
|
||||
_closeButton.accessibilityLabel = @"关闭";
|
||||
_closeButton.accessibilityLabel = KBLocalized(@"Close");
|
||||
}
|
||||
return _closeButton;
|
||||
}
|
||||
@@ -161,7 +161,7 @@
|
||||
_textField.clearButtonMode = UITextFieldViewModeWhileEditing;
|
||||
_textField.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold];
|
||||
_textField.textColor = [UIColor blackColor];
|
||||
_textField.placeholder = @"Please Enter The Modified Nickname";
|
||||
_textField.placeholder = KBLocalized(@"Please Enter The Modified Nickname");
|
||||
}
|
||||
return _textField;
|
||||
}
|
||||
@@ -169,7 +169,7 @@
|
||||
- (UIButton *)saveButton {
|
||||
if (!_saveButton) {
|
||||
_saveButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_saveButton setTitle:@"Save" forState:UIControlStateNormal];
|
||||
[_saveButton setTitle:KBLocalized(@"Save") forState:UIControlStateNormal];
|
||||
[_saveButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
|
||||
_saveButton.titleLabel.font = [UIFont systemFontOfSize:20 weight:UIFontWeightSemibold];
|
||||
_saveButton.backgroundColor = [UIColor colorWithRed:0.02 green:0.75 blue:0.67 alpha:1.0];
|
||||
@@ -180,4 +180,3 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
_minusTapArea = [[UIControl alloc] init];
|
||||
_minusTapArea.backgroundColor = [UIColor clearColor];
|
||||
// 提高命中率:即使轻微偏离也能点中
|
||||
_minusTapArea.accessibilityLabel = @"删除";
|
||||
_minusTapArea.accessibilityLabel = KBLocalized(@"Delete");
|
||||
}
|
||||
return _minusTapArea;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
}];
|
||||
[self.coverView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.left.right.equalTo(self.cardView);
|
||||
make.height.equalTo(self.cardView.mas_width).multipliedBy(0.66); // 接近截图比例
|
||||
make.height.mas_equalTo(KBFit(126));
|
||||
}];
|
||||
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.equalTo(self.cardView).offset(12);
|
||||
|
||||
@@ -163,23 +163,10 @@ static NSString * const kKBMyKeyboardCellId = @"kKBMyKeyboardCellId";
|
||||
if (!self) { return; }
|
||||
NSIndexPath *tapIndexPath = [weakCV indexPathForCell:tappedCell];
|
||||
if (!tapIndexPath) { return; }
|
||||
// [KBAlert confirmTitle:@"删除该标签?" message:@"删除后不可恢复" completion:^(BOOL ok) {
|
||||
// if (!ok) { return; }
|
||||
// // 更新数据源并删除 item
|
||||
// if (tapIndexPath.section < self.dataSourceArray.count) {
|
||||
// NSMutableArray *section = self.dataSourceArray[tapIndexPath.section];
|
||||
// if (tapIndexPath.item < section.count) {
|
||||
// [section removeObjectAtIndex:tapIndexPath.item];
|
||||
// [self.collectionView performBatchUpdates:^{
|
||||
// [self.collectionView deleteItemsAtIndexPaths:@[tapIndexPath]];
|
||||
// } completion:nil];
|
||||
// }
|
||||
// }
|
||||
// }];
|
||||
[KBAlert confirmTitle:@"删除该标签?"
|
||||
message:@"删除后不可恢复"
|
||||
ok:@"确定"
|
||||
cancel:@"取消"
|
||||
[KBAlert confirmTitle:KBLocalized(@"Delete this tag?")
|
||||
message:KBLocalized(@"This action cannot be undone")
|
||||
ok:KBLocalized(@"Confirm")
|
||||
cancel:KBLocalized(@"Cancel")
|
||||
okColor:[UIColor redColor]
|
||||
cancelColor:[UIColor blackColor]
|
||||
completion:^(BOOL ok) {
|
||||
@@ -229,7 +216,7 @@ static NSString * const kKBMyKeyboardCellId = @"kKBMyKeyboardCellId";
|
||||
- (void)onSave {
|
||||
// 这里只做示意:保存当前顺序
|
||||
NSLog(@"保存顺序: %@", self.dataSourceArray);
|
||||
[KBHUD showInfo:@"已保存"];
|
||||
[KBHUD showInfo:KBLocalized(@"Saved")];
|
||||
}
|
||||
|
||||
#pragma mark - Lazy UI
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
NSString *userID = self.items[2][@"value"];
|
||||
if (userID.length == 0) return;
|
||||
UIPasteboard.generalPasteboard.string = userID;
|
||||
[KBHUD showInfo:@"复制成功"];
|
||||
[KBHUD showInfo:KBLocalized(@"Copy Success")];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,11 +55,8 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) {
|
||||
make.left.equalTo(self.view).offset(15);
|
||||
make.right.equalTo(self.view).offset(-15);
|
||||
make.height.mas_equalTo([KBSkinBottomActionView preferredHeight]);
|
||||
if (@available(iOS 11.0, *)) {
|
||||
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom);
|
||||
} else {
|
||||
make.bottom.equalTo(self.view);
|
||||
}
|
||||
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-10);
|
||||
|
||||
}];
|
||||
|
||||
// 列表底部距离操作条顶部 10
|
||||
|
||||
@@ -61,9 +61,9 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
|
||||
// 空态视图(LYEmptyView)统一样式 + 重试按钮
|
||||
KBWeakSelf
|
||||
[self.collectionView kb_makeDefaultEmptyViewWithImage:nil
|
||||
title:@"暂无皮肤"
|
||||
detail:@"下拉刷新试试"
|
||||
buttonTitle:@"重试"
|
||||
title:KBLocalized(@"No skins yet")
|
||||
detail:KBLocalized(@"Pull down to refresh")
|
||||
buttonTitle:KBLocalized(@"Retry")
|
||||
tapHandler:nil
|
||||
buttonHandler:^{ [weakSelf.collectionView.mj_header beginRefreshing]; }];
|
||||
[self.collectionView kb_setLYAutoShowEnabled:NO]; // 采用手动控制显隐
|
||||
@@ -224,7 +224,7 @@ static NSString * const kMySkinCellId = @"kMySkinCellId";
|
||||
CGFloat spacing = 12;
|
||||
CGFloat W = UIScreen.mainScreen.bounds.size.width;
|
||||
CGFloat itemW = floor((W - inset * 2 - spacing) / 2.0);
|
||||
CGFloat itemH = itemW * 0.82f; // 接近截图比例
|
||||
CGFloat itemH = KBFit(168); // 接近截图比例
|
||||
layout.itemSize = CGSizeMake(itemW, itemH);
|
||||
layout.minimumInteritemSpacing = spacing;
|
||||
layout.minimumLineSpacing = spacing;
|
||||
|
||||
@@ -62,7 +62,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
|
||||
parameters:parameters
|
||||
error:&serror];
|
||||
if (serror || !req) {
|
||||
if (completion) completion(nil, nil, serror ?: [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey: @"无效的URL"}]);
|
||||
if (completion) completion(nil, nil, serror ?: [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Invalid URL")}]);
|
||||
return nil;
|
||||
}
|
||||
[self applyHeaders:headers toMutableRequest:req contentType:nil];
|
||||
@@ -109,7 +109,7 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
|
||||
|
||||
- (BOOL)ensureEnabled:(KBNetworkCompletion)completion {
|
||||
if (!self.isEnabled) {
|
||||
NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDisabled userInfo:@{NSLocalizedDescriptionKey: @"网络未启用(可能未开启完全访问)"}];
|
||||
NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDisabled userInfo:@{NSLocalizedDescriptionKey: KBLocalized(@"Network disabled (Full Access may be off)")}];
|
||||
if (completion) completion(nil, nil, e);
|
||||
return NO;
|
||||
}
|
||||
@@ -162,12 +162,12 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
|
||||
}
|
||||
NSData *data = (NSData *)responseObject;
|
||||
if (![data isKindOfClass:[NSData class]]) {
|
||||
#if DEBUG
|
||||
KBLOG(@"无效响应\nURL: %@\n说明: %@", req.URL.absoluteString, @"未获取到数据");
|
||||
#endif
|
||||
if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidResponse userInfo:@{NSLocalizedDescriptionKey:@"无数据"}]);
|
||||
return;
|
||||
}
|
||||
#if DEBUG
|
||||
KBLOG(@"无效响应\nURL: %@\n说明: %@", req.URL.absoluteString, KBLocalized(@"未获取到数据"));
|
||||
#endif
|
||||
if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorInvalidResponse userInfo:@{NSLocalizedDescriptionKey:KBLocalized(@"No data")}]);
|
||||
return;
|
||||
}
|
||||
NSString *ct = nil;
|
||||
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
|
||||
ct = ((NSHTTPURLResponse *)response).allHeaderFields[@"Content-Type"];
|
||||
@@ -189,12 +189,12 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
|
||||
NSError *jsonErr = nil;
|
||||
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonErr];
|
||||
if (jsonErr) {
|
||||
#if DEBUG
|
||||
#if DEBUG
|
||||
KBLOG(@"响应解析失败(JSON)\nURL: %@\n错误: %@",
|
||||
req.URL.absoluteString,
|
||||
jsonErr.localizedDescription);
|
||||
#endif
|
||||
if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDecodeFailed userInfo:@{NSLocalizedDescriptionKey:@"JSON解析失败"}]);
|
||||
#endif
|
||||
if (completion) completion(nil, response, [NSError errorWithDomain:KBNetworkErrorDomain code:KBNetworkErrorDecodeFailed userInfo:@{NSLocalizedDescriptionKey:KBLocalized(@"Failed to parse JSON")}]);
|
||||
return;
|
||||
}
|
||||
#if DEBUG
|
||||
@@ -243,20 +243,20 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
|
||||
|
||||
#pragma mark - Private helpers
|
||||
|
||||
- (void)fail:(KBNetworkError)code completion:(KBNetworkCompletion)completion {
|
||||
NSString *msg = @"网络错误";
|
||||
switch (code) {
|
||||
case KBNetworkErrorDisabled: msg = @"网络未启用(可能未开启完全访问)"; break;
|
||||
case KBNetworkErrorInvalidURL: msg = @"无效的URL"; break;
|
||||
case KBNetworkErrorInvalidResponse: msg = @"无效的响应"; break;
|
||||
case KBNetworkErrorDecodeFailed: msg = @"解析失败"; break;
|
||||
default: break;
|
||||
- (void)fail:(KBNetworkError)code completion:(KBNetworkCompletion)completion {
|
||||
NSString *msg = KBLocalized(@"Network error");
|
||||
switch (code) {
|
||||
case KBNetworkErrorDisabled: msg = KBLocalized(@"Network disabled (Full Access may be off)"); break;
|
||||
case KBNetworkErrorInvalidURL: msg = KBLocalized(@"Invalid URL"); break;
|
||||
case KBNetworkErrorInvalidResponse: msg = KBLocalized(@"Invalid response"); break;
|
||||
case KBNetworkErrorDecodeFailed: msg = KBLocalized(@"Parse failed"); break;
|
||||
default: break;
|
||||
}
|
||||
NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain
|
||||
code:code
|
||||
userInfo:@{NSLocalizedDescriptionKey: msg}];
|
||||
if (completion) completion(nil, nil, e);
|
||||
}
|
||||
NSError *e = [NSError errorWithDomain:KBNetworkErrorDomain
|
||||
code:code
|
||||
userInfo:@{NSLocalizedDescriptionKey: msg}];
|
||||
if (completion) completion(nil, nil, e);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -42,12 +42,12 @@
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[self.payVM applePayReqWithParams:params needShow:NO completion:^(NSInteger sta, NSString * _Nullable msg) {
|
||||
[KBHUD dismiss];
|
||||
[KBHUD showInfo:(sta == ERROR_CODE ? @"支付失败" : @"支付成功")];
|
||||
[KBHUD showInfo:(sta == ERROR_CODE ? KBLocalized(@"Payment failed") : KBLocalized(@"Payment successful"))];
|
||||
if (sta == SUCCESS_CODE) {
|
||||
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
|
||||
if (handler) handler(@"成功", nil);
|
||||
if (handler) handler(KBLocalized(@"Success"), nil);
|
||||
} else {
|
||||
if (handler) handler(@"失败", nil);
|
||||
if (handler) handler(KBLocalized(@"Failed"), nil);
|
||||
}
|
||||
(void)weakSelf; // keep self during block life if needed
|
||||
}];
|
||||
@@ -68,4 +68,3 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ static NSString * const kKBJfPayCellId = @"kKBJfPayCellId";
|
||||
}
|
||||
|
||||
- (void)agreementButtonAction{
|
||||
[KBHUD showInfo:@"跳转协议"];
|
||||
[KBHUD showInfo:KBLocalized(@"Open agreement")];
|
||||
}
|
||||
|
||||
#pragma mark - Lazy UI
|
||||
|
||||
@@ -127,10 +127,10 @@ static NSString * const kKBVipReviewListCellId = @"kKBVipReviewListCellId";
|
||||
#pragma mark - Bottom Actions
|
||||
- (void)onTapPayButton {
|
||||
// TODO: 接入支付,这里仅做 UI
|
||||
[KBHUD showInfo:@"Pay clicked"];
|
||||
[KBHUD showInfo:KBLocalized(@"Pay clicked")];
|
||||
}
|
||||
- (void)agreementButtonAction{
|
||||
[KBHUD showInfo:@"跳转协议"];
|
||||
[KBHUD showInfo:KBLocalized(@"Open agreement")];
|
||||
}
|
||||
|
||||
#pragma mark - UICollectionView DataSource
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
if (needShow) { [KBHUD dismiss]; }
|
||||
|
||||
if (error) {
|
||||
if (completion) completion(ERROR_CODE, error.localizedDescription ?: @"网络错误");
|
||||
if (completion) completion(ERROR_CODE, error.localizedDescription ?: KBLocalized(@"Network error"));
|
||||
return;
|
||||
}
|
||||
|
||||
NSInteger sta = [self.class extractStatusFromResponseObject:jsonOrData response:response];
|
||||
NSString *msg = [self.class extractMessageFromResponseObject:jsonOrData] ?: (sta == SUCCESS_CODE ? @"OK" : @"失败");
|
||||
NSString *msg = [self.class extractMessageFromResponseObject:jsonOrData] ?: (sta == SUCCESS_CODE ? @"OK" : KBLocalized(@"Failed"));
|
||||
if (completion) completion(sta, msg);
|
||||
}];
|
||||
}
|
||||
@@ -62,4 +62,3 @@
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -44,10 +44,10 @@
|
||||
- (void)tapTrash {
|
||||
// 弹出确认框:是否删除所有历史记录
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[KBAlert confirmTitle:@"清空历史"
|
||||
message:@"是否删除所有历史记录?"
|
||||
ok:@"确定"
|
||||
cancel:@"取消"
|
||||
[KBAlert confirmTitle:KBLocalized(@"Clear history")
|
||||
message:KBLocalized(@"Delete all history?")
|
||||
ok:KBLocalized(@"Confirm")
|
||||
cancel:KBLocalized(@"Cancel")
|
||||
okColor:weakSelf.confirmColor
|
||||
cancelColor:weakSelf.cancelColor
|
||||
completion:^(BOOL ok) {
|
||||
|
||||
@@ -83,7 +83,12 @@ typedef NS_ENUM(NSInteger, KBSearchSection) {
|
||||
}];
|
||||
|
||||
// 初始化测试数据
|
||||
self.historyWords = [@[@"果冻橙", @"芒果", @"有机水果卷心菜", @"水果萝卜", @"熟冻帝王蟹", @"赣南脐橙"] mutableCopy];
|
||||
self.historyWords = [@[KBLocalized(@"果冻橙"),
|
||||
KBLocalized(@"芒果"),
|
||||
KBLocalized(@"有机水果卷心菜"),
|
||||
KBLocalized(@"水果萝卜"),
|
||||
KBLocalized(@"熟冻帝王蟹"),
|
||||
KBLocalized(@"赣南脐橙")] mutableCopy];
|
||||
self.recommendItems = @[
|
||||
@{@"title":@"Dopamine", @"price":@"20"},
|
||||
@{@"title":@"Dopamine", @"price":@"20"},
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
if (self.isNeedFooter) {
|
||||
self.collectionView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[weakSelf.dataSource addObject:@"加载更多成功"]; // 模拟新增一条
|
||||
[weakSelf.dataSource addObject:KBLocalized(@"Loaded more successfully")]; // 模拟新增一条
|
||||
[weakSelf.collectionView reloadData];
|
||||
[weakSelf.collectionView.mj_footer endRefreshing];
|
||||
});
|
||||
|
||||
@@ -76,7 +76,10 @@ static const CGFloat JXheightForHeaderInSection = 50;
|
||||
self.view.backgroundColor = [UIColor whiteColor];
|
||||
self.navigationController.navigationBar.translucent = false;
|
||||
self.edgesForExtendedLayout = UIRectEdgeNone;
|
||||
_titles = @[@"能力", @"爱好", @"队友",@"能力2", @"爱好2", @"队友2",@"能力", @"爱好", @"队友",@"能力2", @"爱好2", @"队友2"];
|
||||
_titles = @[KBLocalized(@"能力"), KBLocalized(@"爱好"), KBLocalized(@"队友"),
|
||||
KBLocalized(@"能力2"), KBLocalized(@"爱好2"), KBLocalized(@"队友2"),
|
||||
KBLocalized(@"能力"), KBLocalized(@"爱好"), KBLocalized(@"队友"),
|
||||
KBLocalized(@"能力2"), KBLocalized(@"爱好2"), KBLocalized(@"队友2")];
|
||||
|
||||
_userHeaderView = [[KBShopHeadView alloc] init];
|
||||
_categoryView = (JXCategoryTitleView *)[[KBCategoryTitleView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, JXheightForHeaderInSection)];
|
||||
@@ -130,8 +133,8 @@ static const CGFloat JXheightForHeaderInSection = 50;
|
||||
|
||||
__weak typeof(self)weakSelf = self;
|
||||
self.pagerView.mainTableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
self.categoryView.titles = @[@"高级能力", @"高级爱好", @"高级队友"];
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
self.categoryView.titles = @[KBLocalized(@"高级能力"), KBLocalized(@"高级爱好"), KBLocalized(@"高级队友")];
|
||||
self.categoryView.defaultSelectedIndex = 0;
|
||||
[self.categoryView reloadData];
|
||||
[self.pagerView reloadData];
|
||||
@@ -147,7 +150,7 @@ static const CGFloat JXheightForHeaderInSection = 50;
|
||||
self.naviBGView.frame = CGRectMake(0, 0, KB_SCREEN_WIDTH, KB_NAV_TOTAL_HEIGHT);
|
||||
[self.view addSubview:self.naviBGView];
|
||||
UILabel *naviTitleLabel = [[UILabel alloc] init];
|
||||
naviTitleLabel.text = @"商城";
|
||||
naviTitleLabel.text = KBLocalized(@"商城");
|
||||
naviTitleLabel.textAlignment = NSTextAlignmentCenter;
|
||||
naviTitleLabel.frame = CGRectMake(0, KB_STATUSBAR_HEIGHT, self.view.bounds.size.width, 44);
|
||||
[self.naviBGView addSubview:naviTitleLabel];
|
||||
@@ -192,11 +195,18 @@ static const CGFloat JXheightForHeaderInSection = 50;
|
||||
list.isNeedHeader = self.isNeedHeader;
|
||||
list.isNeedFooter = self.isNeedFooter;
|
||||
if (index == 0) {
|
||||
list.dataSource = @[@"橡胶火箭", @"橡胶火箭炮", @"橡胶机关枪", @"橡胶子弹", @"橡胶攻城炮", @"橡胶象枪", @"橡胶象枪乱打", @"橡胶灰熊铳", @"橡胶雷神象枪", @"橡胶猿王枪", @"橡胶犀·榴弹炮", @"橡胶大蛇炮", @"橡胶火箭", @"橡胶火箭炮", @"橡胶机关枪", @"橡胶子弹", @"橡胶攻城炮", @"橡胶象枪", @"橡胶象枪乱打", @"橡胶灰熊铳", @"橡胶雷神象枪", @"橡胶猿王枪", @"橡胶犀·榴弹炮", @"橡胶大蛇炮"].mutableCopy;
|
||||
list.dataSource = @[KBLocalized(@"橡胶火箭"), KBLocalized(@"橡胶火箭炮"), KBLocalized(@"橡胶机关枪"), KBLocalized(@"橡胶子弹"),
|
||||
KBLocalized(@"橡胶攻城炮"), KBLocalized(@"橡胶象枪"), KBLocalized(@"橡胶象枪乱打"), KBLocalized(@"橡胶灰熊铳"),
|
||||
KBLocalized(@"橡胶雷神象枪"), KBLocalized(@"橡胶猿王枪"), KBLocalized(@"橡胶犀·榴弹炮"), KBLocalized(@"橡胶大蛇炮"),
|
||||
KBLocalized(@"橡胶火箭"), KBLocalized(@"橡胶火箭炮"), KBLocalized(@"橡胶机关枪"), KBLocalized(@"橡胶子弹"),
|
||||
KBLocalized(@"橡胶攻城炮"), KBLocalized(@"橡胶象枪"), KBLocalized(@"橡胶象枪乱打"), KBLocalized(@"橡胶灰熊铳"),
|
||||
KBLocalized(@"橡胶雷神象枪"), KBLocalized(@"橡胶猿王枪"), KBLocalized(@"橡胶犀·榴弹炮"), KBLocalized(@"橡胶大蛇炮")].mutableCopy;
|
||||
}else if (index == 1) {
|
||||
list.dataSource = @[@"吃烤肉", @"吃鸡腿肉", @"吃牛肉", @"各种肉"].mutableCopy;
|
||||
list.dataSource = @[KBLocalized(@"吃烤肉"), KBLocalized(@"吃鸡腿肉"), KBLocalized(@"吃牛肉"), KBLocalized(@"各种肉")].mutableCopy;
|
||||
}else {
|
||||
list.dataSource = @[@"【剑士】罗罗诺亚·索隆", @"【航海士】娜美", @"【狙击手】乌索普", @"【厨师】香吉士", @"【船医】托尼托尼·乔巴", @"【船匠】 弗兰奇", @"【音乐家】布鲁克", @"【考古学家】妮可·罗宾"].mutableCopy;
|
||||
list.dataSource = @[KBLocalized(@"【剑士】罗罗诺亚·索隆"), KBLocalized(@"【航海士】娜美"), KBLocalized(@"【狙击手】乌索普"),
|
||||
KBLocalized(@"【厨师】香吉士"), KBLocalized(@"【船医】托尼托尼·乔巴"), KBLocalized(@"【船匠】 弗兰奇"),
|
||||
KBLocalized(@"【音乐家】布鲁克"), KBLocalized(@"【考古学家】妮可·罗宾")].mutableCopy;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
- (void)setupTextField {
|
||||
CGRect frame = CGRectMake(([UIScreen mainScreen].bounds.size.width - 200)/2, ([UIScreen mainScreen].bounds.size.height - 200)/2, 200, 200);
|
||||
self.textView = [[UITextView alloc] initWithFrame:frame];
|
||||
self.textView.text = @"测试";
|
||||
self.textView.text = KBLocalized(@"测试");
|
||||
self.textView.layer.borderColor = [UIColor blackColor].CGColor;
|
||||
self.textView.layer.borderWidth = 0.5;
|
||||
[self.view addSubview:self.textView];
|
||||
|
||||
Reference in New Issue
Block a user