// // XPRoomViewController.m // xplan-ios // // Created by 冯硕 on 2021/10/11. // #import "XPRoomViewController.h" ///Third #import #import ///Tool #import "XPMacro.h" #import "XPConstant.h" #import "AccountInfoStorage.h" #import "RtcManager.h" #import "XPRoomMiniManager.h" #import "TTPopup.h" #import "Api+ArrangeMic.h" #import "Api+Room.h" #import "DESEncrypt.h" ///Model #import "RoomInfoModel.h" #import "UserInfoModel.h" #import "AttachmentModel.h" #import "ArrangeMicModel.h" #import "XPReleaseRadioModel.h" #import "XPNobleTrumpetModel.h" #import "GuildSuperAdminInfoModel.h" #import "XPKickUserModel.h" #import "ContentLevelUpgradeModel.h" #import "XPReceiveRedPacketModel.h" #import "XPRedPacketModel.h" ///View #import "BaseNavigationController.h" #import "XPRoomActivityContainerView.h" #import "XPRoomBackContainerView.h" #import "XPRoomMenuContainerView.h" #import "XPRoomMessageContainerView.h" #import "RoomHeaderView.h" #import "SocialStageView.h" #import "DatingStageView.h" #import "AnchorStageView.h" #import "LittleGameStageView.h" #import "AnchorPkStageView.h" #import "LittleGameScrollStageView.h" #import "XPRoomAnimationView.h" #import "XPRoomFunctionContainerView.h" #import "XPArrangeMicViewController.h" #import "XPRoomSettingInputView.h" #import "XPRoomLittleGameContainerView.h" #import "AnchorRoomScrollView.h" #import "AnchorRoomSrollTipView.h" #import "XPReceiveRedPacketView.h" ///P #import "XPRoomPresenter.h" #import "XPRoomProtocol.h" #import "RoomHostDelegate.h" #import "RoomGuestDelegate.h" #import "XCHUDTool.h" UIKIT_EXTERN NSString * const kRoomGiftEffectUpdateNotificationKey; UIKIT_EXTERN NSString * const kRoomMiniNotificationKey; UIKIT_EXTERN NSString * kNewUserRechargeKey; NSString * const kHadShowAnchorRoomTipKey = @"kHadShowAnchorRoomTipKey";//是否展示过个播房上划用户引导 NSString * const kHadQuitOtherRoomKey = @"kHadQuitOtherRoomKey";//是否退出过非自己房间 @interface XPRoomViewController () ///背景 @property (nonatomic,strong) XPRoomBackContainerView *backContainerView; ///个播上下切换view @property (nonatomic, strong) AnchorRoomScrollView *anchorScrollView; ///房间信息 @property (nonatomic,strong) RoomHeaderView *roomHeaderView; ///坑位信息 @property (nonatomic,strong) StageView *stageView; ///公屏 @property (nonatomic,strong) XPRoomMessageContainerView *messageContainerView; ///底部操作栏 @property (nonatomic,strong) XPRoomMenuContainerView *menuContainerView; ///活动 @property (nonatomic,strong) XPRoomActivityContainerView *activityContainerView; ///动画的view @property (nonatomic,strong) XPRoomAnimationView *animationView; ///功能view的的容器 @property (nonatomic,strong) XPRoomFunctionContainerView *functionView; ///小游戏的容器 @property (nonatomic,strong) XPRoomLittleGameContainerView *littleGameView; ///房间的Uid @property (nonatomic,copy) NSString * roomUid; ///小游戏的id @property (nonatomic,copy) NSString *mgId; ///礼物id @property (nonatomic, copy) NSString *giftId; ///用户信息 @property (nonatomic,strong) UserInfoModel *userInfo; ///房间信息 @property (nonatomic,strong) RoomInfoModel *roomInfo; ///本地是否修改过礼物特效显示 当前房间如果设置过礼物特效是否显示的话 就不再跟随房间礼物特效的更新而更新 @property (nonatomic,assign) BOOL hasAnimationEffect; ///跟随的 @property (nonatomic,copy) NSString *fromNick; @property (nonatomic,assign) UserEnterRoomFromType fromType; @property (nonatomic,copy) NSString *fromUid; ///超管列表 @property (nonatomic,strong) NSArray *superMangerList; ///是否请求过了超管 @property (nonatomic,assign) BOOL isRequestSuperAdmin; ///是否是最小化进房 @property (nonatomic,assign) BOOL isMiniEnter; ///个播上划引导 @property (nonatomic, strong) AnchorRoomSrollTipView *anchorScrollTipView; ///滚动过的个播列表 @property (nonatomic,strong) NSMutableArray *anchorRoomList; ///序号 @property (nonatomic,assign) NSInteger anchorIndex; @end @implementation XPRoomViewController + (BOOL)openRoom:(NSString *)roomUid viewController:(UIViewController *)viewController { return [self openRoom:roomUid fromNick:nil fromType:0 fromUid:nil viewController:viewController]; } + (BOOL) openRoom:(NSString*)roomUid fromNick:(NSString * __nullable)fromNick fromType:(UserEnterRoomFromType)fromType fromUid:(NSString * __nullable)fromUid viewController:(UIViewController*)viewController { XPRoomViewController * roomVC = [[self alloc] init]; roomVC.roomUid = roomUid; roomVC.fromUid = fromUid; roomVC.fromType = fromType; roomVC.fromNick = fromNick; BaseNavigationController * baseNav = [[BaseNavigationController alloc] initWithRootViewController:roomVC]; baseNav.modalPresentationStyle = UIModalPresentationFullScreen; [viewController presentViewController:baseNav animated:YES completion:nil]; return YES; } /**最小化进房 * @params roomUid 房主uid * @params viewController 启动方 */ + (BOOL)openMiniRoom:(NSString*)roomUid viewController:(UIViewController*)viewController { XPRoomViewController * roomVC = [[self alloc] init]; roomVC.roomUid = roomUid; roomVC.isMiniEnter = YES; BaseNavigationController * baseNav = [[BaseNavigationController alloc] initWithRootViewController:roomVC]; baseNav.modalPresentationStyle = UIModalPresentationFullScreen; [viewController presentViewController:baseNav animated:YES completion:nil]; return roomVC; } /** XPRoomViewController 不允许外部 init ,请通过该方法启动房间。 * @params roomUid 房主uid * @params viewController 启动方 * @params mgId 小游戏的id */ + (BOOL)openRoom:(NSString*)roomUid mgId:(NSString *)mgId viewController:(UIViewController*)viewController { XPRoomViewController * roomVC = [[self alloc] init]; roomVC.roomUid = roomUid; roomVC.mgId = mgId; BaseNavigationController * baseNav = [[BaseNavigationController alloc] initWithRootViewController:roomVC]; baseNav.modalPresentationStyle = UIModalPresentationFullScreen; [viewController presentViewController:baseNav animated:YES completion:nil]; return YES; } /// h5进房并弹出礼物面板 /// @param roomUid 房主Uid /// @param giftId 礼物id /// @param viewController 启动方 + (BOOL)openRoom:(NSString *)roomUid giftId:(NSString *)giftId viewController:(UIViewController *)viewController { XPRoomViewController * roomVC = [[self alloc] init]; roomVC.roomUid = roomUid; roomVC.giftId = giftId; BaseNavigationController * baseNav = [[BaseNavigationController alloc] initWithRootViewController:roomVC]; baseNav.modalPresentationStyle = UIModalPresentationFullScreen; [viewController presentViewController:baseNav animated:YES completion:nil]; return YES; } - (void)dealloc { #warning to dox - 时刻注意这个方法 功能做完的时候删除此方法 NSLog(@"房间销毁了"); [[NIMSDK sharedSDK].chatroomManager removeDelegate:self]; [[NIMSDK sharedSDK].chatManager removeDelegate:self]; [[NIMSDK sharedSDK].loginManager removeDelegate:self]; [[NIMSDK sharedSDK].conversationManager removeDelegate:self]; [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (XPRoomPresenter *)createPresenter { return [[XPRoomPresenter alloc] init]; } - (BOOL)isHiddenNavBar { return YES; } - (void)viewDidLoad { [super viewDidLoad]; [self exitOldRoom]; [self initSubViews]; [self initSubViewConstraints]; if (self.isMiniEnter) { [self initEnterRoomSuccess:[XPRoomMiniManager shareManager].getRoomInfo user:[XPRoomMiniManager shareManager].getUserInfo]; } else { [XCHUDTool showAnchorLoading:self.navigationController.view]; [self.presenter initEnterRoom:self.roomUid user:[AccountInfoStorage instance].getUid]; } /// 公屏 福袋礼物爆出的礼物 需要依赖 当前房间中的礼物列表 需要提前获取礼物列表 可以拿到礼物 没有想到别的方法去解决这个问题 有需要改的在修改吧 [self.presenter getNormalGiftList:self.roomUid]; ///获取房间超管列表 [self.presenter getRoomSuperAdmin:self.roomUid]; //监听云信消息x [[NIMSDK sharedSDK].chatroomManager addDelegate:self]; [[NIMSDK sharedSDK].chatManager addDelegate:self]; [[NIMSDK sharedSDK].loginManager addDelegate:self]; [[NIMSDK sharedSDK].conversationManager addDelegate:self]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myGiftEffectUpdate:) name:kRoomGiftEffectUpdateNotificationKey object:nil]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self.menuContainerView menuResignFirstResponder]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; } #pragma mark - Private Method - (void)initSubViews { [self.view addSubview:self.backContainerView]; [self.view addSubview:self.littleGameView]; [self.view addSubview:self.stageView]; [self.view addSubview:self.messageContainerView]; [self.view addSubview:self.menuContainerView]; [self.view addSubview:self.activityContainerView]; [self.view addSubview:self.roomHeaderView]; [self.view addSubview:self.functionView]; [self.view addSubview:self.animationView]; } - (void)initSubViewConstraints { [self.backContainerView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self.view); }]; [self.roomHeaderView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.top.mas_equalTo(self.view); make.height.mas_equalTo(kNavigationHeight); }]; [self.stageView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(self.view); make.top.mas_equalTo(self.roomHeaderView.mas_bottom); make.height.mas_equalTo(self.stageView.hightForStageView); }]; [self.messageContainerView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.stageView.mas_bottom); make.bottom.equalTo(self.menuContainerView.mas_top).offset(-5); make.left.equalTo(self.view); make.right.equalTo(self.activityContainerView.mas_left).offset(-10); }]; [self.menuContainerView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(self.view); make.bottom.mas_equalTo(-kSafeAreaBottomHeight- 8); make.height.mas_equalTo(40); }]; [self.activityContainerView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.messageContainerView); make.right.mas_equalTo(self.view); make.bottom.mas_equalTo(self.menuContainerView.mas_top).offset(-5); make.width.mas_equalTo(80); }]; [self.animationView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self.view); }]; [self.functionView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self.view); }]; [self.littleGameView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self.view); }]; } - (void)updateViewConstraintsOnAnchorRoom { [self.anchorScrollView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self.view); }]; [self.backContainerView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self.anchorScrollView.middleImageView); }]; [self.roomHeaderView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.top.mas_equalTo(self.anchorScrollView.middleImageView); make.height.mas_equalTo(kNavigationHeight); }]; [self.stageView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(self.anchorScrollView.middleImageView); make.top.mas_equalTo(self.roomHeaderView.mas_bottom); make.height.mas_equalTo(self.stageView.hightForStageView); }]; [self.messageContainerView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.stageView.mas_bottom); make.bottom.mas_equalTo(self.backContainerView).mas_offset(-5-40-8-kSafeAreaBottomHeight); make.left.equalTo(self.anchorScrollView.middleImageView); make.right.equalTo(self.activityContainerView.mas_left).offset(-10); }]; [self.menuContainerView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(self.anchorScrollView.middleImageView); make.bottom.mas_equalTo(self.anchorScrollView.middleImageView).offset(-kSafeAreaBottomHeight- 8); make.height.mas_equalTo(40); }]; [self.activityContainerView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.messageContainerView); make.right.mas_equalTo(self.anchorScrollView.middleImageView); make.bottom.mas_equalTo(self.backContainerView).mas_offset(-5-40-8-kSafeAreaBottomHeight); make.width.mas_equalTo(80); }]; [self.functionView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self.anchorScrollView.middleImageView); }]; } - (void)exitOldRoom { NSString * roomUid = [NSString stringWithFormat:@"%ld", [XPRoomMiniManager shareManager].getRoomInfo.uid]; if (roomUid.integerValue > 0 && roomUid.integerValue != self.roomUid.integerValue) { //有最小化房间 并且要进入的房间和最小化的房间不一样的话 就先退掉 最小化的房间 NSString * roomId = [NSString stringWithFormat:@"%ld", [XPRoomMiniManager shareManager].getRoomInfo.roomId]; [self.presenter exitNIMRoom:roomId]; [[RtcManager instance] exitRoom]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [self.presenter reportUserOutRoom:roomUid]; } } - (void)userEnterRoomSuccess { AttachmentModel *attachment = [[AttachmentModel alloc]init]; attachment.first = CustomMessageType_Car_Notify; attachment.second = Custom_Message_Sub_Car_EnterRoom; NSMutableDictionary *att = [NSMutableDictionary dictionary]; if (self.userInfo.userVipInfoVO.enterHide) {///贵族隐身进房,不发座驾消息 return; } if (self.userInfo.viewUrl.length > 0) { [att setValue:self.userInfo.nick forKey:@"nick"]; [att setValue:self.userInfo.viewUrl forKey:@"viewUrl"]; [att setValue:@(self.userInfo.otherViewType) forKey:@"otherViewType"]; } else if (self.userInfo.carEffect.length > 0) { [att setValue:self.userInfo.carEffect forKey:@"effect"]; [att setValue:self.userInfo.nick forKey:@"nick"]; } else { return; } attachment.data = att; NSString *sessionID = [NSString stringWithFormat:@"%ld",self.roomInfo.roomId]; NIMMessage *message = [[NIMMessage alloc]init]; NIMCustomObject *object = [[NIMCustomObject alloc] init]; object.attachment = attachment; message.messageObject = object; //构造会话 NIMSession *session = [NIMSession session:sessionID type:NIMSessionTypeChatroom]; [[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil]; } - (void)changeStageViewOnRoomUpdate { if (self.roomInfo.roomModeType == RoomModeType_Open_Blind && ![self.stageView isKindOfClass:[DatingStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[DatingStageView alloc] initWithDelegate:self]; } else if(self.roomInfo.datingState == RoomDatingStateChangeType_Close && ![self.stageView isKindOfClass:[SocialStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[SocialStageView alloc] initWithDelegate:self]; } else if (self.roomInfo.type == RoomType_Anchor) { if (self.roomInfo.roomModeType == RoomModeType_Open_AcrossRoomPK_mode && ![self.stageView isKindOfClass:[AnchorPKStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[AnchorPKStageView alloc] initWithDelegate:self]; } else if(self.roomInfo.roomModeType == RoomModeType_Normal_Mode && ![self.stageView isKindOfClass:[AnchorStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[AnchorStageView alloc] initWithDelegate:self]; } } else if(self.roomInfo.type == RoomType_MiniGame) { if (self.roomInfo.mgMicNum > 6 && ![self.stageView isKindOfClass:[LittleGameScrollStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[LittleGameScrollStageView alloc] initWithDelegate:self]; } else if (self.roomInfo.mgMicNum <= 6 && ![self.stageView isKindOfClass:[LittleGameStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[LittleGameStageView alloc] initWithDelegate:self]; } }else if(self.roomInfo.hadChangeRoomType && ![self.stageView isKindOfClass:[SocialStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[SocialStageView alloc] initWithDelegate:self]; } else { return; } if (!self.stageView.superview) { [self.view insertSubview:self.stageView belowSubview:self.roomHeaderView]; } if (self.roomInfo.type == RoomType_MiniGame) { [self.stageView mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(self.view); make.top.mas_equalTo(self.roomHeaderView.mas_bottom).offset(26 + 4); make.height.mas_equalTo(self.stageView.hightForStageView); }]; [self.messageContainerView mas_remakeConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo(70); make.bottom.mas_equalTo(self.menuContainerView.mas_top).offset(-5); make.left.mas_equalTo(self.view); make.right.mas_equalTo(self.activityContainerView.mas_left).offset(-10); }]; [self.activityContainerView mas_remakeConstraints:^(MASConstraintMaker *make) { make.height.mas_equalTo(65); make.right.mas_equalTo(self.view); make.bottom.mas_equalTo(self.menuContainerView.mas_top).offset(-5); make.width.mas_equalTo(80); }]; } else { [self.stageView mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(self.view); make.top.mas_equalTo(self.roomHeaderView.mas_bottom); make.height.mas_equalTo(self.stageView.hightForStageView); }]; [self.messageContainerView mas_remakeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.stageView.mas_bottom); make.bottom.mas_equalTo(self.menuContainerView.mas_top).offset(-5); make.left.mas_equalTo(self.view); make.right.mas_equalTo(self.activityContainerView.mas_left).offset(-10); }]; [self.activityContainerView mas_remakeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.messageContainerView); make.right.mas_equalTo(self.view); make.bottom.mas_equalTo(self.menuContainerView.mas_top).offset(-5); make.width.mas_equalTo(80); }]; } } - (void)changeStageViewOnAnchorRoom { if (self.roomInfo.roomModeType == RoomModeType_Open_AcrossRoomPK_mode && ![self.stageView isKindOfClass:[AnchorPKStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[AnchorPKStageView alloc] initWithDelegate:self]; } else if(self.roomInfo.roomModeType == RoomModeType_Normal_Mode && ![self.stageView isKindOfClass:[AnchorStageView class]]) { [self.stageView removeFromSuperview]; self.stageView = nil; self.stageView = [[AnchorStageView alloc] initWithDelegate:self]; } if (!self.stageView.superview) { [self.anchorScrollView insertSubview:self.stageView belowSubview:self.roomHeaderView]; } [self.stageView mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(self.anchorScrollView.middleImageView); make.top.mas_equalTo(self.roomHeaderView.mas_bottom); make.height.mas_equalTo(self.stageView.hightForStageView); }]; [self.messageContainerView mas_remakeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.stageView.mas_bottom); make.bottom.mas_equalTo(self.backContainerView).mas_offset(-5-40-8-kSafeAreaBottomHeight); make.left.mas_equalTo(self.anchorScrollView.middleImageView); make.right.mas_equalTo(self.activityContainerView.mas_left).offset(-10); }]; [self.activityContainerView mas_remakeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.messageContainerView); make.right.mas_equalTo(self.anchorScrollView.middleImageView); make.bottom.mas_equalTo(self.backContainerView).mas_offset(-5-40-8-kSafeAreaBottomHeight); make.width.mas_equalTo(80); }]; } - (void)cancelRoomArrangeMic { ///退出排麦 if (self.roomInfo.roomModeType == RoomModeType_Open_Micro_Mode || self.roomInfo.roomModeType == RoomModeType_Open_Blind) { NSString * roomUid = [NSString stringWithFormat:@"%ld", self.roomInfo.uid]; NSString * uid = [AccountInfoStorage instance].getUid; [Api getRoomArrangeMicList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { if (code == 200) { ArrangeMicModel * arrangeMicModel= [ArrangeMicModel modelWithJSON:data.data]; if (arrangeMicModel.myPos.intValue > 0) { __block NSString * grouptype = @"0"; if (self.roomInfo.roomModeType == RoomModeType_Open_Blind) { [arrangeMicModel.queue enumerateObjectsUsingBlock:^(ArrangeMicUserModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if (obj.uid.integerValue == [AccountInfoStorage instance].getUid.integerValue) { grouptype = [NSString stringWithFormat:@"%ld", obj.groupType]; *stop = YES; } }]; } [Api cancelArrangeMic:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {} roomUid:roomUid operUid:uid groupType:grouptype]; } } } roomUid:roomUid operUid:uid page:@"1" pageSize:@"50"]; }else if(self.roomInfo.roomModeType == RoomModeType_Open_PK_Mode) { NSString * roomUid = [NSString stringWithFormat:@"%ld", self.roomInfo.uid]; NSString * uid = [AccountInfoStorage instance].getUid; [Api getRoomPKUserList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { if (code == 200) { ArrangeMicModel * arrangeMicModel= [ArrangeMicModel modelWithJSON:data.data]; if (arrangeMicModel.myPos.intValue > 0) { __block NSString * grouptype = @"0"; [arrangeMicModel.queue enumerateObjectsUsingBlock:^(ArrangeMicUserModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if (obj.uid.integerValue == [AccountInfoStorage instance].getUid.integerValue) { grouptype = [NSString stringWithFormat:@"%ld", obj.groupType]; *stop = YES; } }]; [Api cancelRoomPKArrangeMic:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { } roomUid:roomUid operUid:uid groupType:grouptype]; } } } roomUid:roomUid operUid:uid page:@"1" pageSize:@"50"]; } } ///超管进入密码房间 - (void)superAdminEnterPwdRoom:(RoomInfoModel *)roomInfo { __block BOOL isSuperAdmin = NO; [self.superMangerList enumerateObjectsUsingBlock:^(GuildSuperAdminInfoModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj.uid isEqualToString:[AccountInfoStorage instance].getUid]) { isSuperAdmin = YES; *stop = YES; } }]; if (!isSuperAdmin) { XPRoomSettingInputView * titleView = [[XPRoomSettingInputView alloc] init]; titleView.maxCount = 15; titleView.delegate = self; titleView.type = RoomSettingInputType_Input_Pwd; TTPopupConfig * config = [[TTPopupConfig alloc] init]; config.contentView = titleView; config.maskBackgroundAlpha = 1; config.shouldDismissOnBackgroundTouch = NO; [TTPopup popupWithConfig:config]; } else { self.roomInfo.datingState = roomInfo.roomModeType == RoomModeType_Open_Blind ? RoomDatingStateChangeType_Open : RoomDatingStateChangeType_Normal; [self changeStageViewOnRoomUpdate]; [self.roomHeaderView onRoomEntered]; [self.activityContainerView onRoomEntered]; [self.menuContainerView onRoomEntered]; [self.backContainerView onRoomEntered]; [self.littleGameView onRoomEntered]; if ([XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {// 最小化进房 还是原来的房间的话 不需要重新进入云信 因为压根没退 [self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo]; [self.functionView onRoomEntered]; [self.messageContainerView onRoomEntered]; } else { //虽然没退出房间 但是队列还是要拿的 [self.stageView onRoomMiniEntered]; [self.messageContainerView onRoomMiniEntered]; [self.functionView onRoomMiniEntered]; [self.functionView onRoomEntered]; } [[XPRoomMiniManager shareManager] configRoomInfo:nil]; [[XPRoomMiniManager shareManager] configUserInfo:nil]; [[XPRoomMiniManager shareManager] configCurrentMusic:nil isPlaying:NO]; } } ///超管进个播有密码房间 - (void)handleSuperManagerEnterAnchorRoom:(RoomInfoModel *)roomInfo { __block BOOL isSuperAdmin = NO; [self.superMangerList enumerateObjectsUsingBlock:^(GuildSuperAdminInfoModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj.uid isEqualToString:[AccountInfoStorage instance].getUid]) { isSuperAdmin = YES; *stop = YES; } }]; if (!isSuperAdmin) { XPRoomSettingInputView * titleView = [[XPRoomSettingInputView alloc] init]; titleView.maxCount = 15; titleView.delegate = self; titleView.type = RoomSettingInputType_Input_Pwd; TTPopupConfig * config = [[TTPopupConfig alloc] init]; config.contentView = titleView; config.maskBackgroundAlpha = 1; config.shouldDismissOnBackgroundTouch = NO; [TTPopup popupWithConfig:config]; } else { self.roomInfo.datingState = roomInfo.roomModeType == RoomModeType_Open_Blind ? RoomDatingStateChangeType_Open : RoomDatingStateChangeType_Normal; if (!self.anchorScrollView.superview) { [self.view insertSubview:self.anchorScrollView belowSubview:self.menuContainerView]; } [self.backContainerView removeFromSuperview]; [self.stageView removeFromSuperview]; [self.messageContainerView removeFromSuperview]; [self.activityContainerView removeFromSuperview]; [self.roomHeaderView removeFromSuperview]; [self.functionView removeFromSuperview]; [self.anchorScrollView addSubview:self.backContainerView]; [self.anchorScrollView addSubview:self.stageView]; [self.anchorScrollView addSubview:self.messageContainerView]; [self.anchorScrollView addSubview:self.activityContainerView]; [self.anchorScrollView addSubview:self.roomHeaderView]; [self.anchorScrollView addSubview:self.functionView]; if (!self.menuContainerView.superview) { [self.view addSubview:self.menuContainerView]; } [self.view bringSubviewToFront:self.animationView]; [self updateViewConstraintsOnAnchorRoom]; [self changeStageViewOnAnchorRoom]; [self.roomHeaderView onRoomEntered]; [self.activityContainerView onRoomEntered]; [self.menuContainerView onRoomEntered]; [self.backContainerView onRoomEntered]; [self.littleGameView onRoomEntered]; if ([XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {// 最小化进房 还是原来的房间的话 不需要重新进入云信 因为压根没退 [self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo]; [self.functionView onRoomEntered]; [self.messageContainerView onRoomEntered]; } else { //虽然没退出房间 但是队列还是要拿的 [self.stageView onRoomMiniEntered]; [self.messageContainerView onRoomMiniEntered]; [self.functionView onRoomMiniEntered]; [self.functionView onRoomEntered]; } [[XPRoomMiniManager shareManager] configRoomInfo:nil]; [[XPRoomMiniManager shareManager] configUserInfo:nil]; [[XPRoomMiniManager shareManager] configCurrentMusic:nil isPlaying:NO]; } } ///展示个播上划引导 - (void)showAnchorScrollTipView { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *anchoScrollTip = [defaults objectForKey:kHadShowAnchorRoomTipKey]; if (!anchoScrollTip) { UIWindow *window = [UIApplication sharedApplication].delegate.window; [window addSubview:self.anchorScrollTipView]; [window bringSubviewToFront:self.anchorScrollTipView]; } } #pragma mark - 本地礼物特效更新 - (void)myGiftEffectUpdate:(NSNotification *)notification { NSDictionary * dic = notification.object; self.roomInfo.hasAnimationEffect = ((NSNumber *)dic[@"hasAnimationEffect"]).boolValue; self.hasAnimationEffect = self.roomInfo.hasAnimationEffect; [self.roomHeaderView onRoomUpdate]; } #pragma mark - XPRoomProtocol - (void)initEnterRoomSuccess:(RoomInfoModel *)roomInfo user:(UserInfoModel *)userInfo { [self hideHUD]; userInfo.fromUid = self.fromUid; userInfo.fromType = self.fromType; userInfo.fromNick = self.fromNick; self.hasAnimationEffect = roomInfo.hasAnimationEffect; self.roomInfo = roomInfo; self.userInfo = userInfo; if (roomInfo.type == RoomType_Anchor) {//个播房,获取下一个房间 [self handleInitAnchorRoom]; [self showAnchorScrollTipView]; return; } if (roomInfo.valid) { // 房间有效,直接进入房间 if (roomInfo.roomPwd.length > 0 && roomInfo.uid != [AccountInfoStorage instance].getUid.integerValue && [XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {//进房密码的情况 if (!self.isRequestSuperAdmin) { [Api getRoomSuperAdminList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { NSArray * array = [GuildSuperAdminInfoModel modelsWithArray:data.data]; self.superMangerList = array; [self superAdminEnterPwdRoom:roomInfo]; } roomUid:self.roomUid]; } else { [self superAdminEnterPwdRoom:roomInfo]; } } else { self.roomInfo.datingState = roomInfo.roomModeType == RoomModeType_Open_Blind ? RoomDatingStateChangeType_Open : RoomDatingStateChangeType_Normal; [self changeStageViewOnRoomUpdate]; [self.roomHeaderView onRoomEntered]; [self.activityContainerView onRoomEntered]; [self.menuContainerView onRoomEntered]; [self.backContainerView onRoomEntered]; [self.littleGameView onRoomEntered]; if ([XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {// 最小化进房 还是原来的房间的话 不需要重新进入云信 因为压根没退 [self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo]; [self.functionView onRoomEntered]; [self.messageContainerView onRoomEntered]; } else { //虽然没退出房间 但是队列还是要拿的 [self.stageView onRoomMiniEntered]; [self.messageContainerView onRoomMiniEntered]; [self.functionView onRoomMiniEntered]; [self.functionView onRoomEntered]; } [[XPRoomMiniManager shareManager] configRoomInfo:nil]; [[XPRoomMiniManager shareManager] configUserInfo:nil]; [[XPRoomMiniManager shareManager] configCurrentMusic:nil isPlaying:NO]; } } else { // 房间无效,分是否为自己房间进行处理 if ([self.roomUid isEqualToString:[NSString stringWithFormat:@"%ld", userInfo.uid]]) { // 当前用户进入自己房间 if (roomInfo.roomId > 0) { // 存在房间信息,直接使用房间信息开房 if (roomInfo.type == RoomType_MiniGame && roomInfo.mgId > 0) { self.mgId = [NSString stringWithFormat:@"%lld", roomInfo.mgId]; } [self.presenter openRoom:roomInfo.title type:roomInfo.type roomPwd:roomInfo.roomPwd roomDesc:roomInfo.roomDesc backPic:@"" mgId:self.mgId]; } else { // 不存在房间信息,全新开房 NSString* title = [NSString stringWithFormat:@"%@的房间", userInfo.nick]; RoomType type = RoomType_Game; if (self.mgId.length > 0) { type = RoomType_MiniGame; } [self.presenter openRoom:title type:type roomPwd:@"" roomDesc:@"" backPic:@"" mgId:self.mgId]; } } else { // 当前用户进入别人房间 // TODO: 房主已经下线。 [self showSuccessToast:@"房主已下线"]; [self enterRoomFail:0]; } } } - (void)openRoomSuccess:(RoomInfoModel *)roomInfo { [XCHUDTool hideHUDInView:self.navigationController.view]; [self hideHUD]; self.roomInfo = roomInfo; if (roomInfo.type == RoomType_Anchor) { [self handleInitAnchorRoom]; [self showAnchorScrollTipView]; return; } [self changeStageViewOnRoomUpdate]; [self.roomHeaderView onRoomEntered]; [self.activityContainerView onRoomEntered]; [self.backContainerView onRoomEntered]; [self.littleGameView onRoomEntered]; [self.functionView onRoomEntered]; [self.messageContainerView onRoomEntered]; [self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo]; } - (void)enterRoomSuccess:(NIMChatroom *)chatRoom { [XCHUDTool hideHUDInView:self.navigationController.view]; // room/get中的房间在线人数 是定时更新的 不是及时刷新 self.roomInfo.onlineNum = chatRoom.onlineUserCount; [self.stageView onRoomEntered]; [self.functionView onRoomEntered]; //上报进房 if (self.roomInfo != nil) { [self.presenter reportUserInterRoom:[NSString stringWithFormat:@"%zd", self.roomInfo.uid]]; } if (self.giftId.length) { [[NSNotificationCenter defaultCenter] postNotificationName:@"kShowGiftView" object:@{@"giftId": self.giftId}]; } //获取一下红包信息 [self.presenter getRedPacket:[NSString stringWithFormat:@"%ld", self.roomInfo.uid]]; } - (void)enterRoomFail:(NSInteger)code { [XCHUDTool hideHUDInView:self.navigationController.view]; [self hideHUD]; if (code == 13003) { [self showErrorToast:@"您已被管理员拉黑"]; } [self dismissViewControllerAnimated:YES completion:nil]; } ///请求房间超管成功 ///这个接口本来是想和roominfo 和userinfo 一起请求的 但是 进房的同步操作 只有超管进入密码房间才会有同步的问题 - (void)getRoomSuperAdminScuccess:(NSArray *)list { self.isRequestSuperAdmin = YES; self.superMangerList = list; } ///获取推荐滚动的个播房列表(只有第一次进房获取) - (void)getNextAnchorRoomSuccess:(RoomInfoModel *)roomInfo { [self hideHUD]; if (roomInfo) { //获取下一个房间成功 if (![self.anchorRoomList containsObject:self.roomUid]) { [self.anchorRoomList addObject:self.roomUid]; } self.anchorIndex = self.anchorRoomList.count -1; //1、退出房间操作 self.anchorScrollView.isCanScrollTop = YES; self.anchorScrollView.contentOffset = CGPointMake(0, KScreenHeight); self.isRequestSuperAdmin = NO; [self exitOldRoom]; [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [[RtcManager instance] exitRoom]; [self.presenter reportUserOutRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.uid]]; [self.functionView onRoomChange]; //2、移除房间子控件 [self.stageView removeFromSuperview]; [self.messageContainerView removeFromSuperview]; [self.activityContainerView removeFromSuperview]; [self.roomHeaderView removeFromSuperview]; [self.functionView removeFromSuperview]; self.functionView = nil; self.messageContainerView = nil; self.stageView = nil; [self.menuContainerView removeFromSuperview]; self.menuContainerView = nil; //3、重新进入房间 self.roomUid = [NSString stringWithFormat:@"%zd", roomInfo.uid]; [self.presenter initEnterRoom:self.roomUid user:[AccountInfoStorage instance].getUid]; /// 公屏 福袋礼物爆出的礼物 需要依赖 当前房间中的礼物列表 需要提前获取礼物列表 可以拿到礼物 没有想到别的方法去解决这个问题 有需要改的在修改吧 [self.presenter getNormalGiftList:self.roomUid]; ///获取房间超管列表 [self.presenter getRoomSuperAdmin:self.roomUid]; } else { if (self.anchorScrollView.isCanScrollTop) { self.anchorScrollView.contentOffset = CGPointMake(0, KScreenHeight); } else { self.anchorScrollView.contentOffset = CGPointMake(0, 0); } [self showErrorToast:@"已经到底啦~自动为您返回当前房间"]; } } - (void)getCurrentRoomInfoSuccess:(RoomInfoModel *)roomInfo { [self hideHUD]; self.anchorScrollView.contentOffset = CGPointMake(0, KScreenHeight); if (roomInfo && roomInfo.valid) { //1、退出房间操作 self.isRequestSuperAdmin = NO; [self exitOldRoom]; [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [[RtcManager instance] exitRoom]; [self.presenter reportUserOutRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.uid]]; //2、移除房间子控件 [self.backContainerView removeFromSuperview]; [self.stageView removeFromSuperview]; [self.messageContainerView removeFromSuperview]; [self.activityContainerView removeFromSuperview]; [self.roomHeaderView removeFromSuperview]; [self.functionView removeFromSuperview]; self.functionView = nil; self.messageContainerView = nil; self.stageView = nil; [self.menuContainerView removeFromSuperview]; self.menuContainerView = nil; //3、重新进入房间 self.roomUid = [NSString stringWithFormat:@"%zd", roomInfo.uid]; [self.presenter initEnterRoom:self.roomUid user:[AccountInfoStorage instance].getUid]; /// 公屏 福袋礼物爆出的礼物 需要依赖 当前房间中的礼物列表 需要提前获取礼物列表 可以拿到礼物 没有想到别的方法去解决这个问题 有需要改的在修改吧 [self.presenter getNormalGiftList:self.roomUid]; ///获取房间超管列表 [self.presenter getRoomSuperAdmin:self.roomUid]; } else { [self showErrorToast:@"已经到顶啦~自动为您返回当前房间"]; } } ///个播房初始化一些操作 - (void)handleInitAnchorRoom { if (self.roomInfo.valid) { // 房间有效,直接进入房间 if (self.roomInfo.roomPwd.length > 0 && self.roomInfo.uid != [AccountInfoStorage instance].getUid.integerValue && [XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {//进房密码的情况 if (!self.isRequestSuperAdmin) { [Api getRoomSuperAdminList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { NSArray * array = [GuildSuperAdminInfoModel modelsWithArray:data.data]; self.superMangerList = array; [self handleSuperManagerEnterAnchorRoom:self.roomInfo]; } roomUid:self.roomUid]; } else { [self handleSuperManagerEnterAnchorRoom:self.roomInfo]; } } else { self.roomInfo.datingState = self.roomInfo.roomModeType == RoomModeType_Open_Blind ? RoomDatingStateChangeType_Open : RoomDatingStateChangeType_Normal; if (!self.anchorScrollView.superview) { [self.view addSubview:self.anchorScrollView]; } [self.backContainerView removeFromSuperview]; [self.stageView removeFromSuperview]; [self.messageContainerView removeFromSuperview]; [self.activityContainerView removeFromSuperview]; [self.roomHeaderView removeFromSuperview]; [self.functionView removeFromSuperview]; [self.menuContainerView removeFromSuperview]; [self.anchorScrollView addSubview:self.backContainerView]; [self.anchorScrollView addSubview:self.stageView]; [self.anchorScrollView addSubview:self.messageContainerView]; [self.anchorScrollView addSubview:self.activityContainerView]; [self.anchorScrollView addSubview:self.roomHeaderView]; [self.anchorScrollView addSubview:self.functionView]; [self.anchorScrollView addSubview:self.menuContainerView]; [self.view bringSubviewToFront:self.animationView]; [self updateViewConstraintsOnAnchorRoom]; [self changeStageViewOnAnchorRoom]; [self.roomHeaderView onRoomEntered]; [self.activityContainerView onRoomEntered]; [self.menuContainerView onRoomEntered]; [self.backContainerView onRoomEntered]; [self.littleGameView onRoomEntered]; if ([XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {// 最小化进房 还是原来的房间的话 不需要重新进入云信 因为压根没退 [self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo]; [self.functionView onRoomEntered]; [self.messageContainerView onRoomEntered]; } else { //虽然没退出房间 但是队列还是要拿的 [self.stageView onRoomMiniEntered]; [self.messageContainerView onRoomMiniEntered]; [self.functionView onRoomMiniEntered]; [self.functionView onRoomEntered]; } [[XPRoomMiniManager shareManager] configRoomInfo:nil]; [[XPRoomMiniManager shareManager] configUserInfo:nil]; [[XPRoomMiniManager shareManager] configCurrentMusic:nil isPlaying:NO]; } } else { // 房间无效,分是否为自己房间进行处理 if ([self.roomUid isEqualToString:[NSString stringWithFormat:@"%ld", self.userInfo.uid]]) { // 当前用户进入自己房间 if (self.roomInfo.roomId > 0) { // 存在房间信息,直接使用房间信息开房 if (self.roomInfo.type == RoomType_MiniGame && self.roomInfo.mgId > 0) { self.mgId = [NSString stringWithFormat:@"%lld", self.roomInfo.mgId]; } [self.presenter openRoom:self.roomInfo.title type:self.roomInfo.type roomPwd:self.roomInfo.roomPwd roomDesc:self.roomInfo.roomDesc backPic:@"" mgId:self.mgId]; } else { // 不存在房间信息,全新开房 NSString* title = [NSString stringWithFormat:@"%@的房间", self.userInfo.nick]; RoomType type = RoomType_Game; if (self.mgId.length > 0) { type = RoomType_MiniGame; } [self.presenter openRoom:title type:type roomPwd:@"" roomDesc:@"" backPic:@"" mgId:self.mgId]; } } else { // 当前用户进入别人房间 // TODO: 房主已经下线。 [self showSuccessToast:@"房主已下线"]; [self enterRoomFail:0]; } } } - (void)getRedPacketSuccess:(NSArray *)list { if (list.count == 0) { return; } for (XPRedPacketModel *data in list) { XPReceiveRedPacketView *view = [[XPReceiveRedPacketView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)]; view.receiveModel = data; [self.view addSubview:view]; [self.view bringSubviewToFront:view]; } } #pragma mark - NIMChatroomManagerDelegate - (void)chatroomBeKicked:(NIMChatroomBeKickedResult *)result { if (result.reason == 2) { [self showErrorToast:@"您被管理员踢出直播间"]; } else if (result.reason == 5) { [self showErrorToast:@"您已被管理员拉黑"]; } [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [self cancelRoomArrangeMic]; [[RtcManager instance] exitRoom]; [self.presenter reportUserOutRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.uid]]; [self.littleGameView handleSelfInExitEvent]; [self.littleGameView destroyMG]; [self dismissViewControllerAnimated:YES completion:nil]; } #pragma mark - NIMChatManagerDelegate - (void)onRecvMessages:(NSArray *)messages { for (NIMMessage * message in messages) { ///房间内收到p2p的消息 比如升级消息 if (message.session.sessionType == NIMSessionTypeP2P) { if(message.messageType == NIMMessageTypeCustom) { NIMCustomObject *obj = (NIMCustomObject *)message.messageObject; if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) { AttachmentModel * attachment = obj.attachment; if (attachment.first == CustomMessageType_User_UpGrade) { ContentLevelUpgradeModel * levelInfo = [ContentLevelUpgradeModel modelWithDictionary:attachment.data]; if (attachment.second == Custom_Message_Sub_User_UpGrade_Exper) { self.userInfo.userLevelVo.experLevelSeq = levelInfo.levelSeq; } else if(attachment.second == Custom_Message_Sub_User_UpGrade_Charm) { self.userInfo.userLevelVo.charmLevelSeq = levelInfo.levelSeq; } } } } } // 非房间内消息不处理 if (message.session.sessionType != NIMSessionTypeChatroom) { continue; } // 非本房间不处理 if (![message.session.sessionId isEqualToString:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]) { continue; } if (message.messageType == NIMMessageTypeNotification) { NIMNotificationObject *notiMsg = (NIMNotificationObject *)message.messageObject; NIMChatroomNotificationContent *content = (NIMChatroomNotificationContent *)notiMsg.content; NSInteger onLineNumber = self.roomInfo.onlineNum; switch (content.eventType) { case NIMChatroomEventTypeInfoUpdated: // 麦序状态更新 { NSDictionary *data = [content.notifyExt toJSONObject]; int type = [data[@"type"] intValue]; switch (type) { case 1: case 3: { NSMutableDictionary *lastRoomInfoDic = [NSMutableDictionary dictionaryWithDictionary:[self.roomInfo model2dictionary]]; [lastRoomInfoDic addEntriesFromDictionary: ((NSString *)data[@"roomInfo"]).toJSONObject]; RoomInfoModel *newRoomInfo = [RoomInfoModel modelWithJSON:lastRoomInfoDic]; //TODO: 从小游戏房间切换到普通房间的话 mgid不会被清除掉 if (newRoomInfo.type != RoomType_MiniGame) { newRoomInfo.mgId = 0; } newRoomInfo.hasAnimationEffect = self.hasAnimationEffect; if (newRoomInfo.roomModeType == RoomModeType_Open_Blind && self.roomInfo.roomModeType != RoomModeType_Open_Blind) { ///普通房 切换为相亲房 newRoomInfo.datingState = RoomDatingStateChangeType_Open; } else if(newRoomInfo.roomModeType != RoomModeType_Open_Blind && self.roomInfo.roomModeType == RoomModeType_Open_Blind) { ///关闭了相亲房 newRoomInfo.datingState = RoomDatingStateChangeType_Close; } else { newRoomInfo.datingState = RoomDatingStateChangeType_Normal; } //房间类型是否变更了(从个播->普通,个播->小游戏等) newRoomInfo.hadChangeRoomType = self.roomInfo.type != newRoomInfo.type; BOOL anchorToOther = newRoomInfo.type != RoomType_Anchor && self.roomInfo.type == RoomType_Anchor;//个播变其他房 self.roomInfo = newRoomInfo; [self.backContainerView onRoomUpdate]; if (self.roomInfo.type == RoomType_Anchor && self.roomInfo.hadChangeRoomType) {///从其他房变为个播房 [self handleInitAnchorRoom]; [self showAnchorScrollTipView]; } else if (anchorToOther) { [self.anchorScrollView removeFromSuperview]; [self.backContainerView removeFromSuperview]; [self.stageView removeFromSuperview]; [self.messageContainerView removeFromSuperview]; [self.activityContainerView removeFromSuperview]; [self.roomHeaderView removeFromSuperview]; [self.functionView removeFromSuperview]; [self.view addSubview:self.backContainerView]; [self.view addSubview:self.stageView]; [self.view addSubview:self.messageContainerView]; [self.view addSubview:self.activityContainerView]; [self.view addSubview:self.roomHeaderView]; [self.view addSubview:self.functionView]; [self.view bringSubviewToFront:self.menuContainerView]; [self.view bringSubviewToFront:self.animationView]; [self initSubViewConstraints]; [self changeStageViewOnRoomUpdate]; [self.stageView onRoomUpdate]; [self.menuContainerView onRoomUpdate]; [self.functionView onRoomUpdate]; [self.activityContainerView onRoomUpdate]; [self.messageContainerView onRoomUpdate]; [self.littleGameView onRoomUpdate]; } else { if (self.roomInfo.type == RoomType_Anchor) { [self changeStageViewOnAnchorRoom]; } else { [self changeStageViewOnRoomUpdate]; } [self.stageView onRoomUpdate]; [self.menuContainerView onRoomUpdate]; [self.functionView onRoomUpdate]; [self.activityContainerView onRoomUpdate]; [self.messageContainerView onRoomUpdate]; [self.littleGameView onRoomUpdate]; } } break; } } break; case NIMChatroomEventTypeEnter: if (content.source.userId.integerValue != [AccountInfoStorage instance].getUid.integerValue && self.userInfo.platformRole != 1) { onLineNumber += 1; }else {///如果是自己的话 如果有坐骑的话 [self userEnterRoomSuccess]; ///在活动页面 判断是否显示 相亲加入的按钮 所以需要等用户进房成功之后才能获取 房间角色 [self.activityContainerView onRoomUpdate]; [self.menuContainerView onRoomUpdate]; } break; case NIMChatroomEventTypeAddBlack: case NIMChatroomEventTypeKicked: case NIMChatroomEventTypeExit: onLineNumber -= 1; break; case NIMChatroomEventTypeQueueChange: // 麦序上下麦 { NSDictionary* data = (NSDictionary *)content.ext; UserInfoModel* userInfo = [UserInfoModel modelWithJSON:[data objectForKey:NIMChatroomEventInfoQueueChangeItemValueKey]]; NSInteger changeType = [data[NIMChatroomEventInfoQueueChangeTypeKey] integerValue]; if (changeType == 1 && userInfo.uid == [AccountInfoStorage instance].getUid.integerValue) { [self cancelRoomArrangeMic]; } } break; default: break; } self.roomInfo.onlineNum = onLineNumber; [self.roomHeaderView onRoomUpdate]; [self.stageView handleNIMNotificationMessage:message]; [self.animationView handleNIMNotificationMessage:message]; [self.messageContainerView handleNIMNotificationMessage:message]; [self.activityContainerView handleNIMNotificationMessage:message]; [self.menuContainerView handleNIMNotificationMessage:message]; [self.functionView handleNIMNotificationMessage:message]; [self.littleGameView handleNIMNotificationMessage:message]; } else if (message.messageType == NIMMessageTypeCustom) { NIMCustomObject *obj = (NIMCustomObject *)message.messageObject; if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) { AttachmentModel * attachment = obj.attachment; [self.stageView handleNIMCustomMessage:message]; [self.animationView handleNIMCustomMessage:message]; [self.menuContainerView handleNIMCustomMessage:message]; [self.activityContainerView handleNIMCustomMessage:message]; [self.functionView handleNIMCustomMessage:message]; [self.littleGameView handleNIMCustomMessage:message]; if (attachment.first == CustomMessageType_First_Recharge_Reward && attachment.second == Custom_Message_Sub_Room_First_Recharge_Reward) { self.userInfo.isFirstCharge = NO; [self.menuContainerView onRoomUpdate]; [self.activityContainerView onRoomUpdate]; } else if (attachment.first == CustomMessageType_Update_RoomInfo && attachment.second == Custom_Message_Sub_Update_RoomInfo_MessageState) { ///兼容安卓和iOS 协议不同的问题 NSDictionary * dic= attachment.data[@"roomInfo"]; if (dic.allKeys.count <=0) { dic = attachment.data; } RoomInfoModel * roomInfo = [RoomInfoModel modelWithDictionary:dic]; self.roomInfo.isCloseScreen = roomInfo.isCloseScreen; [self.menuContainerView onRoomUpdate]; } else if(attachment.first == CustomMessageType_Queue && attachment.second == Custom_Message_Sub_Queue_Invite) { NSDictionary *dic = attachment.data; NSString *uid = dic[@"uid"]; if (uid.integerValue == [AccountInfoStorage instance].getUid.integerValue) { [self cancelRoomArrangeMic]; } } else if(attachment.first == CustomMessageType_Hall_Super_Admin && attachment.second == Custom_Message_Sub_Hall_Super_Admin_Kick_Manager_Out_Room) { XPKickUserModel * userInfo = [XPKickUserModel modelWithJSON:attachment.data]; if (userInfo.targetUid == [AccountInfoStorage instance].getUid.integerValue) { [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [self cancelRoomArrangeMic]; [[RtcManager instance] exitRoom]; [self.presenter reportUserOutRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.uid]]; [self.littleGameView handleSelfInExitEvent]; [self.littleGameView destroyMG]; [self dismissViewControllerAnimated:YES completion:nil]; } } else if (attachment.first == CustomMessageType_RedPacket) { if (attachment.second == Custom_Message_Sub_RoomDiamandRedPacket) { XPReceiveRedPacketView *view = [[XPReceiveRedPacketView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)]; XPReceiveRedPacketModel *data = [XPReceiveRedPacketModel modelWithJSON:attachment.data]; view.redPacketModel = data; [self.view addSubview:view]; [self.view bringSubviewToFront:view]; } } [self.messageContainerView handleNIMCustomMessage:message]; } } else if(message.messageType == NIMMessageTypeText) { [self.messageContainerView handleNIMTextMessage:message]; } else if(message.messageType == NIMMessageTypeTip) { [self.messageContainerView handleNIMTextMessage:message]; } } } //发送消息成功回调 - (void)sendMessage:(NIMMessage *)message didCompleteWithError:(NSError *)error { // 非本房间不处理 if (![message.session.sessionId isEqualToString:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]) { return; } if (message.yidunAntiSpamRes) { NSDictionary * spamRes = message.yidunAntiSpamRes.toJSONObject; NSDictionary * spamResExt = ((NSString *)spamRes[@"ext"]).toJSONObject; if ([spamResExt[@"antispam"][@"suggestion"] intValue] == 2) { [self showErrorToast:@"消息中可能含有违规信息,请停止发送类似信息!"]; return; } } if (error) return; if (message.messageType == NIMMessageTypeCustom) { NIMCustomObject *obj = (NIMCustomObject *)message.messageObject; if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) { AttachmentModel * attachment = obj.attachment; [self.stageView handleNIMCustomMessage:message]; [self.animationView handleNIMCustomMessage:message]; [self.functionView handleNIMCustomMessage:message]; if (attachment.first == CustomMessageType_Update_RoomInfo && attachment.second == Custom_Message_Sub_Update_RoomInfo_MessageState) { RoomInfoModel * roomInfo = [RoomInfoModel modelWithDictionary:attachment.data[@"roomInfo"]]; self.roomInfo.isCloseScreen = roomInfo.isCloseScreen; [self.menuContainerView onRoomUpdate]; } [self.messageContainerView handleNIMCustomMessage:message]; } }else if(message.messageType == NIMMessageTypeText) { [self.messageContainerView handleNIMTextMessage:message]; [self.littleGameView handleNIMTextMessage:message]; } } #pragma mark - NIMLoginManagerDelegate - (void)onKickout:(NIMLoginKickoutResult *)result { [self exitRoom]; [self dismissViewControllerAnimated:YES completion:nil]; } #pragma mark - NIMConversationManagerDelegate - (void)didAddRecentSession:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount { [self.menuContainerView addNIMRecentSession:recentSession]; } - (void)didUpdateRecentSession:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount { [self.menuContainerView addNIMRecentSession:recentSession]; } - (void)didRemoveRecentSession:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount { [self.menuContainerView removeNIMRecentSession:recentSession]; } #pragma mark - RoomDelegate - (RoomInfoModel *)getRoomInfo { return self.roomInfo; } - (UserInfoModel *)getUserInfo { return self.userInfo; } - (void)exitRoom { [self.menuContainerView menuResignFirstResponder]; if (self.roomInfo.roomModeType == RoomModeType_Open_Micro_Mode || self.roomInfo.roomModeType == RoomModeType_Open_Blind) { NSString * roomUid = [NSString stringWithFormat:@"%ld", self.roomInfo.uid]; NSString * uid = [AccountInfoStorage instance].getUid; [Api getRoomArrangeMicList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { if (code == 200) { ArrangeMicModel * arrangeMicModel= [ArrangeMicModel modelWithJSON:data.data]; if (arrangeMicModel.myPos.intValue > 0) { [TTPopup alertWithMessage:@"退出房间后将退出目前排麦,再次进入需要重新排麦,确认退出房间吗?" confirmHandler:^{ __block NSString * grouptype = @"0"; if (self.roomInfo.roomModeType == RoomModeType_Open_Blind) { [arrangeMicModel.queue enumerateObjectsUsingBlock:^(ArrangeMicUserModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if (obj.uid.integerValue == [AccountInfoStorage instance].getUid.integerValue) { grouptype = [NSString stringWithFormat:@"%ld", obj.groupType]; *stop = YES; } }]; } [Api cancelArrangeMic:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { } roomUid:roomUid operUid:uid groupType:grouptype]; [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [[RtcManager instance] exitRoom]; [self.presenter reportUserOutRoom:roomUid]; [self handleFirstOutRoom]; [self dismissViewControllerAnimated:YES completion:nil]; } cancelHandler:^{ }]; return; } } [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [[RtcManager instance] exitRoom]; [self.presenter reportUserOutRoom:roomUid]; [self handleFirstOutRoom]; [self dismissViewControllerAnimated:YES completion:nil]; } roomUid:roomUid operUid:uid page:@"1" pageSize:@"50"]; } else if(self.roomInfo.roomModeType == RoomModeType_Open_PK_Mode) { NSString * roomUid = [NSString stringWithFormat:@"%ld", self.roomInfo.uid]; NSString * uid = [AccountInfoStorage instance].getUid; [Api getRoomPKUserList:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { if (code == 200) { ArrangeMicModel * arrangeMicModel= [ArrangeMicModel modelWithJSON:data.data]; if (arrangeMicModel.myPos.intValue > 0) { [TTPopup alertWithMessage:@"退出房间后将退出目前排麦,再次进入需要重新排麦,确认退出房间吗?" confirmHandler:^{ __block NSString * grouptype = @"0"; [arrangeMicModel.queue enumerateObjectsUsingBlock:^(ArrangeMicUserModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if (obj.uid.integerValue == [AccountInfoStorage instance].getUid.integerValue) { grouptype = [NSString stringWithFormat:@"%ld", obj.groupType]; *stop = YES; } }]; [Api cancelRoomPKArrangeMic:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { } roomUid:roomUid operUid:uid groupType:grouptype]; [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [[RtcManager instance] exitRoom]; [self handleFirstOutRoom]; [self dismissViewControllerAnimated:YES completion:nil]; } cancelHandler:^{ }]; return; } } [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [[RtcManager instance] exitRoom]; [self handleFirstOutRoom]; [self dismissViewControllerAnimated:YES completion:nil]; } roomUid:roomUid operUid:uid page:@"1" pageSize:@"50"]; }else if(self.roomInfo.type == RoomType_MiniGame) { if ([self.littleGameView isInSudGame]) { TTAlertConfig *config = [[TTAlertConfig alloc] init]; config.cancelButtonConfig.title = @"取消"; config.confirmButtonConfig.title = @"确认"; config.message = @"退出房间则默认认输逃跑,是否退房?"; [TTPopup alertWithConfig:config confirmHandler:^{ // 知道了 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[RtcManager instance] exitRoom]; [self.littleGameView handleSelfInExitEvent]; [self.littleGameView destroyMG]; [self handleFirstOutRoom]; [self dismissViewControllerAnimated:YES completion:nil]; }); } cancelHandler:^{ }]; } else { [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[RtcManager instance] exitRoom]; [self.littleGameView handleSelfInExitEvent]; [self.littleGameView destroyMG]; [self handleFirstOutRoom]; [self dismissViewControllerAnimated:YES completion:nil]; } } else { [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[XPRoomMiniManager shareManager] resetLocalMessage]; [[RtcManager instance] exitRoom]; [self.presenter reportUserOutRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.uid]]; [self handleFirstOutRoom]; [self dismissViewControllerAnimated:YES completion:nil]; } } - (void)miniRoom { [self.menuContainerView menuResignFirstResponder]; if(self.roomInfo.type == RoomType_MiniGame) { if ([self.littleGameView isInSudGame]) { TTAlertConfig *config = [[TTAlertConfig alloc] init]; config.cancelButtonConfig.title = @"取消"; config.confirmButtonConfig.title = @"确认"; config.message = @"退出房间则默认认输逃跑,是否退房?"; [TTPopup alertWithConfig:config confirmHandler:^{ // 知道了 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [[XPRoomMiniManager shareManager] configRoomInfo:self.roomInfo]; [[XPRoomMiniManager shareManager] configUserInfo:self.userInfo]; [[XPRoomMiniManager shareManager] configCurrentMusic:self.functionView.getCurrentMusic isPlaying:self.functionView.isPlaying]; NSDictionary * dic = @{@"roomInfo":self.roomInfo.model2dictionary, @"userInfo":self.userInfo.model2dictionary, @"microQueue":self.getMicroQueue}; [[NSNotificationCenter defaultCenter] postNotificationName:kRoomMiniNotificationKey object:nil userInfo:dic]; [self.view endEditing:YES]; [self.littleGameView handleSelfInExitEvent]; [self.littleGameView destroyMG]; [self handleFirstOutRoom]; [self dismissViewControllerAnimated:YES completion:nil]; }); } cancelHandler:^{ }]; } else { [[XPRoomMiniManager shareManager] configRoomInfo:self.roomInfo]; [[XPRoomMiniManager shareManager] configUserInfo:self.userInfo]; [[XPRoomMiniManager shareManager] configCurrentMusic:self.functionView.getCurrentMusic isPlaying:self.functionView.isPlaying]; NSDictionary * dic = @{@"roomInfo":self.roomInfo.model2dictionary, @"userInfo":self.userInfo.model2dictionary, @"microQueue":self.getMicroQueue}; [[NSNotificationCenter defaultCenter] postNotificationName:kRoomMiniNotificationKey object:nil userInfo:dic]; [self.view endEditing:YES]; [self.littleGameView handleSelfInExitEvent]; [self.littleGameView destroyMG]; [self handleFirstOutRoom]; [self dismissViewControllerAnimated:YES completion:nil]; } }else { [[XPRoomMiniManager shareManager] configRoomInfo:self.roomInfo]; [[XPRoomMiniManager shareManager] configUserInfo:self.userInfo]; [[XPRoomMiniManager shareManager] configCurrentMusic:self.functionView.getCurrentMusic isPlaying:self.functionView.isPlaying]; NSDictionary * dic = @{@"roomInfo":self.roomInfo.model2dictionary, @"userInfo":self.userInfo.model2dictionary, @"microQueue":self.getMicroQueue}; [[NSNotificationCenter defaultCenter] postNotificationName:kRoomMiniNotificationKey object:nil userInfo:dic]; [self.view endEditing:YES]; [self handleFirstOutRoom]; [self dismissViewControllerAnimated:YES completion:nil]; } } - (UINavigationController *)getCurrentNav { return self.navigationController; } - (NSMutableDictionary *)getMicroQueue { return [self.stageView getMicroQueue]; } - (NSArray *)getRoomSuperAdminList { return self.superMangerList; } - (NSArray *)getRoomPKGroupTeamList { return [self.functionView getRoomPKGroupTeamList]; } - (BOOL)isRoomPKPlaying { return [self.functionView isRoomPKPlaying]; } - (void)onMicroQueueUpdate:(NSMutableDictionary *)queue { [self.menuContainerView onMicroQueueUpdate:queue]; [self.functionView onRoomUpdate]; [self.functionView onMicroQueueUpdate:queue]; } - (CGPoint)animationPointAtStageViewByUid:(NSString *)uid { return [self.stageView animationPointAtStageViewByUid:uid]; } #pragma mark - 首次退出非自己的房间,处理是否需要弹新用户充值优惠 - (void)handleFirstOutRoom { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if (![defaults boolForKey:kHadQuitOtherRoomKey] && self.userInfo.uid != self.roomInfo.uid && self.userInfo.showLimitCharge) { [defaults setBool:YES forKey:kHadQuitOtherRoomKey]; [defaults synchronize]; [[NSNotificationCenter defaultCenter] postNotificationName:kNewUserRechargeKey object:nil]; } } #pragma mark - XPRoomLittleGameContainerViewDelegate - (void)hiddenSudGamePostionView { [self.functionView hiddenSudGamePostionView]; } #pragma mark - AnchorRoomScrollViewDelegate - (void)anchorScrollViewScrollToNext:(AnchorRoomScrollView *)anchorScrollView { if (!self) { return; } [self.view endEditing:YES]; [self showAnchorLoading]; [self.presenter getCycleAnchorRoomList:[NSString stringWithFormat:@"%ld", self.roomInfo.uid]]; } - (void)anchorScrollViewScrollToPrevious:(AnchorRoomScrollView *)anchorScrollView { if (!self || self.anchorRoomList.count <= 0) { return; } [self.view endEditing:YES]; [self showAnchorLoading]; if (self.anchorIndex < self.anchorRoomList.count) { NSString * roomUid = [self.anchorRoomList objectAtIndex:self.anchorIndex]; [self.presenter getCurrentRoomInfo:roomUid]; self.anchorIndex --; }else { [self showErrorToast:@"已经到顶啦~自动为您返回当前房间"]; self.anchorScrollView.contentOffset = CGPointMake(0, KScreenHeight); } } #pragma mark - XPRoomSettingInputViewDelegate ///点击了完成 - (void)xPRoomSettingInputView:(XPRoomSettingInputView *)view didClickConfirm:(NSString *)text type:(RoomSettingInputType)type { NSString *pwdDes = [DESEncrypt encryptUseDES:text key:KeyWithType(KeyType_PasswordEncode)]; if ([pwdDes isEqualToString:self.roomInfo.roomPwd]) { [TTPopup dismiss]; view.isPwdError = NO; if (self.roomInfo.type == RoomType_Anchor) { if (!self.anchorScrollView.superview) { [self.view insertSubview:self.anchorScrollView belowSubview:self.menuContainerView]; } [self.backContainerView removeFromSuperview]; [self.stageView removeFromSuperview]; [self.messageContainerView removeFromSuperview]; [self.activityContainerView removeFromSuperview]; [self.roomHeaderView removeFromSuperview]; [self.functionView removeFromSuperview]; [self.anchorScrollView addSubview:self.backContainerView]; [self.anchorScrollView addSubview:self.stageView]; [self.anchorScrollView addSubview:self.messageContainerView]; [self.anchorScrollView addSubview:self.activityContainerView]; [self.anchorScrollView addSubview:self.roomHeaderView]; [self.anchorScrollView addSubview:self.functionView]; if (!self.menuContainerView.superview) { [self.view addSubview:self.menuContainerView]; } [self.view bringSubviewToFront:self.animationView]; [self updateViewConstraintsOnAnchorRoom]; [self changeStageViewOnAnchorRoom]; [self.roomHeaderView onRoomEntered]; [self.activityContainerView onRoomEntered]; [self.menuContainerView onRoomEntered]; [self.backContainerView onRoomEntered]; [self.littleGameView onRoomEntered]; if ([XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {// 最小化进房 还是原来的房间的话 不需要重新进入云信 因为压根没退 [self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo]; [self.functionView onRoomEntered]; [self.messageContainerView onRoomEntered]; } else { //虽然没退出房间 但是队列还是要拿的 [self.stageView onRoomMiniEntered]; [self.messageContainerView onRoomMiniEntered]; [self.functionView onRoomMiniEntered]; [self.functionView onRoomEntered]; } [[XPRoomMiniManager shareManager] configRoomInfo:nil]; [[XPRoomMiniManager shareManager] configUserInfo:nil]; [[XPRoomMiniManager shareManager] configCurrentMusic:nil isPlaying:NO]; } else { [self.roomHeaderView onRoomEntered]; [self.activityContainerView onRoomEntered]; [self.menuContainerView onRoomEntered]; [self changeStageViewOnRoomUpdate]; [self.backContainerView onRoomEntered]; [self.functionView onRoomEntered]; [self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo]; [self.messageContainerView onRoomEntered]; [self.littleGameView onRoomEntered]; [[XPRoomMiniManager shareManager] configRoomInfo:nil]; [[XPRoomMiniManager shareManager] configUserInfo:nil]; [[XPRoomMiniManager shareManager] configCurrentMusic:nil isPlaying:NO]; } } else { view.isPwdError = YES; } } - (void)didClickCancel:(RoomSettingInputType)type { if (type == RoomSettingInputType_Input_Pwd) { [self enterRoomFail:0]; } } - (XPRoomBackContainerView *)backContainerView { if (!_backContainerView) { _backContainerView = [[XPRoomBackContainerView alloc] initWithdelegate:self]; } return _backContainerView; } - (RoomHeaderView *)roomHeaderView { if (!_roomHeaderView) { _roomHeaderView = [[RoomHeaderView alloc] initWithDelegate:self]; } return _roomHeaderView; } - (XPRoomMessageContainerView *)messageContainerView { if (!_messageContainerView) { _messageContainerView = [[XPRoomMessageContainerView alloc] initWithDelegate:self]; } return _messageContainerView; } - (XPRoomMenuContainerView *)menuContainerView { if (!_menuContainerView) { _menuContainerView = [[XPRoomMenuContainerView alloc] initWithDelegate:self]; } return _menuContainerView; } - (XPRoomActivityContainerView *)activityContainerView { if (!_activityContainerView) { _activityContainerView = [[XPRoomActivityContainerView alloc] initWithdelegate:self]; } return _activityContainerView; } - (XPRoomAnimationView *)animationView { if (!_animationView) { _animationView = [[XPRoomAnimationView alloc] initWithDelegate:self]; } return _animationView; } - (XPRoomFunctionContainerView *)functionView { if (!_functionView) { _functionView = [[XPRoomFunctionContainerView alloc] initWithdelegate:self]; } return _functionView; } - (StageView *)stageView { if (!_stageView) { _stageView = [[SocialStageView alloc] initWithDelegate:self]; } return _stageView; } - (XPRoomLittleGameContainerView *)littleGameView { if (!_littleGameView) { _littleGameView = [[XPRoomLittleGameContainerView alloc] initWithDelegate:self]; _littleGameView.delegate = self; } return _littleGameView; } - (AnchorRoomScrollView *)anchorScrollView { if (!_anchorScrollView) { _anchorScrollView = [[AnchorRoomScrollView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)]; _anchorScrollView.anchorScrollDelegate = self; if (@available(iOS 11.0, *)) { _anchorScrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; } } return _anchorScrollView; } - (AnchorRoomSrollTipView *)anchorScrollTipView { if (!_anchorScrollTipView) { _anchorScrollTipView = [[AnchorRoomSrollTipView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)]; } return _anchorScrollTipView; } - (NSMutableArray *)anchorRoomList { if (!_anchorRoomList) { _anchorRoomList = [NSMutableArray array]; } return _anchorRoomList; } @end