// // SessionViewController.m // xplan-ios // // Created by zu on 2021/11/28. // #import "SessionViewController.h" #import #import ///Tool #import "XCCurrentVCStackManager.h" #import "NIMMessageMaker.h" #import "XPMacro.h" #import "UITableView+NIMScrollToBottom.h" ///Model #import "RoomInfoModel.h" #import "UserInfoModel.h" #import "MessageMenuModel.h" ///View #import "XPSessionMessageHeadView.h" #import "XPMineUserInfoViewController.h" #import "XPRoomViewController.h" #import "RoomHostDelegate.h" #import "SessionToolbarView.h" #import "MessageCell.h" #import "SessionChatLimitView.h" ///P #import "MessagePresenter.h" #import "MessageProtocol.h" @interface SessionViewController () @property (nonatomic, strong) NIMSession * session; @property (nonatomic, strong) NSMutableArray * messages; @property (nonatomic, strong) UITableView * sessionTableView; ///跟随进房卡片 @property (nonatomic, strong) XPSessionMessageHeadView *followInRoomView; @property (nonatomic, strong) UserInfoModel *userInfo; ///输入框 @property (nonatomic,strong) SessionToolbarView *toolbarView; @end @implementation SessionViewController - (void)dealloc { [[NIMSDK sharedSDK].chatManager removeDelegate:self]; [[NIMSDK sharedSDK].conversationManager removeDelegate:self]; [[NIMSDK sharedSDK].mediaManager removeDelegate:self]; [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (MessagePresenter *)createPresenter { return [[MessagePresenter alloc] init]; } - (instancetype)initWithSession:(NIMSession *)session { self = [super init]; if (self) { _session = session; [self initViews]; [self initLayout]; } return self; } - (void)viewDidLoad { [super viewDidLoad]; [IQKeyboardManager sharedManager].enable = NO; [IQKeyboardManager sharedManager].enableAutoToolbar = NO; [self initData]; [[NIMSDK sharedSDK].chatManager addDelegate:self]; [[NIMSDK sharedSDK].conversationManager addDelegate:self]; [self.presenter getUserInfo:self.session.sessionId]; } - (void)initViews { NIMUser * user = [[NIMSDK sharedSDK].userManager userInfo:self.session.sessionId]; if (user) { self.title = user.userInfo.nickName; } else { self.title = @"加载中……"; } [self.view addSubview:self.followInRoomView]; [self.view addSubview:self.sessionTableView]; [self.view addSubview:self.toolbarView]; } - (void)initLayout { [self.followInRoomView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.top.mas_equalTo(self.view); make.height.mas_equalTo(80); }]; [self.sessionTableView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.top.mas_equalTo(self.view); make.bottom.mas_equalTo(self.toolbarView.mas_top); }]; [self.toolbarView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(self.view); make.bottom.mas_equalTo(self.view); }]; } - (void)initData { NSArray *messages = [[NIMSDK sharedSDK].conversationManager messagesInSession:self.session message:nil limit:1000]; [self.messages addObjectsFromArray:messages.copy]; [self.sessionTableView reloadData]; [self.sessionTableView nim_scrollToBottom:NO]; [[NIMSDK sharedSDK].userManager fetchUserInfos:@[self.session.sessionId] completion:^(NSArray * _Nullable users, NSError * _Nullable error) { if (!error) { self.title = users[0].userInfo.nickName; } }]; [[NIMSDK sharedSDK].conversationManager markAllMessagesReadInSession:self.session]; [self.presenter getChatLimitReceiverUid:self.session.sessionId]; } #pragma mark - MessageProtocol - (void)onGetLimitChat:(ChatLimitModel *)chatLimit { BOOL chatDisabled = !chatLimit.chat && self.messages.count <= 0; if (chatDisabled) { SessionChatLimitView *chatLimitView = [[SessionChatLimitView alloc] initWithChatLimit:chatLimit]; self.sessionTableView.tableHeaderView = chatLimitView; } else { self.sessionTableView.tableHeaderView = nil; } self.toolbarView.sendDisabled = chatDisabled; } ///获取用户信息成功 - (void)onGetSessionUserInfoSuccess:(UserInfoModel *)userInfo { _userInfo = userInfo; if (userInfo.roomUid) { self.followInRoomView.hidden = NO; self.followInRoomView.userInfo = userInfo; [self.sessionTableView mas_updateConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(self.view).mas_offset(80); }]; } } #pragma mark - MessageCellDelegate - (void)updateMessageSuccess:(NIMMessage *)message { if ([message.session.sessionId isEqualToString:self.session.sessionId]) { [self.sessionTableView reloadData]; } } #pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.messages.count; } - (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath { NIMMessage * message = [self.messages objectAtIndex:indexPath.row]; NSString * identifier = [MessageCell cellContent:message]; ///从复用池中获取所需要的cell MessageCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier]; if (!cell) { ///如果没有的话 根据identifier 注册一下 重新获取一下即可 [tableView registerClass:[MessageCell class] forCellReuseIdentifier:identifier]; ///如果注册过了 就不需要判断cell是否为空 cell = [tableView dequeueReusableCellWithIdentifier:identifier]; } cell.delegate = self; [cell renderWithMessage:[self.messages objectAtIndex:indexPath.row]]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NIMMessage *msg = [self.messages objectAtIndex:indexPath.row]; return [MessageCell measureHeight:msg]; } - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { [self.toolbarView foldMenuView]; } #pragma mark - NIMChatManagerDelegate - (void)onRecvMessages:(NSArray *)messages { NIMMessage *message = messages.firstObject; NIMSession *session = message.session; if (![session isEqual:self.session] || !messages.count) { return; } for (NIMMessage *message in messages) { if (message.isDeleted) { continue; } [self.messages addObject:message]; } [self.sessionTableView reloadData]; [self.sessionTableView nim_scrollToBottom:YES]; [[NIMSDK sharedSDK].conversationManager markAllMessagesReadInSession:self.session]; } - (void)sendMessage:(NIMMessage *)message didCompleteWithError:(NSError *)error { if (message.session.sessionType != NIMSessionTypeP2P) { return; } [self.messages addObject:message]; [self.sessionTableView reloadData]; [self.sessionTableView nim_scrollToBottom:YES]; } - (void)fetchMessageAttachment:(NIMMessage *)message didCompleteWithError:(NSError *)error { if (![message.session isEqual:self.session]) return; for (NIMMessage * msg in self.messages) { if ([msg.messageId isEqualToString:message.messageId]) { NSInteger index = [self.messages indexOfObject:msg]; [self.messages replaceObjectAtIndex:index withObject:message]; [self.sessionTableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationNone]; break; } } } #pragma mark - NIMConversationManagerDelegate - (void)messagesDeletedInSession:(NIMSession *)session { [self.messages removeAllObjects]; [self initData]; } #pragma mark - XPSessionMessageHeadViewDelegate - (void)onAvatarClick:(NSInteger)uid { XPMineUserInfoViewController * infoVC = [[XPMineUserInfoViewController alloc] init]; infoVC.uid = uid; [self.navigationController pushViewController:infoVC animated:YES]; } - (void)onFollowInRoom:(NSString *)roomUid { __block BOOL isSameRoom = NO; __block RoomInfoModel *roomModel; [self.navigationController.viewControllers enumerateObjectsUsingBlock:^(__kindof UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj isKindOfClass:[XPRoomViewController class]]) { XPRoomViewController * rooomVC = obj; [self.navigationController popToRootViewControllerAnimated:NO]; roomModel = rooomVC.getRoomInfo; if(rooomVC.getRoomInfo.uid == [roomUid integerValue]) { isSameRoom = YES; } else { [rooomVC exitRoom]; } *stop = YES; } }]; if (!isSameRoom) { if (roomModel.type == RoomType_MiniGame) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [XPRoomViewController openRoom:roomUid fromNick:self.userInfo.nick fromType:UserEnterRoomFromType_Follow_User fromUid:[NSString stringWithFormat:@"%ld", self.userInfo.uid] viewController:[[XCCurrentVCStackManager shareManager] getCurrentVC]]; }); } else { [XPRoomViewController openRoom:roomUid fromNick:self.userInfo.nick fromType:UserEnterRoomFromType_Follow_User fromUid:[NSString stringWithFormat:@"%ld", self.userInfo.uid] viewController:self]; } } } #pragma mark - MessageToolbarViewDelegate - (void)keyboardWillChangeFrame:(CGRect)rect { CGFloat heightFromBottom = rect.size.height; heightFromBottom = MAX(0.0, heightFromBottom); [self.toolbarView mas_updateConstraints:^(MASConstraintMaker *make) { make.bottom.mas_equalTo(self.view).offset(-heightFromBottom); }]; [self.sessionTableView nim_scrollToBottom:YES]; } - (void)sendTextMessage:(NSString *)text { NIMMessage *message = [NIMMessageMaker msgWithText:text]; [[[NIMSDK sharedSDK] chatManager] sendMessage:message toSession:self.session error:nil]; } - (void)didSelectMenuItem:(MessageMenuModel *)info { switch (info.type) { case MessageMenuType_Photo: break; case MessageMenuType_Gift: break; default: break; } } #pragma mark - Getters And Setters - (NSArray *)messages { if (!_messages) { _messages = [[NSMutableArray alloc] init]; } return _messages; } #pragma mark - Event Response - (void)closeKeyBoard { [self.view endEditing:YES]; [self.toolbarView foldMenuView]; } - (UITableView *)sessionTableView { if (!_sessionTableView) { _sessionTableView = [[UITableView alloc] init]; _sessionTableView.delegate = self; _sessionTableView.dataSource = self; _sessionTableView.backgroundColor = UIColor.clearColor; _sessionTableView.separatorStyle = UITableViewCellSeparatorStyleNone; _sessionTableView.showsVerticalScrollIndicator = NO; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeKeyBoard)]; [_sessionTableView addGestureRecognizer:tap]; } return _sessionTableView; } - (XPSessionMessageHeadView *)followInRoomView { if (!_followInRoomView) { _followInRoomView = [[XPSessionMessageHeadView alloc] init]; _followInRoomView.delegate = self; _followInRoomView.hidden = YES; } return _followInRoomView; } - (SessionToolbarView *)toolbarView { if (!_toolbarView) { _toolbarView = [[SessionToolbarView alloc] init]; _toolbarView.delegate = self; } return _toolbarView; } @end