// // 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" ///Model #import "RoomInfoModel.h" #import "UserInfoModel.h" #import "AttachmentModel.h" ///View #import "BaseNavigationController.h" #import "XPRoomActivityContainerView.h" #import "XPRoomBackContainerView.h" #import "XPRoomMenuContainerView.h" #import "XPRoomMessageContainerView.h" #import "RoomHeaderView.h" #import "SocialStageView.h" #import "XPRoomAnimationView.h" ///P #import "XPRoomPresenter.h" #import "XPRoomProtocol.h" #import "RoomHostDelegate.h" #import "RoomGuestDelegate.h" @interface XPRoomViewController () ///背景 @property (nonatomic,strong) XPRoomBackContainerView *backContainerView; ///房间信息 @property (nonatomic,strong) RoomHeaderView *roomHeaderView; ///坑位信息 @property (nonatomic,strong) SocialStageView *stageView; ///公屏 @property (nonatomic,strong) XPRoomMessageContainerView *messageContainerView; ///底部操作栏 @property (nonatomic,strong) XPRoomMenuContainerView *menuContainerView; ///活动 @property (nonatomic,strong) XPRoomActivityContainerView *activityContainerView; ///动画的view @property (nonatomic,strong) XPRoomAnimationView *animationView; ///房间的Uid @property (nonatomic,copy) NSString * roomUid; ///用户信息 @property (nonatomic,strong) UserInfoModel *userInfo; ///房间信息 @property (nonatomic,strong) RoomInfoModel *roomInfo; @end @implementation XPRoomViewController + (BOOL)openRoom:(NSString *)roomUid viewController:(UIViewController *)viewController { XPRoomViewController * roomVC = [[self alloc] init]; roomVC.roomUid = roomUid; BaseNavigationController * baseNav = [[BaseNavigationController alloc] initWithRootViewController:roomVC]; baseNav.modalPresentationStyle = UIModalPresentationFullScreen; [viewController presentViewController:baseNav animated:YES completion:nil]; return YES; } - (void)dealloc { #warning to dox - 时刻注意这个方法 功能做完的时候删除此方法 } - (XPRoomPresenter *)createPresenter { return [[XPRoomPresenter alloc] init]; } - (BOOL)isHiddenNavBar { return YES; } - (void)viewDidLoad { [super viewDidLoad]; [self exitOldRoom]; [self initSubViews]; [self initSubViewConstraints]; [self.presenter initEnterRoom:self.roomUid user:[AccountInfoStorage instance].getUid]; /// 公屏 福袋礼物爆出的礼物 需要依赖 当前房间中的礼物列表 需要提前获取礼物列表 可以拿到礼物 没有想到别的方法去解决这个问题 有需要改的在修改吧 [self.presenter getNormalGiftList:self.roomUid]; //监听云信消息 [[NIMSDK sharedSDK].chatroomManager addDelegate:self]; [[NIMSDK sharedSDK].chatManager addDelegate:self]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self.view endEditing:YES]; } #pragma mark - Private Method - (void)initSubViews { [self.view addSubview:self.backContainerView]; [self.view addSubview:self.roomHeaderView]; [self.view addSubview:self.stageView]; [self.view addSubview:self.messageContainerView]; [self.view addSubview:self.menuContainerView]; [self.view addSubview:self.activityContainerView]; [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); }]; [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); }]; } - (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]; } } #pragma mark - XPRoomProtocol - (void)initEnterRoomSuccess:(RoomInfoModel *)roomInfo user:(UserInfoModel *)userInfo { self.roomInfo = roomInfo; self.userInfo = userInfo; if (roomInfo.valid) { // 房间有效,直接进入房间 if (roomInfo.roomPwd.length > 0) {//进房密码的情况 [self showErrorToast:@"房间已上锁"]; [self enterRoomFail]; } else { [self.roomHeaderView onRoomUpdate]; [self.activityContainerView onRoomUpdate]; [self.menuContainerView onRoomUpdate]; if ([XPRoomMiniManager shareManager].getRoomInfo.uid != self.roomUid.integerValue) {// 最小化进房 还是原来的房间的话 不需要重新进入云信 因为压根没退 [self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo]; } else { //虽然没退出房间 但是队列还是要拿的 [self.stageView onRoomEntered]; } [[XPRoomMiniManager shareManager] configRoomInfo:nil]; } } else { // 房间无效,分是否为自己房间进行处理 if ([self.roomUid isEqualToString:[NSString stringWithFormat:@"%ld", userInfo.uid]]) { // 当前用户进入自己房间 if (roomInfo.roomId > 0) { // 存在房间信息,直接使用房间信息开房 [self.presenter openRoom:roomInfo.title type:roomInfo.type roomPwd:roomInfo.roomPwd roomDesc:roomInfo.roomDesc backPic:@""]; } else { // 不存在房间信息,全新开房 NSString* title = [NSString stringWithFormat:@"%@的房间", userInfo.nick]; [self.presenter openRoom:title type:RoomType_Game roomPwd:@"" roomDesc:@"" backPic:@""]; } } else { // 当前用户进入别人房间 // TODO: 房主已经下线。 [self showSuccessToast:@"房主已下线"]; [self enterRoomFail]; } } } - (void)openRoomSuccess:(RoomInfoModel *)roomInfo { self.roomInfo = roomInfo; [self.roomHeaderView onRoomUpdate]; [self.activityContainerView onRoomUpdate]; [self.presenter enterNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId] user:self.userInfo]; } - (void)enterRoomSuccess:(NIMChatroom *)chatRoom { // room/get中的房间在线人数 是定时更新的 不是及时刷新 self.roomInfo.onlineNum = chatRoom.onlineUserCount; [self.stageView onRoomEntered]; } - (void)enterRoomFail { [self dismissViewControllerAnimated:YES completion:nil]; } #pragma mark - NIMChatroomManagerDelegate - (void)chatroomBeKicked:(NIMChatroomBeKickedResult *)result { if (result.reason == 2) { [self showErrorToast:@"您被管理员踢出直播间"]; } else if (result.reason == 5) { [self showErrorToast:@"您已被管理员拉黑"]; } [[RtcManager instance] exitRoom]; [self dismissViewControllerAnimated:YES completion:nil]; } #pragma mark - NIMChatManagerDelegate - (void)onRecvMessages:(NSArray *)messages { for (NIMMessage * message in messages) { // 非房间内消息不处理 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: { RoomInfoModel * roomInfo =[RoomInfoModel modelWithJSON:data[@"roomInfo"]]; self.roomInfo.leaveMode = roomInfo.leaveMode; self.roomInfo.showGiftValue = roomInfo.showGiftValue; [self.stageView onRoomUpdate]; } break; } } break; case NIMChatroomEventTypeEnter: if (content.source.userId.integerValue != [AccountInfoStorage instance].getUid.integerValue) { onLineNumber += 1; } break; case NIMChatroomEventTypeAddBlack: case NIMChatroomEventTypeKicked: case NIMChatroomEventTypeExit: onLineNumber -= 1; break; default: break; } self.roomInfo.onlineNum = onLineNumber; [self.roomHeaderView onRoomUpdate]; [self.stageView handleNIMNotificationMessage:content]; } else if (message.messageType == NIMMessageTypeCustom) { NIMCustomObject *obj = (NIMCustomObject *)message.messageObject; if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) { [self.stageView handleNIMCustomMessage:obj.attachment]; } } } } //发送消息成功回调 - (void)sendMessage:(NIMMessage *)message didCompleteWithError:(NSError *)error { if (error) return; if (message.messageType == NIMMessageTypeCustom) { NIMCustomObject *obj = (NIMCustomObject *)message.messageObject; if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) { [self.stageView handleNIMCustomMessage:obj.attachment]; } } } #pragma mark - RoomDelegate - (RoomInfoModel *)getRoomInfo { return self.roomInfo; } - (UserInfoModel *)getUserInfo { return self.userInfo; } - (void)exitRoom { [self.presenter exitNIMRoom:[NSString stringWithFormat:@"%ld", self.roomInfo.roomId]]; [[RtcManager instance] exitRoom]; [self dismissViewControllerAnimated:YES completion:nil]; } - (void)miniRoom { [[XPRoomMiniManager shareManager] configRoomInfo:self.roomInfo]; 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 dismissViewControllerAnimated:YES completion:nil]; } - (UINavigationController *)getCurrentNav { return self.navigationController; } - (NSMutableDictionary *)getMicroQueue { return [self.stageView getMicroQueue]; } - (void)onMicroQueueUpdate:(NSMutableDictionary *)queue { [self.menuContainerView onMicroQueueUpdate:queue]; } - (CGPoint)centerForUserAtUid:(NSString *)uid { return [self.stageView centerForUserAtUid:uid]; } - (XPRoomBackContainerView *)backContainerView { if (!_backContainerView) { _backContainerView = [[XPRoomBackContainerView alloc] initWithdelegate:self]; } return _backContainerView; } - (RoomHeaderView *)roomHeaderView { if (!_roomHeaderView) { _roomHeaderView = [[RoomHeaderView alloc] initWithDelegate:self]; } return _roomHeaderView; } - (SocialStageView *)stageView { if (!_stageView) { _stageView = [[SocialStageView alloc] initWithDelegate:self]; } return _stageView; } - (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; } @end