4124 lines
165 KiB
Objective-C
4124 lines
165 KiB
Objective-C
//
|
||
// RoomAnimationView.m
|
||
// YuMi
|
||
//
|
||
// Created by P on 2025/1/13.
|
||
//
|
||
|
||
#import "RoomAnimationView.h"
|
||
|
||
#import <POP.h>
|
||
#import <SVGA.h>
|
||
#import <libpag/libpag.h>
|
||
#import <NIMSDK/NIMSDK.h>
|
||
#import <UIImageView+WebCache.h>
|
||
|
||
#import "UIView+VAP.h"
|
||
|
||
#import "ClientConfig.h"
|
||
#import "XPGiftStorage.h"
|
||
#import "UserInfoModel.h"
|
||
#import "RoomInfoModel.h"
|
||
#import "MicroQueueModel.h"
|
||
#import "AttachmentModel.h"
|
||
#import "QGVAPConfigModel.h"
|
||
#import "ActivityInfoModel.h"
|
||
#import "GiftReceiveInfoModel.h"
|
||
#import "XPRoomEnterHideTipView.h"
|
||
#import "XPMessageRemoteExtModel.h"
|
||
#import "PIBaseAnimationViewModel.h"
|
||
#import "XPRoomGiftAnimationParser.h"
|
||
|
||
#import "GiftComboManager.h"
|
||
#import "GiftAnimationManager.h"
|
||
|
||
#import "MSRoomGameWebVC.h"
|
||
#import "XPRoomViewController.h"
|
||
#import "PIUniversalBannerView.h"
|
||
#import "PIUniversalBannerModel.h"
|
||
|
||
#import "CPGiftBanner.h"
|
||
#import "CPLevelUpAnimation.h"
|
||
#import "CPBindingAnimation.h"
|
||
#import "GameUniversalBannerView.h"
|
||
#import "LuckyGiftWinningFlagView.h"
|
||
#import "LuckyGiftWinningBannerView.h"
|
||
#import "RoomHighValueGiftBannerAnimation.h"
|
||
#import "LuckyPackageBannerView.h"
|
||
#import "BravoGiftBannerView.h"
|
||
#import "XCCurrentVCStackManager.h"
|
||
#import "BravoGiftWinningFlagView.h"
|
||
#import "RoomEnterModel.h"
|
||
|
||
// Old Methods
|
||
#import "DatingInfoModel.h"
|
||
#import "XPWebViewController.h"
|
||
#import "XPRoomCandyGiftView.h"
|
||
#import "XPSailingAnimationView.h"
|
||
#import "AcrossRoomPKPrizeModel.h"
|
||
#import "XPRoomNobleLevelUpView.h"
|
||
|
||
#import "XPRoomGiftCompoundView.h"
|
||
#import "XPRoomGiftBroadcastView.h"
|
||
#import "XPRoomLuckyBigPrizeView.h"
|
||
#import "XPTreasureFairyGiftView.h"
|
||
#import "XPAcrossRoomPKPrizeView.h"
|
||
#import "PIRoomGiftBroadcastWindow.h"
|
||
#import "XPRoomDatingAnimationView.h"
|
||
#import "XPRoomAnchorRankBannerView.h"
|
||
|
||
#import "XPRoomGraffitiGiftAnimationView.h"
|
||
#import "XPRoomFunctionContainerView.h"
|
||
#import "XPRoomRankEntranceView.h"
|
||
#import "XPRoomAnchorRankEnterView.h"
|
||
#import "MSRoomOnLineView.h"
|
||
|
||
static const CGFloat kTipViewStayDuration = 3.0;
|
||
static const CGFloat kTipViewMoveDuration = 0.5;
|
||
|
||
@interface RoomAnimationView () <
|
||
PAGViewListener,
|
||
SVGAPlayerDelegate,
|
||
HWDMP4PlayDelegate,
|
||
GiftAnimationDelegate,
|
||
NIMBroadcastManagerDelegate,
|
||
|
||
PIUniversalBannerViewDelegate,
|
||
XPRoomGiftBroadcastViewDelegate,
|
||
XPRoomLuckyBigPrizeViewDelegate,
|
||
PIRoomGiftBroadcastWindowDelegate,
|
||
XPRoomAnchorRankBannerViewDelegate,
|
||
|
||
XPRoomGraffitiGiftAnimationViewDelegate
|
||
>
|
||
|
||
@property (nonatomic, weak) id<RoomHostDelegate>hostDelegate;
|
||
|
||
///最底层
|
||
@property (nonatomic, strong) XPRoomAnimationHitView *bottomContainer;
|
||
///中层
|
||
@property (nonatomic, strong) XPRoomAnimationHitView *middleContainer;
|
||
///顶层
|
||
@property (nonatomic, strong) XPRoomAnimationHitView *topContainer;
|
||
|
||
@property (nonatomic, strong) XPRoomAnimationHitView *bannerContainer;
|
||
|
||
/// --- 进场
|
||
/// 存放进房待播放动画的"队列"(这里用数组模拟队列 FIFO)
|
||
@property (nonatomic, strong) NSMutableArray<NSDictionary *> *enterRoomAnimationQueue;
|
||
/// 标记当前是否有进房动画在执行
|
||
@property (nonatomic, assign) BOOL isEnterRoomAnimating;
|
||
@property (nonatomic, strong) SVGAImageView *enterEffectView;
|
||
|
||
/// --- 礼物
|
||
@property(nonatomic, strong) PAGView *pagGiftEffectView;
|
||
@property(nonatomic, strong) SVGAParser *vggParser;
|
||
@property(nonatomic, assign) BOOL isPlayingGiftEffect;
|
||
@property(nonatomic, strong) NSMutableArray *svgaQueue;
|
||
@property(nonatomic, strong) VAPView *vapGiftEffectView;
|
||
@property(nonatomic, strong) SVGAImageView *vggGiftEffectView;
|
||
@property(nonatomic, strong) NSMutableArray *mp4AvatarLoaders;
|
||
@property(nonatomic, copy) NSString *GiftDynamicEffectListPath;
|
||
@property(nonatomic, strong) dispatch_source_t giftEffectTimer;
|
||
@property(nonatomic, strong) dispatch_queue_t giftEffectsQueue;
|
||
@property(nonatomic, strong) XPRoomGiftAnimationParser *vapParser;
|
||
@property(nonatomic, strong) GiftAnimationManager *giftAnimationManager;
|
||
@property(nonatomic, strong) GiftReceiveInfoModel *mp4TempReceiveInfoModel;
|
||
|
||
/// --- 飘屏
|
||
@property (nonatomic, strong) NSMutableArray *roomBannertModelsQueueV2; // 特效播放队列,包括幸运礼物 banner, CP banner 和 CP 特效
|
||
@property (nonatomic, assign) BOOL isRoomBannerV2Displaying;
|
||
|
||
// --- Brove 金币动画
|
||
@property (nonatomic, strong) SVGAVideoEntity *broveSVGAEntity_lv_1;
|
||
@property (nonatomic, strong) SVGAVideoEntity *broveSVGAEntity_lv_2;
|
||
@property (nonatomic, strong) SVGAVideoEntity *broveSVGAEntity_lv_3;
|
||
@property (nonatomic, strong) NSMutableArray *broveSVGAQueue;
|
||
@property (nonatomic, assign) BOOL isBroveSVGAPlaying;
|
||
@property (nonatomic, assign) NSInteger viewIndex;
|
||
|
||
/// --- 座驾
|
||
///座驾pag动效
|
||
@property(nonatomic, strong) PAGView *carPagEffectView;
|
||
///座驾VAP特效
|
||
@property(nonatomic, strong) VAPView *carVapEffectView;
|
||
@property(nonatomic, strong) SVGAImageView *carSVGAEffectView;
|
||
@property(nonatomic, strong) NSMutableArray<NSDictionary *> *carEffectQueue;
|
||
|
||
/// --- 旧逻辑,有需要再重构
|
||
@property(nonatomic, assign) BOOL isPlayOfB;
|
||
@property(nonatomic, strong) NSMutableArray<PIBaseAnimationViewModel *> *animationListB; // 玩法
|
||
@property(nonatomic, assign) CGFloat broadCastHieght;
|
||
@property (nonatomic, strong) NetImageView *imageLoader;
|
||
@property (nonatomic, strong) SVGAImageView *datingEffectView;
|
||
@property (nonatomic, strong) NSMutableArray<AttachmentModel *> *sailingQueue;
|
||
@property (nonatomic, strong) NSMutableArray<DatingInfoModel *> *datingEffectQueue;
|
||
@property (nonatomic, strong) NSMutableArray<AttachmentModel *> *graffitiGiftQueue;
|
||
@property (nonatomic, strong) NSMutableArray<AcrossRoomPKPrizeModel *> *acrossRoomPKQueue;
|
||
@property (nonatomic,strong) SVGAImageView *luckyGiftEffectView; ///福袋礼物送礼物的特效
|
||
@property (nonatomic, strong) VAPView *luckyVapGiftEffectView; ///福袋礼物VAP特效
|
||
|
||
//@property(nonatomic, strong) PIUniversalBannerView *tempUniversalBanner; // 防止内存没有被持有而过早回收
|
||
@property(nonatomic, strong) NSMutableArray <PIUniversalBannerView *>* universalBannerViewCaches;
|
||
@end
|
||
|
||
@implementation RoomAnimationView
|
||
|
||
- (void)setIsPlayOfB:(BOOL)isPlayOfB {
|
||
_isPlayOfB = isPlayOfB;
|
||
}
|
||
|
||
- (void)dealloc
|
||
{
|
||
[[NIMSDK sharedSDK].broadcastManager removeDelegate:self];
|
||
|
||
[NSObject cancelPreviousPerformRequestsWithTarget:self];
|
||
|
||
[self pop_removeAllAnimations];
|
||
|
||
if (_giftEffectTimer && !dispatch_source_testcancel(_giftEffectTimer)) {
|
||
dispatch_source_cancel(_giftEffectTimer);
|
||
_giftEffectTimer = nil;
|
||
}
|
||
|
||
if (_giftEffectsQueue) {
|
||
self.giftEffectsQueue = NULL;
|
||
}
|
||
}
|
||
|
||
-(void)resumeTimer{
|
||
if(self.giftEffectTimer != nil){
|
||
dispatch_source_cancel(self.giftEffectTimer);
|
||
self.giftEffectTimer = nil;
|
||
}
|
||
[self.pagGiftEffectView removeListener:self];
|
||
self.hostDelegate = nil;
|
||
[[GiftComboManager sharedManager] removeComboFlag];
|
||
}
|
||
|
||
- (instancetype)initWithHostDelegate:(id<RoomHostDelegate>)hDelegate {
|
||
if (self = [super init]) {
|
||
self.hostDelegate = hDelegate;
|
||
[[NIMSDK sharedSDK].broadcastManager addDelegate:self];
|
||
|
||
[self setup];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
#pragma mark - SETUP
|
||
- (void)setup {
|
||
[self setupUI];
|
||
[self setupEnterRoom];
|
||
[self setupGiftEffects];
|
||
[self setupBanner];
|
||
[self setupCar];
|
||
[self setupOldMethods];
|
||
}
|
||
|
||
- (void)setupUI {
|
||
[self addSubview:self.bottomContainer];
|
||
[self insertSubview:self.middleContainer aboveSubview:self.bottomContainer];
|
||
[self insertSubview:self.topContainer aboveSubview:self.middleContainer];
|
||
[self insertSubview:self.bannerContainer aboveSubview:self.topContainer];
|
||
|
||
[self.bottomContainer mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.edges.mas_equalTo(self);
|
||
}];
|
||
[self.middleContainer mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.edges.mas_equalTo(self);
|
||
}];
|
||
[self.topContainer mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.edges.mas_equalTo(self);
|
||
}];
|
||
[self.bannerContainer mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.mas_equalTo(self).offset(kNavigationHeight);
|
||
make.leading.trailing.mas_equalTo(self);
|
||
make.height.mas_equalTo(80);
|
||
}];
|
||
}
|
||
|
||
- (void)setupEnterRoom {
|
||
self.enterRoomAnimationQueue = [NSMutableArray array];
|
||
}
|
||
|
||
- (void)setupGiftEffects {
|
||
self.GiftDynamicEffectListPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) xpSafeObjectAtIndex:0] stringByAppendingPathComponent:@"GiftDynamicEffectList"];
|
||
|
||
self.giftAnimationManager = [[GiftAnimationManager alloc] initWithContainerView:self.bottomContainer];
|
||
self.giftAnimationManager.delegate = self;
|
||
|
||
_giftEffectsQueue = dispatch_queue_create("com.RoomGiftEffects.queue", DISPATCH_QUEUE_SERIAL);
|
||
}
|
||
|
||
- (void)setupBanner {
|
||
_roomBannertModelsQueueV2 = [NSMutableArray array];
|
||
// 新方案:启用区域化Banner手势系统
|
||
[self setupZonedBannerGesture];
|
||
}
|
||
|
||
#pragma mark - Zoned Banner Gesture System
|
||
|
||
- (void)setupZonedBannerGesture {
|
||
NSLog(@"🚀 新方案: 启用区域化Banner手势系统");
|
||
|
||
// 1. 添加中央区域滑动手势
|
||
UIPanGestureRecognizer *centerPanGesture =
|
||
[[UIPanGestureRecognizer alloc] initWithTarget:self
|
||
action:@selector(handleCenterPan:)];
|
||
centerPanGesture.delegate = self;
|
||
centerPanGesture.minimumNumberOfTouches = 1;
|
||
centerPanGesture.maximumNumberOfTouches = 1;
|
||
[self.bannerContainer addGestureRecognizer:centerPanGesture];
|
||
|
||
// 2. 添加中央区域点击手势(备选)
|
||
UITapGestureRecognizer *centerTapGesture =
|
||
[[UITapGestureRecognizer alloc] initWithTarget:self
|
||
action:@selector(handleCenterTap:)];
|
||
centerTapGesture.delegate = self;
|
||
[self.bannerContainer addGestureRecognizer:centerTapGesture];
|
||
|
||
// 3. 添加左右区域点击手势
|
||
UITapGestureRecognizer *leftTapGesture =
|
||
[[UITapGestureRecognizer alloc] initWithTarget:self
|
||
action:@selector(handleLeftTap:)];
|
||
leftTapGesture.delegate = self;
|
||
[self.bannerContainer addGestureRecognizer:leftTapGesture];
|
||
|
||
UITapGestureRecognizer *rightTapGesture =
|
||
[[UITapGestureRecognizer alloc] initWithTarget:self
|
||
action:@selector(handleRightTap:)];
|
||
rightTapGesture.delegate = self;
|
||
[self.bannerContainer addGestureRecognizer:rightTapGesture];
|
||
|
||
// 4. 设置手势优先级:中央区域Pan优先于Tap
|
||
[centerTapGesture requireGestureRecognizerToFail:centerPanGesture];
|
||
|
||
// 5. 手势事件传递配置
|
||
centerPanGesture.cancelsTouchesInView = NO;
|
||
centerPanGesture.delaysTouchesBegan = NO;
|
||
centerPanGesture.delaysTouchesEnded = NO;
|
||
|
||
centerTapGesture.cancelsTouchesInView = NO;
|
||
centerTapGesture.delaysTouchesBegan = NO;
|
||
centerTapGesture.delaysTouchesEnded = NO;
|
||
|
||
leftTapGesture.cancelsTouchesInView = NO;
|
||
leftTapGesture.delaysTouchesBegan = NO;
|
||
leftTapGesture.delaysTouchesEnded = NO;
|
||
|
||
rightTapGesture.cancelsTouchesInView = NO;
|
||
rightTapGesture.delaysTouchesBegan = NO;
|
||
rightTapGesture.delaysTouchesEnded = NO;
|
||
|
||
NSLog(@"✅ 区域化Banner手势配置完成");
|
||
NSLog(@" - 中央区域: Pan手势 + Tap手势(备选)");
|
||
NSLog(@" - 左右区域: Tap手势(透传)");
|
||
NSLog(@" - 手势优先级: 中央Pan优先于中央Tap");
|
||
NSLog(@" - bannerContainer手势数量: %ld", (long)self.bannerContainer.gestureRecognizers.count);
|
||
|
||
// 验证手势识别器是否正确添加
|
||
for (UIGestureRecognizer *gesture in self.bannerContainer.gestureRecognizers) {
|
||
NSLog(@" - 手势: %@ (delegate: %@)", NSStringFromClass([gesture class]), gesture.delegate ? @"已设置" : @"未设置");
|
||
}
|
||
|
||
// 添加调试视图(仅在测试环境)
|
||
[self addZoneDebugViews];
|
||
|
||
// 确保bannerContainer可以接收用户交互
|
||
self.bannerContainer.userInteractionEnabled = YES;
|
||
NSLog(@"🔧 bannerContainer用户交互已启用: %@", self.bannerContainer.userInteractionEnabled ? @"是" : @"否");
|
||
|
||
// 检查并启用所有Banner子视图的用户交互
|
||
for (UIView *subview in self.bannerContainer.subviews) {
|
||
if (!subview.userInteractionEnabled) {
|
||
subview.userInteractionEnabled = YES;
|
||
NSLog(@"🔧 启用Banner子视图用户交互: %@", NSStringFromClass([subview class]));
|
||
}
|
||
|
||
// 特别处理LuckyGiftWinningBannerView的按钮冲突
|
||
if ([NSStringFromClass([subview class]) containsString:@"LuckyGiftWinningBannerView"]) {
|
||
NSLog(@"🔧 检测到LuckyGiftWinningBannerView,将在配置方法中处理");
|
||
}
|
||
}
|
||
|
||
// 验证手势识别器状态
|
||
NSLog(@"🔧 手势识别器验证:");
|
||
NSLog(@" - bannerContainer手势数量: %ld", (long)self.bannerContainer.gestureRecognizers.count);
|
||
for (UIGestureRecognizer *gesture in self.bannerContainer.gestureRecognizers) {
|
||
NSLog(@" - 手势: %@ (enabled: %@, delegate: %@)",
|
||
NSStringFromClass([gesture class]),
|
||
gesture.enabled ? @"是" : @"否",
|
||
gesture.delegate ? @"已设置" : @"未设置");
|
||
}
|
||
}
|
||
|
||
#pragma mark - Zone Calculation
|
||
|
||
- (CGRect)getCenterZone {
|
||
CGFloat containerWidth = self.bannerContainer.bounds.size.width;
|
||
CGFloat centerWidth = containerWidth * 2.0 / 3.0; // 2/3 容器宽度
|
||
CGFloat centerX = (containerWidth - centerWidth) / 2.0;
|
||
|
||
return CGRectMake(centerX, 0, centerWidth, self.bannerContainer.bounds.size.height);
|
||
}
|
||
|
||
- (CGRect)getLeftZone {
|
||
CGFloat containerWidth = self.bannerContainer.bounds.size.width;
|
||
CGFloat zoneWidth = containerWidth / 6.0; // 1/6 容器宽度
|
||
|
||
return CGRectMake(0, 0, zoneWidth, self.bannerContainer.bounds.size.height);
|
||
}
|
||
|
||
- (CGRect)getRightZone {
|
||
CGFloat containerWidth = self.bannerContainer.bounds.size.width;
|
||
CGFloat zoneWidth = containerWidth / 6.0; // 1/6 容器宽度
|
||
CGFloat rightX = containerWidth - zoneWidth;
|
||
|
||
return CGRectMake(rightX, 0, zoneWidth, self.bannerContainer.bounds.size.height);
|
||
}
|
||
|
||
- (BannerZone)getZoneForPoint:(CGPoint)point {
|
||
CGRect centerZone = [self getCenterZone];
|
||
CGRect leftZone = [self getLeftZone];
|
||
CGRect rightZone = [self getRightZone];
|
||
|
||
NSLog(@"🎯 区域计算 - 触摸点:(%.1f,%.1f)", point.x, point.y);
|
||
NSLog(@" - 中央区域: (%.1f,%.1f,%.1f,%.1f)", centerZone.origin.x, centerZone.origin.y, centerZone.size.width, centerZone.size.height);
|
||
NSLog(@" - 左侧区域: (%.1f,%.1f,%.1f,%.1f)", leftZone.origin.x, leftZone.origin.y, leftZone.size.width, leftZone.size.height);
|
||
NSLog(@" - 右侧区域: (%.1f,%.1f,%.1f,%.1f)", rightZone.origin.x, rightZone.origin.y, rightZone.size.width, rightZone.size.height);
|
||
|
||
if (CGRectContainsPoint(centerZone, point)) {
|
||
NSLog(@"🎯 触摸点在中央区域");
|
||
return BannerZoneCenter;
|
||
} else if (CGRectContainsPoint(leftZone, point)) {
|
||
NSLog(@"🎯 触摸点在左侧区域");
|
||
return BannerZoneLeft;
|
||
} else if (CGRectContainsPoint(rightZone, point)) {
|
||
NSLog(@"🎯 触摸点在右侧区域");
|
||
return BannerZoneRight;
|
||
}
|
||
|
||
NSLog(@"🎯 触摸点在无效区域");
|
||
return BannerZoneNone;
|
||
}
|
||
|
||
#pragma mark - Visual Debug (Test Environment)
|
||
|
||
- (void)addZoneDebugViews {
|
||
// 仅在测试环境添加
|
||
#ifdef DEBUG
|
||
NSLog(@"🎨 开始添加区域调试视图");
|
||
NSLog(@" - bannerContainer: %@ (frame: %.1f,%.1f,%.1f,%.1f)",
|
||
self.bannerContainer ? @"存在" : @"nil",
|
||
self.bannerContainer.frame.origin.x, self.bannerContainer.frame.origin.y,
|
||
self.bannerContainer.frame.size.width, self.bannerContainer.frame.size.height);
|
||
|
||
// 延迟添加,确保布局完成
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
// 中央区域 - 半透明蓝色
|
||
UIView *centerDebugView = [[UIView alloc] init];
|
||
centerDebugView.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.3];
|
||
centerDebugView.frame = [self getCenterZone];
|
||
centerDebugView.userInteractionEnabled = NO;
|
||
centerDebugView.tag = 999; // 设置debug视图tag
|
||
[self.bannerContainer addSubview:centerDebugView];
|
||
|
||
// 左侧区域 - 半透明红色
|
||
UIView *leftDebugView = [[UIView alloc] init];
|
||
leftDebugView.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.3];
|
||
leftDebugView.frame = [self getLeftZone];
|
||
leftDebugView.userInteractionEnabled = NO;
|
||
leftDebugView.tag = 999; // 设置debug视图tag
|
||
[self.bannerContainer addSubview:leftDebugView];
|
||
|
||
// 右侧区域 - 半透明绿色
|
||
UIView *rightDebugView = [[UIView alloc] init];
|
||
rightDebugView.backgroundColor = [[UIColor greenColor] colorWithAlphaComponent:0.3];
|
||
rightDebugView.frame = [self getRightZone];
|
||
rightDebugView.userInteractionEnabled = NO;
|
||
rightDebugView.tag = 999; // 设置debug视图tag
|
||
[self.bannerContainer addSubview:rightDebugView];
|
||
|
||
NSLog(@"🎨 区域调试视图已添加");
|
||
NSLog(@" - 中央区域: 蓝色 (%.1f, %.1f, %.1f, %.1f)",
|
||
centerDebugView.frame.origin.x, centerDebugView.frame.origin.y,
|
||
centerDebugView.frame.size.width, centerDebugView.frame.size.height);
|
||
NSLog(@" - 左侧区域: 红色 (%.1f, %.1f, %.1f, %.1f)",
|
||
leftDebugView.frame.origin.x, leftDebugView.frame.origin.y,
|
||
leftDebugView.frame.size.width, leftDebugView.frame.size.height);
|
||
NSLog(@" - 右侧区域: 绿色 (%.1f, %.1f, %.1f, %.1f)",
|
||
rightDebugView.frame.origin.x, rightDebugView.frame.origin.y,
|
||
rightDebugView.frame.size.width, rightDebugView.frame.size.height);
|
||
});
|
||
#endif
|
||
}
|
||
|
||
- (void)ensureDebugViewsExist {
|
||
#ifdef DEBUG
|
||
// 检查是否已经有debug视图
|
||
BOOL hasDebugViews = NO;
|
||
for (UIView *subview in self.bannerContainer.subviews) {
|
||
if (subview.tag == 999) {
|
||
hasDebugViews = YES;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!hasDebugViews) {
|
||
NSLog(@"🎨 重新添加debug视图");
|
||
[self addZoneDebugViews];
|
||
}
|
||
#endif
|
||
}
|
||
|
||
#pragma mark - UIGestureRecognizerDelegate
|
||
|
||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
|
||
NSLog(@"🎯 shouldReceiveTouch被调用 - 手势:%@ 触摸:%p", NSStringFromClass([gestureRecognizer class]), touch);
|
||
|
||
CGPoint touchPoint = [touch locationInView:self.bannerContainer];
|
||
BannerZone zone = [self getZoneForPoint:touchPoint];
|
||
|
||
// 检查触摸的目标视图
|
||
UIView *hitView = [self.bannerContainer hitTest:touchPoint withEvent:nil];
|
||
NSString *hitViewClass = hitView ? NSStringFromClass([hitView class]) : @"nil";
|
||
|
||
// 检查触摸事件是否被拦截
|
||
if (hitView && hitView != self.bannerContainer) {
|
||
NSLog(@"🎯 触摸被视图拦截: %@", hitViewClass);
|
||
// 检查拦截视图的用户交互设置
|
||
NSLog(@"🎯 拦截视图用户交互: %@", hitView.userInteractionEnabled ? @"启用" : @"禁用");
|
||
|
||
// 特别检查GameUniversalBannerView
|
||
if ([hitViewClass containsString:@"GameUniversalBannerView"]) {
|
||
NSLog(@"🎯 GameUniversalBannerView拦截了触摸事件");
|
||
}
|
||
}
|
||
|
||
NSString *gestureType = @"Unknown";
|
||
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
|
||
gestureType = @"Pan";
|
||
} else if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
|
||
gestureType = @"Tap";
|
||
}
|
||
|
||
NSString *zoneName = @"None";
|
||
switch (zone) {
|
||
case BannerZoneCenter: zoneName = @"Center"; break;
|
||
case BannerZoneLeft: zoneName = @"Left"; break;
|
||
case BannerZoneRight: zoneName = @"Right"; break;
|
||
case BannerZoneNone: zoneName = @"None"; break;
|
||
}
|
||
|
||
NSLog(@"🎯 Banner手势判断: %@手势 - 触摸点:(%.1f,%.1f) 区域:%@ hitView:%@",
|
||
gestureType, touchPoint.x, touchPoint.y, zoneName, hitViewClass);
|
||
|
||
// 检查是否在有效区域内
|
||
if (zone == BannerZoneNone) {
|
||
NSLog(@"🎯 ❌ %@手势在有效区域外被拒绝", gestureType);
|
||
return NO;
|
||
}
|
||
|
||
// 额外检查:确保触摸点确实在bannerContainer的边界内
|
||
if (!CGRectContainsPoint(self.bannerContainer.bounds, touchPoint)) {
|
||
NSLog(@"🎯 ❌ %@手势在bannerContainer边界外被拒绝 - 触摸点:(%.1f,%.1f) 容器边界:(%.1f,%.1f,%.1f,%.1f)",
|
||
gestureType, touchPoint.x, touchPoint.y,
|
||
self.bannerContainer.bounds.origin.x, self.bannerContainer.bounds.origin.y,
|
||
self.bannerContainer.bounds.size.width, self.bannerContainer.bounds.size.height);
|
||
return NO;
|
||
}
|
||
|
||
// 根据手势类型和区域进行判断
|
||
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
|
||
// Pan手势只在中央区域允许,且优先于按钮点击
|
||
if (zone == BannerZoneCenter) {
|
||
if ([hitView isKindOfClass:[UIButton class]]) {
|
||
NSLog(@"🎯 ✅ Pan手势在中央区域按钮上被允许(滑动优先)");
|
||
} else {
|
||
NSLog(@"🎯 ✅ Pan手势在中央区域被允许");
|
||
}
|
||
return YES;
|
||
} else {
|
||
NSLog(@"🎯 ❌ Pan手势在%@区域被拒绝", zoneName);
|
||
return NO;
|
||
}
|
||
}
|
||
|
||
if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
|
||
// Tap手势:在按钮区域拒绝,在其他区域允许
|
||
if ([hitView isKindOfClass:[UIButton class]]) {
|
||
NSLog(@"🎯 ❌ Tap手势在按钮区域被拒绝(保护按钮点击)");
|
||
return NO;
|
||
}
|
||
|
||
NSLog(@"🎯 ✅ Tap手势在%@区域被允许", zoneName);
|
||
return YES;
|
||
}
|
||
|
||
NSLog(@"🎯 ❌ 未知手势类型被拒绝");
|
||
return NO;
|
||
}
|
||
|
||
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
|
||
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
|
||
// 允许同时识别,通过 shouldReceiveTouch 精确控制
|
||
NSLog(@"🎯 手势同时识别: %@ 与 %@",
|
||
NSStringFromClass([gestureRecognizer class]),
|
||
NSStringFromClass([otherGestureRecognizer class]));
|
||
return YES;
|
||
}
|
||
|
||
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
|
||
NSString *gestureType = @"Unknown";
|
||
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
|
||
gestureType = @"Pan";
|
||
} else if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
|
||
gestureType = @"Tap";
|
||
}
|
||
|
||
NSLog(@"🎯 手势开始检查: %@手势 - ShouldBegin被调用", gestureType);
|
||
|
||
// 检查Banner容器状态
|
||
if (!self.bannerContainer.userInteractionEnabled) {
|
||
NSLog(@"🎯 ❌ Banner容器交互被禁用");
|
||
return NO;
|
||
}
|
||
|
||
// 检查是否有Banner显示
|
||
if (self.bannerContainer.subviews.count == 0) {
|
||
NSLog(@"🎯 ❌ 没有Banner子视图");
|
||
return NO;
|
||
}
|
||
|
||
// 检查Banner容器是否可见且有效
|
||
if (self.bannerContainer.hidden || self.bannerContainer.alpha <= 0.01) {
|
||
NSLog(@"🎯 ❌ Banner容器不可见");
|
||
return NO;
|
||
}
|
||
|
||
// 检查Banner容器是否有有效的frame
|
||
if (CGRectIsEmpty(self.bannerContainer.frame) || CGRectIsNull(self.bannerContainer.frame)) {
|
||
NSLog(@"🎯 ❌ Banner容器frame无效");
|
||
return NO;
|
||
}
|
||
|
||
NSLog(@"🎯 ✅ %@手势允许开始", gestureType);
|
||
return YES;
|
||
}
|
||
|
||
#pragma mark - Gesture Handlers
|
||
|
||
- (void)handleCenterPan:(UIPanGestureRecognizer *)gesture {
|
||
static NSInteger callCount = 0;
|
||
callCount++;
|
||
NSLog(@"🔥 中央区域Pan手势 - 第%ld次", (long)callCount);
|
||
NSLog(@"🔥 Pan手势被触发!手势状态: %ld", (long)gesture.state);
|
||
NSLog(@"🔥 Pan手势视图: %@", gesture.view);
|
||
|
||
// 检查是否有Banner显示
|
||
if (self.bannerContainer.subviews.count == 0) {
|
||
NSLog(@"🔥 ❌ 没有Banner显示,忽略手势");
|
||
return;
|
||
}
|
||
|
||
NSString *stateString = @"Unknown";
|
||
switch (gesture.state) {
|
||
case UIGestureRecognizerStatePossible: stateString = @"Possible"; break;
|
||
case UIGestureRecognizerStateBegan: stateString = @"Began"; break;
|
||
case UIGestureRecognizerStateChanged: stateString = @"Changed"; break;
|
||
case UIGestureRecognizerStateEnded: stateString = @"Ended"; break;
|
||
case UIGestureRecognizerStateCancelled: stateString = @"Cancelled"; break;
|
||
case UIGestureRecognizerStateFailed: stateString = @"Failed"; break;
|
||
}
|
||
|
||
CGPoint velocity = [gesture velocityInView:self.bannerContainer];
|
||
CGPoint translation = [gesture translationInView:self.bannerContainer];
|
||
|
||
NSLog(@"👆 中央区域滑动状态: %@ - 速度:(%.1f,%.1f) 距离:(%.1f,%.1f)",
|
||
stateString, velocity.x, velocity.y, translation.x, translation.y);
|
||
|
||
static const CGFloat kVelocityThreshold = 500.0;
|
||
static const CGFloat kDistanceThreshold = 100.0;
|
||
|
||
switch (gesture.state) {
|
||
case UIGestureRecognizerStateBegan:
|
||
NSLog(@"✅ 中央区域滑动: 开始识别 - RTL: %@", isMSRTL() ? @"是" : @"否");
|
||
break;
|
||
|
||
case UIGestureRecognizerStateChanged: {
|
||
BOOL isHorizontalSwipe = fabs(velocity.x) > fabs(velocity.y);
|
||
BOOL isCorrectDirection = isMSRTL() ? (velocity.x > 0) : (velocity.x < 0);
|
||
BOOL isEnoughVelocity = fabs(velocity.x) > kVelocityThreshold;
|
||
BOOL isEnoughDistance = fabs(translation.x) > kDistanceThreshold;
|
||
|
||
if (isHorizontalSwipe && isCorrectDirection &&
|
||
(isEnoughVelocity || isEnoughDistance)) {
|
||
NSLog(@"✅ 中央区域滑动: 满足移除条件 - 速度:%.1f 距离:%.1f", fabs(velocity.x), fabs(translation.x));
|
||
[self handleSwipeOutBanner];
|
||
gesture.state = UIGestureRecognizerStateEnded;
|
||
}
|
||
break;
|
||
}
|
||
|
||
case UIGestureRecognizerStateEnded:
|
||
case UIGestureRecognizerStateCancelled:
|
||
NSLog(@"👆 中央区域滑动: 结束");
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handleCenterTap:(UITapGestureRecognizer *)gesture {
|
||
CGPoint touchPoint = [gesture locationInView:self.bannerContainer];
|
||
NSLog(@"🎯 中央区域点击: 传递到Banner处理 - 触摸点:(%.1f,%.1f)", touchPoint.x, touchPoint.y);
|
||
|
||
// 检查是否有Banner显示
|
||
if (self.bannerContainer.subviews.count == 0) {
|
||
NSLog(@"🎯 ❌ 没有Banner显示,忽略点击");
|
||
return;
|
||
}
|
||
|
||
// 传递点击事件到Banner内部处理
|
||
[self forwardTapToBanner:touchPoint];
|
||
}
|
||
|
||
- (void)handleLeftTap:(UITapGestureRecognizer *)gesture {
|
||
CGPoint touchPoint = [gesture locationInView:self.bannerContainer];
|
||
if (touchPoint.x > KScreenWidth/2) {
|
||
NSLog(@"🎯 左侧区域点击: 不是左侧区域 - 触摸点:(%.1f,%.1f)", touchPoint.x, touchPoint.y);
|
||
return;
|
||
}
|
||
NSLog(@"🎯 左侧区域点击: 检查Banner处理能力 - 触摸点:(%.1f,%.1f)", touchPoint.x, touchPoint.y);
|
||
|
||
// 检查是否有Banner显示
|
||
if (self.bannerContainer.subviews.count == 0) {
|
||
NSLog(@"🎯 ❌ 没有Banner显示,忽略点击");
|
||
return;
|
||
}
|
||
|
||
// 先尝试让Banner处理,不能处理则透传
|
||
if (![self forwardTapToBanner:touchPoint]) {
|
||
NSLog(@"📱 左侧区域点击: Banner无法处理,透传到底部");
|
||
[self simulatePassthroughTap:touchPoint];
|
||
}
|
||
}
|
||
|
||
- (void)handleRightTap:(UITapGestureRecognizer *)gesture {
|
||
CGPoint touchPoint = [gesture locationInView:self.bannerContainer];
|
||
if (touchPoint.x < KScreenWidth/2) {
|
||
NSLog(@"🎯 右侧区域点击: 不是右侧区域 - 触摸点:(%.1f,%.1f)", touchPoint.x, touchPoint.y);
|
||
return;
|
||
}
|
||
NSLog(@"🎯 右侧区域点击: 检查Banner处理能力 - 触摸点:(%.1f,%.1f)", touchPoint.x, touchPoint.y);
|
||
|
||
// 检查是否有Banner显示
|
||
if (self.bannerContainer.subviews.count == 0) {
|
||
NSLog(@"🎯 ❌ 没有Banner显示,忽略点击");
|
||
return;
|
||
}
|
||
|
||
// 先尝试让Banner处理,不能处理则透传
|
||
if (![self forwardTapToBanner:touchPoint]) {
|
||
NSLog(@"📱 右侧区域点击: Banner无法处理,透传到底部");
|
||
[self simulatePassthroughTap:touchPoint];
|
||
}
|
||
}
|
||
|
||
#pragma mark - Event Forwarding
|
||
|
||
- (BOOL)forwardTapToBanner:(CGPoint)point {
|
||
// 查找Banner子视图
|
||
UIView *bannerView = nil;
|
||
for (UIView *subview in self.bannerContainer.subviews) {
|
||
if (CGRectContainsPoint(subview.frame, point)) {
|
||
bannerView = subview;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (bannerView) {
|
||
// 转换坐标到Banner视图
|
||
CGPoint bannerPoint = [bannerView convertPoint:point fromView:self.bannerContainer];
|
||
|
||
// 查找可点击的目标
|
||
UIView *targetView = [bannerView hitTest:bannerPoint withEvent:nil];
|
||
|
||
if ([targetView isKindOfClass:[UIButton class]]) {
|
||
UIButton *button = (UIButton *)targetView;
|
||
[button sendActionsForControlEvents:UIControlEventTouchUpInside];
|
||
NSLog(@"🎯 Banner处理点击: 触发按钮 %@", button.titleLabel.text ?: @"(无标题)");
|
||
return YES;
|
||
} else if (targetView && targetView != bannerView) {
|
||
NSLog(@"🎯 Banner处理点击: 找到目标视图 %@", NSStringFromClass([targetView class]));
|
||
return YES;
|
||
}
|
||
}
|
||
|
||
NSLog(@"🎯 Banner处理点击: 无法处理");
|
||
return NO;
|
||
}
|
||
|
||
- (void)simulatePassthroughTap:(CGPoint)point {
|
||
UIView *hostView = nil;
|
||
if ([self.hostDelegate respondsToSelector:@selector(getSuperView)]) {
|
||
hostView = [self.hostDelegate getSuperView];
|
||
}
|
||
|
||
if (!hostView) {
|
||
NSLog(@"📱 Banner穿透点击: 无法获取主视图");
|
||
return;
|
||
}
|
||
|
||
CGPoint convertedPoint = [hostView convertPoint:point fromView:self.bannerContainer];
|
||
|
||
XPRoomFunctionContainerView *functionView = nil;
|
||
for (UIView *subview in hostView.subviews) {
|
||
if ([NSStringFromClass([subview class]) containsString:@"XPRoomFunctionContainerView"]) {
|
||
functionView = (XPRoomFunctionContainerView *)subview;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (functionView) {
|
||
CGPoint functionPoint = [functionView convertPoint:convertedPoint fromView:hostView];
|
||
|
||
if (CGRectContainsPoint(functionView.bounds, functionPoint)) {
|
||
UIView *targetView = [functionView hitTest:functionPoint withEvent:nil];
|
||
|
||
if ([targetView isKindOfClass:[UIButton class]]) {
|
||
UIButton *button = (UIButton *)targetView;
|
||
[button sendActionsForControlEvents:UIControlEventTouchUpInside];
|
||
NSLog(@"📱 Banner穿透点击: 成功触发底部按钮 %@", button.titleLabel.text ?: @"(无标题)");
|
||
} else if ([NSStringFromClass([targetView class]) containsString:@"MSRoomOnLineView"] ||
|
||
[targetView.superview isKindOfClass:[MSRoomOnLineView class]]) {
|
||
// 直接调用XPRoomFunctionContainerView的onlineTapRecognizer方法
|
||
if ([functionView respondsToSelector:@selector(onlineTapRecognizer)]) {
|
||
[functionView performSelector:@selector(onlineTapRecognizer)];
|
||
NSLog(@"📱 Banner穿透点击: 成功触发MSRoomOnLineView的onlineTapRecognizer");
|
||
} else {
|
||
NSLog(@"📱 Banner穿透点击: 无法找到onlineTapRecognizer方法");
|
||
}
|
||
} else if ([NSStringFromClass([targetView class]) containsString:@"XPRoomRankEntranceView"] ||
|
||
[targetView.superview isKindOfClass:[XPRoomRankEntranceView class]]) {
|
||
// 触发贡献榜手势
|
||
if ([functionView respondsToSelector:@selector(contributionButtonAction:)]) {
|
||
[functionView performSelector:@selector(contributionButtonAction:) withObject:nil];
|
||
NSLog(@"📱 Banner穿透点击: 成功触发XPRoomRankEntranceView的contributionButtonAction");
|
||
}
|
||
} else if ([NSStringFromClass([targetView class]) containsString:@"XPRoomAnchorRankEnterView"] ||
|
||
[targetView.superview isKindOfClass:[XPRoomAnchorRankEnterView class]]) {
|
||
// 触发小时榜手势
|
||
if ([functionView respondsToSelector:@selector(onAnchorHourRankButtonAction:)]) {
|
||
[functionView performSelector:@selector(onAnchorHourRankButtonAction:) withObject:nil];
|
||
NSLog(@"📱 Banner穿透点击: 成功触发XPRoomAnchorRankEnterView的onAnchorHourRankButtonAction");
|
||
}
|
||
} else if ([NSStringFromClass([targetView class]) containsString:@"XPAnchorFansTeamEntranceView"]) {
|
||
// 触发粉丝团手势
|
||
if ([functionView respondsToSelector:@selector(tapFansTeamRecognizer)]) {
|
||
[functionView performSelector:@selector(tapFansTeamRecognizer)];
|
||
NSLog(@"📱 Banner穿透点击: 成功触发XPAnchorFansTeamEntranceView的tapFansTeamRecognizer");
|
||
}
|
||
} else if (targetView) {
|
||
NSLog(@"📱 Banner穿透点击: 找到目标视图但不是按钮: %@", NSStringFromClass([targetView class]));
|
||
} else {
|
||
NSLog(@"📱 Banner穿透点击: 在功能容器范围内但未找到可点击目标");
|
||
}
|
||
} else {
|
||
NSLog(@"📱 Banner穿透点击: 点击位置不在功能容器范围内");
|
||
}
|
||
} else {
|
||
NSLog(@"📱 Banner穿透点击: 未找到功能容器");
|
||
}
|
||
}
|
||
|
||
- (void)handleSwipeOutBanner {
|
||
NSLog(@"🚨 发送SwipeOutBanner通知 - 当前状态: isRoomBannerV2Displaying=%@", self.isRoomBannerV2Displaying ? @"YES" : @"NO");
|
||
|
||
// 防止重复处理
|
||
if (!self.isRoomBannerV2Displaying) {
|
||
NSLog(@"🚨 警告: 尝试关闭banner但状态显示没有正在显示的banner");
|
||
return;
|
||
}
|
||
|
||
// 立即设置状态为NO,防止重复处理
|
||
self.isRoomBannerV2Displaying = NO;
|
||
|
||
[[NSNotificationCenter defaultCenter] postNotificationName:@"SwipeOutBanner" object:nil];
|
||
|
||
// 延迟处理下一个banner,确保当前banner完全关闭
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
[self processNextRoomEffectAttachment];
|
||
});
|
||
}
|
||
|
||
#pragma mark - Banner Interaction Management
|
||
|
||
- (void)configureBannerInteraction:(UIView *)bannerView {
|
||
NSString *bannerClassName = NSStringFromClass([bannerView class]);
|
||
NSLog(@"🔧 配置Banner交互: %@", bannerClassName);
|
||
|
||
// 确保Banner可以接收用户交互
|
||
bannerView.userInteractionEnabled = YES;
|
||
|
||
// 根据Banner类型进行特殊处理
|
||
if ([bannerClassName containsString:@"LuckyGiftWinningBannerView"]) {
|
||
NSLog(@"🔧 LuckyGiftWinningBannerView: 处理按钮冲突");
|
||
// 查找覆盖按钮并记录
|
||
for (UIView *subview in bannerView.subviews) {
|
||
if ([subview isKindOfClass:[UIButton class]]) {
|
||
NSLog(@"🔧 找到LuckyGiftWinningBannerView覆盖按钮");
|
||
}
|
||
}
|
||
|
||
// 确保Pan手势优先于按钮点击
|
||
for (UIGestureRecognizer *gesture in self.bannerContainer.gestureRecognizers) {
|
||
if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) {
|
||
gesture.cancelsTouchesInView = YES;
|
||
NSLog(@"🔧 设置Pan手势cancelsTouchesInView = YES (LuckyGiftWinningBannerView)");
|
||
}
|
||
}
|
||
} else if ([bannerClassName containsString:@"GameUniversalBannerView"]) {
|
||
NSLog(@"🔧 GameUniversalBannerView: 确保交互启用");
|
||
// 确保所有子视图都可以交互
|
||
[self enableInteractionForView:bannerView];
|
||
|
||
// 检查GameUniversalBannerView是否有自己的手势识别器
|
||
NSLog(@"🔧 GameUniversalBannerView手势识别器数量: %ld", (long)bannerView.gestureRecognizers.count);
|
||
for (UIGestureRecognizer *gesture in bannerView.gestureRecognizers) {
|
||
NSLog(@"🔧 GameUniversalBannerView手势: %@ (enabled: %@)",
|
||
NSStringFromClass([gesture class]),
|
||
gesture.enabled ? @"是" : @"否");
|
||
}
|
||
} else if ([bannerClassName containsString:@"RoomHighValueGiftBannerAnimation"]) {
|
||
NSLog(@"🔧 RoomHighValueGiftBannerAnimation: 确保交互启用");
|
||
// 确保所有子视图都可以交互
|
||
[self enableInteractionForView:bannerView];
|
||
|
||
// 检查RoomHighValueGiftBannerAnimation是否有自己的手势识别器
|
||
NSLog(@"🔧 RoomHighValueGiftBannerAnimation手势识别器数量: %ld", (long)bannerView.gestureRecognizers.count);
|
||
for (UIGestureRecognizer *gesture in bannerView.gestureRecognizers) {
|
||
NSLog(@"🔧 RoomHighValueGiftBannerAnimation手势: %@ (enabled: %@)",
|
||
NSStringFromClass([gesture class]),
|
||
gesture.enabled ? @"是" : @"否");
|
||
}
|
||
|
||
// 确保Pan手势优先于按钮点击
|
||
for (UIGestureRecognizer *gesture in self.bannerContainer.gestureRecognizers) {
|
||
if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) {
|
||
gesture.cancelsTouchesInView = YES;
|
||
NSLog(@"🔧 设置Pan手势cancelsTouchesInView = YES (RoomHighValueGiftBannerAnimation)");
|
||
}
|
||
}
|
||
} else if ([bannerClassName containsString:@"BravoGiftBannerView"]) {
|
||
NSLog(@"🔧 BravoGiftBannerView: 确保交互启用");
|
||
// 确保所有子视图都可以交互
|
||
[self enableInteractionForView:bannerView];
|
||
|
||
// 检查BravoGiftBannerView是否有自己的手势识别器
|
||
NSLog(@"🔧 BravoGiftBannerView手势识别器数量: %ld", (long)bannerView.gestureRecognizers.count);
|
||
for (UIGestureRecognizer *gesture in bannerView.gestureRecognizers) {
|
||
NSLog(@"🔧 BravoGiftBannerView手势: %@ (enabled: %@)",
|
||
NSStringFromClass([gesture class]),
|
||
gesture.enabled ? @"是" : @"否");
|
||
}
|
||
|
||
// 确保Pan手势优先于按钮点击
|
||
for (UIGestureRecognizer *gesture in self.bannerContainer.gestureRecognizers) {
|
||
if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) {
|
||
gesture.cancelsTouchesInView = YES;
|
||
NSLog(@"🔧 设置Pan手势cancelsTouchesInView = YES (BravoGiftBannerView)");
|
||
}
|
||
}
|
||
} else if ([bannerClassName containsString:@"LuckyPackageBannerView"]) {
|
||
NSLog(@"🔧 LuckyPackageBannerView: 确保交互启用");
|
||
// 确保所有子视图都可以交互
|
||
[self enableInteractionForView:bannerView];
|
||
|
||
// 检查LuckyPackageBannerView是否有自己的手势识别器
|
||
NSLog(@"🔧 LuckyPackageBannerView手势识别器数量: %ld", (long)bannerView.gestureRecognizers.count);
|
||
for (UIGestureRecognizer *gesture in bannerView.gestureRecognizers) {
|
||
NSLog(@"🔧 LuckyPackageBannerView手势: %@ (enabled: %@)",
|
||
NSStringFromClass([gesture class]),
|
||
gesture.enabled ? @"是" : @"否");
|
||
}
|
||
|
||
// 确保Pan手势优先于按钮点击
|
||
for (UIGestureRecognizer *gesture in self.bannerContainer.gestureRecognizers) {
|
||
if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) {
|
||
gesture.cancelsTouchesInView = YES;
|
||
NSLog(@"🔧 设置Pan手势cancelsTouchesInView = YES (LuckyPackageBannerView)");
|
||
}
|
||
}
|
||
} else if ([bannerClassName containsString:@"CPGiftBanner"]) {
|
||
NSLog(@"🔧 CPGiftBanner: 确保交互启用");
|
||
// 确保所有子视图都可以交互
|
||
[self enableInteractionForView:bannerView];
|
||
|
||
// 检查CPGiftBanner是否有自己的手势识别器
|
||
NSLog(@"🔧 CPGiftBanner手势识别器数量: %ld", (long)bannerView.gestureRecognizers.count);
|
||
for (UIGestureRecognizer *gesture in bannerView.gestureRecognizers) {
|
||
NSLog(@"🔧 CPGiftBanner手势: %@ (enabled: %@)",
|
||
NSStringFromClass([gesture class]),
|
||
gesture.enabled ? @"是" : @"否");
|
||
}
|
||
|
||
// 确保Pan手势优先于按钮点击
|
||
for (UIGestureRecognizer *gesture in self.bannerContainer.gestureRecognizers) {
|
||
if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) {
|
||
gesture.cancelsTouchesInView = YES;
|
||
NSLog(@"🔧 设置Pan手势cancelsTouchesInView = YES (CPGiftBanner)");
|
||
}
|
||
}
|
||
} else {
|
||
// 默认处理:确保所有banner都能响应手势
|
||
NSLog(@"🔧 默认Banner处理: %@", bannerClassName);
|
||
[self enableInteractionForView:bannerView];
|
||
|
||
// 确保Pan手势优先于按钮点击
|
||
for (UIGestureRecognizer *gesture in self.bannerContainer.gestureRecognizers) {
|
||
if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) {
|
||
gesture.cancelsTouchesInView = YES;
|
||
NSLog(@"🔧 设置Pan手势cancelsTouchesInView = YES (默认处理)");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
- (void)enableInteractionForView:(UIView *)view {
|
||
view.userInteractionEnabled = YES;
|
||
|
||
for (UIView *subview in view.subviews) {
|
||
subview.userInteractionEnabled = YES;
|
||
[self enableInteractionForView:subview];
|
||
}
|
||
}
|
||
|
||
#pragma mark - Legacy Support
|
||
|
||
- (void)setupCar {
|
||
_carEffectQueue = [NSMutableArray array];
|
||
}
|
||
|
||
- (void)setupOldMethods {
|
||
_broadCastHieght = 190 - 150 + kGetScaleWidth(69);
|
||
_sailingQueue = @[].mutableCopy;
|
||
_datingEffectQueue = @[].mutableCopy;
|
||
_graffitiGiftQueue = @[].mutableCopy;
|
||
_acrossRoomPKQueue = @[].mutableCopy;
|
||
_animationListB = @[].mutableCopy;
|
||
}
|
||
|
||
#pragma mark - Method: Enter Roooooom
|
||
- (void)enterRoom:(NIMMessage *)message content:(NIMChatroomNotificationContent *)content {
|
||
NIMMessageChatroomExtension *messageExt = (NIMMessageChatroomExtension *)message.messageExt;
|
||
NSDictionary * dic = [(NSDictionary *)messageExt.roomExt.toJSONObject objectForKey:message.from];
|
||
XPMessageRemoteExtModel *extModel = [XPMessageRemoteExtModel modelWithJSON:dic];
|
||
|
||
if (extModel.platformRole == 1) {
|
||
return;
|
||
}
|
||
|
||
if (extModel.enterHide) {
|
||
//隐身进房
|
||
if ([message.from isEqualToString:[AccountInfoStorage instance].getUid]) {
|
||
[self createEnterHideAnimation];
|
||
}
|
||
} else {
|
||
[self userEnterRoom:content ext:extModel];
|
||
}
|
||
}
|
||
|
||
///自己的隐身进房提示
|
||
- (void)createEnterHideAnimation {
|
||
NSDictionary * dic= @{@"title":@"隐身进房",
|
||
@"isMe":@"",
|
||
@"experLevelSeq":@"",
|
||
@"effectPath" : @""};
|
||
[self.enterRoomAnimationQueue addObject:dic];
|
||
[self tryDequeueAnimation];
|
||
}
|
||
|
||
|
||
- (void)userEnterRoom:(NIMChatroomNotificationContent *)content ext:(XPMessageRemoteExtModel *)extModel {
|
||
NSString *userName = [self _resolveUserNameFromContent:content extModel:extModel];
|
||
NSString *title = [NSString stringWithFormat:YMLocalizedString(@"XPRoomAnimationView0"), userName];
|
||
|
||
NSDictionary * dic= @{@"title":title,
|
||
@"experLevelSeq":[NSString stringWithFormat:@"%ld", extModel.experLevelSeq],
|
||
@"effectPath" : extModel.enterRoomEffects.length ? extModel.enterRoomEffects : @""};
|
||
[self.enterRoomAnimationQueue addObject:dic];
|
||
[self tryDequeueAnimation];
|
||
}
|
||
|
||
- (void)tryDequeueAnimation {
|
||
// 如果当前正有动画在播放,或者队列里啥都没有,直接return
|
||
if (self.isEnterRoomAnimating || self.enterRoomAnimationQueue.count == 0) {
|
||
return;
|
||
}
|
||
self.isEnterRoomAnimating = YES;
|
||
|
||
// 取出队列头部的动画信息并移除
|
||
NSDictionary *dic = [self.enterRoomAnimationQueue firstObject];
|
||
if (self.enterRoomAnimationQueue.count > 0) {
|
||
[self.enterRoomAnimationQueue xpSafeRemoveObjectAtIndex:0];
|
||
}
|
||
|
||
NSString *title = [dic objectForKey:@"title"];
|
||
if ([title isEqualToString:@"隐身进房"]) {
|
||
[self playHideEnterRoomAnimation];
|
||
} else {
|
||
// 开始执行动画
|
||
[self playUserEnterRoomAnimation:[dic objectForKey:@"title"]
|
||
experLevelSeq:[dic objectForKey:@"experLevelSeq"]
|
||
effectPath:[dic objectForKey:@"effectPath"]
|
||
isCPEnter:[[dic objectForKey:@"isCP"] boolValue]];
|
||
}
|
||
}
|
||
|
||
- (void)playHideEnterRoomAnimation {
|
||
XPRoomEnterHideTipView *enterHideTipView = [[XPRoomEnterHideTipView alloc] initWithFrame:CGRectMake(KScreenWidth,
|
||
(KScreenHeight - 48) * 0.5,
|
||
KScreenWidth,
|
||
48)];
|
||
[self.bottomContainer addSubview:enterHideTipView];
|
||
|
||
@kWeakify(self);
|
||
[self enterRoomAnimationFor:enterHideTipView
|
||
startFrom:enterHideTipView.center
|
||
startTo:CGPointMake(enterHideTipView.frame.size.width / 2, enterHideTipView.center.y)
|
||
endFrom:CGPointMake(0, enterHideTipView.center.y)
|
||
endTo:CGPointMake(-KScreenWidth / 2, enterHideTipView.center.y)
|
||
duration:CACurrentMediaTime() + kTipViewStayDuration
|
||
completion:^(BOOL finished) {
|
||
@kStrongify(self);
|
||
[self endAnimationEnterEffect];
|
||
}];
|
||
}
|
||
|
||
- (void)playUserEnterRoomAnimation:(NSString *)title
|
||
experLevelSeq:(NSString *)experLevelSeq
|
||
effectPath:(NSString *)effectPath
|
||
isCPEnter:(BOOL)isCP {
|
||
|
||
NSDictionary *attributes = @{
|
||
NSFontAttributeName:kFontRegular(26),
|
||
NSForegroundColorAttributeName:[UIColor whiteColor]
|
||
};
|
||
NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:title
|
||
attributes:attributes];
|
||
[attributeString setYy_alignment:NSTextAlignmentLeft];
|
||
|
||
BOOL hasEffectPath = ![NSString isEmpty:effectPath];
|
||
[self addEnterEffectView: hasEffectPath];
|
||
|
||
if (isCP) {
|
||
[self playCPPPPEnterRoomSvgaWith:attributeString];
|
||
} else if (hasEffectPath) {
|
||
[self playEnterRoomSvga:effectPath
|
||
content:attributeString
|
||
needMoveAnimation:YES];
|
||
} else {
|
||
[self playEnterRoomSvgaWith:experLevelSeq
|
||
content:attributeString];
|
||
}
|
||
}
|
||
|
||
- (void)addEnterEffectView:(BOOL)hasEffectPath {
|
||
if (self.enterEffectView.superview == nil) {
|
||
[self.bottomContainer addSubview:self.enterEffectView];
|
||
}
|
||
|
||
self.enterEffectView.loops = hasEffectPath ? 0 : 1;
|
||
|
||
self.enterEffectView.frame = CGRectMake(hasEffectPath ? KScreenWidth : 0,
|
||
340 + kSafeAreaTopHeight,
|
||
KScreenWidth,
|
||
hasEffectPath ? 75 : 50);
|
||
}
|
||
|
||
- (void)playEnterRoomSvga:(NSString *)path
|
||
content:(NSAttributedString *)content
|
||
needMoveAnimation:(BOOL)isNeed {
|
||
@kWeakify(self);
|
||
SVGAParser *parser = [[SVGAParser alloc] init];
|
||
[parser parseWithURL:[NSURL URLWithString:path]
|
||
completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
|
||
@kStrongify(self);
|
||
self.enterEffectView.alpha = 1;
|
||
self.enterEffectView.hidden = NO;
|
||
self.enterEffectView.videoItem = videoItem;
|
||
[self.enterEffectView setAttributedText:content forKey:@"room_text"];
|
||
[self.enterEffectView startAnimation];
|
||
if (isNeed) {
|
||
[self popAnimationEnterEffect];
|
||
}
|
||
} failureBlock:^(NSError * _Nullable error) {
|
||
@kStrongify(self);
|
||
[self endAnimationEnterEffect];
|
||
}];
|
||
}
|
||
|
||
- (void)playEnterRoomSvgaWith:(NSString *)seq
|
||
content:(NSAttributedString *)content {
|
||
NSInteger seqNum = [NSString isEmpty:seq] ? 0 : [seq integerValue];
|
||
NSString *path = [self _mapExperLevelSeqToLocalKey:seqNum];
|
||
if ([NSString isEmpty:path]) {
|
||
[self endAnimationEnterEffect];
|
||
return;
|
||
}
|
||
|
||
NSString *targetPath = [NSString stringWithFormat:@"%@/%@.svga", @"https://image.molistar.xyz", path];
|
||
[self playEnterRoomSvga:targetPath content:content needMoveAnimation:NO];
|
||
}
|
||
|
||
- (void)playCPPPPEnterRoomSvgaWith:(NSAttributedString *)content {
|
||
if ([NSString isEmpty:content.string]) {
|
||
[self endAnimationEnterEffect];
|
||
return;
|
||
}
|
||
NSString *path = @"CP进场";
|
||
@kWeakify(self);
|
||
SVGAParser *parser = [[SVGAParser alloc] init];
|
||
[parser parseWithNamed:path inBundle:[NSBundle mainBundle] completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) {
|
||
@kStrongify(self);
|
||
self.enterEffectView.loops = 0;
|
||
self.enterEffectView.alpha = 1;
|
||
self.enterEffectView.hidden = NO;
|
||
self.enterEffectView.videoItem = videoItem;
|
||
[self.enterEffectView setAttributedText:content forKey:@"room_text"];
|
||
[self.enterEffectView startAnimation];
|
||
[self popAnimationEnterEffect];
|
||
} failureBlock:^(NSError * _Nonnull error) {
|
||
@kStrongify(self);
|
||
[self endAnimationEnterEffect];
|
||
}];
|
||
}
|
||
|
||
- (void)popAnimationEnterEffect {
|
||
@kWeakify(self);
|
||
[self enterRoomAnimationFor:self.enterEffectView
|
||
startFrom:self.enterEffectView.center
|
||
startTo:CGPointMake(self.enterEffectView.frame.size.width / 2, self.enterEffectView.center.y)
|
||
endFrom:CGPointMake(0, self.enterEffectView.center.y)
|
||
endTo:CGPointMake(-KScreenWidth / 2, self.enterEffectView.center.y)
|
||
duration:CACurrentMediaTime() + kTipViewStayDuration
|
||
completion:^(BOOL finished) {
|
||
@kStrongify(self);
|
||
[self endAnimationEnterEffect];
|
||
}];
|
||
}
|
||
|
||
- (void)endAnimationEnterEffect {
|
||
self.isEnterRoomAnimating = NO;
|
||
[self.enterEffectView stopAnimation];
|
||
self.enterEffectView.hidden = YES;
|
||
[self.enterEffectView removeFromSuperview];
|
||
[self tryDequeueAnimation];
|
||
}
|
||
|
||
#pragma mark - Method: Banner
|
||
- (void)inserBannerModelToQueue:(AttachmentModel *)obj {
|
||
// 参数验证
|
||
if (!obj || ![obj isKindOfClass:[AttachmentModel class]]) {
|
||
NSLog(@"⚠️ 警告: inserBannerModelToQueue 接收到无效参数: %@", obj);
|
||
return;
|
||
}
|
||
|
||
#ifdef DEBUG
|
||
// DEBUG环境:复制banner数据用于测试
|
||
BOOL enableBannerCopy = YES; // 设置为NO可以禁用复制功能
|
||
NSInteger copyCount = 10; // 可以调整这个数字来改变复制数量
|
||
|
||
if (enableBannerCopy) {
|
||
NSLog(@"🧪 DEBUG环境:收到banner数据,复制%ld份用于测试", (long)copyCount);
|
||
NSLog(@"🧪 原始banner类型: %@", NSStringFromClass([obj class]));
|
||
|
||
// 添加原始数据
|
||
[self.roomBannertModelsQueueV2 addObject:obj];
|
||
|
||
// 复制指定份数
|
||
for (int i = 1; i < copyCount; i++) {
|
||
AttachmentModel *copiedObj = [[AttachmentModel alloc] init];
|
||
|
||
// 安全复制data
|
||
if ([obj.data respondsToSelector:@selector(mutableCopy)]) {
|
||
copiedObj.data = [obj.data mutableCopy];
|
||
} else if ([obj.data respondsToSelector:@selector(copy)]) {
|
||
copiedObj.data = [obj.data copy];
|
||
} else {
|
||
copiedObj.data = obj.data; // 直接引用,注意这可能不是深拷贝
|
||
}
|
||
|
||
copiedObj.first = obj.first;
|
||
copiedObj.second = obj.second;
|
||
copiedObj.isBroadcast = obj.isBroadcast;
|
||
copiedObj.seq = obj.seq;
|
||
|
||
NSLog(@"🧪 复制第%d份banner数据", i + 1);
|
||
[self.roomBannertModelsQueueV2 addObject:copiedObj];
|
||
}
|
||
|
||
NSLog(@"🧪 队列中banner总数: %ld", (long)self.roomBannertModelsQueueV2.count);
|
||
|
||
// 显示队列中banner类型的分布
|
||
NSMutableDictionary *typeCount = [NSMutableDictionary dictionary];
|
||
for (AttachmentModel *banner in self.roomBannertModelsQueueV2) {
|
||
NSString *typeKey = [NSString stringWithFormat:@"%d", banner.second];
|
||
NSNumber *count = typeCount[typeKey];
|
||
typeCount[typeKey] = @(count.integerValue + 1);
|
||
}
|
||
|
||
NSLog(@"🧪 队列中banner类型分布:");
|
||
for (NSString *typeKey in typeCount.allKeys) {
|
||
NSLog(@" - 类型%@: %@个", typeKey, typeCount[typeKey]);
|
||
}
|
||
} else {
|
||
// 禁用复制功能,正常添加
|
||
NSLog(@"🧪 DEBUG环境:复制功能已禁用,正常添加banner");
|
||
[self.roomBannertModelsQueueV2 addObject:obj];
|
||
}
|
||
#else
|
||
// 生产环境:正常添加
|
||
[self.roomBannertModelsQueueV2 addObject:obj];
|
||
#endif
|
||
|
||
if (!self.isRoomBannerV2Displaying) {
|
||
[self processNextRoomEffectAttachment];
|
||
}
|
||
}
|
||
|
||
|
||
- (void)sortBannerQueue {
|
||
RoomInfoModel *roomInfo = self.hostDelegate.getRoomInfo;
|
||
NSString *currentRoomUid = @(roomInfo.uid).stringValue;
|
||
NSString *currentUid = [AccountInfoStorage instance].getUid;
|
||
[self.roomBannertModelsQueueV2 sortUsingComparator:^NSComparisonResult(AttachmentModel * _Nonnull obj1, AttachmentModel * _Nonnull obj2) {
|
||
|
||
// 检查 obj1 的属性
|
||
NSArray *obj1UidList = [obj1.data valueForKey:@"uidList"];
|
||
NSNumber *obj1RoomUid = [obj1.data valueForKey:@"roomUid"];
|
||
BOOL obj1IsCurrentUser = obj1UidList && [obj1UidList containsObject:currentUid];
|
||
BOOL obj1IsCurrentRoom = obj1RoomUid && [obj1RoomUid.stringValue isEqualToString:currentRoomUid];
|
||
|
||
// 检查 obj2 的属性
|
||
NSArray *obj2UidList = [obj2.data valueForKey:@"uidList"];
|
||
NSNumber *obj2RoomUid = [obj2.data valueForKey:@"roomUid"];
|
||
BOOL obj2IsCurrentUser = obj2UidList && [obj2UidList containsObject:currentUid];
|
||
BOOL obj2IsCurrentRoom = obj2RoomUid && [obj2RoomUid.stringValue isEqualToString:currentRoomUid];
|
||
|
||
if (obj1IsCurrentUser && !obj2IsCurrentUser) {
|
||
return NSOrderedAscending;
|
||
} else if (!obj1IsCurrentUser && obj2IsCurrentUser) {
|
||
return NSOrderedDescending;
|
||
} else if (obj1IsCurrentRoom && !obj2IsCurrentRoom) {
|
||
return NSOrderedAscending;
|
||
} else if (!obj1IsCurrentRoom && obj2IsCurrentRoom) {
|
||
return NSOrderedDescending;
|
||
} else {
|
||
return NSOrderedSame;
|
||
}
|
||
}];
|
||
}
|
||
|
||
- (void)processNextRoomEffectAttachment {
|
||
NSLog(@"🔄 processNextRoomEffectAttachment 被调用 - 当前状态: isRoomBannerV2Displaying=%@, 队列数量: %ld",
|
||
self.isRoomBannerV2Displaying ? @"YES" : @"NO", (long)self.roomBannertModelsQueueV2.count);
|
||
|
||
// 检查队列是否有元素
|
||
if (self.roomBannertModelsQueueV2.count == 0) {
|
||
// 如果队列为空,停止处理
|
||
self.isRoomBannerV2Displaying = NO;
|
||
NSLog(@"🔄 队列为空,停止处理");
|
||
return;
|
||
}
|
||
if (self.isRoomBannerV2Displaying) {
|
||
NSLog(@"🔄 已有banner正在显示,跳过处理");
|
||
return;
|
||
}
|
||
|
||
[self sortBannerQueue];
|
||
|
||
// 从队列中取出第一个元素并移出队列
|
||
AttachmentModel *nextAttachment = [self.roomBannertModelsQueueV2 firstObject];
|
||
if (self.roomBannertModelsQueueV2.count > 0) {
|
||
[self.roomBannertModelsQueueV2 xpSafeRemoveObjectAtIndex:0];
|
||
}
|
||
|
||
// 设置为正在显示的状态
|
||
self.isRoomBannerV2Displaying = YES;
|
||
NSLog(@"🔄 设置状态为正在显示: %@", NSStringFromClass([nextAttachment class]));
|
||
|
||
// 清理之前的banner,防止多个banner同时显示(保留debug视图)
|
||
NSMutableArray *viewsToRemove = [NSMutableArray array];
|
||
for (UIView *subview in self.bannerContainer.subviews) {
|
||
// 保留debug视图(tag为999的视图)
|
||
if (subview.tag == 999) {
|
||
NSLog(@"🔄 保留debug视图: %@", NSStringFromClass([subview class]));
|
||
} else {
|
||
// 其他视图都是banner,需要移除
|
||
[viewsToRemove addObject:subview];
|
||
NSLog(@"🔄 标记移除banner: %@", NSStringFromClass([subview class]));
|
||
}
|
||
}
|
||
|
||
for (UIView *view in viewsToRemove) {
|
||
[view removeFromSuperview];
|
||
}
|
||
|
||
NSLog(@"🔄 清理了 %ld 个banner视图,保留debug视图", (long)viewsToRemove.count);
|
||
|
||
// 确保debug视图存在
|
||
[self ensureDebugViewsExist];
|
||
|
||
switch (nextAttachment.second) {
|
||
case Custom_Message_Sub_General_Floating_Screen_One_Room:
|
||
case Custom_Message_Sub_General_Floating_Screen_All_Room:
|
||
// 通用飘屏
|
||
[self playGameBanner:nextAttachment];
|
||
break;
|
||
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;
|
||
case Custom_Message_Sub_Gift_ChannelNotify:
|
||
[self playRoomGiftBanner:nextAttachment];
|
||
break;
|
||
case Custom_Message_Sub_LuckyPackage:
|
||
[self playLuckyPackageBanner:nextAttachment];
|
||
break;
|
||
case Custom_Message_Sub_Super_Gift_Banner:
|
||
[self playBroveBanner:nextAttachment];
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)playBroveBanner:(AttachmentModel *)obj {
|
||
if (!obj.data) {
|
||
self.isRoomBannerV2Displaying = NO;
|
||
[self processNextRoomEffectAttachment];
|
||
return;
|
||
}
|
||
self.isRoomBannerV2Displaying = YES;
|
||
@kWeakify(self);
|
||
RoomInfoModel *roomInfo = self.hostDelegate.getRoomInfo;
|
||
[BravoGiftBannerView display:self.bannerContainer
|
||
inRoomUid:roomInfo.uid
|
||
with:obj
|
||
complete:^{
|
||
@kStrongify(self);
|
||
NSLog(@"🔄 BravoGiftBannerView complete 回调被调用");
|
||
self.isRoomBannerV2Displaying = NO;
|
||
[self processNextRoomEffectAttachment];
|
||
} exitCurrentRoom:^{
|
||
@kStrongify(self);
|
||
[self.hostDelegate exitRoom];
|
||
}];
|
||
|
||
// 延迟配置Banner交互,确保Banner已添加到视图层级
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
for (UIView *subview in self.bannerContainer.subviews) {
|
||
if ([NSStringFromClass([subview class]) containsString:@"BravoGiftBannerView"]) {
|
||
[self configureBannerInteraction:subview];
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 确保debug视图存在
|
||
[self ensureDebugViewsExist];
|
||
});
|
||
}
|
||
|
||
- (void)playLuckyPackageBanner:(AttachmentModel *)obj {
|
||
if (!obj.data) {
|
||
self.isRoomBannerV2Displaying = NO;
|
||
[self processNextRoomEffectAttachment];
|
||
return;
|
||
}
|
||
self.isRoomBannerV2Displaying = YES;
|
||
@kWeakify(self);
|
||
RoomInfoModel *roomInfo = self.hostDelegate.getRoomInfo;
|
||
[LuckyPackageBannerView display:self.bannerContainer
|
||
inRoomUid:roomInfo.uid
|
||
with:obj
|
||
complete:^{
|
||
@kStrongify(self);
|
||
NSLog(@"🔄 LuckyPackageBannerView complete 回调被调用");
|
||
self.isRoomBannerV2Displaying = NO;
|
||
[self processNextRoomEffectAttachment];
|
||
} exitCurrentRoom:^{
|
||
@kStrongify(self);
|
||
[self.hostDelegate exitRoom];
|
||
}];
|
||
|
||
// 延迟配置Banner交互,确保Banner已添加到视图层级
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
for (UIView *subview in self.bannerContainer.subviews) {
|
||
if ([NSStringFromClass([subview class]) containsString:@"LuckyPackageBannerView"]) {
|
||
[self configureBannerInteraction:subview];
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 确保debug视图存在
|
||
[self ensureDebugViewsExist];
|
||
});
|
||
}
|
||
|
||
- (void)receiveRoomGiftBanner:(AttachmentModel *)obj {
|
||
[self inserBannerModelToQueue:obj];
|
||
}
|
||
|
||
- (void)playRoomGiftBanner:(AttachmentModel *)obj {
|
||
if (!obj.data) {
|
||
self.isRoomBannerV2Displaying = NO;
|
||
[self processNextRoomEffectAttachment];
|
||
return;
|
||
}
|
||
self.isRoomBannerV2Displaying = YES;
|
||
@kWeakify(self);
|
||
[RoomHighValueGiftBannerAnimation display:self.bannerContainer
|
||
with:obj
|
||
complete:^{
|
||
@kStrongify(self);
|
||
NSLog(@"🔄 RoomHighValueGiftBannerAnimation complete 回调被调用");
|
||
self.isRoomBannerV2Displaying = NO;
|
||
[self processNextRoomEffectAttachment];
|
||
}];
|
||
|
||
// 延迟配置Banner交互,确保Banner已添加到视图层级
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
for (UIView *subview in self.bannerContainer.subviews) {
|
||
if ([NSStringFromClass([subview class]) containsString:@"RoomHighValueGiftBannerAnimation"]) {
|
||
[self configureBannerInteraction:subview];
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 确保debug视图存在
|
||
[self ensureDebugViewsExist];
|
||
});
|
||
}
|
||
|
||
- (void)receiveCPEvent:(AttachmentModel *)attachment {
|
||
[self inserBannerModelToQueue:attachment];
|
||
}
|
||
|
||
- (void)playCPBinding:(AttachmentModel *)attachment {
|
||
@kWeakify(self);
|
||
[CPBindingAnimation display:self.topContainer
|
||
with:attachment
|
||
complete:^{
|
||
@kStrongify(self);
|
||
self.isRoomBannerV2Displaying = NO;
|
||
[self processNextRoomEffectAttachment];
|
||
}];
|
||
}
|
||
|
||
- (void)playCPGiftBanner:(AttachmentModel *)attachMent {
|
||
@kWeakify(self);
|
||
[CPGiftBanner display:self.bannerContainer
|
||
with:attachMent
|
||
complete:^{
|
||
@kStrongify(self);
|
||
NSLog(@"🔄 CPGiftBanner complete 回调被调用");
|
||
self.isRoomBannerV2Displaying = NO;
|
||
[self processNextRoomEffectAttachment];
|
||
}];
|
||
|
||
// 延迟配置Banner交互,确保Banner已添加到视图层级
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
for (UIView *subview in self.bannerContainer.subviews) {
|
||
if ([NSStringFromClass([subview class]) containsString:@"CPGiftBanner"]) {
|
||
[self configureBannerInteraction:subview];
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 确保debug视图存在
|
||
[self ensureDebugViewsExist];
|
||
});
|
||
}
|
||
|
||
- (void)playCPLevelUp:(AttachmentModel *)attachMent {
|
||
@kWeakify(self);
|
||
[CPLevelUpAnimation display:self.topContainer
|
||
with:attachMent
|
||
complete:^{
|
||
@kStrongify(self);
|
||
self.isRoomBannerV2Displaying = NO;
|
||
[self processNextRoomEffectAttachment];
|
||
}];
|
||
}
|
||
|
||
- (void)receiveLuckGiftWinning:(AttachmentModel *)attachment {
|
||
RoomInfoModel *roomInfo = self.hostDelegate.getRoomInfo;
|
||
[LuckyGiftWinningFlagView display:self.topContainer
|
||
with:attachment
|
||
roomID:roomInfo.roomId
|
||
uID:[AccountInfoStorage instance].getUid];
|
||
}
|
||
|
||
- (void)receiveBravoGiftWinning:(AttachmentModel *)attachment {
|
||
RoomInfoModel *roomInfo = self.hostDelegate.getRoomInfo;
|
||
BravoGiftWinningFlagViewModel *flagModel = [BravoGiftWinningFlagView display:self.topContainer
|
||
with:attachment
|
||
roomID:roomInfo.roomId
|
||
uID:[AccountInfoStorage instance].getUid];
|
||
if (flagModel.roomId != roomInfo.roomId || flagModel.uid != [AccountInfoStorage instance].getUid.integerValue) {
|
||
return;
|
||
}
|
||
if ([flagModel.receiverUidList containsObject:@([AccountInfoStorage instance].getUid.integerValue)]) {
|
||
// 数据同步到 combo
|
||
[[NSNotificationCenter defaultCenter] postNotificationName:@"receiveLuckGiftWinning" object:[NSString stringByRemovingRedundantZeros:@(flagModel.receiverProfit).stringValue]];
|
||
}
|
||
|
||
if (!self.hostDelegate.getRoomInfo.hasAnimationEffect) {
|
||
return;
|
||
}
|
||
NSDictionary *tip = [attachment.data objectForKey:@"tip"];
|
||
if (tip) {
|
||
NSNumber *level = [tip objectForKey:@"level"];
|
||
NSNumber *coins = [tip objectForKey:@"coins"];
|
||
if (level) {
|
||
[self loadBroveSVGAVideoItem:level.integerValue];
|
||
}
|
||
if (coins) {
|
||
[[NSNotificationCenter defaultCenter] postNotificationName:@"receiveLuckGiftWinning" object:[NSString stringByRemovingRedundantZeros:coins.stringValue]];
|
||
}
|
||
}
|
||
}
|
||
|
||
- (void)loadBroveSVGAVideoItem:(NSInteger)level {
|
||
if (level < 3) {
|
||
return;
|
||
}
|
||
NSString *svgaItemName = @"";
|
||
SVGAVideoEntity *entity;
|
||
switch (level) {
|
||
// case 1:
|
||
// svgaItemName = @"小";
|
||
// entity = self.broveSVGAEntity_lv_1;
|
||
// break;
|
||
// case 2:
|
||
// svgaItemName = @"中";
|
||
// entity = self.broveSVGAEntity_lv_2;
|
||
// break;
|
||
case 3:
|
||
svgaItemName = @"大";
|
||
entity = self.broveSVGAEntity_lv_3;
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if ([NSString isEmpty:svgaItemName]) {
|
||
return;
|
||
}
|
||
|
||
if (self.broveSVGAQueue.count >=3) {
|
||
return;
|
||
}
|
||
|
||
SVGAImageView *svgaView = [[SVGAImageView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
|
||
svgaView.backgroundColor = [UIColor clearColor];
|
||
svgaView.contentMode = UIViewContentModeScaleAspectFill;
|
||
svgaView.userInteractionEnabled = NO;
|
||
if (!entity) {
|
||
@kWeakify(self);
|
||
SVGAParser *parser = [[SVGAParser alloc] init];
|
||
[parser parseWithNamed:svgaItemName
|
||
inBundle:[NSBundle mainBundle]
|
||
completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) {
|
||
@kStrongify(self);
|
||
switch (level) {
|
||
// case 1:
|
||
// self.broveSVGAEntity_lv_1 = videoItem;
|
||
// break;
|
||
// case 2:
|
||
// self.broveSVGAEntity_lv_2 = videoItem;
|
||
// break;
|
||
case 3:
|
||
self.broveSVGAEntity_lv_3 = videoItem;
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
[self startPlayBroveSVGA:svgaView level:level];
|
||
} failureBlock:^(NSError * _Nonnull error) {
|
||
|
||
}];
|
||
} else {
|
||
[self startPlayBroveSVGA:svgaView level:level];
|
||
}
|
||
}
|
||
|
||
- (void)startPlayBroveSVGA:(SVGAImageView *)svgaView level:(NSInteger)level {
|
||
if (!_broveSVGAQueue) {
|
||
_broveSVGAQueue = [[NSMutableArray alloc] init];
|
||
self.viewIndex = 0;
|
||
}
|
||
if (![self.broveSVGAQueue containsObject:svgaView]) {
|
||
[self.broveSVGAQueue addObject:svgaView];
|
||
}
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((0.3 + (self.viewIndex * 0.1)) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
SVGAVideoEntity *entity;
|
||
switch (level) {
|
||
case 1:
|
||
entity = self.broveSVGAEntity_lv_1;
|
||
break;
|
||
case 2:
|
||
entity = self.broveSVGAEntity_lv_2;
|
||
break;
|
||
case 3:
|
||
entity = self.broveSVGAEntity_lv_3;
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
// [self insertSubview:svgaView atIndex:self.viewIndex];
|
||
[self _addSubviewToMiddleContainer:svgaView];
|
||
svgaView.tag = 913;
|
||
svgaView.delegate = self;
|
||
svgaView.videoItem = entity;
|
||
svgaView.loops = 1;
|
||
[svgaView startAnimation];
|
||
self.viewIndex += 1;
|
||
});
|
||
}
|
||
|
||
- (void)receiveLuckGiftBanner:(AttachmentModel *)attachment {
|
||
[self inserBannerModelToQueue:attachment];
|
||
}
|
||
|
||
- (void)playLuckyWinningBanner:(AttachmentModel *)nextAttachment {
|
||
RoomInfoModel *roomInfo = self.hostDelegate.getRoomInfo;
|
||
@kWeakify(self);
|
||
[LuckyGiftWinningBannerView display:self.bannerContainer
|
||
inRoomUid:roomInfo.uid
|
||
with:nextAttachment
|
||
complete:^{
|
||
@kStrongify(self);
|
||
NSLog(@"🔄 LuckyGiftWinningBannerView complete 回调被调用");
|
||
self.isRoomBannerV2Displaying = NO;
|
||
[self processNextRoomEffectAttachment];
|
||
} exitCurrentRoom:^{
|
||
@kStrongify(self);
|
||
[self.hostDelegate exitRoom];
|
||
}];
|
||
|
||
// 延迟配置Banner交互,确保Banner已添加到视图层级
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
for (UIView *subview in self.bannerContainer.subviews) {
|
||
if ([NSStringFromClass([subview class]) containsString:@"LuckyGiftWinningBannerView"]) {
|
||
[self configureBannerInteraction:subview];
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 确保debug视图存在
|
||
[self ensureDebugViewsExist];
|
||
});
|
||
}
|
||
|
||
-(void)receiveRoomGeneralFloatingScreen:(AttachmentModel *)attachment{
|
||
PIBaseAnimationViewModel *roomGraffiti = [PIBaseAnimationViewModel new];
|
||
roomGraffiti.data = attachment.data;
|
||
roomGraffiti.type = GiftBannerType_General_Floating_Screen;
|
||
roomGraffiti.first = attachment.first;
|
||
roomGraffiti.second = attachment.second;
|
||
|
||
PIUniversalBannerModel *model = [PIUniversalBannerModel modelWithDictionary:attachment.data];
|
||
if (model.skipType == 7 &&
|
||
(attachment.second == Custom_Message_Sub_General_Floating_Screen_One_Room ||
|
||
attachment.second == Custom_Message_Sub_General_Floating_Screen_All_Room)) {
|
||
[self receiveGameBanner:attachment];
|
||
} else {
|
||
if(self.animationListB.count == 0 && self.isPlayOfB == NO){
|
||
[self createGeneralFloatingScreenAnimation:roomGraffiti bannerModel:model];
|
||
}
|
||
[self.animationListB addObject:roomGraffiti];
|
||
}
|
||
}
|
||
|
||
- (void)receiveGameBanner:(AttachmentModel *)attachment {
|
||
[self inserBannerModelToQueue:attachment];
|
||
}
|
||
|
||
- (void)playGameBanner:(AttachmentModel *)attachment {
|
||
@kWeakify(self);
|
||
[GameUniversalBannerView display:self.bannerContainer
|
||
with:attachment
|
||
complete:^{
|
||
@kStrongify(self);
|
||
NSLog(@"🔄 GameUniversalBannerView complete 回调被调用");
|
||
self.isRoomBannerV2Displaying = NO;
|
||
[self processNextRoomEffectAttachment];
|
||
} goToGame:^(NSInteger gameID) {
|
||
@kStrongify(self);
|
||
NSArray *baishunList = [self.hostDelegate getPlayList];
|
||
for (ActivityInfoModel *model in baishunList) {
|
||
if (model.id == gameID) {
|
||
MSRoomGameWebVC *vc = [[MSRoomGameWebVC alloc]initWithDelegate:self.hostDelegate
|
||
gameModel:model];
|
||
vc.view.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight);
|
||
XPRoomViewController *roomVC = (XPRoomViewController *)self.hostDelegate;
|
||
[roomVC addChildViewController:vc];
|
||
RoomAnimationView *animationView;
|
||
for (id obj in self.hostDelegate.getSuperView.subviews) {
|
||
if ([obj isKindOfClass:[RoomAnimationView class]]){
|
||
animationView = obj;
|
||
break;
|
||
}
|
||
}
|
||
[self.hostDelegate.getSuperView addSubview:vc.view];
|
||
vc.view.tag = 913;
|
||
break;
|
||
}
|
||
}
|
||
}];
|
||
|
||
// 延迟配置Banner交互,确保Banner已添加到视图层级
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
for (UIView *subview in self.bannerContainer.subviews) {
|
||
if ([NSStringFromClass([subview class]) containsString:@"GameUniversalBannerView"]) {
|
||
[self configureBannerInteraction:subview];
|
||
|
||
// 验证bannerContainer的手势识别器
|
||
NSLog(@"🔧 Banner显示后验证:");
|
||
NSLog(@" - bannerContainer手势数量: %ld", (long)self.bannerContainer.gestureRecognizers.count);
|
||
for (UIGestureRecognizer *gesture in self.bannerContainer.gestureRecognizers) {
|
||
NSLog(@" - 手势: %@ (enabled: %@, delegate: %@)",
|
||
NSStringFromClass([gesture class]),
|
||
gesture.enabled ? @"是" : @"否",
|
||
gesture.delegate ? @"已设置" : @"未设置");
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 确保debug视图存在
|
||
[self ensureDebugViewsExist];
|
||
});
|
||
}
|
||
|
||
#pragma mark - Method: Car
|
||
- (void)handleCarEnter:(AttachmentModel *)attachment {
|
||
if (attachment.second == Custom_Message_Sub_Car_EnterRoom) {
|
||
if (self.isPlayingGiftEffect) {
|
||
return;
|
||
}
|
||
if ([self _isInSudGame]) {
|
||
return;
|
||
}
|
||
if (!self.hostDelegate.getRoomInfo.hasAnimationEffect) {
|
||
return;
|
||
}
|
||
if (self.hostDelegate.getUserInfo.platformRole == 1) {
|
||
return;
|
||
}
|
||
NSInteger otherViewType = [attachment.data[@"otherViewType"] integerValue];
|
||
NSString *viewUrl = attachment.data[@"viewUrl"];
|
||
NSString *effect = attachment.data[@"effect"];
|
||
NSDictionary *dic = nil;
|
||
if (![NSString isEmpty:viewUrl]) {
|
||
dic = @{@"otherViewType":@(otherViewType), @"viewUrl":viewUrl};
|
||
} else if(![NSString isEmpty:effect]) {
|
||
dic = @{@"effect":effect};
|
||
}
|
||
|
||
[self starHandleCarEffect:dic];
|
||
}
|
||
}
|
||
|
||
- (void)starHandleCarEffect:(NSDictionary *)dic {
|
||
if (!dic) {
|
||
return;
|
||
}
|
||
[self.carEffectQueue addObject:dic];
|
||
[self playCarEffect:dic];
|
||
}
|
||
|
||
- (void)nextCarEffect {
|
||
if (self.carEffectQueue.count > 0) {
|
||
if (self.carEffectQueue.count > 0) {
|
||
[self.carEffectQueue xpSafeRemoveObjectAtIndex:0];
|
||
}
|
||
}
|
||
if (self.carEffectQueue.count > 0) {
|
||
[self playCarEffect:self.carEffectQueue.firstObject];
|
||
}
|
||
}
|
||
|
||
- (void)playCarEffect:(NSDictionary *)effectDict {
|
||
NSString *viewUrl = [effectDict objectForKey:@"viewUrl"];
|
||
NSString *carEffect = [effectDict objectForKey:@"effect"];
|
||
@kWeakify(self);
|
||
if (![NSString isEmpty:viewUrl]) {
|
||
[self.vapParser parseWithURL:viewUrl completionBlock:^(NSString * _Nullable videoUrl) {
|
||
@kStrongify(self);
|
||
if (![NSString isEmpty:videoUrl]) {
|
||
if([videoUrl.lowercaseString containsString:@".pag"]){
|
||
self.carPagEffectView.hidden = NO;
|
||
[self _addSubviewToMiddleContainer:self.carPagEffectView];
|
||
[self.carPagEffectView setPath:videoUrl];
|
||
[self.carPagEffectView play];
|
||
} else {
|
||
self.carVapEffectView.hidden = NO;
|
||
[self _addSubviewToMiddleContainer:self.carVapEffectView];
|
||
[self.carVapEffectView setMute:NO];
|
||
[self.carVapEffectView playHWDMP4:videoUrl repeatCount:1 delegate:self];
|
||
}
|
||
}
|
||
} failureBlock:^(NSError * _Nullable error) {
|
||
@kStrongify(self);
|
||
[self nextCarEffect];
|
||
}];
|
||
} else if (![NSString isEmpty:carEffect]) {
|
||
[self.vggParser parseWithURL:[NSURL URLWithString:carEffect]
|
||
completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
|
||
@kStrongify(self);
|
||
if (videoItem) {
|
||
[self _addSubviewToMiddleContainer:self.carSVGAEffectView];
|
||
[self _updateGiftEffectContentMode:self.carSVGAEffectView
|
||
size:videoItem.videoSize];
|
||
self.carSVGAEffectView.videoItem = videoItem;
|
||
[self.carSVGAEffectView startAnimation];
|
||
}
|
||
} failureBlock:^(NSError * _Nullable error) {
|
||
@kStrongify(self);
|
||
[self nextCarEffect];
|
||
}];
|
||
}
|
||
}
|
||
|
||
#pragma mark - Method: Send Gifts
|
||
- (void)receiveGiftHandleSendGiftAnimationWith:(GiftReceiveInfoModel *)receiveInfo attachment:(AttachmentModel *)attachment {
|
||
if (!self.hostDelegate.getRoomInfo.hasAnimationEffect) {
|
||
return;
|
||
}
|
||
|
||
GiftInfoModel *giftInfo = receiveInfo.gift;
|
||
if (attachment.second == Custom_Message_Sub_AllMicroLuckySend ||
|
||
attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend ||
|
||
attachment.second == Custom_Message_Sub_Gift_LuckySend) {
|
||
NSString * giftId = [NSString stringWithFormat:@"%ld", receiveInfo.luckyGiftList.giftList.firstObject.giftId];
|
||
NSString *roomUid = receiveInfo.roomUid == 0 ? receiveInfo.uid : @(receiveInfo.roomUid).stringValue;
|
||
giftInfo = [[XPGiftStorage shareStorage] findGiftInfo:giftId inRoom:roomUid];
|
||
}
|
||
|
||
if (giftInfo == nil) {
|
||
giftInfo = [[XPGiftStorage shareStorage] findGiftInfo:receiveInfo.giftId inRoom:@(receiveInfo.roomUid).stringValue];
|
||
}
|
||
if (giftInfo == nil) {
|
||
giftInfo = [receiveInfo.displayGift xpSafeObjectAtIndex:0];
|
||
}
|
||
|
||
receiveInfo.gift = giftInfo;
|
||
RoomInfoModel * roomInfo = [self.hostDelegate getRoomInfo];
|
||
if ((giftInfo.otherViewType == GiftOtherViewTypeMp4 ||
|
||
giftInfo.otherViewType == GiftOtherViewTypePag) &&
|
||
giftInfo.viewUrl.length > 0 && roomInfo.hasAnimationEffect) {
|
||
receiveInfo.mp4Url = giftInfo.viewUrl;
|
||
} else if (giftInfo.hasVggPic &&
|
||
giftInfo.vggUrl.length > 0
|
||
&& roomInfo.hasAnimationEffect) {///SVGA动画
|
||
receiveInfo.vggUrl = giftInfo.vggUrl;
|
||
}
|
||
|
||
if (attachment.second != Custom_Message_Sub_Gift_EmbeddedStyle) {
|
||
// Custom_Message_Sub_Gift_EmbeddedStyle 只需播放特效
|
||
[self.giftAnimationManager enqueueGift:receiveInfo];
|
||
}
|
||
}
|
||
|
||
- (void)receiveGift:(GiftReceiveInfoModel *)receiveInfo {
|
||
if (receiveInfo.isHomeShow) {
|
||
return;
|
||
}
|
||
|
||
// 处理 combo
|
||
[[GiftComboManager sharedManager] receiveGiftInfoForDisplayComboFlags:receiveInfo
|
||
container:self];
|
||
|
||
if (receiveInfo.isLuckyBagGift) {
|
||
if (receiveInfo.isShowAnimation) {
|
||
[self handleLuckyBagGifts:receiveInfo];
|
||
}
|
||
} else {
|
||
if (![NSString isEmpty:receiveInfo.mp4Url] || ![NSString isEmpty:receiveInfo.vggUrl]) {
|
||
[self addToSvgaQueue:receiveInfo];
|
||
}
|
||
}
|
||
|
||
dispatch_async(self.giftEffectsQueue, ^{
|
||
if (self.giftEffectTimer == nil &&
|
||
self.svgaQueue.count > 0) {
|
||
[self startHandleGiftEffectTimer];
|
||
}
|
||
});
|
||
|
||
}
|
||
|
||
- (void)handleLuckyBagGifts:(GiftReceiveInfoModel *)receiveInfo {
|
||
//如果是福袋礼物的话 就不用看他的价值了 只要有SVGA的话 就播放
|
||
// MARK: 此代码从 XPRoomAnimationView copy 而来,暂时无法确认其正确性
|
||
RoomInfoModel * roomInfo = [self.hostDelegate getRoomInfo];
|
||
if (receiveInfo.displayGift.count > 0) {
|
||
[receiveInfo.displayGift enumerateObjectsUsingBlock:^(GiftInfoModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
|
||
if ((obj.otherViewType == GiftOtherViewTypeMp4 || obj.otherViewType == GiftOtherViewTypePag) && obj.viewUrl && obj.viewUrl.length > 0 && roomInfo.hasAnimationEffect) {
|
||
GiftReceiveInfoModel * model = [[GiftReceiveInfoModel alloc] init];
|
||
model.mp4Url = obj.viewUrl;
|
||
model.avatar = receiveInfo.sendUserAvatar;
|
||
model.gift = obj;
|
||
model.giftNum = [obj.giftNum integerValue];;
|
||
model.nick = receiveInfo.nick;
|
||
model.targetUids = receiveInfo.targetUids;
|
||
model.isBatch = receiveInfo.isBatch;
|
||
model.targetAvatar = receiveInfo.targetAvatar;
|
||
model.targetNick = receiveInfo.targetNick;
|
||
[self addToSvgaQueue:model];
|
||
} else if (obj.hasVggPic && roomInfo.hasAnimationEffect) {
|
||
GiftReceiveInfoModel * model = [[GiftReceiveInfoModel alloc] init];
|
||
model.mp4Url = obj.viewUrl;
|
||
model.avatar = receiveInfo.sendUserAvatar;
|
||
model.gift = obj;
|
||
model.giftNum = [obj.giftNum integerValue];;
|
||
model.nick = receiveInfo.nick;
|
||
model.targetUids = receiveInfo.targetUids;
|
||
model.isBatch = receiveInfo.isBatch;
|
||
model.targetAvatar = receiveInfo.targetAvatar;
|
||
model.targetNick = receiveInfo.targetNick;
|
||
[self addToSvgaQueue:model];
|
||
}
|
||
}];
|
||
}
|
||
}
|
||
|
||
- (void)startHandleGiftEffectTimer {
|
||
NSTimeInterval period = 2.0;
|
||
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
|
||
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
|
||
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), period * NSEC_PER_SEC, 0); //每秒执行
|
||
@kWeakify(self);
|
||
dispatch_source_set_event_handler(timer, ^{
|
||
@kStrongify(self)
|
||
if (!self) {
|
||
return;
|
||
}
|
||
dispatch_async(self.giftEffectsQueue, ^{
|
||
NSLog(@"******************* 当前队列个数: %@,image loader 个数: %@", @(self.svgaQueue.count), @(self.mp4AvatarLoaders.count));
|
||
if (self.svgaQueue.count == 0) {
|
||
dispatch_source_cancel(timer);
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
self.giftEffectTimer = nil;
|
||
});
|
||
} else {
|
||
if (self.isPlayingGiftEffect == NO) {
|
||
self.isPlayingGiftEffect = YES;
|
||
GiftReceiveInfoModel *receiveModel = [self.svgaQueue xpSafeObjectAtIndex:0];
|
||
if ([receiveModel isKindOfClass:[GiftReceiveInfoModel class]]) {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[self createGiftSvgaAnimation:receiveModel];
|
||
});
|
||
}else {
|
||
[self removeFromSvgaQueueAtIndex:0];
|
||
self.isPlayingGiftEffect = NO;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
});
|
||
|
||
self.giftEffectTimer = timer;
|
||
dispatch_resume(timer);
|
||
}
|
||
|
||
-(void)createGiftSvgaAnimation:(GiftReceiveInfoModel *)receiveInfo {
|
||
GiftInfoModel *giftInfo = receiveInfo.gift;
|
||
NSString *targetURL = @"";
|
||
|
||
if (receiveInfo.isLuckyBagGift) {
|
||
// 播放背包礼物动画
|
||
if (![NSString isEmpty:receiveInfo.mp4Url]) {
|
||
[self stopCarEffect:giftInfo.goldPrice];
|
||
targetURL = receiveInfo.mp4Url;
|
||
[self playLuckyGiftEffectWithVapUrl:receiveInfo.mp4Url];
|
||
} else if (![NSString isEmpty:receiveInfo.luckyGiftSvgaUrl]) {
|
||
[self stopCarEffect:giftInfo.goldPrice];
|
||
targetURL = receiveInfo.luckyGiftSvgaUrl;
|
||
[self playGiftEffectWithVapUrl:receiveInfo.luckyGiftSvgaUrl];
|
||
} else if (![NSString isEmpty:giftInfo.luckyGiftSvgaUrl]) {
|
||
[self stopCarEffect:giftInfo.goldPrice];
|
||
targetURL = giftInfo.luckyGiftSvgaUrl;
|
||
[self playGiftEffectWithVapUrl:giftInfo.luckyGiftSvgaUrl];
|
||
}
|
||
} else {
|
||
[self stopCarEffect:giftInfo.goldPrice];
|
||
if (giftInfo.otherViewType == GiftOtherViewTypePag ||
|
||
giftInfo.otherViewType == GiftOtherViewTypeMp4) {
|
||
if (giftInfo.otherViewType == GiftOtherViewTypePag) {
|
||
[self playGiftEffectWithPagUrl:giftInfo.viewUrl];
|
||
targetURL = giftInfo.viewUrl;
|
||
} else {
|
||
self.mp4TempReceiveInfoModel = receiveInfo;
|
||
[self playGiftEffectWithVapUrl:giftInfo.viewUrl];
|
||
targetURL = giftInfo.viewUrl;
|
||
}
|
||
}
|
||
// 兜底,同时判断是否可以执行 svga
|
||
if ([NSString isEmpty:targetURL] && giftInfo.hasVggPic && giftInfo.vggUrl.length > 0) {
|
||
[self playGiftEffectWithVggUrl:giftInfo.vggUrl];
|
||
targetURL = giftInfo.vggUrl;
|
||
}
|
||
}
|
||
|
||
// NSLog(@"******************* 执行播放, 是否MP4:%@,URL: %@, self.svgaQueue num: %@", @(giftInfo.otherViewType), targetURL, @(self.svgaQueue.count));
|
||
|
||
[[NSNotificationCenter defaultCenter] postNotificationName:@"kExchangeRoomAnimationViewAndGameViewIndex"
|
||
object:nil];
|
||
@kWeakify(self);
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
@kStrongify(self);
|
||
[self removeFromSvgaQueueAtIndex:0];
|
||
});
|
||
}
|
||
|
||
- (void)stopCarEffect:(double)goldPrice {
|
||
if ([ClientConfig shareConfig].configInfo.hideCarEffectGiftPrice <= goldPrice) {
|
||
[self.carEffectQueue removeAllObjects];
|
||
[self.carSVGAEffectView stopAnimation];
|
||
[self.carVapEffectView stopHWDMP4];
|
||
[self.carPagEffectView stop];
|
||
}
|
||
}
|
||
|
||
- (void)playGiftEffectWithPagUrl:(NSString *)pagUrl {
|
||
@kWeakify(self);
|
||
[self.vapParser parseWithURL:pagUrl
|
||
completionBlock:^(NSString * _Nullable videoUrl) {
|
||
@kStrongify(self);
|
||
if ([NSString isEmpty:videoUrl]) {
|
||
[self playPAGFailure];
|
||
} else {
|
||
[self _addSubviewToMiddleContainer:self.pagGiftEffectView];
|
||
[self.pagGiftEffectView setPath:videoUrl];
|
||
[self.pagGiftEffectView play];
|
||
}
|
||
} failureBlock:^(NSError * _Nullable error) {
|
||
@kStrongify(self);
|
||
[self playPAGFailure];
|
||
}];
|
||
}
|
||
|
||
- (void)playGiftEffectWithVapUrl:(NSString *)vapUrl {
|
||
NSString *encodingUrl = [vapUrl pureURLString];
|
||
NSString *fullPath = [self _findFullPath:vapUrl];
|
||
|
||
self.mp4AvatarLoaders = @[].mutableCopy;
|
||
if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath]){
|
||
[self playVAG:fullPath];
|
||
}else {
|
||
@kWeakify(self);
|
||
[self.vapParser parseWithURL:encodingUrl
|
||
completionBlock:^(NSString * _Nullable videoUrl) {
|
||
@kStrongify(self);
|
||
if ([NSString isEmpty:videoUrl]) {
|
||
[self playVAGFailure];
|
||
} else {
|
||
[self playVAG:videoUrl];
|
||
}
|
||
} failureBlock:^(NSError * _Nullable error) {
|
||
@kStrongify(self);
|
||
[self playVAGFailure];
|
||
}];
|
||
}
|
||
}
|
||
|
||
- (void)playGiftEffectWithVggUrl:(NSString *)vggUrl {
|
||
NSString *encodingUrl = [vggUrl pureURLString];
|
||
NSString *fullPath = [self _findFullPath:vggUrl];
|
||
// NSLog(@"******************* 解释 SVGA : %@ | %@", encodingUrl, fullPath);
|
||
if (![NSString isEmpty:fullPath] && [[NSFileManager defaultManager] fileExistsAtPath:fullPath]) {
|
||
NSData *data = [NSData dataWithContentsOfFile:fullPath options:0 error:NULL];
|
||
NSString *fileName = [[encodingUrl componentsSeparatedByString:@"/"] lastObject];
|
||
@kWeakify(self);
|
||
[self.vggParser parseWithData:data
|
||
cacheKey:fileName
|
||
completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) {
|
||
@kStrongify(self);
|
||
if (videoItem) {
|
||
[self playVGG:videoItem];
|
||
} else {
|
||
[self playVGGFailure];
|
||
}
|
||
} failureBlock:^(NSError * _Nonnull error) {
|
||
@kStrongify(self);
|
||
[self playVGGFailure];
|
||
}];
|
||
} else {
|
||
@kWeakify(self);
|
||
[self.vggParser parseWithURL:[NSURL URLWithString:encodingUrl]
|
||
completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
|
||
@kStrongify(self);
|
||
// NSLog(@"******************* 解释 SVGA 成功");
|
||
if (videoItem) {
|
||
[self playVGG:videoItem];
|
||
} else {
|
||
[self playVGGFailure];
|
||
}
|
||
} failureBlock:^(NSError * _Nullable error) {
|
||
@kStrongify(self);
|
||
// NSLog(@"******************* 解释 SVGA 失败:%@", error);
|
||
[self playVGGFailure];
|
||
}];
|
||
}
|
||
}
|
||
|
||
- (void)playVGG:(SVGAVideoEntity *)videoItem {
|
||
[self.vggGiftEffectView stopAnimation];
|
||
[self _addSubviewToMiddleContainer:self.vggGiftEffectView];
|
||
[self _updateGiftEffectContentMode:self.vggGiftEffectView
|
||
size:videoItem.videoSize];
|
||
self.vggGiftEffectView.videoItem = videoItem;
|
||
[self.vggGiftEffectView startAnimation];
|
||
}
|
||
|
||
- (void)playVGGFailure {
|
||
[self playVGGEnd];
|
||
}
|
||
|
||
- (void)playVGGEnd {
|
||
self.isPlayingGiftEffect = NO;
|
||
self.vggGiftEffectView.hidden = YES;
|
||
}
|
||
|
||
- (void)playVAG:(NSString *)url {
|
||
@kWeakify(self);
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
@kStrongify(self);
|
||
[self _addSubviewToMiddleContainer:self.vapGiftEffectView];
|
||
[self.vapGiftEffectView setMute:NO];
|
||
[self.vapGiftEffectView playHWDMP4:url
|
||
repeatCount:1
|
||
delegate:self];
|
||
});
|
||
}
|
||
|
||
- (void)playVAGFailure {
|
||
[self playVAGEnd];
|
||
}
|
||
|
||
- (void)playVAGEnd {
|
||
self.isPlayingGiftEffect = NO;
|
||
self.vapGiftEffectView.hidden = YES;
|
||
[self.vapGiftEffectView setMute:YES];
|
||
[self.vapGiftEffectView stopHWDMP4];
|
||
[self.vapGiftEffectView removeFromSuperview];
|
||
self.vapGiftEffectView = nil;
|
||
}
|
||
|
||
- (void)playPAGFailure {
|
||
self.isPlayingGiftEffect = NO;
|
||
self.pagGiftEffectView.hidden = YES;
|
||
}
|
||
|
||
#pragma mark - Delegates
|
||
#pragma mark - SVGA delegate
|
||
- (void)svgaPlayerDidFinishedAnimation:(SVGAPlayer *)player {
|
||
if (player.tag == 913) {
|
||
[player clear];
|
||
player.delegate = nil;
|
||
[player removeFromSuperview];
|
||
self.viewIndex -= 1;
|
||
if ([self.broveSVGAQueue containsObject:player]) {
|
||
[self.broveSVGAQueue removeObject:player];
|
||
}
|
||
return;
|
||
}
|
||
if (player == self.enterEffectView && player.loops == 1) {
|
||
[self endAnimationEnterEffect];
|
||
}
|
||
else if (player == self.vggGiftEffectView) {
|
||
[self playVGGEnd];
|
||
}
|
||
else if (player == self.carSVGAEffectView) {
|
||
self.carSVGAEffectView.hidden = YES;
|
||
[self.carSVGAEffectView removeFromSuperview];
|
||
[self nextCarEffect];
|
||
}
|
||
}
|
||
|
||
#pragma mark - HWDMP4PlayDelegate
|
||
- (BOOL)shouldStartPlayMP4:(VAPView *)container config:(QGVAPConfigModel *)config {
|
||
CGFloat width = config.info.size.width;
|
||
CGFloat height = config.info.size.height;
|
||
|
||
container.center = self.center;
|
||
[container mas_updateConstraints:^(MASConstraintMaker *make) {
|
||
make.width.mas_equalTo(KScreenWidth);
|
||
make.height.mas_equalTo(KScreenWidth * height / width);
|
||
}];
|
||
return YES;
|
||
}
|
||
|
||
- (void)viewDidFinishPlayMP4:(NSInteger)totalFrameCount view:(VAPView *)container {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
container.hidden = YES;
|
||
if (container == self.carVapEffectView) {
|
||
[self.carVapEffectView removeFromSuperview];
|
||
self.carVapEffectView = nil;
|
||
[self nextCarEffect];
|
||
}
|
||
else if (container == self.vapGiftEffectView) {
|
||
[self playVAGEnd];
|
||
}
|
||
else if(container == self.luckyVapGiftEffectView) {
|
||
[self.luckyVapGiftEffectView removeFromSuperview];
|
||
self.luckyVapGiftEffectView = nil;
|
||
}
|
||
});
|
||
}
|
||
|
||
- (void)viewDidStopPlayMP4:(NSInteger)lastFrameIndex view:(VAPView *)container {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
container.hidden = YES;
|
||
if (container == self.carVapEffectView) {
|
||
[self.carVapEffectView removeFromSuperview];
|
||
[self nextCarEffect];
|
||
}
|
||
else if (container == self.vapGiftEffectView) {
|
||
[self playVAGEnd];
|
||
}
|
||
else if(container == self.luckyVapGiftEffectView) {
|
||
[self.luckyVapGiftEffectView removeFromSuperview];
|
||
self.luckyVapGiftEffectView = nil;
|
||
}
|
||
});
|
||
}
|
||
|
||
- (void)viewDidFailPlayMP4:(NSError *)error{
|
||
[self playVAGFailure];
|
||
}
|
||
|
||
- (void)loadVapImageWithURL:(NSString *)urlStr
|
||
context:(NSDictionary *)context
|
||
completion:(VAPImageCompletionBlock)completionBlock {
|
||
if (self.mp4TempReceiveInfoModel) {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
QGVAPSourceInfo *info = (QGVAPSourceInfo *)context[@"resource"];
|
||
|
||
// NSLog(@" MP4 的 key - info.contentTag : %@", info.contentTag);
|
||
[self _loadMP4AvatarURL:urlStr
|
||
info:info
|
||
completion:completionBlock];
|
||
});
|
||
}
|
||
}
|
||
|
||
- (void)_loadMP4AvatarURL:(NSString *)urlStr
|
||
info:(QGVAPSourceInfo *)info
|
||
completion:(VAPImageCompletionBlock)completionBlock {
|
||
NSString *path = @"";
|
||
switch (self.mp4TempReceiveInfoModel.gift.showAvatarType) {
|
||
case 1: // 只使用 avatar
|
||
case 3:
|
||
path = self.mp4TempReceiveInfoModel.avatar;
|
||
if ([NSString isEmpty:path]) {
|
||
path = self.mp4TempReceiveInfoModel.sendUserAvatar;
|
||
}
|
||
break;
|
||
case 2: // 只使用 target avatar
|
||
path = self.mp4TempReceiveInfoModel.targetAvatar;
|
||
if ([NSString isEmpty:path]) {
|
||
path = self.mp4TempReceiveInfoModel.recvUserAvatar;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if ([NSString isEmpty:path]) {
|
||
completionBlock(kImage(@"common_avatar"), nil, @"dafeult image");
|
||
} else {
|
||
NetImageView *avatar_Loader = [[NetImageView alloc] init];
|
||
[avatar_Loader loadImageWithUrl:path
|
||
completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) {
|
||
completionBlock(image, nil, urlStr);
|
||
}];
|
||
|
||
[self.mp4AvatarLoaders addObject:avatar_Loader];
|
||
}
|
||
}
|
||
|
||
#pragma mark - PAGViewListener
|
||
- (void)onAnimationEnd:(PAGView*)pagView{
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
pagView.hidden = YES;
|
||
if (pagView == self.pagGiftEffectView) {
|
||
self.isPlayingGiftEffect = NO;
|
||
}
|
||
else if(pagView == self.carPagEffectView){
|
||
[self.carPagEffectView removeFromSuperview];
|
||
self.carPagEffectView = nil;
|
||
[self nextCarEffect];
|
||
}
|
||
});
|
||
}
|
||
|
||
- (void)onAnimationCancel:(PAGView*)pagView{
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
pagView.hidden = YES;
|
||
if (pagView == self.pagGiftEffectView) {
|
||
self.isPlayingGiftEffect = NO;
|
||
}
|
||
});
|
||
}
|
||
|
||
#pragma mark - RoomHostDelegate
|
||
#pragma mark - RoomGuestDelegate: NIMCustomMessage
|
||
- (void)handleNIMCustomMessage:(NIMMessage *)message {
|
||
if (![message.messageObject isKindOfClass:[NIMCustomObject class]]) {
|
||
return;
|
||
}
|
||
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
|
||
if (obj.attachment == nil || ![obj.attachment isKindOfClass:[AttachmentModel class]]) {
|
||
return;
|
||
}
|
||
|
||
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
|
||
switch (attachment.first) {
|
||
case CustomMessageType_User_Enter_Room:
|
||
[self _handleEnterRoomMessage:message];
|
||
break;
|
||
case CustomMessageType_RedPacket:
|
||
[self _handleLuckyPackageMessage:attachment];
|
||
break;
|
||
case CustomMessageType_Gift:
|
||
[self _handleGiftMessage:attachment];
|
||
break;
|
||
case CustomMessageType_AllMicroSend:
|
||
[self _handleGiftMessage:attachment];
|
||
break;
|
||
case CustomMessageType_Car_Notify:
|
||
[self handleCarEnter:attachment];
|
||
break;
|
||
case CustomMessageType_CP:
|
||
[self receiveCPEvent:attachment];
|
||
break;
|
||
case CustomMessageType_Super_Gift:
|
||
[self _handleSuperGift:attachment];
|
||
break;
|
||
case CustomMessageType_General_Floating_Screen:
|
||
[self _handleCommonBanner:attachment];
|
||
break;
|
||
case CustomMessageType_LuckyBag:
|
||
[self handleLuckyBag:attachment];
|
||
break;
|
||
case CustomMessageType_Look_Love:
|
||
[self handle98:attachment];
|
||
break;
|
||
case CustomMessageType_RoomPlay_Dating:
|
||
[self handleDating:attachment];
|
||
break;
|
||
case CustomMessageType_Across_Room_PK:
|
||
[self handleAcrossRoomPK:attachment];
|
||
break;
|
||
case CustomMessageType_Anchor_FansTeam:
|
||
[self handleAnchorFansTeam:attachment];
|
||
break;
|
||
case CustomMessageType_Anchor_Hour_Rank:
|
||
[self handleAnchorHourRank:attachment];
|
||
break;
|
||
case CustomMessageType_License_Hour_Rank:
|
||
[self handleLicenseHourRank:attachment];
|
||
break;
|
||
case CustomMessageType_Gift_Compound:
|
||
[self handle93:attachment];
|
||
break;
|
||
case CustomMessageType_Room_Sailing:
|
||
[self handle81:attachment];
|
||
break;
|
||
case CustomMessageType_Graffiti_Gift: {
|
||
[self receiveRoomGraffitiGift:attachment];
|
||
}
|
||
break;
|
||
case CustomMessageType_Graffiti_Star_Kitchen:
|
||
[self handle104:attachment];
|
||
break;
|
||
case CustomMessageType_Treasure_Fairy:
|
||
[self handleFairy:attachment];
|
||
break;
|
||
case CustomMessageType_Tarot:
|
||
[self handleTarot:attachment];
|
||
break;
|
||
case CustomMessageType_Common_H5:
|
||
[self handleCommonH5:attachment];
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)_handleEnterRoomMessage:(NIMMessage *)message {
|
||
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
|
||
if (obj.attachment == nil || ![obj.attachment isKindOfClass:[AttachmentModel class]]) {
|
||
return;
|
||
}
|
||
|
||
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_User_Enter_Room: {
|
||
RoomEnterModel *model = [RoomEnterModel modelWithJSON:attachment.data];
|
||
if (model.platformRole == 1) {
|
||
return;
|
||
}
|
||
if (model.enterHide) {
|
||
//隐身进房
|
||
if (model.uid == [AccountInfoStorage instance].getUid.integerValue) {
|
||
[self createEnterHideAnimation];
|
||
}
|
||
} else {
|
||
NSString *userName = model.nick;
|
||
if (model.cpList.count > 0 && model.screenType < 3) {
|
||
NSString *title = [NSString stringWithFormat:YMLocalizedString(@"XPRoomAnimationView0"), userName];
|
||
NSDictionary * dic= @{@"title":title,
|
||
@"experLevelSeq":[NSString stringWithFormat:@"%ld", model.experLevelSeq],
|
||
@"effectPath" : @"",
|
||
@"isCP":@(YES)
|
||
};
|
||
[self.enterRoomAnimationQueue addObject:dic];
|
||
} else {
|
||
NSString *title = [NSString stringWithFormat:YMLocalizedString(@"XPRoomAnimationView0"), userName];
|
||
|
||
NSDictionary * dic= @{@"title":title,
|
||
@"experLevelSeq":[NSString stringWithFormat:@"%ld", model.experLevelSeq],
|
||
@"effectPath" : model.enterRoomEffects.length ? model.enterRoomEffects : @""};
|
||
[self.enterRoomAnimationQueue addObject:dic];
|
||
}
|
||
[self tryDequeueAnimation];
|
||
}
|
||
}
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)_handleLuckyPackageMessage:(AttachmentModel *)attachment {
|
||
if ([self _isInSudGame]) {
|
||
return;
|
||
}
|
||
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_LuckyPackage:
|
||
[self receiveLuckGiftBanner:attachment];
|
||
break;
|
||
|
||
default:
|
||
return;
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)_handleGiftMessage:(AttachmentModel *)attachment {
|
||
if ([self _isInSudGame]) {
|
||
return;
|
||
}
|
||
|
||
GiftReceiveInfoModel * receiveInfo = [GiftReceiveInfoModel modelWithJSON:attachment.data];
|
||
[receiveInfo giftDataAlignment];
|
||
|
||
receiveInfo.isLuckyBagGift = (attachment.second == Custom_Message_Sub_Gift_LuckySend ||
|
||
attachment.second == Custom_Message_Sub_AllMicroLuckySend ||
|
||
attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend);
|
||
receiveInfo.isBatch = (attachment.second == Custom_Message_Sub_AllBatchSend ||
|
||
attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend);
|
||
receiveInfo.isComboBatch = (attachment.second == Custom_Message_Sub_AllMicroSend);
|
||
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_Gift_Send:
|
||
[self _handleGift:receiveInfo attachment:attachment];
|
||
break;
|
||
case Custom_Message_Sub_AllMicroSend:
|
||
case Custom_Message_Sub_AllBatchSend:
|
||
[self _handleGift:receiveInfo attachment:attachment];
|
||
break;
|
||
case Custom_Message_Sub_Gift_ChannelNotify:
|
||
//处理原广播通用飘屏 banner 逻辑
|
||
[self receiveRoomGiftBanner:attachment];
|
||
return;
|
||
break;
|
||
case Custom_Message_Sub_Gift_EmbeddedStyle:
|
||
[self _handleGiftEmbeddedStyle:receiveInfo attachment:attachment];
|
||
break;
|
||
case 607:
|
||
[self receiveLuckGiftBanner:attachment];
|
||
break;
|
||
case Custom_Message_Sub_Gift_LuckySend:
|
||
case Custom_Message_Sub_AllMicroLuckySend:
|
||
case Custom_Message_Sub_AllBatchMicroLuckySend:
|
||
{
|
||
[self _handleGift:receiveInfo attachment:attachment];
|
||
// if (receiveInfo.mp4Url.length > 0) {
|
||
// [self playLuckyGiftEffectWithVapUrl:receiveInfo.mp4Url];
|
||
// } else {
|
||
// NSString * svgaString = receiveInfo.luckyGiftSvgaUrl.length > 0 ? receiveInfo.luckyGiftSvgaUrl : receiveInfo.gift.luckyGiftSvgaUrl;
|
||
// NSURL * luckyGiftSvgaUrl = [NSURL URLWithString:svgaString];
|
||
// if (luckyGiftSvgaUrl.absoluteString.length > 0) {
|
||
// [self play:luckyGiftSvgaUrl];
|
||
// }
|
||
// }
|
||
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
// [self receiveGift:receiveInfo];
|
||
// });
|
||
}
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if (receiveInfo.isLuckyBagGift) {
|
||
[self receiveGiftHandleSendGiftAnimationWith:receiveInfo
|
||
attachment:attachment];
|
||
[self _handleBagGift:receiveInfo];
|
||
} else {
|
||
if (receiveInfo.gift.notifyFull == 1 &&
|
||
attachment.second == Custom_Message_Sub_Gift_Send) {
|
||
// 全服礼物,但由自己发送,不在此逻辑播放
|
||
return;
|
||
}
|
||
// 处理从位置 发送者 到 接受者 的礼物移动动画
|
||
[self receiveGiftHandleSendGiftAnimationWith:receiveInfo
|
||
attachment:attachment];
|
||
// 播放礼物动画(svga/mp4)(如果有的话)
|
||
[self receiveGift:receiveInfo];
|
||
}
|
||
}
|
||
|
||
- (void)_handleBagGift:(GiftReceiveInfoModel *)receiveInfo {
|
||
if (!self.hostDelegate.getRoomInfo.hasAnimationEffect) {
|
||
return;
|
||
}
|
||
[self receiveGift:receiveInfo];
|
||
}
|
||
|
||
- (void)_handleGift:(GiftReceiveInfoModel *)receiveInfo
|
||
attachment:(AttachmentModel *)attachment {
|
||
// 确认接受者有 uid
|
||
if (receiveInfo.targetUsers.count == 0) {
|
||
GiftReceiveUserInfoModel *model = [[GiftReceiveUserInfoModel alloc] init];
|
||
model.nick = receiveInfo.targetNick;
|
||
model.avatar = receiveInfo.targetAvatar;
|
||
model.uid = receiveInfo.uid.integerValue;
|
||
receiveInfo.targetUsers = @[model];
|
||
}
|
||
// 确认接受者有 uid
|
||
if (receiveInfo.targetUsers.count > 0 && receiveInfo.targetUids.count <= 0) {
|
||
receiveInfo.targetUids = [receiveInfo.targetUsers valueForKeyPath:@"uid"];
|
||
}
|
||
}
|
||
|
||
- (void)_handleGiftEmbeddedStyle:(GiftReceiveInfoModel *)receiveInfo
|
||
attachment:(AttachmentModel *)attachment {
|
||
// 数据对齐
|
||
receiveInfo.targetUid = [[attachment.data objectForKey:@"recvUserUid"] stringValue];
|
||
receiveInfo.targetNick = [attachment.data objectForKey:@"recvUserNick"];
|
||
receiveInfo.targetAvatar = [attachment.data objectForKey:@"recvUserAvatar"];
|
||
receiveInfo.avatar = [attachment.data objectForKey:@"sendUserAvatar"];
|
||
receiveInfo.nick = [attachment.data objectForKey:@"sendUserNick"];
|
||
receiveInfo.uid = [[attachment.data objectForKey:@"sendUserUid"] stringValue];
|
||
|
||
// 确认接受者有 uid
|
||
if (receiveInfo.targetUsers.count > 0 && receiveInfo.targetUids.count <= 0) {
|
||
receiveInfo.targetUids = [receiveInfo.targetUsers valueForKeyPath:@"uid"];
|
||
}
|
||
}
|
||
|
||
- (void)_handleSuperGift:(AttachmentModel *)attachment {
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_Super_Gift_Winning_Coins:
|
||
[self receiveLuckGiftWinning:attachment];
|
||
break;
|
||
case Custom_Message_Sub_Super_Gift_Winning_Coins_ALL_Room:
|
||
[self receiveLuckGiftBanner:attachment];
|
||
break;
|
||
case Custom_Message_Sub_Super_Gift_Banner:
|
||
[self handleBroveGiftBanner:attachment];
|
||
break;
|
||
case Custom_Message_Sub_Super_Gift_UI_Rffect:
|
||
[self receiveBravoGiftWinning:attachment];
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)_handleCommonBanner:(AttachmentModel *)attachment {
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_General_Floating_Screen_One_Room:
|
||
case Custom_Message_Sub_General_Floating_Screen_All_Room:
|
||
[self receiveRoomGeneralFloatingScreen:attachment];
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (NSString *)_findFullPath:(NSString *)url {
|
||
NSString *encodingUrl = [url pureURLString];
|
||
NSString *fileName = [[encodingUrl componentsSeparatedByString:@"/"] lastObject];
|
||
NSString *fullPath = [self.GiftDynamicEffectListPath stringByAppendingPathComponent:fileName];
|
||
return fullPath;
|
||
}
|
||
|
||
- (void)_updateGiftEffectContentMode:(UIView *)view
|
||
size:(CGSize)size {
|
||
CGFloat width = size.width;
|
||
CGFloat height = size.height;
|
||
if (width > height) {
|
||
view.contentMode = UIViewContentModeScaleAspectFit;
|
||
} else {//高大于宽
|
||
CGFloat resizeH = KScreenWidth * height / width;//按照屏幕的宽度去缩放,获得高度
|
||
if (resizeH > KScreenHeight) {//如果大于屏幕高度,填充
|
||
view.contentMode = UIViewContentModeScaleAspectFill;
|
||
} else {//小于屏幕高度,
|
||
view.contentMode = UIViewContentModeScaleAspectFit;
|
||
}
|
||
}
|
||
}
|
||
|
||
- (void)handleCommonH5:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
|
||
switch (attachment.second) {
|
||
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handleTarot:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handleFairy:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L4:
|
||
case Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L5:
|
||
case Custom_Message_Sub_Treasure_Fairy_Convert_L1:
|
||
case Custom_Message_Sub_Treasure_Fairy_Convert_L2:
|
||
case Custom_Message_Sub_Treasure_Fairy_Convert_L3:
|
||
[self receiveTreasureFairyGiftHighLevel:attachment];
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handle98:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_Look_Love_InRoom_NeedAllMicSend:
|
||
[self receiveCandyTreeGiftHighLevle:attachment];
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handle104:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handleLuckyBag:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_Room_Gift_LuckBag_FullScree:
|
||
case Custom_Message_Sub_Room_Gift_LuckBag_Server:
|
||
[self receiveLuckyGiftBigPrize:attachment];
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handleVIPLevelUp:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_Room_Noble_LevelUp_Suspend:
|
||
[self receiveNobleLevelUp:attachment];
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handleDating:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_Room_Play_Dating_Public_Result:
|
||
[self roomDatingPublicResult:attachment];
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handleAcrossRoomPK:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_AcrossRoomPK_Result:
|
||
[self acrossRoomPKBannerAnimation:attachment];
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handleAnchorFansTeam:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_FansTeam_Join_Success: {
|
||
GiftReceiveInfoModel *receiveInfo = [[GiftReceiveInfoModel alloc] init];
|
||
GiftInfoModel *giftInfo = [GiftInfoModel modelWithJSON:attachment.data[@"giftVo"]];
|
||
receiveInfo.gift = giftInfo;
|
||
receiveInfo.giftInfo = giftInfo;
|
||
[self receiveFansTeamGiftHandleSendGiftAnimation:attachment];
|
||
[self receiveGift:receiveInfo];
|
||
}
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handleAnchorHourRank:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_Anchor_Hour_Rank:
|
||
[self receiveAnchorHourRank:attachment];
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handleLicenseHourRank:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_License_Hour_Rank:
|
||
[self receiveAnchorHourRank:attachment];
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handle93:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_Gift_Compound:
|
||
[self receiveGiftCompound:attachment];
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handle81:(AttachmentModel *)attachment {
|
||
if (!attachment) {
|
||
return;
|
||
}
|
||
switch (attachment.second) {
|
||
case Custom_Message_Sub_Sailing_AllRoom_Notify:
|
||
case Custom_Message_Sub_Sailing_InRoom_NeedAllMicSend:
|
||
[self receiveRoomSailing:attachment];
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (void)handleBroveGiftBanner:(AttachmentModel *)attachment {
|
||
[self inserBannerModelToQueue:attachment];
|
||
}
|
||
|
||
|
||
#pragma mark - RoomGuestDelegate: NIMNotificationMessageDelegate
|
||
- (void)handleNIMNotificationMessage:(NIMMessage *)message {
|
||
return;
|
||
// NIMNotificationObject *notiMsg = (NIMNotificationObject *)message.messageObject;
|
||
// NIMChatroomNotificationContent *content = (NIMChatroomNotificationContent *)notiMsg.content;
|
||
// if (!content) {
|
||
// return;
|
||
// }
|
||
//
|
||
// switch (content.eventType) {
|
||
// case NIMChatroomEventTypeEnter:
|
||
// [self enterRoom:message content:content];
|
||
// break;
|
||
//
|
||
// default:
|
||
// break;
|
||
// }
|
||
}
|
||
|
||
#pragma mark - NIMBroadcastManagerDelegate
|
||
- (void)onReceiveBroadcastMessage:(NIMBroadcastMessage *)broadcastMessage {
|
||
if (broadcastMessage.content) {
|
||
NSDictionary *msgDictionary = [broadcastMessage.content toJSONObject];
|
||
AttachmentModel *attachment = [AttachmentModel modelWithJSON:msgDictionary[@"body"]];
|
||
NSString *partitionId = [NSString stringWithFormat:@"%@",attachment.data[@"partitionId"]];
|
||
if(![partitionId isEqualToString:self.hostDelegate.getUserInfo.partitionId]){
|
||
return;
|
||
}
|
||
|
||
switch (attachment.first) {
|
||
case CustomMessageType_General_Floating_Screen:
|
||
[self _handleCommonBanner:attachment];
|
||
break;
|
||
case CustomMessageType_Noble_VIP:
|
||
[self handleVIPLevelUp:attachment];
|
||
break;
|
||
case CustomMessageType_LuckyBag:
|
||
[self handleLuckyBag:attachment];
|
||
break;
|
||
case CustomMessageType_Graffiti_Star_Kitchen:
|
||
[self handle104:attachment];
|
||
break;
|
||
case CustomMessageType_Look_Love:
|
||
[self handle98:attachment];
|
||
break;
|
||
case CustomMessageType_Treasure_Fairy:
|
||
[self handleFairy:attachment];
|
||
break;
|
||
case CustomMessageType_Tarot:
|
||
[self handleTarot:attachment];
|
||
break;
|
||
case CustomMessageType_Common_H5:
|
||
[self handleCommonH5:attachment];
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
#pragma mark - GiftAnimationManagerDelegate
|
||
- (CGPoint)animationPointAtStageViewByUid:(NSString *)uid {
|
||
return [self.hostDelegate animationPointAtStageViewByUid:uid];
|
||
}
|
||
|
||
#pragma mark - Gesture
|
||
// 注释掉整个方法
|
||
/*
|
||
- (void)addBnnerContainGesture {
|
||
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self
|
||
action:@selector(handleSwipe)];
|
||
if (isMSRTL()) {
|
||
swipe.direction = UISwipeGestureRecognizerDirectionRight;
|
||
} else {
|
||
swipe.direction = UISwipeGestureRecognizerDirectionLeft;
|
||
}
|
||
|
||
[self.bannerContainer addGestureRecognizer:swipe];
|
||
}
|
||
*/
|
||
|
||
- (void)handleSwipe {
|
||
[[NSNotificationCenter defaultCenter] postNotificationName:@"SwipeOutBanner" object:nil];
|
||
}
|
||
|
||
#pragma mark - Animations
|
||
- (void)enterRoomAnimationFor:(UIView *)targetView
|
||
startFrom:(CGPoint)sfPoint
|
||
startTo:(CGPoint)stPoint
|
||
endFrom:(CGPoint)efPoint
|
||
endTo:(CGPoint)etPoint
|
||
duration:(CFTimeInterval)duration
|
||
completion:(void (^)(BOOL finished))completion {
|
||
@kWeakify(self);
|
||
[self enterRoomMoveInAnimationFor:targetView
|
||
fromValue:sfPoint
|
||
toValue:stPoint
|
||
completion:^(BOOL finished) {
|
||
if (finished) {
|
||
@kStrongify(self);
|
||
@kWeakify(self);
|
||
[self enterRoomMoveOutAnimationFor:targetView
|
||
fromValue:efPoint
|
||
toValue:etPoint
|
||
beginTime:duration
|
||
completion:^(BOOL finished) {
|
||
if (finished) {
|
||
@kStrongify(self);
|
||
[self cleanupAnimationsForView:targetView];
|
||
if (completion) {
|
||
completion(finished);
|
||
}
|
||
}
|
||
}];
|
||
}
|
||
}];
|
||
}
|
||
|
||
- (void)enterRoomMoveInAnimationFor:(UIView *)view
|
||
fromValue:(CGPoint)fromValue
|
||
toValue:(CGPoint)toValue
|
||
completion:(void (^)(BOOL finished))completion {
|
||
POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
springAnimation.springSpeed = 12;
|
||
springAnimation.springBounciness = 10.f;
|
||
springAnimation.fromValue = [NSValue valueWithCGPoint:fromValue];
|
||
springAnimation.toValue = [NSValue valueWithCGPoint:toValue];
|
||
[springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
if (completion) completion(finished);
|
||
}];
|
||
[view pop_addAnimation:springAnimation forKey:@"amationSpringIn"];
|
||
}
|
||
|
||
- (void)enterRoomMoveOutAnimationFor:(UIView *)view
|
||
fromValue:(CGPoint)fromValue
|
||
toValue:(CGPoint)toValue
|
||
beginTime:(CFTimeInterval)beginTime
|
||
completion:(void (^)(BOOL finished))completion {
|
||
POPSpringAnimation *moveAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
moveAnimation.fromValue = [NSValue valueWithCGPoint:fromValue];
|
||
moveAnimation.toValue = [NSValue valueWithCGPoint:toValue];
|
||
moveAnimation.beginTime = beginTime;
|
||
moveAnimation.springSpeed = 8;
|
||
moveAnimation.springBounciness = 15.f;
|
||
[moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
if (completion) completion(finished);
|
||
}];
|
||
[view pop_addAnimation:moveAnimation forKey:@"animetionMoveOut"];
|
||
}
|
||
|
||
- (void)cleanupAnimationsForView:(UIView *)view {
|
||
[view pop_removeAllAnimations];
|
||
[view removeFromSuperview];
|
||
}
|
||
|
||
#pragma mark - Common methods
|
||
- (NSString *)_resolveUserNameFromContent:(NIMChatroomNotificationContent *)content
|
||
extModel:(XPMessageRemoteExtModel *)extModel {
|
||
// 1) extModel.nick 优先
|
||
if (![NSString isEmpty:extModel.nick]) {
|
||
return extModel.nick;
|
||
}
|
||
// 2) 如果 extModel.nick 为空,看 content.source.nick
|
||
if (![NSString isEmpty:content.source.nick]) {
|
||
return content.source.nick;
|
||
}
|
||
// 3) 如果依然空,并且是自己,则取本地 nick
|
||
if (content.source.userId.intValue == self.hostDelegate.getUserInfo.uid &&
|
||
![NSString isEmpty:self.hostDelegate.getUserInfo.nick]) {
|
||
return self.hostDelegate.getUserInfo.nick;
|
||
}
|
||
// 4) 兜底
|
||
return @"";
|
||
}
|
||
|
||
- (NSString *)_mapExperLevelSeqToLocalKey:(NSInteger)seq {
|
||
if (seq >= 30 && seq <= 39) {
|
||
return @"experience_entre_effect_30";
|
||
} else if (seq >= 40 && seq <= 49) {
|
||
return @"experience_entre_effect_40";
|
||
} else if (seq >= 50 && seq <= 59) {
|
||
return @"experience_entre_effect_50";
|
||
} else if (seq >= 60 && seq <= 69) {
|
||
return @"experience_entre_effect_60";
|
||
} else if (seq >= 70 && seq <= 79) {
|
||
return @"experience_entre_effect_70";
|
||
} else if (seq >= 80 && seq <= 89) {
|
||
return @"experience_entre_effect_80";
|
||
} else if (seq >= 90) {
|
||
return @"experience_entre_effect_90";
|
||
}
|
||
return @"";
|
||
}
|
||
|
||
- (BOOL)_isInSudGame {
|
||
BOOL isGamePlaying = NO;
|
||
if (self.hostDelegate.getRoomInfo.type == RoomType_MiniGame) {
|
||
NSInteger micCount = self.hostDelegate.getRoomInfo.mgMicNum;
|
||
for (int i = -1; i<micCount; i++) {
|
||
NSMutableDictionary * micQueue = self.hostDelegate.getMicroQueue;
|
||
MicroQueueModel *micSequence = [micQueue objectForKey:[NSString stringWithFormat:@"%d", i]];
|
||
if (micSequence == nil || micSequence.userInfo == nil) {
|
||
continue;
|
||
}
|
||
if (micSequence.userInfo.uid == [AccountInfoStorage instance].getUid.integerValue &&
|
||
micSequence.userInfo.gameStatus == LittleGamePlayStatus_Plying) {
|
||
isGamePlaying = YES;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return isGamePlaying;
|
||
}
|
||
|
||
- (void)_addSubviewToMiddleContainer:(UIView *)view {
|
||
if (view.superview == nil) {
|
||
[self.middleContainer addSubview:view];
|
||
[view mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.center.mas_equalTo(self.middleContainer);
|
||
make.width.mas_equalTo(KScreenWidth);
|
||
make.height.mas_equalTo(KScreenHeight);
|
||
}];
|
||
}
|
||
view.hidden = NO;
|
||
}
|
||
|
||
#pragma mark - Lazy init
|
||
- (XPRoomAnimationHitView *)bottomContainer {
|
||
if (!_bottomContainer) {
|
||
_bottomContainer = [[XPRoomAnimationHitView alloc] init];
|
||
}
|
||
return _bottomContainer;
|
||
}
|
||
|
||
- (XPRoomAnimationHitView *)middleContainer {
|
||
if (!_middleContainer) {
|
||
_middleContainer = [[XPRoomAnimationHitView alloc] init];
|
||
}
|
||
return _middleContainer;
|
||
}
|
||
|
||
- (XPRoomAnimationHitView *)topContainer {
|
||
if (!_topContainer) {
|
||
_topContainer = [[XPRoomAnimationHitView alloc] init];
|
||
}
|
||
return _topContainer;
|
||
}
|
||
|
||
- (XPRoomAnimationHitView *)bannerContainer {
|
||
if (!_bannerContainer) {
|
||
_bannerContainer = [[XPRoomAnimationHitView alloc] init];
|
||
#if DEBUG
|
||
_bannerContainer.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
|
||
#endif
|
||
}
|
||
return _bannerContainer;
|
||
}
|
||
|
||
- (SVGAImageView *)enterEffectView {
|
||
if (_enterEffectView == nil) {
|
||
_enterEffectView = [[SVGAImageView alloc]init];
|
||
_enterEffectView.delegate = self;
|
||
_enterEffectView.contentMode = UIViewContentModeScaleAspectFill;
|
||
_enterEffectView.frame = CGRectMake(0, 0, KScreenWidth, 50);
|
||
_enterEffectView.backgroundColor = [UIColor clearColor];
|
||
_enterEffectView.alpha = 0;
|
||
_enterEffectView.userInteractionEnabled = NO;
|
||
}
|
||
return _enterEffectView;
|
||
}
|
||
|
||
- (NSMutableArray *)svgaQueue{
|
||
if(!_svgaQueue){
|
||
_svgaQueue = [NSMutableArray array];
|
||
}
|
||
return _svgaQueue;
|
||
}
|
||
|
||
- (void)addToSvgaQueue:(GiftReceiveInfoModel *)model {
|
||
dispatch_async(self.giftEffectsQueue, ^{
|
||
[self.svgaQueue addObject:model];
|
||
});
|
||
}
|
||
|
||
- (void)removeFromSvgaQueueAtIndex:(NSInteger)index {
|
||
dispatch_async(self.giftEffectsQueue, ^{
|
||
if (index < self.svgaQueue.count) {
|
||
if (index < self.svgaQueue.count) {
|
||
[self.svgaQueue xpSafeRemoveObjectAtIndex:index];
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
- (XPRoomGiftAnimationParser *)vapParser {
|
||
if (!_vapParser) {
|
||
_vapParser = [[XPRoomGiftAnimationParser alloc] init];
|
||
}
|
||
return _vapParser;
|
||
}
|
||
|
||
- (PAGView *)pagGiftEffectView{
|
||
if(!_pagGiftEffectView){
|
||
_pagGiftEffectView = [[PAGView alloc]init];
|
||
[_pagGiftEffectView addListener:self];
|
||
_pagGiftEffectView.backgroundColor = [UIColor clearColor];
|
||
_pagGiftEffectView.userInteractionEnabled = NO;
|
||
_pagGiftEffectView.repeatCount = 1;
|
||
_pagGiftEffectView.scaleMode = PAGScaleModeStretch;
|
||
}
|
||
return _pagGiftEffectView;
|
||
}
|
||
|
||
- (VAPView *)vapGiftEffectView {
|
||
if (!_vapGiftEffectView) {
|
||
_vapGiftEffectView = [[VAPView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
|
||
_vapGiftEffectView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
|
||
_vapGiftEffectView.contentMode = UIViewContentModeScaleAspectFill;
|
||
_vapGiftEffectView.hidden = YES;
|
||
_vapGiftEffectView.userInteractionEnabled = NO;
|
||
}
|
||
return _vapGiftEffectView;
|
||
}
|
||
|
||
- (SVGAParser *)vggParser {
|
||
if (!_vggParser) {
|
||
_vggParser = [[SVGAParser alloc] init];
|
||
}
|
||
return _vggParser;
|
||
}
|
||
|
||
- (SVGAImageView *)vggGiftEffectView {
|
||
if (!_vggGiftEffectView) {
|
||
_vggGiftEffectView = [[SVGAImageView alloc]init];
|
||
_vggGiftEffectView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
|
||
_vggGiftEffectView.userInteractionEnabled = NO;
|
||
_vggGiftEffectView.delegate = self;
|
||
_vggGiftEffectView.hidden = YES;
|
||
_vggGiftEffectView.loops = 1;
|
||
_vggGiftEffectView.clearsAfterStop = YES;
|
||
}
|
||
return _vggGiftEffectView;
|
||
}
|
||
|
||
- (VAPView *)carVapEffectView {
|
||
if (!_carVapEffectView) {
|
||
_carVapEffectView = [[VAPView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
|
||
_carVapEffectView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.3];
|
||
_carVapEffectView.contentMode = UIViewContentModeScaleAspectFill;
|
||
_carVapEffectView.hidden = YES;
|
||
}
|
||
return _carVapEffectView;
|
||
}
|
||
|
||
- (SVGAImageView *)carSVGAEffectView {
|
||
if (_carSVGAEffectView == nil) {
|
||
_carSVGAEffectView = [[SVGAImageView alloc]init];
|
||
_carSVGAEffectView.delegate = self;
|
||
_carSVGAEffectView.contentMode = UIViewContentModeScaleAspectFit;
|
||
_carSVGAEffectView.frame = CGRectMake(0, 0, KScreenWidth, KScreenHeight);
|
||
_carSVGAEffectView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.3];
|
||
_carSVGAEffectView.hidden = YES;
|
||
_carSVGAEffectView.userInteractionEnabled = NO;
|
||
_carSVGAEffectView.loops = 1;
|
||
_carSVGAEffectView.clearsAfterStop = YES;
|
||
}
|
||
return _carSVGAEffectView;
|
||
}
|
||
|
||
- (PAGView *)carPagEffectView{
|
||
if(!_carPagEffectView){
|
||
_carPagEffectView = [[PAGView alloc]init];
|
||
[_carPagEffectView addListener:self];
|
||
_carPagEffectView.backgroundColor = [UIColor clearColor];
|
||
_carPagEffectView.userInteractionEnabled = NO;
|
||
_carPagEffectView.repeatCount = 1;
|
||
_carPagEffectView.scaleMode = PAGScaleModeStretch;
|
||
}
|
||
return _carPagEffectView;
|
||
}
|
||
|
||
#pragma mark - OLD METHODs
|
||
|
||
|
||
|
||
|
||
- (void)receiveLuckyGiftBigPrize:(AttachmentModel *)attachment {
|
||
if ([self _isInSudGame]) {return;}
|
||
|
||
PIBaseAnimationViewModel * prizeModel = [PIBaseAnimationViewModel modelWithDictionary:attachment.data];
|
||
prizeModel.type = GiftBannerType_Lucky;
|
||
prizeModel.isInRoomVisable = attachment.second == Custom_Message_Sub_Room_Gift_LuckBag;
|
||
|
||
if(self.animationListB.count == 0 && self.isPlayOfB == NO){
|
||
[self createBigPrizeAnimation:prizeModel];
|
||
}
|
||
[self.animationListB addObject:prizeModel];
|
||
}
|
||
|
||
- (void)createBigPrizeAnimation:(PIBaseAnimationViewModel *)prizeModel {
|
||
self.isPlayOfB = YES;
|
||
CGFloat top = (kNavigationHeight + 15);
|
||
XPRoomLuckyBigPrizeView * luckyGiftEffectView = [[XPRoomLuckyBigPrizeView alloc] initWithFrame:CGRectMake(KScreenWidth, top, 375, 71)];
|
||
luckyGiftEffectView.delegate = self;
|
||
[self.topContainer addSubview:luckyGiftEffectView];
|
||
luckyGiftEffectView.giftInfo = prizeModel;
|
||
|
||
POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
springAnimation.springSpeed = 12;
|
||
springAnimation.springBounciness = 10.f;
|
||
springAnimation.fromValue = [NSValue valueWithCGPoint:luckyGiftEffectView.center];
|
||
springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(KScreenWidth / 2, luckyGiftEffectView.center.y)];
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 7 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
||
POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, luckyGiftEffectView.center.y)];
|
||
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, luckyGiftEffectView.center.y)];
|
||
moveAnimation.beginTime = CACurrentMediaTime();
|
||
moveAnimation.duration = 0.5;
|
||
moveAnimation.repeatCount = 1;
|
||
moveAnimation.removedOnCompletion = YES;
|
||
@kWeakify(self);
|
||
[moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
@kStrongify(self);
|
||
if (finished) {
|
||
[luckyGiftEffectView removeFromSuperview];
|
||
if (self.animationListB.count > 0) {
|
||
[self.animationListB xpSafeRemoveObjectAtIndex:0];
|
||
}
|
||
self.isPlayOfB = NO;
|
||
[self playAnimationWithModel];
|
||
}
|
||
}];
|
||
[luckyGiftEffectView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"];
|
||
});
|
||
[luckyGiftEffectView pop_addAnimation:springAnimation forKey:@"nobleLevelUpspingOutAnimation"];
|
||
}
|
||
|
||
- (void)receiveCandyTreeGiftHighLevle:(AttachmentModel *)attatchment {
|
||
if ([self _isInSudGame]) {return;}
|
||
PIBaseAnimationViewModel *giftModel = [PIBaseAnimationViewModel new];
|
||
giftModel.data = attatchment.data;
|
||
giftModel.second = attatchment.second;
|
||
giftModel.first = attatchment.first;
|
||
giftModel.type = GiftBannerType_Love;
|
||
if (self.animationListB.count == 0 && self.isPlayOfB == NO) {
|
||
[self createCandyTreeBannerAnimation:giftModel];
|
||
}
|
||
[self.animationListB addObject:giftModel];
|
||
}
|
||
|
||
- (void)createCandyTreeBannerAnimation:(PIBaseAnimationViewModel *)attatchment {
|
||
CGFloat kscale = (CGFloat)60 / (CGFloat)375;
|
||
self.isPlayOfB = YES;
|
||
CGFloat top = (kNavigationHeight + 15);
|
||
XPRoomCandyGiftView *candyTreeView = [[XPRoomCandyGiftView alloc] initWithFrame:CGRectMake(KScreenWidth, top, KScreenWidth , KScreenWidth * kscale)];
|
||
candyTreeView.isMaxLargeGift = attatchment.second == Custom_Message_Sub_Look_Love_InRoom_NeedAllMicSend;
|
||
candyTreeView.candyInfo = attatchment.data;
|
||
[self.middleContainer addSubview:candyTreeView];
|
||
POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
springAnimation.springSpeed = 12;
|
||
springAnimation.springBounciness = 10.f;
|
||
springAnimation.fromValue = [NSValue valueWithCGPoint:candyTreeView.center];
|
||
springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(candyTreeView.frame.size.width / 2, candyTreeView.center.y)];
|
||
@kWeakify(self);
|
||
[springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
@kStrongify(self);
|
||
if (finished) {
|
||
POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, candyTreeView.center.y)];
|
||
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, candyTreeView.center.y)];
|
||
moveAnimation.beginTime = CACurrentMediaTime() + 3;
|
||
moveAnimation.duration = 0.5;
|
||
moveAnimation.repeatCount = 1;
|
||
moveAnimation.removedOnCompletion = YES;
|
||
@kWeakify(self);
|
||
[moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
@kStrongify(self);
|
||
if (finished) {
|
||
[candyTreeView removeFromSuperview];
|
||
self.isPlayOfB = NO;
|
||
if (self.animationListB.count > 0) {
|
||
[self.animationListB xpSafeRemoveObjectAtIndex:0];
|
||
}
|
||
[self playAnimationWithModel];
|
||
}
|
||
}];
|
||
[candyTreeView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"];
|
||
}
|
||
}];
|
||
[candyTreeView pop_addAnimation:springAnimation forKey:@"candyTreespingOutAnimation"];
|
||
}
|
||
|
||
- (void)receiveNobleLevelUp:(AttachmentModel *)attachment {
|
||
@kWeakify(self);
|
||
[[NetImageView new]loadImageWithUrl:attachment.data[@"avatar"] completion:^(UIImage * _Nonnull image, NSURL * _Nonnull url) {
|
||
@kStrongify(self);
|
||
PIBaseAnimationViewModel *nobleModel = [PIBaseAnimationViewModel new];
|
||
nobleModel.data = attachment.data;
|
||
nobleModel.type = GiftBannerType_Nobleman;
|
||
if (self.animationListB.count == 0 && self.isPlayOfB == NO) {
|
||
[self createNobleLevelUpBannerAnimation:nobleModel];
|
||
}
|
||
[self.animationListB addObject:nobleModel];
|
||
}];
|
||
}
|
||
|
||
- (void)createNobleLevelUpBannerAnimation:(PIBaseAnimationViewModel *)model {
|
||
self.isPlayOfB = YES;
|
||
CGFloat top = (kNavigationHeight + 15);
|
||
XPRoomNobleLevelUpView *nobleLevelUpView = [[XPRoomNobleLevelUpView alloc] initWithFrame:CGRectMake(KScreenWidth, top, KScreenWidth, 90)];
|
||
nobleLevelUpView.nobleInfo = model.data;
|
||
[self.topContainer addSubview:nobleLevelUpView];
|
||
@kWeakify(self);
|
||
@kWeakify(nobleLevelUpView);
|
||
nobleLevelUpView.completionBlock = ^{
|
||
@kStrongify(self);
|
||
@kStrongify(nobleLevelUpView);
|
||
POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
springAnimation.springSpeed = 12;
|
||
springAnimation.springBounciness = 10.f;
|
||
springAnimation.fromValue = [NSValue valueWithCGPoint:nobleLevelUpView.center];
|
||
springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(nobleLevelUpView.frame.size.width / 2, nobleLevelUpView.center.y)];
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, nobleLevelUpView.center.y)];
|
||
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, nobleLevelUpView.center.y)];
|
||
moveAnimation.beginTime = CACurrentMediaTime() + 3;
|
||
moveAnimation.duration = 0.5;
|
||
moveAnimation.repeatCount = 1;
|
||
moveAnimation.removedOnCompletion = YES;
|
||
@kWeakify(self);
|
||
[moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
@kStrongify(self);
|
||
if (finished) {
|
||
self.isPlayOfB = NO;
|
||
[nobleLevelUpView removeFromSuperview];
|
||
if (self.animationListB.count > 0) {
|
||
[self.animationListB xpSafeRemoveObjectAtIndex:0];
|
||
}
|
||
[self playAnimationWithModel];
|
||
}
|
||
}];
|
||
[nobleLevelUpView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"];
|
||
});
|
||
[nobleLevelUpView pop_addAnimation:springAnimation forKey:@"nobleLevelUpspingOutAnimation"];
|
||
};
|
||
}
|
||
|
||
- (void)createAnchorHourRankAnimation:(PIBaseAnimationViewModel *)attachment {
|
||
self.isPlayOfB = YES;
|
||
CGFloat top = (kNavigationHeight + 15);
|
||
XPRoomAnchorRankBannerView *anchorRankView = [[XPRoomAnchorRankBannerView alloc] initWithFrame:CGRectMake(KScreenWidth,top, KScreenWidth, kGetScaleWidth(55))];
|
||
anchorRankView.anchorRankInfo = [RoomHalfHourRankModel modelWithDictionary:attachment.data];
|
||
anchorRankView.delegate = self;
|
||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gotoTopRankAnchorRoom:)];
|
||
[anchorRankView addGestureRecognizer:tap];
|
||
[self.topContainer addSubview:anchorRankView];
|
||
POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
springAnimation.springSpeed = 12;
|
||
springAnimation.springBounciness = 10.f;
|
||
springAnimation.fromValue = [NSValue valueWithCGPoint:anchorRankView.center];
|
||
springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(anchorRankView.frame.size.width / 2, anchorRankView.center.y)];
|
||
[springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
if (finished) {
|
||
POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, anchorRankView.center.y)];
|
||
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, anchorRankView.center.y)];
|
||
moveAnimation.beginTime = CACurrentMediaTime() + 3;
|
||
moveAnimation.duration = 0.5;
|
||
moveAnimation.repeatCount = 1;
|
||
moveAnimation.removedOnCompletion = YES;
|
||
[moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
[anchorRankView removeFromSuperview];
|
||
self.isPlayOfB = NO;
|
||
if(self.animationListB.count > 0){
|
||
[self.animationListB xpSafeRemoveObjectAtIndex:0];
|
||
[self playAnimationWithModel];
|
||
}
|
||
}];
|
||
[anchorRankView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"];
|
||
}
|
||
}];
|
||
[anchorRankView pop_addAnimation:springAnimation forKey:@"nobleLevelUpspingOutAnimation"];
|
||
}
|
||
|
||
- (void)gotoTopRankAnchorRoom:(UITapGestureRecognizer *)tap {
|
||
XPRoomAnchorRankBannerView * view = (XPRoomAnchorRankBannerView *)tap.view;
|
||
if (view.anchorRankInfo.uid.integerValue > 0) {
|
||
[self.hostDelegate exitRoom];
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
[XPRoomViewController openRoom:view.anchorRankInfo.uid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC];
|
||
});
|
||
}
|
||
}
|
||
|
||
- (void)receiveTreasureFairyGiftHighLevel:(AttachmentModel *)attatchment {
|
||
if ([self _isInSudGame]) {return;}
|
||
PIBaseAnimationViewModel *giftModel = [PIBaseAnimationViewModel new];
|
||
giftModel.data = attatchment.data;
|
||
giftModel.second = attatchment.second;
|
||
giftModel.first = attatchment.first;
|
||
giftModel.type = GiftBannerType_Fairy;
|
||
if (self.animationListB.count == 0 && self.isPlayOfB == NO) {
|
||
[self createTreasureFairyBannerAnimation:giftModel];
|
||
}
|
||
[self.animationListB addObject:giftModel];
|
||
}
|
||
|
||
- (void)createTreasureFairyBannerAnimation:(PIBaseAnimationViewModel *)attatchment {
|
||
self.isPlayOfB = YES;
|
||
CGFloat kscale = (CGFloat)60 / (CGFloat)375;
|
||
CGFloat top = (kNavigationHeight + 15);
|
||
XPTreasureFairyGiftView *treasureView = [[XPTreasureFairyGiftView alloc] initWithFrame:CGRectMake(KScreenWidth, top, KScreenWidth , KScreenWidth * kscale)];
|
||
//最大礼物
|
||
if ((attatchment.second == Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L5) || (attatchment.second == Custom_Message_Sub_Treasure_Fairy_Convert_L3)) {
|
||
treasureView.isMaxLargeGift = YES;
|
||
}else{
|
||
treasureView.isMaxLargeGift = NO;
|
||
}
|
||
if ((attatchment.second == Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L4) || (attatchment.second == Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L5)) {
|
||
treasureView.isDrawGift = YES; //抽奖
|
||
}else{
|
||
treasureView.isDrawGift = NO; //召唤
|
||
}
|
||
treasureView.treasureInfo = attatchment.data;
|
||
[self.middleContainer addSubview:treasureView];
|
||
POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
springAnimation.springSpeed = 12;
|
||
springAnimation.springBounciness = 10.f;
|
||
springAnimation.fromValue = [NSValue valueWithCGPoint:treasureView.center];
|
||
springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(treasureView.frame.size.width / 2, treasureView.center.y)];
|
||
[springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
if (finished) {
|
||
POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, treasureView.center.y)];
|
||
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, treasureView.center.y)];
|
||
moveAnimation.beginTime = CACurrentMediaTime() + 3;
|
||
moveAnimation.duration = 0.5;
|
||
moveAnimation.repeatCount = 1;
|
||
moveAnimation.removedOnCompletion = YES;
|
||
@kWeakify(self);
|
||
[moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
@kStrongify(self);
|
||
if (finished) {
|
||
[treasureView removeFromSuperview];
|
||
self.isPlayOfB = NO;
|
||
if (self.animationListB.count > 0) {
|
||
[self.animationListB xpSafeRemoveObjectAtIndex:0];
|
||
}
|
||
[self playAnimationWithModel];
|
||
}
|
||
}];
|
||
[treasureView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"];
|
||
}
|
||
}];
|
||
[treasureView pop_addAnimation:springAnimation forKey:@"candyTreespingOutAnimation"];
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
- (void)createGiftCompoundBannerAnimation:(PIBaseAnimationViewModel *)attachment {
|
||
self.isPlayOfB = YES;
|
||
XPRoomGiftCompoundView *compoundGiftView = [[XPRoomGiftCompoundView alloc] initWithFrame:CGRectMake(KScreenWidth, kNavigationHeight + 15, KScreenWidth, 45)];
|
||
compoundGiftView.compoundGiftInfo = attachment.data;
|
||
[self.middleContainer addSubview:compoundGiftView];
|
||
POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
springAnimation.springSpeed = 12;
|
||
springAnimation.springBounciness = 10.f;
|
||
springAnimation.fromValue = [NSValue valueWithCGPoint:compoundGiftView.center];
|
||
springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(compoundGiftView.frame.size.width / 2, compoundGiftView.center.y)];
|
||
[springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
if (finished) {
|
||
POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, compoundGiftView.center.y)];
|
||
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, compoundGiftView.center.y)];
|
||
moveAnimation.beginTime = CACurrentMediaTime() + 3;
|
||
moveAnimation.duration = 0.5;
|
||
moveAnimation.repeatCount = 1;
|
||
moveAnimation.removedOnCompletion = YES;
|
||
@kWeakify(self);
|
||
[moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
@kStrongify(self);
|
||
if (finished) {
|
||
[compoundGiftView removeFromSuperview];
|
||
self.isPlayOfB = NO;
|
||
if(self.animationListB.count > 0){
|
||
[self.animationListB xpSafeRemoveObjectAtIndex:0];
|
||
}
|
||
[self playAnimationWithModel];
|
||
}
|
||
}];
|
||
[compoundGiftView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"];
|
||
}
|
||
}];
|
||
[compoundGiftView pop_addAnimation:springAnimation forKey:@"compoundGiftSpingOutAnimation"];
|
||
}
|
||
|
||
- (void)createGeneralFloatingScreenAnimation:(PIBaseAnimationViewModel *)attachment bannerModel:(PIUniversalBannerModel *)model {
|
||
self.isPlayOfB = YES;
|
||
CGFloat top = (kNavigationHeight + 15);
|
||
|
||
if (!model) {
|
||
model = [PIUniversalBannerModel modelWithDictionary:attachment.data];
|
||
}
|
||
|
||
BOOL isSvga = [model.resourceType.uppercaseString isEqualToString:@"SVGA"];
|
||
__block PIUniversalBannerView *bannerView;
|
||
@kWeakify(self);
|
||
if (isSvga == YES) {
|
||
SVGAParser *parser = [SVGAParser new];
|
||
[parser parseWithURL:[NSURL URLWithString:model.resourceContent] completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) {
|
||
@kStrongify(self);
|
||
model.videoItem = videoItem;
|
||
CGFloat height = kGetScaleWidth(60);
|
||
if(videoItem.videoSize.width > 0){
|
||
height = KScreenWidth * videoItem.videoSize.height / videoItem.videoSize.width;
|
||
}
|
||
|
||
bannerView = [[PIUniversalBannerView alloc]initWithFrame:CGRectMake(KScreenWidth, top, KScreenWidth, height)];
|
||
[self showGeneralFloatingScreenView:bannerView model:model];
|
||
} failureBlock:^(NSError * _Nonnull error) {
|
||
@kStrongify(self);
|
||
[bannerView removeFromSuperview];
|
||
self.isPlayOfB = NO;
|
||
if(self.animationListB.count > 0){
|
||
[self.animationListB xpSafeRemoveObjectAtIndex:0];
|
||
}
|
||
[self playAnimationWithModel];
|
||
}];
|
||
}else{
|
||
if (!_imageLoader) {
|
||
_imageLoader = [[NetImageView alloc] init];
|
||
}
|
||
[self.imageLoader loadImageWithUrl:model.resourceContent
|
||
completion:^(UIImage * _Nonnull image, NSURL * _Nonnull url) {
|
||
@kStrongify(self);
|
||
model.image = image;
|
||
CGFloat width = image.size.width <= 0 ? kGetScaleWidth(60) : image.size.width;
|
||
CGFloat height = image.size.height ;
|
||
CGFloat getHeight = KScreenWidth * height / width;
|
||
if (getHeight > 100) {
|
||
getHeight = 100;
|
||
}
|
||
bannerView = [[PIUniversalBannerView alloc]initWithFrame:CGRectMake(KScreenWidth, top, KScreenWidth, getHeight) ];
|
||
[self showGeneralFloatingScreenView:bannerView model:model];
|
||
|
||
}
|
||
fail:^(NSError * _Nonnull error) {
|
||
@kStrongify(self);
|
||
[bannerView removeFromSuperview];
|
||
self.isPlayOfB = NO;
|
||
if(self.animationListB.count > 0){
|
||
[self.animationListB xpSafeRemoveObjectAtIndex:0];
|
||
}
|
||
[self playAnimationWithModel];
|
||
}];
|
||
}
|
||
}
|
||
|
||
-(void)showGeneralFloatingScreenView:(PIUniversalBannerView *)bannerView model:(PIUniversalBannerModel *)model{
|
||
BOOL isSvga = [model.resourceType isEqualToString:@"SVGA"];
|
||
bannerView.isSvga = isSvga;
|
||
bannerView.delegate = self;
|
||
if (!_universalBannerViewCaches) {
|
||
_universalBannerViewCaches = @[].mutableCopy;
|
||
}
|
||
[self.universalBannerViewCaches addObject:bannerView];
|
||
@kWeakify(bannerView);
|
||
@kWeakify(self);
|
||
[bannerView setAllowToPlay:^{
|
||
@kStrongify(self);
|
||
@kStrongify(bannerView);
|
||
[self.topContainer addSubview:bannerView];
|
||
POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
springAnimation.springSpeed = 12;
|
||
springAnimation.springBounciness = 10.f;
|
||
springAnimation.fromValue = [NSValue valueWithCGPoint:bannerView.center];
|
||
springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(bannerView.frame.size.width / 2, bannerView.center.y)];
|
||
@kWeakify(self);
|
||
[springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
if (finished) {
|
||
POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, bannerView.center.y)];
|
||
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, bannerView.center.y)];
|
||
moveAnimation.beginTime = CACurrentMediaTime() + 5;
|
||
moveAnimation.duration = 0.5;
|
||
moveAnimation.repeatCount = 1;
|
||
moveAnimation.removedOnCompletion = YES;
|
||
|
||
[moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
@kStrongify(self);
|
||
if (finished) {
|
||
[bannerView removeFromSuperview];
|
||
[self.universalBannerViewCaches removeObject:bannerView];
|
||
self.isPlayOfB = NO;
|
||
if(self.animationListB.count > 0){
|
||
[self.animationListB xpSafeRemoveObjectAtIndex:0];
|
||
}
|
||
[self playAnimationWithModel];
|
||
}
|
||
}];
|
||
[bannerView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"];
|
||
}
|
||
}];
|
||
[bannerView pop_addAnimation:springAnimation forKey:@"starKitchenOutAnimation"];
|
||
}];
|
||
|
||
bannerView.model = model;
|
||
}
|
||
|
||
- (void)roomDatingPublicResult:(AttachmentModel *)attachment {
|
||
self.datingEffectQueue = [NSMutableArray array];
|
||
///心动结果公布的话 结果是一个数组
|
||
NSArray * results = [DatingInfoModel modelsWithArray:attachment.data[@"list"]];
|
||
[self.datingEffectQueue addObjectsFromArray:results];
|
||
if (self.datingEffectQueue.count > 0) {
|
||
[self startDatingAnimation:self.datingEffectQueue.firstObject];
|
||
}
|
||
}
|
||
|
||
- (void)startDatingAnimation:(DatingInfoModel *)datingModel {
|
||
[[NSNotificationCenter defaultCenter] postNotificationName:@"message" object:[self createRoomDatingResultMessage:datingModel]];
|
||
NSString * targetUid= [NSString stringWithFormat:@"%ld", datingModel.targetUid];
|
||
NSString * uid= [NSString stringWithFormat:@"%ld", datingModel.uid];
|
||
if (datingModel.hasHeart || datingModel.hasSelectUser) {
|
||
datingModel.originPoint = [self.hostDelegate animationPointAtStageViewByUid:uid];
|
||
datingModel.targetPoint = [self.hostDelegate animationPointAtStageViewByUid:targetUid];
|
||
}
|
||
XPRoomDatingAnimationView *datingView = [[XPRoomDatingAnimationView alloc] init];
|
||
[self.topContainer addSubview:datingView];
|
||
[datingView startAnimationWithModel:datingModel finishBlock:^(BOOL finish) {
|
||
[datingView removeFromSuperview];
|
||
[self.datingEffectQueue removeObject:datingModel];
|
||
if (self.datingEffectQueue.count > 0) {
|
||
DatingInfoModel * datingModel = [self.datingEffectQueue firstObject];
|
||
[self startDatingAnimation:datingModel];
|
||
}
|
||
}];
|
||
}
|
||
|
||
- (NIMMessage *)createRoomDatingResultMessage:(DatingInfoModel *)datingModel {
|
||
NIMMessage * message = [[NIMMessage alloc] init];
|
||
NIMSession * session = [NIMSession session:[NSString stringWithFormat:@"%ld", self.hostDelegate.getRoomInfo.roomId] type:NIMSessionTypeChatroom];
|
||
[message setValue:session forKey:@"session"];
|
||
AttachmentModel * attach = [[AttachmentModel alloc] init];
|
||
attach.first = CustomMessageType_RoomPlay_Dating;
|
||
if (datingModel.hasHeart) {///如果是互选的话
|
||
attach.second = Custom_Message_Sub_Room_Play_Dating_Result_Mutual;
|
||
} else {
|
||
attach.second = Custom_Message_Sub_Room_Play_Dating_Result_Not_Mutual;
|
||
}
|
||
attach.data = [datingModel model2dictionary];
|
||
NIMCustomObject * object = [[NIMCustomObject alloc] init];
|
||
object.attachment = attach;
|
||
message.messageObject = object;
|
||
return message;
|
||
}
|
||
|
||
- (void)acrossRoomPKBannerAnimation:(AttachmentModel *)attacment {
|
||
AcrossRoomPKPrizeModel * prizeModel = [AcrossRoomPKPrizeModel modelWithJSON:attacment.data];
|
||
if (attacment.second == Custom_Message_Sub_AnchorPK_Result) {
|
||
prizeModel.pkType = 1;
|
||
} else {
|
||
prizeModel.pkType = 0;
|
||
}
|
||
[self.acrossRoomPKQueue addObject:prizeModel];
|
||
if (self.acrossRoomPKQueue.count == 1 ) {//判断为1个时开始播放,防止多条消息回来后重叠播放
|
||
[self startAcrossRoomPKAnimation:self.acrossRoomPKQueue.firstObject];
|
||
}
|
||
}
|
||
|
||
- (void)startAcrossRoomPKAnimation:(AcrossRoomPKPrizeModel *)model {
|
||
XPAcrossRoomPKPrizeView *wishEffectView = [[XPAcrossRoomPKPrizeView alloc] initWithFrame:CGRectMake(KScreenWidth, kNavigationHeight+40, KScreenWidth, 87)];
|
||
wishEffectView.data = model;
|
||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gotoPkWinRoom:)];
|
||
[wishEffectView addGestureRecognizer:tap];
|
||
[self.topContainer addSubview:wishEffectView];
|
||
[UIView animateWithDuration:0.5 animations:^{
|
||
wishEffectView.frame = CGRectMake(0, kNavigationHeight+40, KScreenWidth, 87);
|
||
} completion:^(BOOL finished) {
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
[UIView animateWithDuration:0.5 animations:^{
|
||
wishEffectView.hidden = YES;
|
||
} completion:^(BOOL finished) {
|
||
[wishEffectView removeFromSuperview];
|
||
[self.acrossRoomPKQueue removeObject:model];
|
||
if (self.acrossRoomPKQueue.count > 0) {
|
||
[self startAcrossRoomPKAnimation:self.acrossRoomPKQueue.firstObject];
|
||
}
|
||
}];
|
||
});
|
||
}];
|
||
}
|
||
|
||
- (void)gotoPkWinRoom:(UITapGestureRecognizer *)tap {
|
||
XPAcrossRoomPKPrizeView * view = (XPAcrossRoomPKPrizeView *)tap.view;
|
||
if (view.data.winUid.length > 0) {
|
||
[self.hostDelegate exitRoom];
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
[XPRoomViewController openRoom:view.data.winUid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC];
|
||
});
|
||
}
|
||
}
|
||
|
||
- (void)receiveFansTeamGiftHandleSendGiftAnimation:(AttachmentModel *)attachment {
|
||
if ([self _isInSudGame]) {return;}
|
||
if (!self.hostDelegate.getRoomInfo.hasAnimationEffect) {return;}
|
||
GiftReceiveInfoModel *receiveInfo = [[GiftReceiveInfoModel alloc] init];
|
||
GiftInfoModel *gift = [GiftInfoModel modelWithJSON:attachment.data[@"giftVo"]];
|
||
receiveInfo.gift = gift;
|
||
receiveInfo.giftInfo = gift;
|
||
receiveInfo.targetUid = [NSString stringWithFormat:@"%ld", self.hostDelegate.getRoomInfo.uid];
|
||
GiftInfoModel * giftInfo = receiveInfo.gift ? receiveInfo.gift : receiveInfo.giftInfo;
|
||
if (attachment.second == Custom_Message_Sub_AllMicroLuckySend || attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend || attachment.second == Custom_Message_Sub_Gift_LuckySend) {
|
||
NSString * giftId = [NSString stringWithFormat:@"%ld", receiveInfo.luckyGiftList.giftList.firstObject.giftId];
|
||
giftInfo = [[XPGiftStorage shareStorage] findGiftInfo:giftId inRoom:@(receiveInfo.roomUid).stringValue];
|
||
}
|
||
if (giftInfo == nil) {
|
||
giftInfo = [[XPGiftStorage shareStorage] findGiftInfo:receiveInfo.giftId inRoom:@(receiveInfo.roomUid).stringValue];
|
||
}
|
||
|
||
///在最外面判断是否可以拿到那个礼物 后面使用就不用判断了
|
||
receiveInfo.gift = giftInfo;
|
||
receiveInfo.isLuckyBagGift = (attachment.second == Custom_Message_Sub_AllMicroLuckySend || attachment.second == Custom_Message_Sub_AllBatchMicroLuckySend || attachment.second == Custom_Message_Sub_Gift_LuckySend);
|
||
[self.giftAnimationManager enqueueGift:receiveInfo];
|
||
}
|
||
|
||
- (void)receiveAnchorHourRank:(AttachmentModel *)attachment {
|
||
PIBaseAnimationViewModel *anchorModel =[PIBaseAnimationViewModel new];
|
||
anchorModel.data = attachment.data;
|
||
anchorModel.type = GiftBannerType_AnchorHour;
|
||
if(self.animationListB.count == 0 && self.isPlayOfB == NO){
|
||
[self createAnchorHourRankAnimation:anchorModel];
|
||
}
|
||
[self.animationListB addObject:anchorModel];
|
||
}
|
||
|
||
- (void)receiveGiftCompound:(AttachmentModel *)attachment {
|
||
if ([self _isInSudGame]) {return;}
|
||
PIBaseAnimationViewModel *magicModel =[PIBaseAnimationViewModel new];
|
||
magicModel.data = attachment.data;
|
||
magicModel.type = GiftBannerType_Magic_House;
|
||
if(self.animationListB.count == 0 && self.isPlayOfB == NO){
|
||
[self createGiftCompoundBannerAnimation:magicModel];
|
||
}
|
||
[self.animationListB addObject:magicModel];
|
||
}
|
||
|
||
- (void)receiveRoomSailing:(AttachmentModel *)attachment {
|
||
if ([self _isInSudGame]) {return;}
|
||
if (self.sailingQueue.count == 0) {
|
||
[self createSailingBannerAnimation:attachment];
|
||
}
|
||
[self.sailingQueue addObject:attachment];
|
||
}
|
||
|
||
- (void)createSailingBannerAnimation:(AttachmentModel *)attatchment {
|
||
CGFloat kscale = (CGFloat)60 / (CGFloat)375;
|
||
XPSailingAnimationView *sailingView = [[XPSailingAnimationView alloc] initWithFrame:CGRectMake(KScreenWidth, kNavigationHeight + 15, KScreenWidth, KScreenWidth * kscale)];
|
||
sailingView.prizeInfo = attatchment.data;
|
||
[self.middleContainer addSubview:sailingView];
|
||
POPSpringAnimation *springAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
springAnimation.springSpeed = 12;
|
||
springAnimation.springBounciness = 10.f;
|
||
springAnimation.fromValue = [NSValue valueWithCGPoint:sailingView.center];
|
||
springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(sailingView.frame.size.width / 2, sailingView.center.y)];
|
||
[springAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
if (finished) {
|
||
POPBasicAnimation *moveAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
|
||
moveAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, sailingView.center.y)];
|
||
moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(-KScreenWidth/2, sailingView.center.y)];
|
||
moveAnimation.beginTime = CACurrentMediaTime() + 3;
|
||
moveAnimation.duration = 0.5;
|
||
moveAnimation.repeatCount = 1;
|
||
moveAnimation.removedOnCompletion = YES;
|
||
@kWeakify(self);
|
||
[moveAnimation setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
|
||
@kStrongify(self);
|
||
if (finished) {
|
||
[sailingView removeFromSuperview];
|
||
if (self.sailingQueue.count > 0) {
|
||
[self.sailingQueue xpSafeRemoveObjectAtIndex:0];
|
||
}
|
||
if (self.sailingQueue.count > 0) {
|
||
[self createSailingBannerAnimation:self.sailingQueue.firstObject];
|
||
}
|
||
}
|
||
}];
|
||
[sailingView pop_addAnimation:moveAnimation forKey:@"moveOutAnimation"];
|
||
}
|
||
}];
|
||
[sailingView pop_addAnimation:springAnimation forKey:@"candyTreespingOutAnimation"];
|
||
}
|
||
|
||
- (void)receiveRoomGraffitiGift:(AttachmentModel *)attachment {
|
||
if (self.graffitiGiftQueue.count == 0) {
|
||
[self startGraffitiGiftAnimation:attachment];
|
||
}
|
||
[self.graffitiGiftQueue addObject:attachment];
|
||
}
|
||
|
||
- (void)startGraffitiGiftAnimation:(AttachmentModel *)model {
|
||
NSDictionary * dic = model.data;
|
||
NSNumber * giftId = dic[@"giftId"];
|
||
GiftInfoModel * giftInfo = [[XPGiftStorage shareStorage] findGiftInfo:giftId.stringValue inRoom:@""];
|
||
NSArray * array = dic[@"drawFixedArray"];
|
||
if (giftInfo.giftUrl.length > 0 && array.count > 0) {
|
||
[[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:giftInfo.giftUrl] options:SDWebImageProgressiveLoad progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
|
||
if (error == nil && image) {
|
||
XPRoomGraffitiGiftAnimationView *graffitiView = [[XPRoomGraffitiGiftAnimationView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
|
||
graffitiView.giftImage = image;
|
||
graffitiView.delegate = self;
|
||
graffitiView.model = model;
|
||
graffitiView.pointArray = array;
|
||
[graffitiView beginDrawAnimation];
|
||
[self.topContainer addSubview:graffitiView];
|
||
} else {
|
||
[self.graffitiGiftQueue removeObject:model];
|
||
if (self.graffitiGiftQueue.count > 0) {
|
||
[self startGraffitiGiftAnimation:self.graffitiGiftQueue.firstObject];
|
||
}
|
||
}
|
||
}];
|
||
} else {
|
||
[self.graffitiGiftQueue removeObject:model];
|
||
if (self.graffitiGiftQueue.count > 0) {
|
||
[self startGraffitiGiftAnimation:self.graffitiGiftQueue.firstObject];
|
||
}
|
||
}
|
||
}
|
||
|
||
- (void)playLuckyGiftEffectWithVapUrl:(NSString *)vapUrl {
|
||
NSString *encodingUrl = [vapUrl pureURLString];
|
||
encodingUrl = [encodingUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
|
||
NSString *fileName = [[encodingUrl componentsSeparatedByString:@"/"] lastObject];
|
||
NSString *fullPath = [self.GiftDynamicEffectListPath stringByAppendingPathComponent:fileName];
|
||
|
||
if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath]){
|
||
vapUrl = fullPath;
|
||
[self _addSubviewToMiddleContainer:self.luckyVapGiftEffectView];
|
||
[self.luckyVapGiftEffectView setMute:NO];
|
||
[self.luckyVapGiftEffectView playHWDMP4:vapUrl repeatCount:1 delegate:self];
|
||
} else {
|
||
@kWeakify(self);
|
||
[self.vapParser parseWithURL:encodingUrl completionBlock:^(NSString * _Nullable videoUrl) {
|
||
@kStrongify(self);
|
||
if (videoUrl.length) {
|
||
[self _addSubviewToMiddleContainer:self.luckyVapGiftEffectView];
|
||
[self.luckyVapGiftEffectView setMute:NO];
|
||
[self.luckyVapGiftEffectView playHWDMP4:videoUrl repeatCount:1 delegate:self];
|
||
}
|
||
} failureBlock:^(NSError * _Nullable error) {
|
||
self.luckyVapGiftEffectView.hidden = YES;
|
||
}];
|
||
}
|
||
}
|
||
|
||
-(void)playAnimationWithModel{
|
||
if(self.animationListB.count <= 0){
|
||
return;
|
||
}
|
||
|
||
if(self.isPlayOfB == YES) {
|
||
return;
|
||
}
|
||
|
||
PIBaseAnimationViewModel *model = self.animationListB.firstObject;
|
||
switch (model.type) {
|
||
case GiftBannerType_Lucky:
|
||
[self createBigPrizeAnimation:model];
|
||
break;
|
||
case GiftBannerType_Love:
|
||
[self createCandyTreeBannerAnimation:model];
|
||
break;
|
||
case GiftBannerType_Nobleman:
|
||
[self createNobleLevelUpBannerAnimation:model];
|
||
break;
|
||
case GiftBannerType_AnchorHour:
|
||
[self createAnchorHourRankAnimation:model];
|
||
break;
|
||
case GiftBannerType_LicneseHour:
|
||
[self createAnchorHourRankAnimation:model];
|
||
break;
|
||
case GiftBannerType_Fairy:
|
||
[self createTreasureFairyBannerAnimation:model];
|
||
break;
|
||
case GiftBannerType_Magic_House:
|
||
[self createGiftCompoundBannerAnimation:model];
|
||
break;
|
||
case GiftBannerType_General_Floating_Screen:
|
||
[self createGeneralFloatingScreenAnimation:model bannerModel:nil];
|
||
break;
|
||
default:
|
||
// 其他未处理的枚举值类型
|
||
// 可能包括但不限于:GiftBannerType_Unknown, GiftBannerType_Normal,
|
||
// GiftBannerType_Special, GiftBannerType_Event 等
|
||
break;
|
||
}
|
||
}
|
||
|
||
- (SVGAImageView *)luckyGiftEffectView {
|
||
if (!_luckyGiftEffectView) {
|
||
_luckyGiftEffectView = [[SVGAImageView alloc]init];
|
||
_luckyGiftEffectView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
|
||
_luckyGiftEffectView.userInteractionEnabled = NO;
|
||
_luckyGiftEffectView.delegate = self;
|
||
_luckyGiftEffectView.hidden = YES;
|
||
}
|
||
return _luckyGiftEffectView;
|
||
}
|
||
|
||
- (VAPView *)luckyVapGiftEffectView {
|
||
if (!_luckyVapGiftEffectView) {
|
||
_luckyVapGiftEffectView = [[VAPView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
|
||
_luckyVapGiftEffectView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
|
||
_luckyVapGiftEffectView.contentMode = UIViewContentModeScaleAspectFill;
|
||
_luckyVapGiftEffectView.hidden = YES;
|
||
}
|
||
return _luckyVapGiftEffectView;
|
||
}
|
||
|
||
#pragma mark - Old Methods Delegate: XPRoomGiftBroadcastViewDelegate
|
||
- (void)xPRoomGiftBroadcastView:(XPRoomGiftBroadcastView *)view enterRoom:(NSString *)roomUid roomName:(NSString *)roomName{
|
||
id isShowBroadcastView = [[NSUserDefaults standardUserDefaults]valueForKey:@"kSaveBrooadcastSelectState"];
|
||
if(isShowBroadcastView == nil){
|
||
PIRoomGiftBroadcastWindow *broadcastView = [[PIRoomGiftBroadcastWindow alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
|
||
broadcastView.roodUid = roomUid;
|
||
broadcastView.roomName = roomName;
|
||
broadcastView.delegate = self;
|
||
[kWindow addSubview:broadcastView];
|
||
return;
|
||
}
|
||
|
||
if (roomUid.length > 0 && self.hostDelegate.getRoomInfo.uid != roomUid.integerValue) {
|
||
[self.hostDelegate exitRoom];
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.7 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
[XPRoomViewController openRoom:roomUid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC];
|
||
});
|
||
}
|
||
}
|
||
|
||
- (void)xPRoomLuckyBigPrizeView:(XPRoomLuckyBigPrizeView *)view luckyGiftInfo:(PIBaseAnimationViewModel *)giftInfo {
|
||
id isShowBroadcastView = [[NSUserDefaults standardUserDefaults]valueForKey:@"kSaveLuckSelectState"];
|
||
if(isShowBroadcastView == nil){
|
||
PIRoomGiftBroadcastWindow *broadcastView = [[PIRoomGiftBroadcastWindow alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
|
||
broadcastView.isLuck = YES;
|
||
broadcastView.roodUid = giftInfo.roomUid;
|
||
broadcastView.roomName = giftInfo.roomTitle;
|
||
broadcastView.delegate = self;
|
||
[kWindow addSubview:broadcastView];
|
||
return;
|
||
}
|
||
if (!giftInfo.isInRoomVisable && giftInfo.roomUid.length > 0 && giftInfo.roomUid.integerValue != self.hostDelegate.getRoomInfo.uid) {
|
||
[self.hostDelegate exitRoom];
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
[XPRoomViewController openRoom:giftInfo.roomUid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC];
|
||
});
|
||
}
|
||
}
|
||
|
||
|
||
|
||
- (void)xPRoomAnchorRankBannerView:(XPRoomAnchorRankBannerView *)view rankInfo:(RoomHalfHourRankModel *)rankInfo{
|
||
if (rankInfo.uid.integerValue > 0 && self.hostDelegate.getRoomInfo.uid != rankInfo.uid.integerValue) {
|
||
[self.hostDelegate exitRoom];
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
[XPRoomViewController openRoom:rankInfo.uid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC];
|
||
});
|
||
}
|
||
}
|
||
|
||
-(void)confirmLeaveForTheRoom:(NSString *_Nonnull)roomUid{
|
||
if (roomUid.length > 0 && self.hostDelegate.getRoomInfo.uid != roomUid.integerValue) {
|
||
[self.hostDelegate exitRoom];
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.7 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
[XPRoomViewController openRoom:roomUid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC];
|
||
});
|
||
}
|
||
}
|
||
|
||
- (void)pIUniversalBannerView:(PIUniversalBannerView *)view didClick:(PIUniversalBannerModel *)model{
|
||
if (model.skipType == 2){
|
||
[self.hostDelegate exitRoom];
|
||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||
[XPRoomViewController openRoom:model.skipContent viewController:[XCCurrentVCStackManager shareManager].getCurrentVC];
|
||
});
|
||
}else if (model.skipType == 3){
|
||
XPWebViewController * webVC = [[XPWebViewController alloc] initWithRoomUID:nil];
|
||
webVC.isPush = YES;
|
||
webVC.url = model.skipContent;
|
||
[self.hostDelegate.getCurrentNav pushViewController:webVC animated:YES];
|
||
}
|
||
}
|
||
|
||
- (void)xPRoomGraffitiGiftAnimationViewCompletion:(XPRoomGraffitiGiftAnimationView *)view attachment:(nonnull AttachmentModel *)attachment{
|
||
[view removeFromSuperview];
|
||
if ([self.graffitiGiftQueue containsObject:attachment]) {
|
||
[self.graffitiGiftQueue removeObject:attachment];
|
||
}
|
||
if (self.graffitiGiftQueue.count > 0) {
|
||
[self startGraffitiGiftAnimation:self.graffitiGiftQueue.firstObject];
|
||
}
|
||
}
|
||
|
||
@end
|