2021-10-14 21:10:04 +08:00
|
|
|
|
//
|
|
|
|
|
// XPRoomMessageView.m
|
|
|
|
|
// xplan-ios
|
|
|
|
|
//
|
|
|
|
|
// Created by 冯硕 on 2021/10/11.
|
|
|
|
|
//
|
|
|
|
|
|
2021-10-18 19:10:13 +08:00
|
|
|
|
#import "XPRoomMessageContainerView.h"
|
2021-10-26 19:10:03 +08:00
|
|
|
|
///Third
|
|
|
|
|
#import <Masonry/Masonry.h>
|
|
|
|
|
#import <NIMSDK/NIMSDK.h>
|
2021-10-29 10:50:39 +08:00
|
|
|
|
#import <YYText/YYText.h>
|
2021-10-27 19:07:10 +08:00
|
|
|
|
///Tool
|
|
|
|
|
#import "ThemeColor.h"
|
2021-10-29 10:50:39 +08:00
|
|
|
|
#import "XPMacro.h"
|
|
|
|
|
#import "XPRoomMessageConstant.h"
|
2021-10-26 19:10:03 +08:00
|
|
|
|
///Model
|
|
|
|
|
#import "XPRoomMessageDisplayModel.h"
|
2021-10-29 10:50:39 +08:00
|
|
|
|
#import "RoomInfoModel.h"
|
2021-10-26 19:10:03 +08:00
|
|
|
|
///View
|
|
|
|
|
#import "XPRoomMessageTableViewCell.h"
|
|
|
|
|
#import "XPRoomMessageHeaderView.h"
|
|
|
|
|
#import "View/XPRoomMessageHeaderView.h"
|
2021-10-27 19:07:10 +08:00
|
|
|
|
///P
|
|
|
|
|
#import "XPIMRoomDelegate.h"
|
2021-10-26 19:10:03 +08:00
|
|
|
|
|
2021-10-27 19:07:10 +08:00
|
|
|
|
|
2021-10-29 10:50:39 +08:00
|
|
|
|
@interface XPRoomMessageContainerView ()<UITableViewDelegate, UITableViewDataSource,NIMChatManagerDelegate, RooMessageDelegte>
|
2021-10-26 19:10:03 +08:00
|
|
|
|
///列表
|
|
|
|
|
@property (nonatomic,strong) UITableView *messageTableView;
|
|
|
|
|
///数据源
|
|
|
|
|
@property (nonatomic,strong) NSMutableArray<XPRoomMessageDisplayModel *> *datasource;
|
|
|
|
|
///临时存放消息的数组
|
|
|
|
|
@property (nonatomic,strong) NSMutableArray<XPRoomMessageDisplayModel *> *tempArray;
|
|
|
|
|
///头部
|
|
|
|
|
@property (nonatomic,strong) XPRoomMessageHeaderView *headerView;
|
2021-10-27 19:07:10 +08:00
|
|
|
|
///底部有新的消息
|
|
|
|
|
@property (nonatomic,strong) UIButton *messageTipsBtn;
|
|
|
|
|
///是否处于正在爬楼
|
|
|
|
|
@property (nonatomic,assign) BOOL isPending;
|
2021-10-29 10:50:39 +08:00
|
|
|
|
///房间的代理
|
|
|
|
|
@property (nonatomic,weak) id<RoomHostDelegate> hostDelegate;
|
2021-10-26 19:10:03 +08:00
|
|
|
|
@end
|
|
|
|
|
|
2021-10-14 21:10:04 +08:00
|
|
|
|
|
2021-10-18 19:10:13 +08:00
|
|
|
|
@implementation XPRoomMessageContainerView
|
2021-10-14 21:10:04 +08:00
|
|
|
|
|
2021-10-29 10:50:39 +08:00
|
|
|
|
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate {
|
|
|
|
|
self = [super init];
|
2021-10-14 21:10:04 +08:00
|
|
|
|
if (self) {
|
2021-10-29 10:50:39 +08:00
|
|
|
|
self.hostDelegate = delegate;
|
|
|
|
|
[[NIMSDK sharedSDK].chatManager addDelegate:self];
|
2021-10-14 21:10:04 +08:00
|
|
|
|
[self initSubViews];
|
|
|
|
|
[self initSubViewConstraints];
|
|
|
|
|
}
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-27 19:07:10 +08:00
|
|
|
|
#pragma mark - Response
|
|
|
|
|
- (void)messagTipsBtnAction:(UIButton *)sender {
|
|
|
|
|
[self tryToappendAndScrollToBottom];
|
|
|
|
|
self.isPending = NO;
|
2021-10-26 19:10:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-14 21:10:04 +08:00
|
|
|
|
#pragma mark - Private Method
|
|
|
|
|
- (void)initSubViews {
|
2021-10-26 19:10:03 +08:00
|
|
|
|
[self addSubview:self.messageTableView];
|
2021-10-27 19:07:10 +08:00
|
|
|
|
[self addSubview:self.messageTipsBtn];
|
2021-10-26 19:10:03 +08:00
|
|
|
|
self.messageTableView.tableHeaderView = self.headerView;
|
2021-10-14 21:10:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)initSubViewConstraints {
|
2021-10-26 19:10:03 +08:00
|
|
|
|
[self.messageTableView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
|
|
make.left.mas_equalTo(self).offset(15);
|
|
|
|
|
make.top.bottom.right.mas_equalTo(self);
|
|
|
|
|
}];
|
2021-10-27 19:07:10 +08:00
|
|
|
|
|
|
|
|
|
[self.messageTipsBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
|
|
make.width.mas_equalTo(100);
|
|
|
|
|
make.height.mas_equalTo(30);
|
|
|
|
|
make.bottom.mas_equalTo(self.mas_bottom).offset(-5);
|
|
|
|
|
make.left.mas_equalTo(self);
|
|
|
|
|
}];
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-29 10:50:39 +08:00
|
|
|
|
///是否是当前房间
|
|
|
|
|
- (BOOL)isCurrentRoom:(NSString *)sessionId {
|
|
|
|
|
if ([sessionId isEqualToString:[NSString stringWithFormat:@"%ld", self.hostDelegate.getRoomInfo.roomId]]) {
|
|
|
|
|
return YES;
|
|
|
|
|
}
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-27 19:07:10 +08:00
|
|
|
|
#pragma mark - 添加数据并且做自动滚动
|
|
|
|
|
///添加信息
|
|
|
|
|
- (void)addRoomMessage:(NIMMessage *)message {
|
2021-10-29 10:50:39 +08:00
|
|
|
|
XPRoomMessageDisplayModel * model = [[XPRoomMessageDisplayModel alloc] initDisplayModel:message delefate:self];
|
2021-10-27 19:07:10 +08:00
|
|
|
|
[self.tempArray addObject:model];
|
|
|
|
|
///开始加入数据
|
|
|
|
|
[self tryToappendAndScrollToBottom];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 添加数据并滚动到底部
|
|
|
|
|
- (void)tryToappendAndScrollToBottom {
|
|
|
|
|
// 处于爬楼状态更新更多按钮
|
|
|
|
|
[self updateMessageTipsBtnHidden];
|
|
|
|
|
if (!self.isPending) {
|
|
|
|
|
// 如果不处在爬楼状态,追加数据源并滚动到底部
|
|
|
|
|
[self appendAndScrollToBottom];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///更新底部有新的消息按钮的状态
|
|
|
|
|
- (void)updateMessageTipsBtnHidden {
|
|
|
|
|
if (self.isPending && self.tempArray.count > 0) {
|
|
|
|
|
self.messageTipsBtn.hidden = NO;
|
|
|
|
|
} else {
|
|
|
|
|
self.messageTipsBtn.hidden = YES;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///追加数据源
|
|
|
|
|
- (void)appendAndScrollToBottom {
|
|
|
|
|
if (self.tempArray.count < 1) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// 执行插入
|
|
|
|
|
NSMutableArray *indexPaths = [NSMutableArray array];
|
|
|
|
|
for (XPRoomMessageDisplayModel *item in self.tempArray) {
|
|
|
|
|
[self.datasource addObject:item];
|
|
|
|
|
[indexPaths addObject:[NSIndexPath indexPathForRow:self.datasource.count - 1 inSection:0]];
|
|
|
|
|
}
|
|
|
|
|
[self.messageTableView reloadData];
|
|
|
|
|
[self.tempArray removeAllObjects];
|
|
|
|
|
|
|
|
|
|
//执行插入动画并滚动
|
|
|
|
|
[self scrollToBottom:YES];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
///执行插入动画并滚动
|
|
|
|
|
- (void)scrollToBottom:(BOOL)animated {
|
|
|
|
|
NSInteger s = [self.messageTableView numberOfSections]; //有多少组
|
|
|
|
|
if (s<1) return;
|
|
|
|
|
NSInteger r = [self.messageTableView numberOfRowsInSection:s-1]; //最后一组行
|
|
|
|
|
if (r<1) return;
|
|
|
|
|
NSIndexPath *ip = [NSIndexPath indexPathForRow:r-1 inSection:s-1]; //取最后一行数据
|
|
|
|
|
[self.messageTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionNone animated:animated]; //滚动到最后一行
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-29 10:50:39 +08:00
|
|
|
|
#pragma mark - NIMChatManagerDelegate
|
|
|
|
|
- (void)onRecvMessages:(NSArray<NIMMessage *> *)messages {
|
|
|
|
|
for (NIMMessage * message in messages) {
|
|
|
|
|
///房间内的消息
|
|
|
|
|
if (message.session.sessionType == NIMSessionTypeChatroom && [self isCurrentRoom:message.session.sessionId]) {
|
|
|
|
|
if (message.messageType == NIMMessageTypeText || message.messageType == NIMMessageTypeTip) {
|
|
|
|
|
[self addRoomMessage:message];
|
|
|
|
|
} else if (message.messageType == NIMMessageTypeNotification) {
|
|
|
|
|
NIMNotificationObject *notiMsg = (NIMNotificationObject *)message.messageObject;
|
|
|
|
|
NIMChatroomNotificationContent *content = (NIMChatroomNotificationContent *)notiMsg.content;
|
|
|
|
|
if (content.eventType == NIMChatroomEventTypeEnter) {
|
|
|
|
|
[self addRoomMessage:message];
|
|
|
|
|
}
|
|
|
|
|
}else if (message.messageType == NIMMessageTypeCustom) {// 如果是自定义消息
|
|
|
|
|
///TODO : 处理自定义消息
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-27 19:07:10 +08:00
|
|
|
|
#pragma mark - ScrollViewDelegate
|
|
|
|
|
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
|
|
|
|
|
// 手动拖拽开始
|
|
|
|
|
self.isPending = YES;
|
|
|
|
|
}
|
|
|
|
|
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
|
|
|
|
|
// 手动拖拽结束(decelerate:0松手时静止;1松手时还在运动,会触发DidEndDecelerating方法)
|
|
|
|
|
if (!decelerate) {
|
|
|
|
|
[self finishDraggingWith:scrollView];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
|
|
|
|
|
// 静止后触发(手动)
|
|
|
|
|
[self finishDraggingWith:scrollView];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 手动拖拽动作彻底完成(减速到零) */
|
|
|
|
|
- (void)finishDraggingWith:(UIScrollView *)scrollView {
|
|
|
|
|
CGFloat contentSizeH = scrollView.contentSize.height;
|
|
|
|
|
CGFloat contentOffsetY = scrollView.contentOffset.y;
|
|
|
|
|
CGFloat sizeH = scrollView.frame.size.height;
|
|
|
|
|
self.isPending = contentSizeH - contentOffsetY - sizeH > 20.0;
|
|
|
|
|
// 如果不处在爬楼状态,追加数据源并滚动到底部
|
|
|
|
|
[self tryToappendAndScrollToBottom];
|
2021-10-26 19:10:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-27 19:07:10 +08:00
|
|
|
|
|
2021-10-26 19:10:03 +08:00
|
|
|
|
#pragma mark - UITableViewDelegate And UITableViewDataSource
|
|
|
|
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
|
|
|
|
return self.datasource.count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
|
|
|
|
XPRoomMessageDisplayModel * model = [self.datasource objectAtIndex:indexPath.row];
|
|
|
|
|
return model.cellHeight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
|
|
|
|
XPRoomMessageTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([XPRoomMessageTableViewCell class])];
|
|
|
|
|
if (cell == nil) {
|
|
|
|
|
cell = [[XPRoomMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass([XPRoomMessageTableViewCell class])];
|
|
|
|
|
}
|
2021-10-27 19:07:10 +08:00
|
|
|
|
XPRoomMessageDisplayModel * model = [self.datasource objectAtIndex:indexPath.row];
|
|
|
|
|
cell.displayModel = model;
|
2021-10-26 19:10:03 +08:00
|
|
|
|
return cell;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-10-29 10:50:39 +08:00
|
|
|
|
- (void)xpRoomMessageDisplayModel:(XPRoomMessageDisplayModel *)displayModel loadImageSuccess:(UIImageView *)imageView {
|
|
|
|
|
NSInteger index = [self.datasource indexOfObject:displayModel];
|
|
|
|
|
XPRoomMessageTableViewCell * cell = [self.messageTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];
|
|
|
|
|
[self loadUrlImageSuccess:imageView cell:cell];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)xpRoomMessageDisplayModel:(XPRoomMessageDisplayModel *)displayModel didClickUser:(NSString *)userId {
|
|
|
|
|
NSLog(@"点击的用户%@", userId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)loadUrlImageSuccess:(UIImageView *)imageView cell:(XPRoomMessageTableViewCell *)cell {
|
|
|
|
|
CGSize size = CGSizeMake(kRoomMessageMaxWidth, CGFLOAT_MAX);
|
|
|
|
|
YYTextLayout *layout = [YYTextLayout layoutWithContainerSize:size text:cell.contentLabel.attributedText];
|
|
|
|
|
NSMutableAttributedString * attribute = [cell.contentLabel.attributedText mutableCopy];
|
|
|
|
|
if (layout.attachments.count > 0) {
|
|
|
|
|
for (int i = 0; i < layout.attachments.count; i++) {
|
|
|
|
|
YYTextAttachment * attachment = [layout.attachments objectAtIndex:i];
|
|
|
|
|
if (imageView == attachment.content) {
|
|
|
|
|
CGFloat kscale = (CGFloat)imageView.image.size.width / (CGFloat)imageView.image.size.height;
|
|
|
|
|
imageView.frame = CGRectMake(0, 0, 40 * kscale, 40);
|
|
|
|
|
attachment.content = imageView;
|
|
|
|
|
NSValue * value = [layout.attachmentRanges objectAtIndex:i];
|
|
|
|
|
NSRange range = value.rangeValue;
|
|
|
|
|
NSMutableAttributedString * resultString = [NSMutableAttributedString yy_attachmentStringWithContent:imageView contentMode:UIViewContentModeScaleAspectFit attachmentSize:imageView.image.size alignToFont:[UIFont systemFontOfSize:14.0] alignment:YYTextVerticalAlignmentCenter];
|
|
|
|
|
[attribute replaceCharactersInRange:range withAttributedString:resultString];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
cell.contentLabel.attributedText = nil;
|
|
|
|
|
cell.contentLabel.attributedText = attribute;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-10-26 19:10:03 +08:00
|
|
|
|
#pragma mark - Getters And Setters
|
|
|
|
|
- (UITableView *)messageTableView {
|
|
|
|
|
if (!_messageTableView) {
|
|
|
|
|
_messageTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
|
|
|
|
|
_messageTableView.delegate = self;
|
|
|
|
|
_messageTableView.dataSource = self;
|
|
|
|
|
_messageTableView.tableFooterView = [UIView new];
|
|
|
|
|
_messageTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
|
|
|
|
_messageTableView.backgroundColor = [UIColor clearColor];
|
2021-10-27 19:07:10 +08:00
|
|
|
|
_messageTableView.showsVerticalScrollIndicator = NO;
|
2021-10-26 19:10:03 +08:00
|
|
|
|
if (@available(iOS 11.0, *)) {
|
|
|
|
|
_messageTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
|
|
|
|
}
|
|
|
|
|
[_messageTableView registerClass:[XPRoomMessageTableViewCell class] forCellReuseIdentifier:NSStringFromClass([XPRoomMessageTableViewCell class])];
|
|
|
|
|
}
|
|
|
|
|
return _messageTableView;
|
2021-10-14 21:10:04 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-26 19:10:03 +08:00
|
|
|
|
- (XPRoomMessageHeaderView *)headerView {
|
|
|
|
|
if (!_headerView) {
|
|
|
|
|
_headerView = [[XPRoomMessageHeaderView alloc] init];
|
|
|
|
|
}
|
|
|
|
|
return _headerView;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-27 19:07:10 +08:00
|
|
|
|
- (UIButton *)messageTipsBtn {
|
|
|
|
|
if (!_messageTipsBtn) {
|
|
|
|
|
_messageTipsBtn = [UIButton buttonWithType:UIButtonTypeCustom];
|
|
|
|
|
[_messageTipsBtn setTitle:@"底部有新消息" forState:UIControlStateNormal];
|
|
|
|
|
[_messageTipsBtn setTitleColor:[ThemeColor appMainColor] forState:UIControlStateNormal];
|
|
|
|
|
_messageTipsBtn.layer.cornerRadius = 15.0;
|
|
|
|
|
_messageTipsBtn.layer.masksToBounds = YES;
|
|
|
|
|
_messageTipsBtn.titleLabel.font = [UIFont systemFontOfSize:12.0];
|
|
|
|
|
_messageTipsBtn.backgroundColor = [UIColor whiteColor];
|
|
|
|
|
[_messageTipsBtn addTarget:self action:@selector(messagTipsBtnAction:) forControlEvents:UIControlEventTouchUpInside];
|
|
|
|
|
_messageTipsBtn.hidden = YES;
|
|
|
|
|
}
|
|
|
|
|
return _messageTipsBtn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSMutableArray<XPRoomMessageDisplayModel *> *)datasource {
|
|
|
|
|
if (!_datasource) {
|
|
|
|
|
_datasource = [NSMutableArray array];
|
|
|
|
|
}
|
|
|
|
|
return _datasource;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSMutableArray<XPRoomMessageDisplayModel *> *)tempArray {
|
|
|
|
|
if (!_tempArray) {
|
|
|
|
|
_tempArray = [NSMutableArray array];
|
|
|
|
|
}
|
|
|
|
|
return _tempArray;
|
|
|
|
|
}
|
2021-10-26 19:10:03 +08:00
|
|
|
|
|
2021-10-14 21:10:04 +08:00
|
|
|
|
@end
|