首次提交
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
|
||||
// Created by Tencent on 2023/06/09.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
/**
|
||||
|
||||
* This file declares the view model used to implement the blocklist page.
|
||||
* The view model is responsible for some data processing and business logic in the interface, such as pulling blacklist information and loading blocklist
|
||||
* data.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TUICommonContactCell.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* 【Module name】 TUIBlackListViewModel
|
||||
* 【Function description】It is responsible for pulling the user's blocklist information and displaying it on the page.
|
||||
* The view model is also responsible for loading the pulled information to facilitate data processing in the client.
|
||||
*/
|
||||
@interface TUIBlackListViewDataProvider : NSObject
|
||||
|
||||
/**
|
||||
* Bocklist data
|
||||
* The blocklist stores the detailed information of the blocked users.
|
||||
* Include details such as user avatar (URL and image), user ID, user nickname, etc. Used to display detailed information when you click to a detailed meeting.
|
||||
*/
|
||||
@property(readonly) NSArray<TUICommonContactCellData *> *blackListData;
|
||||
|
||||
@property(readonly) BOOL isLoadFinished;
|
||||
|
||||
- (void)loadBlackList;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// TUIBlackListViewModel.m
|
||||
// TXIMSDK_TUIKit_iOS
|
||||
//
|
||||
// Created by annidyfeng on 2019/5/5.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIBlackListViewDataProvider.h"
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
|
||||
@interface TUIBlackListViewDataProvider ()
|
||||
@property NSArray<TUICommonContactCellData *> *blackListData;
|
||||
@property BOOL isLoadFinished;
|
||||
@property BOOL isLoading;
|
||||
@end
|
||||
|
||||
@implementation TUIBlackListViewDataProvider
|
||||
|
||||
- (void)loadBlackList {
|
||||
if (self.isLoading) return;
|
||||
self.isLoading = YES;
|
||||
self.isLoadFinished = NO;
|
||||
@weakify(self);
|
||||
[[V2TIMManager sharedInstance]
|
||||
getBlackList:^(NSArray<V2TIMFriendInfo *> *infoList) {
|
||||
@strongify(self);
|
||||
NSMutableArray *list = @[].mutableCopy;
|
||||
for (V2TIMFriendInfo *fd in infoList) {
|
||||
TUICommonContactCellData *data = [[TUICommonContactCellData alloc] initWithFriend:fd];
|
||||
[list addObject:data];
|
||||
}
|
||||
self.blackListData = list;
|
||||
self.isLoadFinished = YES;
|
||||
self.isLoading = NO;
|
||||
}
|
||||
fail:^(int code, NSString *msg) {
|
||||
self.isLoading = NO;
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
// Created by Tencent on 2023/06/09.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
/**
|
||||
|
||||
* This file declares the view model for the friend selection interface
|
||||
* The view model is responsible for pulling friend data through the IM SDK interface and loading the data.
|
||||
*/
|
||||
#import <Foundation/Foundation.h>
|
||||
@class TUICommonContactSelectCellData;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef BOOL (^ContactSelectFilterBlock)(TUICommonContactSelectCellData *data);
|
||||
|
||||
/**
|
||||
* 【Module name】Friend selection interface view model (TContactSelectViewModel)
|
||||
* 【Function description】Implement the friend selection interface view model.
|
||||
* This view model is responsible for pulling friend lists, friend requests and loading related data from the server.
|
||||
* At the same time, this view model will also group friends according to the initials of their nicknames, which helps the view maintain an "alphabet" on the
|
||||
* right side of the interface to quickly retrieve friends.
|
||||
*/
|
||||
@interface TUIContactSelectViewDataProvider : NSObject
|
||||
|
||||
/**
|
||||
* Data dictionary, responsible for classifying friend information (TCommonContactCellData) by initials.
|
||||
* For example, Jack and James are stored in "J".
|
||||
*/
|
||||
@property(readonly) NSDictionary<NSString *, NSArray<TUICommonContactSelectCellData *> *> *dataDict;
|
||||
|
||||
/**
|
||||
* The group list, that is, the group information of the current friend.
|
||||
* For example, if the current user has only one friend "Jack", there is only one element "J" in this list.
|
||||
* The grouping information is up to 26 letters from A - Z and "#".
|
||||
*/
|
||||
@property(readonly) NSArray *groupList;
|
||||
|
||||
/**
|
||||
* An identifier indicating whether the current loading process is complete
|
||||
* YES: Loading is done; NO: Loading
|
||||
* With this identifier, we can avoid reloading the data.
|
||||
*/
|
||||
@property(readonly) BOOL isLoadFinished;
|
||||
|
||||
/**
|
||||
*
|
||||
* Filter to disable contacts
|
||||
*/
|
||||
@property(copy) ContactSelectFilterBlock disableFilter;
|
||||
|
||||
/**
|
||||
*
|
||||
* Filter to display contacts
|
||||
*/
|
||||
@property(copy) ContactSelectFilterBlock avaliableFilter;
|
||||
|
||||
- (void)loadContacts;
|
||||
|
||||
- (void)setSourceIds:(NSArray<NSString *> *)ids;
|
||||
- (void)setSourceIds:(NSArray<NSString *> *)ids displayNames:(NSDictionary *__nullable)displayNames;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// TContactSelectViewModel.m
|
||||
// TXIMSDK_TUIKit_iOS
|
||||
//
|
||||
// Created by annidyfeng on 2019/5/8.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIContactSelectViewDataProvider.h"
|
||||
#import <TIMCommon/TIMCommonModel.h>
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
#import <TUICore/NSString+TUIUtil.h>
|
||||
|
||||
@interface TUIContactSelectViewDataProvider ()
|
||||
@property NSDictionary<NSString *, NSArray<TUICommonContactSelectCellData *> *> *dataDict;
|
||||
@property NSArray *groupList;
|
||||
@property BOOL isLoadFinished;
|
||||
@end
|
||||
|
||||
@implementation TUIContactSelectViewDataProvider
|
||||
|
||||
- (void)loadContacts {
|
||||
self.isLoadFinished = NO;
|
||||
|
||||
@weakify(self);
|
||||
[[V2TIMManager sharedInstance]
|
||||
getFriendList:^(NSArray<V2TIMFriendInfo *> *infoList) {
|
||||
@strongify(self);
|
||||
NSMutableArray *arr = [NSMutableArray new];
|
||||
for (V2TIMFriendInfo *fr in infoList) {
|
||||
[arr addObject:fr.userFullInfo];
|
||||
}
|
||||
[self fillList:arr displayNames:nil];
|
||||
}
|
||||
fail:nil];
|
||||
}
|
||||
|
||||
- (void)setSourceIds:(NSArray<NSString *> *)ids {
|
||||
[self setSourceIds:ids displayNames:nil];
|
||||
}
|
||||
|
||||
- (void)setSourceIds:(NSArray<NSString *> *)ids displayNames:(NSDictionary *__nullable)displayNames {
|
||||
[[V2TIMManager sharedInstance] getUsersInfo:ids
|
||||
succ:^(NSArray<V2TIMUserFullInfo *> *infoList) {
|
||||
[self fillList:infoList displayNames:displayNames];
|
||||
}
|
||||
fail:nil];
|
||||
}
|
||||
|
||||
- (void)fillList:(NSArray<V2TIMUserFullInfo *> *)profiles displayNames:(NSDictionary *__nullable)displayNames {
|
||||
NSMutableDictionary *dataDict = @{}.mutableCopy;
|
||||
NSMutableArray *groupList = @[].mutableCopy;
|
||||
NSMutableArray *nonameList = @[].mutableCopy;
|
||||
|
||||
for (V2TIMUserFullInfo *profile in profiles) {
|
||||
TUICommonContactSelectCellData *data = [[TUICommonContactSelectCellData alloc] init];
|
||||
NSString *showName = @"";
|
||||
if (displayNames && [displayNames.allKeys containsObject:profile.userID]) {
|
||||
showName = [displayNames objectForKey:profile.userID];
|
||||
}
|
||||
if (showName.length == 0) {
|
||||
showName = profile.showName;
|
||||
}
|
||||
data.title = showName;
|
||||
if (profile.faceURL.length) {
|
||||
data.avatarUrl = [NSURL URLWithString:profile.faceURL];
|
||||
}
|
||||
data.identifier = profile.userID;
|
||||
|
||||
if (self.avaliableFilter && !self.avaliableFilter(data)) {
|
||||
continue;
|
||||
}
|
||||
if (self.disableFilter) {
|
||||
data.enabled = !self.disableFilter(data);
|
||||
}
|
||||
|
||||
NSString *group = [[data.title firstPinYin] uppercaseString];
|
||||
if (group.length == 0 || !isalpha([group characterAtIndex:0])) {
|
||||
[nonameList addObject:data];
|
||||
continue;
|
||||
}
|
||||
NSMutableArray *list = [dataDict objectForKey:group];
|
||||
if (!list) {
|
||||
list = @[].mutableCopy;
|
||||
dataDict[group] = list;
|
||||
[groupList addObject:group];
|
||||
}
|
||||
[list addObject:data];
|
||||
}
|
||||
|
||||
[groupList sortUsingSelector:@selector(localizedStandardCompare:)];
|
||||
if (nonameList.count) {
|
||||
[groupList addObject:@"#"];
|
||||
dataDict[@"#"] = nonameList;
|
||||
}
|
||||
for (NSMutableArray *list in [self.dataDict allValues]) {
|
||||
[list sortUsingSelector:@selector(compare:)];
|
||||
}
|
||||
|
||||
self.groupList = groupList;
|
||||
self.dataDict = dataDict;
|
||||
self.isLoadFinished = YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,59 @@
|
||||
|
||||
// Created by Tencent on 2023/06/09.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
/**
|
||||
* This file declares the view model for the Contacts interface.
|
||||
* The view model is responsible for pulling friend lists, friend requests from the server and loading related data.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TUICommonContactCell.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* 【Module name】Message List View Model (TContactViewModel)
|
||||
* 【Function description】A view model that implements a message list.
|
||||
* 1. This view model is responsible for pulling friend lists, friend requests and loading related data from the server.
|
||||
* 2. At the same time, this view model will also group friends by the first latter of their nicknames, which helps the view maintain an "alphabet" on the
|
||||
* right side of the interface to facilitate quick retrieval of friends.
|
||||
*/
|
||||
@interface TUIContactViewDataProvider : NSObject
|
||||
|
||||
/**
|
||||
* Data dictionary, responsible for classifying friend information (TCommonContactCellData) by initials.
|
||||
* For example, Jack and James are stored in "J".
|
||||
*/
|
||||
@property(readonly) NSDictionary<NSString *, NSArray<TUICommonContactCellData *> *> *dataDict;
|
||||
|
||||
/**
|
||||
* The group list, that is, the group information of the current friend.
|
||||
* For example, if the current user has only one friend "Jack", there is only one element "J" in this list.
|
||||
* The grouping information is up to 26 letters from A - Z and "#".
|
||||
*/
|
||||
@property(readonly) NSArray *groupList;
|
||||
|
||||
/**
|
||||
* An identifier indicating whether the current loading process is complete
|
||||
* YES: Loading is done; NO: Loading
|
||||
* With this identifier, we can avoid reloading the data.
|
||||
*/
|
||||
@property(readonly) BOOL isLoadFinished;
|
||||
|
||||
/**
|
||||
* Count of pending friend requests
|
||||
*/
|
||||
@property(readonly) NSUInteger pendencyCnt;
|
||||
|
||||
@property(readonly) NSDictionary *contactMap;
|
||||
|
||||
|
||||
- (void)loadContacts;
|
||||
|
||||
- (void)loadFriendApplication;
|
||||
|
||||
- (void)clearApplicationCnt;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
254
TUIKit/TUIContact/BaseDataProvider/TUIContactViewDataProvider.m
Normal file
254
TUIKit/TUIContact/BaseDataProvider/TUIContactViewDataProvider.m
Normal file
@@ -0,0 +1,254 @@
|
||||
//
|
||||
// TContactViewModel.m
|
||||
// TXIMSDK_TUIKit_iOS
|
||||
//
|
||||
// Created by annidyfeng on 2019/5/5.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIContactViewDataProvider.h"
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
#import <TUICore/NSString+TUIUtil.h>
|
||||
|
||||
#define kGetUserStatusPageCount 500
|
||||
|
||||
@interface TUIContactViewDataProvider () <V2TIMFriendshipListener, V2TIMSDKListener>
|
||||
@property NSDictionary<NSString *, NSArray<TUICommonContactCellData *> *> *dataDict;
|
||||
@property NSArray *groupList;
|
||||
@property BOOL isLoadFinished;
|
||||
@property NSUInteger pendencyCnt;
|
||||
|
||||
@property(nonatomic, strong) NSDictionary *contactMap;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TUIContactViewDataProvider
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
[[V2TIMManager sharedInstance] addFriendListener:self];
|
||||
[[V2TIMManager sharedInstance] addIMSDKListener:self];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)loadContacts {
|
||||
self.isLoadFinished = NO;
|
||||
@weakify(self);
|
||||
[[V2TIMManager sharedInstance]
|
||||
getFriendList:^(NSArray<V2TIMFriendInfo *> *infoList) {
|
||||
@strongify(self);
|
||||
NSMutableDictionary *dataDict = @{}.mutableCopy;
|
||||
NSMutableArray *groupList = @[].mutableCopy;
|
||||
NSMutableArray *nonameList = @[].mutableCopy;
|
||||
|
||||
NSMutableDictionary *contactMap = [NSMutableDictionary dictionary];
|
||||
NSMutableArray *userIDList = [NSMutableArray array];
|
||||
|
||||
for (V2TIMFriendInfo *friend in infoList) {
|
||||
TUICommonContactCellData *data = [[TUICommonContactCellData alloc] initWithFriend:friend];
|
||||
// for online status
|
||||
data.onlineStatus = TUIContactOnlineStatusUnknown;
|
||||
if (data.identifier) {
|
||||
[contactMap setObject:data forKey:data.identifier];
|
||||
[userIDList addObject:data.identifier];
|
||||
}
|
||||
|
||||
NSString *group = [[data.title firstPinYin] uppercaseString];
|
||||
if (group.length == 0 || !isalpha([group characterAtIndex:0])) {
|
||||
[nonameList addObject:data];
|
||||
continue;
|
||||
}
|
||||
NSMutableArray *list = [dataDict objectForKey:group];
|
||||
if (!list) {
|
||||
list = @[].mutableCopy;
|
||||
dataDict[group] = list;
|
||||
[groupList addObject:group];
|
||||
}
|
||||
[list addObject:data];
|
||||
}
|
||||
|
||||
[groupList sortUsingSelector:@selector(localizedStandardCompare:)];
|
||||
if (nonameList.count) {
|
||||
[groupList addObject:@"#"];
|
||||
dataDict[@"#"] = nonameList;
|
||||
}
|
||||
for (NSMutableArray *list in [dataDict allValues]) {
|
||||
[list sortUsingSelector:@selector(compare:)];
|
||||
}
|
||||
self.groupList = groupList;
|
||||
self.dataDict = dataDict;
|
||||
self.contactMap = [NSDictionary dictionaryWithDictionary:contactMap];
|
||||
self.isLoadFinished = YES;
|
||||
|
||||
// refresh online status async
|
||||
[self asyncGetOnlineStatus:userIDList];
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
NSLog(@"getFriendList failed, code:%d desc:%@", code, desc);
|
||||
}];
|
||||
|
||||
[self loadFriendApplication];
|
||||
}
|
||||
|
||||
- (void)loadFriendApplication {
|
||||
@weakify(self);
|
||||
[[V2TIMManager sharedInstance]
|
||||
getFriendApplicationList:^(V2TIMFriendApplicationResult *result) {
|
||||
@strongify(self);
|
||||
self.pendencyCnt = result.unreadCount;
|
||||
}
|
||||
fail:nil];
|
||||
}
|
||||
|
||||
- (void)asyncGetOnlineStatus:(NSArray *)userIDList {
|
||||
if (NSThread.isMainThread) {
|
||||
@weakify(self);
|
||||
dispatch_async(dispatch_get_global_queue(0, 0), ^{
|
||||
@strongify(self);
|
||||
[self asyncGetOnlineStatus:userIDList];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (userIDList.count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@weakify(self);
|
||||
void (^getUserStatus)(NSArray *userIDList) = ^(NSArray *userIDList) {
|
||||
@strongify(self);
|
||||
@weakify(self);
|
||||
[V2TIMManager.sharedInstance getUserStatus:userIDList
|
||||
succ:^(NSArray<V2TIMUserStatus *> *result) {
|
||||
@strongify(self);
|
||||
[self handleOnlineStatus:result];
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
#if DEBUG
|
||||
if (code == ERR_SDK_INTERFACE_NOT_SUPPORT && TUIConfig.defaultConfig.displayOnlineStatusIcon) {
|
||||
[TUITool makeToast:desc];
|
||||
}
|
||||
#endif
|
||||
}];
|
||||
};
|
||||
|
||||
NSInteger count = kGetUserStatusPageCount;
|
||||
if (userIDList.count > count) {
|
||||
NSArray *subUserIDList = [userIDList subarrayWithRange:NSMakeRange(0, count)];
|
||||
NSArray *pendingUserIDList = [userIDList subarrayWithRange:NSMakeRange(count, userIDList.count - count)];
|
||||
getUserStatus(subUserIDList);
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
@strongify(self);
|
||||
[self asyncGetOnlineStatus:pendingUserIDList];
|
||||
});
|
||||
} else {
|
||||
getUserStatus(userIDList);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)asyncUpdateOnlineStatus {
|
||||
if (NSThread.isMainThread) {
|
||||
@weakify(self);
|
||||
dispatch_async(dispatch_get_global_queue(0, 0), ^{
|
||||
@strongify(self);
|
||||
[self asyncUpdateOnlineStatus];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// reset
|
||||
NSMutableArray *userIDList = [NSMutableArray array];
|
||||
for (TUICommonContactCellData *contact in self.contactMap.allValues) {
|
||||
contact.onlineStatus = TUIContactOnlineStatusOffline;
|
||||
if (contact.identifier) {
|
||||
[userIDList addObject:contact.identifier];
|
||||
}
|
||||
}
|
||||
|
||||
// refresh table view on the main thread
|
||||
@weakify(self);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@strongify(self);
|
||||
self.isLoadFinished = YES;
|
||||
|
||||
// fetch
|
||||
[self asyncGetOnlineStatus:userIDList];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)handleOnlineStatus:(NSArray<V2TIMUserStatus *> *)userStatusList {
|
||||
NSInteger changed = 0;
|
||||
for (V2TIMUserStatus *userStatus in userStatusList) {
|
||||
if ([self.contactMap.allKeys containsObject:userStatus.userID]) {
|
||||
changed++;
|
||||
TUICommonContactCellData *contact = [self.contactMap objectForKey:userStatus.userID];
|
||||
contact.onlineStatus = (userStatus.statusType == V2TIM_USER_STATUS_ONLINE) ? TUIContactOnlineStatusOnline : TUIContactOnlineStatusOffline;
|
||||
}
|
||||
}
|
||||
if (changed == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// refresh table view on the main thread
|
||||
@weakify(self);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@strongify(self);
|
||||
self.isLoadFinished = YES;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)clearApplicationCnt {
|
||||
@weakify(self);
|
||||
[[V2TIMManager sharedInstance]
|
||||
setFriendApplicationRead:^{
|
||||
@strongify(self);
|
||||
(self).pendencyCnt = 0;
|
||||
}
|
||||
fail:nil];
|
||||
}
|
||||
|
||||
#pragma mark - V2TIMSDKListener
|
||||
- (void)onUserStatusChanged:(NSArray<V2TIMUserStatus *> *)userStatusList {
|
||||
[self handleOnlineStatus:userStatusList];
|
||||
}
|
||||
|
||||
- (void)onConnectFailed:(int)code err:(NSString *)err {
|
||||
NSLog(@"%s", __func__);
|
||||
}
|
||||
|
||||
- (void)onConnectSuccess {
|
||||
NSLog(@"%s", __func__);
|
||||
[self asyncUpdateOnlineStatus];
|
||||
}
|
||||
|
||||
#pragma mark - V2TIMFriendshipListener
|
||||
- (void)onFriendApplicationListAdded:(NSArray<V2TIMFriendApplication *> *)applicationList {
|
||||
[self loadFriendApplication];
|
||||
}
|
||||
|
||||
- (void)onFriendApplicationListDeleted:(NSArray *)userIDList {
|
||||
[self loadFriendApplication];
|
||||
}
|
||||
|
||||
- (void)onFriendApplicationListRead {
|
||||
[self loadFriendApplication];
|
||||
}
|
||||
|
||||
- (void)onFriendListAdded:(NSArray<V2TIMFriendInfo *> *)infoList {
|
||||
[self loadContacts];
|
||||
}
|
||||
|
||||
- (void)onFriendListDeleted:(NSArray *)userIDList {
|
||||
[self loadContacts];
|
||||
}
|
||||
|
||||
- (void)onFriendProfileChanged:(NSArray<V2TIMFriendInfo *> *)infoList {
|
||||
[self loadContacts];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// TUIFindContactViewDataProvider.h
|
||||
// TUIContact
|
||||
//
|
||||
// Created by harvy on 2021/12/13.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TUIFindContactCellModel.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TUIFindContactViewDataProvider : NSObject
|
||||
|
||||
@property(nonatomic, strong, readonly) NSArray<TUIFindContactCellModel *> *users;
|
||||
@property(nonatomic, strong, readonly) NSArray<TUIFindContactCellModel *> *groups;
|
||||
|
||||
- (void)findUser:(NSString *)userID completion:(dispatch_block_t)completion;
|
||||
- (void)findGroup:(NSString *)groupID completion:(dispatch_block_t)completion;
|
||||
|
||||
- (NSString *)getMyUserIDDescription;
|
||||
- (void)clear;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// TUIFindContactViewDataProvider.m
|
||||
// TUIContact
|
||||
//
|
||||
// Created by harvy on 2021/12/13.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIFindContactViewDataProvider.h"
|
||||
#import <ImSDK_Plus/ImSDK_Plus.h>
|
||||
#import <TUICore/TUIGlobalization.h>
|
||||
#import "TUIFindContactCellModel.h"
|
||||
|
||||
@interface TUIFindContactViewDataProvider ()
|
||||
@property(nonatomic, strong) NSArray<TUIFindContactCellModel *> *users;
|
||||
@property(nonatomic, strong) NSArray<TUIFindContactCellModel *> *groups;
|
||||
@end
|
||||
|
||||
@implementation TUIFindContactViewDataProvider
|
||||
|
||||
- (void)findUser:(NSString *)userID completion:(dispatch_block_t)completion {
|
||||
if (!completion) {
|
||||
return;
|
||||
}
|
||||
if (userID == nil) {
|
||||
self.users = @[];
|
||||
completion();
|
||||
return;
|
||||
}
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[[V2TIMManager sharedInstance] getUsersInfo:@[ userID ]
|
||||
succ:^(NSArray<V2TIMUserFullInfo *> *infoList) {
|
||||
V2TIMUserFullInfo *userInfo = infoList.firstObject;
|
||||
if (userInfo) {
|
||||
TUIFindContactCellModel *cellModel = [[TUIFindContactCellModel alloc] init];
|
||||
cellModel.avatarUrl = [NSURL URLWithString:userInfo.faceURL];
|
||||
cellModel.mainTitle = userInfo.nickName ?: userInfo.userID;
|
||||
cellModel.subTitle = [NSString stringWithFormat:@"ID: %@", userInfo.userID];
|
||||
cellModel.desc = @"";
|
||||
cellModel.type = TUIFindContactTypeC2C;
|
||||
cellModel.contactID = userInfo.userID;
|
||||
cellModel.userInfo = userInfo;
|
||||
weakSelf.users = @[ cellModel ];
|
||||
}
|
||||
completion();
|
||||
}
|
||||
fail:^(int code, NSString *msg) {
|
||||
weakSelf.users = @[];
|
||||
completion();
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)findGroup:(NSString *)groupID completion:(dispatch_block_t)completion {
|
||||
if (!completion) {
|
||||
return;
|
||||
}
|
||||
if (groupID == nil) {
|
||||
self.groups = @[];
|
||||
completion();
|
||||
return;
|
||||
}
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[[V2TIMManager sharedInstance] getGroupsInfo:@[ groupID ]
|
||||
succ:^(NSArray<V2TIMGroupInfoResult *> *groupResultList) {
|
||||
V2TIMGroupInfoResult *result = groupResultList.firstObject;
|
||||
if (result && result.resultCode == 0) {
|
||||
V2TIMGroupInfo *info = result.info;
|
||||
TUIFindContactCellModel *cellModel = [[TUIFindContactCellModel alloc] init];
|
||||
cellModel.avatarUrl = [NSURL URLWithString:info.faceURL];
|
||||
cellModel.mainTitle = info.groupName;
|
||||
cellModel.subTitle = [NSString stringWithFormat:@"ID: %@", info.groupID];
|
||||
cellModel.desc = [NSString stringWithFormat:@"%@: %@",TIMCommonLocalizableString(TUIKitGroupProfileType),info.groupType];
|
||||
cellModel.type = TUIFindContactTypeGroup;
|
||||
cellModel.contactID = info.groupID;
|
||||
cellModel.groupInfo = info;
|
||||
weakSelf.groups = @[ cellModel ];
|
||||
} else {
|
||||
weakSelf.groups = @[];
|
||||
}
|
||||
completion();
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
weakSelf.groups = @[];
|
||||
completion();
|
||||
}];
|
||||
}
|
||||
|
||||
- (NSString *)getMyUserIDDescription {
|
||||
NSString *loginUser = V2TIMManager.sharedInstance.getLoginUser;
|
||||
return [NSString stringWithFormat:TIMCommonLocalizableString(TUIKitAddContactMyUserIDFormat), loginUser];
|
||||
}
|
||||
|
||||
- (void)clear {
|
||||
self.users = @[];
|
||||
self.groups = @[];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
// Created by Tencent on 2023/06/09.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
/**
|
||||
|
||||
* This file declares the view model for the group list interface.
|
||||
* The view model is responsible for pulling and loading the group list data through the interface provided by the IM SDK, which is convenient for the page to
|
||||
* display the group list.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TUICommonContactCell.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
* 【Module name】Group List View Model (TUIGroupConversationListViewModel)
|
||||
* 【Function description】It is responsible for pulling the group information of the user and loading the obtained data.
|
||||
* The view model pulls the group information of the user through the interface provided by the IM SDK. The group information is classified and stored
|
||||
* according to the first latter of the name.
|
||||
*/
|
||||
@interface TUIGroupConversationListViewDataProvider : NSObject
|
||||
|
||||
@property(readonly) NSDictionary<NSString *, NSArray<TUICommonContactCellData *> *> *dataDict;
|
||||
|
||||
@property(readonly) NSArray *groupList;
|
||||
|
||||
@property(readonly) BOOL isLoadFinished;
|
||||
|
||||
- (void)loadConversation;
|
||||
|
||||
- (void)removeData:(TUICommonContactCellData *)data;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// TUIGroupConversationListModel.m
|
||||
// TXIMSDK_TUIKit_iOS
|
||||
//
|
||||
// Created by annidyfeng on 2019/6/11.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIGroupConversationListViewDataProvider.h"
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
#import <TUICore/NSString+TUIUtil.h>
|
||||
|
||||
@interface TUIGroupConversationListViewDataProvider ()
|
||||
@property BOOL isLoadFinished;
|
||||
@property BOOL isLoading;
|
||||
@property NSDictionary<NSString *, NSArray<TUICommonContactCellData *> *> *dataDict;
|
||||
@property NSArray *groupList;
|
||||
@end
|
||||
|
||||
@implementation TUIGroupConversationListViewDataProvider
|
||||
|
||||
- (void)loadConversation {
|
||||
if (self.isLoading) return;
|
||||
self.isLoading = NO;
|
||||
self.isLoadFinished = NO;
|
||||
|
||||
NSMutableDictionary *dataDict = @{}.mutableCopy;
|
||||
NSMutableArray *groupList = @[].mutableCopy;
|
||||
NSMutableArray *nonameList = @[].mutableCopy;
|
||||
|
||||
@weakify(self);
|
||||
[[V2TIMManager sharedInstance]
|
||||
getJoinedGroupList:^(NSArray<V2TIMGroupInfo *> *infoList) {
|
||||
@strongify(self);
|
||||
for (V2TIMGroupInfo *group in infoList) {
|
||||
TUICommonContactCellData *data = [[TUICommonContactCellData alloc] initWithGroupInfo:group];
|
||||
|
||||
NSString *group = [[data.title firstPinYin] uppercaseString];
|
||||
if (group.length == 0 || !isalpha([group characterAtIndex:0])) {
|
||||
[nonameList addObject:data];
|
||||
continue;
|
||||
}
|
||||
NSMutableArray *list = [dataDict objectForKey:group];
|
||||
if (!list) {
|
||||
list = @[].mutableCopy;
|
||||
dataDict[group] = list;
|
||||
[groupList addObject:group];
|
||||
}
|
||||
[list addObject:data];
|
||||
}
|
||||
|
||||
[groupList sortUsingSelector:@selector(localizedStandardCompare:)];
|
||||
if (nonameList.count) {
|
||||
[groupList addObject:@"#"];
|
||||
dataDict[@"#"] = nonameList;
|
||||
}
|
||||
for (NSMutableArray *list in [self.dataDict allValues]) {
|
||||
[list sortUsingSelector:@selector(compare:)];
|
||||
}
|
||||
|
||||
self.groupList = groupList;
|
||||
self.dataDict = dataDict;
|
||||
self.isLoadFinished = YES;
|
||||
}
|
||||
fail:nil];
|
||||
}
|
||||
|
||||
- (void)removeData:(TUICommonContactCellData *)data {
|
||||
NSMutableDictionary *dictDict = [NSMutableDictionary dictionaryWithDictionary:self.dataDict];
|
||||
for (NSString *key in self.dataDict) {
|
||||
NSMutableArray *list = [NSMutableArray arrayWithArray:self.dataDict[key]];
|
||||
if ([list containsObject:data]) {
|
||||
[list removeObject:data];
|
||||
dictDict[key] = list;
|
||||
break;
|
||||
}
|
||||
}
|
||||
self.dataDict = dictDict;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// TUIGroupManageDataProvider.h
|
||||
// TUIGroup
|
||||
//
|
||||
// Created by harvy on 2021/12/24.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@class TUIUserModel;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol TUIGroupManageDataProviderDelegate <NSObject>
|
||||
|
||||
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
|
||||
- (void)reloadData;
|
||||
- (void)showCoverViewWhenMuteAll:(BOOL)show;
|
||||
|
||||
- (void)insertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
|
||||
- (void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
|
||||
|
||||
- (void)onError:(int)code desc:(NSString *)desc operate:(NSString *)operate;
|
||||
|
||||
@end
|
||||
|
||||
@interface TUIGroupManageDataProvider : NSObject
|
||||
|
||||
@property(nonatomic, assign) BOOL muteAll;
|
||||
@property(nonatomic, copy) NSString *groupID;
|
||||
@property(nonatomic, assign) BOOL currentGroupTypeSupportSettingAdmin;
|
||||
@property(nonatomic, assign) BOOL currentGroupTypeSupportAddMemberOfBlocked;
|
||||
@property(nonatomic, weak) id<TUIGroupManageDataProviderDelegate> delegate;
|
||||
@property(nonatomic, strong, readonly) NSMutableArray *datas;
|
||||
|
||||
- (void)loadData;
|
||||
|
||||
- (void)mutedAll:(BOOL)mute completion:(void (^)(int, NSString *))completion;
|
||||
- (void)mute:(BOOL)mute user:(TUIUserModel *)user;
|
||||
|
||||
- (void)updateMuteMembersFilterAdmins;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
285
TUIKit/TUIContact/BaseDataProvider/TUIGroupManageDataProvider.m
Normal file
285
TUIKit/TUIContact/BaseDataProvider/TUIGroupManageDataProvider.m
Normal file
@@ -0,0 +1,285 @@
|
||||
//
|
||||
// TUIGroupManageDataProvider.m
|
||||
// TUIGroup
|
||||
//
|
||||
// Created by harvy on 2021/12/24.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIGroupManageDataProvider.h"
|
||||
#import <ImSDK_Plus/ImSDK_Plus.h>
|
||||
#import <TUICore/TUIGlobalization.h>
|
||||
#import "TUIMemberInfoCellData.h"
|
||||
#import "TUISelectGroupMemberCell.h"
|
||||
|
||||
@interface TUIGroupManageDataProvider ()
|
||||
|
||||
@property(nonatomic, strong) NSMutableArray *datas;
|
||||
|
||||
@property(nonatomic, strong) NSMutableArray *groupInfoDatasArray;
|
||||
@property(nonatomic, strong) NSMutableArray *muteMembersDataArray;
|
||||
|
||||
@property(nonatomic, strong) V2TIMGroupInfo *groupInfo;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TUIGroupManageDataProvider
|
||||
|
||||
- (void)mutedAll:(BOOL)mute completion:(void (^)(int, NSString *))completion {
|
||||
__weak typeof(self) weakSelf = self;
|
||||
V2TIMGroupInfo *groupInfo = [[V2TIMGroupInfo alloc] init];
|
||||
groupInfo.groupID = self.groupID;
|
||||
groupInfo.allMuted = mute;
|
||||
[V2TIMManager.sharedInstance setGroupInfo:groupInfo
|
||||
succ:^{
|
||||
weakSelf.muteAll = mute;
|
||||
weakSelf.groupInfo.allMuted = mute;
|
||||
[weakSelf setupGroupInfo:weakSelf.groupInfo];
|
||||
if (completion) {
|
||||
completion(0, nil);
|
||||
}
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
weakSelf.muteAll = !mute;
|
||||
if (completion) {
|
||||
completion(code, desc);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)mute:(BOOL)mute user:(TUIUserModel *)user {
|
||||
if (!NSThread.isMainThread) {
|
||||
@weakify(self);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@strongify(self);
|
||||
[self mute:mute user:user];
|
||||
});
|
||||
return;
|
||||
}
|
||||
__weak typeof(self) weakSelf = self;
|
||||
void (^callback)(int, NSString *, BOOL) = ^(int code, NSString *desc, BOOL mute) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
TUIMemberInfoCellData *existData = nil;
|
||||
for (TUIMemberInfoCellData *data in weakSelf.muteMembersDataArray) {
|
||||
if ([data.identifier isEqualToString:user.userId]) {
|
||||
existData = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (code == 0 && mute) {
|
||||
// mute succ
|
||||
if (!existData) {
|
||||
TUIMemberInfoCellData *cellData = [[TUIMemberInfoCellData alloc] init];
|
||||
cellData.identifier = user.userId;
|
||||
cellData.name = user.name ?: user.userId;
|
||||
cellData.avatarUrl = user.avatar;
|
||||
[weakSelf.muteMembersDataArray addObject:cellData];
|
||||
}
|
||||
} else if (code == 0 && !mute) {
|
||||
// unmute succ
|
||||
if (existData) {
|
||||
[weakSelf.muteMembersDataArray removeObject:existData];
|
||||
}
|
||||
} else {
|
||||
// fail
|
||||
if ([weakSelf.delegate respondsToSelector:@selector(onError:desc:operate:)]) {
|
||||
[weakSelf.delegate onError:code
|
||||
desc:desc
|
||||
operate:mute ?
|
||||
TIMCommonLocalizableString(TUIKitGroupShutupOption) :
|
||||
TIMCommonLocalizableString(TUIKitGroupDisShutupOption)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if ([weakSelf.delegate respondsToSelector:@selector(reloadData)]) {
|
||||
[weakSelf.delegate reloadData];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
[V2TIMManager.sharedInstance muteGroupMember:self.groupID
|
||||
member:user.userId
|
||||
muteTime:mute ? 365 * 24 * 3600 : 0
|
||||
succ:^{
|
||||
callback(0, nil, mute);
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
callback(code, desc, mute);
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)loadData {
|
||||
self.groupInfoDatasArray = [NSMutableArray array];
|
||||
self.muteMembersDataArray = [NSMutableArray array];
|
||||
self.datas = [NSMutableArray arrayWithArray:@[ self.groupInfoDatasArray, self.muteMembersDataArray ]];
|
||||
|
||||
@weakify(self);
|
||||
[V2TIMManager.sharedInstance getGroupsInfo:@[ self.groupID ?: @"" ]
|
||||
succ:^(NSArray<V2TIMGroupInfoResult *> *groupResultList) {
|
||||
@strongify(self);
|
||||
V2TIMGroupInfoResult *result = groupResultList.firstObject;
|
||||
if (result == nil || result.resultCode != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
V2TIMGroupInfo *groupInfo = result.info;
|
||||
self.groupInfo = groupInfo;
|
||||
[self setupGroupInfo:groupInfo];
|
||||
self.muteAll = groupInfo.allMuted;
|
||||
self.currentGroupTypeSupportSettingAdmin = [self canSupportSettingAdminAtThisGroupType:groupInfo.groupType];
|
||||
self.currentGroupTypeSupportAddMemberOfBlocked = [self canSupportAddMemberOfBlockedAtThisGroupType:groupInfo.groupType];
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
@strongify(self);
|
||||
[self setupGroupInfo:nil];
|
||||
}];
|
||||
|
||||
[self loadMuteMembers];
|
||||
}
|
||||
|
||||
- (void)loadMuteMembers {
|
||||
if (!NSThread.isMainThread) {
|
||||
@weakify(self);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@strongify(self);
|
||||
[self loadMuteMembers];
|
||||
});
|
||||
}
|
||||
|
||||
[self.muteMembersDataArray removeAllObjects];
|
||||
if ([self.delegate respondsToSelector:@selector(reloadData)]) {
|
||||
[self.delegate reloadData];
|
||||
}
|
||||
|
||||
TUIMemberInfoCellData *add = [[TUIMemberInfoCellData alloc] init];
|
||||
add.avatar = TUIContactCommonBundleImage(@"icon_add");
|
||||
add.name = TIMCommonLocalizableString(TUIKitGroupAddShutupMember);
|
||||
add.style = TUIMemberInfoCellStyleAdd;
|
||||
[self.muteMembersDataArray addObject:add];
|
||||
|
||||
if ([self.delegate respondsToSelector:@selector(insertRowsAtIndexPaths:withRowAnimation:)]) {
|
||||
[self.delegate insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:0 inSection:1] ] withRowAnimation:UITableViewRowAnimationNone];
|
||||
}
|
||||
|
||||
[self setupGroupMembers:0 first:YES];
|
||||
}
|
||||
|
||||
- (void)setupGroupMembers:(uint64_t)seq first:(uint64_t)first {
|
||||
if (seq == 0 && !first) {
|
||||
return;
|
||||
}
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[V2TIMManager.sharedInstance
|
||||
getGroupMemberList:self.groupID
|
||||
filter:V2TIM_GROUP_MEMBER_FILTER_ALL
|
||||
nextSeq:0
|
||||
succ:^(uint64_t nextSeq, NSArray<V2TIMGroupMemberFullInfo *> *memberList) {
|
||||
NSMutableArray *indexPaths = [NSMutableArray array];
|
||||
for (V2TIMGroupMemberFullInfo *info in memberList) {
|
||||
if (info.muteUntil && info.muteUntil > [NSDate.new timeIntervalSince1970]) {
|
||||
TUIMemberInfoCellData *member = [[TUIMemberInfoCellData alloc] init];
|
||||
member.avatarUrl = info.faceURL;
|
||||
member.name = (info.nameCard ?: info.nickName) ?: info.userID;
|
||||
member.identifier = info.userID;
|
||||
BOOL exist = NO;
|
||||
for (TUIMemberInfoCellData *data in weakSelf.muteMembersDataArray) {
|
||||
if ([data.identifier isEqualToString:info.userID]) {
|
||||
exist = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL isSuper = (info.role == V2TIM_GROUP_MEMBER_ROLE_SUPER);
|
||||
BOOL isAdMin = (info.role == V2TIM_GROUP_MEMBER_ROLE_ADMIN);
|
||||
BOOL allowShowInMuteList = YES;
|
||||
if (isSuper || isAdMin) {
|
||||
allowShowInMuteList = NO;
|
||||
}
|
||||
if (!exist && allowShowInMuteList) {
|
||||
[weakSelf.muteMembersDataArray addObject:member];
|
||||
[indexPaths addObject:[NSIndexPath indexPathForRow:[weakSelf.muteMembersDataArray indexOfObject:member] inSection:1]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (indexPaths.count) {
|
||||
if ([weakSelf.delegate respondsToSelector:@selector(insertRowsAtIndexPaths:withRowAnimation:)]) {
|
||||
[weakSelf.delegate insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
|
||||
}
|
||||
}
|
||||
|
||||
[weakSelf setupGroupMembers:nextSeq first:NO];
|
||||
}
|
||||
fail:^(int code, NSString *desc){
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setupGroupInfo:(V2TIMGroupInfo *)groupInfo {
|
||||
if (!NSThread.isMainThread) {
|
||||
@weakify(self);
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
@strongify(self);
|
||||
[self setupGroupInfo:groupInfo];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (groupInfo == nil) {
|
||||
return;
|
||||
}
|
||||
[self.groupInfoDatasArray removeAllObjects];
|
||||
|
||||
TUICommonTextCellData *adminSetting = [[TUICommonTextCellData alloc] init];
|
||||
adminSetting.key = TIMCommonLocalizableString(TUIKitGroupManageAdminSetting);
|
||||
adminSetting.value = @"";
|
||||
adminSetting.showAccessory = YES;
|
||||
adminSetting.cselector = @selector(onSettingAdmin:);
|
||||
[self.groupInfoDatasArray addObject:adminSetting];
|
||||
|
||||
TUICommonSwitchCellData *shutupAll = [[TUICommonSwitchCellData alloc] init];
|
||||
shutupAll.title = TIMCommonLocalizableString(TUIKitGroupManageShutAll);
|
||||
shutupAll.on = groupInfo.allMuted;
|
||||
shutupAll.cswitchSelector = @selector(onMutedAll:);
|
||||
[self.groupInfoDatasArray addObject:shutupAll];
|
||||
|
||||
if ([self.delegate respondsToSelector:@selector(reloadData)]) {
|
||||
[self.delegate reloadData];
|
||||
}
|
||||
}
|
||||
|
||||
//- (void)onMutedAll:(TUICommonSwitchCellData *)switchData
|
||||
//{
|
||||
// if ([self.delegate respondsToSelector:@selector(onMutedAll:)]) {
|
||||
// [self.delegate onMutedAll:switchData.isOn];
|
||||
// }
|
||||
//}
|
||||
|
||||
- (void)updateMuteMembersFilterAdmins {
|
||||
[self loadMuteMembers];
|
||||
}
|
||||
- (NSMutableArray *)datas {
|
||||
if (_datas == nil) {
|
||||
_datas = [NSMutableArray array];
|
||||
}
|
||||
return _datas;
|
||||
}
|
||||
|
||||
- (BOOL)canSupportSettingAdminAtThisGroupType:(NSString *)grouptype {
|
||||
if ([grouptype isEqualToString:@"Work"] || [grouptype isEqualToString:@"AVChatRoom"]) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)canSupportAddMemberOfBlockedAtThisGroupType:(NSString *)grouptype {
|
||||
if ([grouptype isEqualToString:@"Work"]) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// TUIGroupMemberDataProvider.h
|
||||
// TXIMSDK_TUIKit_iOS
|
||||
//
|
||||
// Created by xiangzhang on 2021/7/2.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@import ImSDK_Plus;
|
||||
@class TUIGroupMemberCellData;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TUIGroupMemberDataProvider : NSObject
|
||||
@property(nonatomic, strong) V2TIMGroupInfo *groupInfo;
|
||||
@property(nonatomic, assign) BOOL isNoMoreData;
|
||||
|
||||
- (instancetype)initWithGroupID:(NSString *)groupID;
|
||||
- (void)loadDatas:(void (^)(BOOL success, NSString *err, NSArray *datas))completion;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// TUIGroupMemberDataProvider.m
|
||||
// TXIMSDK_TUIKit_iOS
|
||||
//
|
||||
// Created by xiangzhang on 2021/7/2.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIGroupMemberDataProvider.h"
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
#import "TUIMemberInfoCellData.h"
|
||||
|
||||
@interface TUIGroupMemberDataProvider ()
|
||||
@property(nonatomic, strong) NSString *groupID;
|
||||
@property(nonatomic, assign) NSUInteger index;
|
||||
@end
|
||||
|
||||
@implementation TUIGroupMemberDataProvider
|
||||
- (instancetype)initWithGroupID:(NSString *)groupID {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.groupID = groupID;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)loadDatas:(void (^)(BOOL success, NSString *err, NSArray *datas))completion {
|
||||
@weakify(self);
|
||||
[[V2TIMManager sharedInstance] getGroupMemberList:self.groupID
|
||||
filter:V2TIM_GROUP_MEMBER_FILTER_ALL
|
||||
nextSeq:self.index
|
||||
succ:^(uint64_t nextSeq, NSArray<V2TIMGroupMemberFullInfo *> *memberList) {
|
||||
@strongify(self);
|
||||
self.index = nextSeq;
|
||||
self.isNoMoreData = (nextSeq == 0);
|
||||
NSMutableArray *arrayM = [NSMutableArray array];
|
||||
NSMutableArray *ids = [NSMutableArray array];
|
||||
NSMutableDictionary *map = [NSMutableDictionary dictionary];
|
||||
for (V2TIMGroupMemberFullInfo *member in memberList) {
|
||||
TUIMemberInfoCellData *user = [[TUIMemberInfoCellData alloc] init];
|
||||
user.identifier = member.userID;
|
||||
user.role = member.role;
|
||||
if (member.nameCard.length > 0) {
|
||||
user.name = member.nameCard;
|
||||
} else if (member.friendRemark.length > 0) {
|
||||
user.name = member.friendRemark;
|
||||
} else if (member.nickName.length > 0) {
|
||||
user.name = member.nickName;
|
||||
} else {
|
||||
user.name = member.userID;
|
||||
}
|
||||
[arrayM addObject:user];
|
||||
[ids addObject:user.identifier];
|
||||
if (user.identifier && user) {
|
||||
map[user.identifier] = user;
|
||||
}
|
||||
}
|
||||
|
||||
[[V2TIMManager sharedInstance] getUsersInfo:ids
|
||||
succ:^(NSArray<V2TIMUserFullInfo *> *infoList) {
|
||||
NSArray *userIDs = map.allKeys;
|
||||
for (V2TIMUserFullInfo *info in infoList) {
|
||||
if (![userIDs containsObject:info.userID]) {
|
||||
continue;
|
||||
}
|
||||
TUIMemberInfoCellData *user = map[info.userID];
|
||||
user.avatarUrl = info.faceURL;
|
||||
}
|
||||
if (completion) {
|
||||
completion(YES, @"", arrayM);
|
||||
}
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
if (completion) {
|
||||
completion(NO, desc, @[]);
|
||||
}
|
||||
}];
|
||||
}
|
||||
fail:^(int code, NSString *msg) {
|
||||
if (completion) {
|
||||
completion(NO, msg, @[]);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
// Created by Tencent on 2023/06/09.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
/**
|
||||
* This file declares the view model for the friend request interface.
|
||||
* The view model can pull the friend application information through the interface provided by the IM SDK, and load the pulled information to facilitate the
|
||||
* further display of the friend application interface.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "TUICommonPendencyCell.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TUINewFriendViewDataProvider : NSObject
|
||||
|
||||
@property(readonly) NSArray *dataList;
|
||||
|
||||
/**
|
||||
* Has data not shown.
|
||||
* YES:There are unshown requests;NO:All requests are loaded.
|
||||
*/
|
||||
@property BOOL hasNextData;
|
||||
|
||||
@property BOOL isLoading;
|
||||
|
||||
- (void)loadData;
|
||||
|
||||
- (void)removeData:(TUICommonPendencyCellData *)data;
|
||||
- (void)agreeData:(TUICommonPendencyCellData *)data;
|
||||
- (void)rejectData:(TUICommonPendencyCellData *)data;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// TUINewFriendViewModel.m
|
||||
// TXIMSDK_TUIKit_iOS
|
||||
//
|
||||
// Created by annidyfeng on 2019/5/7.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUINewFriendViewDataProvider.h"
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
|
||||
@interface TUINewFriendViewDataProvider ()
|
||||
|
||||
@property NSArray *dataList;
|
||||
|
||||
@property(nonatomic, assign) uint64_t origSeq;
|
||||
|
||||
@property(nonatomic, assign) uint64_t seq;
|
||||
|
||||
@property(nonatomic, assign) uint64_t timestamp;
|
||||
|
||||
@property(nonatomic, assign) uint64_t numPerPage;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TUINewFriendViewDataProvider
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
|
||||
_numPerPage = 5;
|
||||
_dataList = @[];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)loadData {
|
||||
if (self.isLoading) return;
|
||||
self.isLoading = YES;
|
||||
@weakify(self);
|
||||
[[V2TIMManager sharedInstance]
|
||||
getFriendApplicationList:^(V2TIMFriendApplicationResult *result) {
|
||||
@strongify(self);
|
||||
NSMutableArray *list = @[].mutableCopy;
|
||||
for (V2TIMFriendApplication *item in result.applicationList) {
|
||||
if (item.type == V2TIM_FRIEND_APPLICATION_COME_IN) {
|
||||
TUICommonPendencyCellData *data = [[TUICommonPendencyCellData alloc] initWithPendency:item];
|
||||
data.hideSource = YES;
|
||||
[list addObject:data];
|
||||
}
|
||||
}
|
||||
self.dataList = list;
|
||||
self.isLoading = NO;
|
||||
self.hasNextData = YES;
|
||||
}
|
||||
fail:nil];
|
||||
}
|
||||
|
||||
- (void)removeData:(TUICommonPendencyCellData *)data {
|
||||
NSMutableArray *dataList = [NSMutableArray arrayWithArray:self.dataList];
|
||||
[dataList removeObject:data];
|
||||
self.dataList = dataList;
|
||||
[[V2TIMManager sharedInstance] deleteFriendApplication:data.application succ:nil fail:nil];
|
||||
}
|
||||
|
||||
- (void)agreeData:(TUICommonPendencyCellData *)data {
|
||||
[[V2TIMManager sharedInstance] acceptFriendApplication:data.application type:V2TIM_FRIEND_ACCEPT_AGREE_AND_ADD succ:nil fail:nil];
|
||||
data.isAccepted = YES;
|
||||
}
|
||||
|
||||
- (void)rejectData:(TUICommonPendencyCellData *)data {
|
||||
[V2TIMManager.sharedInstance refuseFriendApplication:data.application
|
||||
succ:^(V2TIMFriendOperationResult *result) {
|
||||
|
||||
}
|
||||
fail:^(int code, NSString *desc){
|
||||
|
||||
}];
|
||||
|
||||
data.isRejected = YES;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// TUISettingAdminDataProvider.h
|
||||
// TUIGroup
|
||||
//
|
||||
// Created by harvy on 2021/12/28.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@class TUIUserModel;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TUISettingAdminDataProvider : NSObject
|
||||
|
||||
@property(nonatomic, copy) NSString *groupID;
|
||||
|
||||
@property(nonatomic, strong, readonly) NSMutableArray *datas;
|
||||
@property(nonatomic, strong, readonly) NSMutableArray *owners;
|
||||
@property(nonatomic, strong, readonly) NSMutableArray *admins;
|
||||
|
||||
- (void)loadData:(void (^)(int, NSString *))callback;
|
||||
|
||||
- (void)removeAdmin:(NSString *)userID callback:(void (^)(int, NSString *))callback;
|
||||
- (void)settingAdmins:(NSArray<TUIUserModel *> *)userModels callback:(void (^)(int, NSString *))callback;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
212
TUIKit/TUIContact/BaseDataProvider/TUISettingAdminDataProvider.m
Normal file
212
TUIKit/TUIContact/BaseDataProvider/TUISettingAdminDataProvider.m
Normal file
@@ -0,0 +1,212 @@
|
||||
//
|
||||
// TUISettingAdminDataProvider.m
|
||||
// TUIGroup
|
||||
//
|
||||
// Created by harvy on 2021/12/28.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUISettingAdminDataProvider.h"
|
||||
#import <ImSDK_Plus/ImSDK_Plus.h>
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
#import "TUIMemberInfoCellData.h"
|
||||
|
||||
@interface TUISettingAdminDataProvider ()
|
||||
|
||||
@property(nonatomic, strong) NSMutableArray *datas;
|
||||
|
||||
@property(nonatomic, strong) NSMutableArray *owners;
|
||||
@property(nonatomic, strong) NSMutableArray *admins;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TUISettingAdminDataProvider
|
||||
|
||||
- (void)removeAdmin:(NSString *)userID callback:(void (^)(int, NSString *))callback {
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[V2TIMManager.sharedInstance setGroupMemberRole:self.groupID
|
||||
member:userID
|
||||
newRole:V2TIM_GROUP_MEMBER_ROLE_MEMBER
|
||||
succ:^{
|
||||
TUIMemberInfoCellData *exist = [self existAdmin:userID];
|
||||
if (exist) {
|
||||
[weakSelf.admins removeObject:exist];
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback(0, nil);
|
||||
}
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
if (callback) {
|
||||
callback(code, desc);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)settingAdmins:(NSArray<TUIUserModel *> *)userModels callback:(void (^)(int, NSString *))callback;
|
||||
{
|
||||
NSMutableArray *validUsers = [NSMutableArray array];
|
||||
for (TUIUserModel *user in userModels) {
|
||||
TUIMemberInfoCellData *exist = [self existAdmin:user.userId];
|
||||
if (!exist) {
|
||||
TUIMemberInfoCellData *data = [[TUIMemberInfoCellData alloc] init];
|
||||
data.identifier = user.userId;
|
||||
data.name = user.name;
|
||||
data.avatarUrl = user.avatar;
|
||||
[validUsers addObject:data];
|
||||
}
|
||||
}
|
||||
|
||||
if (validUsers.count == 0) {
|
||||
if (callback) {
|
||||
callback(0, nil);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.admins.count + validUsers.count > 11) {
|
||||
if (callback) {
|
||||
callback(-1, @"The number of administrator must be less than ten");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
__block int errorCode = 0;
|
||||
__block NSString *errorMsg = nil;
|
||||
NSMutableArray *results = [NSMutableArray array];
|
||||
|
||||
dispatch_group_t group = dispatch_group_create();
|
||||
for (TUIMemberInfoCellData *data in validUsers) {
|
||||
dispatch_group_enter(group);
|
||||
[V2TIMManager.sharedInstance setGroupMemberRole:self.groupID
|
||||
member:data.identifier
|
||||
newRole:V2TIM_GROUP_MEMBER_ROLE_ADMIN
|
||||
succ:^{
|
||||
[results addObject:data];
|
||||
dispatch_group_leave(group);
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
if (errorCode == 0) {
|
||||
errorCode = code;
|
||||
errorMsg = desc;
|
||||
}
|
||||
dispatch_group_leave(group);
|
||||
}];
|
||||
}
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
|
||||
[weakSelf.admins addObjectsFromArray:results];
|
||||
if (callback) {
|
||||
callback(errorCode, errorMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)loadData:(void (^)(int, NSString *))callback {
|
||||
{
|
||||
TUIMemberInfoCellData *add = [[TUIMemberInfoCellData alloc] init];
|
||||
add.style = TUIMemberInfoCellStyleAdd;
|
||||
add.name = TIMCommonLocalizableString(TUIKitGroupAddAdmins);
|
||||
add.avatar = TUIContactCommonBundleImage(@"icon_add");
|
||||
[self.admins addObject:add];
|
||||
}
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
__block int errorCode = 0;
|
||||
__block NSString *errorMsg = nil;
|
||||
|
||||
dispatch_group_t group = dispatch_group_create();
|
||||
dispatch_group_enter(group);
|
||||
[V2TIMManager.sharedInstance getGroupMemberList:self.groupID
|
||||
filter:V2TIM_GROUP_MEMBER_FILTER_OWNER
|
||||
nextSeq:0
|
||||
succ:^(uint64_t nextSeq, NSArray<V2TIMGroupMemberFullInfo *> *memberList) {
|
||||
for (V2TIMGroupMemberFullInfo *info in memberList) {
|
||||
TUIMemberInfoCellData *cellData = [[TUIMemberInfoCellData alloc] init];
|
||||
cellData.identifier = info.userID;
|
||||
cellData.name = (info.nameCard ?: info.nickName) ?: info.userID;
|
||||
cellData.avatarUrl = info.faceURL;
|
||||
if (info.role == V2TIM_GROUP_MEMBER_ROLE_SUPER) {
|
||||
[weakSelf.owners addObject:cellData];
|
||||
}
|
||||
}
|
||||
|
||||
dispatch_group_leave(group);
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
if (errorCode == 0) {
|
||||
errorCode = code;
|
||||
errorMsg = desc;
|
||||
}
|
||||
dispatch_group_leave(group);
|
||||
}];
|
||||
|
||||
dispatch_group_enter(group);
|
||||
[V2TIMManager.sharedInstance getGroupMemberList:self.groupID
|
||||
filter:V2TIM_GROUP_MEMBER_FILTER_ADMIN
|
||||
nextSeq:0
|
||||
succ:^(uint64_t nextSeq, NSArray<V2TIMGroupMemberFullInfo *> *memberList) {
|
||||
for (V2TIMGroupMemberFullInfo *info in memberList) {
|
||||
TUIMemberInfoCellData *cellData = [[TUIMemberInfoCellData alloc] init];
|
||||
cellData.identifier = info.userID;
|
||||
cellData.name = (info.nameCard ?: info.nickName) ?: info.userID;
|
||||
cellData.avatarUrl = info.faceURL;
|
||||
if (info.role == V2TIM_GROUP_MEMBER_ROLE_ADMIN) {
|
||||
[weakSelf.admins addObject:cellData];
|
||||
}
|
||||
}
|
||||
dispatch_group_leave(group);
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
if (errorCode == 0) {
|
||||
errorCode = code;
|
||||
errorMsg = desc;
|
||||
}
|
||||
dispatch_group_leave(group);
|
||||
}];
|
||||
|
||||
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
|
||||
weakSelf.datas = [NSMutableArray arrayWithArray:@[ weakSelf.owners, weakSelf.admins ]];
|
||||
if (callback) {
|
||||
callback(errorCode, errorMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (TUIMemberInfoCellData *)existAdmin:(NSString *)userID {
|
||||
TUIMemberInfoCellData *exist = nil;
|
||||
for (TUIMemberInfoCellData *data in self.admins) {
|
||||
if ([data.identifier isEqual:userID]) {
|
||||
exist = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return exist;
|
||||
}
|
||||
|
||||
- (NSMutableArray *)datas {
|
||||
if (_datas == nil) {
|
||||
_datas = [NSMutableArray array];
|
||||
}
|
||||
return _datas;
|
||||
}
|
||||
|
||||
- (NSMutableArray *)owners {
|
||||
if (_owners == nil) {
|
||||
_owners = [NSMutableArray array];
|
||||
}
|
||||
return _owners;
|
||||
}
|
||||
|
||||
- (NSMutableArray *)admins {
|
||||
if (_admins == nil) {
|
||||
_admins = [NSMutableArray array];
|
||||
}
|
||||
return _admins;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user