This commit is contained in:
2025-12-17 19:45:39 +08:00
parent 8bad475288
commit 886de394d0
10 changed files with 207 additions and 36 deletions

View File

@@ -9,11 +9,39 @@
#import "KBFullAccessManager.h"
#import "KBKeyboardSubscriptionFeatureMarqueeView.h"
#import "KBKeyboardSubscriptionOptionCell.h"
#import "KBConfig.h"
#import <MJExtension/MJExtension.h>
static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptionCellId";
static id KBKeyboardSubscriptionSanitizeJSON(id obj) {
if (!obj || obj == (id)kCFNull) { return nil; }
if ([obj isKindOfClass:[NSDictionary class]]) {
NSDictionary *dict = (NSDictionary *)obj;
NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:dict.count];
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
(void)stop;
if (![key isKindOfClass:[NSString class]]) { return; }
id sanitized = KBKeyboardSubscriptionSanitizeJSON(value);
if (!sanitized) { return; }
result[key] = sanitized;
}];
return result;
}
if ([obj isKindOfClass:[NSArray class]]) {
NSArray *arr = (NSArray *)obj;
NSMutableArray *result = [NSMutableArray arrayWithCapacity:arr.count];
for (id item in arr) {
id sanitized = KBKeyboardSubscriptionSanitizeJSON(item);
if (!sanitized) { continue; }
[result addObject:sanitized];
}
return result;
}
return obj;
}
@interface KBKeyboardSubscriptionView () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@property (nonatomic, strong) UIImageView *cardView;
@property (nonatomic, strong) UIButton *closeButton;
@@ -25,6 +53,7 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
@property (nonatomic, strong) UIActivityIndicatorView *loadingIndicator;
@property (nonatomic, strong) UILabel *emptyLabel;
@property (nonatomic, copy) NSArray<KBKeyboardSubscriptionProduct *> *products;
@property (nonatomic, copy, nullable) NSArray *productsRawJSON;
@property (nonatomic, assign) NSInteger selectedIndex;
@property (nonatomic, assign) BOOL didLoadOnce;
@property (nonatomic, assign, getter=isLoading) BOOL loading;
@@ -156,6 +185,7 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
return;
}
KBKeyboardSubscriptionProduct *product = self.products[self.selectedIndex];
[self kb_persistPrefillPayloadForProduct:product];
if ([self.delegate respondsToSelector:@selector(subscriptionView:didTapPurchaseForProduct:)]) {
[self.delegate subscriptionView:self didTapPurchaseForProduct:product];
}
@@ -191,6 +221,7 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
NSString *tip = error.localizedDescription ?: KBLocalized(@"Network error");
[KBHUD showInfo:tip];
self.products = @[];
self.productsRawJSON = nil;
self.selectedIndex = NSNotFound;
[self.collectionView reloadData];
self.emptyLabel.hidden = NO;
@@ -203,12 +234,15 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
}
if (![dataObj isKindOfClass:[NSArray class]]) {
self.products = @[];
self.productsRawJSON = nil;
self.selectedIndex = NSNotFound;
[self.collectionView reloadData];
self.emptyLabel.hidden = NO;
[self updatePurchaseButtonState];
return;
}
id sanitized = KBKeyboardSubscriptionSanitizeJSON(dataObj);
self.productsRawJSON = [sanitized isKindOfClass:NSArray.class] ? (NSArray *)sanitized : nil;
NSArray *models = [KBKeyboardSubscriptionProduct mj_objectArrayWithKeyValuesArray:(NSArray *)dataObj];
self.products = models ?: @[];
self.selectedIndex = self.products.count > 0 ? 0 : NSNotFound;
@@ -221,6 +255,25 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
}];
}
- (void)kb_persistPrefillPayloadForProduct:(KBKeyboardSubscriptionProduct *)product {
if (![product isKindOfClass:KBKeyboardSubscriptionProduct.class]) { return; }
if (![self.productsRawJSON isKindOfClass:NSArray.class] || self.productsRawJSON.count == 0) { return; }
NSUserDefaults *ud = [[NSUserDefaults alloc] initWithSuiteName:AppGroup];
if (!ud) { return; }
NSMutableDictionary *payload = [NSMutableDictionary dictionary];
payload[@"ts"] = @((long long)floor([NSDate date].timeIntervalSince1970));
payload[@"src"] = @"keyboard";
if (product.productId.length) {
payload[@"productId"] = product.productId;
}
if (self.selectedIndex != NSNotFound) {
payload[@"selectedIndex"] = @(self.selectedIndex);
}
payload[@"products"] = self.productsRawJSON;
[ud setObject:payload forKey:AppGroup_SubscriptionPrefillPayload];
[ud synchronize];
}
- (void)selectCurrentProductAnimated:(BOOL)animated {
if (self.selectedIndex == NSNotFound || self.selectedIndex >= self.products.count) { return; }
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:self.selectedIndex inSection:0];
@@ -401,4 +454,3 @@ static NSString * const kKBKeyboardSubscriptionCellId = @"kKBKeyboardSubscriptio
}
@end