Files
yinmeng-ios/xplan-ios/Main/Message/View/Session/SessionViewController.m
2021-12-08 18:53:33 +08:00

236 lines
7.9 KiB
Objective-C

//
// SessionViewController.m
// xplan-ios
//
// Created by zu on 2021/11/28.
//
#import "SessionViewController.h"
#import "MessageCell.h"
#import "SendMessageView.h"
#import "SessionChatLimitView.h"
#import "UITableView+NIMScrollToBottom.h"
#import "NIMMessageMaker.h"
#import "XPMacro.h"
#import <Masonry/Masonry.h>
#import "MessagePresenter.h"
#import "MessageProtocol.h"
@interface SessionViewController ()<MessageProtocol, UITableViewDelegate, UITableViewDataSource, NIMChatManagerDelegate, NIMConversationManagerDelegate, NIMMediaManagerDelegate, SendMessageViewDelegate>
@property (nonatomic, strong) NIMSession * session;
@property (nonatomic, strong) NSMutableArray<NIMMessage *> * messages;
@property (nonatomic, strong) UITableView * sessionTableView;
@property (nonatomic, strong) SendMessageView * sendMessageView;
@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];
[self initData];
[[NIMSDK sharedSDK].chatManager addDelegate:self];
[[NIMSDK sharedSDK].conversationManager addDelegate:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
- (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.sessionTableView];
[self.view addSubview:self.sendMessageView];
}
- (void)initLayout {
[self.sessionTableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.top.mas_equalTo(self.view);
make.bottom.mas_equalTo(self.sendMessageView.mas_top);
}];
[self.sendMessageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.bottom.mas_equalTo(self.view);
}];
}
- (void)initData {
NSArray<NIMMessage *> *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<NIMUser *> * _Nullable users, NSError * _Nullable error) {
if (!error) {
self.title = users[0].userInfo.nickName;
}
}];
[[NIMSDK sharedSDK].conversationManager markAllMessagesReadInSession:self.session];
[self.presenter getChatLimit];
}
- (void)keyboardWillShow:(NSNotification *)notification {
NSDictionary *info = [notification userInfo];
NSNumber *curve = [info objectForKey:UIKeyboardAnimationCurveUserInfoKey];
CGFloat duration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
UIViewAnimationOptions options = (UIViewAnimationOptions)curve << 16;
[UIView animateWithDuration:duration delay:0.0 options:options animations:^{
[self.sessionTableView nim_scrollToBottom:YES];
} completion:nil];
}
#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.sendMessageView.sendDisabled = chatDisabled;
}
#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 {
MessageCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([MessageCell class])];
if (cell == nil) {
cell = [[MessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass([MessageCell class])];
}
[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];
}
#pragma mark - NIMChatManagerDelegate
- (void)onRecvMessages:(NSArray<NIMMessage *> *)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 {
[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 - SendMessageViewDelegate
- (void)sendTextMessage:(NSString *)text {
NIMMessage *message = [NIMMessageMaker msgWithText:text];
[[[NIMSDK sharedSDK] chatManager] sendMessage:message toSession:self.session error:nil];
}
- (NSArray<NIMMessage *> *)messages {
if (!_messages) {
_messages = [[NSMutableArray alloc] init];
}
return _messages;
}
- (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;
}
- (void)closeKeyBoard {
[self.view endEditing:YES];
[self.sessionTableView endEditing:YES];
}
- (SendMessageView *)sendMessageView {
if (!_sendMessageView) {
_sendMessageView = [[SendMessageView alloc] init];
_sendMessageView.delegate = self;
_sendMessageView.sendDisabled = YES;
}
return _sendMessageView;
}
@end