// // YOUPAIUCIMP2PSessionVC.m // wolfman // // Created by 张灿 on 2017/6/3. // Copyright © 2017年 shareSmile. All rights reserved. // #import "YOUPAIUCIMP2PSessionVC.h" #import "NIMSessionConfigurateProtocol.h" #import "NIMKit.h" #import "NIMMessageCellProtocol.h" #import "NIMMessageModel.h" #import "NIMKitUtil.h" #import "NIMCustomLeftBarView.h" #import "NIMBadgeView.h" #import "UITableView+NIMScrollToBottom.h" #import "NIMMessageMaker.h" #import "UIView+NIM.h" #import "NIMKitTitleView.h" #import "NIMKitKeyboardInfo.h" #import "NIMSessionConfigurator.h" #import "NIMKitInfoFetchOption.h" #import "YOUPAIUCIMP2PSessionConfig.h" #import "NTESTimerHolder.h" #import "NSDictionary+NTESJson.h" #import "NTESCustomSysNotificationSender.h" #import "UIViewController+TFPresent.h" #import "YOUPAIZYIMSessionDetailWindow.h" #import "YOUPAIZYUpdateRemarkWindow.h" #import "YOUPAILCReportVC.h" #import "YOUPAILZUserShowVC.h" #import "YOUPAILZChatRoomPasswordWindow.h" #import "LZAlertWindow.h" #import "YOUPAIZhaPianTextAttachment.h" #import "YOUPAIZhaPianTextAttachment2.h" #import "LOTAnimationView.h" #import "YOUPAILZChatRoomVC.h" #import "YOUPAILZSessionDetailVC.h" @interface YOUPAIUCIMP2PSessionVC () @property (nonatomic,readwrite) NIMMessage *messageForMenu; @property (nonatomic,strong) UILabel *titleLabel; @property (nonatomic,strong) UILabel *subTitleLabel; @property (nonatomic,strong) NSIndexPath *lastVisibleIndexPathBeforeRotation; @property (nonatomic,strong) YOUPAIUCIMP2PSessionConfig* sessionConfig; @property (nonatomic,strong) NIMCustomLeftBarView* badgeBarView; @property (nonatomic,strong) NTESCustomSysNotificationSender *notificaionSender; @property (nonatomic,strong) NTESTimerHolder *titleTimer; @property(nonatomic,strong)UIView *bgView; @property(nonatomic,copy)NSString *youpaiptalk_room_id; @end @implementation YOUPAIUCIMP2PSessionVC #pragma mark - 子类实现 - (void)vqf_youpaifprofileClick{ NSLog(@"头像点击啦"); } - (instancetype)initWithSession:(NIMSession *)session{ self = [super initWithNibName:nil bundle:nil]; if (self) { _session = session; } return self; } - (void)dealloc { [self removeListener]; [[NIMKit sharedKit].robotTemplateParser clean]; _tableView.delegate = nil; _tableView.dataSource = nil; } - (void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; //判断是否有本地消息记录 用来判断是否是第一次聊天 [self youpaifcheckLocalMessage]; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; _notificaionSender = [[NTESCustomSysNotificationSender alloc] init]; BOOL disableCommandTyping = self.disableCommandTyping || (self.session.sessionType == NIMSessionTypeP2P &&[[NIMSDK sharedSDK].userManager isUserInBlackList:self.session.sessionId]); if (!disableCommandTyping) { _titleTimer = [[NTESTimerHolder alloc] init]; [[NIMSDK sharedSDK].systemNotificationManager addDelegate:self]; } //导航栏 [self youpaifsetupNav]; //消息 tableView [self youpaifsetupTableView]; //输入框 inputView [self youpaifsetupInputView]; //会话相关逻辑配置器安装 [self youpaifsetupConfigurator]; //添加监听 [self addListener]; //进入会话时,标记所有消息已读,并发送已读回执 [self markRead]; //更新已读位置 [self uiCheckReceipts:nil]; [self loadShowChatRoomHeaderViewData]; } - (void)youpaifsetupNav { //子类实现 [self setUpTitleView]; //导航栏设置 NIMCustomLeftBarView *leftBarView = [[NIMCustomLeftBarView alloc] initWithFrame:CGRectMake(0, 0, 70, 44)]; leftBarView.badgeView.badgeTextColor = LZ273145Color; leftBarView.backImgV.image = [UIImage imageNamed:@"vqu_images_navigation_back_black"]; [leftBarView addTarget:self action:@selector(youpaifbackClick) forControlEvents:UIControlEventTouchUpInside]; // self.navigationController.navigationBar.barTintColor = LZ273145Color; UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithCustomView:leftBarView]; // if (@available(iOS 11.0, *)) { // leftBarView.translatesAutoresizingMaskIntoConstraints = NO; // } self.badgeBarView = leftBarView; self.navigationItem.leftBarButtonItem = leftItem; // //设置不进入聊天详情的页面号 // NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary]; // textAttrs[NSForegroundColorAttributeName] = LZ273145Color; // self.navigationController.navigationBar.titleTextAttributes = textAttrs; // if (@available(iOS 15.0, *)) { // UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init]; // appearance.backgroundEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleRegular]; // [appearance setBackgroundColor:[UIColor whiteColor]]; // appearance.backgroundEffect = nil; // appearance.shadowColor = [UIColor clearColor]; // appearance.titleTextAttributes = textAttrs; // self.navigationController.navigationBar.standardAppearance = appearance; // self.navigationController.navigationBar.scrollEdgeAppearance = appearance; // } // if (![self.session.sessionId isEqualToString:[LCSaveData getSysId]] && (![self.session.sessionId isEqualToString:[LCSaveData getServerId]])) { // self.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(youpaifuserSetClick) image:[UIImage imageNamed:@"vqu_images_IM_im_details"]]; // } [LCHttpHelper requestWithURLString:AppConfig parameters:nil needToken:YES type:(HttpRequestTypePost) success:^(id responseObject) { NSDictionary* dict = (NSDictionary*)responseObject; NSInteger code = [[dict objectForKey:@"code"] integerValue]; if (code==0) {//成功 NSArray *array = [[[dict objectForKey:@"data"]objectForKey:@"config"] objectForKey:@"no_info"]; if (![array containsObject:self.session.sessionId]) { self.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(youpaifuserSetClick) image:[UIImage imageNamed:@"vqu_images_IM_im_details"]] ; } } } failure:^(NSError *error) {}]; } - (void)youpaifbackClick{ [self.navigationController popViewControllerAnimated:YES]; } #pragma mark-更多 - (void)youpaifuserSetClick{ YOUPAILZSessionDetailVC *vc = [[YOUPAILZSessionDetailVC alloc] init]; vc.youpaipsession = self.session; [self.navigationController pushViewController:vc animated:YES]; // YOUPAIZYIMSessionDetailWindow *vc= [[YOUPAIZYIMSessionDetailWindow alloc]init]; // vc.vWidth = KScreenWidth -68; // vc.vHeight = 315+25+30; // vc.youpaipsession = self.session; // vc.youpaipdelegate = self; // vc.isTouchDismiss = YES; // [self TFPresentVC:vc completion:^{}]; } -(void)loadShowChatRoomHeaderViewData{ [LCHttpHelper requestWithURLString:ChatRoom_getUserTalk parameters:@{@"user_id":self.session.sessionId} needToken:YES type:(HttpRequestTypePost) success:^(id responseObject) { NSDictionary* dict = (NSDictionary*)responseObject; NSInteger code = [[dict objectForKey:@"code"] integerValue]; if (code == 0) {//成功 NSString *roomID =dict[@"data"][@"room_id"]; if (roomID.length>0) { [self loadShowChatRoomHeaderView:dict[@"data"][@"avatar"]:dict[@"data"][@"room_id"]]; self.youpaiptalk_room_id =dict[@"data"][@"room_id"]; } }else{ [ZCHUDHelper showTitle:dict[@"message"]]; } } failure:^(NSError *error) { }]; } //头部语音房显示 -(void)loadShowChatRoomHeaderView:(NSString*)avatar :(NSString*)roomId{ UIView *bgView = [UIView new]; self.bgView = bgView; [self.view addSubview:bgView]; [bgView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.mas_equalTo(20); make.centerX.mas_equalTo(0); make.height.mas_equalTo(40); make.width.mas_equalTo(240); }]; UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(vqf_handlePan:)]; [bgView addGestureRecognizer:panGestureRecognizer]; // bgView.backgroundColor = [UIColor yellowColor]; UIImageView *youpaipcoverImgV = [[UIImageView alloc] init]; youpaipcoverImgV.layer.cornerRadius = 35.0f/2; youpaipcoverImgV.clipsToBounds = YES; youpaipcoverImgV.contentMode = UIViewContentModeScaleAspectFill; [bgView addSubview:youpaipcoverImgV]; [youpaipcoverImgV mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(0); make.left.mas_equalTo(0); make.size.mas_offset(CGSizeMake(35, 35)); }]; youpaipcoverImgV.backgroundColor = [UIColor clearColor]; [youpaipcoverImgV sd_setImageWithURL:[LCTools getImageUrlWithAddress:avatar] placeholderImage:nil]; LOTAnimationView *youpaiptalkingAnimationView = [LOTAnimationView animationWithFilePath:[[NSBundle mainBundle] pathForResource:@"ic_chatroom_seat_animation" ofType:@"json"]]; youpaiptalkingAnimationView.frame = CGRectMake(0.0f, 0.0f, 35.0f * 1.7f, 35.0f * 1.7f); youpaiptalkingAnimationView.loopAnimation = YES; youpaiptalkingAnimationView.contentMode = UIViewContentModeScaleAspectFill; [youpaiptalkingAnimationView play]; [bgView addSubview:youpaiptalkingAnimationView]; [youpaiptalkingAnimationView mas_makeConstraints:^(MASConstraintMaker *make) { make.center.equalTo(youpaipcoverImgV); make.size.mas_offset(CGSizeMake(35 * 1.7f, 35 * 1.7f)); }]; // UIButton *contentImage = [UIButton new]; [bgView addSubview:contentImage]; [contentImage mas_makeConstraints:^(MASConstraintMaker *make) { make.left.mas_equalTo(youpaipcoverImgV.mas_right).offset(-5); make.width.mas_equalTo(166); make.height.mas_equalTo(26); make.centerY.mas_equalTo(youpaipcoverImgV); }]; [contentImage setBackgroundImage:[UIImage imageNamed:@"vqu_chatroom_bg_HeaderView_bg"] forState:UIControlStateNormal]; [bgView sendSubviewToBack:contentImage]; [contentImage addTarget:self action:@selector(contentImageClickToChatRoom) forControlEvents:UIControlEventTouchUpInside]; // UILabel *contentLabel = [UILabel new]; [contentImage addSubview:contentLabel]; [contentLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.mas_equalTo(10); make.centerY.mas_equalTo(0); }]; contentLabel.text = @"我在语聊厅内表演"; contentLabel.textColor = [UIColor whiteColor]; contentLabel.font = [UIFont systemFontOfSize:12]; // UIImageView *contentRightImage = [UIImageView new]; [bgView addSubview:contentRightImage]; [contentRightImage mas_makeConstraints:^(MASConstraintMaker *make) { make.left.mas_equalTo(contentLabel.mas_right).offset(3); make.centerY.mas_equalTo(0); make.size.mas_equalTo(CGSizeMake(51, 20)); }]; contentRightImage.image = [UIImage imageNamed:@"vqu_chatroom_bg_HeaderView_right"]; //取消 UIButton *cancelBtn = [UIButton new]; [bgView addSubview:cancelBtn]; [cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.left.mas_equalTo(contentRightImage.mas_right); make.centerY.mas_equalTo(0); make.size.mas_equalTo(CGSizeMake(30, 20)); }]; UIImageView *im = [UIImageView new]; [cancelBtn addSubview:im]; [im mas_makeConstraints:^(MASConstraintMaker *make) { make.center.mas_equalTo(0); make.size.mas_equalTo(CGSizeMake(9, 9)); }]; im.image = [UIImage imageNamed:@"vqu_chatroom_bg_HeaderView_cancel"]; // cancelBtn.backgroundColor= [UIColor redColor]; [cancelBtn addTarget:self action:@selector(cancelBtnClick) forControlEvents:UIControlEventTouchUpInside]; } - (void)vqf_handlePan:(UIPanGestureRecognizer*) recognizer{ CGPoint translation = [recognizer translationInView:self.view]; CGFloat centerX=recognizer.view.center.x+ translation.x; CGFloat thecenter=0; recognizer.view.center = CGPointMake(centerX,recognizer.view.center.y+ translation.y); [recognizer setTranslation:CGPointZero inView:self.view]; if(recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled) { if(centerX > KScreenWidth/2) { thecenter = KScreenWidth-240.0f/2 - 10.0f; }else{ thecenter = 240.0f / 2 + 10.0f; } [UIView animateWithDuration:0.3 animations:^{ CGFloat y = recognizer.view.center.y; if (recognizer.view.center.y < NavBarHeight) { y = 21.0f+15; }else if (recognizer.view.center.y > KScreenHeight - TabbarHeight - 21.0f - 240.0f / 2.0f){ y = KScreenHeight - TabbarHeight - 21.0f - 240.0f / 2.0f; } recognizer.view.center=CGPointMake(thecenter, y + translation.y); }]; } } -(void)cancelBtnClick{ [UIView animateWithDuration:0.01 animations:^{ self.bgView.frame = CGRectMake(0,-NavBarHeight, 240, 40); }]; } -(void)contentImageClickToChatRoom{ if ([[YOUPAILZChatRoomManager shareManager].chatroomModel.youpaiproom_id isEqual:self.youpaiptalk_room_id] && [YOUPAILZChatRoomManager shareManager].chatroomController != nil) { [[YOUPAILZChatRoomManager shareManager] youpaifshowChatRoom]; return; } [self youpaifshowPasswordWindowWithRoomId:self.youpaiptalk_room_id youpaipis_comein_room_hide:0]; } - (void)youpaifshowPasswordWindowWithRoomId:(NSString *)roomId youpaipis_comein_room_hide:(NSInteger)youpaipis_comein_room_hide{ @weakify(self); [LCHttpHelper requestWithURLString:GetRoomStatus parameters:@{@"room_id":roomId} needToken:YES type:(HttpRequestTypePost) success:^(id responseObject) { @strongify(self); NSDictionary* dict = (NSDictionary*)responseObject; NSInteger code = [[dict objectForKey:@"code"] integerValue]; if (code==0) { NSDictionary *data = [dict objectForKey:@"data"]; if ([[data objectForKey:@"pwd"] integerValue] == 1) { // 有密码 YOUPAILZChatRoomPasswordWindow *window = [[YOUPAILZChatRoomPasswordWindow alloc] init]; [window setYoupaippasswordBlock:^(NSString * _Nonnull password, YOUPAILZChatRoomPasswordWindow * _Nonnull window) { @strongify(self); [self youpaifgoChatRoomVCWithPwd:password RoomId:roomId youpaipis_comein_room_hide:youpaipis_comein_room_hide window:window]; }]; [self TFPresentVC:window completion:^{}]; }else{ [self youpaifgoChatRoomVCWithPwd:@"" RoomId:roomId youpaipis_comein_room_hide:youpaipis_comein_room_hide window:nil]; } } } failure:^(NSError *error) { }]; } /// 加入语聊房 /// @param pwd 密码 /// @param roomId 房间号 /// @param youpaipis_comein_room_hide 是否悄悄进房 /// @param window 密码框 - (void)youpaifgoChatRoomVCWithPwd:(NSString *)pwd RoomId:(NSString *)roomId youpaipis_comein_room_hide:(NSInteger)youpaipis_comein_room_hide window:(YOUPAILZChatRoomPasswordWindow *)window{ [ZCHUDHelper show]; @weakify(self); [LCHttpHelper requestWithURLString:JoinTalk parameters:@{@"room_id":roomId,@"pwd":pwd,@"is_comein_room_hide":@(youpaipis_comein_room_hide)} needToken:YES type:(HttpRequestTypePost) success:^(id responseObject) { [ZCHUDHelper dismiss]; @strongify(self); NSDictionary* dict = (NSDictionary*)responseObject; NSInteger code = [[dict objectForKey:@"code"] integerValue]; if (code==0) { if (window != nil) { [window dismissViewControllerAnimated:YES completion:^{}]; } [[YOUPAILZChatRoomManager shareManager] youpaifleaveChannel]; YOUPAILZChatRoomModel *youpaipchatroomModel = [YOUPAILZChatRoomModel mj_objectWithKeyValues:dict[@"data"]]; // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ YOUPAILZChatRoomVC *vc = [[YOUPAILZChatRoomVC alloc] init]; vc.youpaipchatroomModel = youpaipchatroomModel; [[LCTools getContainNavigationControllerCurrentVC].navigationController pushViewController:vc animated:YES]; [YOUPAILZChatRoomManager shareManager].chatroomModel = vc.youpaipchatroomModel; [YOUPAILZChatRoomManager shareManager].chatroomController = vc; // }); }else{ if (window != nil) { [window youpaifshowHUDWithTitle:[dict objectForKey:@"message"]]; }else{ [ZCHUDHelper showTitle:[dict objectForKey:@"message"]]; } } } failure:^(NSError *error) { [ZCHUDHelper dismiss]; }]; } - (void)youpaifsetupTableView { self.view.backgroundColor = [UIColor whiteColor]; self.tableView = [[YOUPAIUCBaseTouchTableView alloc] initWithFrame:CGRectMake(0, NavBarHeight, KScreenWidth, KScreenHeight-NavBarHeight) style:UITableViewStylePlain]; self.tableView.touchDelegate = self; self.tableView.backgroundColor = LZFAFAFCColor; self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; self.tableView.estimatedRowHeight = 0; self.tableView.estimatedSectionHeaderHeight = 0; self.tableView.estimatedSectionFooterHeight = 0; self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; if ([self.sessionConfig respondsToSelector:@selector(sessionBackgroundImage)] && [self.sessionConfig sessionBackgroundImage]) { UIImageView *imgView = [[UIImageView alloc] initWithFrame:self.view.bounds]; imgView.image = [self.sessionConfig sessionBackgroundImage]; imgView.contentMode = UIViewContentModeScaleAspectFill; self.tableView.backgroundView = imgView; } if (@available(iOS 15.0, *)) { self.tableView.sectionHeaderTopPadding = 0; } [self.view addSubview:self.tableView]; } - (void)youpaifsetupInputView { if ([self shouldShowInputView]) { self.sessionInputView = [[YOUPAINIMInputView alloc] initWithFrame:CGRectMake(0, 0, self.view.nim_width,0) config:self.sessionConfig]; self.sessionInputView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; [self.sessionInputView setSession:self.session]; [self.sessionInputView setInputDelegate:self]; [self.sessionInputView setInputActionDelegate:self]; [self.sessionInputView refreshStatus:NIMInputStatusText]; [self.view addSubview:_sessionInputView]; // self.sessionInputView self.tableView.nim_height -= self.sessionInputView.toolBar.nim_height; } } - (void)youpaifsetupConfigurator { _configurator = [[NIMSessionConfigurator alloc] init]; [_configurator youpaifuc_setup:self]; BOOL needProximityMonitor = [self needProximityMonitor]; [[NIMSDK sharedSDK].mediaManager setNeedProximityMonitor:needProximityMonitor]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.interactor onViewWillAppear]; // [self.navigationController.navigationBar setBackgroundColor:LCNavColor]; // if (@available(iOS 15.0, *)) { // [self.navigationController.navigationBar.scrollEdgeAppearance setBackgroundColor:LCNavColor]; // [self.navigationController.navigationBar.standardAppearance setBackgroundColor:LCNavColor]; // } } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.sessionInputView endEditing:YES]; // [self.navigationController.navigationBar setBackgroundColor:[UIColor clearColor]]; // if (@available(iOS 15.0, *)) { // [self.navigationController.navigationBar.scrollEdgeAppearance setBackgroundColor:[UIColor clearColor]]; // [self.navigationController.navigationBar.standardAppearance setBackgroundColor:[UIColor clearColor]]; // } } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [self.interactor onViewDidDisappear]; } - (void)viewDidLayoutSubviews { [self changeLeftBarBadge:self.conversationManager.allUnreadCount]; [self.interactor resetLayout]; } #pragma mark - 第一次聊天的提示信息 - (void)youpaifcheckLocalMessage{ NIMMessageSearchOption* option = [[NIMMessageSearchOption alloc]init]; option.allMessageTypes = YES; option.order = NIMMessageSearchOrderDesc; [[[NIMSDK sharedSDK] conversationManager] searchMessages:self.session option:option result:^(NSError * _Nullable error, NSArray * _Nullable messages) { if (messages.count==0 && [LCSaveModel getUserModel].youpaipuserinfo.youpaipgender==2) { //不是系统和客服才请求 if (![self.session.sessionId isEqualToString:[LCSaveData getSysId]] && ![self.session.sessionId isEqualToString:[LCSaveData getServerId]]) {//请求提示信息 } } }]; } #pragma mark - 对方输入状态 - (void)onReceiveCustomSystemNotification:(NIMCustomSystemNotification *)notification { if (!notification.sendToOnlineUsersOnly) { return; } NSData *data = [[notification content] dataUsingEncoding:NSUTF8StringEncoding]; if (data) { NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; if ([dict jsonInteger:NTESNotifyID] == NTESCommandTyping && self.session.sessionType == NIMSessionTypeP2P && [notification.sender isEqualToString:self.session.sessionId]) { [self refreshSessionTitle:@"对方正在输入..."]; [_titleTimer startTimer:5 delegate:self repeats:NO]; } } } - (void)onNTESTimerFired:(NTESTimerHolder *)holder { [self refreshSessionTitle:self.youpaifsessionTitle]; } #pragma mark - 消息收发接口 - (void)sendMessage:(NIMMessage *)message { // // 构造自定义消息附件 // NIMCustomObject *object = [[NIMCustomObject alloc] init]; // YOUPAIZhaPianTextAttachment *attachment = [[YOUPAIZhaPianTextAttachment alloc] init]; // object.attachment = attachment; // // // 构造出具体消息并注入附件 // NIMMessage *message1 = [[NIMMessage alloc] init]; // message1.messageObject = object; // // // NIMCustomObject *object1 = [[NIMCustomObject alloc] init]; // YOUPAIZhaPianTextAttachment2 *attachment1 = [[YOUPAIZhaPianTextAttachment2 alloc] init]; // object1.attachment = attachment1; // // // 构造出具体消息并注入附件 // NIMMessage *message2 = [[NIMMessage alloc] init]; // message2.messageObject = object1; // // // // 错误反馈对象 // NSError *error = nil; // if ([message.text isEqualToString:@"63"]) { // // [[NIMSDK sharedSDK].chatManager sendMessage:message1 toSession:self.session error:&error]; // }else if ([message.text isEqualToString:@"64"]){ // [[NIMSDK sharedSDK].chatManager sendMessage:message2 toSession:self.session error:&error]; // }else{ // [self.interactor sendMessage:message]; // } [UMengRecordTool umengEventCountWithId:ClickSendMessage]; // 发送消息 // [self.interactor sendMessageReceipt:@[message]]; [self.interactor sendMessage:message]; } #pragma mark - Touch Event - (void)youpaifdidTouchesBegan:(YOUPAIUCBaseTouchTableView *)tableView{ [_sessionInputView endEditing:YES]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; [_sessionInputView endEditing:YES]; } #pragma mark - NIMSessionConfiguratorDelegate - (void)didFetchMessageData { [self uiCheckReceipts:nil]; [self.tableView reloadData]; [self.tableView nim_scrollToBottom:NO]; } - (void)didRefreshMessageData { [self refreshSessionTitle:self.youpaifsessionTitle]; [self refreshSessionSubTitle:self.sessionSubTitle]; [self.tableView reloadData]; } - (void)didPullUpMessageData {} #pragma mark - 会话title - (NSString *)youpaifsessionTitle { NSString *title = @""; NIMSessionType type = self.session.sessionType; switch (type) { case NIMSessionTypeTeam:{ NIMTeam *team = [[[NIMSDK sharedSDK] teamManager] teamById:self.session.sessionId]; title = [NSString stringWithFormat:@"%@(%zd)",[team teamName],[team memberNumber]]; } break; case NIMSessionTypeP2P:{ title = [NIMKitUtil showNick:self.session.sessionId inSession:self.session]; } break; default: break; } return title; } - (NSString *)sessionSubTitle{return @"";}; #pragma mark - NIMChatManagerDelegate //开始发送 - (void)willSendMessage:(NIMMessage *)message { id interactor = self.interactor; if ([message.session isEqual:self.session]) { if ([interactor findMessageModel:message]) { [interactor updateMessage:message]; }else{ [interactor addMessages:@[message]]; } } } //上传资源文件成功 - (void)uploadAttachmentSuccess:(NSString *)urlString forMessage:(NIMMessage *)message { //如果需要使用富文本推送,可以在这里进行 message apns payload 的设置 } //发送结果 - (void)sendMessage:(NIMMessage *)message didCompleteWithError:(NSError *)error { if ([message.session isEqual:_session]) { [self.interactor updateMessage:message]; if (message.session.sessionType == NIMSessionTypeTeam) { //如果是群的话需要检查一下回执显示情况 NIMMessageReceipt *receipt = [[NIMMessageReceipt alloc] initWithMessage:message]; [self.interactor checkReceipts:@[receipt]]; }else{ if (error == nil && [LCSaveModel getUserModel].youpaipuserinfo.youpaipgender == 2) { NIMMessageSearchOption *searchOption = [[NIMMessageSearchOption alloc] init]; searchOption.messageTypes = @[@(NIMMessageTypeText),@(NIMMessageTypeImage),@(NIMMessageTypeAudio),@(NIMMessageTypeVideo)]; searchOption.fromIds = @[[LCSaveModel getUserModel].youpaipuserinfo.youpaipuser_id]; [[NIMSDK sharedSDK].conversationManager searchMessages:self.session option:searchOption result:^(NSError * _Nullable error, NSArray * _Nullable messages) { if (messages.count == 1) { [LCHttpHelper requestWithURLString:SendTipMsg parameters:@{@"user_id":self.session.sessionId} needToken:YES type:(HttpRequestTypePost) success:^(id responseObject) { NSDictionary* dict = (NSDictionary*)responseObject; NSInteger code = [[dict objectForKey:@"code"] integerValue]; if (code==0) { } } failure:^(NSError *error) { }]; } }]; } } } } //发送进度 -(void)sendMessage:(NIMMessage *)message progress:(float)progress { if ([message.session isEqual:_session]) { [self.interactor updateMessage:message]; } } //接收消息 - (void)onRecvMessages:(NSArray *)messages { if ([self shouldAddListenerForNewMsg]) { NIMMessage *message = messages.firstObject; NIMSession *session = message.session; if (![session isEqual:self.session] || !messages.count) { return; } [self youpaifuiAddMessages:messages]; [self.interactor markRead]; } } - (void)fetchMessageAttachment:(NIMMessage *)message progress:(float)progress { if ([message.session isEqual:_session]) { [self.interactor updateMessage:message]; } } - (void)fetchMessageAttachment:(NIMMessage *)message didCompleteWithError:(NSError *)error { if ([message.session isEqual:_session]) { NIMMessageModel *model = [self.interactor findMessageModel:message]; //下完缩略图之后,因为比例有变化,重新刷下宽高。 [model cleanCache]; [self.interactor updateMessage:message]; } } - (void)onRecvMessageReceipts:(NSArray *)receipts { if ([self shouldAddListenerForNewMsg]) { NSMutableArray *handledReceipts = [[NSMutableArray alloc] init]; for (NIMMessageReceipt *receipt in receipts) { if ([receipt.session isEqual:self.session]) { [handledReceipts addObject:receipt]; } } if (handledReceipts.count) { [self uiCheckReceipts:handledReceipts]; } } } #pragma mark - NIMConversationManagerDelegate - (void)messagesDeletedInSession:(NIMSession *)session{ [self.interactor resetMessages:nil]; [self.tableView reloadData]; } - (void)didAddRecentSession:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount{ [self changeUnreadCount:recentSession totalUnreadCount:totalUnreadCount]; } - (void)didUpdateRecentSession:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount{ [self changeUnreadCount:recentSession totalUnreadCount:totalUnreadCount]; } - (void)didRemoveRecentSession:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount{ [self changeUnreadCount:recentSession totalUnreadCount:totalUnreadCount]; } - (void)changeUnreadCount:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount{ if ([recentSession.session isEqual:self.session]) { return; } [self changeLeftBarBadge:totalUnreadCount]; } #pragma mark - NIMMediaManagerDelegate - (void)recordAudio:(NSString *)filePath didBeganWithError:(NSError *)error { if (!filePath || error) { _sessionInputView.recording = NO; [self youpaifonRecordFailed:error]; } } - (void)recordAudio:(NSString *)filePath didCompletedWithError:(NSError *)error { if(!error) { if ([self youpaifrecordFileCanBeSend:filePath]) { [self sendMessage:[NIMMessageMaker msgWithAudio:filePath]]; }else{ [self showRecordFileNotSendReason]; } } else { [self youpaifonRecordFailed:error]; } _sessionInputView.recording = NO; } - (void)recordAudioDidCancelled { _sessionInputView.recording = NO; } - (void)recordAudioProgress:(NSTimeInterval)currentTime { [_sessionInputView updateAudioRecordTime:currentTime]; } - (void)recordAudioInterruptionBegin { [[NIMSDK sharedSDK].mediaManager cancelRecord]; } #pragma mark - 录音相关接口 - (void)youpaifonRecordFailed:(NSError *)error{} - (BOOL)youpaifrecordFileCanBeSend:(NSString *)filepath { return YES; } - (void)showRecordFileNotSendReason{} #pragma mark - NIMInputDelegate - (void)youpaifdidChangeInputHeight:(CGFloat)inputHeight { [self.interactor changeLayout:inputHeight]; } #pragma mark - NIMInputActionDelegate - (BOOL)onTapMediaItem:(NIMMediaItem *)item{ SEL sel = item.selctor; BOOL handled = sel && [self respondsToSelector:sel]; if (handled) { NIMKit_SuppressPerformSelectorLeakWarning([self performSelector:sel withObject:item]); handled = YES; } return handled; } - (void)onTextChanged:(id)sender{ [_notificaionSender sendTypingState:self.session]; } - (void)onSendText:(NSString *)text atUsers:(NSArray *)atUsers { NSMutableArray *users = [NSMutableArray arrayWithArray:atUsers]; if (self.session.sessionType == NIMSessionTypeP2P) { [users addObject:self.session.sessionId]; } NSString *robotsToSend = [self robotsToSend:users]; NIMMessage *message = nil; if (robotsToSend.length) { message = [NIMMessageMaker msgWithRobotQuery:text toRobot:robotsToSend]; } else { message = [NIMMessageMaker msgWithText:text]; } if (atUsers.count) { NIMMessageApnsMemberOption *apnsOption = [[NIMMessageApnsMemberOption alloc] init]; apnsOption.userIds = atUsers; apnsOption.forcePush = YES; NIMKitInfoFetchOption *option = [[NIMKitInfoFetchOption alloc] init]; option.session = self.session; NSString *me = [[NIMKit sharedKit].provider infoByUser:[NIMSDK sharedSDK].loginManager.currentAccount option:option].showName; apnsOption.apnsContent = [NSString stringWithFormat:@"%@在群里@了你",me]; message.apnsMemberOption = apnsOption; } [self sendMessage:message]; } - (NSString *)robotsToSend:(NSArray *)atUsers { for (NSString *userId in atUsers) { if ([[NIMSDK sharedSDK].robotManager isValidRobot:userId]) { return userId; } } return nil; } - (void)onSelectChartlet:(NSString *)chartletId catalog:(NSString *)catalogId{} - (void)onCancelRecording { [[NIMSDK sharedSDK].mediaManager cancelRecord]; } - (void)onStopRecording { [[NIMSDK sharedSDK].mediaManager stopRecord]; } - (void)onStartRecording { _sessionInputView.recording = YES; NIMAudioType type = [self recordAudioType]; NSTimeInterval duration = [NIMKit sharedKit].config.recordMaxDuration; [[NIMSDK sharedSDK].mediaManager addDelegate:self]; [[NIMSDK sharedSDK].mediaManager record:type duration:duration]; } #pragma mark - NIMMessageCellDelegate - (BOOL)onTapCell:(NIMKitEvent *)event{ BOOL handle = NO; NSString *eventName = event.eventName; if ([eventName isEqualToString:NIMKitEventNameTapAudio]) { [self.interactor mediaAudioPressed:event.messageModel]; handle = YES; } if ([eventName isEqualToString:NIMKitEventNameTapRobotBlock]) { NSDictionary *param = event.data; NIMMessage *message = [NIMMessageMaker msgWithRobotSelect:param[@"text"] target:param[@"target"] params:param[@"param"] toRobot:param[@"robotId"]]; [self sendMessage:message]; handle = YES; } if ([eventName isEqualToString:NIMKitEventNameTapRobotContinueSession]) { NIMRobotObject *robotObject = (NIMRobotObject *)event.messageModel.message.messageObject; NIMRobot *robot = [[NIMSDK sharedSDK].robotManager robotInfo:robotObject.robotId]; NSString *text = [NSString stringWithFormat:@"%@%@%@",NIMInputAtStartChar,robot.nickname,NIMInputAtEndChar]; NIMInputAtItem *item = [[NIMInputAtItem alloc] init]; item.uid = robot.userId; item.name = robot.nickname; [self.sessionInputView.atCache addAtItem:item]; [self.sessionInputView.toolBar insertText:text]; handle = YES; } return handle; } - (void)onRetryMessage:(NIMMessage *)message { if (message.isReceivedMsg) { [[[NIMSDK sharedSDK] chatManager] fetchMessageAttachment:message error:nil]; }else{ [[[NIMSDK sharedSDK] chatManager] resendMessage:message error:nil]; } } - (BOOL)onLongPressCell:(NIMMessage *)message inView:(UIView *)view { BOOL handle = NO; NSArray *items = [self youpaifmenusItems:message]; if ([items count] && [self becomeFirstResponder]) { UIMenuController *controller = [UIMenuController sharedMenuController]; controller.menuItems = items; _messageForMenu = message; [controller setTargetRect:view.bounds inView:view]; [controller setMenuVisible:YES animated:YES]; handle = YES; } return handle; } - (BOOL)disableAudioPlayedStatusIcon:(NIMMessage *)message { BOOL disable = NO; if ([self.sessionConfig respondsToSelector:@selector(disableAudioPlayedStatusIcon)]) { disable = [self.sessionConfig disableAudioPlayedStatusIcon]; } return disable; } #pragma mark - 配置项 - (id)sessionConfig { return [[YOUPAIUCIMP2PSessionConfig alloc] init]; //使用默认配置 } #pragma mark - 配置项列表 //是否需要监听新消息通知 : 某些场景不需要监听新消息,如浏览服务器消息历史界面 - (BOOL)shouldAddListenerForNewMsg { BOOL should = YES; if ([self.sessionConfig respondsToSelector:@selector(disableReceiveNewMessages)]) { should = ![self.sessionConfig disableReceiveNewMessages]; } return should; } //是否需要显示输入框 : 某些场景不需要显示输入框,如使用 3D touch 的场景预览会话界面内容 - (BOOL)shouldShowInputView { BOOL should = YES; if ([self.sessionConfig respondsToSelector:@selector(disableInputView)]) { should = ![self.sessionConfig disableInputView]; } if ([[LCSaveData getSysId] isEqualToString:self.session.sessionId] || [self.session.sessionId isEqualToString:@"11"]) { should = NO; } return should; } //当前录音格式 : NIMSDK 支持 aac 和 amr 两种格式 - (NIMAudioType)recordAudioType { NIMAudioType type = NIMAudioTypeAAC; if ([self.sessionConfig respondsToSelector:@selector(recordType)]) { type = [self.sessionConfig recordType]; } return type; } //是否需要监听感应器事件 - (BOOL)needProximityMonitor { BOOL needProximityMonitor = YES; if ([self.sessionConfig respondsToSelector:@selector(disableProximityMonitor)]) { needProximityMonitor = !self.sessionConfig.disableProximityMonitor; } return needProximityMonitor; } #pragma mark - 菜单 - (NSArray *)youpaifmenusItems:(NIMMessage *)message { NSMutableArray *items = [NSMutableArray array]; BOOL copyText = NO; if (message.messageType == NIMMessageTypeText) { copyText = YES; } if (message.messageType == NIMMessageTypeRobot) { NIMRobotObject *robotObject = (NIMRobotObject *)message.messageObject; copyText = !robotObject.isFromRobot; } if (copyText) { [items addObject:[[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copyText:)]]; } [items addObject:[[UIMenuItem alloc] initWithTitle:@"删除" action:@selector(deleteMsg:)]]; return items; } - (NIMMessage *)messageForMenu { return _messageForMenu; } - (BOOL)canBecomeFirstResponder { return YES; } - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { NSArray *items = [[UIMenuController sharedMenuController] menuItems]; for (UIMenuItem *item in items) { if (action == [item action]){ return YES; } } return NO; } - (void)copyText:(id)sender { NIMMessage *message = [self messageForMenu]; if (message.text.length) { UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; [pasteboard setString:message.text]; } } - (void)deleteMsg:(id)sender { NIMMessage *message = [self messageForMenu]; [self youpaifuiDeleteMessage:message]; [self.conversationManager deleteMessage:message]; } - (void)menuDidHide:(NSNotification *)notification { [UIMenuController sharedMenuController].menuItems = nil; } #pragma mark - 操作接口 - (void)youpaifuiAddMessages:(NSArray *)messages { [self.interactor addMessages:messages]; } - (void)youpaifuiInsertMessages:(NSArray *)messages { [self.interactor insertMessages:messages]; } - (NIMMessageModel *)youpaifuiDeleteMessage:(NIMMessage *)message{ NIMMessageModel *model = [self.interactor deleteMessage:message]; if (model.shouldShowReadLabel && model.message.session.sessionType == NIMSessionTypeP2P) { [self uiCheckReceipts:nil]; } return model; } - (void)youpaifuiUpdateMessage:(NIMMessage *)message{ [self.interactor updateMessage:message]; } - (void)uiCheckReceipts:(NSArray *)receipts { [self.interactor checkReceipts:receipts]; } #pragma mark - NIMMeidaButton - (void)onTapMediaItemPicture:(NIMMediaItem *)item { [self.interactor mediaPicturePressed]; } - (void)onTapMediaItemShoot:(NIMMediaItem *)item { [self.interactor mediaShootPressed]; } - (void)onTapMediaItemLocation:(NIMMediaItem *)item { [self.interactor mediaLocationPressed]; } #pragma mark - 旋转处理 (iOS8 or above) - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { self.lastVisibleIndexPathBeforeRotation = [self.tableView indexPathsForVisibleRows].lastObject; [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; if (self.view.window) { __weak typeof(self) wself = self; [coordinator animateAlongsideTransition:^(id context) { [[NIMSDK sharedSDK].mediaManager cancelRecord]; [wself.interactor cleanCache]; [wself.sessionInputView reset]; [wself.tableView reloadData]; [wself.tableView scrollToRowAtIndexPath:wself.lastVisibleIndexPathBeforeRotation atScrollPosition:UITableViewScrollPositionBottom animated:NO]; } completion:nil]; } } #pragma mark - 标记已读 - (void)markRead { [self.interactor markRead]; } #pragma mark - Private - (void)addListener { [[NIMSDK sharedSDK].chatManager addDelegate:self]; [[NIMSDK sharedSDK].conversationManager addDelegate:self]; } - (void)removeListener { [[NIMSDK sharedSDK].chatManager removeDelegate:self]; [[NIMSDK sharedSDK].conversationManager removeDelegate:self]; } - (void)changeLeftBarBadge:(NSInteger)unreadCount { // NIMCustomLeftBarView *leftBarView = (NIMCustomLeftBarView *)self.navigationItem.leftBarButtonItem.customView; self.badgeBarView.badgeView.badgeValue = [NSString stringWithFormat:@"%ld", unreadCount]; // self.badgeBarView.badgeView.backgroundColor = [UIColor yellowColor]; self.badgeBarView.badgeView.hidden = !unreadCount; } - (id)conversationManager{ switch (self.session.sessionType) { case NIMSessionTypeChatroom: return nil; break; case NIMSessionTypeP2P: case NIMSessionTypeTeam: default: return [NIMSDK sharedSDK].conversationManager; } } - (void)setUpTitleView { NIMKitTitleView *titleView = (NIMKitTitleView *)self.navigationItem.titleView; if (!titleView || ![titleView isKindOfClass:[NIMKitTitleView class]]) { titleView = [[NIMKitTitleView alloc] initWithFrame:CGRectZero]; self.navigationItem.titleView = titleView; titleView.titleLabel.text = self.youpaifsessionTitle; titleView.subtitleLabel.text = self.sessionSubTitle; titleView.titleLabel.textColor = LZ273145Color; titleView.titleLabel.font = LCFont16; self.titleLabel = titleView.titleLabel; self.subTitleLabel = titleView.subtitleLabel; } [titleView sizeToFit]; } - (void)refreshSessionTitle:(NSString *)title { self.titleLabel.text = title; [self setUpTitleView]; } - (void)refreshSessionSubTitle:(NSString *)title { self.subTitleLabel.text = title; [self setUpTitleView]; } #pragma mark ZYIMSessionDetailWindowDelegate -(void)youpaifimSessionDetailWindowAction:(NSString *)type andSession:(NIMSession *)session { if ([type isEqualToString:@"updateRemark"]) {//设置备注名 YOUPAIZYUpdateRemarkWindow *VC= [[YOUPAIZYUpdateRemarkWindow alloc]init]; VC.vWidth = KScreenWidth -68; VC.vHeight = ScaleHeight(187)+10; VC.youpaipsession = session; VC.isTouchDismiss = NO; [kAppDelegate.window.rootViewController TFPresentVC:VC completion:^{ }]; } if ([type isEqualToString:@"clearChat"]) {//清除聊天记录 WeakSelf; LZAlertAction *cancelAction = [LZAlertAction actionWithTitle:@"取消" handler:^(LZAlertAction *action) { }]; cancelAction.cornerRadius = 24.0f; cancelAction.color = LZ273145Color; cancelAction.bgColor = LZF5F4F7Color; LZAlertAction *confimAction = [LZAlertAction actionWithTitle:@"删除" handler:^(LZAlertAction *action) { [weakSelf clearChatSession:session]; }]; confimAction.cornerRadius = 24.0f; confimAction.color = [UIColor whiteColor]; confimAction.bgColor = [UIColor colorWithPatternImage:[LCTools ColorImage:CGSizeMake((KScreenWidth - 105.0f) / 2.0f, 48.0f) FromColors:@[LZBFB6FFColor,LZ7C69FEColor] ByGradientType:GradientLeftToRight]]; LZAlertWindow *alert = [LZAlertWindow alertWithTitle:@"提示" content:@"确定删除该聊天?" action:@[cancelAction,confimAction]]; alert.contentTextAlignment = NSTextAlignmentCenter; [self TFPresentVC:alert completion:^{}]; } if ([type isEqualToString:@"report"]) {//举报 YOUPAILCReportVC* report = [[YOUPAILCReportVC alloc]init]; report.youpaipreport_uid = session.sessionId; report.youpaiptype = 4; [self.navigationController pushViewController:report animated:YES]; } } -(void)showUserVCWithSession:(NIMSession *)session { YOUPAILZUserShowVC *vc = [[YOUPAILZUserShowVC alloc] init]; vc.youpaipuserId = session.sessionId; [self.navigationController pushViewController:vc animated:YES]; } -(void)clearChatSession:(NIMSession *)session { id manager = [[NIMSDK sharedSDK] conversationManager]; NIMDeleteMessagesOption* deleteOption = [[NIMDeleteMessagesOption alloc]init]; deleteOption.removeSession = NO; deleteOption.removeTable = YES; [manager deleteAllmessagesInSession:session option:deleteOption]; [ZCHUDHelper showTitle:@"已清空"]; } @end