// // SessionListViewController.m // xplan-ios // // Created by zu on 2021/11/25. // #import "SessionListViewController.h" #import "SessionListCell.h" #import "SessionViewController.h" #import "ThemeColor.h" #import "XPMacro.h" #import "Api+Mine.h" #import "AccountInfoStorage.h" #import "NSArray+Safe.h" #import "ClientConfig.h" ///Model #import "UserInfoModel.h" #import "XPSessionListFansPartyModel.h" ///View #import "XPSessionFindNewViewController.h" #import "TTPopUp.h" #import "XPTeenagerHomeView.h" #import "XPSessionListHeadView.h" NSString * const kMessageShowReadDotKey = @"kMessageShowReadDotKey"; #import @interface SessionListViewController () @property (nonatomic, strong) XPSessionListHeadView *headView; /** * 会话列表 */ @property (nonatomic, strong) UITableView *sessionListView; /** * 最近会话集合 */ @property (nonatomic, strong) NSMutableArray *recentSessions; @property (nonatomic, assign) SessionListOpenType openType; ///用户信息 @property (nonatomic,strong) UserInfoModel *userInfo; ///青少年空白view @property (nonatomic, strong) XPTeenagerHomeView *teenagerView; @end @implementation SessionListViewController @synthesize parentMode = _parentMode; - (void)dealloc { [[NIMSDK sharedSDK].conversationManager removeDelegate:self]; [[NIMSDK sharedSDK].loginManager removeDelegate:self]; } - (BOOL)isHiddenNavBar { return YES; } - (void)setParentMode:(BOOL)parentMode { _parentMode = parentMode; if (parentMode) { if (!self.teenagerView.superview) { [self.view addSubview:self.teenagerView]; [self.teenagerView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.mas_equalTo(self.view); }]; } [self setTabBarItemBadge:0]; } else { [self.teenagerView removeFromSuperview]; __block int unreadCount = 0; NSMutableArray * uids = [[NSMutableArray alloc] init]; [self.recentSessions enumerateObjectsUsingBlock:^(NIMRecentSession * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { [uids addObject:obj.session.sessionId]; unreadCount += obj.unreadCount; }]; [self setTabBarItemBadge:unreadCount]; } } - (instancetype)initWithType:(SessionListOpenType)type { self = [self init]; if (self) { _openType = type; [self initDatas]; } return self; } - (instancetype)init { self = [super init]; if (self) { _openType = SessionListOpenTypeDefault; [self initDatas]; [[NIMSDK sharedSDK].conversationManager addDelegate:self]; [[NIMSDK sharedSDK].loginManager addDelegate:self]; ///置顶会话同步 [[NIMSDKConfig sharedConfig] setShouldSyncStickTopSessionInfos:YES]; } return self; } - (void)viewDidLoad { [super viewDidLoad]; [self initViews]; [self initLayout]; [self getUserInfo]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if (self.openType == SessionListOpenTypeDefault) { [Api requestFansParty:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { if (code == 200) { NSArray *array = [XPSessionListFansPartyModel modelsWithArray:data.data]; self.headView.friendsArray = array; } }]; } } - (void)getUserInfo { NSString * uid = [AccountInfoStorage instance].getUid; [Api getUserInfo:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { if (code == 200) { UserInfoModel * userInfo = [UserInfoModel modelWithDictionary:data.data]; self.userInfo = userInfo; [self.sessionListView reloadData]; [self.headView updateToolViewWithUserLevel:self.userInfo.userLevelVo.charmLevelSeq]; } } uid:uid]; } - (void)initViews { if (self.openType == SessionListOpenTypeDefault) { [self.view addSubview:self.headView]; self.view.backgroundColor = UIColor.clearColor; } [self.view addSubview:self.sessionListView]; } - (void)initLayout { if (self.openType == SessionListOpenTypeDefault) { [self.headView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.mas_equalTo(0); make.top.mas_equalTo(8); }]; } [self.sessionListView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.bottom.mas_equalTo(self.view); if (self.openType == SessionListOpenTypeDefault) { make.top.mas_equalTo(self.headView.mas_bottom); } else { make.top.mas_equalTo(self.view); } }]; } - (void)initDatas { [self.recentSessions removeAllObjects]; _recentSessions = [[NIMSDK sharedSDK].conversationManager.allRecentSessions mutableCopy]; __block int unreadCount = 0; NSMutableArray * uids = [[NSMutableArray alloc] init]; NSMutableArray *officalArray = [NSMutableArray array]; NSMutableArray* sessionList = [NSMutableArray array]; [self.recentSessions enumerateObjectsUsingBlock:^(NIMRecentSession * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if (self.openType != SessionListOpenTypeRoom && [[ClientConfig shareConfig].configInfo.officialMsgUids containsObject:obj.session.sessionId]) { [officalArray addObject:obj]; [self.headView updateBadgeWithSessionId:obj.session.sessionId unreadCount:obj.unreadCount]; } else { if (obj.session.sessionId.integerValue > 0) { [sessionList addObject:obj]; unreadCount += obj.unreadCount; } } }]; self.recentSessions = sessionList; [self setTabBarItemBadge:unreadCount]; [[NIMSDK sharedSDK].userManager fetchUserInfos:uids completion:nil]; NIMLoadRecentSessionsOptions *options = [[NIMLoadRecentSessionsOptions alloc] init]; options.sortByStickTopInfos = YES; [NIMSDK.sharedSDK.chatExtendManager loadRecentSessionsWithOptions:options completion:^(NSError * _Nullable error, NSArray * _Nullable recentSessions) { if (error) { // handle error return; } }]; } #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ [tableView deselectRowAtIndexPath:indexPath animated:YES]; if (self.openType == SessionListOpenTypeRoom) { NIMRecentSession *recentSession = [self.recentSessions safeObjectAtIndex1:indexPath.row]; SessionViewController * sessionVC =[[SessionViewController alloc] initWithSession:recentSession.session]; sessionVC.openType = self.openType; CATransition *transition = [CATransition animation]; transition.duration = 0.3f; transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; transition.type = kCATransitionPush; transition.subtype = kCATransitionFromRight; [self.mainController.view.layer addAnimation:transition forKey:nil]; [self.mainController.view addSubview:sessionVC.view]; [self.mainController addChildViewController:sessionVC]; } else { NIMRecentSession *recentSession = [self.recentSessions safeObjectAtIndex1:indexPath.row]; SessionViewController *vc = [[SessionViewController alloc] initWithSession:recentSession.session]; vc.openType = self.openType; [self.navigationController pushViewController:vc animated:YES]; } } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 75.f; } #pragma mark - UITableViewDataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.recentSessions.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString * cellId = @"cellId"; SessionListCell * cell = [tableView dequeueReusableCellWithIdentifier:cellId]; if (!cell) { cell = [[SessionListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId]; UILongPressGestureRecognizer *longPressPR = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)]; longPressPR.minimumPressDuration = 1; cell.tag = indexPath.row; [cell addGestureRecognizer:longPressPR]; } NIMRecentSession *recent = [self.recentSessions safeObjectAtIndex1:indexPath.row]; [cell renderWithSession:recent]; return cell; } // ⑥长按手势的回调方法 - (void)longPressAction:(UILongPressGestureRecognizer *)sender{ if(sender.state == UIGestureRecognizerStateBegan){ TTAlertConfig *config = [[TTAlertConfig alloc] init]; config.title = @"提示"; config.message = @"确定删除该聊天吗?"; [TTPopup alertWithConfig:config confirmHandler:^{ SessionListCell * cell = (SessionListCell *)sender.view; NIMRecentSession * session = cell.session; NIMSessionDeleteAllRemoteMessagesOptions *option = [[NIMSessionDeleteAllRemoteMessagesOptions alloc]init]; [[NIMSDK sharedSDK].conversationManager deleteAllRemoteMessagesInSession:session.session options:option completion:^(NSError * _Nullable error) { [[NIMSDK sharedSDK].conversationManager deleteRecentSession:session]; }]; } cancelHandler:^{ }]; } } #pragma mark - NIMConversationManagerDelegate - (void)didLoadAllRecentSessionCompletion { [self initDatas]; [self.sessionListView reloadData]; } - (void)didAddRecentSession:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount { if(self.openType != SessionListOpenTypeRoom && [[ClientConfig shareConfig].configInfo.officialMsgUids containsObject:recentSession.session.sessionId]) { [self.headView updateBadgeWithSessionId:recentSession.session.sessionId unreadCount:recentSession.unreadCount]; return; } if (recentSession.session.sessionId.integerValue > 0) { [self.recentSessions addObject:recentSession]; } [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; }]; [self.sessionListView reloadData]; [self setTabBarItemBadge:totalUnreadCount]; } - (void)didUpdateRecentSession:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount { if(self.openType != SessionListOpenTypeRoom && [[ClientConfig shareConfig].configInfo.officialMsgUids containsObject:recentSession.session.sessionId]) { [self.headView updateBadgeWithSessionId:recentSession.session.sessionId unreadCount:recentSession.unreadCount]; return; } for (NIMRecentSession *recent in self.recentSessions) { if ([recentSession.session.sessionId isEqualToString:recent.session.sessionId]) { [self.recentSessions removeObject:recent]; break; } } NSInteger insert = [self findInsertPlace:recentSession]; if (recentSession.session.sessionId.integerValue > 0) { [self.recentSessions insertObject:recentSession atIndex:insert]; } [self.sessionListView reloadData]; [self setTabBarItemBadge:totalUnreadCount]; } - (void)didRemoveRecentSession:(NIMRecentSession *)recentSession totalUnreadCount:(NSInteger)totalUnreadCount { // 清理本地数据 NSUInteger index = [self.recentSessions indexOfObject:recentSession]; if (index < self.recentSessions.count) { [self.recentSessions removeObjectAtIndex:index]; } // 如果删除本地会话后就不允许漫游当前会话,则需要进行一次删除服务器会话的操作 BOOL deleteRemote = NO; if (deleteRemote) { [[NIMSDK sharedSDK].conversationManager deleteRemoteSessions:@[recentSession.session] completion:nil]; } [self.sessionListView reloadData]; [self setTabBarItemBadge:totalUnreadCount]; } #pragma mark - NIMLoginManagerDelegate - (void)onLogin:(NIMLoginStep)step { if (step == NIMLoginStepSyncOK) { [self initDatas]; } } #pragma mark - JXCategoryListContentViewDelegate - (UIView *)listView { return self.view; } #pragma mark - XPSessionListHeadViewDelegate ///点击官方公告 - (void)XPSessionListHeadViewDidClickOffice { NSString *uid = [[ClientConfig shareConfig].configInfo.officialMsgUids safeObjectAtIndex1:0]; SessionViewController *sessionVC = [[SessionViewController alloc] initWithSession:[NIMSession session:uid type:NIMSessionTypeP2P]]; sessionVC.openType = self.openType; [self.navigationController pushViewController:sessionVC animated:YES]; } ///点击活动通知 - (void)XPSessionListHeadViewDidClickActivity { NSString *uid = [[ClientConfig shareConfig].configInfo.officialMsgUids safeObjectAtIndex1:1]; SessionViewController *sessionVC = [[SessionViewController alloc] initWithSession:[NIMSession session:uid type:NIMSessionTypeP2P]]; sessionVC.openType = self.openType; [self.navigationController pushViewController:sessionVC animated:YES]; } ///点击订阅提醒 - (void)XPSessionListHeadViewDidClickSubscribe { NSString *uid = [[ClientConfig shareConfig].configInfo.officialMsgUids safeObjectAtIndex1:2]; SessionViewController *sessionVC = [[SessionViewController alloc] initWithSession:[NIMSession session:uid type:NIMSessionTypeP2P]]; sessionVC.openType = self.openType; [self.navigationController pushViewController:sessionVC animated:YES]; } ///点击发现萌新 - (void)XPSessionListHeadViewDidClickMengxin { XPSessionFindNewViewController * findNewVC = [[XPSessionFindNewViewController alloc] init]; [self.navigationController pushViewController:findNewVC animated:YES]; } #pragma mark - Private - (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)setTabBarItemBadge:(NSInteger)value { if (self.parentMode) { [self.tabBarItem setBadgeValue:0]; return; } if (value > 0) { [self.tabBarController.tabBar.items[3] setBadgeValue:[NSString stringWithFormat:@"%ld", value]]; } else { [self.tabBarController.tabBar.items[3] setBadgeValue:nil]; } } #pragma mark - action - (void)allRead { NSInteger count = [NIMSDK sharedSDK].conversationManager.allUnreadCount; if (count<1) { [self showErrorToast:@"暂无未读消息需要清理"]; return; } TTAlertConfig * config = [[TTAlertConfig alloc] init]; config.confirmButtonConfig.title = @"清除"; config.message =@"清除当前未读消息提醒?"; [TTPopup alertWithConfig:config confirmHandler:^{ NSMutableArray *array = [NSMutableArray array]; [self.recentSessions enumerateObjectsUsingBlock:^(NIMRecentSession * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { [array addObject:obj.session]; }]; [[NIMSDK sharedSDK].conversationManager batchMarkMessagesReadInSessions:array]; [self setTabBarItemBadge:0]; [self.sessionListView reloadData]; } cancelHandler:^{ }]; } - (UITableView *)sessionListView { if (!_sessionListView) { _sessionListView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; _sessionListView.separatorStyle = UITableViewCellSeparatorStyleNone; _sessionListView.backgroundColor = UIColor.clearColor; _sessionListView.delegate = self; _sessionListView.dataSource = self; _sessionListView.showsVerticalScrollIndicator = NO; } return _sessionListView; } - (NSMutableArray *)recentSessions { if (!_recentSessions) { _recentSessions = [NSMutableArray array]; } return _recentSessions; } - (XPTeenagerHomeView *)teenagerView { if (!_teenagerView) { _teenagerView = [[XPTeenagerHomeView alloc] init]; } return _teenagerView; } - (XPSessionListHeadView *)headView { if (!_headView) { _headView = [[XPSessionListHeadView alloc] init]; _headView.delegate = self; } return _headView; } @end