Compare commits
7 Commits
a83fd918a8
...
635ad932c7
| Author | SHA1 | Date | |
|---|---|---|---|
| 635ad932c7 | |||
| cbe0a53cac | |||
| 5c273c3963 | |||
| c9743cb363 | |||
| f0cb69948e | |||
| 0144f9cc6d | |||
| ae4070ae88 |
@@ -102,6 +102,7 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
||||
@property(nonatomic, strong) NSMutableArray<KBChatMessage *> *chatMessages;
|
||||
@property(nonatomic, strong) AVAudioPlayer *chatAudioPlayer;
|
||||
@property(nonatomic, assign) BOOL chatPanelVisible;
|
||||
@property(nonatomic, copy) NSString *chatPanelBaselineText; // 打开聊天面板时宿主输入框已有的文本
|
||||
@property(nonatomic, strong, nullable) id kb_fullAccessObserverToken;
|
||||
@property(nonatomic, strong, nullable) id kb_skinObserverToken;
|
||||
@end
|
||||
@@ -563,6 +564,9 @@ static NSString *KBFormatMB(uint64_t bytes) {
|
||||
}
|
||||
self.chatPanelVisible = show;
|
||||
if (show) {
|
||||
// 记录打开聊天面板时宿主输入框已有的文本,发送时只取新增部分
|
||||
[[KBInputBufferManager shared] refreshFromProxyIfPossible:self.textDocumentProxy];
|
||||
self.chatPanelBaselineText = [KBInputBufferManager shared].liveText ?: @"";
|
||||
[self kb_ensureChatPanelViewIfNeeded];
|
||||
self.chatPanelView.hidden = NO;
|
||||
self.chatPanelView.alpha = 0.0;
|
||||
@@ -1033,7 +1037,15 @@ static NSString *KBFormatMB(uint64_t bytes) {
|
||||
return;
|
||||
}
|
||||
[[KBInputBufferManager shared] refreshFromProxyIfPossible:self.textDocumentProxy];
|
||||
NSString *rawText = [KBInputBufferManager shared].liveText ?: @"";
|
||||
NSString *fullText = [KBInputBufferManager shared].liveText ?: @"";
|
||||
|
||||
// 去掉打开聊天面板前宿主输入框里已有的基线文本,只取新增部分
|
||||
NSString *baseline = self.chatPanelBaselineText ?: @"";
|
||||
NSString *rawText = fullText;
|
||||
if (baseline.length > 0 && [fullText hasPrefix:baseline]) {
|
||||
rawText = [fullText substringFromIndex:baseline.length];
|
||||
}
|
||||
|
||||
NSString *trim =
|
||||
[rawText stringByTrimmingCharactersInSet:
|
||||
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
@@ -1042,6 +1054,7 @@ static NSString *KBFormatMB(uint64_t bytes) {
|
||||
return;
|
||||
}
|
||||
[self kb_sendChatText:trim];
|
||||
// 只清除新增的文本,保留基线文本
|
||||
[self kb_clearHostInputForText:rawText];
|
||||
}
|
||||
|
||||
|
||||
@@ -140,6 +140,10 @@
|
||||
"Nickname" = "Nickname";
|
||||
"Gender" = "Gender";
|
||||
"User ID" = "User ID";
|
||||
"Modify Gender" = "Modify Gender";
|
||||
"Male" = "Male";
|
||||
"Female" = "Female";
|
||||
"The Third Gender" = "The Third Gender";
|
||||
|
||||
" Paste Ta's Words" = " Paste Ta's Words";
|
||||
|
||||
@@ -192,10 +196,6 @@
|
||||
"测试" = "Test";
|
||||
"这里是设置内容占位" = "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";
|
||||
|
||||
@@ -103,7 +103,6 @@
|
||||
"Please check this app's wireless-data permission or network connection in Settings." = "请在“设置”中检查本应用的无线数据权限或网络连接。";
|
||||
|
||||
// 权限与引导(英文 key)
|
||||
"Usage Guide" = "使用引导";
|
||||
"Turn on Allow Full Access to experience all features" = "开启【允许完全访问】,体验完整功能";
|
||||
"Allow Full Access" = "允许完全访问";
|
||||
"Follow: Settings → General → Keyboard → Keyboards → %@ → Allow Full Access" = "请按路径:设置→通用→键盘→键盘→%@→允许完全访问";
|
||||
@@ -142,6 +141,10 @@
|
||||
"Nickname" = "用户名";
|
||||
"Gender" = "性别";
|
||||
"User ID" = "用户ID";
|
||||
"Modify Gender" = "修改性别";
|
||||
"Male" = "男";
|
||||
"Female" = "女";
|
||||
"The Third Gender" = "第三性别";
|
||||
|
||||
" Paste Ta's Words" = " 粘贴TA的话";
|
||||
|
||||
@@ -195,10 +198,6 @@
|
||||
"Test" = "测试";
|
||||
"暂无数据" = "暂无数据"; // 已有英文 key "No data"
|
||||
"Settings" = "设置";
|
||||
"Usage Guide" = "使用引导";
|
||||
"螃蟹啊斯柯达积分卡" = "螃蟹啊斯柯达积分卡";
|
||||
"❎不是自己的键盘" = "❎不是自己的键盘";
|
||||
"是自己的键盘" = "是自己的键盘";
|
||||
|
||||
|
||||
"Change The Nickname" = "修改名称";
|
||||
|
||||
22
keyBoard/Assets.xcassets/My/my_svip_icon.imageset/Contents.json
vendored
Normal file
22
keyBoard/Assets.xcassets/My/my_svip_icon.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "my_svip_icon@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "my_svip_icon@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
keyBoard/Assets.xcassets/My/my_svip_icon.imageset/my_svip_icon@2x.png
vendored
Normal file
BIN
keyBoard/Assets.xcassets/My/my_svip_icon.imageset/my_svip_icon@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
BIN
keyBoard/Assets.xcassets/My/my_svip_icon.imageset/my_svip_icon@3x.png
vendored
Normal file
BIN
keyBoard/Assets.xcassets/My/my_svip_icon.imageset/my_svip_icon@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -308,6 +308,12 @@ static NSString * const KBAISelectedPersonaIdKey = @"KBAISelectedPersonaId";
|
||||
if (weakSelf.currentPage == 1) {
|
||||
[weakSelf.collectionView reloadData];
|
||||
[weakSelf preloadDataForIndexes:@[@0, @1, @2]];
|
||||
// 首次加载完成后,主动保存默认 persona 到 AppGroup,
|
||||
// 避免用户未滑动时键盘扩展拿不到数据
|
||||
if (weakSelf.personas.count > 0) {
|
||||
NSInteger index = MIN(MAX(weakSelf.currentIndex, 0), weakSelf.personas.count - 1);
|
||||
[weakSelf saveSelectedPersonaToAppGroup:weakSelf.personas[index]];
|
||||
}
|
||||
} else if (pageModel.records.count > 0) {
|
||||
NSInteger newCount = weakSelf.personas.count;
|
||||
NSMutableArray<NSIndexPath *> *indexPaths = [NSMutableArray array];
|
||||
|
||||
@@ -99,9 +99,8 @@
|
||||
- (void)buttonTapped:(UIButton *)button {
|
||||
NSInteger index = button.tag;
|
||||
if (index != self.selectedIndex) {
|
||||
self.selectedIndex = index;
|
||||
[self updateButtonStates];
|
||||
|
||||
// 先通知 delegate,由 delegate 决定是否允许切换(如登录拦截)
|
||||
// delegate 允许时会主动调用 setSelectedIndex: 来更新状态
|
||||
if ([self.delegate respondsToSelector:@selector(customTabBar:
|
||||
didSelectItemAtIndex:)]) {
|
||||
[self.delegate customTabBar:self didSelectItemAtIndex:index];
|
||||
|
||||
@@ -154,12 +154,15 @@
|
||||
|
||||
- (void)customTabBar:(KBCustomTabBar *)tabBar
|
||||
didSelectItemAtIndex:(NSInteger)index {
|
||||
// 登录检查
|
||||
if ((index == 1 || index == 2) && ![KBUserSessionManager shared].isLoggedIn) {
|
||||
// 登录检查:未登录时跳登录页,不切换 Tab,不更新选中状态
|
||||
if ((index == 1 || index == 2 || index == 3) && ![KBUserSessionManager shared].isLoggedIn) {
|
||||
[[KBUserSessionManager shared] goLoginVC];
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新自定义 TabBar 的选中状态
|
||||
[self.customTabBar setSelectedIndex:index];
|
||||
|
||||
// 切换 VC
|
||||
self.selectedIndex = index;
|
||||
|
||||
|
||||
@@ -212,6 +212,7 @@
|
||||
// }
|
||||
// }];
|
||||
[[KBNetworkManager shared] POST:API_CHARACTER_ADD_USER_CHARACTER jsonBody:params headers:nil autoShowBusinessError:true completion:^(NSDictionary * _Nullable json, NSURLResponse * _Nullable response, NSError * _Nullable error) {
|
||||
[KBHUD dismiss];
|
||||
if (!error) {
|
||||
[self refreshUserCharacterCacheForKeyboard];
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@ typedef NS_ENUM(NSInteger, UserSex) {
|
||||
/// 是否是 VIP
|
||||
@property (nonatomic, assign) BOOL isVip;
|
||||
|
||||
/// 1: vip 2:svip
|
||||
@property (nonatomic, assign) NSInteger vipLevel;
|
||||
|
||||
// token
|
||||
@property (nonatomic, copy, nullable) NSString *token; // token/access_token/accessToken
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
- (UILabel *)titleLabel {
|
||||
if (!_titleLabel) {
|
||||
_titleLabel = [UILabel new];
|
||||
_titleLabel.text = @"Modify Gender";
|
||||
_titleLabel.text = KBLocalized(@"Modify Gender");
|
||||
_titleLabel.textColor = [UIColor blackColor];
|
||||
_titleLabel.font = [KBFont medium:16];
|
||||
}
|
||||
@@ -226,7 +226,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 = [KBFont medium:16];
|
||||
_saveButton.backgroundColor = [UIColor colorWithRed:0.02 green:0.75 blue:0.67 alpha:1.0];
|
||||
|
||||
@@ -136,9 +136,17 @@
|
||||
[self kb_applyVipLayout:isVip];
|
||||
self.vipIconView.hidden = !isVip;
|
||||
self.vipExpiryLabel.hidden = !isVip;
|
||||
if (isVip) {
|
||||
self.vipIconView.image = [UIImage imageNamed:[self kb_vipIconNameFromVipLevel:user.vipLevel]];
|
||||
}
|
||||
self.vipExpiryLabel.text = isVip ? [self vipExpiryDisplayTextFrom:user.vipExpiry] : nil;
|
||||
}
|
||||
|
||||
- (NSString *)kb_vipIconNameFromVipLevel:(NSInteger)vipLevel {
|
||||
if (vipLevel == 2) { return @"my_svip_icon"; }
|
||||
return @"my_vip_icon";
|
||||
}
|
||||
|
||||
- (void)kb_applyVipLayout:(BOOL)isVip {
|
||||
NSInteger state = isVip ? 1 : 0;
|
||||
if (self.kb_vipLayoutState == state) { return; }
|
||||
|
||||
@@ -576,8 +576,11 @@ autoShowBusinessError:YES
|
||||
if (!_manager) {
|
||||
NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration ephemeralSessionConfiguration];
|
||||
cfg.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
|
||||
cfg.timeoutIntervalForRequest = self.timeout; // 单次请求超时
|
||||
cfg.timeoutIntervalForResource = 60.0; // 整个资源传输最大 60s
|
||||
|
||||
// 不在会话级别设置超时,避免与 per-request 的 serializer.timeoutInterval 产生不一致
|
||||
if (@available(iOS 11.0, *)) { cfg.waitsForConnectivity = YES; }
|
||||
// if (@available(iOS 11.0, *)) { cfg.waitsForConnectivity = YES; }
|
||||
_manager = [[AFHTTPSessionManager alloc] initWithBaseURL:nil sessionConfiguration:cfg];
|
||||
// 默认不使用 JSON 解析器,保持原生数据,再按需解析
|
||||
_manager.responseSerializer = [AFHTTPResponseSerializer serializer];
|
||||
|
||||
Reference in New Issue
Block a user