Files
peko-ios/YuMi/Modules/YMMessage/View/Session/MSSessionPublicChatHallVC.m
eggmanQQQ 614d431b2c 优化 mic 位头像逻辑
调整错误的代码单词
2024-07-19 14:59:36 +08:00

1078 lines
46 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.

//
// MSSessionPublicChatHallVC.m
// YuMi
//
// Created by duoban on 2024/5/6.
//
#import "MSSessionPublicChatHallVC.h"
#import <IQKeyboardManager/IQKeyboardManager.h>
#import <TZImagePickerController/TZImagePickerController.h>
#import <MJRefresh/MJRefresh.h>
#import <Photos/Photos.h>
///Tool
#import "XCCurrentVCStackManager.h"
#import "NIMMessageMaker.h"
#import "UITableView+NIMScrollToBottom.h"
#import "QEmotionHelper.h"
#import "QKeyboardManager.h"
#import "ClientConfig.h"
///Model
#import "QPhotoImageModel.h"
#import "AttachmentModel.h"
#import "MessageBaseModel.h"
#import "MessageHeadlinesTextModel.h"
#import "MessageAudioModel.h"
#import "MessageTimeModel.h"
#import "MessageImageModel.h"
#import "MessageUnSupportModel.h"
#import "MessageTipsModel.h"
#import "XPMessageRemoteExtModel.h"
#import "MSSessionPublicChatHalImageModel.h"
#import "MSSessionPublicChatHalImageCell.h"
#import "MSSessionPublicChatHalRightTextCell.h"
///View
#import "MSSessionPublicChatHalTextCell.h"
#import "MessageCell.h"
#import "XPMineUserInfoViewController.h"
#import "SessionNavView.h"
#import "QInputBarView.h"
#import "QKeyboardManager.h"
#import "QEmotionBoardView.h"
#import "QinputPhotoView.h"
#import "SessionUserInfoTableViewCell.h"
///P
#import "MessagePresenter.h"
#import "MessageProtocol.h"
#import "Api+Message.h"
#import "XPRoomMessageConstant.h"
#import "MSSessionPublicChatHallHeadView.h"
#import "MSSessionReleaseHeadlinesView.h"
#import "MessageHeadlinesModel.h"
#import "Api+Mine.h"
#import "XPIncomeRecordModel.h"
#import "XPCandyTreeInsufficientBalanceView.h"
#import "XPIAPRechargeViewController.h"
#import "Api+Mine.h"
#import "MSSessionPublicChatHalIRightmageCell.h"
@interface MSSessionPublicChatHallVC ()<SessionNavViewDelegate,MessageProtocol, UITableViewDelegate, UITableViewDataSource, NIMChatManagerDelegate, NIMConversationManagerDelegate, NIMMediaManagerDelegate, MessageCellDelegate, TZImagePickerControllerDelegate, SessionNavViewDelegate, QInputBarViewDelegate, QInputBarViewDataSource,InputBoardDataSource ,InputBoardDelegate , QEmotionBoardViewDelegate, QinputPhotoViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate,MSSessionReleaseHeadlinesViewDelegate,XPCandyTreeInsufficientBalanceViewDelegate>
@property (nonatomic, strong) NIMSession * session;
@property (nonatomic, strong) NSMutableArray<MessageBaseModel *> * messages;
@property (nonatomic,strong) SessionNavView *sessionNavView;
@property (nonatomic, strong) UITableView * sessionTableView;
@property (nonatomic,strong) NIMMessage *lastMessage;
@property(nonatomic,strong)QInputBarView *inputBarView;
@property(nonatomic,strong)QKeyboardManager *keyboardManager;
@property (nonatomic, strong) UserInfoModel *userInfo;
@property(nonatomic,strong) MSSessionPublicChatHallHeadView *headView;
///相册
@property (nonatomic,strong) QinputPhotoView *photoView;
///
@property (nonatomic,strong) NSArray *phototArray;
@property(nonatomic,assign) BOOL isLoadHistoryMessage;
@property(nonatomic,copy) NSString *publicChatMessageRoomId;
@property(nonatomic,copy) NSString *releaseCoins;
@property(nonatomic,copy) NSString *myCoins;
@property(nonatomic,strong) UIButton *sendBtn;
@end
@implementation MSSessionPublicChatHallVC
- (BOOL)isHiddenNavBar {
return YES;
}
- (void)dealloc {
[[NIMSDK sharedSDK].chatManager removeDelegate:self];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self.presenter exitNIMRoom:self.publicChatMessageRoomId];
}
- (MessagePresenter *)createPresenter {
return [[MessagePresenter alloc] init];
}
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[Api requestRecordIncome:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if(code == 200){
XPIncomeRecordModel *model = [XPIncomeRecordModel modelWithDictionary:data.data];
self.myCoins = @(model.diamonds).stringValue;
}
}];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.isLoadHistoryMessage = YES;
[self initViews];
[self initLayout];
[self initHeaderAndFooterRrfresh];
[IQKeyboardManager sharedManager].enable = NO;
[IQKeyboardManager sharedManager].enableAutoToolbar = NO;
[[NIMSDK sharedSDK].chatManager addDelegate:self];
}
- (void)initHeaderAndFooterRrfresh {
[self initData];
}
#pragma mark - 提前加载相册中的图片
- (void)loadAlbumPhotos {
[YYUtility checkAssetsLibrayAvailable:^{} denied:^{} restriction:^{}];
}
#pragma mark - cell的样式
- (MessageBaseModel *)modeTransformMessage:(NIMMessage *)message {
MessageBaseModel * model;
switch (message.messageType) {
case NIMMessageTypeText:
model = [[MessageHeadlinesTextModel alloc] initWithMessage:message];
break;
case NIMMessageTypeImage:
model = [[MSSessionPublicChatHalImageModel alloc] initWithMessage:message];
break;
case NIMMessageTypeCustom:
model = [self modelTransformCustomMessage:message];
break;
default:
model = [[MessageUnSupportModel alloc] initWithMessage:message];
break;
}
return model;
}
- (MessageBaseModel *)modelTransformCustomMessage:(NIMMessage *)message {
MessageBaseModel * model;
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
if (attachment.first == CustomMessageType_Chat_Hall_Headlinesn && attachment.second == Custom_Message_Sub_Chat_Hall_Headlinesn) {
model = [[MessageHeadlinesModel alloc] initWithMessage:message];
MSSessionPublicChatHallTopModel *topModel = [MSSessionPublicChatHallTopModel modelWithDictionary:attachment.data];
[self getPublicChatHallTopTextSuccess:topModel];
}
return model;
}
-(void)setTime:(MSSessionPublicChatHallTopModel *)topModel{
// NSInteger time = topModel.endTime/1000 - topModel.startTime/1000;
// [self performSelector:@selector(setHeadViewData) withObject:nil afterDelay:time];
}
-(void)setHeadViewData{
self.headView.topModel = nil;
}
-(BOOL)isCanAddMsg:(NIMMessage *)message{
BOOL isCanAdd = NO;
NSString *publicChatRoomId = [NSString stringWithFormat:@"%@",[ClientConfig shareConfig].configInfo.publicChatRoomIdMap[self.userInfo.partitionId]];
if(![message.session.sessionId isEqualToString:publicChatRoomId]){
return NO;
}
switch (message.messageType) {
case NIMMessageTypeText:
isCanAdd = YES;
break;
case NIMMessageTypeImage:
isCanAdd = YES;
break;
case NIMMessageTypeCustom:
{
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
AttachmentModel *attachment = (AttachmentModel *)obj.attachment;
if (attachment.first == CustomMessageType_Chat_Hall_Headlinesn && attachment.second == Custom_Message_Sub_Chat_Hall_Headlinesn) {
MSSessionPublicChatHallTopModel *topModel = [MSSessionPublicChatHallTopModel modelWithDictionary:attachment.data];
[self getPublicChatHallTopTextSuccess:topModel];
if(topModel.recordStatus == 0){
isCanAdd = YES;
}
}
}
break;
default:
break;
}
return isCanAdd;
}
- (UINavigationController *)getKeyWindowNav {
if ([XCCurrentVCStackManager shareManager].getCurrentVC) {
return [XCCurrentVCStackManager shareManager].getCurrentVC.navigationController;
}
return self.navigationController;
}
- (MessageBaseModel *)createTimeMessage:(NIMMessage *)message {
MessageTimeModel * timeModel = [[MessageTimeModel alloc] initWithMessage:message];
timeModel.time = [self timestrToTimeSecond:[NSString stringWithFormat:@"%f", message.timestamp]];
return timeModel;
}
- (NSString *)timestrToTimeSecond:(NSString *)timeStr {//timestr 豪秒
NSTimeInterval interval = [timeStr doubleValue];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval];
return [NSDate stringFromDate:date];
}
- (void)addTimeMessage:(NIMMessage *)message {
if ([self isCanAddMsg:message] == NO){return;}
if (self.messages.count > 0) {
NIMMessage * lastMessage = self.messages.lastObject.message;
CGFloat dur = message.timestamp - lastMessage.timestamp;
if (dur / 60 > 5) {
NIMMessage * newMessage = [[NIMMessage alloc] init];
newMessage.timestamp = message.timestamp;
[newMessage setValue:self.session forKey:@"session"];
MessageBaseModel * timeModel = [self createTimeMessage:newMessage];
[self.messages addObject:timeModel];
}
}
}
#pragma mark - Private Method
- (void)initInputView {
// 初始化输入工具条frame可以先这样临时设置下面的addBottomInputBarView方法会重置输入条frame
// 如果你想要自定义输入条View请参考TextFieldViewController代码
QInputBarViewConfiguration *inputBarViewConfiguration = [QInputBarViewConfiguration defaultInputBarViewConfiguration];
inputBarViewConfiguration.voiceButtonHidden = YES;//隐藏语音按钮
inputBarViewConfiguration.extendButtonHidden = YES;//隐藏拓展按钮
inputBarViewConfiguration.toolHidden = NO;
inputBarViewConfiguration.giftButtonHidden = YES;
inputBarViewConfiguration.cameraButtonHidden = NO;
inputBarViewConfiguration.photoButtonHidden = NO;
_inputBarView = [[QInputBarView alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.width,inputBarViewConfiguration.inputViewHeight)];
[_inputBarView setupWithConfiguration:inputBarViewConfiguration];
_inputBarView.delegate = self;
//keyboard管理类用来管理键盘各大面板的切换
_keyboardManager = [[QKeyboardManager alloc] initWithViewController:self];
_keyboardManager.dataSource = self;
//因为addBottomInputBarView方法会立刻触发delegate所以这里需要先设置delegate
_keyboardManager.delegate = self;
[_keyboardManager addBottomInputBarView:_inputBarView belowViewController:NO];
//把输入框(如果有的话)绑定给管理类
[_keyboardManager bindTextView:_inputBarView.inputTextView];
}
- (void)initViews {
[self.view addSubview:self.sessionNavView];
[self.view addSubview:self.headView];
[self.view addSubview:self.sessionTableView];
[self.view addSubview:self.sendBtn];
[self initInputView];
}
- (void)initLayout {
[self.sessionNavView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(kNavigationHeight);
make.leading.top.trailing.mas_equalTo(self.view);
}];
[self.headView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.sessionNavView.mas_bottom).mas_offset(kGetScaleWidth(0));
make.leading.trailing.equalTo(self.view).inset(kGetScaleWidth(0));
make.height.mas_greaterThanOrEqualTo(kGetScaleWidth(101));
}];
[self.sendBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.mas_equalTo(kGetScaleWidth(96));
make.height.mas_equalTo(kGetScaleWidth(80));
make.trailing.mas_equalTo(-kGetScaleWidth(0));
make.top.equalTo(self.headView.mas_bottom).mas_offset(kGetScaleWidth(255));
}];
}
-(void)clickReleaseBtnAction{
MSSessionReleaseHeadlinesView *releaseView = [[MSSessionReleaseHeadlinesView alloc]initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
releaseView.golds = self.releaseCoins;
releaseView.myCoins = self.myCoins;
releaseView.delegate = self;
[TTPopup popupView:releaseView style:TTPopupStyleAlert];
}
-(void)sendHeadlineBtnAction{
[self clickReleaseBtnAction];
}
- (void)viewDidLayoutSubviews{
}
- (void)initData {
self.sessionNavView.title = YMLocalizedString(@"MSSessionPublicChatHallVC0");
[self showLoading];
[self.presenter getUserInfoWithUid:[AccountInfoStorage instance].getUid];
[self.presenter getPublicChatHallTopTextPayMoney];
[self.presenter getPublicChatHallTopText];
}
- (BOOL)isExistMessages:(NIMMessage *)message{
BOOL isExist = NO;
NIMMessage * model;
for (NIMMessage *item in self.messages.reverseObjectEnumerator.allObjects) {
if ([item isKindOfClass:[NIMMessage class]] && [item.messageId isEqualToString:message.messageId]) {
model = item;
isExist = YES;
break;
}
}
if (model) {
model = message;
}
return isExist;
}
- (void)sendPublicChatHallTopTextSuccess{
[Api requestRecordIncome:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if(code == 200){
XPIncomeRecordModel *model = [XPIncomeRecordModel modelWithDictionary:data.data];
self.myCoins = @(model.diamonds).stringValue;
}
}];
}
-(void)getPublicChatHallTopTextPayMoneySuccess:(NSString *)money{
self.releaseCoins = money;
}
- (void)getPublicChatHallTopTextSuccess:(MSSessionPublicChatHallTopModel *)model{
self.headView.topModel = model;
if (model == nil || model.recordStatus == 1) {
[self.headView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.sessionNavView.mas_bottom).mas_offset(kGetScaleWidth(0));
make.leading.trailing.equalTo(self.view).inset(kGetScaleWidth(0));
make.height.mas_equalTo(kGetScaleWidth(101));
}];
} else {
CGFloat height = [UILabel getLabelHeightWithText:model.content
width:KScreenWidth - 29 - 13
font:kFontMedium(14)];
height = height + 47.5 + 13;
[self.headView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.sessionNavView.mas_bottom).mas_offset(kGetScaleWidth(0));
make.leading.trailing.equalTo(self.view).inset(kGetScaleWidth(0));
make.height.mas_equalTo(kGetScaleWidth(height));
}];
}
}
///获取用户信息成功
- (void)onGetUserInfoSuccess:(UserInfoModel *)userInfo {
_userInfo = userInfo;
self.sessionNavView.userInfo = userInfo;
self.publicChatMessageRoomId = [NSString stringWithFormat:@"%@",[ClientConfig shareConfig].configInfo.publicChatRoomIdMap[_userInfo.partitionId]];
if(self.publicChatMessageRoomId.length > 0){
_session = [NIMSession session:self.publicChatMessageRoomId type:NIMSessionTypeChatroom];
[self.presenter enterNIMRoom:self.publicChatMessageRoomId user:userInfo];
}else{
[self hideHUD];
}
}
///进入聊天室成功
-(void)enterPublicChatHallSuccess:(NIMChatroom *)chatRoom{
[self handleFetchHistoryMessage];
}
///进入聊天室失败
-(void)enterPublicChatHallFail:(NSInteger)code{
[self hideHUD];
}
- (void)handleFetchHistoryMessage {
NSString *roomId = self.publicChatMessageRoomId;
NIMHistoryMessageSearchOption *option = [[NIMHistoryMessageSearchOption alloc] init];
option.limit = 100;
option.startTime = 0;
option.order = NIMMessageSearchOrderAsc;
option.messageTypes = @[@(NIMMessageTypeText),@(NIMMessageTypeImage)];
[[NIMSDK sharedSDK].chatroomManager fetchMessageHistory:roomId option:option result:^(NSError * _Nullable error, NSArray<NIMMessage *> * _Nullable messages) {
if(error != nil){
self.isLoadHistoryMessage = NO;
}
//如果拉取的数量等于请求的数量说明这个时间点以后的消息数量大于等于需要拉取的数量直接拉取最新的50条
if (messages.count == 100) {
NIMHistoryMessageSearchOption *option = [[NIMHistoryMessageSearchOption alloc] init];
option.limit = 100;
option.order = NIMMessageSearchOrderDesc;
option.messageTypes = @[@(NIMMessageTypeText),@(NIMMessageTypeImage)];
[[NIMSDK sharedSDK].chatroomManager fetchMessageHistory:roomId option:option result:^(NSError * _Nullable error, NSArray<NIMMessage *> * _Nullable messages) {
if(error != nil){
self.isLoadHistoryMessage = NO;
}
[self hideHUD];
dispatch_async(dispatch_get_main_queue(), ^{///回到主线程
if (self.messages.count > kRoomMessageMaxLength) {
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, kRoomMessageMaxLength/2)];
NSArray *needRemoveMsgArray = [self.messages objectsAtIndexes:set];
[self.messages removeObjectsInArray:needRemoveMsgArray];
}else{
for (NIMMessage *message in messages.reverseObjectEnumerator) {
[self addTimeMessage:message];
if (message.isDeleted) {
continue;
}
if ([self isCanAddMsg:message]){
[self addTimeMessage:message];
MessageBaseModel * model = [self modeTransformMessage:message];
[self.messages addObject:model];
}
}
}
// 执行插入
[self.sessionTableView reloadData];
//执行插入动画并滚动
if(self.messages.count > 0){
NSIndexPath *ip = [NSIndexPath indexPathForRow:self.messages.count-1 inSection:0]; //取最后一行数据
[self.sessionTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:YES]; //滚动到最后一行
}
});
}];
return;
}
dispatch_async(dispatch_get_main_queue(), ^{///回到主线程
[self hideHUD];
if (self.messages.count > kRoomMessageMaxLength) {
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, kRoomMessageMaxLength/2)];
NSArray *needRemoveMsgArray = [self.messages objectsAtIndexes:set];
[self.messages removeObjectsInArray:needRemoveMsgArray];
}else{
for (NIMMessage *message in messages) {
[self addTimeMessage:message];
if (message.isDeleted) {
continue;
}
if ([self isCanAddMsg:message]){
[self addTimeMessage:message];
MessageBaseModel * model = [self modeTransformMessage:message];
[self.messages addObject:model];
}
}
}
// 执行插入
[self.sessionTableView reloadData];
//执行插入动画并滚动
if(self.messages.count > 0){
NSIndexPath *ip = [NSIndexPath indexPathForRow:self.messages.count-1 inSection:0]; //取最后一行数据
[self.sessionTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:YES]; //滚动到最后一行
}
});
}];
}
#pragma mark - MessageCellDelegate
- (void)updateMessageSuccess:(NIMMessage *)message {
if ([message.session.sessionId isEqualToString:self.session.sessionId]) {
[self.sessionTableView reloadData];
}
}
- (void)didTapAvatar:(NSString *)uid {
XPMineUserInfoViewController * infoVC = [[XPMineUserInfoViewController alloc] init];
infoVC.uid = uid.integerValue;
[[self getKeyWindowNav] pushViewController:infoVC animated:YES];
}
#pragma mark - MSSessionReleaseHeadlinesViewDelegate
- (void)releaseHeadlinesWithText:(NSString *)text{
if (self.myCoins.integerValue < self.releaseCoins.integerValue){
XPCandyTreeInsufficientBalanceView *balanceView = [[XPCandyTreeInsufficientBalanceView alloc]initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)];
balanceView.delegate = self;
[self. view addSubview:balanceView];
return;
}
[self.presenter sendPublicChatHallTopTextWithcontent:text];
}
-(void)payBalanceAction{
XPIAPRechargeViewController * webVC =[[XPIAPRechargeViewController alloc] init];
webVC.type = @"4";
[[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController pushViewController:webVC animated:YES];
}
#pragma mark - SessionNavViewDelegate
- (void)sessionNavView:(SessionNavView *)view didClickBack:(UIButton *)sender {
[self.navigationController popViewControllerAnimated:YES];
}
#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 {
MessageBaseModel * message = [self.messages xpSafeObjectAtIndex:indexPath.row];
MessageHeadlinesTextModel * textModel = (MessageHeadlinesTextModel *)message;
switch (message.messageType) {
case SessionMessageType_Text: {
if(textModel.isSelf){
MSSessionPublicChatHalRightTextCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([MSSessionPublicChatHalRightTextCell class])
forIndexPath:indexPath];
[cell render:message];
return cell;
} else {
MSSessionPublicChatHalTextCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([MSSessionPublicChatHalTextCell class])
forIndexPath:indexPath];
[cell render:message];
return cell;
}
}
break;
case SessionMessageType_Image: {
if(textModel.isSelf){
MSSessionPublicChatHalIRightmageCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([MSSessionPublicChatHalIRightmageCell class])
forIndexPath:indexPath];
[cell render:message];
return cell;
} else {
MSSessionPublicChatHalImageCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([MSSessionPublicChatHalImageCell class])
forIndexPath:indexPath];
[cell render:message];
return cell;
}
}
break;
default:{
NSString * identifier = [message 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 xpSafeObjectAtIndex:indexPath.row]];
[cell renderWithMessage:[self.messages xpSafeObjectAtIndex:indexPath.row]];
return cell;
}
break;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
MessageBaseModel *m = [self.messages xpSafeObjectAtIndex:indexPath.row];
NSLog(@"%@",m.message.remoteExt);
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.keyboardManager hideAllBoardView];
}
#pragma mark - NIMChatManagerDelegate
- (void)onRecvMessages:(NSArray<NIMMessage *> *)messages {
if(!messages.count){
return;
}
if (self.messages.count > kRoomMessageMaxLength) {
NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, kRoomMessageMaxLength/2)];
NSArray *needRemoveMsgArray = [self.messages objectsAtIndexes:set];
[self.messages removeObjectsInArray:needRemoveMsgArray];
}
for (NIMMessage *message in messages) {
if (![self isCanAddMsg:message]){
return;
}
// [self addTimeMessage:message];
if (message.isDeleted) {
continue;
}
if ([self isCanAddMsg:message]){
[self addTimeMessage:message];
MessageBaseModel * model = [self modeTransformMessage:message];
[self.messages addObject:model];
}
}
[self.sessionTableView reloadData];
if(self.messages.count > 0){
NSIndexPath *ip = [NSIndexPath indexPathForRow:self.messages.count-1
inSection:0]; //取最后一行数据
[self.sessionTableView scrollToRowAtIndexPath:ip
atScrollPosition:UITableViewScrollPositionBottom
animated:YES]; //滚动到最后一行
}
}
- (void)sendMessage:(NIMMessage *)message didCompleteWithError:(NSError *)error {
if (message.session.sessionType != NIMSessionTypeChatroom) {
return;
}
if (![self isCanAddMsg:message]){
return;
}
[self addTimeMessage:message];
if (![self isExistMessages:message]) {
if ([self isCanAddMsg:message]){
[self addTimeMessage:message];
MessageBaseModel * model = [self modeTransformMessage:message];
[self.messages addObject:model];
}
}
if (message.yidunAntiSpamRes) {
NSDictionary * spamRes = message.yidunAntiSpamRes.toJSONObject;
id spamResExt = ((NSString *)spamRes[@"ext"]).toJSONObject;
NSDictionary *antispamDic = nil;
if ([spamResExt isKindOfClass:[NSArray class]]) {
antispamDic = [spamResExt xpSafeObjectAtIndex:0];
} else if ([spamResExt isKindOfClass:[NSDictionary class]]) {
antispamDic = spamResExt[@"antispam"];
}
NSDictionary *realAntiDic = nil;
if ([[antispamDic allKeys] containsObject:@"antispam"]) {
realAntiDic = antispamDic[@"antispam"];;
} else {
realAntiDic = antispamDic;
}
if (realAntiDic) {
NSInteger suggestion = [realAntiDic[@"suggestion"] integerValue];
if (suggestion == 2) {
NSDictionary * dic = @{@"suggestion": @"2"};
message.localExt = dic;
[[NIMSDK sharedSDK].conversationManager updateMessage:message forSession:self.session completion:nil];
[self showErrorToast:YMLocalizedString(@"XPRoomViewController10")];
}
}
}
[self.sessionTableView reloadData];
if(self.messages.count > 0){
NSIndexPath *ip = [NSIndexPath indexPathForRow:self.messages.count-1 inSection:0]; //取最后一行数据
[self.sessionTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:YES]; //滚动到最后一行
}
}
- (void)sendTextMessage:(NSString *)text {
NIMMessage *message = [NIMMessageMaker msgWithText:text];
message.remoteExt = [self getRemoteExt];
[[[NIMSDK sharedSDK] chatManager] sendMessage:message toSession:self.session error:nil];
}
-(NSDictionary *)getRemoteExt{
UserInfoModel *userInfo = self.userInfo;
XPMessageRemoteExtModel *extModel = [[XPMessageRemoteExtModel alloc] init];
extModel.defUser = userInfo.defUser;
extModel.erbanNo = userInfo.erbanNo;
extModel.carName = userInfo.carName;
extModel.inRoomNameplatePic = userInfo.nameplatePic;
extModel.inRoomNameplateWord = userInfo.nameplateWord;
extModel.isCustomWord = userInfo.isCustomWord;
extModel.charmUrl = userInfo.userLevelVo.charmUrl;
extModel.experLevelSeq = userInfo.userLevelVo.experLevelSeq;
extModel.experUrl = userInfo.userLevelVo.expertUrl;
extModel.newUser = userInfo.newUser;
extModel.vipIcon = userInfo.userVipInfoVO.vipIcon;
extModel.androidBubbleUrl = userInfo.androidBubbleUrl;
extModel.iosBubbleUrl = userInfo.iosBubbleUrl;
extModel.fromSayHelloChannel = userInfo.fromSayHelloChannel;
extModel.avatar = userInfo.avatar;
extModel.nick = userInfo.nick;
extModel.headWearType = [userInfo isHeadWearSVGA] ? 1 : 0;
NSString *headwearUrl= userInfo.headwearEffect.length > 0 ? userInfo.headwearEffect : userInfo.headwearPic;
extModel.headWearUrl = headwearUrl;
NSMutableDictionary *remoteExt = [NSMutableDictionary dictionaryWithObject:extModel.model2dictionary forKey:[AccountInfoStorage instance].getUid];
return remoteExt;
}
#pragma mark - TZImagePickerControllerDelegate
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto infos:(NSArray<NSDictionary *> *)infos {
@kWeakify(self);
[photos enumerateObjectsUsingBlock:^(UIImage * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
@kStrongify(self);
if (obj) {
NIMMessage * message = [NIMMessageMaker msgWithImage:obj];
message.remoteExt = [self getRemoteExt];
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:self.session error:nil];
}
}];
}
#pragma mark - SessionUserInfoTableViewCellDelegate
- (void)sessionUserInfoTableViewCell:(SessionUserInfoTableViewCell *)view showUserInfoVC:(UserInfoModel *)userInfo {
[self didTapAvatar:[NSString stringWithFormat:@"%ld", userInfo.uid]];
}
#pragma mark - InputBoardDataSource
//@return 点加号按钮弹出的拓展面板View且无需设置frame
- (UIView *)keyboardManagerExtendBoardView:(QKeyboardManager *)keyboardManager {
UIView *boardView = [UIView new];
boardView.backgroundColor = UIColor.clearColor;
return boardView;
}
//@return 点表情按钮弹出的表情面板View且无需设置frame
- (UIView *)keyboardManagerEmotionBoardView:(QKeyboardManager *)keyboardManager {
QEmotionBoardView *emotionView = [[QEmotionBoardView alloc] init];
QEmotionHelper *faceManager = [QEmotionHelper sharedEmotionHelper];
emotionView.emotions = faceManager.emotionArray;
emotionView.delegate = self;
if (@available(iOS 11.0, *)) {
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
emotionView.backgroundColor = [UIColor colorNamed:@"q_input_extend_bg" inBundle:bundle compatibleWithTraitCollection:nil];
} else {
emotionView.backgroundColor = [UIColor colorWithRed:(246)/255.0f green:(246)/255.0f blue:(246)/255.0f alpha:1];
}
return emotionView;
}
//@return 点表情按钮弹出的表情面板View且无需设置frame
- (UIView *)keyboardManagerPhotoBoardView:(QKeyboardManager *)keyboardManager{
QinputPhotoView *emotionView = [[QinputPhotoView alloc] init];
self.photoView = emotionView;
emotionView.photoList = self.phototArray;
emotionView.delegate = self;
emotionView.backgroundColor = [UIColor colorWithRed:(246)/255.0f green:(246)/255.0f blue:(246)/255.0f alpha:1];
return emotionView;
}
//@return 点表情按钮弹出的表情面板View的高度
- (CGFloat)keyboardManagerEmotionBoardHeight:(QKeyboardManager *)keyboardManager {
return 294;
}
//@return 点加号按钮弹出的拓展面板View的高度
- (CGFloat)keyboardManagerExtendBoardHeight:(QKeyboardManager *)keyboardManager {
return 174;
}
- (CGFloat)keyboardManagerPhotoBoardHeight:(QKeyboardManager *)keyboardManager {
return 184 + kSafeAreaBottomHeight;
}
//点击表情按钮,切换到表情面板
- (void)inputBarView:(QInputBarView *)inputBarView onEmotionButtonClick:(UIButton *)emotionSwitchButton {
if (emotionSwitchButton.isSelected) {
[_keyboardManager switchToEmotionBoardKeyboard];
} else {
_inputBarView.inputTextView.text = @"";
[_inputBarView textViewBecomeFirstResponder];
}
}
- (void)inputBarView:(QInputBarView *)inputBarView onVoiceSwitchButtonClick:(UIButton *)voiceSwitchButton {
if (!voiceSwitchButton.isSelected) {
_inputBarView.inputTextView.text = @"";
[_inputBarView textViewBecomeFirstResponder];
} else {
[_keyboardManager hideAllBoardView];
}
}
- (void)inputBarView:(QInputBarView *)inputBarView onGiftButtonClick:(UIButton *)emotionSwitchButton {
[_keyboardManager hideAllBoardView];
}
- (void)inputBarView:(QInputBarView *)inputBarView onCameraButtonClick:(UIButton *)emotionSwitchButton {
[_keyboardManager hideAllBoardView];
@kWeakify(self);
[YYUtility checkCameraAvailable:^{
@kStrongify(self);
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.allowsEditing = YES;
[self presentViewController:imagePicker animated:YES completion:NULL];
} denied:^{
@kStrongify(self);
[self showNotPhoto:YMLocalizedString(@"SessionViewController19") content:YMLocalizedString(@"SessionViewController10")];
} restriction:^{
@kStrongify(self);
[self showNotPhoto:YMLocalizedString(@"SessionViewController19") content:YMLocalizedString(@"SessionViewController12")];
}];
}
- (void)inputBarView:(QInputBarView *)inputBarView onPhototButtonClick:(UIButton *)emotionSwitchButton {
if (emotionSwitchButton.isSelected) {
@kWeakify(self);
[YYUtility checkAssetsLibrayAvailable:^{
@kStrongify(self);
[TZImagePickerConfig sharedInstance].allowPickingImage = YES;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[[TZImageManager manager] getCameraRollAlbumWithFetchAssets:NO completion:^(TZAlbumModel *model) {
[[TZImageManager manager] getAssetsFromFetchResult:model.result completion:^(NSArray<TZAssetModel *> *models) {
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray * array = [NSMutableArray array];
if (models.count > 40) {
for (int i = 0; i < 40; i++) {
TZAssetModel * assets = [models objectAtIndex:i];
QPhotoImageModel * infor = [[QPhotoImageModel alloc] init];
infor.isOrigin = NO;
infor.assetInfo = assets;
[array addObject:infor];
}
} else {
for (int i = 0; i < models.count; i++) {
TZAssetModel * assets = [models objectAtIndex:i];
QPhotoImageModel * infor = [[QPhotoImageModel alloc] init];
infor.isOrigin = NO;
infor.assetInfo = assets;
[array addObject:infor];
}
}
self.phototArray = array;
if (self.phototArray.count > 0) {
self.photoView.photoList = self.phototArray;
[self.keyboardManager switchToPhotoBoardKeyboard];
} else {
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:self];
imagePickerVc.modalPresentationStyle = UIModalPresentationOverFullScreen;
imagePickerVc.allowPickingVideo = NO;
imagePickerVc.allowTakeVideo = NO;
imagePickerVc.naviBgColor = [DJDKMIMOMColor appCellBackgroundColor];
imagePickerVc.naviTitleColor = [DJDKMIMOMColor mainTextColor];
imagePickerVc.barItemTextColor = [DJDKMIMOMColor mainTextColor];
[self presentViewController:imagePickerVc animated:YES completion:nil];
}
});
}];
}];
});
} denied:^{
@kStrongify(self);
[self showNotPhoto:YMLocalizedString(@"SessionViewController20") content:YMLocalizedString(@"SessionViewController14")];
} restriction:^{
@kStrongify(self);
[self showNotPhoto:YMLocalizedString(@"SessionViewController20") content:YMLocalizedString(@"SessionViewController16")];
}];
} else {
[_keyboardManager hideAllBoardView];
_inputBarView.inputTextView.text = @"";
[_inputBarView textViewResignFirstResponder];
}
}
- (void)showNotPhoto:(NSString *)title content:(NSString *)content {
TTAlertConfig *config = [[TTAlertConfig alloc] init];
config.title = title;
config.message = content;
[TTPopup alertWithConfig:config confirmHandler:^{
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {
}];
}
} cancelHandler:^{
}];
}
#pragma mark - InputBoardDelegate
- (void)keyboardManager:(QKeyboardManager *)keyboardManager onWholeInputViewHeightDidChange:(CGFloat)wholeInputViewHeight reason:(WholeInputViewHeightDidChangeReason)reason {
[UIView animateWithDuration:0.2 animations:^{
if(self.messages.count > 0){
NSIndexPath *ip = [NSIndexPath indexPathForRow:self.messages.count-1 inSection:0]; //取最后一行数据
[self.sessionTableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:NO]; //滚动到最后一行
}
[self.sessionTableView mas_remakeConstraints:^(MASConstraintMaker *make) {
make.leading.trailing.mas_equalTo(self.view);
make.top.mas_equalTo(self.headView.mas_bottom);
make.bottom.mas_equalTo(self.view).offset(-wholeInputViewHeight - kSafeAreaBottomHeight);
}];
}];
}
#pragma mark - QEmotionBoardViewDelegate
/**
* 选中表情时的回调
* @param index 被选中的表情在`emotions`里的索引
* @param emotion 被选中的表情对应的`QMUIEmotion`对象
*/
- (void)emotionView:(QEmotionBoardView *)emotionView didSelectEmotion:(QEmotion *)emotion atIndex:(NSInteger)index {
//把😊插入到输入栏
UIFont *font = [UIFont systemFontOfSize:17.5];
NSTextAttachment * emotionAtt = [[NSTextAttachment alloc] init];
UIImage *iconImage = emotion.image;
emotionAtt.bounds = CGRectMake(0, roundf(font.capHeight - emotion.image.size.width)/2.f, emotion.image.size.width, emotion.image.size.height);
emotionAtt.image = iconImage;
emotionAtt.imageName = emotion.displayName;
NSAttributedString *emotionAttribute = [NSMutableAttributedString attributedStringWithAttachment:(NSTextAttachment *)emotionAtt];
[_inputBarView insertEmotionAttributedString:emotionAttribute];
}
// 删除按钮的点击事件回调
- (void)emotionViewDidSelectDeleteButton:(QEmotionBoardView *)emotionView {
if (![_inputBarView deleteEmotion]){
//根据当前的光标,这次点击删除按钮并没有删除表情,那么就删除文字
[_inputBarView.inputTextView deleteBackward];
}
}
// 发送按钮的点击事件回调
- (void)emotionViewDidSelectSendButton:(QEmotionBoardView *)emotionView {
[self sendTextMessage:[_inputBarView textViewInputNormalText]];
_inputBarView.inputTextView.text = @"";
[_keyboardManager hideAllBoardView];
}
/**
* 点击了系统键盘的发送按钮
* @param inputNormalText "害~你好啊[微笑]"
*/
- (void)inputBarView:(QInputBarView *)inputBarView onKeyboardSendClick:(NSString *)inputNormalText {
[self sendTextMessage:inputNormalText];
_inputBarView.inputTextView.text = @"";
[_keyboardManager hideAllBoardView];
}
#pragma mark - QinputPhotoViewDelegate
- (void)qinputPhotoView:(QinputPhotoView *)view didClickSend:(NSArray *)photoList {
for (int i = 0; i < photoList.count; i++) {
QPhotoImageModel * imageInfo = [photoList xpSafeObjectAtIndex:i];
UIImage * image;
if (view.isOrigin) {
image = imageInfo.originImage;
} else {
image = imageInfo.compressImage;
}
if (image == nil){
continue;
}
// 发送消息
NIMMessage * message = [NIMMessageMaker msgWithImage:image];
message.remoteExt = [self getRemoteExt];
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:self.session error:nil];
[view resetChoosePhotos];
}
}
- (void)qinputPhotoView:(QinputPhotoView *)view didClickPhoto:(UIButton *)sender {
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:self];
imagePickerVc.modalPresentationStyle = UIModalPresentationOverFullScreen;
imagePickerVc.allowPickingVideo = NO;
imagePickerVc.allowTakeVideo = NO;
imagePickerVc.naviBgColor = [DJDKMIMOMColor appCellBackgroundColor];
imagePickerVc.naviTitleColor = [DJDKMIMOMColor mainTextColor];
imagePickerVc.barItemTextColor = [DJDKMIMOMColor mainTextColor];
[self presentViewController:imagePickerVc animated:YES completion:nil];
}
#pragma mark - UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *selectedPhoto = [info objectForKey:UIImagePickerControllerEditedImage];
if (selectedPhoto) {
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImageWriteToSavedPhotosAlbum(selectedPhoto, nil, nil, nil);
}
// NIMAntiSpamOption *option = [[NIMAntiSpamOption alloc]init];
// option.yidunEnabled = YES;
// option.businessId = @"e9da8bd5c76da23d5e37f87e5ab1f5e9";
NIMMessage * message = [NIMMessageMaker msgWithImage:selectedPhoto];
message.remoteExt = [self getRemoteExt];
// message.antiSpamOption = option;
// 发送消息
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:self.session error:nil];
}
[picker dismissViewControllerAnimated:YES completion:^{}];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[picker dismissViewControllerAnimated:YES completion:^{
}];
}
#pragma mark - Getters And Setters
- (NSArray<MessageBaseModel *> *)messages {
if (!_messages) {
_messages = [[NSMutableArray alloc] init];
}
return _messages;
}
#pragma mark - Event Response
- (void)closeKeyBoard {
[self.view endEditing:YES];
[self.inputBarView textViewResignFirstResponder];
}
- (UITableView *)sessionTableView {
if (!_sessionTableView) {
_sessionTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_sessionTableView.delegate = self;
_sessionTableView.dataSource = self;
_sessionTableView.backgroundColor = UIColor.clearColor;
_sessionTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_sessionTableView.showsVerticalScrollIndicator = NO;
[_sessionTableView registerClass:[MSSessionPublicChatHalTextCell class] forCellReuseIdentifier:NSStringFromClass([MSSessionPublicChatHalTextCell class])];
[_sessionTableView registerClass:[MSSessionPublicChatHalImageCell class] forCellReuseIdentifier:NSStringFromClass([MSSessionPublicChatHalImageCell class])];
[_sessionTableView registerClass:[MSSessionPublicChatHalRightTextCell class] forCellReuseIdentifier:NSStringFromClass([MSSessionPublicChatHalRightTextCell class])];
[_sessionTableView registerClass:[MSSessionPublicChatHalIRightmageCell class] forCellReuseIdentifier:NSStringFromClass([MSSessionPublicChatHalIRightmageCell class])];
if (@available(iOS 11.0, *)) {
_sessionTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
}
return _sessionTableView;
}
- (SessionNavView *)sessionNavView {
if (!_sessionNavView) {
_sessionNavView = [[SessionNavView alloc] init];
_sessionNavView.delegate = self;
_sessionNavView.isPublicChatHall = YES;
}
return _sessionNavView;
}
- (MSSessionPublicChatHallHeadView *)headView{
if(!_headView){
_headView = [[MSSessionPublicChatHallHeadView alloc]initWithFrame:CGRectZero];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(clickReleaseBtnAction)];
[_headView addGestureRecognizer:tap];
}
return _headView;
}
- (UIButton *)sendBtn{
if(!_sendBtn){
_sendBtn = [UIButton new];
[_sendBtn setBackgroundImage:[UIImage getLanguageImage:@"ms_message_send_headline_bnt"] forState:UIControlStateNormal];
[_sendBtn addTarget:self action:@selector(sendHeadlineBtnAction) forControlEvents:UIControlEventTouchUpInside];
}
return _sendBtn;
}
@end