2
22
CustomKeyboard/KeyboardAssets.xcassets/home_ai_icon.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "home_ai_icon@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "home_ai_icon@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
CustomKeyboard/KeyboardAssets.xcassets/home_ai_icon.imageset/home_ai_icon@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
CustomKeyboard/KeyboardAssets.xcassets/home_ai_icon.imageset/home_ai_icon@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 18 KiB |
22
CustomKeyboard/KeyboardAssets.xcassets/home_chat_icon.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "home_chat_icon@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "home_chat_icon@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
CustomKeyboard/KeyboardAssets.xcassets/home_chat_icon.imageset/home_chat_icon@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
CustomKeyboard/KeyboardAssets.xcassets/home_chat_icon.imageset/home_chat_icon@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 16 KiB |
22
CustomKeyboard/KeyboardAssets.xcassets/home_emotion_icon.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "home_emotion_icon@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "home_emotion_icon@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
CustomKeyboard/KeyboardAssets.xcassets/home_emotion_icon.imageset/home_emotion_icon@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 9.3 KiB |
BIN
CustomKeyboard/KeyboardAssets.xcassets/home_emotion_icon.imageset/home_emotion_icon@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 18 KiB |
22
CustomKeyboard/KeyboardAssets.xcassets/home_keyboard_icon.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "home_keyboard_icon@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "home_keyboard_icon@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
CustomKeyboard/KeyboardAssets.xcassets/home_keyboard_icon.imageset/home_keyboard_icon@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
CustomKeyboard/KeyboardAssets.xcassets/home_keyboard_icon.imageset/home_keyboard_icon@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 25 KiB |
22
CustomKeyboard/KeyboardAssets.xcassets/keybord_bg_icon.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "keybord_bg_icon@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "keybord_bg_icon@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
CustomKeyboard/KeyboardAssets.xcassets/keybord_bg_icon.imageset/keybord_bg_icon@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 486 KiB |
BIN
CustomKeyboard/KeyboardAssets.xcassets/keybord_bg_icon.imageset/keybord_bg_icon@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
@@ -299,6 +299,10 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
|
||||
}
|
||||
}
|
||||
|
||||
- (void)functionViewDidRequestSubscription:(KBFunctionView *)functionView {
|
||||
[self showSubscriptionPanel];
|
||||
}
|
||||
|
||||
#pragma mark - KBKeyboardSubscriptionViewDelegate
|
||||
|
||||
- (void)subscriptionViewDidTapClose:(KBKeyboardSubscriptionView *)view {
|
||||
|
||||
@@ -181,13 +181,16 @@ didReceiveResponse:(NSURLResponse *)response
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session
|
||||
task:(NSURLSessionTask *)task
|
||||
task:(NSURLSessionTask *)task
|
||||
didCompleteWithError:(nullable NSError *)error;
|
||||
{
|
||||
if (_closedByUser) {
|
||||
_buffer = [NSMutableData data];
|
||||
return;
|
||||
}
|
||||
|
||||
[self _dispatchPlainBufferIfNeeded];
|
||||
|
||||
WJXEvent *event = [[WJXEvent alloc] initWithReadyState:WJXEventStateClosed];
|
||||
if (nil == (event.error = error)) {
|
||||
event.error = [NSError errorWithDomain:@"WJXEventSource" code:event.readyState userInfo:@{
|
||||
@@ -239,13 +242,16 @@ didCompleteWithError:(nullable NSError *)error;
|
||||
WJXEvent *event = [[WJXEvent alloc] initWithReadyState:WJXEventStateOpen];
|
||||
|
||||
NSString *eventString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||
if (eventString.length == 0) { return; }
|
||||
NSArray *lines = [eventString componentsSeparatedByCharactersInSet:NSCharacterSet.newlineCharacterSet];
|
||||
BOOL hasDataLine = NO;
|
||||
for (NSString *line in lines) {
|
||||
if ([line hasPrefix:@"id:"]) {
|
||||
event.eventId = [[line substringFromIndex:3] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet];
|
||||
} else if ([line hasPrefix:@"event:"]) {
|
||||
event.event = [[line substringFromIndex:6] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet];
|
||||
} else if ([line hasPrefix:@"data:"]) {
|
||||
hasDataLine = YES;
|
||||
NSString *data = [[line substringFromIndex:5] stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet];
|
||||
event.data = event.data ? [event.data stringByAppendingFormat:@"\n%@", data] : data;
|
||||
} else if ([line hasPrefix:@"retry:"]) {
|
||||
@@ -254,6 +260,13 @@ didCompleteWithError:(nullable NSError *)error;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasDataLine) {
|
||||
NSString *trimmed = [eventString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
if (trimmed.length > 0) {
|
||||
event.data = trimmed;
|
||||
}
|
||||
}
|
||||
|
||||
if (event.eventId) {
|
||||
self.lastEventId = event.eventId;
|
||||
}
|
||||
@@ -272,6 +285,15 @@ didCompleteWithError:(nullable NSError *)error;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)_dispatchPlainBufferIfNeeded
|
||||
{
|
||||
if (_buffer.length == 0) { return; }
|
||||
NSData *data = [_buffer copy];
|
||||
[_buffer setLength:0];
|
||||
if (data.length == 0) { return; }
|
||||
[self _parseEventData:data];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Setters
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
@optional
|
||||
- (void)functionView:(KBFunctionView *_Nullable)functionView didTapToolActionAtIndex:(NSInteger)index;
|
||||
- (void)functionView:(KBFunctionView *_Nullable)functionView didRightTapToolActionAtIndex:(NSInteger)index;
|
||||
- (void)functionViewDidRequestSubscription:(KBFunctionView *_Nullable)functionView;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#import "WJXEventSource.h"
|
||||
#import "KBTagItemModel.h"
|
||||
#import <MJExtension/MJExtension.h>
|
||||
#import "KBBizCode.h"
|
||||
|
||||
@interface KBFunctionView () <KBFunctionBarViewDelegate, KBStreamOverlayViewDelegate, KBFunctionTagListViewDelegate>
|
||||
// UI
|
||||
@@ -347,6 +348,7 @@
|
||||
NSError *error = nil;
|
||||
NSDictionary *payload = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
|
||||
if (error || ![payload isKindOfClass:[NSDictionary class]]) { return; }
|
||||
if ([self kb_handleBizErrorIfNeeded:payload]) { return; }
|
||||
NSString *type = payload[@"type"];
|
||||
if (![type isKindOfClass:[NSString class]]) { return; }
|
||||
|
||||
@@ -395,6 +397,32 @@
|
||||
self.eventSourceDidReceiveDone = NO;
|
||||
}
|
||||
|
||||
- (BOOL)kb_handleBizErrorIfNeeded:(NSDictionary *)payload {
|
||||
NSInteger code = KBBizCodeFromJSONObject(payload);
|
||||
if (code == NSNotFound || code == KBBizCodeSuccess) {
|
||||
return NO;
|
||||
}
|
||||
BOOL needSubscriptionGuide = (code == KBBizCodeQuotaExhausted);
|
||||
NSString *msg = KBBizMessageFromJSONObject(payload);
|
||||
if (msg.length == 0) {
|
||||
msg = KBLocalized(@"拉取失败");
|
||||
}
|
||||
NSError *bizError = [NSError errorWithDomain:@"KBStreamBizError"
|
||||
code:code
|
||||
userInfo:@{NSLocalizedDescriptionKey: msg}];
|
||||
[self kb_finishEventSourceWithError:bizError];
|
||||
if (needSubscriptionGuide) {
|
||||
[self kb_requestSubscriptionGuide];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)kb_requestSubscriptionGuide {
|
||||
if ([self.delegate respondsToSelector:@selector(functionViewDidRequestSubscription:)]) {
|
||||
[self.delegate functionViewDidRequestSubscription:self];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Event Parsing
|
||||
|
||||
- (NSString *)kb_normalizedLLMChunkString:(id)dataValue {
|
||||
|
||||
@@ -17,7 +17,7 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
|
||||
@end
|
||||
|
||||
@interface KBKeyboardSubscriptionView () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
|
||||
@property (nonatomic, strong) UIView *cardView;
|
||||
@property (nonatomic, strong) UIImageView *cardView;
|
||||
@property (nonatomic, strong) UIButton *closeButton;
|
||||
@property (nonatomic, strong) UILabel *titleLabel;
|
||||
@property (nonatomic, strong) UIScrollView *featureScrollView;
|
||||
@@ -35,7 +35,6 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
|
||||
@property (nonatomic, assign, getter=isLoading) BOOL loading;
|
||||
@property (nonatomic, strong) CADisplayLink *featureDisplayLink;
|
||||
@property (nonatomic, assign) CGFloat featureLoopWidth;
|
||||
@property (nonatomic, strong) CAGradientLayer *cardGradientLayer;
|
||||
@end
|
||||
|
||||
@implementation KBKeyboardSubscriptionView
|
||||
@@ -56,7 +55,6 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
|
||||
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
self.cardGradientLayer.frame = self.cardView.bounds;
|
||||
self.featureLoopWidth = self.featureScrollView.contentSize.width * 0.5f;
|
||||
[self startFeatureTickerIfNeeded];
|
||||
}
|
||||
@@ -98,10 +96,10 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
|
||||
- (void)setupCardView {
|
||||
[self addSubview:self.cardView];
|
||||
[self.cardView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.equalTo(self.mas_left).offset(6);
|
||||
make.right.equalTo(self.mas_right).offset(-6);
|
||||
make.top.equalTo(self.mas_top).offset(4);
|
||||
make.bottom.equalTo(self.mas_bottom).offset(-4);
|
||||
make.left.equalTo(self.mas_left).offset(0);
|
||||
make.right.equalTo(self.mas_right).offset(0);
|
||||
make.top.equalTo(self.mas_top).offset(0);
|
||||
make.bottom.equalTo(self.mas_bottom).offset(0);
|
||||
}];
|
||||
|
||||
[self.cardView addSubview:self.closeButton];
|
||||
@@ -422,17 +420,13 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
|
||||
|
||||
#pragma mark - Lazy
|
||||
|
||||
- (UIView *)cardView {
|
||||
- (UIImageView *)cardView {
|
||||
if (!_cardView) {
|
||||
_cardView = [[UIView alloc] init];
|
||||
_cardView.layer.cornerRadius = 20;
|
||||
_cardView.layer.masksToBounds = YES;
|
||||
_cardGradientLayer = [CAGradientLayer layer];
|
||||
_cardGradientLayer.colors = @[ (id)[UIColor colorWithRed:0.80 green:0.96 blue:0.91 alpha:1].CGColor,
|
||||
(id)[UIColor colorWithRed:0.72 green:0.89 blue:0.98 alpha:1].CGColor ];
|
||||
_cardGradientLayer.startPoint = CGPointMake(0, 0);
|
||||
_cardGradientLayer.endPoint = CGPointMake(1, 1);
|
||||
[_cardView.layer insertSublayer:_cardGradientLayer atIndex:0];
|
||||
_cardView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"keybord_bg_icon"]];
|
||||
// _cardView.layer.cornerRadius = 20;
|
||||
// _cardView.layer.masksToBounds = YES;
|
||||
_cardView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
_cardView.clipsToBounds = true;
|
||||
}
|
||||
return _cardView;
|
||||
}
|
||||
|
||||
@@ -76,6 +76,9 @@ typedef NS_ENUM(NSInteger, KBBizCode) {
|
||||
|
||||
/// 特定收据无效
|
||||
KBBizCodeReceiptError = 50016,
|
||||
|
||||
/// 免费次数耗尽,需要订阅
|
||||
KBBizCodeQuotaExhausted = 50022,
|
||||
};
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||