This commit is contained in:
2026-01-09 19:13:35 +08:00
parent ef332ecaa1
commit 1b6724f043
10 changed files with 978 additions and 756 deletions

View File

@@ -8,23 +8,26 @@
#import "KeyboardViewController.h" #import "KeyboardViewController.h"
#import "KBKeyBoardMainView.h" #import "KBKeyBoardMainView.h"
#import "KBKey.h"
#import "KBFunctionView.h"
#import "KBSettingView.h"
#import "Masonry.h"
#import "KBAuthManager.h" #import "KBAuthManager.h"
#import "KBFullAccessManager.h"
#import "KBSkinManager.h"
#import "KBSkinInstallBridge.h"
#import "KBHostAppLauncher.h"
#import "KBKeyboardSubscriptionView.h"
#import "KBKeyboardSubscriptionProduct.h"
#import "KBBackspaceUndoManager.h" #import "KBBackspaceUndoManager.h"
#import "KBFullAccessManager.h"
#import "KBFunctionView.h"
#import "KBHostAppLauncher.h"
#import "KBInputBufferManager.h" #import "KBInputBufferManager.h"
#import "KBKey.h"
#import "KBKeyboardSubscriptionProduct.h"
#import "KBKeyboardSubscriptionView.h"
#import "KBSettingView.h"
#import "KBSkinInstallBridge.h"
#import "KBSkinManager.h"
#import "KBSuggestionEngine.h" #import "KBSuggestionEngine.h"
#import "Masonry.h"
#import "UIImage+KBColor.h"
// #import "KBLog.h" // #import "KBLog.h"
// 使 static kb_consumePendingShopSkin // 使 static kb_consumePendingShopSkin
//
@interface KeyboardViewController (KBSkinShopBridge) @interface KeyboardViewController (KBSkinShopBridge)
- (void)kb_consumePendingShopSkin; - (void)kb_consumePendingShopSkin;
@end @end
@@ -37,12 +40,14 @@ static NSString * const kKBDefaultSkinIdDark = @"normal_hei_them";
static NSString *const kKBDefaultSkinZipNameDark = @"normal_hei_them"; static NSString *const kKBDefaultSkinZipNameDark = @"normal_hei_them";
static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center, static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
void *observer, void *observer, CFStringRef name,
CFStringRef name,
const void *object, const void *object,
CFDictionaryRef userInfo) { CFDictionaryRef userInfo) {
KeyboardViewController *strongSelf = (__bridge KeyboardViewController *)observer; KeyboardViewController *strongSelf =
if (!strongSelf) { return; } (__bridge KeyboardViewController *)observer;
if (!strongSelf) {
return;
}
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
if ([strongSelf respondsToSelector:@selector(kb_consumePendingShopSkin)]) { if ([strongSelf respondsToSelector:@selector(kb_consumePendingShopSkin)]) {
[strongSelf kb_consumePendingShopSkin]; [strongSelf kb_consumePendingShopSkin];
@@ -50,11 +55,16 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
}); });
} }
@interface KeyboardViewController () <KBKeyBoardMainViewDelegate, KBFunctionViewDelegate, KBKeyboardSubscriptionViewDelegate> @interface KeyboardViewController () <KBKeyBoardMainViewDelegate,
@property (nonatomic, strong) UIButton *nextKeyboardButton; // KBFunctionViewDelegate,
KBKeyboardSubscriptionViewDelegate>
@property(nonatomic, strong)
UIButton *nextKeyboardButton; //
@property(nonatomic, strong) UIView *contentView; @property(nonatomic, strong) UIView *contentView;
@property (nonatomic, strong) KBKeyBoardMainView *keyBoardMainView; // 0 @property(nonatomic, strong) KBKeyBoardMainView
@property (nonatomic, strong) KBFunctionView *functionView; // 0 *keyBoardMainView; // 0
@property(nonatomic, strong)
KBFunctionView *functionView; // 0
@property(nonatomic, strong) KBSettingView *settingView; // @property(nonatomic, strong) KBSettingView *settingView; //
@property(nonatomic, strong) UIImageView *bgImageView; // @property(nonatomic, strong) UIImageView *bgImageView; //
@property(nonatomic, strong) KBKeyboardSubscriptionView *subscriptionView; @property(nonatomic, strong) KBKeyboardSubscriptionView *subscriptionView;
@@ -86,24 +96,30 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
[KBHUD setContainerView:self.view]; [KBHUD setContainerView:self.view];
// 访便 // 访便
[[KBFullAccessManager shared] bindInputController:self]; [[KBFullAccessManager shared] bindInputController:self];
__unused id token = [[NSNotificationCenter defaultCenter] addObserverForName:KBFullAccessChangedNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(__unused NSNotification * _Nonnull note) { __unused id token = [[NSNotificationCenter defaultCenter]
addObserverForName:KBFullAccessChangedNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(__unused NSNotification *_Nonnull note){
// 访 UI // 访 UI
}]; }];
// //
__unused id token2 = [[NSNotificationCenter defaultCenter] addObserverForName:KBSkinDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(__unused NSNotification * _Nonnull note) { __unused id token2 = [[NSNotificationCenter defaultCenter]
addObserverForName:KBSkinDidChangeNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(__unused NSNotification *_Nonnull note) {
[self kb_applyTheme]; [self kb_applyTheme];
}]; }];
[self kb_applyTheme]; [self kb_applyTheme];
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), CFNotificationCenterAddObserver(
(__bridge const void *)(self), CFNotificationCenterGetDarwinNotifyCenter(),
KBSkinInstallNotificationCallback, (__bridge const void *)(self), KBSkinInstallNotificationCallback,
(__bridge CFStringRef)KBDarwinSkinInstallRequestNotification, (__bridge CFStringRef)KBDarwinSkinInstallRequestNotification, NULL,
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately); CFNotificationSuspensionBehaviorDeliverImmediately);
[self kb_consumePendingShopSkin]; [self kb_consumePendingShopSkin];
[self kb_applyDefaultSkinIfNeeded]; [self kb_applyDefaultSkinIfNeeded];
} }
- (void)viewWillAppear:(BOOL)animated { - (void)viewWillAppear:(BOOL)animated {
@@ -112,9 +128,13 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
[[KBBackspaceUndoManager shared] registerNonClearAction]; [[KBBackspaceUndoManager shared] registerNonClearAction];
[[KBInputBufferManager shared] resetWithText:@""]; [[KBInputBufferManager shared] resetWithText:@""];
[[KBLocalizationManager shared] reloadFromSharedStorageIfNeeded]; [[KBLocalizationManager shared] reloadFromSharedStorageIfNeeded];
// /QQ 宿 documentContext liveText manualSnapshot // /QQ 宿 documentContext
[[KBInputBufferManager shared] updateFromExternalContextBefore:self.textDocumentProxy.documentContextBeforeInput // liveText manualSnapshot
after:self.textDocumentProxy.documentContextAfterInput]; [[KBInputBufferManager shared]
updateFromExternalContextBefore:self.textDocumentProxy
.documentContextBeforeInput
after:self.textDocumentProxy
.documentContextAfterInput];
} }
- (void)viewWillDisappear:(BOOL)animated { - (void)viewWillDisappear:(BOOL)animated {
@@ -125,7 +145,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection]; [super traitCollectionDidChange:previousTraitCollection];
if (@available(iOS 13.0, *)) { if (@available(iOS 13.0, *)) {
if (previousTraitCollection.userInterfaceStyle != self.traitCollection.userInterfaceStyle) { if (previousTraitCollection.userInterfaceStyle !=
self.traitCollection.userInterfaceStyle) {
[self kb_applyDefaultSkinIfNeeded]; [self kb_applyDefaultSkinIfNeeded];
} }
} }
@@ -133,11 +154,13 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
- (void)textDidChange:(id<UITextInput>)textInput { - (void)textDidChange:(id<UITextInput>)textInput {
[super textDidChange:textInput]; [super textDidChange:textInput];
[[KBInputBufferManager shared] updateFromExternalContextBefore:self.textDocumentProxy.documentContextBeforeInput [[KBInputBufferManager shared]
after:self.textDocumentProxy.documentContextAfterInput]; updateFromExternalContextBefore:self.textDocumentProxy
.documentContextBeforeInput
after:self.textDocumentProxy
.documentContextAfterInput];
} }
- (void)setupUI { - (void)setupUI {
self.view.translatesAutoresizingMaskIntoConstraints = NO; self.view.translatesAutoresizingMaskIntoConstraints = NO;
@@ -147,8 +170,10 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
CGFloat screenWidth = CGRectGetWidth([UIScreen mainScreen].bounds); CGFloat screenWidth = CGRectGetWidth([UIScreen mainScreen].bounds);
CGFloat outerVerticalInset = KBFit(4.0f); CGFloat outerVerticalInset = KBFit(4.0f);
NSLayoutConstraint *h = [self.view.heightAnchor constraintEqualToConstant:keyboardHeight]; NSLayoutConstraint *h =
NSLayoutConstraint *w = [self.view.widthAnchor constraintEqualToConstant:screenWidth]; [self.view.heightAnchor constraintEqualToConstant:keyboardHeight];
NSLayoutConstraint *w =
[self.view.widthAnchor constraintEqualToConstant:screenWidth];
self.kb_heightConstraint = h; self.kb_heightConstraint = h;
self.kb_widthConstraint = w; self.kb_widthConstraint = w;
@@ -189,14 +214,14 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
}]; }];
} }
#pragma mark - Private #pragma mark - Private
// MARK: - Suggestions // MARK: - Suggestions
- (void)kb_updateCurrentWordWithInsertedText:(NSString *)text { - (void)kb_updateCurrentWordWithInsertedText:(NSString *)text {
if (text.length == 0) { return; } if (text.length == 0) {
return;
}
if ([self kb_isAlphabeticString:text]) { if ([self kb_isAlphabeticString:text]) {
NSString *current = self.currentWord ?: @""; NSString *current = self.currentWord ?: @"";
self.currentWord = [current stringByAppendingString:text]; self.currentWord = [current stringByAppendingString:text];
@@ -215,11 +240,13 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
- (void)kb_scheduleContextRefreshResetSuppression:(BOOL)resetSuppression { - (void)kb_scheduleContextRefreshResetSuppression:(BOOL)resetSuppression {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[self kb_refreshCurrentWordFromDocumentContextResetSuppression:resetSuppression]; [self kb_refreshCurrentWordFromDocumentContextResetSuppression:
resetSuppression];
}); });
} }
- (void)kb_refreshCurrentWordFromDocumentContextResetSuppression:(BOOL)resetSuppression { - (void)kb_refreshCurrentWordFromDocumentContextResetSuppression:
(BOOL)resetSuppression {
NSString *context = self.textDocumentProxy.documentContextBeforeInput ?: @""; NSString *context = self.textDocumentProxy.documentContextBeforeInput ?: @"";
NSString *word = [self kb_extractTrailingWordFromContext:context]; NSString *word = [self kb_extractTrailingWordFromContext:context];
self.currentWord = word ?: @""; self.currentWord = word ?: @"";
@@ -230,11 +257,15 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
} }
- (NSString *)kb_extractTrailingWordFromContext:(NSString *)context { - (NSString *)kb_extractTrailingWordFromContext:(NSString *)context {
if (context.length == 0) { return @""; } if (context.length == 0) {
return @"";
}
static NSCharacterSet *letters = nil; static NSCharacterSet *letters = nil;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
letters = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]; letters = [NSCharacterSet
characterSetWithCharactersInString:
@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];
}); });
NSInteger idx = (NSInteger)context.length - 1; NSInteger idx = (NSInteger)context.length - 1;
@@ -246,16 +277,22 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
idx -= 1; idx -= 1;
} }
NSUInteger start = (NSUInteger)(idx + 1); NSUInteger start = (NSUInteger)(idx + 1);
if (start >= context.length) { return @""; } if (start >= context.length) {
return @"";
}
return [context substringFromIndex:start]; return [context substringFromIndex:start];
} }
- (BOOL)kb_isAlphabeticString:(NSString *)text { - (BOOL)kb_isAlphabeticString:(NSString *)text {
if (text.length == 0) { return NO; } if (text.length == 0) {
return NO;
}
static NSCharacterSet *letters = nil; static NSCharacterSet *letters = nil;
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
letters = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]; letters = [NSCharacterSet
characterSetWithCharactersInString:
@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];
}); });
for (NSUInteger i = 0; i < text.length; i++) { for (NSUInteger i = 0; i < text.length; i++) {
if (![letters characterIsMember:[text characterAtIndex:i]]) { if (![letters characterIsMember:[text characterAtIndex:i]]) {
@@ -275,19 +312,28 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
[self.keyBoardMainView kb_setSuggestions:@[]]; [self.keyBoardMainView kb_setSuggestions:@[]];
return; return;
} }
NSArray<NSString *> *items = [self.suggestionEngine suggestionsForPrefix:prefix limit:5]; NSArray<NSString *> *items =
NSArray<NSString *> *cased = [self kb_applyCaseToSuggestions:items prefix:prefix]; [self.suggestionEngine suggestionsForPrefix:prefix limit:5];
NSArray<NSString *> *cased = [self kb_applyCaseToSuggestions:items
prefix:prefix];
[self.keyBoardMainView kb_setSuggestions:cased]; [self.keyBoardMainView kb_setSuggestions:cased];
} }
- (NSArray<NSString *> *)kb_applyCaseToSuggestions:(NSArray<NSString *> *)items prefix:(NSString *)prefix { - (NSArray<NSString *> *)kb_applyCaseToSuggestions:(NSArray<NSString *> *)items
if (items.count == 0 || prefix.length == 0) { return items; } prefix:(NSString *)prefix {
if (items.count == 0 || prefix.length == 0) {
return items;
}
BOOL allUpper = [prefix isEqualToString:prefix.uppercaseString]; BOOL allUpper = [prefix isEqualToString:prefix.uppercaseString];
BOOL firstUpper = [[prefix substringToIndex:1] isEqualToString:[[prefix substringToIndex:1] uppercaseString]]; BOOL firstUpper = [[prefix substringToIndex:1]
isEqualToString:[[prefix substringToIndex:1] uppercaseString]];
if (!allUpper && !firstUpper) { return items; } if (!allUpper && !firstUpper) {
return items;
}
NSMutableArray<NSString *> *result = [NSMutableArray arrayWithCapacity:items.count]; NSMutableArray<NSString *> *result =
[NSMutableArray arrayWithCapacity:items.count];
for (NSString *word in items) { for (NSString *word in items) {
if (allUpper) { if (allUpper) {
[result addObject:word.uppercaseString]; [result addObject:word.uppercaseString];
@@ -307,13 +353,15 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
self.keyBoardMainView.hidden = show; self.keyBoardMainView.hidden = show;
if (show) { if (show) {
[[KBMaiPointReporter sharedReporter] reportPageExposureWithEventName:@"enter_keyboard_function_panel" [[KBMaiPointReporter sharedReporter]
reportPageExposureWithEventName:@"enter_keyboard_function_panel"
pageId:@"keyboard_function_panel" pageId:@"keyboard_function_panel"
extra:nil extra:nil
completion:nil]; completion:nil];
[self hideSubscriptionPanel]; [self hideSubscriptionPanel];
} else { } else {
[[KBMaiPointReporter sharedReporter] reportPageExposureWithEventName:@"enter_keyboard_main_panel" [[KBMaiPointReporter sharedReporter]
reportPageExposureWithEventName:@"enter_keyboard_main_panel"
pageId:@"keyboard_main_panel" pageId:@"keyboard_main_panel"
extra:nil extra:nil
completion:nil]; completion:nil];
@@ -330,7 +378,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
/// / keyBoardMainView / /// / keyBoardMainView /
- (void)showSettingView:(BOOL)show { - (void)showSettingView:(BOOL)show {
if (show) { if (show) {
[[KBMaiPointReporter sharedReporter] reportPageExposureWithEventName:@"enter_keyboard_settings" [[KBMaiPointReporter sharedReporter]
reportPageExposureWithEventName:@"enter_keyboard_settings"
pageId:@"keyboard_settings" pageId:@"keyboard_settings"
extra:nil extra:nil
completion:nil]; completion:nil];
@@ -342,27 +391,46 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
// //
make.edges.equalTo(self.contentView); make.edges.equalTo(self.contentView);
}]; }];
[self.settingView.backButton addTarget:self action:@selector(onTapSettingsBack) forControlEvents:UIControlEventTouchUpInside]; [self.settingView.backButton addTarget:self
action:@selector(onTapSettingsBack)
forControlEvents:UIControlEventTouchUpInside];
// } // }
[self.contentView bringSubviewToFront:self.settingView]; [self.contentView bringSubviewToFront:self.settingView];
// keyBoardMainView self.view // keyBoardMainView self.view
[self.contentView layoutIfNeeded]; [self.contentView layoutIfNeeded];
CGFloat w = CGRectGetWidth(self.keyBoardMainView.bounds); CGFloat w = CGRectGetWidth(self.keyBoardMainView.bounds);
if (w <= 0) { w = CGRectGetWidth(self.contentView.bounds); } if (w <= 0) {
if (w <= 0) { w = [self kb_portraitWidth]; } w = CGRectGetWidth(self.contentView.bounds);
}
if (w <= 0) {
w = [self kb_portraitWidth];
}
self.settingView.transform = CGAffineTransformMakeTranslation(w, 0); self.settingView.transform = CGAffineTransformMakeTranslation(w, 0);
self.settingView.hidden = NO; self.settingView.hidden = NO;
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ [UIView animateWithDuration:0.25
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.settingView.transform = CGAffineTransformIdentity; self.settingView.transform = CGAffineTransformIdentity;
} completion:nil]; }
completion:nil];
} else { } else {
if (!self.settingView || self.settingView.hidden) return; if (!self.settingView || self.settingView.hidden)
return;
CGFloat w = CGRectGetWidth(self.keyBoardMainView.bounds); CGFloat w = CGRectGetWidth(self.keyBoardMainView.bounds);
if (w <= 0) { w = CGRectGetWidth(self.contentView.bounds); } if (w <= 0) {
if (w <= 0) { w = [self kb_portraitWidth]; } w = CGRectGetWidth(self.contentView.bounds);
[UIView animateWithDuration:0.22 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{ }
if (w <= 0) {
w = [self kb_portraitWidth];
}
[UIView animateWithDuration:0.22
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
self.settingView.transform = CGAffineTransformMakeTranslation(w, 0); self.settingView.transform = CGAffineTransformMakeTranslation(w, 0);
} completion:^(BOOL finished) { }
completion:^(BOOL finished) {
self.settingView.hidden = YES; self.settingView.hidden = YES;
}]; }];
} }
@@ -377,15 +445,18 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
return; return;
} }
// //
// 2) -> App App // 2) -> App App
//
if (!KBAuthManager.shared.isLoggedIn) { if (!KBAuthManager.shared.isLoggedIn) {
NSString *schemeStr = [NSString stringWithFormat:@"%@://login?src=keyboard", KB_APP_SCHEME]; NSString *schemeStr =
[NSString stringWithFormat:@"%@://login?src=keyboard", KB_APP_SCHEME];
NSURL *scheme = [NSURL URLWithString:schemeStr]; NSURL *scheme = [NSURL URLWithString:schemeStr];
// UIApplication App // UIApplication App
BOOL ok = [KBHostAppLauncher openHostAppURL:scheme fromResponder:self.view]; BOOL ok = [KBHostAppLauncher openHostAppURL:scheme fromResponder:self.view];
return; return;
} }
[[KBMaiPointReporter sharedReporter] reportPageExposureWithEventName:@"enter_keyboard_subscription_panel" [[KBMaiPointReporter sharedReporter]
reportPageExposureWithEventName:@"enter_keyboard_subscription_panel"
pageId:@"keyboard_subscription_panel" pageId:@"keyboard_subscription_panel"
extra:nil extra:nil
completion:nil]; completion:nil];
@@ -402,34 +473,47 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
panel.hidden = NO; panel.hidden = NO;
panel.alpha = 0.0; panel.alpha = 0.0;
CGFloat height = CGRectGetHeight(self.contentView.bounds); CGFloat height = CGRectGetHeight(self.contentView.bounds);
if (height <= 0) { height = 260; } if (height <= 0) {
height = 260;
}
panel.transform = CGAffineTransformMakeTranslation(0, height); panel.transform = CGAffineTransformMakeTranslation(0, height);
[panel refreshProductsIfNeeded]; [panel refreshProductsIfNeeded];
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ [UIView animateWithDuration:0.25
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
panel.alpha = 1.0; panel.alpha = 1.0;
panel.transform = CGAffineTransformIdentity; panel.transform = CGAffineTransformIdentity;
} completion:nil]; }
completion:nil];
} }
- (void)hideSubscriptionPanel { - (void)hideSubscriptionPanel {
if (!self.subscriptionView || self.subscriptionView.hidden) { return; } if (!self.subscriptionView || self.subscriptionView.hidden) {
return;
}
CGFloat height = CGRectGetHeight(self.subscriptionView.bounds); CGFloat height = CGRectGetHeight(self.subscriptionView.bounds);
if (height <= 0) { height = CGRectGetHeight(self.contentView.bounds); } if (height <= 0) {
height = CGRectGetHeight(self.contentView.bounds);
}
KBKeyboardSubscriptionView *panel = self.subscriptionView; KBKeyboardSubscriptionView *panel = self.subscriptionView;
[UIView animateWithDuration:0.22 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{ [UIView animateWithDuration:0.22
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
panel.alpha = 0.0; panel.alpha = 0.0;
panel.transform = CGAffineTransformMakeTranslation(0, height); panel.transform = CGAffineTransformMakeTranslation(0, height);
} completion:^(BOOL finished) { }
completion:^(BOOL finished) {
panel.hidden = YES; panel.hidden = YES;
panel.alpha = 1.0; panel.alpha = 1.0;
panel.transform = CGAffineTransformIdentity; panel.transform = CGAffineTransformIdentity;
}]; }];
} }
// MARK: - KBKeyBoardMainViewDelegate // MARK: - KBKeyBoardMainViewDelegate
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView didTapKey:(KBKey *)key { - (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView
didTapKey:(KBKey *)key {
switch (key.type) { switch (key.type) {
case KBKeyTypeCharacter: { case KBKeyTypeCharacter: {
[[KBBackspaceUndoManager shared] registerNonClearAction]; [[KBBackspaceUndoManager shared] registerNonClearAction];
@@ -439,10 +523,17 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
[[KBInputBufferManager shared] appendText:text]; [[KBInputBufferManager shared] appendText:text];
} break; } break;
case KBKeyTypeBackspace: case KBKeyTypeBackspace:
[[KBInputBufferManager shared] refreshFromProxyIfPossible:self.textDocumentProxy]; [[KBInputBufferManager shared]
[[KBInputBufferManager shared] prepareSnapshotForDeleteWithContextBefore:self.textDocumentProxy.documentContextBeforeInput refreshFromProxyIfPossible:self.textDocumentProxy];
after:self.textDocumentProxy.documentContextAfterInput]; [[KBInputBufferManager shared]
[[KBBackspaceUndoManager shared] captureAndDeleteBackwardFromProxy:self.textDocumentProxy count:1]; prepareSnapshotForDeleteWithContextBefore:
self.textDocumentProxy.documentContextBeforeInput
after:
self.textDocumentProxy
.documentContextAfterInput];
[[KBBackspaceUndoManager shared]
captureAndDeleteBackwardFromProxy:self.textDocumentProxy
count:1];
[self kb_scheduleContextRefreshResetSuppression:NO]; [self kb_scheduleContextRefreshResetSuppression:NO];
[[KBInputBufferManager shared] applyHoldDeleteCount:1]; [[KBInputBufferManager shared] applyHoldDeleteCount:1];
break; break;
@@ -459,7 +550,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
[[KBInputBufferManager shared] appendText:@"\n"]; [[KBInputBufferManager shared] appendText:@"\n"];
break; break;
case KBKeyTypeGlobe: case KBKeyTypeGlobe:
[self advanceToNextInputMode]; break; [self advanceToNextInputMode];
break;
case KBKeyTypeCustom: case KBKeyTypeCustom:
[[KBBackspaceUndoManager shared] registerNonClearAction]; [[KBBackspaceUndoManager shared] registerNonClearAction];
// //
@@ -473,9 +565,11 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
} }
} }
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView didTapToolActionAtIndex:(NSInteger)index { - (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView
didTapToolActionAtIndex:(NSInteger)index {
NSDictionary *extra = @{@"index" : @(index)}; NSDictionary *extra = @{@"index" : @(index)};
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_toolbar_action" [[KBMaiPointReporter sharedReporter]
reportClickWithEventName:@"click_keyboard_toolbar_action"
pageId:@"keyboard_main_panel" pageId:@"keyboard_main_panel"
elementId:@"toolbar_action" elementId:@"toolbar_action"
extra:extra extra:extra
@@ -489,7 +583,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
} }
- (void)keyBoardMainViewDidTapSettings:(KBKeyBoardMainView *)keyBoardMainView { - (void)keyBoardMainViewDidTapSettings:(KBKeyBoardMainView *)keyBoardMainView {
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_settings_btn" [[KBMaiPointReporter sharedReporter]
reportClickWithEventName:@"click_keyboard_settings_btn"
pageId:@"keyboard_main_panel" pageId:@"keyboard_main_panel"
elementId:@"settings_btn" elementId:@"settings_btn"
extra:nil extra:nil
@@ -497,8 +592,11 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
[self showSettingView:YES]; [self showSettingView:YES];
} }
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView didSelectEmoji:(NSString *)emoji { - (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView
if (emoji.length == 0) { return; } didSelectEmoji:(NSString *)emoji {
if (emoji.length == 0) {
return;
}
[[KBBackspaceUndoManager shared] registerNonClearAction]; [[KBBackspaceUndoManager shared] registerNonClearAction];
[self.textDocumentProxy insertText:emoji]; [self.textDocumentProxy insertText:emoji];
[self kb_clearCurrentWord]; [self kb_clearCurrentWord];
@@ -506,7 +604,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
} }
- (void)keyBoardMainViewDidTapUndo:(KBKeyBoardMainView *)keyBoardMainView { - (void)keyBoardMainViewDidTapUndo:(KBKeyBoardMainView *)keyBoardMainView {
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_undo_btn" [[KBMaiPointReporter sharedReporter]
reportClickWithEventName:@"click_keyboard_undo_btn"
pageId:@"keyboard_main_panel" pageId:@"keyboard_main_panel"
elementId:@"undo_btn" elementId:@"undo_btn"
extra:nil extra:nil
@@ -515,8 +614,10 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
[self kb_scheduleContextRefreshResetSuppression:YES]; [self kb_scheduleContextRefreshResetSuppression:YES];
} }
- (void)keyBoardMainViewDidTapEmojiSearch:(KBKeyBoardMainView *)keyBoardMainView { - (void)keyBoardMainViewDidTapEmojiSearch:
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_emoji_search_btn" (KBKeyBoardMainView *)keyBoardMainView {
[[KBMaiPointReporter sharedReporter]
reportClickWithEventName:@"click_keyboard_emoji_search_btn"
pageId:@"keyboard_main_panel" pageId:@"keyboard_main_panel"
elementId:@"emoji_search_btn" elementId:@"emoji_search_btn"
extra:nil extra:nil
@@ -524,10 +625,14 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
[KBHUD showInfo:KBLocalized(@"Search coming soon")]; [KBHUD showInfo:KBLocalized(@"Search coming soon")];
} }
- (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView didSelectSuggestion:(NSString *)suggestion { - (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView
if (suggestion.length == 0) { return; } didSelectSuggestion:(NSString *)suggestion {
if (suggestion.length == 0) {
return;
}
NSDictionary *extra = @{@"suggestion_len" : @(suggestion.length)}; NSDictionary *extra = @{@"suggestion_len" : @(suggestion.length)};
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_suggestion_item" [[KBMaiPointReporter sharedReporter]
reportClickWithEventName:@"click_keyboard_suggestion_item"
pageId:@"keyboard_main_panel" pageId:@"keyboard_main_panel"
elementId:@"suggestion_item" elementId:@"suggestion_item"
extra:extra extra:extra
@@ -544,30 +649,36 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
[self.suggestionEngine recordSelection:suggestion]; [self.suggestionEngine recordSelection:suggestion];
self.suppressSuggestions = YES; self.suppressSuggestions = YES;
[self.keyBoardMainView kb_setSuggestions:@[]]; [self.keyBoardMainView kb_setSuggestions:@[]];
[[KBInputBufferManager shared] replaceTailWithText:suggestion deleteCount:current.length]; [[KBInputBufferManager shared] replaceTailWithText:suggestion
deleteCount:current.length];
} }
// MARK: - KBFunctionViewDelegate // MARK: - KBFunctionViewDelegate
- (void)functionView:(KBFunctionView *)functionView didTapToolActionAtIndex:(NSInteger)index { - (void)functionView:(KBFunctionView *)functionView
didTapToolActionAtIndex:(NSInteger)index {
// index == 0 // index == 0
if (index == 0) { if (index == 0) {
[self showFunctionPanel:NO]; [self showFunctionPanel:NO];
} }
} }
- (void)functionView:(KBFunctionView *_Nullable)functionView didRightTapToolActionAtIndex:(NSInteger)index{ - (void)functionView:(KBFunctionView *_Nullable)functionView
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_function_right_action" didRightTapToolActionAtIndex:(NSInteger)index {
[[KBMaiPointReporter sharedReporter]
reportClickWithEventName:@"click_keyboard_function_right_action"
pageId:@"keyboard_function_panel" pageId:@"keyboard_function_panel"
elementId:@"right_action" elementId:@"right_action"
extra:@{@"action" : @"login_or_recharge"} extra:@{@"action" : @"login_or_recharge"}
completion:nil]; completion:nil];
if (!KBAuthManager.shared.isLoggedIn) { if (!KBAuthManager.shared.isLoggedIn) {
NSString *schemeStr = [NSString stringWithFormat:@"%@://login?src=keyboard", KB_APP_SCHEME]; NSString *schemeStr =
[NSString stringWithFormat:@"%@://login?src=keyboard", KB_APP_SCHEME];
NSURL *scheme = [NSURL URLWithString:schemeStr]; NSURL *scheme = [NSURL URLWithString:schemeStr];
// UIApplication App // UIApplication App
BOOL ok = [KBHostAppLauncher openHostAppURL:scheme fromResponder:self.view]; BOOL ok = [KBHostAppLauncher openHostAppURL:scheme fromResponder:self.view];
return; return;
} }
NSString *schemeStr = [NSString stringWithFormat:@"%@://recharge?src=keyboard", KB_APP_SCHEME]; NSString *schemeStr =
[NSString stringWithFormat:@"%@://recharge?src=keyboard", KB_APP_SCHEME];
NSURL *scheme = [NSURL URLWithString:schemeStr]; NSURL *scheme = [NSURL URLWithString:schemeStr];
// //
// if (!ul && !scheme) { return; } // if (!ul && !scheme) { return; }
@@ -589,7 +700,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
#pragma mark - KBKeyboardSubscriptionViewDelegate #pragma mark - KBKeyboardSubscriptionViewDelegate
- (void)subscriptionViewDidTapClose:(KBKeyboardSubscriptionView *)view { - (void)subscriptionViewDidTapClose:(KBKeyboardSubscriptionView *)view {
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_subscription_close_btn" [[KBMaiPointReporter sharedReporter]
reportClickWithEventName:@"click_keyboard_subscription_close_btn"
pageId:@"keyboard_subscription_panel" pageId:@"keyboard_subscription_panel"
elementId:@"close_btn" elementId:@"close_btn"
extra:nil extra:nil
@@ -597,12 +709,15 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
[self hideSubscriptionPanel]; [self hideSubscriptionPanel];
} }
- (void)subscriptionView:(KBKeyboardSubscriptionView *)view didTapPurchaseForProduct:(KBKeyboardSubscriptionProduct *)product { - (void)subscriptionView:(KBKeyboardSubscriptionView *)view
didTapPurchaseForProduct:(KBKeyboardSubscriptionProduct *)product {
NSMutableDictionary *extra = [NSMutableDictionary dictionary]; NSMutableDictionary *extra = [NSMutableDictionary dictionary];
if ([product.productId isKindOfClass:NSString.class] && product.productId.length > 0) { if ([product.productId isKindOfClass:NSString.class] &&
product.productId.length > 0) {
extra[@"product_id"] = product.productId; extra[@"product_id"] = product.productId;
} }
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_subscription_product_btn" [[KBMaiPointReporter sharedReporter]
reportClickWithEventName:@"click_keyboard_subscription_product_btn"
pageId:@"keyboard_subscription_panel" pageId:@"keyboard_subscription_panel"
elementId:@"product_btn" elementId:@"product_btn"
extra:extra.copy extra:extra.copy
@@ -645,43 +760,52 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
return _subscriptionView; return _subscriptionView;
} }
#pragma mark - Actions #pragma mark - Actions
- (void)kb_openRechargeForProduct:(KBKeyboardSubscriptionProduct *)product { - (void)kb_openRechargeForProduct:(KBKeyboardSubscriptionProduct *)product {
if (![product isKindOfClass:KBKeyboardSubscriptionProduct.class] || product.productId.length == 0) { if (![product isKindOfClass:KBKeyboardSubscriptionProduct.class] ||
product.productId.length == 0) {
[KBHUD showInfo:KBLocalized(@"Product unavailable")]; [KBHUD showInfo:KBLocalized(@"Product unavailable")];
return; return;
} }
NSString *encodedId = [self.class kb_urlEncodedString:product.productId]; NSString *encodedId = [self.class kb_urlEncodedString:product.productId];
NSString *title = [product displayTitle]; NSString *title = [product displayTitle];
NSString *encodedTitle = [self.class kb_urlEncodedString:title]; NSString *encodedTitle = [self.class kb_urlEncodedString:title];
NSMutableArray<NSString *> *params = [NSMutableArray arrayWithObjects:@"autoPay=1", @"prefill=1", nil]; NSMutableArray<NSString *> *params =
[NSMutableArray arrayWithObjects:@"autoPay=1", @"prefill=1", nil];
if (encodedId.length) { if (encodedId.length) {
[params addObject:[NSString stringWithFormat:@"productId=%@", encodedId]]; [params addObject:[NSString stringWithFormat:@"productId=%@", encodedId]];
} }
if (encodedTitle.length) { if (encodedTitle.length) {
[params addObject:[NSString stringWithFormat:@"productTitle=%@", encodedTitle]]; [params
addObject:[NSString stringWithFormat:@"productTitle=%@", encodedTitle]];
} }
NSString *query = [params componentsJoinedByString:@"&"]; NSString *query = [params componentsJoinedByString:@"&"];
NSString *urlString = [NSString stringWithFormat:@"%@://recharge?src=keyboard&%@", KB_APP_SCHEME, query]; NSString *urlString = [NSString
stringWithFormat:@"%@://recharge?src=keyboard&%@", KB_APP_SCHEME, query];
NSURL *scheme = [NSURL URLWithString:urlString]; NSURL *scheme = [NSURL URLWithString:urlString];
BOOL success = [KBHostAppLauncher openHostAppURL:scheme fromResponder:self.view]; BOOL success = [KBHostAppLauncher openHostAppURL:scheme
fromResponder:self.view];
if (!success) { if (!success) {
[KBHUD showInfo:KBLocalized(@"Please open the App to finish purchase")]; [KBHUD showInfo:KBLocalized(@"Please open the App to finish purchase")];
} }
} }
+ (NSString *)kb_urlEncodedString:(NSString *)value { + (NSString *)kb_urlEncodedString:(NSString *)value {
if (value.length == 0) { return @""; } if (value.length == 0) {
return @"";
}
NSString *reserved = @"!*'();:@&=+$,/?%#[]"; NSString *reserved = @"!*'();:@&=+$,/?%#[]";
NSMutableCharacterSet *allowed = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy]; NSMutableCharacterSet *allowed =
[[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
[allowed removeCharactersInString:reserved]; [allowed removeCharactersInString:reserved];
return [value stringByAddingPercentEncodingWithAllowedCharacters:allowed] ?: @""; return [value stringByAddingPercentEncodingWithAllowedCharacters:allowed]
?: @"";
} }
- (void)onTapSettingsBack { - (void)onTapSettingsBack {
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_keyboard_settings_back_btn" [[KBMaiPointReporter sharedReporter]
reportClickWithEventName:@"click_keyboard_settings_back_btn"
pageId:@"keyboard_settings" pageId:@"keyboard_settings"
elementId:@"back_btn" elementId:@"back_btn"
extra:nil extra:nil
@@ -690,14 +814,14 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
} }
- (void)dealloc { - (void)dealloc {
CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), CFNotificationCenterRemoveObserver(
CFNotificationCenterGetDarwinNotifyCenter(),
(__bridge const void *)(self), (__bridge const void *)(self),
(__bridge CFStringRef)KBDarwinSkinInstallRequestNotification, (__bridge CFStringRef)KBDarwinSkinInstallRequestNotification, NULL);
NULL);
} }
// App App
// App App //
- (void)viewDidAppear:(BOOL)animated { - (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated]; [super viewDidAppear:animated];
// if (!_kb_didTriggerLoginDeepLinkOnce) { // if (!_kb_didTriggerLoginDeepLinkOnce) {
@@ -714,22 +838,29 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
[self kb_updateKeyboardLayoutIfNeeded]; [self kb_updateKeyboardLayoutIfNeeded];
} }
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { - (void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:
(id<UIViewControllerTransitionCoordinator>)coordinator {
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
__weak typeof(self) weakSelf = self; __weak typeof(self) weakSelf = self;
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { [coordinator
animateAlongsideTransition:^(
id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
[weakSelf kb_updateKeyboardLayoutIfNeeded]; [weakSelf kb_updateKeyboardLayoutIfNeeded];
} completion:^(__unused id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { }
completion:^(
__unused id<
UIViewControllerTransitionCoordinatorContext> _Nonnull context) {
[weakSelf kb_updateKeyboardLayoutIfNeeded]; [weakSelf kb_updateKeyboardLayoutIfNeeded];
}]; }];
} }
//- (void)kb_tryOpenContainerForLoginIfNeeded { //- (void)kb_tryOpenContainerForLoginIfNeeded {
// // 使 App Scheme // // 使 App Scheme
// NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@@//login?src=keyboard", KB_APP_SCHEME]]; // NSURL *url = [NSURL URLWithString:[NSString
// if (!url) return; // stringWithFormat:@"%@@//login?src=keyboard", KB_APP_SCHEME]]; if (!url)
// KBWeakSelf // return; KBWeakSelf [self.extensionContext openURL:url
// [self.extensionContext openURL:url completionHandler:^(__unused BOOL success) { // completionHandler:^(__unused BOOL success) {
// // 使 // // 使
// __unused typeof(weakSelf) selfStrong = weakSelf; // __unused typeof(weakSelf) selfStrong = weakSelf;
// }]; // }];
@@ -740,8 +871,48 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
- (void)kb_applyTheme { - (void)kb_applyTheme {
KBSkinTheme *t = [KBSkinManager shared].current; KBSkinTheme *t = [KBSkinManager shared].current;
UIImage *img = [[KBSkinManager shared] currentBackgroundImage]; UIImage *img = [[KBSkinManager shared] currentBackgroundImage];
if ([self kb_isDefaultKeyboardTheme:t]) { BOOL isDefaultTheme = [self kb_isDefaultKeyboardTheme:t];
BOOL isDarkMode = [self kb_isDarkModeActive];
CGSize size = self.bgImageView.bounds.size; CGSize size = self.bgImageView.bounds.size;
if (isDefaultTheme) {
if (isDarkMode) {
// 使使
//
img = nil;
self.bgImageView.image = nil;
// 使
if (@available(iOS 13.0, *)) {
// iOS 使 (RGB: 44, 44, 46 in sRGB, #2C2C2E)
// 使
UIColor *kbBgColor =
[UIColor colorWithDynamicProvider:^UIColor *_Nonnull(
UITraitCollection *_Nonnull traitCollection) {
if (traitCollection.userInterfaceStyle ==
UIUserInterfaceStyleDark) {
//
return [UIColor colorWithRed:43.0 / 255.0
green:43.0 / 255.0
blue:43.0 / 255.0
alpha:1.0];
} else {
return [UIColor colorWithRed:209.0 / 255.0
green:211.0 / 255.0
blue:219.0 / 255.0
alpha:1.0];
}
}];
self.contentView.backgroundColor = kbBgColor;
self.bgImageView.backgroundColor = kbBgColor;
} else {
UIColor *darkColor = [UIColor colorWithRed:43.0 / 255.0
green:43.0 / 255.0
blue:43.0 / 255.0
alpha:1.0];
self.contentView.backgroundColor = darkColor;
self.bgImageView.backgroundColor = darkColor;
}
} else {
// 使
if (size.width <= 0 || size.height <= 0) { if (size.width <= 0 || size.height <= 0) {
[self.view layoutIfNeeded]; [self.view layoutIfNeeded];
size = self.bgImageView.bounds.size; size = self.bgImageView.bounds.size;
@@ -752,15 +923,24 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
if (size.width <= 0 || size.height <= 0) { if (size.width <= 0 || size.height <= 0) {
size = [UIScreen mainScreen].bounds.size; size = [UIScreen mainScreen].bounds.size;
} }
img = [self kb_defaultGradientImageWithSize:size]; UIColor *topColor = [UIColor colorWithHex:0xDEDFE4];
UIColor *bottomColor = [UIColor colorWithHex:0xD1D3DB];
img = [self kb_defaultGradientImageWithSize:size
topColor:topColor
bottomColor:bottomColor];
self.contentView.backgroundColor = [UIColor clearColor];
self.bgImageView.backgroundColor = [UIColor clearColor];
}
NSLog(@"===");
} else {
// 使
self.contentView.backgroundColor = [UIColor clearColor];
self.bgImageView.backgroundColor = [UIColor clearColor];
} }
NSLog(@"⌨️[Keyboard] apply theme id=%@ hasBg=%d", t.skinId, (img != nil)); NSLog(@"⌨️[Keyboard] apply theme id=%@ hasBg=%d", t.skinId, (img != nil));
[self kb_logSkinDiagnosticsWithTheme:t backgroundImage:img]; [self kb_logSkinDiagnosticsWithTheme:t backgroundImage:img];
self.bgImageView.image = img; self.bgImageView.image = img;
BOOL hasImg = (img != nil); BOOL hasImg = (img != nil);
self.view.backgroundColor = hasImg ? [UIColor clearColor] : t.keyboardBackground;
self.contentView.backgroundColor = hasImg ? [UIColor clearColor] : t.keyboardBackground;
self.keyBoardMainView.backgroundColor = hasImg ? [UIColor clearColor] : t.keyboardBackground;
// //
if ([self.keyBoardMainView respondsToSelector:@selector(kb_applyTheme)]) { if ([self.keyBoardMainView respondsToSelector:@selector(kb_applyTheme)]) {
// method declared in KBKeyBoardMainView.h // method declared in KBKeyBoardMainView.h
@@ -796,23 +976,39 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
} }
- (NSString *)kb_defaultSkinIdForCurrentStyle { - (NSString *)kb_defaultSkinIdForCurrentStyle {
return [self kb_isDarkModeActive] ? kKBDefaultSkinIdDark : kKBDefaultSkinIdLight; return [self kb_isDarkModeActive] ? kKBDefaultSkinIdDark
: kKBDefaultSkinIdLight;
} }
- (NSString *)kb_defaultSkinZipNameForCurrentStyle { - (NSString *)kb_defaultSkinZipNameForCurrentStyle {
return [self kb_isDarkModeActive] ? kKBDefaultSkinZipNameDark : kKBDefaultSkinZipNameLight; return [self kb_isDarkModeActive] ? kKBDefaultSkinZipNameDark
: kKBDefaultSkinZipNameLight;
}
- (UIImage *)kb_defaultGradientImageWithSize:(CGSize)size
topColor:(UIColor *)topColor
bottomColor:(UIColor *)bottomColor {
if (size.width <= 0 || size.height <= 0) {
return nil;
}
// trait collection
// UIGraphicsBeginImageContextWithOptions 使
UIColor *resolvedTopColor = topColor;
UIColor *resolvedBottomColor = bottomColor;
if (@available(iOS 13.0, *)) {
resolvedTopColor =
[topColor resolvedColorWithTraitCollection:self.traitCollection];
resolvedBottomColor =
[bottomColor resolvedColorWithTraitCollection:self.traitCollection];
} }
- (UIImage *)kb_defaultGradientImageWithSize:(CGSize)size {
if (size.width <= 0 || size.height <= 0) { return nil; }
CAGradientLayer *layer = [CAGradientLayer layer]; CAGradientLayer *layer = [CAGradientLayer layer];
layer.frame = CGRectMake(0, 0, size.width, size.height); layer.frame = CGRectMake(0, 0, size.width, size.height);
layer.startPoint = CGPointMake(0.5, 0.0); layer.startPoint = CGPointMake(0.5, 0.0);
layer.endPoint = CGPointMake(0.5, 1.0); layer.endPoint = CGPointMake(0.5, 1.0);
layer.colors = @[ layer.colors =
(id)[UIColor colorWithHex:0xDEDFE4].CGColor, @[ (id)resolvedTopColor.CGColor, (id)resolvedBottomColor.CGColor ];
(id)[UIColor colorWithHex:0xD1D3DB].CGColor
];
UIGraphicsBeginImageContextWithOptions(size, YES, 0); UIGraphicsBeginImageContextWithOptions(size, YES, 0);
[layer renderInContext:UIGraphicsGetCurrentContext()]; [layer renderInContext:UIGraphicsGetCurrentContext()];
@@ -827,11 +1023,14 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
NSString *skinId = theme.skinId ?: @""; NSString *skinId = theme.skinId ?: @"";
NSString *name = theme.name ?: @""; NSString *name = theme.name ?: @"";
NSMutableArray<NSString *> *roots = [NSMutableArray array]; NSMutableArray<NSString *> *roots = [NSMutableArray array];
NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:AppGroup]; NSURL *containerURL = [[NSFileManager defaultManager]
containerURLForSecurityApplicationGroupIdentifier:AppGroup];
if (containerURL.path.length > 0) { if (containerURL.path.length > 0) {
[roots addObject:containerURL.path]; [roots addObject:containerURL.path];
} }
NSString *cacheRoot = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; NSString *cacheRoot = NSSearchPathForDirectoriesInDomains(
NSCachesDirectory, NSUserDomainMask, YES)
.firstObject;
if (cacheRoot.length > 0) { if (cacheRoot.length > 0) {
[roots addObject:cacheRoot]; [roots addObject:cacheRoot];
} }
@@ -844,36 +1043,58 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
iconsDir = [iconsDir stringByAppendingPathComponent:@"icons"]; iconsDir = [iconsDir stringByAppendingPathComponent:@"icons"];
BOOL isDir = NO; BOOL isDir = NO;
BOOL exists = [fm fileExistsAtPath:iconsDir isDirectory:&isDir] && isDir; BOOL exists = [fm fileExistsAtPath:iconsDir isDirectory:&isDir] && isDir;
NSArray *contents = exists ? [fm contentsOfDirectoryAtPath:iconsDir error:nil] : nil; NSArray *contents =
exists ? [fm contentsOfDirectoryAtPath:iconsDir error:nil] : nil;
NSUInteger count = contents.count; NSUInteger count = contents.count;
BOOL hasQ = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_q.png"]]; BOOL hasQ =
BOOL hasQUp = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_q_up.png"]]; exists &&
BOOL hasDel = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_del.png"]]; [fm fileExistsAtPath:[iconsDir
BOOL hasShift = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_up.png"]]; stringByAppendingPathComponent:@"key_q.png"]];
BOOL hasShiftUpper = exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:@"key_up_upper.png"]]; BOOL hasQUp =
NSString *line = [NSString stringWithFormat:@"root=%@ icons=%@ exist=%d count=%tu key_q=%d key_q_up=%d key_del=%d key_up=%d key_up_upper=%d", exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:
root, iconsDir, exists, count, hasQ, hasQUp, hasDel, hasShift, hasShiftUpper]; @"key_q_up.png"]];
BOOL hasDel =
exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:
@"key_del.png"]];
BOOL hasShift =
exists &&
[fm fileExistsAtPath:[iconsDir
stringByAppendingPathComponent:@"key_up.png"]];
BOOL hasShiftUpper =
exists && [fm fileExistsAtPath:[iconsDir stringByAppendingPathComponent:
@"key_up_upper.png"]];
NSString *line = [NSString
stringWithFormat:@"root=%@ icons=%@ exist=%d count=%tu key_q=%d "
@"key_q_up=%d key_del=%d key_up=%d key_up_upper=%d",
root, iconsDir, exists, count, hasQ, hasQUp, hasDel,
hasShift, hasShiftUpper];
[lines addObject:line]; [lines addObject:line];
} }
NSLog(@"[Keyboard] theme id=%@ name=%@ hasBg=%d\n%@", NSLog(@"[Keyboard] theme id=%@ name=%@ hasBg=%d\n%@", skinId, name,
skinId, name, (image != nil), [lines componentsJoinedByString:@"\n"]); (image != nil), [lines componentsJoinedByString:@"\n"]);
#endif #endif
} }
- (void)kb_consumePendingShopSkin { - (void)kb_consumePendingShopSkin {
KBWeakSelf KBWeakSelf [KBSkinInstallBridge
[KBSkinInstallBridge consumePendingRequestFromBundle:NSBundle.mainBundle consumePendingRequestFromBundle:NSBundle.mainBundle
completion:^(BOOL success, NSError * _Nullable error) { completion:^(BOOL success,
NSError *_Nullable error) {
if (!success) { if (!success) {
if (error) { if (error) {
NSLog(@"[Keyboard] skin request failed: %@", error); NSLog(@"[Keyboard] skin request failed: %@",
[KBHUD showInfo:KBLocalized(@"皮肤资源准备失败,请稍后再试")]; error);
[KBHUD
showInfo:
KBLocalized(
@"皮肤资源准备失败,请稍后再试")];
} }
return; return;
} }
[weakSelf kb_applyTheme]; [weakSelf kb_applyTheme];
[KBHUD showInfo:KBLocalized(@"皮肤已更新,立即体验吧")]; [KBHUD showInfo:KBLocalized(
@"皮肤已更新,立即体验吧")];
}]; }];
} }
@@ -886,7 +1107,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
} }
NSString *currentId = [KBSkinManager shared].current.skinId ?: @""; NSString *currentId = [KBSkinManager shared].current.skinId ?: @"";
BOOL isDefault = (currentId.length == 0 || [currentId isEqualToString:@"default"]); BOOL isDefault =
(currentId.length == 0 || [currentId isEqualToString:@"default"]);
BOOL isLightDefault = [currentId isEqualToString:kKBDefaultSkinIdLight]; BOOL isLightDefault = [currentId isEqualToString:kKBDefaultSkinIdLight];
BOOL isDarkDefault = [currentId isEqualToString:kKBDefaultSkinIdDark]; BOOL isDarkDefault = [currentId isEqualToString:kKBDefaultSkinIdDark];
if (!isDefault && !isLightDefault && !isDarkDefault) { if (!isDefault && !isLightDefault && !isDarkDefault) {
@@ -895,10 +1117,13 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
} }
NSString *targetId = [self kb_defaultSkinIdForCurrentStyle]; NSString *targetId = [self kb_defaultSkinIdForCurrentStyle];
NSString *targetZip = [self kb_defaultSkinZipNameForCurrentStyle]; NSString *targetZip = [self kb_defaultSkinZipNameForCurrentStyle];
if (currentId.length > 0 && [currentId isEqualToString:targetId]) { return; } if (currentId.length > 0 && [currentId isEqualToString:targetId]) {
return;
}
NSError *applyError = nil; NSError *applyError = nil;
if ([KBSkinInstallBridge applyInstalledSkinWithId:targetId error:&applyError]) { if ([KBSkinInstallBridge applyInstalledSkinWithId:targetId
error:&applyError]) {
return; return;
} }
@@ -906,8 +1131,10 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
name:targetId name:targetId
zipName:targetZip zipName:targetZip
iconShortNames:nil]; iconShortNames:nil];
[KBSkinInstallBridge consumePendingRequestFromBundle:NSBundle.mainBundle [KBSkinInstallBridge
completion:^(__unused BOOL success, __unused NSError * _Nullable error) { consumePendingRequestFromBundle:NSBundle.mainBundle
completion:^(__unused BOOL success,
__unused NSError *_Nullable error){
// //
}]; }];
} }
@@ -920,7 +1147,9 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
} }
- (CGFloat)kb_keyboardHeightForWidth:(CGFloat)width { - (CGFloat)kb_keyboardHeightForWidth:(CGFloat)width {
if (width <= 0) { width = KB_DESIGN_WIDTH; } if (width <= 0) {
width = KB_DESIGN_WIDTH;
}
return kKBKeyboardBaseHeight * (width / KB_DESIGN_WIDTH); return kKBKeyboardBaseHeight * (width / KB_DESIGN_WIDTH);
} }
@@ -936,8 +1165,10 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
} }
BOOL widthChanged = (fabs(self.kb_lastPortraitWidth - portraitWidth) >= 0.5); BOOL widthChanged = (fabs(self.kb_lastPortraitWidth - portraitWidth) >= 0.5);
BOOL heightChanged = (fabs(self.kb_lastKeyboardHeight - keyboardHeight) >= 0.5); BOOL heightChanged =
if (!widthChanged && !heightChanged && containerWidth > 0 && self.kb_widthConstraint.constant == containerWidth) { (fabs(self.kb_lastKeyboardHeight - keyboardHeight) >= 0.5);
if (!widthChanged && !heightChanged && containerWidth > 0 &&
self.kb_widthConstraint.constant == containerWidth) {
return; return;
} }
self.kb_lastPortraitWidth = portraitWidth; self.kb_lastPortraitWidth = portraitWidth;

View File

@@ -8,7 +8,7 @@
// - 兼容后端“/t”作为分段标记可自动替换为制表符“\t” // - 兼容后端“/t”作为分段标记可自动替换为制表符“\t”
// - 首段去首个“\t”若首次正文以一个制表符起始允许前导空白可只移除“一个”\t // - 首段去首个“\t”若首次正文以一个制表符起始允许前导空白可只移除“一个”\t
// //
// 暂未使用
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@@ -4,7 +4,7 @@
// //
// Created by Mac on 2025/11/12. // Created by Mac on 2025/11/12.
// //
// 暂未使用
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@@ -255,11 +255,8 @@
- (void)kb_applyTheme { - (void)kb_applyTheme {
KBSkinManager *mgr = [KBSkinManager shared]; KBSkinManager *mgr = [KBSkinManager shared];
BOOL hasImg = ([mgr currentBackgroundImage] != nil); self.backgroundColor = [UIColor clearColor];
// UIColor *bg = mgr.current.keyboardBackground; self.keyboardView.backgroundColor = [UIColor clearColor];
UIColor *bg = [UIColor colorWithHex:0xD1D3DB];
self.backgroundColor = hasImg ? [UIColor clearColor] : bg;
self.keyboardView.backgroundColor = hasImg ? [UIColor clearColor] : bg;
if ([self.topBar respondsToSelector:@selector(kb_applyTheme)]) { if ([self.topBar respondsToSelector:@selector(kb_applyTheme)]) {
[self.topBar kb_applyTheme]; [self.topBar kb_applyTheme];
} }

View File

@@ -83,6 +83,10 @@
if (CGRectGetHeight(bounds) <= 0 || CGRectGetWidth(bounds) <= 0) { if (CGRectGetHeight(bounds) <= 0 || CGRectGetWidth(bounds) <= 0) {
return; return;
} }
//
if (self.iconView.image != nil) {
self.titleLabel.hidden = YES;
}
self.bottomShadowLayer.frame = CGRectMake(0, self.bottomShadowLayer.frame = CGRectMake(0,
CGRectGetHeight(bounds) - shadowHeight, CGRectGetHeight(bounds) - shadowHeight,
CGRectGetWidth(bounds), CGRectGetWidth(bounds),

View File

@@ -41,7 +41,7 @@ static const CGFloat kKBLettersRow2EdgeSpacerMultiplier = 0.5;
- (instancetype)initWithFrame:(CGRect)frame { - (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) { if (self = [super initWithFrame:frame]) {
self.backgroundColor = [KBSkinManager shared].current.keyboardBackground; self.backgroundColor = [UIColor clearColor];
_layoutStyle = KBKeyboardLayoutStyleLetters; _layoutStyle = KBKeyboardLayoutStyleLetters;
// Shift // Shift
_shiftOn = NO; _shiftOn = NO;

View File

@@ -68,7 +68,7 @@
#define API_SUBSCRIPTION_PRODUCT_LIST @"/products/subscription/list" // 查询订阅商品列表 #define API_SUBSCRIPTION_PRODUCT_LIST @"/products/subscription/list" // 查询订阅商品列表
/// AI /// AI
#define API_AI_TALK @"/chat/talk" // 排行榜标签列表 #define API_AI_TALK @"/chat/talk"

View File

@@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
04050ECB2F10FB8F008051EB /* UIImage+KBColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 047C655D2EBCD5B20035E841 /* UIImage+KBColor.m */; };
041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */ = {isa = PBXBuildFile; fileRef = 041007D12ECE012000D203BB /* KBSkinIconMap.strings */; }; 041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */ = {isa = PBXBuildFile; fileRef = 041007D12ECE012000D203BB /* KBSkinIconMap.strings */; };
041007D42ECE012500D203BB /* 002.zip in Resources */ = {isa = PBXBuildFile; fileRef = 041007D32ECE012500D203BB /* 002.zip */; }; 041007D42ECE012500D203BB /* 002.zip in Resources */ = {isa = PBXBuildFile; fileRef = 041007D32ECE012500D203BB /* 002.zip */; };
04122F5D2EC5E5A900EF7AB3 /* KBLoginVM.m in Sources */ = {isa = PBXBuildFile; fileRef = 04122F5B2EC5E5A900EF7AB3 /* KBLoginVM.m */; }; 04122F5D2EC5E5A900EF7AB3 /* KBLoginVM.m in Sources */ = {isa = PBXBuildFile; fileRef = 04122F5B2EC5E5A900EF7AB3 /* KBLoginVM.m */; };
@@ -67,7 +68,6 @@
04791F982ED49CE7004E8522 /* KBFont.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791F972ED49CE7004E8522 /* KBFont.m */; }; 04791F982ED49CE7004E8522 /* KBFont.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791F972ED49CE7004E8522 /* KBFont.m */; };
04791F992ED49CE7004E8522 /* KBFont.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791F972ED49CE7004E8522 /* KBFont.m */; }; 04791F992ED49CE7004E8522 /* KBFont.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791F972ED49CE7004E8522 /* KBFont.m */; };
04791FF72ED5B985004E8522 /* Christmas.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04791FF62ED5B985004E8522 /* Christmas.zip */; }; 04791FF72ED5B985004E8522 /* Christmas.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04791FF62ED5B985004E8522 /* Christmas.zip */; };
04791FFB2ED5EAB8004E8522 /* normal_hei_them.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04791FFA2ED5EAB8004E8522 /* normal_hei_them.zip */; };
04791FFC2ED71D17004E8522 /* UIColor+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95E42EB220B5007BD342 /* UIColor+Extension.m */; }; 04791FFC2ED71D17004E8522 /* UIColor+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95E42EB220B5007BD342 /* UIColor+Extension.m */; };
04791FFF2ED830FA004E8522 /* KBKeyboardMaskView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791FFE2ED830FA004E8522 /* KBKeyboardMaskView.m */; }; 04791FFF2ED830FA004E8522 /* KBKeyboardMaskView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04791FFE2ED830FA004E8522 /* KBKeyboardMaskView.m */; };
047920072ED86ABC004E8522 /* kb_guide_keyboard.gif in Resources */ = {isa = PBXBuildFile; fileRef = 047920062ED86ABC004E8522 /* kb_guide_keyboard.gif */; }; 047920072ED86ABC004E8522 /* kb_guide_keyboard.gif in Resources */ = {isa = PBXBuildFile; fileRef = 047920062ED86ABC004E8522 /* kb_guide_keyboard.gif */; };
@@ -145,8 +145,6 @@
049FB2292EC31BB000FAB05D /* KBChangeNicknamePopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2282EC31BB000FAB05D /* KBChangeNicknamePopView.m */; }; 049FB2292EC31BB000FAB05D /* KBChangeNicknamePopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2282EC31BB000FAB05D /* KBChangeNicknamePopView.m */; };
049FB22C2EC31F8800FAB05D /* KBGenderPickerPopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB22B2EC31F8800FAB05D /* KBGenderPickerPopView.m */; }; 049FB22C2EC31F8800FAB05D /* KBGenderPickerPopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB22B2EC31F8800FAB05D /* KBGenderPickerPopView.m */; };
049FB22F2EC34EB900FAB05D /* KBStreamTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB22E2EC34EB900FAB05D /* KBStreamTextView.m */; }; 049FB22F2EC34EB900FAB05D /* KBStreamTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB22E2EC34EB900FAB05D /* KBStreamTextView.m */; };
049FB2322EC45A0000FAB05D /* KBStreamFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2312EC45A0000FAB05D /* KBStreamFetcher.m */; };
049FB2352EC45C6A00FAB05D /* NetworkStreamHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2342EC45C6A00FAB05D /* NetworkStreamHandler.m */; };
049FB23B2EC4766700FAB05D /* KBFunctionTagListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2372EC4766700FAB05D /* KBFunctionTagListView.m */; }; 049FB23B2EC4766700FAB05D /* KBFunctionTagListView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2372EC4766700FAB05D /* KBFunctionTagListView.m */; };
049FB23C2EC4766700FAB05D /* KBStreamOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2392EC4766700FAB05D /* KBStreamOverlayView.m */; }; 049FB23C2EC4766700FAB05D /* KBStreamOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2392EC4766700FAB05D /* KBStreamOverlayView.m */; };
049FB23F2EC4B6EF00FAB05D /* KBULBridgeNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB23E2EC4B6EF00FAB05D /* KBULBridgeNotification.m */; }; 049FB23F2EC4B6EF00FAB05D /* KBULBridgeNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB23E2EC4B6EF00FAB05D /* KBULBridgeNotification.m */; };
@@ -172,7 +170,8 @@
04C6EADD2EAF8CEB0089C901 /* KBToolBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 04C6EADC2EAF8CEB0089C901 /* KBToolBar.m */; }; 04C6EADD2EAF8CEB0089C901 /* KBToolBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 04C6EADC2EAF8CEB0089C901 /* KBToolBar.m */; };
04D1F6B22EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */; }; 04D1F6B22EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */; };
04D1F6B32EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */; }; 04D1F6B32EDFF10A00B12345 /* KBSkinInstallBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */; };
04E1617C2F0FCA050022C23B /* normal_them.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04E1617B2F0FCA050022C23B /* normal_them.zip */; }; 04E161832F10E6470022C23B /* normal_hei_them.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04E161812F10E6470022C23B /* normal_hei_them.zip */; };
04E161842F10E6470022C23B /* normal_them.zip in Resources */ = {isa = PBXBuildFile; fileRef = 04E161822F10E6470022C23B /* normal_them.zip */; };
04FC95672EB0546C007BD342 /* KBKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95652EB0546C007BD342 /* KBKey.m */; }; 04FC95672EB0546C007BD342 /* KBKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95652EB0546C007BD342 /* KBKey.m */; };
04FC956A2EB05497007BD342 /* KBKeyButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95692EB05497007BD342 /* KBKeyButton.m */; }; 04FC956A2EB05497007BD342 /* KBKeyButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95692EB05497007BD342 /* KBKeyButton.m */; };
04FC956D2EB054B7007BD342 /* KBKeyboardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC956C2EB054B7007BD342 /* KBKeyboardView.m */; }; 04FC956D2EB054B7007BD342 /* KBKeyboardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC956C2EB054B7007BD342 /* KBKeyboardView.m */; };
@@ -351,7 +350,6 @@
04791F962ED49CE7004E8522 /* KBFont.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBFont.h; sourceTree = "<group>"; }; 04791F962ED49CE7004E8522 /* KBFont.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBFont.h; sourceTree = "<group>"; };
04791F972ED49CE7004E8522 /* KBFont.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBFont.m; sourceTree = "<group>"; }; 04791F972ED49CE7004E8522 /* KBFont.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBFont.m; sourceTree = "<group>"; };
04791FF62ED5B985004E8522 /* Christmas.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = Christmas.zip; sourceTree = "<group>"; }; 04791FF62ED5B985004E8522 /* Christmas.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = Christmas.zip; sourceTree = "<group>"; };
04791FFA2ED5EAB8004E8522 /* normal_hei_them.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = normal_hei_them.zip; sourceTree = "<group>"; };
04791FFD2ED830FA004E8522 /* KBKeyboardMaskView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKeyboardMaskView.h; sourceTree = "<group>"; }; 04791FFD2ED830FA004E8522 /* KBKeyboardMaskView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKeyboardMaskView.h; sourceTree = "<group>"; };
04791FFE2ED830FA004E8522 /* KBKeyboardMaskView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKeyboardMaskView.m; sourceTree = "<group>"; }; 04791FFE2ED830FA004E8522 /* KBKeyboardMaskView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKeyboardMaskView.m; sourceTree = "<group>"; };
047920062ED86ABC004E8522 /* kb_guide_keyboard.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = kb_guide_keyboard.gif; sourceTree = "<group>"; }; 047920062ED86ABC004E8522 /* kb_guide_keyboard.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = kb_guide_keyboard.gif; sourceTree = "<group>"; };
@@ -495,10 +493,6 @@
049FB22B2EC31F8800FAB05D /* KBGenderPickerPopView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBGenderPickerPopView.m; sourceTree = "<group>"; }; 049FB22B2EC31F8800FAB05D /* KBGenderPickerPopView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBGenderPickerPopView.m; sourceTree = "<group>"; };
049FB22D2EC34EB900FAB05D /* KBStreamTextView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBStreamTextView.h; sourceTree = "<group>"; }; 049FB22D2EC34EB900FAB05D /* KBStreamTextView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBStreamTextView.h; sourceTree = "<group>"; };
049FB22E2EC34EB900FAB05D /* KBStreamTextView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBStreamTextView.m; sourceTree = "<group>"; }; 049FB22E2EC34EB900FAB05D /* KBStreamTextView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBStreamTextView.m; sourceTree = "<group>"; };
049FB2302EC45A0000FAB05D /* KBStreamFetcher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBStreamFetcher.h; sourceTree = "<group>"; };
049FB2312EC45A0000FAB05D /* KBStreamFetcher.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBStreamFetcher.m; sourceTree = "<group>"; };
049FB2332EC45C6A00FAB05D /* NetworkStreamHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NetworkStreamHandler.h; sourceTree = "<group>"; };
049FB2342EC45C6A00FAB05D /* NetworkStreamHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NetworkStreamHandler.m; sourceTree = "<group>"; };
049FB2362EC4766700FAB05D /* KBFunctionTagListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBFunctionTagListView.h; sourceTree = "<group>"; }; 049FB2362EC4766700FAB05D /* KBFunctionTagListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBFunctionTagListView.h; sourceTree = "<group>"; };
049FB2372EC4766700FAB05D /* KBFunctionTagListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBFunctionTagListView.m; sourceTree = "<group>"; }; 049FB2372EC4766700FAB05D /* KBFunctionTagListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBFunctionTagListView.m; sourceTree = "<group>"; };
049FB2382EC4766700FAB05D /* KBStreamOverlayView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBStreamOverlayView.h; sourceTree = "<group>"; }; 049FB2382EC4766700FAB05D /* KBStreamOverlayView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBStreamOverlayView.h; sourceTree = "<group>"; };
@@ -540,7 +534,8 @@
04C6EAE12EAF940F0089C901 /* KBPermissionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPermissionViewController.m; sourceTree = "<group>"; }; 04C6EAE12EAF940F0089C901 /* KBPermissionViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPermissionViewController.m; sourceTree = "<group>"; };
04D1F6B02EDFF10A00B12345 /* KBSkinInstallBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinInstallBridge.h; sourceTree = "<group>"; }; 04D1F6B02EDFF10A00B12345 /* KBSkinInstallBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSkinInstallBridge.h; sourceTree = "<group>"; };
04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinInstallBridge.m; sourceTree = "<group>"; }; 04D1F6B12EDFF10A00B12345 /* KBSkinInstallBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSkinInstallBridge.m; sourceTree = "<group>"; };
04E1617B2F0FCA050022C23B /* normal_them.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = normal_them.zip; sourceTree = "<group>"; }; 04E161812F10E6470022C23B /* normal_hei_them.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = normal_hei_them.zip; sourceTree = "<group>"; };
04E161822F10E6470022C23B /* normal_them.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = normal_them.zip; sourceTree = "<group>"; };
04FC953A2EAFAE56007BD342 /* KeyBoardPrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyBoardPrefixHeader.pch; sourceTree = "<group>"; }; 04FC953A2EAFAE56007BD342 /* KeyBoardPrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyBoardPrefixHeader.pch; sourceTree = "<group>"; };
04FC95642EB0546C007BD342 /* KBKey.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKey.h; sourceTree = "<group>"; }; 04FC95642EB0546C007BD342 /* KBKey.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKey.h; sourceTree = "<group>"; };
04FC95652EB0546C007BD342 /* KBKey.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKey.m; sourceTree = "<group>"; }; 04FC95652EB0546C007BD342 /* KBKey.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKey.m; sourceTree = "<group>"; };
@@ -691,13 +686,13 @@
041007D02ECE010100D203BB /* Resource */ = { 041007D02ECE010100D203BB /* Resource */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
04E1617B2F0FCA050022C23B /* normal_them.zip */, 04E161812F10E6470022C23B /* normal_hei_them.zip */,
04E161822F10E6470022C23B /* normal_them.zip */,
A1B2C3EC2F20000000000001 /* kb_words.txt */, A1B2C3EC2F20000000000001 /* kb_words.txt */,
A1B2C3F02F20000000000002 /* kb_keyboard_layout_config.json */, A1B2C3F02F20000000000002 /* kb_keyboard_layout_config.json */,
0498BDF42EEC50EE006CC1D5 /* emoji_categories.json */, 0498BDF42EEC50EE006CC1D5 /* emoji_categories.json */,
041007D12ECE012000D203BB /* KBSkinIconMap.strings */, 041007D12ECE012000D203BB /* KBSkinIconMap.strings */,
041007D32ECE012500D203BB /* 002.zip */, 041007D32ECE012500D203BB /* 002.zip */,
04791FFA2ED5EAB8004E8522 /* normal_hei_them.zip */,
04791FF62ED5B985004E8522 /* Christmas.zip */, 04791FF62ED5B985004E8522 /* Christmas.zip */,
); );
path = Resource; path = Resource;
@@ -1726,10 +1721,6 @@
0498BDD92EE7ECEA006CC1D5 /* WJXEventSource */, 0498BDD92EE7ECEA006CC1D5 /* WJXEventSource */,
A1B2C3E02EB0C0A100000001 /* KBNetworkManager.h */, A1B2C3E02EB0C0A100000001 /* KBNetworkManager.h */,
A1B2C3E12EB0C0A100000001 /* KBNetworkManager.m */, A1B2C3E12EB0C0A100000001 /* KBNetworkManager.m */,
049FB2302EC45A0000FAB05D /* KBStreamFetcher.h */,
049FB2312EC45A0000FAB05D /* KBStreamFetcher.m */,
049FB2332EC45C6A00FAB05D /* NetworkStreamHandler.h */,
049FB2342EC45C6A00FAB05D /* NetworkStreamHandler.m */,
); );
path = Network; path = Network;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1824,13 +1815,13 @@
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
04E161832F10E6470022C23B /* normal_hei_them.zip in Resources */,
04E161842F10E6470022C23B /* normal_them.zip in Resources */,
04A9FE202EB893F10020DB6D /* Localizable.strings in Resources */, 04A9FE202EB893F10020DB6D /* Localizable.strings in Resources */,
041007D42ECE012500D203BB /* 002.zip in Resources */, 041007D42ECE012500D203BB /* 002.zip in Resources */,
04E1617C2F0FCA050022C23B /* normal_them.zip in Resources */,
041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */, 041007D22ECE012000D203BB /* KBSkinIconMap.strings in Resources */,
A1B2C3ED2F20000000000001 /* kb_words.txt in Resources */, A1B2C3ED2F20000000000001 /* kb_words.txt in Resources */,
A1B2C3F12F20000000000002 /* kb_keyboard_layout_config.json in Resources */, A1B2C3F12F20000000000002 /* kb_keyboard_layout_config.json in Resources */,
04791FFB2ED5EAB8004E8522 /* normal_hei_them.zip in Resources */,
0498BDF52EEC50EE006CC1D5 /* emoji_categories.json in Resources */, 0498BDF52EEC50EE006CC1D5 /* emoji_categories.json in Resources */,
04791FF72ED5B985004E8522 /* Christmas.zip in Resources */, 04791FF72ED5B985004E8522 /* Christmas.zip in Resources */,
04286A0B2ECD88B400CE730C /* KeyboardAssets.xcassets in Resources */, 04286A0B2ECD88B400CE730C /* KeyboardAssets.xcassets in Resources */,
@@ -1930,13 +1921,13 @@
files = ( files = (
0498BD862EE1BEC9006CC1D5 /* KBSignUtils.m in Sources */, 0498BD862EE1BEC9006CC1D5 /* KBSignUtils.m in Sources */,
04791FFC2ED71D17004E8522 /* UIColor+Extension.m in Sources */, 04791FFC2ED71D17004E8522 /* UIColor+Extension.m in Sources */,
049FB2322EC45A0000FAB05D /* KBStreamFetcher.m in Sources */,
0450AC4A2EF2C3ED00B6AF06 /* KBKeyboardSubscriptionOptionCell.m in Sources */, 0450AC4A2EF2C3ED00B6AF06 /* KBKeyboardSubscriptionOptionCell.m in Sources */,
04A9FE0F2EB481100020DB6D /* KBHUD.m in Sources */, 04A9FE0F2EB481100020DB6D /* KBHUD.m in Sources */,
04C6EADD2EAF8CEB0089C901 /* KBToolBar.m in Sources */, 04C6EADD2EAF8CEB0089C901 /* KBToolBar.m in Sources */,
A1B2C3EB2F20000000000001 /* KBSuggestionBarView.m in Sources */, A1B2C3EB2F20000000000001 /* KBSuggestionBarView.m in Sources */,
04FC95792EB09BC8007BD342 /* KBKeyBoardMainView.m in Sources */, 04FC95792EB09BC8007BD342 /* KBKeyBoardMainView.m in Sources */,
04FEDAB32EEDB05000123456 /* KBEmojiPanelView.m in Sources */, 04FEDAB32EEDB05000123456 /* KBEmojiPanelView.m in Sources */,
04050ECB2F10FB8F008051EB /* UIImage+KBColor.m in Sources */,
04FEDB032EFE000000123456 /* KBEmojiBottomBarView.m in Sources */, 04FEDB032EFE000000123456 /* KBEmojiBottomBarView.m in Sources */,
0498BD8C2EE69E15006CC1D5 /* KBTagItemModel.m in Sources */, 0498BD8C2EE69E15006CC1D5 /* KBTagItemModel.m in Sources */,
046131142ECF454500A6FADF /* KBKeyPreviewView.m in Sources */, 046131142ECF454500A6FADF /* KBKeyPreviewView.m in Sources */,
@@ -1949,7 +1940,6 @@
04A9FE1A2EB892460020DB6D /* KBLocalizationManager.m in Sources */, 04A9FE1A2EB892460020DB6D /* KBLocalizationManager.m in Sources */,
A1B2C3EA2F20000000000001 /* KBSuggestionEngine.m in Sources */, A1B2C3EA2F20000000000001 /* KBSuggestionEngine.m in Sources */,
A1B2C3E22EB0C0A100000001 /* KBNetworkManager.m in Sources */, A1B2C3E22EB0C0A100000001 /* KBNetworkManager.m in Sources */,
049FB2352EC45C6A00FAB05D /* NetworkStreamHandler.m in Sources */,
04FC956A2EB05497007BD342 /* KBKeyButton.m in Sources */, 04FC956A2EB05497007BD342 /* KBKeyButton.m in Sources */,
04FEDAA12EEDB00100123456 /* KBEmojiDataProvider.m in Sources */, 04FEDAA12EEDB00100123456 /* KBEmojiDataProvider.m in Sources */,
04FC95B22EB0B2CC007BD342 /* KBSettingView.m in Sources */, 04FC95B22EB0B2CC007BD342 /* KBSettingView.m in Sources */,