Files
peko-ios/YuMi/Modules/YMRoom/View/MessageContainerView/XPRoomMessageContainerView.m
2025-01-07 20:07:54 +08:00

1642 lines
67 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// YMRoomMessageView.m
// YUMI
//
// Created by YUMI on 2021/10/11.
//
#import "XPRoomMessageContainerView.h"
///Third
#import <Masonry/Masonry.h>
#import <NIMSDK/NIMSDK.h>
///Tool
#import "DJDKMIMOMColor.h"
#import "YUMIMacroUitls.h"
#import "XPRoomMessageConstant.h"
#import "XPRoomMessageParser.h"
#import "AccountInfoStorage.h"
#import "XPRoomMiniManager.h"
#import "PLTimeUtil.h"
#import "ClientConfig.h"
#import <POP.h>
#import "ThemeColor+Room.h"
#import "NSArray+Safe.h"
#import "Api+Room.h"
///Model
#import "RoomInfoModel.h"
#import "AttachmentModel.h"
#import "RoomFaceSendInfoModel.h"
#import "XPMessageRemoteExtModel.h"
#import "RoomPKChooseUserModel.h"
#import "CandyTreeResultModel.h"
#import "RoomSailingPrizeModel.h"
#import "UserInfoModel.h"
#import "XPMessageInfoModel.h"
#import "GiftReceiveInfoModel.h"
#import "XPGiftStorage.h"
///View
#import "XPRoomMessageTableViewCell.h"
#import "XPRoomMessageHeaderView.h"
#import "PIRoomMessagePhotoAlbumCell.h"
#import "PIRoomMessageUnlockPhotoAlbumView.h"
#import "PIRoomPhotoAlbumItemModel.h"
#import "SDPhotoBrowser.h"
#import "XPSkillCardPlayerManager.h"
// Boom
#import "BoomInfoModel.h"
NSString * const kRoomShowTopicKey = @"kRoomShowTopicKey";
@interface XPRoomMessageContainerView ()<UITableViewDelegate, UITableViewDataSource, XPRoomMessageTableViewCellDelegate, UIGestureRecognizerDelegate,PIRoomMessagePhotoAlbumCellDelegate,SDPhotoBrowserDelegate,PIRoomMessageUnlockPhotoAlbumViewDelegate>
///房间的代理
@property (nonatomic,weak) id<RoomHostDelegate> hostDelegate;
///列表
@property (nonatomic,strong) UITableView *messageTableView;
///头部
@property (nonatomic,strong) XPRoomMessageHeaderView *headerView;
///底部有新的消息
@property (nonatomic,strong) UIButton *messageTipsBtn;
///有人at你
@property (nonatomic, strong) UIButton *atTipBtn;
///是否处于正在爬楼
@property (nonatomic,assign) BOOL isPending;
///是否是最小化进房的
@property (nonatomic,assign) BOOL isMiniEnter;
///数据源
@property (nonatomic,strong) NSMutableArray<XPMessageInfoModel *> *datasource;
@property (nonatomic,strong) NSMutableArray<XPMessageInfoModel *> *datasource_chat;
@property (nonatomic,strong) NSMutableArray<XPMessageInfoModel *> *datasource_gift;
///临时存放消息的数组
@property (nonatomic,strong) NSMutableArray *incomingMessages;
///有多少人at我
@property (nonatomic, assign) NSInteger atCount;
///@我的消息位置集合
@property (nonatomic, strong) NSMutableArray *locationArray;
///messageView 持有这个工具类 进行数据的分发操作 TODO: 有需要在改
@property (nonatomic,strong) XPRoomMessageParser *messageParser;
@property(nonatomic,strong) PIRoomPhotoAlbumItemModel *lookUpModel;
@property(nonatomic,assign) BOOL isLoadHistoryMessage;
@property (nonatomic, assign) NSInteger displayType;
@end
@implementation XPRoomMessageContainerView
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (instancetype)initWithDelegate:(id<RoomHostDelegate>)delegate {
self = [super init];
if (self) {
self.displayType = 1;
self.isLoadHistoryMessage = YES;
self.hostDelegate = delegate;
[self initSubViews];
[self initSubViewConstraints];
}
return self;
}
- (void)changeType:(NSInteger)type {
if (self.displayType == type) {
return;
}
self.displayType = type;
[self.messageTableView reloadData];
if (self.displayType == 1) {
self.messageTableView.tableHeaderView = self.headerView;
} else {
self.messageTableView.tableHeaderView = nil;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self scrollToBottom:YES];
});
}
/// 更新其他 tag 的数据源,若传入空数组,则初始化并从 datasource 中获取数据
- (void)updateAllDataSource:(NSArray *)datas {
if (!datas || datas.count == 0) {
self.datasource_chat = @[].mutableCopy;
self.datasource_gift = @[].mutableCopy;
datas = self.datasource;
}
for (XPMessageInfoModel *model in datas) {
switch (model.first) {
case NIMMessageTypeText:
[self.datasource_chat addObject:model];
break;
case CustomMessageType_Gift:
case CustomMessageType_RoomBoom:
case CustomMessageType_Candy_Tree:
case CustomMessageType_Super_Gift:
case CustomMessageType_AllMicroSend:
case CustomMessageType_Treasure_Fairy:
[self.datasource_gift addObject:model];
break;
}
}
}
- (UIView *)listView {
return self;
}
- (void)showUserCard:(NSInteger)uid{
[self.messageParser showUserCard:uid];
}
#pragma mark - Response
- (void)messageTipsBtnAction:(UIButton *)sender {
self.isPending = NO;
self.messageTipsBtn.hidden = YES;
[self appendAndScrollToBottom];
}
- (void)atTipsBtnAction:(UIButton *)sender {
self.isPending = YES;
[self appendAndScrollToAtUser];
}
///追加数据源
- (void)appendAndScrollToAtUser {
// 1. 检查 incomingMessages 是否为空
if (self.incomingMessages.count < 1) {
NSInteger rows = self.datasource.count;
// 2. 安全检查 locationArray 是否为空
if (self.locationArray.count == 0) {
[self scrollToBottomWithTipsHidden:YES];
return;
}
// 3. 获取首个 @ 消息的索引,并进行安全检查
int index = [self safeGetIndexFromLocationArrayAt:0];
if (index == NSNotFound) {
[self scrollToBottomWithTipsHidden:YES];
return;
}
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
if (rows > indexPath.row) {
[self.messageTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
if (rows == indexPath.row + 1) {
self.messageTipsBtn.hidden = YES;
self.isPending = NO;
}
} else {
[self scrollToBottomWithTipsHidden:YES];
}
[self safelyRemoveLocationAtIndex:0];
[self updateAtTipButton];
return;
}
// 4. 超长消息处理逻辑
if (self.datasource.count > kRoomMessageMaxLength) {
NSInteger removedCount = kRoomMessageMaxLength / 2;
[self safelyRemoveMessages:removedCount];
}
// 5. 插入新消息
NSMutableArray *indexPaths = @[].mutableCopy;
NSMutableArray *tempNewDatas = @[].mutableCopy;
for (id item in self.incomingMessages) {
XPMessageInfoModel *model = [self parseMessage:item];
if (!model) continue;
[tempNewDatas addObject:model];
[self.datasource addObject:model];
[indexPaths addObject:[NSIndexPath indexPathForRow:self.datasource.count - 1 inSection:0]];
[self processAtMentionsForMessage:item];
}
[self updateAllDataSource:tempNewDatas];
[self.incomingMessages removeAllObjects];
[self.messageTableView reloadData];
// 6. 滚动到指定位置或底部
[self scrollToFirstLocationOrBottom];
// if (self.incomingMessages.count < 1) {
// NSInteger rows = self.datasource.count;
// if (!self.locationArray.count) {
// [self.messageTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(rows-1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
// self.messageTipsBtn.hidden = YES;
// self.isPending = NO;
// self.atCount = 0;
// self.atTipBtn.hidden = YES;
// return;
// }
// int index = [self.locationArray[0] intValue];
// NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
// if (rows > indexPath.row) {
// [self.messageTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
// if (rows == indexPath.row + 1) {
// self.messageTipsBtn.hidden = YES;
// self.isPending = NO;
// }
// } else {
// [self.messageTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(rows-1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
// //滚动到底部时隐藏@提示
// self.messageTipsBtn.hidden = YES;
// }
// if (self.locationArray.count) {
// [self.locationArray removeObjectAtIndex:0];
// self.atCount -= 1;
// [self.atTipBtn setTitle:[NSString stringWithFormat:YMLocalizedString(@"XPRoomMessageContainerView0"), (unsigned long)self.locationArray.count] forState:UIControlStateNormal];
// if (self.locationArray.count == 0) {
// self.atTipBtn.hidden = YES;
// }
// } else {
// self.atTipBtn.hidden = YES;
// }
// } else {
// if (self.datasource.count > kRoomMessageMaxLength) {
// NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, kRoomMessageMaxLength/2)];
// NSArray *needRemoveMsgArray = [self.datasource objectsAtIndexes:set];
// [self.datasource removeObjectsInArray:needRemoveMsgArray];
// [self updateAllDataSource:nil];
// NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
// for (int i = 0; i<self.locationArray.count; i++) {///移除掉前面消息的数据后前面如果有at我的消息也一并移除掉
// NSNumber *number = self.locationArray[i];
// if (number.integerValue < kRoomMessageMaxLength / 2) {
// self.atCount--;
// [indexSet addIndex:i];
// }
// }
// [self.locationArray removeObjectsAtIndexes:indexSet];
// for (int i = 0; i<self.locationArray.count; i++) {//移除前面的at消息后,后面的at消息需要更新索引
// NSNumber *number = self.locationArray[i];
// number = @(number.integerValue - kRoomMessageMaxLength / 2);
// [self.locationArray replaceObjectAtIndex:i withObject:number];
// }
// }
//
// // 执行插入
// NSMutableArray *indexPaths = @[].mutableCopy;
// NSMutableArray *tempNewDatas = @[].mutableCopy;
// for (id item in self.incomingMessages) {
// XPMessageInfoModel *model = nil;
// if ([item isKindOfClass:[NIMMessage class]]) {
// model = [self.messageParser parseMessageAttribute:item];
// } else if ([item isKindOfClass:[NIMBroadcastMessage class]]) {
// model = [self.messageParser parseBroadcastMessageAttribute:item];
// }
// if (!model) {
// continue;
// }
// [tempNewDatas addObject:model];
// [self.datasource addObject:model];
// [indexPaths addObject:[NSIndexPath indexPathForRow:self.datasource.count - 1 inSection:0]];
// if ([item isKindOfClass:[NIMMessage class]]) {
// id nickNameInfos = [(NIMMessage*)item remoteExt][@"atUids"];
// if ([nickNameInfos isKindOfClass:[NSArray class]]) {
// for (NSString *nick in nickNameInfos) {
// if ([nick isEqualToString:[AccountInfoStorage instance].getUid]) {
// [self.locationArray addObject:@(self.datasource.count-1)];
// }
// }
// }
// }
// }
// [self updateAllDataSource:tempNewDatas];
// [self.incomingMessages removeAllObjects];
// [self.messageTableView reloadData];
//
// NSInteger rows = self.datasource.count;
// if (!self.locationArray.count) {
// [self.messageTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(rows-1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
// self.messageTipsBtn.hidden = YES;
// self.isPending = NO;
// self.atCount = 0;
// self.atTipBtn.hidden = YES;
// return;
// }
//
// int index = [self.locationArray[0] intValue];
// NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
// if (rows > indexPath.row) {
// [self.messageTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
// if (rows == indexPath.row + 1) {
// self.messageTipsBtn.hidden = YES;
// self.isPending = NO;
// }
// } else {
// [self.messageTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(rows-1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
// //滚动到底部时隐藏@提示
// self.messageTipsBtn.hidden = YES;
// }
// if (self.locationArray.count) {
// [self.locationArray removeObjectAtIndex:0];
// self.atCount -= 1;
// [self.atTipBtn setTitle:[NSString stringWithFormat:YMLocalizedString(@"XPRoomMessageContainerView1"), (unsigned long)self.locationArray.count] forState:UIControlStateNormal];
// if (self.locationArray.count == 0) {
// self.atTipBtn.hidden = YES;
// }
// } else {
// self.atTipBtn.hidden = YES;
// }
// }
}
- (void)scrollToBottomWithTipsHidden:(BOOL)hidden {
NSInteger rows = self.datasource.count;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(rows - 1) inSection:0];
[self.messageTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
self.messageTipsBtn.hidden = hidden;
self.isPending = NO;
self.atCount = 0;
self.atTipBtn.hidden = hidden;
}
- (void)updateLocationArrayForMessageRemoval:(NSInteger)removedCount {
NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
for (int i = 0; i < self.locationArray.count; i++) {
NSNumber *number = self.locationArray[i];
if (number.integerValue < removedCount) {
self.atCount--;
[indexSet addIndex:i];
}
}
[self.locationArray removeObjectsAtIndexes:indexSet];
for (int i = 0; i < self.locationArray.count; i++) {
NSNumber *number = self.locationArray[i];
self.locationArray[i] = @(number.integerValue - removedCount);
}
}
- (void)updateAtTipButton {
if (self.locationArray.count == 0) {
self.atTipBtn.hidden = YES;
} else {
[self.atTipBtn setTitle:[NSString stringWithFormat:YMLocalizedString(@"XPRoomMessageContainerView0"), (unsigned long)self.locationArray.count] forState:UIControlStateNormal];
self.atTipBtn.hidden = NO;
}
}
- (int)safeGetIndexFromLocationArrayAt:(NSUInteger)index {
if (index < self.locationArray.count) {
NSNumber *number = self.locationArray[index];
return [number intValue];
}
return NSNotFound; // 返回一个无效值,避免崩溃
}
- (void)safelyRemoveLocationAtIndex:(NSUInteger)index {
if (index < self.locationArray.count) {
[self.locationArray removeObjectAtIndex:index];
self.atCount = MAX(0, self.atCount - 1);
}
}
- (void)safelyRemoveMessages:(NSInteger)count {
if (self.datasource.count >= count) {
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, count)];
[self.datasource removeObjectsAtIndexes:set];
[self updateAllDataSource:nil];
// 更新 locationArray
NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
for (NSUInteger i = 0; i < self.locationArray.count; i++) {
NSNumber *number = self.locationArray[i];
if (number.integerValue < count) {
[indexSet addIndex:i];
} else {
self.locationArray[i] = @(number.integerValue - count);
}
}
[self.locationArray removeObjectsAtIndexes:indexSet];
}
}
- (XPMessageInfoModel *)parseMessage:(id)item {
if ([item isKindOfClass:[NIMMessage class]]) {
return [self.messageParser parseMessageAttribute:item];
} else if ([item isKindOfClass:[NIMBroadcastMessage class]]) {
return [self.messageParser parseBroadcastMessageAttribute:item];
}
return nil;
}
- (void)processAtMentionsForMessage:(id)item {
if ([item isKindOfClass:[NIMMessage class]]) {
NSArray *nickNameInfos = [(NIMMessage *)item remoteExt][@"atUids"];
if ([nickNameInfos isKindOfClass:[NSArray class]]) {
for (NSString *nick in nickNameInfos) {
if ([nick isEqualToString:[AccountInfoStorage instance].getUid]) {
[self.locationArray addObject:@(self.datasource.count - 1)];
}
}
}
}
}
- (void)scrollToFirstLocationOrBottom {
NSInteger rows = self.datasource.count;
if (self.locationArray.count == 0) {
[self scrollToBottomWithTipsHidden:YES];
return;
}
int index = [self safeGetIndexFromLocationArrayAt:0];
if (index == NSNotFound || index >= rows) {
[self scrollToBottomWithTipsHidden:YES];
} else {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
[self.messageTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
[self safelyRemoveLocationAtIndex:0];
}
[self updateAtTipButton];
}
#pragma mark - @我
///查找有多少人@我
- (void)findAtMeNumber {
if (self.incomingMessages.count) {
NIMMessage *message = self.incomingMessages.lastObject;
if (![message isKindOfClass:[NIMMessage class]] || ![message respondsToSelector:@selector(remoteExt)]) {
return;
}
id nickNameNifo = message.remoteExt[@"atUids"];
if ([nickNameNifo isKindOfClass:[NSArray class]]) {
for (NSString *nick in nickNameNifo) {
if ([nick isEqualToString:[AccountInfoStorage instance].getUid]) {
self.atCount += 1;
}
}
}
if (self.atCount > 0) {
self.atTipBtn.hidden = NO;
[self.atTipBtn setTitle:[NSString stringWithFormat:YMLocalizedString(@"XPRoomMessageContainerView2"), self.atCount] forState:UIControlStateNormal];
} else {
self.atTipBtn.hidden = YES;
}
}
}
#pragma mark - Private Method
- (void)initSubViews {
self.clipsToBounds = YES;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addCustomMessage:) name:@"message" object:nil];
[self addSubview:self.messageTableView];
[self addSubview:self.messageTipsBtn];
[self addSubview:self.atTipBtn];
self.messageTableView.tableHeaderView = self.headerView;
}
- (void)initSubViewConstraints {
RoomInfoModel *infoModel = self.hostDelegate.getRoomInfo;
CGFloat top = infoModel.type == RoomType_MiniGame ? 0 : 10;
[self.messageTableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(self).offset(15);
make.bottom.trailing.mas_equalTo(self);
make.top.equalTo(self).mas_offset(top);
}];
[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.leading.mas_equalTo(self);
}];
[self.atTipBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(100);
make.height.mas_equalTo(30);
make.bottom.mas_equalTo(self.mas_bottom).offset(-5);
make.leading.mas_equalTo(self);
}];
}
///是否是当前房间
- (BOOL)isCurrentRoom:(NSString *)sessionId {
if ([sessionId isEqualToString:[NSString stringWithFormat:@"%ld", self.hostDelegate.getRoomInfo.roomId]]) {
return YES;
}
return NO;
}
///判断是否隐身进房
- (BOOL)handleHideEnter:(NIMMessage *)message {
NIMMessageChatroomExtension * messageExt = (NIMMessageChatroomExtension *)message.messageExt;
NSDictionary * dic = [(NSDictionary *)messageExt.roomExt.toJSONObject objectForKey:message.from];
XPMessageRemoteExtModel * extModel = [XPMessageRemoteExtModel modelWithJSON:dic];
return (extModel.enterHide || extModel.platformRole == 1);
}
#pragma mark - 添加数据并且做自动滚动
///添加信息
- (void)addRoomMessage:(id)messageData {
if(self.isLoadHistoryMessage == YES)return;
[self.incomingMessages addObject:messageData];
NSInteger messageCount = 0;
switch (self.displayType) {
case 1:
messageCount = self.datasource.count;
break;
case 2:
messageCount = self.datasource_chat.count;
break;
case 3:
messageCount = self.datasource_gift.count;
break;
default:
break;
}
if ([messageData isKindOfClass:[NIMBroadcastMessage class]]) {
NIMBroadcastMessage *broadcastMessage = (NIMBroadcastMessage *)messageData;
[[XPRoomMiniManager shareManager] saveRoomMessage:broadcastMessage];
} else if ([messageData isKindOfClass:[NIMMessage class]]) {
NIMMessage *message = (NIMMessage *)messageData;
if (!self.isMiniEnter) {/// 最小化进房的话 不需要重新保存
if (self.hostDelegate.getRoomInfo.isCloseScreen) {
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) {
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
if (attachment.first == CustomMessageType_Update_RoomInfo &&
attachment.second == Custom_Message_Sub_Update_RoomInfo_MessageState){
[[XPRoomMiniManager shareManager] saveRoomMessage:message];
}
}
} else {
[[XPRoomMiniManager shareManager] saveRoomMessage:message];
}
}
}
if (self.isPending) {
// switch (self.displayType) {
// case 1:
// self.messageTipsBtn.hidden = self.datasource.count == messageCount;
// break;
// case 2:
// self.messageTipsBtn.hidden = self.datasource_chat.count == messageCount;
// break;
// case 3:
// self.messageTipsBtn.hidden = self.datasource_gift.count == messageCount;
// break;
// default:
// break;
// }
self.messageTipsBtn.hidden = NO;
[self findAtMeNumber];
} else {
[self appendAndScrollToBottom];
}
}
///追加数据源
- (void)appendAndScrollToBottom {
if (self.incomingMessages.count < 1) {
///滚动到底部如果有人at自己后income消息在点击at按钮处做了拼接处理因为点击at按钮跳转到的是对应的at人消息如果后面有其他消息时点有更多按钮时需要滚动到最底部
[self scrollToBottom:YES];
return;
}
if (self.datasource.count > kRoomMessageMaxLength) {
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, kRoomMessageMaxLength/2)];
NSArray *needRemoveMsgArray = [self.datasource objectsAtIndexes:set];
[self.datasource removeObjectsInArray:needRemoveMsgArray];
}
NSMutableArray *tempArray = @[].mutableCopy;
@kWeakify(self);
[self.incomingMessages enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
@kStrongify(self);
id model = nil;
if ([obj isKindOfClass:[NIMMessage class]]) {
model = [self.messageParser parseMessageAttribute:(NIMMessage *)obj];
} else if ([obj isKindOfClass:[NIMBroadcastMessage class]]) {
model = [self.messageParser parseBroadcastMessageAttribute:(NIMBroadcastMessage *)obj];
}
if (model) {
[tempArray addObject:model];
[self.datasource addObject:model];
}
}];
[self.incomingMessages removeAllObjects];
[self updateAllDataSource:tempArray];
[self.messageTableView reloadData];
//执行插入动画并滚动
[self scrollToBottom:NO];
}
///执行插入动画并滚动
- (void)scrollToBottom:(BOOL)animated {
NSArray *source = @[];
switch (self.displayType) {
case 1:
source = self.datasource;
break;
case 2:
source = self.datasource_chat;
break;
case 3:
source = self.datasource_gift;
break;
default:
source = self.datasource;
break;
}
if(source.count > 0){
NSIndexPath *ip = [NSIndexPath indexPathForRow:source.count-1 inSection:0]; //取最后一行数据
[self.messageTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:animated]; //滚动到最后一行
self.atCount = 0;
self.atTipBtn.hidden = YES;
[self.locationArray removeAllObjects];
}
}
///自定义消息 是否可以加到 公屏 需要自己维护
- (BOOL)isCanDisplayMessage:(NIMMessage *)message {
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) {
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
if (attachment.first == CustomMessageType_Face && attachment.second == Custom_Message_Sub_Face_Send) {
if ([attachment.data[@"data"] isKindOfClass:[NSArray class]]) {
NSArray * array = [RoomFaceSendInfoModel modelsWithArray:attachment.data[@"data"]];
for (int i = 0; i< array.count; i++) {
RoomFaceSendInfoModel * sendInfo = [array xpSafeObjectAtIndex:i];
if (sendInfo.resultIndexes.count <=0) {
return NO;
}
}
}
}else if (attachment.first == CustomMessageType_Room_PK && attachment.second == Custom_Message_Sub_Room_PK_Manager_Up_Mic) {
if (attachment.data && [attachment.data allKeys].count > 0) {
for (NSDictionary * dic in [attachment.data allValues]) {
RoomPKChooseUserModel * userModel = [RoomPKChooseUserModel modelWithDictionary:dic];
if (userModel.groupType == GroupType_Red || userModel.groupType == GroupType_Blue) {
return YES;
}
}
}
return NO;
} else if(attachment.first == CustomMessageType_Room_Sailing && (attachment.second == Custom_Message_Sub_Sailing_AllRoom_Notify || attachment.second == Custom_Message_Sub_Sailing_InRoom_NeedAllMicSend)) {
RoomSailingPrizeModel * prizeModel = [RoomSailingPrizeModel modelWithDictionary:attachment.data];
if (self.hostDelegate.getUserInfo.userLevelVo.experLevelSeq > prizeModel.userLevelLimit) {
return YES;
}
} else if(attachment.first == CustomMessageType_Room_Album){
return YES;
}else if(attachment.first == CustomMessageType_Gift) {
if(attachment.data[@"isRoomAlbum"] != nil){
BOOL isRoomAlbum = [attachment.data[@"isRoomAlbum"] boolValue];
if(isRoomAlbum == YES){
return NO;
}
}
GiftReceiveInfoModel *info = [GiftReceiveInfoModel modelWithJSON:attachment.data];
GiftInfoModel *giftInfo = info.gift == nil ? info.giftInfo : info.gift;
if (giftInfo == nil) {
giftInfo = [[XPGiftStorage shareStorage] findGiftInfo:info.giftId];
}
if (giftInfo.giftType == GiftType_super){
return NO;
}
}else if(attachment.first == CustomMessageType_AllMicroSend){
GiftReceiveInfoModel *info = [GiftReceiveInfoModel modelWithJSON:attachment.data];
GiftInfoModel *giftInfo = info.gift == nil ? info.giftInfo : info.gift;
if (giftInfo == nil) {
giftInfo = [[XPGiftStorage shareStorage] findGiftInfo:info.giftId];
}
if (giftInfo.giftType == GiftType_super){
return NO;
}
}
return [[[self supportMessageDic] objectForKey:@(attachment.first)] containsObject:@(attachment.second)];
}
return NO;
}
- (NSDictionary *)supportMessageDic {
return @{
@(CustomMessageType_AllMicroSend):
[NSSet setWithObjects:
@(Custom_Message_Sub_AllMicroSend),
@(Custom_Message_Sub_AllMicroLuckySend),
@(Custom_Message_Sub_AllBatchSend),
@(Custom_Message_Sub_AllBatchMicroLuckySend),
nil],
@(CustomMessageType_Gift):
[NSSet setWithObjects:
@(Custom_Message_Sub_Gift_Send),
@(Custom_Message_Sub_Gift_LuckySend),
nil],
@(CustomMessageType_Room_Tip):
[NSSet setWithObjects:
@(Custom_Message_Sub_Room_Tip_ShareRoom),
@(Custom_Message_Sub_Room_Tip_Attention_Owner),
nil],
@(CustomMessageType_Kick_User):
[NSSet setWithObjects:
@(Custom_Message_Sub_Kick_BeKicked),
@(Custom_Message_Sub_Kick_BlackList),
nil],
@(CustomMessageType_Queue):
[NSSet setWithObjects:
@(Custom_Message_Sub_Queue_Kick),
nil],
@(CustomMessageType_Look_Love):
[NSSet setWithObjects:
@(Custom_Message_Sub_Look_Love_Me),
@(Custom_Message_Sub_Look_Love_InRoom),
@(Custom_Message_Sub_Look_Love_AllRoom),
@(Custom_Message_Sub_Look_Love_AllRoom_Notify),
@(Custom_Message_Sub_Look_Love_InRoom_NeedAllMicSend),
nil],
@(CustomMessageType_Arrange_Mic):
[NSSet setWithObjects:
@(Custom_Message_Sub_Arrange_Mic_Mode_Open),
@(Custom_Message_Sub_Arrange_Mic_Mode_Close),
@(Custom_Message_Sub_Arrange_Mic_Free_Mic_Open),
@(Custom_Message_Sub_Arrange_Mic_Free_Mic_Close),
nil],
@(CustomMessageType_Update_RoomInfo):
[NSSet setWithObjects:
@(Custom_Message_Sub_Update_RoomInfo_MessageState),
@(Custom_Message_Sub_Update_RoomInfo_AnimateEffect),
nil],
@(CustomMessageType_Collection_Room):
[NSSet setWithObjects:
@(Custom_Message_Sub_Collect_Room_Tips),
nil],
@(CustomMessageType_RoomPlay_Dating):
[NSSet setWithObjects:
@(Custom_Message_Sub_Room_Play_Dating_Pick_Heart),
@(Custom_Message_Sub_Room_Play_Dating_Result_Mutual),
@(Custom_Message_Sub_Room_Play_Dating_Result_Not_Mutual),
nil],
@(CustomMessageType_Noble_VIP):
[NSSet setWithObjects:
@(Custom_Message_Sub_Room_Open_Noble_VIP),
@(Custom_Message_Sub_Room_Noble_LevelUp),
@(Custom_Message_Sub_AllRoom_Noble_LevelUp_Suspend),
nil],
@(CustomMessageType_Face):
[NSSet setWithObjects:
@(Custom_Message_Sub_Face_Send),
nil],
@(CustomMessageType_Anchor_FansTeam):
[NSSet setWithObjects:
@(Custom_Message_Sub_FansTeam_Open_Success),
@(Custom_Message_Sub_FansTeam_Open_Fail),
@(Custom_Message_Sub_FansTeam_Join_Success),
@(Custom_Message_Sub_FansTeam_Out_Success),
nil],
@(CustomMessageType_Hall_Super_Admin):
[NSSet setWithObjects:
@(Custom_Message_Sub_Hall_Super_Admin_Kick_Manager_Out_Room),
nil],
@(CustomMessageType_Room_PK):
[NSSet setWithObjects:
@(Custom_Message_Sub_Room_PK_Manager_Up_Mic),
@(Custom_Message_Sub_Room_PK_Mode_Close),
@(Custom_Message_Sub_Room_PK_Result),
@(Custom_Message_Sub_Room_PK_Mode_Open),
@(Custom_Message_Sub_Room_PK_Start),
@(Custom_Message_Sub_Room_PK_Re_Start),
nil],
@(CustomMessageType_LuckyBag):
[NSSet setWithObjects:
@(Custom_Message_Sub_Room_Gift_LuckBag_Server),
@(Custom_Message_Sub_Room_Gift_LuckBag_FullScree),
nil],
@(CustomMessageType_Gift_Compound):
[NSSet setWithObjects:@(Custom_Message_Sub_Gift_Compound),
nil],
@(CustomMessageType_Tarot):
[NSSet setWithObjects:
@(Custom_Message_Sub_Tarot_Novice),
@(Custom_Message_Sub_Tarot_Advanced),
@(Custom_Message_Sub_Tarot_Intermediate),
nil],
@(CustomMessageType_Room_Sailing):
[NSSet setWithObjects:
@(Custom_Message_Sub_Sailing_Me),
@(Custom_Message_Sub_Sailing_InRoom),
@(Custom_Message_Sub_Sailing_AllRoom),
@(Custom_Message_Sub_Sailing_AllRoom_Notify),
@(Custom_Message_Sub_Sailing_InRoom_NeedAllMicSend),
nil],
@(CustomMessageType_RedPacket):
[NSSet setWithObjects:
@(Custom_Message_Sub_OpenRedPacketSuccess),
nil],
@(CustomMessageType_Treasure_Fairy):
[NSSet setWithObjects:
@(Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L1),
@(Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L2),
@(Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L3),
@(Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L4),
@(Custom_Message_Sub_Treasure_Fairy_Draw_Gift_L5),
@(Custom_Message_Sub_Treasure_Fairy_Draw_Ball_L1),
@(Custom_Message_Sub_Treasure_Fairy_Draw_Ball_L2),
@(Custom_Message_Sub_Treasure_Fairy_Draw_Ball_L3),
@(Custom_Message_Sub_Treasure_Fairy_Convert_L1),
@(Custom_Message_Sub_Treasure_Fairy_Convert_L2),
@(Custom_Message_Sub_Treasure_Fairy_Convert_L3),
nil],
@(CustomMessageType_Guardian_Planet):
[NSSet setWithObjects:
@(Custom_Message_Sub_Guardian_Planet_One_Room),
@(Custom_Message_Sub_Guardian_Planet_All_Room),
nil],
@(CustomMessageType_General_Public_Screen):
[NSSet setWithObjects:
@(Custom_Message_Sub_General_Public_Screen_One_Room),
@(Custom_Message_Sub_General_Public_Screen_All_Room),
nil],
@(CustomMessageType_Super_Gift):
[NSSet setWithObjects:
@(Custom_Message_Sub_Super_Gift),
nil],
};
}
- (void)addCustomMessage:(NSNotification *)notification {
self.isMiniEnter = NO;
if (self.hostDelegate.getRoomInfo.isCloseScreen) {return;}
NIMMessage * message = notification.object;
[self addRoomMessage:message];
}
///用户进入房间显示 房间话题
- (void)createUserEnterRoomAddRoomTopicMessage {
if ([ClientConfig shareConfig].configInfo.hideNoticeVersion == YES) {
return;
}
RoomInfoModel * roomInfo = self.hostDelegate.getRoomInfo;
if (roomInfo.uid == [AccountInfoStorage instance].getUid.integerValue) {return;}
NSString * key = [NSString stringWithFormat:@"%@_%@_%ld", kRoomShowTopicKey, [AccountInfoStorage instance].getUid, roomInfo.uid];
NSDate * oldDate = [[NSUserDefaults standardUserDefaults] valueForKey:key];
NSDate * date = [NSDate date];
if (roomInfo.introduction.length > 0) {
if (oldDate) {
NSDateComponents *compons = [PLTimeUtil compareTwoDate:date secondDate:[NSDate date]];
if (ABS(compons.year) > 0 || ABS(compons.month) > 0 || ABS(compons.day) > 0) {
NIMMessage * message = [[NIMMessage alloc] init];
NIMTipObject *tipObject = [[NIMTipObject alloc] init];
message.messageObject = tipObject;
NSString * content = [NSString stringWithFormat:YMLocalizedString(@"XPRoomMessageContainerView3"), roomInfo.introduction];
message.text = content;
message.localExt = @{@"isRoomTopic": @(NO)};
[message setValue:@(NIMMessageTypeTip) forKey:@"messageType"];
[message setValue:[NIMSession session:[NSString stringWithFormat:@"%ld", roomInfo.roomId] type:NIMSessionTypeChatroom] forKey:@"session"];
[self addRoomMessage:message];
[[NSUserDefaults standardUserDefaults] setValue:@(YES) forKey:key];
[[NSUserDefaults standardUserDefaults] synchronize];
}
} else {
NIMMessage * message = [[NIMMessage alloc] init];
NSString * content = [NSString stringWithFormat:YMLocalizedString(@"XPRoomMessageContainerView3"), roomInfo.introduction];
message.text = content;
message.localExt = @{@"isRoomTopic": @(NO)};
[message setValue:@(NIMMessageTypeTip) forKey:@"messageType"];
[message setValue:[NIMSession session:[NSString stringWithFormat:@"%ld", roomInfo.roomId] type:NIMSessionTypeChatroom] forKey:@"session"];
[self addRoomMessage:message];
[[NSUserDefaults standardUserDefaults] setValue:@(YES) forKey:key];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
NIMMessage * message = [[NIMMessage alloc] init];
NIMTipObject *tipObject = [[NIMTipObject alloc] init];
message.messageObject = tipObject;
message.text = YMLocalizedString(@"XPRoomMessageContainerView5");
message.localExt = @{@"isRoomTopic": @(YES)};
[message setValue:@(NIMMessageTypeTip) forKey:@"messageType"];
[message setValue:[NIMSession session:[NSString stringWithFormat:@"%ld", roomInfo.roomId] type:NIMSessionTypeChatroom] forKey:@"session"];
[self addRoomMessage:message];
}
- (void)handleBroadcastMessageAttachment:(AttachmentModel *)attachment; {
// if (attachment.first == CustomMessageType_RoomBoom) {
// Boom632Model *m = [Boom632Model modelWithJSON:attachment.data];
// NIMMessage * message = [[NIMMessage alloc] init];
// message.text = YMLocalizedString(@"XPRoomMessageContainerView5");
// message.localExt = @{@"isRoomTopic": @(YES)};
// [message setValue:@(NIMMessageTypeTip) forKey:@"messageType"];
// [message setValue:[NIMSession session:[NSString stringWithFormat:@"%ld", roomInfo.roomId] type:NIMSessionTypeChatroom] forKey:@"session"];
// [self addRoomMessage:message];
// }
}
- (void)handleBroadcastMessage:(NIMBroadcastMessage *)message {
[self addRoomMessage:message];
}
#pragma mark - RoomGuestDelegate
- (void)handleNIMCustomAttachment:(AttachmentModel *)attachment{
}
- (void)handleNIMCustomMessage:(NIMMessage *)message {
self.isMiniEnter = NO;
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) {
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
if (attachment.first == CustomMessageType_Update_RoomInfo &&
attachment.second == Custom_Message_Sub_Update_RoomInfo_MessageState) {
[self.datasource removeAllObjects];
[self updateAllDataSource:nil];
[self.incomingMessages removeAllObjects];
[self.locationArray removeAllObjects];
self.atCount = 0;
self.atTipBtn.hidden = YES;
self.messageTipsBtn.hidden = YES;
self.isPending = NO;
[[XPRoomMiniManager shareManager] resetLocalMessage];
[self addRoomMessage:message];
return;
} else if (attachment.first == CustomMessageType_Update_RoomInfo &&
attachment.second == Custom_Message_Sub_Update_RoomInfo_CleanScreen) {
[self.datasource removeAllObjects];
[self updateAllDataSource:nil];
[self.incomingMessages removeAllObjects];
[self.locationArray removeAllObjects];
self.atCount = 0;
self.atTipBtn.hidden = YES;
self.messageTipsBtn.hidden = YES;
self.isPending = NO;
[[XPRoomMiniManager shareManager] resetLocalMessage];
[self addRoomMessage:message];
return;
} else if(attachment.first == CustomMessageType_Candy_Tree &&
attachment.second == Custom_Message_Sub_Candy_Tree_Me) {
CandyTreeGiftInfoModel * model = [CandyTreeGiftInfoModel modelWithDictionary:attachment.data];
if (model.uid.integerValue != [AccountInfoStorage instance].getUid.integerValue) {
return;
}
} else if (attachment.first == CustomMessageType_Kick_User) {
NSString * uid = [AccountInfoStorage instance].getUid;
NSString * roomId = [NSString stringWithFormat:@"%ld", self.hostDelegate.getRoomInfo.roomId];
NIMChatroomMembersByIdsRequest *request = [[NIMChatroomMembersByIdsRequest alloc]init];
request.roomId = roomId;
request.userIds = @[uid];
[[NIMSDK sharedSDK].chatroomManager fetchChatroomMembersByIds:request completion:^(NSError * _Nullable error, NSArray<NIMChatroomMember *> * _Nullable members) {
if (error == nil) {
NIMChatroomMember * member = members.firstObject;
BOOL isCreator = member.type == NIMChatroomMemberTypeCreator;
BOOL isManager = member.type == NIMChatroomMemberTypeManager;
if (isCreator || isManager) {
[self addRoomMessage:message];
}
}
}];
return;
}
}
if (self.hostDelegate.getRoomInfo.isCloseScreen) {
return;
}
if ([self isCanDisplayMessage:message]) {
[self addRoomMessage:message];
}
}
- (void)handleNIMNotificationMessage:(NIMMessage *)message {
self.isMiniEnter = NO;
NIMNotificationObject *notiMsg = (NIMNotificationObject *)message.messageObject;
if (![notiMsg.content isKindOfClass:[NIMChatroomNotificationContent class]]) {
return;
}
NIMChatroomNotificationContent *content = (NIMChatroomNotificationContent *)notiMsg.content;
RoomInfoModel *roomInfo = self.hostDelegate.getRoomInfo;
if (content.eventType == NIMChatroomEventTypeEnter) {
if (roomInfo.isCloseScreen) {
self.isLoadHistoryMessage = NO;
AttachmentModel *attachment = [[AttachmentModel alloc]init];
attachment.first = CustomMessageType_Update_RoomInfo;
attachment.second = Custom_Message_Sub_Update_RoomInfo_MessageState;
attachment.data = @{@"roomInfo":self.hostDelegate.getRoomInfo.model2dictionary};
NIMMessage *message = [[NIMMessage alloc]init];
NIMCustomObject *object = [[NIMCustomObject alloc] init];
object.attachment = attachment;
message.messageObject = object;
[self addRoomMessage:message];
return;
} else {
NIMChatroomNotificationMember *member = content.targets[0];
if (member.userId.integerValue == [AccountInfoStorage instance].getUid.integerValue) {
///自己进房成功后拉取历史消息
if(self.datasource.count > 0)
{
self.isLoadHistoryMessage = NO;
return;
}
[self handleFetchHistoryMessage:message];
} else {
self.isLoadHistoryMessage = NO;
BOOL hideEnter = [self handleHideEnter:message];
if (!hideEnter) {
///插入进房消息及房间公告提示
[self addRoomMessage:message];
}
}
}
} else if(content.eventType == NIMChatroomEventTypeInfoUpdated) {
if (roomInfo.isCloseScreen) {return;}
if (roomInfo.datingState == RoomDatingStateChangeType_Open) {
NSString * uid = [AccountInfoStorage instance].getUid;
NSString * roomId = [NSString stringWithFormat:@"%ld", roomInfo.roomId];
NIMChatroomMembersByIdsRequest *request = [[NIMChatroomMembersByIdsRequest alloc]init];
request.roomId = roomId;
request.userIds = @[uid];
[[NIMSDK sharedSDK].chatroomManager fetchChatroomMembersByIds:request completion:^(NSError * _Nullable error, NSArray<NIMChatroomMember *> * _Nullable members) {
if (error == nil) {
NIMChatroomMember * member = members.firstObject;
BOOL isCreator = member.type == NIMChatroomMemberTypeCreator;
BOOL isManager = member.type == NIMChatroomMemberTypeManager;
if (isCreator || isManager) {
[self addRoomMessage:message];
}
}
}];
}
}
}
- (void)handleFetchNewestMessage:(NIMMessage *)message {
RoomInfoModel * roomInfo = self.hostDelegate.getRoomInfo;
NSString *roomId = [NSString stringWithFormat:@"%ld", self.hostDelegate.getRoomInfo.roomId];
NIMHistoryMessageSearchOption *option = [[NIMHistoryMessageSearchOption alloc] init];
option.limit = [ClientConfig shareConfig].configInfo.roomMessageCount;
option.order = NIMMessageSearchOrderDesc;
option.messageTypes = @[@(NIMMessageTypeText),@(NIMMessageTypeCustom)];
@kWeakify(self);
[[NIMSDK sharedSDK].chatroomManager fetchMessageHistory:roomId
option:option
result:^(NSError * _Nullable error, NSArray<NIMMessage *> * _Nullable messages) {
@kStrongify(self);
if(error != nil){
self.isLoadHistoryMessage = NO;
}
if (self.datasource.count > kRoomMessageMaxLength) {
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, kRoomMessageMaxLength/2)];
NSArray *needRemoveMsgArray = [self.datasource objectsAtIndexes:set];
[self.datasource removeObjectsInArray:needRemoveMsgArray];
}
// 执行插入
for (NIMMessage *item in messages.reverseObjectEnumerator) {
[self dealWithHistoryDataWithMessage:item];
}
self.isLoadHistoryMessage = NO;
BOOL hideEnter = [self handleHideEnter:message];
if (!hideEnter) {
///插入进房消息及房间公告提示
[self addRoomMessage:message];
}
if (!roomInfo.hasAnimationEffect) {
[self roomInfoNoGiftAnimationMessage:message];
}
[self createUserEnterRoomAddRoomTopicMessage];
[self updateAllDataSource:nil];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.messageTableView reloadData];
[self scrollToBottom:YES];
});
}];
}
- (void)handleFetchHistoryMessage:(NIMMessage *)message {
RoomInfoModel * roomInfo = self.hostDelegate.getRoomInfo;
NSString *roomId = [NSString stringWithFormat:@"%ld", self.hostDelegate.getRoomInfo.roomId];
NIMHistoryMessageSearchOption *option = [[NIMHistoryMessageSearchOption alloc] init];
option.limit = [ClientConfig shareConfig].configInfo.roomMessageCount;
option.startTime = self.hostDelegate.getRoomInfo.clearScreenTime / 1000.0;
option.order = NIMMessageSearchOrderAsc;
option.messageTypes = @[@(NIMMessageTypeText),@(NIMMessageTypeCustom)];
[[NIMSDK sharedSDK].chatroomManager fetchMessageHistory:roomId
option:option
result:^(NSError * _Nullable error, NSArray<NIMMessage *> * _Nullable messages) {
if(error != nil){
self.isLoadHistoryMessage = NO;
}
if (messages.count) {
//如果拉取的数量等于请求的数量说明这个时间点以后的消息数量大于等于需要拉取的数量直接拉取最新的50条
if (messages.count == [ClientConfig shareConfig].configInfo.roomMessageCount) {
[self handleFetchNewestMessage:message];
} else {
if (self.datasource.count > kRoomMessageMaxLength) {
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, kRoomMessageMaxLength/2)];
NSArray *needRemoveMsgArray = [self.datasource objectsAtIndexes:set];
[self.datasource removeObjectsInArray:needRemoveMsgArray];
}
// 执行插入
for (NIMMessage *item in messages) {
[self dealWithHistoryDataWithMessage:item];
}
self.isLoadHistoryMessage = NO;
BOOL hideEnter = [self handleHideEnter:message];
if (!hideEnter) {
///插入进房消息及房间公告提示
[self addRoomMessage:message];
}
if (!roomInfo.hasAnimationEffect) {
[self roomInfoNoGiftAnimationMessage:message];
}
[self createUserEnterRoomAddRoomTopicMessage];
[self updateAllDataSource:nil];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.messageTableView reloadData];
[self scrollToBottom:YES];
});
}
}else{
dispatch_async(dispatch_get_main_queue(), ^{///回到主线程
self.isLoadHistoryMessage = NO;
BOOL hideEnter = [self handleHideEnter:message];
if (!hideEnter) {
///插入进房消息及房间公告提示
[self addRoomMessage:message];
}
if (!roomInfo.hasAnimationEffect) {
[self roomInfoNoGiftAnimationMessage:message];
}
[self createUserEnterRoomAddRoomTopicMessage];
});
}
}];
}
-(void)dealWithHistoryDataWithMessage:(NIMMessage *)item{
BOOL isHaveSave = NO;
if(item.messageType == NIMMessageTypeText){
isHaveSave = YES;
}else if(item.messageType == NIMMessageTypeCustom){
NIMCustomObject *obj = (NIMCustomObject *)item.messageObject;
if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) {
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
if (attachment.first == CustomMessageType_Room_Album && attachment.second == Custom_Message_Sub_Room_Album) {
isHaveSave = YES;
}
}
}
if(isHaveSave == NO)return;
[self.datasource addObject:[self.messageParser parseMessageAttribute:item]];
if (!self.isMiniEnter) {/// 最小化进房的话 不需要重新保存
if (self.hostDelegate.getRoomInfo.isCloseScreen) {
NIMCustomObject *obj = (NIMCustomObject *)item.messageObject;
if (obj.attachment != nil && [obj.attachment isKindOfClass:[AttachmentModel class]]) {
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
if (attachment.first == CustomMessageType_Update_RoomInfo && attachment.second == Custom_Message_Sub_Update_RoomInfo_MessageState){
[[XPRoomMiniManager shareManager] saveRoomMessage:item];
}
}
} else {
[[XPRoomMiniManager shareManager] saveRoomMessage:item];
}
}
}
- (void)handleNIMTextMessage:(NIMMessage *)message {
self.isMiniEnter = NO;
if (self.hostDelegate.getRoomInfo.isCloseScreen) {return;}
[self addRoomMessage:message];
}
- (void)roomInfoNoGiftAnimationMessage:(NIMMessage *)message {
self.isMiniEnter = NO;
AttachmentModel *attachement = [[AttachmentModel alloc]init];
attachement.first = CustomMessageType_Update_RoomInfo;
attachement.second = Custom_Message_Sub_Update_RoomInfo_AnimateEffect;
NIMMessage *tempMessage = [[NIMMessage alloc]init];
NIMCustomObject *customObject = [[NIMCustomObject alloc]init];
customObject.attachment = attachement;
tempMessage.messageObject = customObject;
[self addRoomMessage:tempMessage];
}
- (void)onRoomMiniEntered {
self.isMiniEnter = YES;
self.isLoadHistoryMessage = NO;
///最小化进房 不需要请求任何接口 但是如果不加延迟的话 无法滚动到底部 原因还不知道
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSMutableArray *tempArray = @[].mutableCopy;
NSArray * temArray = [XPRoomMiniManager shareManager].getLocalCurrentRoomMessage;
[temArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
id model = nil;
if ([obj isKindOfClass:[NIMMessage class]]) {
model = [self.messageParser parseMessageAttribute:(NIMMessage *)obj];
} else if ([obj isKindOfClass:[NIMBroadcastMessage class]]) {
model = [self.messageParser parseBroadcastMessageAttribute:(NIMBroadcastMessage *)obj];
}
if (model) {
[tempArray addObject:model];
[self.datasource addObject:model];
}
}];
[self updateAllDataSource:tempArray];
[self.messageTableView reloadData];
//执行插入动画并滚动
[self scrollToBottom:YES];
});
}
- (void)onRoomEntered {
[[XPRoomMiniManager shareManager] resetLocalMessage];
self.headerView.bubbleColor = self.hostDelegate.getRoomInfo.type == RoomType_MiniGame ? [UIColor colorWithWhite:1 alpha:0.2] : [UIColor colorWithWhite:1 alpha:0.3];
}
- (void)onRoomUpdate {
///改变公屏的背景样式
if (self.hostDelegate.getRoomInfo.hadChangeRoomType) {
self.headerView.bubbleColor = self.hostDelegate.getRoomInfo.type == RoomType_MiniGame ? [UIColor colorWithWhite:1 alpha:0.2] : [UIColor colorWithWhite:1 alpha:0.3];
[self.messageTableView reloadData];
}
RoomInfoModel *infoModel = self.hostDelegate.getRoomInfo;
CGFloat top = infoModel.type == RoomType_MiniGame ? 0 : 10;
[self.messageTableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(self).offset(15);
make.bottom.trailing.mas_equalTo(self);
make.top.equalTo(self).mas_offset(top);
}];
}
#pragma mark - ScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
// 手动拖拽开始
self.isPending = YES;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
// 手动拖拽结束decelerate0松手时静止1松手时还在运动,会触发DidEndDecelerating方法
if (!decelerate) {
[self finishDraggingWith:scrollView];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
// 静止后触发(手动)
[self finishDraggingWith:scrollView];
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
if (!self.isPending && self.incomingMessages.count <= 0) {
[self scrollToBottom:YES];
}
}
/**
手动拖拽动作彻底完成(减速到零)
*/
- (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;
if (!self.isPending) {
self.messageTipsBtn.hidden = YES;
self.atTipBtn.hidden = YES;
self.atCount = 0;
[self.locationArray removeAllObjects];
if (self.incomingMessages.count > 0) {
[self appendAndScrollToBottom];
}
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"roomMessageTabelViewStopScroll" object:nil];
}
#pragma mark - UITableViewDelegate And UITableViewDataSource
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *source = @[];
switch (self.displayType) {
case 1:
source = self.datasource;
break;
case 2:
source = self.datasource_chat;
break;
case 3:
source = self.datasource_gift;
break;
default:
source = self.datasource;
break;
}
XPMessageInfoModel *model = [source xpSafeObjectAtIndex:indexPath.row];
// 如果 model 中有高度数据,使用 model 的高度
if (model.rowHeight > 0) {
return model.rowHeight;
}
// 否则,使用自适应高度
// return 100;
return UITableViewAutomaticDimension;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
switch (self.displayType) {
case 1:
return self.datasource.count;
break;
case 2:
return self.datasource_chat.count;
break;
case 3:
return self.datasource_gift.count;
break;
default:
return self.datasource.count;
break;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *source = @[];
switch (self.displayType) {
case 1:
source = self.datasource;
break;
case 2:
source = self.datasource_chat;
break;
case 3:
source = self.datasource_gift;
break;
default:
source = self.datasource;
break;
}
XPMessageInfoModel *model = [source xpSafeObjectAtIndex:indexPath.row];
NSString *cellKey = [NSString isEmpty:model.cellKey] ? NSStringFromClass([XPRoomMessageTableViewCell class]) : model.cellKey;
if(model.first == CustomMessageType_Room_Album){
PIRoomMessagePhotoAlbumCell * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([PIRoomMessagePhotoAlbumCell class])];
cell.delegate = self;
cell.messageInfo = model;
cell.roomType = self.hostDelegate.getRoomInfo.type;
return cell;
}
else if (model.isBoom) {
cellKey = @"XPRoomMessageTableViewCell_Boom";
}
XPRoomMessageTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellKey];
cell.delegate = self;
if (model.isBoom) {
cell.isLeftBigImage = model.isBoom;
}
cell.messageInfo = model;
cell.roomType = self.hostDelegate.getRoomInfo.type;
return cell;
}
//- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
// NSArray *source = @[];
// switch (self.displayType) {
// case 1:
// source = self.datasource;
// break;
// case 2:
// source = self.datasource_chat;
// break;
// case 3:
// source = self.datasource_gift;
// break;
//
// default:
// source = self.datasource;
// break;
// }
// XPMessageInfoModel *model = [source xpSafeObjectAtIndex:indexPath.row];
// if (model.rowHeight == 0) {
// model.rowHeight = CGRectGetHeight(cell.frame);
// }
//}
#pragma mark - XPRoomMessageTableViewCellDelegate
- (void)xPRoomMessageTableViewCellDidTapEmpty:(XPRoomMessageTableViewCell *)view {
if (self.delegate && [self.delegate respondsToSelector:@selector(xPRoomMessageContainerViewlDidTapEmpty:)]) {
[self.delegate xPRoomMessageContainerViewlDidTapEmpty:self];
}
}
-(void)clickDidTapEmptyAction{
if (self.delegate && [self.delegate respondsToSelector:@selector(xPRoomMessageContainerViewlDidTapEmpty:)]) {
[self.delegate xPRoomMessageContainerViewlDidTapEmpty:self];
}
}
#pragma mark - PIRoomMessagePhotoAlbumCell
- (void)pIRoomMessagePhotoAlbumCellDelegateDidTapEmpty:(PIRoomMessagePhotoAlbumCell *)view{
if (self.delegate && [self.delegate respondsToSelector:@selector(xPRoomMessageContainerViewlDidTapEmpty:)]) {
[self.delegate xPRoomMessageContainerViewlDidTapEmpty:self];
}
}
-(void)unlockAlbumHandleWithInfo:(PIRoomPhotoAlbumItemModel *_Nonnull)info{
PIRoomMessageUnlockPhotoAlbumView *albumView = [[PIRoomMessageUnlockPhotoAlbumView alloc]initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
albumView.albumModel = info;
albumView.delegate = self;
[TTPopup popupView:albumView style:TTPopupStyleAlert];
}
-(void)pIRoomMessagePhotoAlbumCell:(PIRoomMessagePhotoAlbumCell *_Nonnull)cell lookUpAlbumPhotoWithAlbumModel:(PIRoomPhotoAlbumItemModel *_Nonnull)albumModel;{
SDPhotoBrowser *browser = [[SDPhotoBrowser alloc]init];
browser.sourceImagesContainerView = cell;
browser.delegate = self;
browser.imageCount = 1;
browser.currentImageIndex = 0;
browser.isMe = NO;
self.lookUpModel = albumModel;
[browser show];
}
- (void)pIRoomMessagePhotoAlbumCell:(PIRoomMessagePhotoAlbumCell *)cell lookUpUserCardModel:(PIRoomPhotoAlbumItemModel *)albumModel{
[self.messageParser showUserCard:albumModel.uid.integerValue];
}
#pragma mark - PIRoomMessageUnlockPhotoAlbumViewDelegate
- (void)unlockRoomAlbumImageWithAlbumModel:(PIRoomPhotoAlbumItemModel *)albumModel{
[XNDJTDDLoadingTool showLoading];
[Api unlockRoomAlbumPhoto:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
[XNDJTDDLoadingTool hideHUD];
if(code == 200){
NSMutableDictionary *getData = [NSMutableDictionary dictionary];
[getData addEntriesFromDictionary:data.data];
AttachmentModel *attachment = [[AttachmentModel alloc] init];
attachment.first = CustomMessageType_Gift;
attachment.second = Custom_Message_Sub_Gift_Send;
NSDictionary *targetUsers = ((NSArray *)[getData objectForKey:@"targetUsers"]).firstObject;
[getData setObject:[targetUsers valueForKeyPath:@"uid"] forKey:@"targetUid"];
[getData setObject:[targetUsers valueForKeyPath:@"nick"] forKey:@"targetNick"];
[getData setObject:[targetUsers valueForKeyPath:@"avatar"] forKey:@"targetAvatar"];
[getData setObject:@(YES) forKey:@"isRoomAlbum"];
attachment.data = getData;
[self sendCustomMessage:attachment];
if(albumModel.ID != nil){
if(![[XPSkillCardPlayerManager shareInstance].photoIdList containsObject:albumModel.ID]){
if([XPSkillCardPlayerManager shareInstance].photoIdList == nil){
[XPSkillCardPlayerManager shareInstance].photoIdList = [NSMutableArray arrayWithArray:@[albumModel.ID]];
}else{
[[XPSkillCardPlayerManager shareInstance].photoIdList addObject:albumModel.ID];
}
}
[[NSNotificationCenter defaultCenter]postNotificationName:@"kGetgetUnlockRoomAlbumPhotoListNot" object:nil];
}
return;
}
[XNDJTDDLoadingTool showErrorWithMessage:msg];
} id:albumModel.ID roomUid:@(self.hostDelegate.getRoomInfo.uid).stringValue];
}
- (void)sendCustomMessage:(AttachmentModel *)attachment {
NSString *sessionID = [NSString stringWithFormat:@"%ld", [self.hostDelegate getRoomInfo].roomId];
NIMMessage *message = [[NIMMessage alloc]init];
NIMCustomObject *object = [[NIMCustomObject alloc] init];
object.attachment = attachment;
message.messageObject = object;
UserInfoModel *userInfo = [self.hostDelegate getUserInfo];
XPMessageRemoteExtModel *extModel = [[XPMessageRemoteExtModel alloc] init];
extModel.androidBubbleUrl = userInfo.androidBubbleUrl;
extModel.iosBubbleUrl = userInfo.iosBubbleUrl;
extModel.fromSayHelloChannel = userInfo.fromSayHelloChannel;
NSMutableDictionary *remoteExt = [NSMutableDictionary dictionaryWithObject:extModel.model2dictionary forKey:[NSString stringWithFormat:@"%ld", userInfo.uid]];
message.remoteExt = remoteExt;
NIMSessionType sessionType = NIMSessionTypeChatroom;
//构造会话
NIMSession *session = [NIMSession session:sessionID type:sessionType];
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
}
#pragma mark - SDPhotoBrowserDelegate
- (NSURL *)photoBrowser:(SDPhotoBrowser *)browser highQualityImageURLForIndex:(NSInteger)index{
if(self.lookUpModel != nil){
return [[NSURL alloc]initWithString:self.lookUpModel.photoUrl];
}
return nil;
}
- (UIImage *)photoBrowser:(SDPhotoBrowser *)browser placeholderImageForIndex:(NSInteger)index {
return [UIImageConstant defaultBannerPlaceholder];
}
#pragma mark - Getters And Setters
- (UITableView *)messageTableView {
if (!_messageTableView) {
_messageTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_messageTableView.delegate = self;
_messageTableView.dataSource = self;
_messageTableView.rowHeight = UITableViewAutomaticDimension;
// _messageTableView.estimatedRowHeight = 44; // 预估高度
_messageTableView.tableFooterView = [UIView new];
_messageTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_messageTableView.backgroundColor = [UIColor clearColor];
_messageTableView.showsVerticalScrollIndicator = NO;
_messageTableView.clipsToBounds = NO;
_messageTableView.tag = 666;
if (@available(iOS 11.0, *)) {
_messageTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
[_messageTableView registerClass:[XPRoomMessageTableViewCell class] forCellReuseIdentifier:@"XPRoomMessageTableViewCell_Boom"];
[_messageTableView registerClass:[XPRoomMessageTableViewCell class] forCellReuseIdentifier:NSStringFromClass([XPRoomMessageTableViewCell class])];
[_messageTableView registerClass:[XPRoomMessageTableViewCell class] forCellReuseIdentifier:@"ChatMessage"];
[_messageTableView registerClass:[PIRoomMessagePhotoAlbumCell class] forCellReuseIdentifier:NSStringFromClass([PIRoomMessagePhotoAlbumCell class])];
}
return _messageTableView;
}
- (XPRoomMessageHeaderView *)headerView {
if (!_headerView) {
_headerView = [[XPRoomMessageHeaderView alloc] init];
}
return _headerView;
}
- (UIButton *)messageTipsBtn {
if (!_messageTipsBtn) {
_messageTipsBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_messageTipsBtn setTitle:YMLocalizedString(@"XPRoomMessageContainerView6") forState:UIControlStateNormal];
[_messageTipsBtn setTitleColor:[DJDKMIMOMColor 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(messageTipsBtnAction:) forControlEvents:UIControlEventTouchUpInside];
_messageTipsBtn.hidden = YES;
}
return _messageTipsBtn;
}
- (UIButton *)atTipBtn {
if (!_atTipBtn) {
_atTipBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[_atTipBtn setTitle:YMLocalizedString(@"XPRoomMessageContainerView7") forState:UIControlStateNormal];
[_atTipBtn setTitleColor:[DJDKMIMOMColor appMainColor] forState:UIControlStateNormal];
_atTipBtn.layer.cornerRadius = 15.0;
_atTipBtn.layer.masksToBounds = YES;
_atTipBtn.titleLabel.font = [UIFont systemFontOfSize:12.0];
_atTipBtn.backgroundColor = [UIColor whiteColor];
[_atTipBtn addTarget:self action:@selector(atTipsBtnAction:) forControlEvents:UIControlEventTouchUpInside];
_atTipBtn.hidden = YES;
}
return _atTipBtn;
}
- (NSMutableArray<XPMessageInfoModel *> *)datasource {
if (!_datasource) {
_datasource = [NSMutableArray array];
}
return _datasource;
}
- (NSMutableArray<XPMessageInfoModel *> *)datasource_chat {
if (!_datasource_chat) {
_datasource_chat = [NSMutableArray array];
}
return _datasource_chat;
}
- (NSMutableArray<XPMessageInfoModel *> *)datasource_gift {
if (!_datasource_gift) {
_datasource_gift = [NSMutableArray array];
}
return _datasource_gift;
}
- (NSMutableArray *)incomingMessages {
if (!_incomingMessages) {
_incomingMessages = [NSMutableArray array];
}
return _incomingMessages;
}
- (NSMutableArray *)locationArray {
if (!_locationArray) {
_locationArray = [NSMutableArray array];
}
return _locationArray;
}
- (XPRoomMessageParser *)messageParser {
if (!_messageParser) {
_messageParser = [[XPRoomMessageParser alloc] init];
_messageParser.hostDelegate = self.hostDelegate;
}
return _messageParser;
}
@end