Files
peko-ios/YuMi/Modules/ShoppingMall/MyDressingViewController.m

454 lines
16 KiB
Objective-C

//
// MyDressingViewController.m
// YuMi
//
// Created by P on 2024/11/13.
//
#import "MyDressingViewController.h"
#import <SVGA.h>
#import <QGVAPWrapView.h>
#import "UserInfoModel.h"
#import "MyDressingDataPresent.h"
#import "ShoppingMallItemPreview.h"
#import "XPSkillCardPlayerManager.h"
#import "ShoppingMallCategoryListView.h"
static NSArray<NSDictionary<NSString *, NSNumber *> *> *MyDressUpOptions(void) {
return @[
@{YMLocalizedString(@"XPMineDressUpViewController2") : @1}, // 座驾
@{YMLocalizedString(@"XPMineDressUpViewController1") : @0}, // 头饰
@{YMLocalizedString(@"XPMineDressUpViewController3") : @2}, // 铭牌
@{YMLocalizedString(@"XPMineDressUpViewController4") : @3}, // 资料卡
@{YMLocalizedString(@"XPMineDressUpViewController5") : @4}, // 聊天气泡
@{YMLocalizedString(@"1.0.30_text_9") : @5} // 個人頁裝飾
];
}
@interface MyDressingViewController ()
@property(nonatomic, strong) UserInfoModel *userInfo;
@property(nonatomic, strong) NetImageView *avatarView;
@property(nonatomic, strong) NetImageView *avatarHeadViewImageView;
@property(nonatomic, strong) SVGAImageView *avatarHeadWearSVGA;
@property (nonatomic, strong) UIView *playEffectMask;
@property (nonatomic, strong) VAPView *mp4Effect;
@property (nonatomic, strong) SVGAImageView *svgaEffect;
@property(nonatomic, strong) UIActivityIndicatorView *loading;
@property(nonatomic, strong) MyDressingDataModel *selectedModel;
@end
@implementation MyDressingViewController
- (MyDressingDataPresent *)createPresenter {
return [[MyDressingDataPresent alloc] init];
}
- (BOOL)isHiddenNavBar {
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.userInfo = [XPSkillCardPlayerManager shareInstance].userInfoModel;
[self setupUI];
[self updateAvatar];
}
- (void)setupUI {
[self setupBackground];
[self setupNavigationBar];
[self setupAvatar];
[self setupContentList];
}
- (void)setupBackground {
self.view.backgroundColor = UIColorFromRGB(0x02061D);
UIImageView *topBG = [[UIImageView alloc] initWithImage:kImage(@"mall_top_bg")];
[self.view addSubview:topBG];
[topBG mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.leading.trailing.mas_equalTo(self.view);
make.height.mas_equalTo(kGetScaleWidth(200));
}];
}
- (void)setupNavigationBar {
UILabel *titleLabel = [self titleLabel];
UIButton *backButton = [self backButton];
[self.view addSubview:titleLabel];
[self.view addSubview:backButton];
[titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.view);
make.top.mas_equalTo(self.view).offset(44 + 11);
make.height.mas_equalTo(22);
}];
[backButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(self.view).offset(16);
make.centerY.mas_equalTo(titleLabel);
make.size.mas_equalTo(CGSizeMake(22, 22));
}];
}
- (void)setupAvatar {
[self.view addSubview:self.avatarView];
[self.avatarView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(100);
make.centerX.mas_equalTo(self.view);
make.size.mas_equalTo(CGSizeMake(73, 73));
}];
[self.view addSubview:self.avatarHeadViewImageView];
[self.avatarHeadViewImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(self.avatarView);
make.size.mas_equalTo(self.avatarView).multipliedBy(1.3);
}];
[self.view addSubview:self.avatarHeadWearSVGA];
[self.avatarHeadWearSVGA mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(self.avatarView);
make.size.mas_equalTo(self.avatarView).multipliedBy(1.3);
}];
}
- (void)setupContentList {
NSInteger bottom = kSafeAreaBottomHeight;
// 内部列表使用 frame 布局,这里要计算 height
ShoppingMallCategoryListView *listView = [[ShoppingMallCategoryListView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight - 100 - 73)];
listView.isForMyDressingPage = YES;
listView.bottomSpace = bottom;
[self.view addSubview:listView];
[listView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.avatarView.mas_bottom).offset(14);
make.leading.trailing.bottom.mas_equalTo(self.view);
}];
@kWeakify(self);
listView.fetchDataForMyDressingPage = ^(NSInteger pageIndex, NSInteger pageNum, FetchDataForMyDressingCompletion _Nonnull completion) {
@kStrongify(self);
[self fetchDataForPage:pageIndex
pageNum:pageNum
completion:completion];
};
listView.didTapItemPlay = ^(NSString * _Nonnull resourcePath) {
@kStrongify(self);
[self playItemEffect:resourcePath];
};
listView.returnMyDressingSelectedModel = ^(MyDressingDataModel * _Nonnull model, NSInteger type) {
@kStrongify(self);
[self handTapItem:model type:type];
};
listView.items = MyDressUpOptions();
}
- (void)updateAvatar {
self.avatarView.imageUrl = self.userInfo.avatar;
if ([NSString isEmpty:self.userInfo.headwearEffect]) {
[self.avatarHeadWearSVGA stopAnimation];
self.avatarHeadWearSVGA.hidden = YES;
} else {
if ([self.userInfo.headwearEffect.lowercaseString hasSuffix:@"svga"]) {
self.avatarHeadWearSVGA.hidden = NO;
self.avatarHeadViewImageView.hidden = YES;
SVGAParser *p = [[SVGAParser alloc] init];
[p parseWithURL:[NSURL URLWithString:self.userInfo.headwearEffect]
completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
self.avatarHeadWearSVGA.videoItem = videoItem;
[self.avatarHeadWearSVGA startAnimation];
self.avatarHeadWearSVGA.hidden = NO;
} failureBlock:^(NSError * _Nullable error) {}];
} else {
self.avatarHeadWearSVGA.hidden = YES;
self.avatarHeadViewImageView.hidden = NO;
self.avatarHeadViewImageView.imageUrl = self.userInfo.headwearEffect;
}
}
}
#pragma mark -
- (void)fetchDataForPage:(NSInteger)pageIndex
pageNum:(NSInteger)pageNum
completion:(FetchDataForMyDressingCompletion)completion {
switch (pageIndex) {
case 0: {
[self.presenter loadMyDressingItems:0
page:pageNum
success:^(NSArray <MyDressingDataModel *>* _Nonnull array, NSInteger type) {
if (completion) {
completion(array);
}
} failure:^(NSError * _Nonnull error) {
}];
}
break;
case 1: {
[self.presenter loadVehicles:^(NSArray <CarModel *>* _Nonnull array) {
if (completion) {
NSMutableArray *transArray = @[].mutableCopy;
for (CarModel *car in array) {
MyDressingDataModel *model = [MyDressingDataModel modelFromVehicle:car];
[transArray addObject:model];
}
completion(transArray);
}
} failure:^(NSError * _Nonnull error) { }];
}
break;
case 2: {
[self.presenter loadNameplate:pageNum
success:^(NSArray<NameplateModel *> * _Nonnull array) {
if (completion) {
NSMutableArray *transArray = @[].mutableCopy;
for (NameplateModel *nameplate in array) {
MyDressingDataModel *model = [MyDressingDataModel modelFromNameplate:nameplate];
[transArray addObject:model];
}
completion(transArray);
}
} failure:^(NSError * _Nonnull error) {
}];
}
break;
case 3: {
[self.presenter loadRoomCard:pageNum
success:^(NSArray<NobleCardModel *> * _Nonnull array) {
if (completion) {
NSMutableArray *transArray = @[].mutableCopy;
for (NobleCardModel *nobleCard in array) {
MyDressingDataModel *model = [MyDressingDataModel modelFromNobelCard:nobleCard];
[transArray addObject:model];
}
completion(transArray);
}
} failure:^(NSError * _Nonnull error) {
}];
}
break;
case 4: {
[self.presenter loadBubble:pageNum
success:^(NSArray<ChatBubbleModel *> * _Nonnull array) {
if (completion) {
NSMutableArray *transArray = @[].mutableCopy;
for (ChatBubbleModel *bubble in array) {
MyDressingDataModel *model = [MyDressingDataModel modelFromChatBubble:bubble];
[transArray addObject:model];
}
completion(transArray);
}
} failure:^(NSError * _Nonnull error) {
}];
}
break;
case 5: {
[self.presenter loadMyDressingItems:5
page:pageNum
success:^(NSArray <MyDressingDataModel *>* _Nonnull array, NSInteger type) {
if (completion) {
completion(array);
}
} failure:^(NSError * _Nonnull error) {
}];
}
break;
default:
break;
}
}
- (void)handTapItem:(MyDressingDataModel *)model type:(NSInteger)type {
if (model.hasExpired) {
// 弹窗购买
ShoppingMallItemPreview *preview = [[ShoppingMallItemPreview alloc] initWithMyDress:model
isVaild:model.obtainWay<=1];
preview.frame = CGRectMake(0, 0, 284, 353);
[TTPopup popupView:preview style:TTPopupStyleAlert];
// @kWeakify(self);
// [preview setBuyWith:^(DressUpShopModel * _Nonnull model) {
// @kStrongify(self);
// @kWeakify(self);
// [self.presenter buyItem:model.dressUpId
// success:^(id _Nonnull obj) {
// @kStrongify(self);
// [TTPopup dismiss];
// [self showSuccessToast:YMLocalizedString(@"XPDressUpShopListViewController0")];
// } failure:^(NSError * _Nonnull error) {
// // @kStrongify(self);
// // [self showErrorToast:error.localizedDescription];
// }];
// }];
} else {
// 直接使用
NSInteger dressID = 0;
if (model) {
dressID = model.dressId;
}
@kWeakify(self);
[self.presenter useDressBy:type
dressID:dressID
success:^(UserInfoModel *userInfo){
@kStrongify(self);
self.userInfo = userInfo;
[XPSkillCardPlayerManager shareInstance].userInfoModel = userInfo;
[self updateAvatar];
// TODO: 更新列表的选中状态
} failure:^(NSError * _Nonnull error) {
}];
}
}
#pragma mark -
- (void)didTapBack {
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark -
- (void)playItemEffect:(NSString *)path {
if (!_playEffectMask) {
[self.view addSubview:self.playEffectMask];
[self.playEffectMask mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.view);
}];
[self.playEffectMask addSubview:self.svgaEffect];
[self.svgaEffect mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.playEffectMask).insets(UIEdgeInsetsMake(0, 0, 0, 0));
}];
}
self.playEffectMask.hidden = NO;
[self.loading startAnimating];
if ([path.lowercaseString hasSuffix:@"svga"]) {
@kWeakify(self);
SVGAParser *p = [[SVGAParser alloc] init];
[p parseWithURL:[NSURL URLWithString:path]
completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
@kStrongify(self);
if (!self.playEffectMask.hidden) {
[self.loading stopAnimating];
self.svgaEffect.hidden = NO;
self.svgaEffect.videoItem = videoItem;
[self.svgaEffect startAnimation];
}
} failureBlock:^(NSError * _Nullable error) {
@kStrongify(self);
[self stopItemSVGAEffect];
}];
} else if ([path.lowercaseString hasSuffix:@"mp4"]) {
}
}
- (void)stopItemSVGAEffect {
[self.loading stopAnimating];
[self.svgaEffect stopAnimation];
self.svgaEffect.hidden = YES;
self.playEffectMask.hidden = YES;
}
#pragma mark -
- (UIButton *)backButton {
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
[b setImage:[kImage(@"vip_center_back_button") ms_SetImageForRTL]
forState:UIControlStateNormal];
[b addTarget:self
action:@selector(didTapBack)
forControlEvents:UIControlEventTouchUpInside];
return b;
}
- (UILabel *)titleLabel {
UILabel *label = [[UILabel alloc] init];
label.textAlignment = NSTextAlignmentCenter;
label.font = kFontMedium(17);
label.text = YMLocalizedString(@"1.0.30_text_8");
label.textColor = UIColorFromRGB(0xD9E7F7);
return label;
}
- (UIView *)playEffectMask {
if (!_playEffectMask) {
_playEffectMask = [[UIView alloc] initWithFrame:self.view.bounds];
_playEffectMask.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5f];
[_playEffectMask addSubview:self.loading];
[self.loading mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(_playEffectMask);
}];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(stopItemSVGAEffect)];
[_playEffectMask addGestureRecognizer:tap];
}
return _playEffectMask;
}
- (SVGAImageView *)svgaEffect {
if (!_svgaEffect) {
_svgaEffect = [[SVGAImageView alloc] init];
_svgaEffect.contentMode = UIViewContentModeScaleAspectFit;
_svgaEffect.autoPlay = YES;
_svgaEffect.loops = 0;
_svgaEffect.clearsAfterStop = YES;
_svgaEffect.hidden = YES;
_svgaEffect.userInteractionEnabled = YES;
}
return _svgaEffect;
}
- (UIActivityIndicatorView *)loading {
if (!_loading) {
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
indicator.translatesAutoresizingMaskIntoConstraints = NO;
indicator.hidesWhenStopped = YES;
_loading = indicator;
}
return _loading;
}
- (NetImageView *)avatarHeadViewImageView {
if (!_avatarHeadViewImageView) {
_avatarHeadViewImageView = [[NetImageView alloc] init];
_avatarHeadViewImageView.contentMode = UIViewContentModeScaleAspectFit;
}
return _avatarHeadViewImageView;
}
- (NetImageView *)avatarView {
if (!_avatarView) {
NetImageConfig * config = [[NetImageConfig alloc]init];
config.imageType = ImageTypeUserIcon;
config.placeHolder = [UIImageConstant defaultAvatarPlaceholder];
_avatarView = [[NetImageView alloc] initWithConfig:config];
[_avatarView setCornerRadius:73/2
corners:kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner | kCALayerMinXMaxYCorner | kCALayerMaxXMaxYCorner
borderWidth:2
borderColor:UIColorFromRGB(0xFBD99A)];
}
return _avatarView;
}
- (SVGAImageView *)avatarHeadWearSVGA {
if (!_avatarHeadWearSVGA) {
_avatarHeadWearSVGA = [[SVGAImageView alloc] init];
_avatarHeadWearSVGA.contentMode = UIViewContentModeScaleAspectFit;
_avatarHeadWearSVGA.autoPlay = YES;
_avatarHeadWearSVGA.loops = 0;
_avatarHeadWearSVGA.clearsAfterStop = YES;
}
return _avatarHeadWearSVGA;
}
@end