// // ChatHistoryController.m // AIIM // // Created by gan on 2025/5/2. // #import #import "ChatHistoryController.h" #import "config.h" #import "ChatsStore.h" #import "CryptoAES.h" #import "SDWebImage/SDWebImage.h" #import "FileNetApi.h" #import "FilePreviewer.h" #import "HistoryPreloader.h" #import "chatCellView.h" @interface ChatHistoryController() @property (weak, nonatomic) IBOutlet UILabel *titleLb; @property (weak, nonatomic) IBOutlet UIScrollView *topScrollV; @property (weak, nonatomic) IBOutlet UITableView *tableView; @property (weak, nonatomic) IBOutlet UIImageView *bigImageV; @property (nonatomic,strong) UITextView *textV; @property (nonatomic,strong) UIButton *bt1; @property (nonatomic,strong) UIButton *bt2; @property (nonatomic,strong) UIButton *bt3; @property (nonatomic,strong) UIButton *bt4; @property (nonatomic,strong) UIButton *bt5; @property (nonatomic,strong) UIButton *bt6; @property(nonatomic, strong) NSArray *msgList; @property (nonatomic,strong) NSString *username; @property (nonatomic,strong) NSString *useravatar; @property (nonatomic) BOOL canloadhistory; @property (nonatomic,strong) NSString *ListType; @property (nonatomic, strong) NSMutableArray * messageArray; @end @implementation ChatHistoryController -(void)viewDidLoad{ [super viewDidLoad]; [self.navigationController setNavigationBarHidden:YES animated:NO]; [_tableView registerClass:chatCellView.class forCellReuseIdentifier:NSStringFromClass(chatCellView.class)]; _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; _tableView.backgroundColor = [UIColor clearColor]; _tableView.delegate=self; _tableView.dataSource = self; ChatsStore.shareInstance.delegate = self; ChatsStore.shareInstance.chatId = self.chatId; _titleLb.text = self.titlename; _textV=[[UITextView alloc] init]; _canloadhistory=true; [self initTopScrollList]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; ChatsStore.shareInstance.delegate = nil; ChatsStore.shareInstance.chatId = nil; } - (IBAction)gotoback:(id)sender { [self dismissViewControllerAnimated:YES completion:nil]; } -(void)initTopScrollList{ CGFloat btwidth = 50.0f; CGFloat btdisten = btwidth+10; _bt1 = [[UIButton alloc] init]; _bt1 = [[UIButton alloc] init]; _bt1.tag = 1; _bt1.frame=CGRectMake(btdisten*0, 10, btwidth, 30); _bt1.backgroundColor =globalColor(GCTypeGreen); _bt1.layer.cornerRadius = 8; _bt1.layer.masksToBounds = YES; // 防止子视图超出圆角边界 _bt1.titleLabel.font = [UIFont systemFontOfSize: 14.0]; [_bt1 setTitle:@"全部" forState:UIControlStateNormal]; _bt1.titleLabel.textColor = [UIColor blackColor]; [_bt1 addTarget:self action:@selector(topBtAct:) forControlEvents:UIControlEventTouchUpInside]; _bt2 = [[UIButton alloc] init]; _bt2 = [[UIButton alloc] init]; _bt2.tag = 2; _bt2.frame=CGRectMake(btdisten*1, 10, btwidth, 30); _bt2.backgroundColor =[UIColor clearColor]; _bt2.layer.cornerRadius = 8; _bt2.layer.masksToBounds = YES; // 防止子视图超出圆角边界 _bt2.titleLabel.font = [UIFont systemFontOfSize: 14.0]; [_bt2 setTitle:@"文本" forState:UIControlStateNormal]; _bt2.titleLabel.textColor = [UIColor blackColor]; [_bt2 addTarget:self action:@selector(topBtAct:) forControlEvents:UIControlEventTouchUpInside]; _bt3 = [[UIButton alloc] init]; _bt3 = [[UIButton alloc] init]; _bt3.tag = 3; _bt3.frame=CGRectMake(btdisten*2, 10, btwidth, 30); _bt3.backgroundColor =[UIColor clearColor]; //globalColor(GCTypeGreen); _bt3.layer.cornerRadius = 8; _bt3.layer.masksToBounds = YES; // 防止子视图超出圆角边界 _bt3.titleLabel.font = [UIFont systemFontOfSize: 14.0]; [_bt3 setTitle:@"图片" forState:UIControlStateNormal]; _bt3.titleLabel.textColor = [UIColor blackColor]; [_bt3 addTarget:self action:@selector(topBtAct:) forControlEvents:UIControlEventTouchUpInside]; _bt4 = [[UIButton alloc] init]; _bt4 = [[UIButton alloc] init]; _bt4.tag = 4; _bt4.frame=CGRectMake(btdisten*3, 10, btwidth, 30); _bt4.backgroundColor =[UIColor clearColor]; //globalColor(GCTypeGreen); _bt4.layer.cornerRadius = 8; _bt4.layer.masksToBounds = YES; // 防止子视图超出圆角边界 _bt4.titleLabel.font = [UIFont systemFontOfSize: 14.0]; [_bt4 setTitle:@"文件" forState:UIControlStateNormal]; _bt4.titleLabel.textColor = [UIColor blackColor]; [_bt4 addTarget:self action:@selector(topBtAct:) forControlEvents:UIControlEventTouchUpInside]; _bt5 = [[UIButton alloc] init]; _bt5 = [[UIButton alloc] init]; _bt5.tag = 5; _bt5.frame=CGRectMake(btdisten*4, 10, btwidth, 30); _bt5.backgroundColor =[UIColor clearColor]; //globalColor(GCTypeGreen); _bt5.layer.cornerRadius = 8; _bt5.layer.masksToBounds = YES; // 防止子视图超出圆角边界 _bt5.titleLabel.font = [UIFont systemFontOfSize: 14.0]; [_bt5 setTitle:@"语音" forState:UIControlStateNormal]; _bt5.titleLabel.textColor = [UIColor blackColor]; [_bt5 addTarget:self action:@selector(topBtAct:) forControlEvents:UIControlEventTouchUpInside]; _bt6 = [[UIButton alloc] init]; _bt6 = [[UIButton alloc] init]; _bt6.tag = 6; _bt6.frame=CGRectMake(btdisten*5, 10, btwidth, 30); _bt6.backgroundColor =[UIColor clearColor]; //globalColor(GCTypeGreen); _bt6.layer.cornerRadius = 8; _bt6.layer.masksToBounds = YES; // 防止子视图超出圆角边界 _bt6.titleLabel.font = [UIFont systemFontOfSize: 14.0]; [_bt6 setTitle:@"视频" forState:UIControlStateNormal]; _bt6.titleLabel.textColor = [UIColor blackColor]; [_bt6 addTarget:self action:@selector(topBtAct:) forControlEvents:UIControlEventTouchUpInside]; [_topScrollV addSubview:_bt1]; [_topScrollV addSubview:_bt2]; [_topScrollV addSubview:_bt3]; [_topScrollV addSubview:_bt4]; [_topScrollV addSubview:_bt5]; [_topScrollV addSubview:_bt6]; [self.messageArray removeAllObjects]; _topScrollV.contentSize = CGSizeMake(60*5+btwidth, 50); [self loadData:@""]; } -(void)topBtAct:(UIButton *)bt{ _bt1.backgroundColor =[UIColor clearColor]; _bt2.backgroundColor =[UIColor clearColor]; _bt3.backgroundColor =[UIColor clearColor]; _bt4.backgroundColor =[UIColor clearColor]; _bt5.backgroundColor =[UIColor clearColor]; _bt6.backgroundColor =[UIColor clearColor]; bt.backgroundColor =globalColor(GCTypeGreen); if(bt.tag==1){ [self.messageArray removeAllObjects]; [self loadData:@""]; return; } if(bt.tag==2){ NSString *type =[NSString stringWithFormat:@"%@",MessageType_text]; [self.messageArray removeAllObjects]; [self loadData:type]; return; } if(bt.tag==3){ NSString *type =[NSString stringWithFormat:@"%@",MessageType_image]; [self.messageArray removeAllObjects]; [self loadData:type]; return; } if(bt.tag==4){ NSString *type =[NSString stringWithFormat:@"%@",MessageType_file]; [self.messageArray removeAllObjects]; [self loadData:type]; return; } if(bt.tag==5){ NSString *type =[NSString stringWithFormat:@"%@",MessageType_voice]; [self.messageArray removeAllObjects]; [self loadData:type]; return; } if(bt.tag==6){ NSString *type =[NSString stringWithFormat:@"%@",MessageType_video]; [self.messageArray removeAllObjects]; [self loadData:type]; return; } } -(void)loadData:(NSString *)state{ _ListType = state; if([_ListType isEqualToString:@""]){ [self loadAllData]; } else{ [self loadDataWithType]; } } -(void)loadAllData{ if(self.type==1){ [ChatsStore.shareInstance getGroupHistory:self.chatId type:@""]; } else{ [ChatsStore.shareInstance reloadData:self.chatId]; } } -(void)loadDataWithType{ if(self.type==1){ [ChatsStore.shareInstance getGroupHistory:self.chatId type:_ListType]; } else{ [ChatsStore.shareInstance reloadDataWithType:self.chatId type:_ListType]; } } #pragma mark ChatsStoreDelegate -(void)ChatsChange:(NSArray *)msgList type:(NSInteger)typpe{ NSInteger oldIndex =self.msgList.count; self.msgList =msgList; NSMutableArray * tempArray = [NSMutableArray array]; for (NSDictionary * msg in msgList) { ChatMessageModel *message = [ChatMessageModel modelWithDictionary:msg]; if (message.avatar.length==0 && message.isSender) { message.avatar = self.useravatar; }else if (message.avatar.length==0 && !message.isSender) { message.avatar = self.avatar; } [tempArray addObject:message]; } [self.messageArray removeAllObjects]; [self.messageArray addObjectsFromArray:tempArray]; // 记录当前滚动位置 CGPoint contentOffset = self.tableView.contentOffset; CGFloat y =self.tableView.contentSize.height-self.tableView.contentOffset.y; [self.tableView reloadData]; if(_canloadhistory){ [self movetoBotton]; } else{ if(oldIndex>0){ contentOffset.y= self.tableView.contentSize.height-y; self.tableView.contentOffset = contentOffset; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self->_canloadhistory=true; }); } } } -(void)movetoBotton{ NSLog(@"movetoBotton----------------------"); if (self.msgList.count>0) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSIndexPath *lastRowIndexPath = [NSIndexPath indexPathForRow:([self.tableView numberOfRowsInSection:0] - 1) inSection:0]; //NSLog(@"lastRowIndexPath:%ld",(long)lastRowIndexPath.row); [self.tableView scrollToRowAtIndexPath:lastRowIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO]; }); } } -(void)movetoindex:(NSInteger)index{ NSLog(@"movetoindex----------------------%ld",index); NSInteger row =self.msgList.count-index; if (row>0) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSIndexPath *lastRowIndexPath = [NSIndexPath indexPathForRow:(row) inSection:0]; //NSLog(@"lastRowIndexPath:%ld",(long)lastRowIndexPath.row); [self.tableView scrollToRowAtIndexPath:lastRowIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO]; }); } } #pragma mark UITableViewDelegate,UITableViewDataSource -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.messageArray.count; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ chatCellView *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(chatCellView.class)]; if (!cell) { cell = [[chatCellView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NSStringFromClass(chatCellView.class)]; } cell.isHistory = YES; cell.parentViewController = self; // ChatMessageModel *message = self.messageArray[indexPath.row]; return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { ChatMessageModel *message = self.messageArray[indexPath.row]; return [chatCellView cellHeightForMessage:message]; } - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{ chatCellView * currentCell = (chatCellView *)cell; ChatMessageModel *message = self.messageArray[indexPath.row]; currentCell.messageModel = message; // currentCell.batchState = self.isBatchMode; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ } -(CGFloat)getcellHeight:(NSString *)text{ NSString *dcontent = text;//[CryptoAES.shareInstance decryptDataL:text]; _textV.font = [UIFont systemFontOfSize:17]; _textV.layer.masksToBounds = YES; // 防止子视图超出边界 _textV.editable = NO; _textV.scrollEnabled = NO; // 禁止滚动,使内容自适应高度 CGRect viewFrame = _textV.frame; viewFrame.origin.y=16; viewFrame.origin.x = 8; viewFrame.size.width =self.view.frame.size.width-110; _textV.frame=viewFrame; _textV.text =dcontent; //_textV.text =@"afa faafa faffaf affafafaffa fafafa affafaf faadafafaf afafa aafafafafa afafafafafaf fafafaf afaffa"; [_textV sizeToFit]; viewFrame=_textV.frame; CGFloat height = viewFrame.size.height+66; return height; } -(CGFloat)getImagCellHeight:(NSDictionary *)extend{ return 232; } -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ if (scrollView.contentOffset.y <80) { // 50 是触发加载的额外距离 // 加载更多数据的代码 if(_canloadhistory){ NSLog(@"触发加载更多。。。。:111:%f",scrollView.contentOffset.y); _canloadhistory=false; [self loadhistoryData]; } else{ NSLog(@"触发加载更多。。。。:2"); } } else{ if(scrollView.contentOffset.y>500){ NSLog(@"触发加载更多。。。。:3333:%f",scrollView.contentOffset.y); } } } -(void)loadhistoryData{ if(self.msgList.count>0){ NSLog(@"self.msgList:%lu",(unsigned long)self.msgList.count); _canloadhistory = false; NSDictionary *eldata = self.msgList[0]; NSString *timestr = eldata[@"timestamp"]; NSInteger time =timestr.integerValue; if([_ListType isEqualToString:@""]){ NSLog(@"1-------------------"); [ChatsStore.shareInstance loadNextDataAll:self.chatId timestp:time]; } else{ NSLog(@"1-------------------"); [ChatsStore.shareInstance loadNextDataWithType:self.chatId type:_ListType timestp:time]; } } } -(NSDictionary *)getgroupuser:(NSString *)userId{ for (NSDictionary *item in ChatsStore.shareInstance.groupUserList) { NSString *_id = item[@"id"]; if(_id.integerValue == userId.integerValue){ return item; } } return nil; } -(void)tableListFileAct:(NSDictionary *)msg{ NSString *messageType=msg[@"messageType"]; if(messageType.intValue==1){//放大展示图片 NSDictionary *extend = msg[@"extend"]; NSString *localurl=extend[@"localurl"]; if([self fileExist:localurl]){ NSURL *imageURL = [NSURL fileURLWithPath:localurl]; [_bigImageV sd_setImageWithURL:imageURL placeholderImage:nil options:SDWebImageRetryFailed]; _bigImageV.alpha = 1; NSLog(@"111111111"); } else{ NSURL *imgUrl = [NSURL URLWithString:extend[@"url"]]; [_bigImageV sd_setImageWithURL:imgUrl completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { }]; _bigImageV.alpha = 1; NSLog(@"222222222"); } } if(messageType.intValue==2){//文件 NSDictionary *extend = msg[@"extend"]; NSString *localurl=extend[@"localurl"]; NSString *imgUrl = extend[@"url"]; NSString *msgId = msg[@"id"]; if([self fileExist:localurl]){//文件已经下载,打开文件位置 } else{//下载文件并保存 NSLog(@"imgUrl:%@",imgUrl); [FileNetApi downLoadWToken:[NSURL URLWithString:imgUrl] thrid:msgId succ:^(int code, NSDictionary * res) { NSLog(@"code:%d",code); } fail:^(NSError * _Nonnull error) { NSLog(@"error:%@",error); }]; } } } -(BOOL)fileExist:(NSString *)filePath{ NSLog(@"filePath:%@",filePath); if ([filePath isKindOfClass:NSString.class]) { if (filePath.length>5) { // 创建 NSFileManager 实例 NSFileManager *fileManager = [NSFileManager defaultManager]; // 检查文件是否存在 BOOL fileExists = [fileManager fileExistsAtPath:filePath]; if (fileExists) { NSLog(@"文件存在"); return true; } else { NSLog(@"文件不存在"); return false; } } } return false; } - (NSMutableArray *)messageArray{ if (!_messageArray) { _messageArray = [NSMutableArray array]; } return _messageArray; } #pragma mark statusBar - (UIStatusBarStyle)preferredStatusBarStyle{ return UIStatusBarStyleLightContent; } @end