// // ShoppingMallViewController.m // YuMi // // Created by P on 2024/11/13. // #import "ShoppingMallViewController.h" #import #import #import "MyDressingViewController.h" #import "ShoppingMallItemPreview.h" #import "ShoppingMallDataPresent.h" #import "ShoppingMallCategoryListView.h" static NSArray *> *DressUpOptions(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 ShoppingMallViewController () @property (nonatomic, strong) UIView *playEffectMask; @property (nonatomic, strong) VAPView *mp4Effect; @property (nonatomic, strong) SVGAImageView *svgaEffect; @property(nonatomic, strong) UIView *bottomControlArea; @property(nonatomic, strong) UILabel *bottomControlPriceLabel; @property(nonatomic, strong) UIButton *bottomControlBuyButton; @property(nonatomic, strong) UIButton *bottomControlGiveButton; @property(nonatomic, strong) DressUpShopModel *selectedModel; @property(nonatomic, strong) UIActivityIndicatorView *loading; @end @implementation ShoppingMallViewController - (ShoppingMallDataPresent *)createPresenter { return [[ShoppingMallDataPresent alloc] init]; } - (BOOL)isHiddenNavBar { return YES; } - (void)viewDidLoad { [super viewDidLoad]; [self setupUI]; } - (void)setupUI { [self setupBackground]; [self setupNavigationBar]; [self setupBottomControlBar]; [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]; UIButton *myDressButton = [self myDressButton]; [self.view addSubview:titleLabel]; [self.view addSubview:backButton]; [self.view addSubview:myDressButton]; [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)); }]; [myDressButton mas_makeConstraints:^(MASConstraintMaker *make) { make.trailing.mas_equalTo(self.view).offset(-16); make.centerY.mas_equalTo(titleLabel); make.size.mas_equalTo(CGSizeMake(102, 22)); }]; } - (void)setupBottomControlBar { [self.view addSubview:self.bottomControlArea]; [self.bottomControlArea mas_makeConstraints:^(MASConstraintMaker *make) { make.bottom.leading.trailing.mas_equalTo(self.view); make.height.mas_equalTo(80 + kSafeAreaBottomHeight); }]; } - (void)setupContentList { NSInteger top = kNavigationHeight; NSInteger bottom = 80 + kSafeAreaBottomHeight; ShoppingMallCategoryListView *listView = [[ShoppingMallCategoryListView alloc] initWithFrame:CGRectMake(0, top, KScreenWidth, KScreenHeight - top - bottom)]; @kWeakify(self); listView.fetchDataForPage = ^(NSInteger pageIndex, FetchDataCompletion completion) { @kStrongify(self); [self fetchDataForPage:pageIndex completion:completion]; }; listView.didTapItemPlay = ^(NSString * _Nonnull resourcePath) { @kStrongify(self); [self playItemEffect:resourcePath]; }; listView.returnSelectedModel = ^(DressUpShopModel * _Nonnull model) { @kStrongify(self); self.selectedModel = model; [self updateBottomControlArea]; }; listView.didTapItemPlay = ^(NSString * _Nonnull resourcePath) { @kStrongify(self); [self playItemEffect:resourcePath]; }; [self.view addSubview:listView]; listView.items = DressUpOptions(); } #pragma mark - - (void)fetchDataForPage:(NSInteger)pageIndex completion:(FetchDataCompletion)completion { [self.presenter loadCategoryItems:pageIndex success:^(NSArray * array) { if (completion) { completion(array); } } failure:^(NSError * _Nonnull error) { // TODO: 增加错误处理 }]; } - (void)updateBottomControlArea { if (self.selectedModel) { self.bottomControlPriceLabel.attributedText = self.selectedModel.pricePerDay; } else { self.bottomControlPriceLabel.text = @""; } } - (void)didTapBuy:(id)sender { if (!self.selectedModel) { return; } ShoppingMallItemPreview *preview = [[ShoppingMallItemPreview alloc] initWith:self.selectedModel]; 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]; }]; }]; } - (void)didTapGive:(id)sender { if (!self.selectedModel) { return; } } - (void)didTapBack { [self.navigationController popViewControllerAnimated:YES]; } - (void)didTapMyDress { MyDressingViewController *myDressVC = [[MyDressingViewController alloc] init]; [self.navigationController pushViewController:myDressVC animated: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); [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 - - (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); }]; } 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; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(stopItemSVGAEffect)]; [_svgaEffect addGestureRecognizer:tap]; } return _svgaEffect; } - (UIView *)bottomControlArea { if (!_bottomControlArea) { _bottomControlArea = [[UIView alloc] init]; [_bottomControlArea addGradientBackgroundWithColors:@[UIColorFromRGB(0x012E4D), UIColorFromRGB(0x0F1435)] startPoint:CGPointMake(0.5, 0) endPoint:CGPointMake(0.5, 1) cornerRadius:0]; [_bottomControlArea addSubview:self.bottomControlPriceLabel]; [self.bottomControlPriceLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.top.mas_equalTo(16); }]; [_bottomControlArea addSubview:self.bottomControlGiveButton]; [self.bottomControlGiveButton mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(14); make.trailing.mas_equalTo(-16); make.size.mas_equalTo(CGSizeMake(74, 32)); }]; [_bottomControlArea addSubview:self.bottomControlBuyButton]; [self.bottomControlBuyButton mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(14); make.trailing.mas_equalTo(self.bottomControlGiveButton.mas_leading).offset(-8); make.size.mas_equalTo(CGSizeMake(74, 32)); }]; } return _bottomControlArea; } - (UILabel *)bottomControlPriceLabel { if (!_bottomControlPriceLabel) { _bottomControlPriceLabel = [[UILabel alloc] init]; } return _bottomControlPriceLabel; } - (UIButton *)bottomControlBuyButton { if (!_bottomControlBuyButton) { _bottomControlBuyButton = [UIButton buttonWithType:UIButtonTypeCustom]; [_bottomControlBuyButton setTitle:YMLocalizedString(@"1.0.30_text_5") forState:UIControlStateNormal]; [_bottomControlBuyButton setTitleColor:UIColorFromRGB(0x51281B) forState:UIControlStateNormal]; [_bottomControlBuyButton addGradientBackgroundWithColors:@[UIColorFromRGB(0xFFE3B2), UIColorFromRGB(0xE9A71D)] startPoint:CGPointMake(0.0, 0.5) endPoint:CGPointMake(1.0, 0.5) cornerRadius:16]; [_bottomControlBuyButton addTarget:self action:@selector(didTapBuy:) forControlEvents:UIControlEventTouchUpInside]; } return _bottomControlBuyButton; } - (UIButton *)bottomControlGiveButton { if (!_bottomControlGiveButton) { _bottomControlGiveButton = [UIButton buttonWithType:UIButtonTypeCustom]; [_bottomControlGiveButton setTitle:YMLocalizedString(@"1.0.30_text_6") forState:UIControlStateNormal]; [_bottomControlGiveButton setTitleColor:UIColorFromRGB(0x172055) forState:UIControlStateNormal]; [_bottomControlGiveButton addGradientBackgroundWithColors:@[UIColorFromRGB(0xB2FCFF), UIColorFromRGB(0x4DA2EA)] startPoint:CGPointMake(0.0, 0.5) endPoint:CGPointMake(1.0, 0.5) cornerRadius:16]; [_bottomControlGiveButton addTarget:self action:@selector(didTapGive:) forControlEvents:UIControlEventTouchUpInside]; } return _bottomControlGiveButton; } - (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_7"); label.textColor = UIColorFromRGB(0xD9E7F7); return label; } - (UIButton *)myDressButton { UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom]; [b addGradientBackgroundWithColors:@[UIColorFromRGB(0x004A4F), UIColorFromRGB(0x11215B)] startPoint:CGPointMake(0.5, 0.0) endPoint:CGPointMake(0.5, 1.0) cornerRadius:11]; [b setCornerRadius:11 corners:kCALayerMaxXMaxYCorner | kCALayerMaxXMinYCorner | kCALayerMinXMaxYCorner | kCALayerMinXMinYCorner borderWidth:1 borderColor:UIColorFromRGB(0x75B4DF)]; [b setAttributedTitle:[[NSAttributedString alloc] initWithString:YMLocalizedString(@"1.0.30_text_8") attributes:@{NSFontAttributeName: kFontMedium(12), NSForegroundColorAttributeName: UIColorFromRGB(0xd9e7f7)}] forState:UIControlStateNormal]; [b setImage:kImage(@"mall_my_icon") forState:UIControlStateNormal]; CGFloat spacing = 2.0; // 图像和标题之间的间距 b.imageEdgeInsets = UIEdgeInsetsMake(0, b.titleLabel.intrinsicContentSize.width + spacing, 0, -b.titleLabel.intrinsicContentSize.width - spacing); b.titleEdgeInsets = UIEdgeInsetsMake(0, -b.imageView.frame.size.width*2, 0, b.imageView.frame.size.width*2 + spacing); // 设置按钮的整体布局和样式 b.contentEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, spacing); [b addTarget:self action:@selector(didTapMyDress) forControlEvents:UIControlEventTouchUpInside]; return b; } - (UIActivityIndicatorView *)loading { if (!_loading) { UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; indicator.translatesAutoresizingMaskIntoConstraints = NO; indicator.hidesWhenStopped = YES; _loading = indicator; } return _loading; } @end