This commit is contained in:
2026-03-04 16:11:13 +08:00
parent 5c0cf2b435
commit 973577c6eb
3 changed files with 81 additions and 35 deletions

View File

@@ -166,9 +166,8 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
[self kb_logSkinDiagnosticsWithTheme:t backgroundImage:img];
self.bgImageView.image = img;
//
if (themeChanged &&
[self.keyBoardMainView respondsToSelector:@selector(kb_applyTheme)]) {
// 使 skinId
if ([self.keyBoardMainView respondsToSelector:@selector(kb_applyTheme)]) {
// method declared in KBKeyBoardMainView.h
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
@@ -177,7 +176,7 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center,
}
// 访 self.functionView
KBFunctionView *functionView = [self kb_functionViewIfCreated];
if (themeChanged && functionView &&
if (functionView &&
[functionView respondsToSelector:@selector(kb_applyTheme)]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

View File

@@ -958,12 +958,15 @@ static NSString * const kKBSkinMetadataThemeKey = @"theme_json";
NSLog(@"[SkinBridge] reloadCurrentSkinIconMap: currentSkin=%@ targetSkin=%@ lang=%@",
currentSkinId, targetSkinId, languageCode);
BOOL isDefaultLike = (currentSkinId.length == 0 ||
[currentSkinId isEqualToString:@"default"] ||
[currentSkinId hasPrefix:@"bundle_skin_default_"]);
//
BOOL hasTargetSkin = [KBSkinManager kb_hasAssetsForSkinId:targetSkinId];
NSLog(@"[SkinBridge] reloadCurrentSkinIconMap: hasTargetSkin=%d", hasTargetSkin);
if (hasTargetSkin) {
if (hasTargetSkin && isDefaultLike) {
//
NSDictionary<NSString *, NSString *> *iconShortNames = [self iconShortNamesForLanguageCode:languageCode];
if (iconShortNames.count == 0) {

View File

@@ -38,6 +38,7 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) {
@property (nonatomic, strong) KBShopVM *shopVM;
@property (nonatomic, strong, nullable) KBShopThemeDetailModel *detailModel;
//@property (nonatomic, assign) BOOL isProcessingAction;
- (NSMutableDictionary *)buildSkinPayloadWithDownloadInfo:(NSDictionary *)info;
@end
@implementation KBSkinDetailVC
@@ -296,41 +297,84 @@ typedef NS_ENUM(NSInteger, KBSkinDetailSection) {
- (void)requestDownload {
// if (self.isProcessingAction) { return; }
// self.isProcessingAction = YES;
[KBHUD showWithStatus:KBLocalized(@"Downloading...")];
__weak typeof(self) weakSelf = self;
[self.shopVM fetchThemeDownloadInfoWithId:self.themeId completion:^(NSDictionary * _Nullable info, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) { return; }
if (error) {
NSLog(@"[KBSkinDetailVC] fetch download info failed: %@", error);
}
NSMutableDictionary *skin = [strongSelf buildSkinPayloadWithDownloadInfo:info];
NSString *zipURL = [skin[@"zip_url"] isKindOfClass:NSString.class] ? skin[@"zip_url"] : @"";
if (skin.count == 0 || zipURL.length == 0) {
[KBHUD dismiss];
[KBHUD showInfo:KBLocalized(@"下载信息缺失")];
return;
}
NSLog(@"⬇️[SkinDetail] download request id=%@ zip=%@ force=YES",
skin[@"id"], zipURL);
[[KBSkinService shared] applySkinWithJSON:skin
fromViewController:strongSelf
mode:KBSkinSourceModeRemoteZip
completion:^(BOOL success) {
[KBHUD dismiss];
NSLog(@"%@[SkinDetail] download result id=%@",
(success ? @"✅" : @"❌"),
strongSelf.detailModel.themeId);
if (success) {
NSString *themeId = strongSelf.detailModel.themeId;
if (themeId.length > 0) {
[strongSelf.shopVM restoreThemeWithId:themeId completion:nil];
}
} else {
[KBHUD showInfo:KBLocalized(@"下载失败")];
}
}];
});
}];
}
- (NSMutableDictionary *)buildSkinPayloadWithDownloadInfo:(NSDictionary *)info {
NSMutableDictionary *skin = [NSMutableDictionary dictionary];
if (!skin[@"id"] && self.detailModel.themeId) {
skin[@"id"] = self.detailModel.themeId;
if ([info isKindOfClass:NSDictionary.class]) {
[info enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if (![key isKindOfClass:NSString.class]) { return; }
if (!obj || obj == [NSNull null]) { return; }
skin[key] = obj;
}];
}
if (!skin[@"name"] && self.detailModel.themeName) {
skin[@"name"] = self.detailModel.themeName;
NSString *themeId = self.detailModel.themeId.length > 0 ? self.detailModel.themeId : self.themeId;
if (themeId.length > 0) {
skin[@"id"] = themeId;
}
skin[@"zip_url"] = self.detailModel.themeDownloadUrl ? self.detailModel.themeDownloadUrl : @"";
if (self.detailModel.themePreviewImageUrl.length > 0) {
skin[@"preview"] = self.detailModel.themePreviewImageUrl;
if (![skin[@"name"] isKindOfClass:NSString.class] || [skin[@"name"] length] == 0) {
if (self.detailModel.themeName.length > 0) {
skin[@"name"] = self.detailModel.themeName;
} else if (themeId.length > 0) {
skin[@"name"] = themeId;
}
}
NSString *zipURL = [skin[@"zip_url"] isKindOfClass:NSString.class] ? skin[@"zip_url"] : @"";
if (zipURL.length == 0) {
id altURL = skin[@"zipUrl"] ?: skin[@"download_url"] ?: skin[@"downloadUrl"];
if ([altURL isKindOfClass:NSString.class]) {
zipURL = altURL;
} else if (self.detailModel.themeDownloadUrl.length > 0) {
zipURL = self.detailModel.themeDownloadUrl;
}
if (zipURL.length > 0) {
skin[@"zip_url"] = zipURL;
}
}
if (![skin[@"preview"] isKindOfClass:NSString.class] || [skin[@"preview"] length] == 0) {
if (self.detailModel.themePreviewImageUrl.length > 0) {
skin[@"preview"] = self.detailModel.themePreviewImageUrl;
}
}
skin[@"force_download"] = @(YES);
NSLog(@"⬇️[SkinDetail] download request id=%@ zip=%@ force=YES",
skin[@"id"], skin[@"zip_url"]);
[KBHUD showWithStatus:KBLocalized(@"Downloading...")];
[[KBSkinService shared] applySkinWithJSON:skin
fromViewController:self
mode:KBSkinSourceModeRemoteZip
completion:^(BOOL success) {
[KBHUD dismiss];
NSLog(@"%@[SkinDetail] download result id=%@",
(success ? @"✅" : @"❌"),
self.detailModel.themeId);
if (success) {
NSString *themeId = self.detailModel.themeId;
if (themeId.length > 0) {
[self.shopVM restoreThemeWithId:themeId completion:nil];
}
} else {
[KBHUD showInfo:KBLocalized(@"下载失败")];
}
}];
return skin;
}
- (void)updateBottomBarAppearance {