diff --git a/YuMi.xcodeproj/project.pbxproj b/YuMi.xcodeproj/project.pbxproj index 5e7acfd0..c5af9939 100644 --- a/YuMi.xcodeproj/project.pbxproj +++ b/YuMi.xcodeproj/project.pbxproj @@ -503,6 +503,14 @@ 5412E0FD2C52512100FDD668 /* RoomBottomEntranceModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 5412E0FC2C52512100FDD668 /* RoomBottomEntranceModel.m */; }; 541DD9552C1EDEFB00B616C4 /* XPHomePagingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 541DD9542C1EDEFB00B616C4 /* XPHomePagingViewController.m */; }; 544A36352C94160F00CA7858 /* RoomMenuBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 544A36342C94160F00CA7858 /* RoomMenuBar.m */; }; + 544B19B02CA1299500885BEB /* CPBindingAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 544B19AF2CA1299500885BEB /* CPBindingAnimation.m */; }; + 544B19B32CA129A800885BEB /* CPLevelUpAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 544B19B22CA129A800885BEB /* CPLevelUpAnimation.m */; }; + 544B19B62CA14A7100885BEB /* CPGiftBanner.m in Sources */ = {isa = PBXBuildFile; fileRef = 544B19B52CA14A7100885BEB /* CPGiftBanner.m */; }; + 544B19BC2CA169BE00885BEB /* level up 3.svga in Resources */ = {isa = PBXBuildFile; fileRef = 544B19B92CA169BE00885BEB /* level up 3.svga */; }; + 544B19BD2CA169BE00885BEB /* level up 4.svga in Resources */ = {isa = PBXBuildFile; fileRef = 544B19BA2CA169BE00885BEB /* level up 4.svga */; }; + 544B19BE2CA169BE00885BEB /* level up 5.svga in Resources */ = {isa = PBXBuildFile; fileRef = 544B19BB2CA169BE00885BEB /* level up 5.svga */; }; + 544B19BF2CA169BE00885BEB /* level up 1.svga in Resources */ = {isa = PBXBuildFile; fileRef = 544B19B72CA169BE00885BEB /* level up 1.svga */; }; + 544B19C02CA169BE00885BEB /* level up 2.svga in Resources */ = {isa = PBXBuildFile; fileRef = 544B19B82CA169BE00885BEB /* level up 2.svga */; }; 5456F3C82C6EF962000E1805 /* VIPCenterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5456F3C72C6EF962000E1805 /* VIPCenterViewController.m */; }; 5458319D2C2AE09300364026 /* XPRoomTypeSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5458319C2C2AE09300364026 /* XPRoomTypeSelectionViewController.m */; }; 545831A02C2AEFAF00364026 /* TenMicStageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5458319F2C2AEFAF00364026 /* TenMicStageView.m */; }; @@ -2556,6 +2564,17 @@ 541DD9542C1EDEFB00B616C4 /* XPHomePagingViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = XPHomePagingViewController.m; sourceTree = ""; }; 544A36332C94160F00CA7858 /* RoomMenuBar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RoomMenuBar.h; sourceTree = ""; }; 544A36342C94160F00CA7858 /* RoomMenuBar.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RoomMenuBar.m; sourceTree = ""; }; + 544B19AE2CA1299500885BEB /* CPBindingAnimation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPBindingAnimation.h; sourceTree = ""; }; + 544B19AF2CA1299500885BEB /* CPBindingAnimation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPBindingAnimation.m; sourceTree = ""; }; + 544B19B12CA129A800885BEB /* CPLevelUpAnimation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPLevelUpAnimation.h; sourceTree = ""; }; + 544B19B22CA129A800885BEB /* CPLevelUpAnimation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPLevelUpAnimation.m; sourceTree = ""; }; + 544B19B42CA14A7100885BEB /* CPGiftBanner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CPGiftBanner.h; sourceTree = ""; }; + 544B19B52CA14A7100885BEB /* CPGiftBanner.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CPGiftBanner.m; sourceTree = ""; }; + 544B19B72CA169BE00885BEB /* level up 1.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = "level up 1.svga"; sourceTree = ""; }; + 544B19B82CA169BE00885BEB /* level up 2.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = "level up 2.svga"; sourceTree = ""; }; + 544B19B92CA169BE00885BEB /* level up 3.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = "level up 3.svga"; sourceTree = ""; }; + 544B19BA2CA169BE00885BEB /* level up 4.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = "level up 4.svga"; sourceTree = ""; }; + 544B19BB2CA169BE00885BEB /* level up 5.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = "level up 5.svga"; sourceTree = ""; }; 5456F3C62C6EF962000E1805 /* VIPCenterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VIPCenterViewController.h; sourceTree = ""; }; 5456F3C72C6EF962000E1805 /* VIPCenterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = VIPCenterViewController.m; sourceTree = ""; }; 5458319B2C2AE09300364026 /* XPRoomTypeSelectionViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XPRoomTypeSelectionViewController.h; sourceTree = ""; }; @@ -6487,6 +6506,11 @@ 54FFD3802C9BD12600DE61E5 /* cp */ = { isa = PBXGroup; children = ( + 544B19B72CA169BE00885BEB /* level up 1.svga */, + 544B19B82CA169BE00885BEB /* level up 2.svga */, + 544B19B92CA169BE00885BEB /* level up 3.svga */, + 544B19BA2CA169BE00885BEB /* level up 4.svga */, + 544B19BB2CA169BE00885BEB /* level up 5.svga */, 54B9C6FA2C9DA4C4003F1CC5 /* CP绑定.mp4 */, 54B9C6F42C9D8D05003F1CC5 /* 3.mp4 */, 54B9C6F52C9D8D05003F1CC5 /* 4.mp4 */, @@ -10932,6 +10956,12 @@ children = ( 54AE7E122C9AD98C006D2BE2 /* CPCard.h */, 54AE7E132C9AD9A6006D2BE2 /* CPCard.m */, + 544B19B42CA14A7100885BEB /* CPGiftBanner.h */, + 544B19B52CA14A7100885BEB /* CPGiftBanner.m */, + 544B19AE2CA1299500885BEB /* CPBindingAnimation.h */, + 544B19AF2CA1299500885BEB /* CPBindingAnimation.m */, + 544B19B12CA129A800885BEB /* CPLevelUpAnimation.h */, + 544B19B22CA129A800885BEB /* CPLevelUpAnimation.m */, E87E545229AA05EA00EBE52B /* XPFootPrintNavView.h */, E87E545329AA05EA00EBE52B /* XPFootPrintNavView.m */, E8B846CC26FDD93D00A777FE /* Recharge */, @@ -11229,6 +11259,11 @@ E80EC87728ACD84000D133C5 /* emoji_148@2x.png in Resources */, E80EC81928ACD84000D133C5 /* emoji_80@2x.png in Resources */, 237701192BD6143700D661F1 /* pi_happy_egg_smash.svga in Resources */, + 544B19BC2CA169BE00885BEB /* level up 3.svga in Resources */, + 544B19BD2CA169BE00885BEB /* level up 4.svga in Resources */, + 544B19BE2CA169BE00885BEB /* level up 5.svga in Resources */, + 544B19BF2CA169BE00885BEB /* level up 1.svga in Resources */, + 544B19C02CA169BE00885BEB /* level up 2.svga in Resources */, E80EC8B328ACD84100D133C5 /* emoji_115@2x.png in Resources */, 54FFD3812C9BD12600DE61E5 /* 4.svga in Resources */, 54FFD3822C9BD12600DE61E5 /* 1.svga in Resources */, @@ -11663,6 +11698,7 @@ 54F469382C29C3B400A83655 /* XPMineAlbumTableViewCell.m in Sources */, 23E9EAA12A84C53900B792F2 /* TTNewAlertView.m in Sources */, 238B37BC2AC55A2C00BFC9D5 /* XPTreasureFairySendView.m in Sources */, + 544B19B02CA1299500885BEB /* CPBindingAnimation.m in Sources */, E8DEC9A12764A5D20078CB70 /* XPRoomMoreItemModel.m in Sources */, E80EC81028ACD84000D133C5 /* QExtendBoardView.m in Sources */, 9B87B3CD2926473D00085110 /* XPSessionListHeadFriendCell.m in Sources */, @@ -12082,6 +12118,7 @@ 9B6B3AAB278C2EA7005551EC /* XPRoomNobleLevelUpView.m in Sources */, E85E7B302A4EB0D300B6D00A /* XPGuildIncomeHeaderView.m in Sources */, E85E7B222A4EB0D300B6D00A /* XPMineGuildIncomeRecordViewController.m in Sources */, + 544B19B32CA129A800885BEB /* CPLevelUpAnimation.m in Sources */, 9BD2ECD5288F838200F5CD9A /* XPMineFootPrintPresenter.m in Sources */, 9B1B72BF2800422E003FACE9 /* XPAnchorPKRuleView.m in Sources */, 54F469352C29711400A83655 /* XPMomentUserDataViewController.m in Sources */, @@ -12468,6 +12505,7 @@ 9B4D449328F15765002572D5 /* XPGiftLuckyGiftBroadcastView.m in Sources */, E81C278C26EAFAF60031E639 /* Base64.m in Sources */, 238B37C92AC55A2C00BFC9D5 /* XPTreasureFairyStoreResultSmallView.m in Sources */, + 544B19B62CA14A7100885BEB /* CPGiftBanner.m in Sources */, E8C1CD7027D894B800376F83 /* RoomFaceTitleItemModel.m in Sources */, E85E7B4B2A4EB0D300B6D00A /* XPMineGuildManagerSetViewController.m in Sources */, 189DD73D26E21C3F00AB55B1 /* YYUtility+Device.m in Sources */, diff --git a/YuMi/Assets.xcassets/1.0.16/cp_banner.imageset/Contents.json b/YuMi/Assets.xcassets/1.0.16/cp_banner.imageset/Contents.json new file mode 100644 index 00000000..f89d6461 --- /dev/null +++ b/YuMi/Assets.xcassets/1.0.16/cp_banner.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "容器 8171@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/YuMi/Assets.xcassets/1.0.16/cp_banner.imageset/容器 8171@3x.png b/YuMi/Assets.xcassets/1.0.16/cp_banner.imageset/容器 8171@3x.png new file mode 100644 index 00000000..c4c521c5 Binary files /dev/null and b/YuMi/Assets.xcassets/1.0.16/cp_banner.imageset/容器 8171@3x.png differ diff --git a/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_1.imageset/3@3x.png b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_1.imageset/3@3x.png new file mode 100644 index 00000000..f0183f1a Binary files /dev/null and b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_1.imageset/3@3x.png differ diff --git a/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_1.imageset/Contents.json b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_1.imageset/Contents.json new file mode 100644 index 00000000..fa52775a --- /dev/null +++ b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "3@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_2.imageset/3@3x-2.png b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_2.imageset/3@3x-2.png new file mode 100644 index 00000000..51563e72 Binary files /dev/null and b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_2.imageset/3@3x-2.png differ diff --git a/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_2.imageset/Contents.json b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_2.imageset/Contents.json new file mode 100644 index 00000000..a5a7d92e --- /dev/null +++ b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "3@3x-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_3.imageset/3@3x-3.png b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_3.imageset/3@3x-3.png new file mode 100644 index 00000000..f28199d7 Binary files /dev/null and b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_3.imageset/3@3x-3.png differ diff --git a/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_3.imageset/Contents.json b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_3.imageset/Contents.json new file mode 100644 index 00000000..06803eef --- /dev/null +++ b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_3.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "3@3x-3.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_4.imageset/3@3x-4.png b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_4.imageset/3@3x-4.png new file mode 100644 index 00000000..df9ad414 Binary files /dev/null and b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_4.imageset/3@3x-4.png differ diff --git a/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_4.imageset/Contents.json b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_4.imageset/Contents.json new file mode 100644 index 00000000..94ce1e76 --- /dev/null +++ b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_4.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "3@3x-4.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_5.imageset/3@3x-5.png b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_5.imageset/3@3x-5.png new file mode 100644 index 00000000..30740b89 Binary files /dev/null and b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_5.imageset/3@3x-5.png differ diff --git a/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_5.imageset/Contents.json b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_5.imageset/Contents.json new file mode 100644 index 00000000..272e5c51 --- /dev/null +++ b/YuMi/Assets.xcassets/1.0.16/cp_level_banner_lv_5.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "3@3x-5.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/YuMi/Modules/YMMine/View/CPListViewController.m b/YuMi/Modules/YMMine/View/CPListViewController.m index 8d4cb5b1..d811d3a5 100644 --- a/YuMi/Modules/YMMine/View/CPListViewController.m +++ b/YuMi/Modules/YMMine/View/CPListViewController.m @@ -41,7 +41,7 @@ - (void)setModel:(RelationUserVO *)model { _model = model; - [self.cpCard updateForCPList:model]; + [self.cpCard updateForCPList:model showBreakHeart:([AccountInfoStorage instance].getUid.integerValue == model.uid)]; } - (CPCard *)cpCard { diff --git a/YuMi/Modules/YMMine/View/Cell/MineInfo/XPMineMultipleContentTableViewCell.m b/YuMi/Modules/YMMine/View/Cell/MineInfo/XPMineMultipleContentTableViewCell.m index 19d341d2..17ec3231 100644 --- a/YuMi/Modules/YMMine/View/Cell/MineInfo/XPMineMultipleContentTableViewCell.m +++ b/YuMi/Modules/YMMine/View/Cell/MineInfo/XPMineMultipleContentTableViewCell.m @@ -219,7 +219,7 @@ return kGetScaleWidth(116); } NSInteger lines = ceil((giftWall.count + luckyGiftWall.count)/4.0); - return 42 + lines * (kGetScaleWidth(116) + 16); + return lines * (kGetScaleWidth(107) + 16); } - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { @@ -333,7 +333,7 @@ } - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { - return self.isMedal ? CGSizeMake(kGetScaleWidth(77), kGetScaleWidth(94)) : CGSizeMake(kGetScaleWidth(77), kGetScaleWidth(116)); + return self.isMedal ? CGSizeMake(kGetScaleWidth(77), kGetScaleWidth(94)) : CGSizeMake(kGetScaleWidth(77), kGetScaleWidth(107)); } diff --git a/YuMi/Modules/YMMine/View/MineInfo/XPMineUserDataViewController.m b/YuMi/Modules/YMMine/View/MineInfo/XPMineUserDataViewController.m index b7b37e6c..c6d98802 100644 --- a/YuMi/Modules/YMMine/View/MineInfo/XPMineUserDataViewController.m +++ b/YuMi/Modules/YMMine/View/MineInfo/XPMineUserDataViewController.m @@ -693,7 +693,7 @@ typedef enum : NSUInteger { [_tableView registerClass:[XPMineMultipleContentTableViewCell class] forCellReuseIdentifier:NSStringFromClass([XPMineMultipleContentTableViewCell class])]; UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, kSafeAreaBottomHeight)]; - footer.backgroundColor = [UIColor purpleColor]; + footer.backgroundColor = [UIColor clearColor]; _tableView.tableFooterView = footer; if (isMSRTL()) { diff --git a/YuMi/Modules/YMMine/View/MineInfo/XPMineUserInfoViewController.m b/YuMi/Modules/YMMine/View/MineInfo/XPMineUserInfoViewController.m index 9eac2f94..cd2a3fcb 100644 --- a/YuMi/Modules/YMMine/View/MineInfo/XPMineUserInfoViewController.m +++ b/YuMi/Modules/YMMine/View/MineInfo/XPMineUserInfoViewController.m @@ -419,30 +419,18 @@ HWDMP4PlayDelegate> [self removeCPAnimation]; } -//provide the content for tags, maybe text or url string ... -//- (NSString *)contentForVapTag:(NSString *)tag resource:(QGVAPSourceInfo *)info { -// -// if ([tag isEqualToString:@"avatar1"]) { -// -// } -// -// NSDictionary *extraInfo = @{@"[avatar1]" : self.userInfo.avatar, -// @"[avatar2]" : @"https://www.popo8.com/gift/gift_231.png"}; -// return extraInfo[tag]; -//} - //provide image for url from tag content - (void)loadVapImageWithURL:(NSString *)urlStr context:(NSDictionary *)context completion:(VAPImageCompletionBlock)completionBlock { dispatch_async(dispatch_get_main_queue(), ^{ QGVAPSourceInfo *info = (QGVAPSourceInfo *)context[@"resource"]; if ([info.contentTag isEqualToString:@"avatar1"] ) { self.avatarLoader = [[NetImageView alloc] init]; - [self.avatarLoader loadImageWithUrl:self.userInfo.avatar completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) { + [self.avatarLoader loadImageWithUrl:self.userInfo.relationUserVO.avatar completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) { completionBlock(image, nil, urlStr); }]; } else { self.cpAvatarLoader = [[NetImageView alloc] init]; - [self.cpAvatarLoader loadImageWithUrl:self.userInfo.avatar completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) { + [self.cpAvatarLoader loadImageWithUrl:self.userInfo.relationUserVO.cpAvatar completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) { completionBlock(image, nil, urlStr); }]; } diff --git a/YuMi/Modules/YMMine/View/SubViews/CPBindingAnimation.h b/YuMi/Modules/YMMine/View/SubViews/CPBindingAnimation.h new file mode 100644 index 00000000..e47ab2d7 --- /dev/null +++ b/YuMi/Modules/YMMine/View/SubViews/CPBindingAnimation.h @@ -0,0 +1,24 @@ +// +// CPBindingAnimation.h +// YuMi +// +// Created by P on 2024/9/23. +// + +#import + +@class AttachmentModel; + +NS_ASSUME_NONNULL_BEGIN + +@interface CPBindingAnimation : UIView + +@property (nonatomic, strong) AttachmentModel *cpAttachment; + ++ (void)display:(UIView *)superView + with:(AttachmentModel *)attachment + complete:(void(^)(void))complete; + +@end + +NS_ASSUME_NONNULL_END diff --git a/YuMi/Modules/YMMine/View/SubViews/CPBindingAnimation.m b/YuMi/Modules/YMMine/View/SubViews/CPBindingAnimation.m new file mode 100644 index 00000000..4ab5da63 --- /dev/null +++ b/YuMi/Modules/YMMine/View/SubViews/CPBindingAnimation.m @@ -0,0 +1,139 @@ +// +// CPBindingAnimation.m +// YuMi +// +// Created by P on 2024/9/23. +// + +#import "CPBindingAnimation.h" + +#import "UIView+VAP.h" +#import "AttachmentModel.h" +#import "QGVAPConfigModel.h" + + +@interface CPBindingAnimation() + +@property (nonatomic, strong) VAPView *cpVAPView; +@property (nonatomic, strong) NetImageView *avatarLoader; +@property (nonatomic, strong) NetImageView *cpAvatarLoader; + +@property (nonatomic, copy) void(^completeDisplay)(void); + +@end + +@implementation CPBindingAnimation + +- (instancetype)init { + if (self = [super init]) { + [self addSubview:self.cpVAPView]; + [self.cpVAPView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.mas_equalTo(self); + }]; + } + return self; +} + +// {"data":{"giftUrl":"https://image.pekolive.com/I Do.png","partitionId":2,"receiverAvatar":"https://img.molistar.xyz/default_avatar_molistar.png","roomUid":3238,"senderAvatar":"https://img.molistar.xyz/default_avatar_molistar.png"},"first":64,"second":643} +- (void)setCpAttachment:(AttachmentModel *)cpAttachment { + _cpAttachment = cpAttachment; +#if DEBUG + if (cpAttachment == nil) { + AttachmentModel *m = [[AttachmentModel alloc] init]; + m.data = @{@"senderAvatar":@"https://img.molistar.xyz/default_avatar_molistar.png", @"receiverAvatar":@"https://img.molistar.xyz/default_avatar_molistar.png"}; + _cpAttachment = m; + } +#endif + [self startPlay]; +} + +- (void)startPlay { + NSString *filePath = [[NSBundle mainBundle] pathForResource:@"CP绑定" ofType:@"mp4"]; + [self.cpVAPView playHWDMP4:filePath delegate:self]; +} + +- (void)endPlay { + if (_cpVAPView) { + @kWeakify(self); + dispatch_async(dispatch_get_main_queue(), ^{ + if (self.completeDisplay) { + self.completeDisplay(); + } + + @kStrongify(self); + [self.cpVAPView removeFromSuperview]; + self.cpVAPView = nil; + }); + } +} + ++ (void)display:(UIView *)superView + with:(AttachmentModel *)attachment + complete:(void(^)(void))complete { + CPBindingAnimation *cpBindingAnimation = [[CPBindingAnimation alloc] init]; + cpBindingAnimation.cpAttachment = attachment; + cpBindingAnimation.completeDisplay = complete; + [superView addSubview:cpBindingAnimation]; + [cpBindingAnimation mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(superView); + make.top.mas_equalTo(146); + make.width.mas_equalTo(KScreenWidth); + make.height.mas_equalTo(kGetScaleWidth(272)); + }]; +} + +#pragma mark - HWDMP4PlayDelegate +- (NSString *)contentForVapTag:(NSString *)tag resource:(QGVAPSourceInfo *)info { + NSDictionary *extraInfo = @{@"name1" : self.cpAttachment.data[@"senderNick"], + @"name2" : self.cpAttachment.data[@"receiverNick"]}; + return extraInfo[tag]; +} + +- (void)loadVapImageWithURL:(NSString *)urlStr + context:(NSDictionary *)context + completion:(VAPImageCompletionBlock)completionBlock { + @kWeakify(self); + dispatch_async(dispatch_get_main_queue(), ^{ + @kStrongify(self); + QGVAPSourceInfo *info = (QGVAPSourceInfo *)context[@"resource"]; + if ([info.contentTag isEqualToString:@"avatar1"] ) { + self.avatarLoader = [[NetImageView alloc] init]; + [self.avatarLoader loadImageWithUrl:self.cpAttachment.data[@"senderAvatar"] completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) { + completionBlock(image, nil, urlStr); + }]; + } else { + self.cpAvatarLoader = [[NetImageView alloc] init]; + [self.cpAvatarLoader loadImageWithUrl:self.cpAttachment.data[@"receiverAvatar"] completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) { + completionBlock(image, nil, urlStr); + }]; + } + }); +} + +- (BOOL)shouldStartPlayMP4:(VAPView *)container config:(QGVAPConfigModel *)config { + return YES; +} + +- (void)viewDidStopPlayMP4:(NSInteger)lastFrameIndex view:(VAPView *)container { + [self endPlay]; +} + +- (void)viewDidFinishPlayMP4:(NSInteger)totalFrameCount view:(VAPView *)container { + [self endPlay]; +} + +- (void)viewDidFailPlayMP4:(NSError *)error { + [self endPlay]; +} + +#pragma mark - +- (VAPView *)cpVAPView { + if (!_cpVAPView) { + _cpVAPView = [[VAPView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, 0)]; + _cpVAPView.contentMode = UIViewContentModeScaleAspectFill; + } + return _cpVAPView; +} + + +@end diff --git a/YuMi/Modules/YMMine/View/SubViews/CPCard.h b/YuMi/Modules/YMMine/View/SubViews/CPCard.h index bcfaa8e1..d354c904 100644 --- a/YuMi/Modules/YMMine/View/SubViews/CPCard.h +++ b/YuMi/Modules/YMMine/View/SubViews/CPCard.h @@ -16,7 +16,7 @@ @property (nonatomic, copy) void(^breakTheHeart)(RelationUserVO *model); - (void)updateForUserPage:(RelationUserVO *)model; -- (void)updateForCPList:(RelationUserVO *)model; +- (void)updateForCPList:(RelationUserVO *)model showBreakHeart:(BOOL)showBreakHeart; @end diff --git a/YuMi/Modules/YMMine/View/SubViews/CPCard.m b/YuMi/Modules/YMMine/View/SubViews/CPCard.m index 14dd41f1..1c962081 100644 --- a/YuMi/Modules/YMMine/View/SubViews/CPCard.m +++ b/YuMi/Modules/YMMine/View/SubViews/CPCard.m @@ -189,9 +189,11 @@ self.breakYourHeartButton.hidden = YES; } -- (void)updateForCPList:(RelationUserVO *)model { +- (void)updateForCPList:(RelationUserVO *)model showBreakHeart:(BOOL)showBreakHeart { self.relationUser = model; + self.breakYourHeartButton.hidden = !showBreakHeart; + [self.backgroundImage mas_updateConstraints:^(MASConstraintMaker *make) { make.bottom.mas_equalTo(self).offset(-12); }]; diff --git a/YuMi/Modules/YMMine/View/SubViews/CPGiftBanner.h b/YuMi/Modules/YMMine/View/SubViews/CPGiftBanner.h new file mode 100644 index 00000000..0af806b4 --- /dev/null +++ b/YuMi/Modules/YMMine/View/SubViews/CPGiftBanner.h @@ -0,0 +1,24 @@ +// +// CPGiftBanner.h +// YuMi +// +// Created by P on 2024/9/23. +// + +#import + +@class AttachmentModel; + +NS_ASSUME_NONNULL_BEGIN + +@interface CPGiftBanner : UIView + +@property (nonatomic, strong) AttachmentModel *bannerAttachment; + ++ (void)display:(UIView *)superView + with:(AttachmentModel *)attachment + complete:(void(^)(void))complete; + +@end + +NS_ASSUME_NONNULL_END diff --git a/YuMi/Modules/YMMine/View/SubViews/CPGiftBanner.m b/YuMi/Modules/YMMine/View/SubViews/CPGiftBanner.m new file mode 100644 index 00000000..cdf79ea5 --- /dev/null +++ b/YuMi/Modules/YMMine/View/SubViews/CPGiftBanner.m @@ -0,0 +1,165 @@ +// +// CPGiftBanner.m +// YuMi +// +// Created by P on 2024/9/23. +// + +#import "CPGiftBanner.h" + +#import "AttachmentModel.h" + +@interface CPGiftBanner() + +@property (nonatomic, strong) NetImageView *avatar_sender; +@property (nonatomic, strong) NetImageView *avatar_receiver; +@property (nonatomic, strong) NetImageView *giftImageView; + +@property (nonatomic, copy) void(^completeDisplay)(void); + +@end + +@implementation CPGiftBanner + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + UIImageView *background = [self backgroundImageView]; + [self addSubview:background]; + [background mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.mas_equalTo(self); + }]; + + UIStackView *stack = [[UIStackView alloc] init]; + stack.translatesAutoresizingMaskIntoConstraints = NO; + stack.spacing = 8; + stack.distribution = UIStackViewDistributionEqualSpacing; + stack.alignment = UIStackViewAlignmentCenter; + [self addSubview:stack]; + [stack mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(self); + make.height.mas_equalTo(50); + make.bottom.mas_equalTo(self).offset(-40); + }]; + + UILabel *label_1 = [self labelWith:@"Send"]; + UILabel *label_2 = [self labelWith:@"CP Gift"]; + [stack addArrangedSubview:self.avatar_sender]; + [stack addArrangedSubview:label_1]; + [stack addArrangedSubview:self.avatar_receiver]; + [stack addArrangedSubview:label_2]; + [stack addArrangedSubview:self.giftImageView]; + + [self.avatar_sender mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.height.mas_equalTo(38); + }]; + + [label_1 mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.mas_greaterThanOrEqualTo(32); + make.height.mas_equalTo(20); + }]; + + [self.avatar_receiver mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.height.mas_equalTo(38); + }]; + + [label_2 mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.mas_greaterThanOrEqualTo(46); + make.height.mas_equalTo(20); + }]; + + [self.giftImageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.height.mas_equalTo(50); + }]; + } + return self; +} + +- (void)setBannerAttachment:(AttachmentModel *)bannerAttachment { + _bannerAttachment = bannerAttachment; + self.avatar_sender.imageUrl = bannerAttachment.data[@"senderAvatar"]; + self.avatar_receiver.imageUrl = bannerAttachment.data[@"receiverAvatar"]; + self.giftImageView.imageUrl = bannerAttachment.data[@"giftUrl"]; +} + ++ (void)display:(UIView *)superView + with:(AttachmentModel *)attachment + complete:(void(^)(void))complete { + + CGFloat width = KScreenWidth; + CGFloat height = kGetScaleWidth(145); + CPGiftBanner *bannerView = [[CPGiftBanner alloc] initWithFrame:CGRectMake(KScreenWidth, 50, width, height)]; + bannerView.bannerAttachment = attachment; + bannerView.completeDisplay = complete; + [superView addSubview:bannerView]; + + @kWeakify(bannerView); + [UIView animateWithDuration:0.25 animations:^{ + bannerView.center = CGPointMake(superView.center.x, height/2 + 50); + } completion:^(BOOL finished) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ + bannerView.frame = CGRectMake(-KScreenWidth, 50, width, height); + } completion:^(BOOL finished) { + @kStrongify(bannerView); + if (bannerView.completeDisplay) { + bannerView.completeDisplay(); + } + [bannerView removeFromSuperview]; + }]; + }); + }]; +} + +#pragma mark - +- (UIImageView *)backgroundImageView { + UIImageView *iv = [[UIImageView alloc] init]; + iv.contentMode = UIViewContentModeScaleAspectFit; + iv.image = kImage(@"cp_banner"); + return iv; +} + +-(UILabel *)labelWith:(NSString *)content { + return [UILabel labelInitWithText:content + font:kFontSemibold(13) + textColor:UIColorFromRGB(0xFFE6A0)]; +} + +- (NetImageConfig *)avatarConfig { + NetImageConfig * config = [[NetImageConfig alloc]init]; + config.imageType = ImageTypeUserIcon; + config.placeHolder = [UIImageConstant defaultAvatarPlaceholder]; + return config; +} + +- (NetImageView *)avatar_sender { + if (!_avatar_sender) { + _avatar_sender = [[NetImageView alloc] initWithConfig:[self avatarConfig]]; + _avatar_sender.layer.masksToBounds = YES; + _avatar_sender.layer.cornerRadius = 38/2; + _avatar_sender.layer.borderColor = [UIColor whiteColor].CGColor; + _avatar_sender.layer.borderWidth = 1; + } + return _avatar_sender; +} + +- (NetImageView *)avatar_receiver { + if (!_avatar_receiver) { + _avatar_receiver = [[NetImageView alloc] initWithConfig:[self avatarConfig]]; + _avatar_receiver.layer.masksToBounds = YES; + _avatar_receiver.layer.cornerRadius = 38/2; + _avatar_receiver.layer.borderColor = [UIColor whiteColor].CGColor; + _avatar_receiver.layer.borderWidth = 1; + } + return _avatar_receiver; +} + +- (NetImageView *)giftImageView { + if (!_giftImageView) { + _giftImageView = [[NetImageView alloc] initWithConfig:[self avatarConfig]]; + _giftImageView.layer.masksToBounds = YES; + _giftImageView.layer.cornerRadius = 50/2; + } + return _giftImageView; +} + +@end diff --git a/YuMi/Modules/YMMine/View/SubViews/CPLevelUpAnimation.h b/YuMi/Modules/YMMine/View/SubViews/CPLevelUpAnimation.h new file mode 100644 index 00000000..da8ad1df --- /dev/null +++ b/YuMi/Modules/YMMine/View/SubViews/CPLevelUpAnimation.h @@ -0,0 +1,24 @@ +// +// CPLevelUpAnimation.h +// YuMi +// +// Created by P on 2024/9/23. +// + +#import + +@class AttachmentModel; + +NS_ASSUME_NONNULL_BEGIN + +@interface CPLevelUpAnimation : UIView + +@property (nonatomic, strong) AttachmentModel *cpAttachment; + ++ (void)display:(UIView *)superView + with:(AttachmentModel *)attachment + complete:(void(^)(void))complete; + +@end + +NS_ASSUME_NONNULL_END diff --git a/YuMi/Modules/YMMine/View/SubViews/CPLevelUpAnimation.m b/YuMi/Modules/YMMine/View/SubViews/CPLevelUpAnimation.m new file mode 100644 index 00000000..f5243b4b --- /dev/null +++ b/YuMi/Modules/YMMine/View/SubViews/CPLevelUpAnimation.m @@ -0,0 +1,193 @@ +// +// CPLevelUpAnimation.m +// YuMi +// +// Created by P on 2024/9/23. +// + +#import "CPLevelUpAnimation.h" + +#import "SVGA.h" +#import "AttachmentModel.h" + +@interface CPLevelUpAnimation() + +@property (nonatomic, strong) SVGAImageView *backgroundSvga; +@property (nonatomic, strong) UIImageView *bottomBannerImageView; +@property (nonatomic, strong) UILabel *bottomContentLabel; + +@property (nonatomic, copy) void(^completeDisplay)(void); + +@property (nonatomic, strong) NSTimer *endPlayTimer; + +@end + +@implementation CPLevelUpAnimation + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + [self addSubview:self.backgroundSvga]; + [self.backgroundSvga mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.mas_equalTo(self); + }]; + + [self addSubview:self.bottomBannerImageView]; + [self.bottomBannerImageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.mas_equalTo(self).offset(-19); + make.centerX.mas_equalTo(self); + make.height.mas_equalTo(17); + make.width.mas_equalTo(kGetScaleWidth(291)); + }]; + + [self addSubview:self.bottomContentLabel]; + [self.bottomContentLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.mas_equalTo(self.bottomBannerImageView); + }]; + } + return self; +} + +- (void)setCpAttachment:(AttachmentModel *)cpAttachment { + + +// { +// cpLevel = 1; +// partitionId = 4; +// receiverAvatar = "https://img.molistar.xyz/default_avatar_molistar.png"; +// receiverNick = "\U7231\U5764\Ud83d\Udc14"; +// receiverUid = 3164; +// roomUid = 3133; +// senderAvatar = "https://image.pekolive.com/image/3283950eebfb7a55ab84e5b15cc29421.jpeg"; +// senderNick = "\U5468\U59d0\U4f26"; +// senderUid = 3133; +// } + + _cpAttachment = cpAttachment; + + NSNumber *level = cpAttachment.data[@"cpLevel"]; + NSString *bannerImageName = [NSString stringWithFormat:@"cp_level_banner_lv_%@", level]; + self.bottomBannerImageView.image = kImage(bannerImageName); + + NSString *senderName = cpAttachment.data[@"senderNick"]; + NSString *receiverName = cpAttachment.data[@"receiverNick"]; + [self updateLabelContent:senderName and:receiverName level:level.integerValue]; + + @kWeakify(self); + SVGAParser *parser = [SVGAParser new]; + [parser parseWithNamed:[NSString stringWithFormat:@"level up %@", level] + inBundle:[NSBundle mainBundle] + completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) { + @kStrongify(self); + NSString *senderAvatar = cpAttachment.data[@"senderAvatar"]; + NSString *receiverAvatar = cpAttachment.data[@"receiverAvatar"]; + self.backgroundSvga.videoItem = videoItem; + [self.backgroundSvga setImageWithURL:[NSURL URLWithString:senderAvatar] forKey:@"user_img1"]; + [self.backgroundSvga setImageWithURL:[NSURL URLWithString:receiverAvatar] forKey:@"user_img2"]; + [self.backgroundSvga startAnimation]; + [self startTimer]; + } failureBlock:^(NSError * _Nonnull error) { + @kStrongify(self); + [self removeFromSuperview]; + if (self.completeDisplay) { + self.completeDisplay(); + } + }]; +} + +- (void)updateLabelContent:(NSString *)name_1 and:(NSString *)name_2 level:(NSInteger)level { + // 根据 level 确定 relation ship + NSString *relationship = @""; + switch (level) { + case 1: + relationship = @"Dup CP"; + break; + case 2: + relationship = @"Best Friends"; + break; + case 3: + relationship = @"Soulmates"; + break; + case 4: + relationship = @"Soulmates"; + break; + case 5: + relationship = @"Soulmates"; + break; + default: + relationship = @"Moli Star"; + break; + } + + // 构造文本内容 + NSString *fullText = [NSString stringWithFormat:@"%@ and %@ Become %@", name_1, name_2, relationship]; + + // 创建可变的 attributed string + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:fullText]; + + // 设置默认颜色为白色 + [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:NSMakeRange(0, fullText.length)]; + + // 找到 "and" 的位置,并设置其颜色为黄色 + NSRange andRange = [fullText rangeOfString:@"and"]; + if (andRange.location != NSNotFound) { + [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor yellowColor] range:andRange]; + } + + // 找到 "Become" 的位置,并设置其颜色为黄色 + NSRange becomeRange = [fullText rangeOfString:@"Become"]; + if (becomeRange.location != NSNotFound) { + [attributedString addAttribute:NSForegroundColorAttributeName value:UIColorFromRGB(0xFFF664) range:becomeRange]; + } + + // 将生成的 attributed string 赋值给 UILabel + self.bottomContentLabel.attributedText = attributedString; +} + ++ (void)display:(UIView *)superView + with:(AttachmentModel *)attachment + complete:(void (^)(void))complete { + CPLevelUpAnimation *levelUp = [[CPLevelUpAnimation alloc] initWithFrame:CGRectMake(0, 190, KScreenWidth, kGetScaleWidth(145))]; + levelUp.cpAttachment = attachment; + levelUp.completeDisplay = complete; + [superView addSubview:levelUp]; +} + +- (void)startTimer { + @kWeakify(self); + NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3 repeats:NO block:^(NSTimer * _Nonnull timer) { + @kStrongify(self); + [self removeFromSuperview]; + [self.backgroundSvga stopAnimation]; + if (self.completeDisplay) { + self.completeDisplay(); + } + }]; +} + +#pragma mark - +- (SVGAImageView *)backgroundSvga { + if (!_backgroundSvga) { + _backgroundSvga = [[SVGAImageView alloc]init]; + _backgroundSvga.backgroundColor = [UIColor clearColor]; + _backgroundSvga.autoPlay = YES; + } + return _backgroundSvga; +} + +- (UIImageView *)bottomBannerImageView { + if (!_bottomBannerImageView) { + _bottomBannerImageView = [[UIImageView alloc] initWithImage:kImage(@"cp_level_banner_lv_1")]; + } + return _bottomBannerImageView; +} + +- (UILabel *)bottomContentLabel { + if (!_bottomContentLabel) { + _bottomContentLabel = [UILabel labelInitWithText:@"" font:kFontMedium(12) textColor:[UIColor whiteColor]]; + _bottomContentLabel.textAlignment = NSTextAlignmentCenter; + } + return _bottomContentLabel; +} + + +@end diff --git a/YuMi/Modules/YMMine/View/SubViews/MineInfo/XPMineUserInfoHeaderView.m b/YuMi/Modules/YMMine/View/SubViews/MineInfo/XPMineUserInfoHeaderView.m index 7cf207d3..9521bf7f 100644 --- a/YuMi/Modules/YMMine/View/SubViews/MineInfo/XPMineUserInfoHeaderView.m +++ b/YuMi/Modules/YMMine/View/SubViews/MineInfo/XPMineUserInfoHeaderView.m @@ -208,7 +208,7 @@ return view;\ // 创建一个新的视图作为蒙层 UIView *overlay = [[UIView alloc] initWithFrame:self.pi_cycleScrollView.bounds]; - + overlay.userInteractionEnabled = NO; // 设置蒙层背景色为黑色,透明度为 0.5 overlay.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; @@ -940,7 +940,7 @@ return view;\ placeholderImage:[UIImageConstant defaultBannerPlaceholder]]; _pi_cycleScrollView.backgroundColor = [UIColor clearColor]; _pi_cycleScrollView.bannerImageViewContentMode = UIViewContentModeScaleAspectFill; - _pi_cycleScrollView.pageControlStyle = SDCycleScrollViewPageContolStyleAnimated;//SDCycleScrollViewPageContolStyleNone; + _pi_cycleScrollView.pageControlStyle = SDCycleScrollViewPageContolStyleNone; _pi_cycleScrollView.autoScroll = NO; // SDCycleScrollView没有适配阿语,在RTL下会乱滚,都用LTR算了 _pi_cycleScrollView.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; diff --git a/YuMi/Modules/YMRoom/View/AnimationView/XPRoomAnimationView.m b/YuMi/Modules/YMRoom/View/AnimationView/XPRoomAnimationView.m index 7837b6bb..dc9e2e1e 100644 --- a/YuMi/Modules/YMRoom/View/AnimationView/XPRoomAnimationView.m +++ b/YuMi/Modules/YMRoom/View/AnimationView/XPRoomAnimationView.m @@ -71,6 +71,10 @@ #import "LuckyGiftWinningBannerView.h" +#import "CPGiftBanner.h" +#import "CPLevelUpAnimation.h" +#import "CPBindingAnimation.h" + @interface XPRoomAnimationView ()< SVGAPlayerDelegate, NIMBroadcastManagerDelegate, @@ -170,13 +174,11 @@ HWDMP4PlayDelegate> @property (nonatomic, copy) NSString *GiftDynamicEffectListPath; -@property (nonatomic, strong) NSMutableArray *roomLuckWinningBannerModels; -@property (nonatomic, assign) BOOL isDisplayLuckWinningBanner; +/// 新的特效播放队列,包括幸运礼物 banner, CP banner 和 CP 特效 +@property (nonatomic, strong) NSMutableArray *roomEffectModelsQueueV2; +@property (nonatomic, assign) BOOL isRoomEffectV2Displaying; ///CP特效 -@property (nonatomic, strong) VAPView *cpVAPView; -@property (nonatomic, strong) NetImageView *avatarLoader; -@property (nonatomic, strong) NetImageView *cpAvatarLoader; @property (nonatomic, strong) AttachmentModel *cpAttachment; @end @@ -208,7 +210,7 @@ HWDMP4PlayDelegate> [self initSubViews]; [self initSubViewConstraints]; - _roomLuckWinningBannerModels = [NSMutableArray array]; + _roomEffectModelsQueueV2 = [NSMutableArray array]; _GiftDynamicEffectListPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) xpSafeObjectAtIndex:0] stringByAppendingPathComponent:@"GiftDynamicEffectList"]; } @@ -387,15 +389,7 @@ HWDMP4PlayDelegate> attachment.second == Custom_Message_Sub_Super_Gift_Winning_Coins_ALL_Room) { [self receiveLuckGiftBanner:attachment]; } else if (attachment.first == CustomMessageType_CP) { - self.cpAttachment = attachment; - if (attachment.second == Custom_Message_Sub_CP_Gift) { - - } else if (attachment.second == Custom_Message_Sub_CP_Upgrade) { - - } else if (attachment.second == Custom_Message_Sub_CP_Binding) { - [self playCPBinding]; -// {"data":{"giftUrl":"https://image.pekolive.com/I Do.png","partitionId":2,"receiverAvatar":"https://img.molistar.xyz/default_avatar_molistar.png","roomUid":3238,"senderAvatar":"https://img.molistar.xyz/default_avatar_molistar.png"},"first":64,"second":643} - } + [self receiveCPEvent: attachment]; } } } @@ -429,33 +423,56 @@ HWDMP4PlayDelegate> } - (void)receiveLuckGiftBanner:(AttachmentModel *)attachment { - [self.roomLuckWinningBannerModels addObject:attachment]; - if (!self.isDisplayLuckWinningBanner) { - [self processNextLuckWinningAttachment]; + [self.roomEffectModelsQueueV2 addObject:attachment]; + if (!self.isRoomEffectV2Displaying) { + [self processNextRoomEffectAttachment]; } } -- (void)processNextLuckWinningAttachment { +- (void)processNextRoomEffectAttachment { // 检查队列是否有元素 - if (self.roomLuckWinningBannerModels.count == 0) { + if (self.roomEffectModelsQueueV2.count == 0) { // 如果队列为空,停止处理 - self.isDisplayLuckWinningBanner = NO; + self.isRoomEffectV2Displaying = NO; return; } // 从队列中取出第一个元素并移出队列 - AttachmentModel *nextAttachment = [self.roomLuckWinningBannerModels firstObject]; - [self.roomLuckWinningBannerModels removeObjectAtIndex:0]; + AttachmentModel *nextAttachment = [self.roomEffectModelsQueueV2 firstObject]; + [self.roomEffectModelsQueueV2 removeObjectAtIndex:0]; // 设置为正在显示的状态 - self.isDisplayLuckWinningBanner = YES; + self.isRoomEffectV2Displaying = YES; + + switch (nextAttachment.second) { + case Custom_Message_Sub_Super_Gift_Winning_Coins_ALL_Room: + [self playLuckyWinningBanner:nextAttachment]; + break; + case Custom_Message_Sub_CP_Gift: + [self playCPGiftBanner:nextAttachment]; + break; + case Custom_Message_Sub_CP_Upgrade: + [self playCPLevelUp:nextAttachment]; + break; + case Custom_Message_Sub_CP_Binding: + [self playCPBinding:nextAttachment]; + break; + default: + break; + } +} + +- (void)playLuckyWinningBanner:(AttachmentModel *)nextAttachment { RoomInfoModel *roomInfo = self.delegate.getRoomInfo; // 执行 display 方法 @kWeakify(self); - [LuckyGiftWinningBannerView display:self inRoomUid:roomInfo.uid with:nextAttachment complete:^{ + [LuckyGiftWinningBannerView display:self + inRoomUid:roomInfo.uid + with:nextAttachment + complete:^{ @kStrongify(self); // Display 完成后,继续处理下一个 - [self processNextLuckWinningAttachment]; + [self processNextRoomEffectAttachment]; } exitCurrentRoom:^{ @kStrongify(self); [self.delegate exitRoom]; @@ -2526,42 +2543,41 @@ HWDMP4PlayDelegate> } #pragma mark - CP 礼物 -- (void)playCPBinding { - [self addSubview:self.cpVAPView]; - [self.cpVAPView mas_makeConstraints:^(MASConstraintMaker *make) { - make.centerX.mas_equalTo(self); - make.top.mas_equalTo(146); - make.width.mas_equalTo(KScreenWidth); - make.height.mas_equalTo(230); +- (void)receiveCPEvent:(AttachmentModel *)attachment { + [self.roomEffectModelsQueueV2 addObject:attachment]; + if (!self.isRoomEffectV2Displaying) { + [self processNextRoomEffectAttachment]; + } +} + +- (void)playCPBinding:(AttachmentModel *)attachment { + @kWeakify(self); + [CPBindingAnimation display:self + with:attachment + complete:^{ + @kStrongify(self); + [self processNextRoomEffectAttachment]; }]; - - NSString *filePath = [[NSBundle mainBundle] pathForResource:@"CP绑定" ofType:@"mp4"]; - [self.cpVAPView playHWDMP4:filePath delegate:self]; } -//provide the content for tags, maybe text or url string ... -- (NSString *)contentForVapTag:(NSString *)tag resource:(QGVAPSourceInfo *)info { - NSDictionary *extraInfo = @{@"[name1]" : @"你阿妈",//self.cpAttachment.data[@"你阿妈"], - @"[name2]" : @"你阿爸"}; - return extraInfo[tag]; +- (void)playCPGiftBanner:(AttachmentModel *)attachMent { + @kWeakify(self); + [CPGiftBanner display:self + with:attachMent + complete:^{ + @kStrongify(self); + [self processNextRoomEffectAttachment]; + }]; } -//provide image for url from tag content -- (void)loadVapImageWithURL:(NSString *)urlStr context:(NSDictionary *)context completion:(VAPImageCompletionBlock)completionBlock { - dispatch_async(dispatch_get_main_queue(), ^{ - QGVAPSourceInfo *info = (QGVAPSourceInfo *)context[@"resource"]; - if ([info.contentTag isEqualToString:@"avatar1"] ) { - self.avatarLoader = [[NetImageView alloc] init]; - [self.avatarLoader loadImageWithUrl:self.cpAttachment.data[@"senderAvatar"] completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) { - completionBlock(image, nil, urlStr); - }]; - } else { - self.cpAvatarLoader = [[NetImageView alloc] init]; - [self.cpAvatarLoader loadImageWithUrl:self.cpAttachment.data[@"receiverAvatar"] completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) { - completionBlock(image, nil, urlStr); - }]; - } - }); +- (void)playCPLevelUp:(AttachmentModel *)attachMent { + @kWeakify(self); + [CPLevelUpAnimation display:self + with:attachMent + complete:^{ + @kStrongify(self); + [self processNextRoomEffectAttachment]; + }]; } #pragma mark - 心愿礼物 @@ -2599,10 +2615,6 @@ HWDMP4PlayDelegate> #pragma mark - HWDMP4PlayDelegate //即将开始播放时询问,true马上开始播放,false放弃播放 - (BOOL)shouldStartPlayMP4:(VAPView *)container config:(QGVAPConfigModel *)config { - if (container == self.cpVAPView) { - return YES; - } - CGFloat width = config.info.size.width; CGFloat height = config.info.size.height; @@ -2635,9 +2647,6 @@ HWDMP4PlayDelegate> } else if(container == self.luckyVapGiftEffectView) { [self.luckyVapGiftEffectView removeFromSuperview]; self.luckyVapGiftEffectView = nil; - } else if (container == self.cpVAPView) { - [self.cpVAPView removeFromSuperview]; - self.cpVAPView = nil; } }); } @@ -2674,11 +2683,6 @@ HWDMP4PlayDelegate> if (self.isLargeGiftAnimating == YES) { self.isLargeGiftAnimating = NO; } - - if (_cpVAPView) { - [self.cpVAPView removeFromSuperview]; - self.cpVAPView = nil; - } } #pragma mark - PAGViewListener /** @@ -3014,13 +3018,4 @@ HWDMP4PlayDelegate> return _broadCastHieght; } -- (VAPView *)cpVAPView { - if (!_cpVAPView) { - _cpVAPView = [[VAPView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)]; - _cpVAPView.contentMode = UIViewContentModeScaleAspectFill; - _cpVAPView.hwd_Delegate = self; - } - return _cpVAPView; -} - @end diff --git a/YuMi/Modules/YMRoom/View/MenuContainerView/XPRoomMenuContainerView.m b/YuMi/Modules/YMRoom/View/MenuContainerView/XPRoomMenuContainerView.m index 738696db..d6505dab 100644 --- a/YuMi/Modules/YMRoom/View/MenuContainerView/XPRoomMenuContainerView.m +++ b/YuMi/Modules/YMRoom/View/MenuContainerView/XPRoomMenuContainerView.m @@ -38,8 +38,6 @@ @interface XPRoomMenuContainerView () -/// -//@property (nonatomic,strong) UIStackView *stackView; ///输入框 @property (nonatomic,strong) UIButton *inputButton; ///麦 @@ -69,6 +67,9 @@ @property (nonatomic,strong) XPRoomMessageBubbleView *miniMessageView; ///代理 @property (nonatomic,weak) id delegate; + +@property (nonatomic, strong) UIStackView *stackView; + @end @@ -235,29 +236,24 @@ #pragma mark - Private Method - (void)initSubViews { -// self.backgroundColor = UIColorRGBAlpha(0xFFFFFF, 0.2); - - UIStackView *stack = [[UIStackView alloc] init]; - stack.spacing = 9; - stack.alignment = UIStackViewAlignmentBottom; -// stack.backgroundColor = [UIColor systemPurpleColor]; - [self addSubview:stack]; - [stack mas_makeConstraints:^(MASConstraintMaker *make) { + [self addSubview:self.stackView]; + [self.stackView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self); make.leading.mas_equalTo(self).offset(15); make.trailing.mas_equalTo(self).offset(-15); make.height.mas_equalTo(46); }]; - [stack addArrangedSubview:self.inputButton]; - [stack addArrangedSubview:self.micButton]; - [stack addArrangedSubview:self.voiceButton]; - [stack addArrangedSubview:self.arrangeMicButton]; - [stack addArrangedSubview:self.messageButton]; - [stack addArrangedSubview:self.moreButton]; - [stack addArrangedSubview:self.svgDisplayView]; - - [stack addSubview:self.faceButton]; - [stack addSubview:self.giftButton]; + [self.stackView addArrangedSubview:self.inputButton]; + [self.stackView addArrangedSubview:self.micButton]; + [self.stackView addArrangedSubview:self.voiceButton]; + [self.stackView addArrangedSubview:self.arrangeMicButton]; + [self.stackView addArrangedSubview:self.messageButton]; + [self.stackView addArrangedSubview:self.moreButton]; + [self.stackView addArrangedSubview:self.svgDisplayView]; + + [self.stackView addSubview:self.faceButton]; + [self.stackView addSubview:self.giftButton]; @kWeakify(self); [self.parser parseWithNamed:@"ms_room_gift_svga_icon" inBundle:nil completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) { @@ -268,37 +264,9 @@ [self.svgDisplayView startAnimation]; } failureBlock:^(NSError * _Nullable error) { }]; - - return; - -// [self.stackView addArrangedSubview:self.micButton]; -// [self.stackView addArrangedSubview:self.voiceButton]; -// [self.stackView addArrangedSubview:self.faceButton]; -// [self.stackView addArrangedSubview:self.arrangeMicButton]; -// [self.stackView addArrangedSubview:self.messageButton]; -// [self.stackView addArrangedSubview:self.moreButton]; -// [self.stackView addArrangedSubview:self.baiShunGameButton]; -// [self.stackView addArrangedSubview:self.pkButton]; - - -// if (isMSRTL()) { -// self.stackView.transform = CGAffineTransformMakeRotation(M_PI); -// }else{ -// self.stackView.transform = CGAffineTransformIdentity; -// } } - (void)initSubViewConstraints { -// [self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) { -// make.top.mas_equalTo(self).offset(16); -// make.height.mas_equalTo(29); -// make.leading.mas_equalTo(self.inputButton.mas_trailing).offset(15); -// make.trailing.mas_equalTo(self.giftButton.mas_leading).offset(-11); -// }]; -// -// [self.stackView mas_makeConstraints:^(MASConstraintMaker *make) { -// make.top.bottom.leading.trailing.height.mas_equalTo(self.scrollView); -// }]; [self.inputButton mas_makeConstraints:^(MASConstraintMaker *make) { // make.top.mas_equalTo(16); @@ -678,16 +646,15 @@ } return _parser; } -//- (UIStackView *)stackView { -// if (!_stackView) { -// _stackView = [[UIStackView alloc] init]; -// _stackView.axis = UILayoutConstraintAxisHorizontal; -// _stackView.distribution = UIStackViewDistributionFill; -// _stackView.alignment = UIStackViewAlignmentLeading; -// _stackView.spacing = 11; -// } -// return _stackView; -//} + +- (UIStackView *)stackView { + if (!_stackView) { + _stackView = [[UIStackView alloc] init]; + _stackView.spacing = 9; + _stackView.alignment = UIStackViewAlignmentBottom; + } + return _stackView; +} - (UIButton *)arrangeMicButton { if (!_arrangeMicButton) { diff --git a/YuMi/Resources/cp/3.mp4 b/YuMi/Resources/cp/3.mp4 index 68a1a35b..10a5e9ac 100644 Binary files a/YuMi/Resources/cp/3.mp4 and b/YuMi/Resources/cp/3.mp4 differ diff --git a/YuMi/Resources/cp/4.mp4 b/YuMi/Resources/cp/4.mp4 index ad68e5c1..1ad167be 100644 Binary files a/YuMi/Resources/cp/4.mp4 and b/YuMi/Resources/cp/4.mp4 differ diff --git a/YuMi/Resources/cp/5.mp4 b/YuMi/Resources/cp/5.mp4 index dd7b4ab2..cc6611bc 100644 Binary files a/YuMi/Resources/cp/5.mp4 and b/YuMi/Resources/cp/5.mp4 differ diff --git a/YuMi/Resources/cp/level up 1.svga b/YuMi/Resources/cp/level up 1.svga new file mode 100644 index 00000000..85d47597 Binary files /dev/null and b/YuMi/Resources/cp/level up 1.svga differ diff --git a/YuMi/Resources/cp/level up 2.svga b/YuMi/Resources/cp/level up 2.svga new file mode 100644 index 00000000..b6ded6fa Binary files /dev/null and b/YuMi/Resources/cp/level up 2.svga differ diff --git a/YuMi/Resources/cp/level up 3.svga b/YuMi/Resources/cp/level up 3.svga new file mode 100644 index 00000000..0e558f22 Binary files /dev/null and b/YuMi/Resources/cp/level up 3.svga differ diff --git a/YuMi/Resources/cp/level up 4.svga b/YuMi/Resources/cp/level up 4.svga new file mode 100644 index 00000000..8b863f59 Binary files /dev/null and b/YuMi/Resources/cp/level up 4.svga differ diff --git a/YuMi/Resources/cp/level up 5.svga b/YuMi/Resources/cp/level up 5.svga new file mode 100644 index 00000000..affd1867 Binary files /dev/null and b/YuMi/Resources/cp/level up 5.svga differ