|
@@ -0,0 +1,278 @@
|
|
|
+//
|
|
|
+// ChatBlackListBodyView.m
|
|
|
+// KulexiuForTeacher
|
|
|
+//
|
|
|
+// Created by 王智 on 2025/4/7.
|
|
|
+//
|
|
|
+
|
|
|
+#import "ChatBlackListBodyView.h"
|
|
|
+#import "StateView.h"
|
|
|
+#import "Reachability.h"
|
|
|
+#import "ContractListCell.h"
|
|
|
+#import "FriendListModel.h"
|
|
|
+#import "KSChatListSearchView.h"
|
|
|
+#import <ImSDK_Plus/ImSDK_Plus.h>
|
|
|
+#import "KSTipsAlert.h"
|
|
|
+
|
|
|
+@interface ChatBlackListBodyView ()<UITableViewDelegate,UITableViewDataSource>
|
|
|
+
|
|
|
+@property (nonatomic, strong) StateView *promptView;
|
|
|
+@property (nonatomic, strong) UIView *promptPlaceView;
|
|
|
+
|
|
|
+@property (nonatomic, assign) BOOL networkAvaiable; // 网络是否可用
|
|
|
+
|
|
|
+@property (nonatomic, strong) NSMutableArray *blackListArray;
|
|
|
+
|
|
|
+@property (nonatomic, strong) KSChatListSearchView *searchView;
|
|
|
+
|
|
|
+@property (nonatomic, strong) KSTipsAlert *alertView;
|
|
|
+
|
|
|
+@end
|
|
|
+
|
|
|
+@implementation ChatBlackListBodyView
|
|
|
+
|
|
|
+- (instancetype)initWithFrame:(CGRect)frame {
|
|
|
+ self = [super initWithFrame:frame];
|
|
|
+ if (self) {
|
|
|
+ self.backgroundColor = HexRGB(0xf8f9fc);
|
|
|
+ self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
|
|
|
+ self.tableView.backgroundColor = HexRGB(0xf8f9fc);
|
|
|
+ self.tableView.showsVerticalScrollIndicator = NO;
|
|
|
+
|
|
|
+ self.tableView.dataSource = self;
|
|
|
+ self.tableView.delegate = self;
|
|
|
+ self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
|
|
+ self.tableView.rowHeight = 70;
|
|
|
+ [self addSubview:self.tableView];
|
|
|
+
|
|
|
+ [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
+ make.left.right.top.bottom.mas_equalTo(self);
|
|
|
+ }];
|
|
|
+
|
|
|
+ UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 10)];
|
|
|
+ bottomView.backgroundColor = HexRGB(0xf8f9fc);
|
|
|
+ self.tableView.tableFooterView = bottomView;
|
|
|
+
|
|
|
+ [self.tableView registerNib:[UINib nibWithNibName:@"ContractListCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"ContractListCell"];
|
|
|
+ MJWeakSelf;
|
|
|
+ self.tableView.mj_header = [KSGifRefreshHeader headerWithRefreshingBlock:^{
|
|
|
+ [weakSelf resetParamenter];
|
|
|
+ [weakSelf requestData];
|
|
|
+ }];
|
|
|
+ }
|
|
|
+ return self;
|
|
|
+}
|
|
|
+
|
|
|
+- (void)endRefresh {
|
|
|
+ [self.tableView.mj_header endRefreshing];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)refreshAndRequestData {
|
|
|
+ [self resetParamenter];
|
|
|
+ [self requestData];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)resetParamenter {
|
|
|
+ [self setPromptString:@"暂无黑名单" imageName:CLIENT_EMPTY_IMG inView:self.tableView];
|
|
|
+ [self.blackListArray removeAllObjects];
|
|
|
+ [self.tableView reloadData];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)beginRefreshImmediately {
|
|
|
+ [self.tableView.mj_header beginRefreshing];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)selectCellAtIndexPath:(NSIndexPath *)indexPath {
|
|
|
+
|
|
|
+ if (self.lastSelectedIndexPath == indexPath) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (self.lastSelectedIndexPath != nil) {
|
|
|
+ UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.lastSelectedIndexPath];
|
|
|
+ [cell setSelected:NO animated:NO];
|
|
|
+ }
|
|
|
+ UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
|
|
|
+ [cell setSelected:YES animated:NO];
|
|
|
+ self.lastSelectedIndexPath = indexPath;
|
|
|
+}
|
|
|
+
|
|
|
+- (void)layoutSubviews {
|
|
|
+ [super layoutSubviews];
|
|
|
+ CGFloat height = [self.searchView getViewHeight];
|
|
|
+ if (![self.subviews containsObject:self.searchView]) {
|
|
|
+ [self addSubview:self.searchView];
|
|
|
+ self.searchView.frame = CGRectMake(0, 0, self.bounds.size.width, height);
|
|
|
+ }
|
|
|
+
|
|
|
+ [self.searchView configText:@"请输入用户名称"];
|
|
|
+ [self.tableView mas_updateConstraints:^(MASConstraintMaker *make) {
|
|
|
+ make.top.mas_equalTo(self).mas_offset(height);
|
|
|
+ }];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)beginFirstRefresh {
|
|
|
+ if (!self.isHeaderRefreshed) {
|
|
|
+ [self beginRefreshImmediately];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+- (void)requestData {
|
|
|
+ [[V2TIMManager sharedInstance] getBlackList:^(NSArray<V2TIMFriendInfo *> *infoList) {
|
|
|
+ [self endRefresh];
|
|
|
+ for (V2TIMFriendInfo *info in infoList) {
|
|
|
+ FriendListModel *model = [[FriendListModel alloc] init];
|
|
|
+ model.friendAvatar = info.userFullInfo.faceURL;
|
|
|
+ model.friendNickname = info.userFullInfo.nickName;
|
|
|
+ model.imFriendId = info.userID;
|
|
|
+ if ([info.userID hasSuffix:@"TEACHER"]) {
|
|
|
+ model.roleType = @"TEACHER";
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ model.roleType = @"STUDENT";
|
|
|
+ }
|
|
|
+ [self.blackListArray addObject:model];
|
|
|
+ }
|
|
|
+ [self changePromptLabelStateWithArray:self.blackListArray];
|
|
|
+ [self.tableView reloadData];
|
|
|
+
|
|
|
+ } fail:^(int code, NSString *desc) {
|
|
|
+ [self endRefresh];
|
|
|
+ if (self.networkAvaiable == NO) {
|
|
|
+ [self setPromptString:@"暂无网络" imageName:CLIENT_NONETWORKING_IMG inView:self.tableView];
|
|
|
+ }
|
|
|
+ [self.blackListArray removeAllObjects];
|
|
|
+ [self.tableView reloadData];
|
|
|
+ [self changePromptLabelStateWithArray:self.blackListArray];
|
|
|
+ }];
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#pragma mark - UITableViewDataSource, UITableViewDelegate
|
|
|
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
|
|
+ return self.blackListArray.count;
|
|
|
+}
|
|
|
+
|
|
|
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
|
|
+ ContractListCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ContractListCell"];
|
|
|
+ FriendListModel *model = self.blackListArray[indexPath.row];
|
|
|
+ MJWeakSelf;
|
|
|
+ [cell configBlackListWithSource:model callback:^(NSString * _Nonnull imUserId, NSString * _Nullable nickName) {
|
|
|
+ [weakSelf removeBlackList:imUserId nickName:nickName];
|
|
|
+ }];
|
|
|
+
|
|
|
+ return cell;
|
|
|
+}
|
|
|
+
|
|
|
+- (void)removeBlackList:(NSString *)imUserId nickName:(NSString *)nickName {
|
|
|
+ MJWeakSelf;
|
|
|
+ NSString *tipsString = [NSString stringWithFormat:@"将%@移除黑名单后,对方可向您发送消息。", nickName];
|
|
|
+ self.alertView = [KSTipsAlert shareInstanceWithTitle:@"移除黑名单" descMessage:tipsString leftTitle:@"取消" rightTitle:@"确认" callback:^(BOOL isSure) {
|
|
|
+ if (isSure) {
|
|
|
+ [weakSelf removeChatPersonFromBlackList:imUserId];
|
|
|
+ }
|
|
|
+ }];
|
|
|
+}
|
|
|
+
|
|
|
+- (void)removeChatPersonFromBlackList:(NSString *)imUserId {
|
|
|
+ [[V2TIMManager sharedInstance] deleteFromBlackList:@[imUserId] succ:^(NSArray<V2TIMFriendOperationResult *> *resultList) {
|
|
|
+ [self refreshAndRequestData];
|
|
|
+ } fail:^(int code, NSString *desc) {
|
|
|
+ // 如果错误 不修改
|
|
|
+ }];
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ 设置没有数据时的显示
|
|
|
+
|
|
|
+ @param promptString 提示语
|
|
|
+ @param imgName 图片名称
|
|
|
+ @param view 显示在什么地方
|
|
|
+ */
|
|
|
+- (void)setPromptString:(NSString *)promptString imageName:(NSString *)imgName inView:(UIView *)view {
|
|
|
+ if (self.promptView != nil) {
|
|
|
+ [self.promptView removeFromSuperview];
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ self.promptView = [[StateView alloc]init];
|
|
|
+ self.promptView.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight - 300);
|
|
|
+ }
|
|
|
+ _promptPlaceView = view;
|
|
|
+ //当请求不到数据时 ,自定义提示view 将会出现;
|
|
|
+ self.promptView.imageName = imgName;
|
|
|
+ self.promptView.alpha = 0.0f;
|
|
|
+ [self.promptView setText:promptString];
|
|
|
+ [view addSubview:self.promptView];
|
|
|
+}
|
|
|
+
|
|
|
+// 结束刷新后调用方法
|
|
|
+- (void)changePromptLabelStateWithArray:(NSMutableArray *)array {
|
|
|
+ NSInteger count;
|
|
|
+ if (array.count) {
|
|
|
+ count = array.count;
|
|
|
+ } else {
|
|
|
+ count = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ [UIView animateWithDuration:0.1 animations:^{
|
|
|
+ [[self promptView] setAlpha:count ? 0.0f :1.0f ] ;
|
|
|
+
|
|
|
+ }] ;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+- (BOOL)networkAvaiable {
|
|
|
+ return [self checkNetworkAvaiable];
|
|
|
+}
|
|
|
+
|
|
|
+- (BOOL)checkNetworkAvaiable {
|
|
|
+ BOOL isExistenceNetwork = YES;
|
|
|
+ Reachability *reach = [Reachability reachabilityWithHostName:@"www.apple.com"];
|
|
|
+ switch ([reach currentReachabilityStatus]) {
|
|
|
+ case NotReachable:
|
|
|
+ isExistenceNetwork = NO;
|
|
|
+ //NSLog(@"notReachable");
|
|
|
+ break;
|
|
|
+ case ReachableViaWiFi:
|
|
|
+ isExistenceNetwork = YES;
|
|
|
+ //NSLog(@"WIFI");
|
|
|
+ break;
|
|
|
+ case ReachableViaWWAN:
|
|
|
+ isExistenceNetwork = YES;
|
|
|
+ //NSLog(@"3G");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return isExistenceNetwork;
|
|
|
+}
|
|
|
+#pragma mark --- lazying
|
|
|
+- (NSMutableArray *)blackListArray {
|
|
|
+ if (!_blackListArray) {
|
|
|
+ _blackListArray = [NSMutableArray array];
|
|
|
+ }
|
|
|
+ return _blackListArray;
|
|
|
+}
|
|
|
+
|
|
|
+- (KSChatListSearchView *)searchView {
|
|
|
+ if (!_searchView) {
|
|
|
+ _searchView = [KSChatListSearchView shareInstance];
|
|
|
+ MJWeakSelf;
|
|
|
+ [_searchView topSearchCallback:^{
|
|
|
+ [weakSelf searchAction];
|
|
|
+ }];
|
|
|
+ }
|
|
|
+ return _searchView;
|
|
|
+}
|
|
|
+
|
|
|
+- (void)searchAction {
|
|
|
+ self.searchKey = self.searchView.searchField.text;
|
|
|
+ [self refreshAndRequestData];
|
|
|
+}
|
|
|
+/*
|
|
|
+// Only override drawRect: if you perform custom drawing.
|
|
|
+// An empty implementation adversely affects performance during animation.
|
|
|
+- (void)drawRect:(CGRect)rect {
|
|
|
+ // Drawing code
|
|
|
+}
|
|
|
+*/
|
|
|
+
|
|
|
+@end
|