// // NIMSessionListViewController.m // NIMKit // // Created by NetEase. // Copyright (c) 2015年 NetEase. All rights reserved. // #import "NIMSessionListViewController.h" #import "NIMSessionViewController.h" #import "NIMSessionListCell.h" #import "UIView+NIM.h" #import "NIMAvatarImageView.h" #import "NIMKitUtil.h" #import "NIMKit.h" #import "NTESSessionUtil.h" @interface NIMSessionListViewController () @end @implementation NIMSessionListViewController - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { } return self; } - (void)dealloc{ [[NIMSDK sharedSDK].conversationManager removeDelegate:self]; [[NIMSDK sharedSDK].loginManager removeDelegate:self]; [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped]; [self.view addSubview:self.tableView]; self.tableView.delegate = self; self.tableView.dataSource = self; self.tableView.tableFooterView = [[UIView alloc] init]; self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; self.tableView.estimatedSectionHeaderHeight = 0.0f; self.tableView.estimatedSectionFooterHeight = 0.0f; if (@available(iOS 15.0, *)) { self.tableView.sectionHeaderTopPadding = 0; } _recentSessions = [[NIMSDK sharedSDK].conversationManager.allRecentSessions mutableCopy]; if (!self.recentSessions.count) { _recentSessions = [NSMutableArray array]; } else { _recentSessions = [self customSortRecents:_recentSessions]; } [[NIMSDK sharedSDK].conversationManager addDelegate:self]; [[NIMSDK sharedSDK].loginManager addDelegate:self]; extern NSString *const NIMKitTeamInfoHasUpdatedNotification; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onTeamInfoHasUpdatedNotification:) name:NIMKitTeamInfoHasUpdatedNotification object:nil]; extern NSString *const NIMKitTeamMembersHasUpdatedNotification; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onTeamMembersHasUpdatedNotification:) name:NIMKitTeamMembersHasUpdatedNotification object:nil]; extern NSString *const NIMKitUserInfoHasUpdatedNotification; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onUserInfoHasUpdatedNotification:) name:NIMKitUserInfoHasUpdatedNotification object:nil]; } - (void)refresh{ // if (self.recentSessions.count == 0) { // self.tableView.hidden = YES; // }else{ // self.tableView.hidden = NO; // } [self.tableView reloadData]; if (![self isNotDataSource]) { [self.tableView lz_hideEmptyView]; }else{ [self showEmptyView]; } } - (BOOL)isNotDataSource{ NSInteger sections = self.tableView.numberOfSections; for (int section = 0; section < sections; section++) { NSInteger rows = [self.tableView numberOfRowsInSection:section]; if (rows != 0) { return NO; } } return YES; } - (void)showEmptyView{ } #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; NIMRecentSession *recentSession = self.recentSessions[indexPath.section]; [self onSelectedRecent:recentSession atIndexPath:indexPath]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 74.f; } - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ return CGFLOAT_MIN; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return CGFLOAT_MIN; } #pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return self.recentSessions.count; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ NIMRecentSession *recent = self.recentSessions[section]; NSDictionary *dict = [[YOUPAILZIntimateManager shareManager].intimateDict objectForKey:recent.session.sessionId]; NSInteger grade = [[dict objectForKey:@"grade"] integerValue]; if (self.isIntimateList && grade < 1) { return 0; } return 1; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString * cellId = @"cellId"; NIMSessionListCell * cell = [tableView dequeueReusableCellWithIdentifier:cellId]; if (!cell) { cell = [[NIMSessionListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId]; } [cell.avatarImageView addTarget:self action:@selector(onTouchAvatar:) forControlEvents:UIControlEventTouchUpInside]; NIMRecentSession *recent = self.recentSessions[indexPath.section]; cell.nameLabel.text = [self nameForRecentSession:recent]; [cell.avatarImageView setAvatarBySession:recent.session]; [cell.nameLabel sizeToFit]; if ([[self contentForRecentSession:recent] isEqualToAttributedString:[[NSAttributedString alloc] initWithString:@"[缘分牵线]"]]) { NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc]initWithString:@"[缘分牵线]"]; [attStr addAttribute:NSForegroundColorAttributeName value:HexColorFromRGB(0xFE66A4) range:NSMakeRange(0, 6)];//字体颜色 [attStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:12] range:NSMakeRange(0, 6)];//字体大小 NSTextAttachment *attchment = [[NSTextAttachment alloc]init]; attchment.bounds = CGRectMake(0, -3,15,15);//设置frame attchment.image = [UIImage imageNamed:@"vqu_images_fate_heart"];//设置图片  NSAttributedString *string = [NSAttributedString attributedStringWithAttachment:(NSTextAttachment *)(attchment)]; [attStr insertAttributedString:string atIndex:5];//插入到第几个下标 cell.messageLabel.attributedText = attStr; }else{ cell.messageLabel.attributedText = [self contentForRecentSession:recent]; } [cell.messageLabel sizeToFit]; cell.timeLabel.text = [self timestampDescriptionForRecentSession:recent]; [cell.timeLabel sizeToFit]; [cell refresh:recent]; cell.intimateBtn.hidden = YES; NSDictionary *dict = [[YOUPAILZIntimateManager shareManager].intimateDict objectForKey:recent.session.sessionId]; NSString *score = [dict objectForKey:@"score"]; if (score.length != 0) { cell.intimateBtn.hidden = NO; [cell.intimateBtn setTitle:[NSString stringWithFormat:@"%@",score] forState:UIControlStateNormal]; } NSString *ext = [self getExtBySession:recent.session]; cell.vipV.hidden = YES; cell.anchorTagImgV.hidden = YES; if (ext.length != 0) { NSData *data = [ext dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; if ([dict.allKeys containsObject:@"vip"]) { NSInteger vip = [[dict valueForKey:@"vip"] integerValue]; NSDictionary *vipInfo = [LCSaveData getNobleInfo]; NSDictionary *vipItemInfo = [vipInfo objectForKey:[NSString stringWithFormat:@"%@",@(vip)]]; if (vipItemInfo != nil) { cell.vipV.hidden = NO; [cell.vipV sd_setImageWithURL:[LCTools getImageUrlWithAddress:[vipItemInfo objectForKey:@"mini_icon"]]]; [cell.vipV mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(cell.nameLabel.mas_right).offset(5.0f); make.centerY.equalTo(cell.nameLabel); make.size.mas_offset(CGSizeMake(30.0f, 19.0f)); }]; } } if ([dict.allKeys containsObject:@"is_live"]) { NSInteger is_live = [[dict valueForKey:@"is_live"] integerValue]; if (is_live == 1) { cell.anchorTagImgV.hidden = NO; } } } [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; //v1.5.6 暗黑模式 // [cell.contentView setBackgroundColor:LCWhiteColor]; cell.avatarImageView.contentMode = UIViewContentModeScaleAspectFill; return cell; } #pragma mark - NIMConversationManagerDelegate - (void)didAddRecentSession:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount{ [self.recentSessions addObject:recentSession]; [self sort]; _recentSessions = [self customSortRecents:_recentSessions]; [self refresh]; } - (void)didUpdateRecentSession:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount{ for (NIMRecentSession *recent in self.recentSessions) { if ([recentSession.session.sessionId isEqualToString:recent.session.sessionId]) { [self.recentSessions removeObject:recent]; break; } } NSInteger insert = [self findInsertPlace:recentSession]; [self.recentSessions insertObject:recentSession atIndex:insert]; _recentSessions = [self customSortRecents:_recentSessions]; [self refresh]; } - (void)didRemoveRecentSession:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount { //清理本地数据 NSInteger index = [self.recentSessions indexOfObject:recentSession]; [self.recentSessions removeObjectAtIndex:index]; //如果删除本地会话后就不允许漫游当前会话,则需要进行一次删除服务器会话的操作 if (self.autoRemoveRemoteSession) { [[NIMSDK sharedSDK].conversationManager deleteRemoteSessions:@[recentSession.session] completion:nil]; } _recentSessions = [self customSortRecents:_recentSessions]; [self refresh]; } - (void)messagesDeletedInSession:(NIMSession *)session{ _recentSessions = [[NIMSDK sharedSDK].conversationManager.allRecentSessions mutableCopy]; _recentSessions = [self customSortRecents:_recentSessions]; [self refresh]; } - (void)allMessagesDeleted{ _recentSessions = [[NIMSDK sharedSDK].conversationManager.allRecentSessions mutableCopy]; _recentSessions = [self customSortRecents:_recentSessions]; [self refresh]; } - (void)allMessagesRead { _recentSessions = [[NIMSDK sharedSDK].conversationManager.allRecentSessions mutableCopy]; _recentSessions = [self customSortRecents:_recentSessions]; [self refresh]; } - (NSMutableArray *)customSortRecents:(NSMutableArray *)recentSessions { return self.recentSessions; } #pragma mark - NIMLoginManagerDelegate - (void)onLogin:(NIMLoginStep)step { if (step == NIMLoginStepSyncOK) { [self refresh]; } } #pragma mark - Override - (void)onSelectedAvatar:(NSString *)userId atIndexPath:(NSIndexPath *)indexPath{}; - (void)onSelectedRecent:(NIMRecentSession *)recentSession atIndexPath:(NSIndexPath *)indexPath{ NIMSessionViewController *vc = [[NIMSessionViewController alloc] initWithSession:recentSession.session]; [self.navigationController pushViewController:vc animated:YES]; } - (NSString *)getExtBySession:(NIMSession *)session{ NIMUser *nimUser = [[[NIMSDK sharedSDK] userManager] userInfo:session.sessionId]; return nimUser.userInfo.ext; } - (NSString *)nameForRecentSession:(NIMRecentSession *)recent{ if (recent.session.sessionType == NIMSessionTypeP2P) { return [NIMKitUtil showNick:recent.session.sessionId inSession:recent.session]; }else{ NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:recent.session.sessionId]; return team.teamName; } } - (NSAttributedString *)contentForRecentSession:(NIMRecentSession *)recent{ NSString *content = [self messageContent:recent.lastMessage]; return [[NSAttributedString alloc] initWithString:content ?: @""]; } - (NSString *)timestampDescriptionForRecentSession:(NIMRecentSession *)recent{ return [NIMKitUtil showTime:recent.lastMessage.timestamp showDetail:NO]; } #pragma mark - Misc - (NSInteger)findInsertPlace:(NIMRecentSession *)recentSession{ __block NSUInteger matchIdx = 0; __block BOOL find = NO; [self.recentSessions enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NIMRecentSession *item = obj; if (item.lastMessage.timestamp <= recentSession.lastMessage.timestamp) { *stop = YES; find = YES; matchIdx = idx; } }]; if (find) { return matchIdx; }else{ return self.recentSessions.count; } } - (void)sort{ [self.recentSessions sortUsingComparator:^NSComparisonResult(id obj1, id obj2) { NIMRecentSession *item1 = obj1; NIMRecentSession *item2 = obj2; if (item1.lastMessage.timestamp < item2.lastMessage.timestamp) { return NSOrderedDescending; } if (item1.lastMessage.timestamp > item2.lastMessage.timestamp) { return NSOrderedAscending; } return NSOrderedSame; }]; } - (void)onTouchAvatar:(id)sender{ UIView *view = [sender superview]; while (![view isKindOfClass:[UITableViewCell class]]) { view = view.superview; } UITableViewCell *cell = (UITableViewCell *)view; NSIndexPath *indexPath = [self.tableView indexPathForCell:cell]; NIMRecentSession *recent = self.recentSessions[indexPath.section]; [self onSelectedAvatar:recent atIndexPath:indexPath]; } #pragma mark - Private - (NSString *)messageContent:(NIMMessage*)lastMessage{ NSString *text = @""; switch (lastMessage.messageType) { case NIMMessageTypeText: text = lastMessage.text; break; case NIMMessageTypeAudio: text = @"[语音]"; break; case NIMMessageTypeImage: text = @"[图片]"; break; case NIMMessageTypeVideo: text = @"[视频]"; break; case NIMMessageTypeLocation: text = @"[位置]"; break; case NIMMessageTypeNotification:{ return [self notificationMessageContent:lastMessage]; } case NIMMessageTypeFile: text = @"[文件]"; break; case NIMMessageTypeTip: text = lastMessage.text; break; case NIMMessageTypeRobot: text = [self robotMessageContent:lastMessage]; break; default: text = @"[未知消息]"; } if (lastMessage.session.sessionType == NIMSessionTypeP2P || lastMessage.messageType == NIMMessageTypeTip) { return text; } else { NSString *from = lastMessage.from; if (lastMessage.messageType == NIMMessageTypeRobot) { NIMRobotObject *object = (NIMRobotObject *)lastMessage.messageObject; if (object.isFromRobot) { from = object.robotId; } } NSString *nickName = [NIMKitUtil showNick:from inSession:lastMessage.session]; return nickName.length ? [nickName stringByAppendingFormat:@" : %@",text] : @""; } } - (NSString *)notificationMessageContent:(NIMMessage *)lastMessage{ NIMNotificationObject *object = lastMessage.messageObject; if (object.notificationType == NIMNotificationTypeNetCall) { NIMNetCallNotificationContent *content = (NIMNetCallNotificationContent *)object.content; if (content.callType == NIMNetCallTypeAudio) { return @"[网络通话]"; } return @"[视频聊天]"; } if (object.notificationType == NIMNotificationTypeTeam) { NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:lastMessage.session.sessionId]; if (team.type == NIMTeamTypeNormal) { return @"[讨论组信息更新]"; }else{ return @"[群信息更新]"; } } return @"[未知消息]"; } - (NSString *)robotMessageContent:(NIMMessage *)lastMessage{ NIMRobotObject *object = lastMessage.messageObject; if (object.isFromRobot) { return @"[机器人消息]"; } else { return lastMessage.text; } } #pragma mark - Notification - (void)onUserInfoHasUpdatedNotification:(NSNotification *)notification{ [self refresh]; } - (void)onTeamInfoHasUpdatedNotification:(NSNotification *)notification{ [self refresh]; } - (void)onTeamMembersHasUpdatedNotification:(NSNotification *)notification{ [self refresh]; } @end