提交
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// TUIConversationListBaseDataProvider.h
|
||||
// TUIConversation
|
||||
//
|
||||
// Created by harvy on 2022/7/14.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@import ImSDK_Plus;
|
||||
|
||||
@class V2TIMConversation;
|
||||
@class V2TIMConversationListFilter;
|
||||
@class V2TIMMessage;
|
||||
@class TUIConversationCellData;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
static NSString *gGroup_conversationFoldListMockID = @"group_conversationFoldListMockID";
|
||||
|
||||
@protocol TUIConversationListDataProviderDelegate <NSObject>
|
||||
@optional
|
||||
- (NSString *)getConversationDisplayString:(V2TIMConversation *)conversation;
|
||||
|
||||
- (void)insertConversationsAtIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)reloadConversationsAtIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)deleteConversationAtIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)reloadAllConversations;
|
||||
|
||||
- (void)updateMarkUnreadCount:(NSInteger)markUnreadCount markHideUnreadCount:(NSInteger)markHideUnreadCount;
|
||||
@end
|
||||
|
||||
@interface TUIConversationListBaseDataProvider : NSObject
|
||||
/**
|
||||
*
|
||||
* The conversations pull filter
|
||||
*/
|
||||
@property(nonatomic, strong) V2TIMConversationListFilter *filter;
|
||||
|
||||
/**
|
||||
* , 100
|
||||
* The count of conversations per page, default is 100
|
||||
*/
|
||||
@property(nonatomic, assign) NSUInteger pageSize;
|
||||
|
||||
/**
|
||||
*
|
||||
* The index of the current page
|
||||
*/
|
||||
@property(nonatomic, assign) NSUInteger pageIndex;
|
||||
|
||||
/**
|
||||
*
|
||||
* An identifier that identifies whether the paging data has been completely pulled
|
||||
*/
|
||||
@property(nonatomic, assign, readonly, getter=isLastPage) BOOL lastPage;
|
||||
|
||||
@property(nonatomic, weak, nullable) id<TUIConversationListDataProviderDelegate> delegate;
|
||||
|
||||
@property(nonatomic, strong, readonly) NSMutableArray<TUIConversationCellData *> *conversationList;
|
||||
|
||||
@property(nonatomic, strong) NSMutableDictionary<NSString *, TUIConversationCellData *> *markHideMap;
|
||||
|
||||
@property(nonatomic, strong) NSMutableDictionary<NSString *, TUIConversationCellData *> *markUnreadMap;
|
||||
|
||||
@property(nonatomic, strong) NSMutableDictionary<NSString *, TUIConversationCellData *> *markFoldMap;
|
||||
|
||||
@property(nonatomic, strong) NSDictionary<NSString *, NSString *> *lastMessageDisplayMap;
|
||||
|
||||
- (void)loadNexPageConversations;
|
||||
- (void)addConversationList:(NSArray<TUIConversationCellData *> *)conversationList;
|
||||
- (void)removeConversation:(TUIConversationCellData *)conversation;
|
||||
- (void)clearHistoryMessage:(TUIConversationCellData *)conversation;
|
||||
- (void)pinConversation:(TUIConversationCellData *)conversation pin:(BOOL)pin;
|
||||
- (void)hideConversation:(TUIConversationCellData *)conversation;
|
||||
- (void)markConversationHide:(TUIConversationCellData *)data;
|
||||
- (void)markConversationAsRead:(TUIConversationCellData *)conv;
|
||||
- (void)markConversationAsUnRead:(TUIConversationCellData *)conv;
|
||||
|
||||
+ (void)cacheConversationFoldListSettings_HideFoldItem:(BOOL)flag;
|
||||
+ (void)cacheConversationFoldListSettings_FoldItemIsUnread:(BOOL)flag;
|
||||
+ (BOOL)getConversationFoldListSettings_HideFoldItem;
|
||||
+ (BOOL)getConversationFoldListSettings_FoldItemIsUnread;
|
||||
|
||||
- (NSString *)getGroupAtTipString:(V2TIMConversation *)conv;
|
||||
- (NSString *)getDraftContent:(V2TIMConversation *)conv;
|
||||
- (BOOL)isConversationNotDisturb:(V2TIMConversation *)conversation;
|
||||
|
||||
// subclass override
|
||||
- (Class)getConversationCellClass;
|
||||
- (void)asnycGetLastMessageDisplay:(NSArray<TUIConversationCellData *> *)duplicateDataList addedDataList:(NSArray<TUIConversationCellData *> *)addedDataList;
|
||||
- (NSString *)getDisplayStringFromService:(V2TIMMessage *)msg;
|
||||
- (NSMutableAttributedString *)getLastDisplayString:(V2TIMConversation *)conversation;
|
||||
- (NSMutableAttributedString *)getLastDisplayStringForFoldList:(V2TIMConversation *)conversation;
|
||||
- (TUIConversationCellData *)cellDataForConversation:(V2TIMConversation *)conversation;
|
||||
- (BOOL)filteConversation:(V2TIMConversation *)conversation;
|
||||
- (void)sortDataList:(NSMutableArray<TUIConversationCellData *> *)dataList;
|
||||
- (void)handleInsertConversationList:(NSArray<TUIConversationCellData *> *)conversationList;
|
||||
- (void)handleUpdateConversationList:(NSArray<TUIConversationCellData *> *)conversationList
|
||||
positions:(NSMutableDictionary<NSString *, NSNumber *> *)positionMaps;
|
||||
- (void)handleHideConversation:(TUIConversationCellData *)conversation;
|
||||
- (void)updateMarkUnreadCount;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// TUIConversationSelectModel.h
|
||||
// TXIMSDK_TUIKit_iOS
|
||||
//
|
||||
// Created by xiangzhang on 2021/6/25.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <TIMCommon/TIMCommonModel.h>
|
||||
#import "TUIConversationCellData.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TUIConversationSelectBaseDataProvider : NSObject
|
||||
@property(nonatomic, strong) NSArray<TUIConversationCellData *> *dataList;
|
||||
|
||||
- (void)loadConversations;
|
||||
|
||||
// subclass override
|
||||
- (Class)getConversationCellClass;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,139 @@
|
||||
//
|
||||
// TUIConversationSelectBaseDataProvider.m
|
||||
// TXIMSDK_TUIKit_iOS
|
||||
//
|
||||
// Created by xiangzhang on 2021/6/25.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIConversationSelectBaseDataProvider.h"
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
|
||||
@interface TUIConversationSelectBaseDataProvider ()
|
||||
@property(nonatomic, strong) NSMutableArray<V2TIMConversation *> *localConvList;
|
||||
@end
|
||||
|
||||
@implementation TUIConversationSelectBaseDataProvider
|
||||
|
||||
- (void)loadConversations {
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[[V2TIMManager sharedInstance] getConversationList:0
|
||||
count:INT_MAX
|
||||
succ:^(NSArray<V2TIMConversation *> *list, uint64_t lastTS, BOOL isFinished) {
|
||||
__strong typeof(weakSelf) strongSelf = weakSelf;
|
||||
[strongSelf updateConversation:list];
|
||||
}
|
||||
fail:^(int code, NSString *msg) {
|
||||
NSLog(@"getConversationList failed");
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)updateConversation:(NSArray *)convList {
|
||||
/**
|
||||
* Update the conversation list on the UI, if it is an existing conversation, replace it, otherwise add it
|
||||
*/
|
||||
for (int i = 0; i < convList.count; ++i) {
|
||||
V2TIMConversation *conv = convList[i];
|
||||
BOOL isExit = NO;
|
||||
for (int j = 0; j < self.localConvList.count; ++j) {
|
||||
V2TIMConversation *localConv = self.localConvList[j];
|
||||
if ([localConv.conversationID isEqualToString:conv.conversationID]) {
|
||||
[self.localConvList replaceObjectAtIndex:j withObject:conv];
|
||||
isExit = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isExit) {
|
||||
[self.localConvList addObject:conv];
|
||||
}
|
||||
}
|
||||
|
||||
NSMutableArray *dataList = [NSMutableArray array];
|
||||
for (V2TIMConversation *conv in self.localConvList) {
|
||||
if ([self filteConversation:conv]) {
|
||||
continue;
|
||||
}
|
||||
Class cls = [self getConversationCellClass];
|
||||
if (cls) {
|
||||
TUIConversationCellData *data = (TUIConversationCellData *)[[cls alloc] init];
|
||||
data.conversationID = conv.conversationID;
|
||||
data.groupID = conv.groupID;
|
||||
data.userID = conv.userID;
|
||||
data.title = conv.showName;
|
||||
data.faceUrl = conv.faceUrl;
|
||||
data.unreadCount = 0;
|
||||
data.draftText = @"";
|
||||
data.subTitle = [[NSMutableAttributedString alloc] initWithString:@""];
|
||||
if (conv.type == V2TIM_C2C) {
|
||||
data.avatarImage = DefaultAvatarImage;
|
||||
} else {
|
||||
data.avatarImage = DefaultGroupAvatarImageByGroupType(conv.groupType);
|
||||
}
|
||||
|
||||
[dataList addObject:data];
|
||||
}
|
||||
}
|
||||
|
||||
[self sortDataList:dataList];
|
||||
self.dataList = dataList;
|
||||
}
|
||||
|
||||
- (BOOL)filteConversation:(V2TIMConversation *)conv {
|
||||
if ([conv.groupType isEqualToString:@"AVChatRoom"]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)sortDataList:(NSMutableArray<TUIConversationCellData *> *)dataList {
|
||||
/**
|
||||
* Sorted by time, the latest conversation is at the top of the conversation list
|
||||
*/
|
||||
[dataList sortUsingComparator:^NSComparisonResult(TUIConversationCellData *obj1, TUIConversationCellData *obj2) {
|
||||
return [obj2.time compare:obj1.time];
|
||||
}];
|
||||
|
||||
/**
|
||||
* Pinned conversations are at the top of the conversation list
|
||||
*/
|
||||
NSArray *topList = [[TUIConversationPin sharedInstance] topConversationList];
|
||||
int existTopListSize = 0;
|
||||
for (NSString *convID in topList) {
|
||||
int userIdx = -1;
|
||||
for (int i = 0; i < dataList.count; i++) {
|
||||
if ([dataList[i].conversationID isEqualToString:convID]) {
|
||||
userIdx = i;
|
||||
dataList[i].isOnTop = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (userIdx >= 0 && userIdx != existTopListSize) {
|
||||
TUIConversationCellData *data = dataList[userIdx];
|
||||
[dataList removeObjectAtIndex:userIdx];
|
||||
[dataList insertObject:data atIndex:existTopListSize];
|
||||
existTopListSize++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray<TUIConversationCellData *> *)dataList {
|
||||
if (_dataList == nil) {
|
||||
_dataList = [NSMutableArray array];
|
||||
}
|
||||
return _dataList;
|
||||
}
|
||||
|
||||
- (NSMutableArray<V2TIMConversation *> *)localConvList {
|
||||
if (_localConvList == nil) {
|
||||
_localConvList = [NSMutableArray array];
|
||||
}
|
||||
return _localConvList;
|
||||
}
|
||||
|
||||
#pragma mark Override func
|
||||
- (Class)getConversationCellClass {
|
||||
// subclass override
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// TUIFoldConversationListBaseDataProvider.h
|
||||
// TUIConversation
|
||||
//
|
||||
// Created by wyl on 2022/7/21.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIConversationListBaseDataProvider.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TUIFoldConversationListBaseDataProvider : TUIConversationListBaseDataProvider
|
||||
|
||||
@property(nonatomic, strong) NSMutableArray *needRemoveConversationList;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,197 @@
|
||||
//
|
||||
// TUIFoldConversationListBaseDataProvider.m
|
||||
// TUIConversation
|
||||
//
|
||||
// Created by wyl on 2022/7/21.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIFoldConversationListBaseDataProvider.h"
|
||||
#import <ImSDK_Plus/ImSDK_Plus.h>
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
#import <TUICore/TUICore.h>
|
||||
#import <TUICore/TUILogin.h>
|
||||
#import "TUIConversationCellData.h"
|
||||
|
||||
@interface TUIFoldConversationListBaseDataProvider (private)
|
||||
@property(nonatomic, assign, getter=isLastPage) BOOL lastPage;
|
||||
|
||||
- (BOOL)filteConversation:(V2TIMConversation *)conv;
|
||||
- (TUIConversationCellData *)cellDataForConversation:(V2TIMConversation *)conversation;
|
||||
- (void)sortDataList:(NSMutableArray<TUIConversationCellData *> *)dataList;
|
||||
- (void)handleHideConversation:(TUIConversationCellData *)conversation;
|
||||
- (void)handleInsertConversationList:(NSArray<TUIConversationCellData *> *)conversationList;
|
||||
- (void)handleUpdateConversationList:(NSArray<TUIConversationCellData *> *)conversationList
|
||||
positions:(NSMutableDictionary<NSString *, NSNumber *> *)positionMaps;
|
||||
- (TUIConversationCellData *)cellDataOfGroupID:(NSString *)groupID;
|
||||
- (void)handleRemoveConversation:(TUIConversationCellData *)conversation;
|
||||
- (void)updateMarkUnreadCount;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TUIFoldConversationListBaseDataProvider
|
||||
|
||||
- (void)loadNexPageConversations {
|
||||
if (self.isLastPage) {
|
||||
return;
|
||||
}
|
||||
@weakify(self);
|
||||
V2TIMConversationListFilter *filter = [[V2TIMConversationListFilter alloc] init];
|
||||
filter.type = V2TIM_GROUP;
|
||||
filter.markType = V2TIM_CONVERSATION_MARK_TYPE_FOLD;
|
||||
|
||||
[V2TIMManager.sharedInstance getConversationListByFilter:filter
|
||||
nextSeq:self.pageIndex
|
||||
count:(int)self.pageSize
|
||||
succ:^(NSArray<V2TIMConversation *> *list, uint64_t nextSeq, BOOL isFinished) {
|
||||
@strongify(self);
|
||||
self.pageIndex = nextSeq;
|
||||
self.lastPage = isFinished;
|
||||
[self preprocess:list];
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
@strongify(self);
|
||||
self.lastPage = YES;
|
||||
}];
|
||||
}
|
||||
- (void)preprocess:(NSArray<V2TIMConversation *> *)v2Convs {
|
||||
if (!NSThread.isMainThread) {
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[weakSelf preprocess:v2Convs];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableDictionary<NSString *, NSNumber *> *conversationMap = [NSMutableDictionary dictionary];
|
||||
for (TUIConversationCellData *item in self.conversationList) {
|
||||
if (item.conversationID) {
|
||||
[conversationMap setObject:@([self.conversationList indexOfObject:item]) forKey:item.conversationID];
|
||||
}
|
||||
}
|
||||
|
||||
NSMutableArray *duplicateDataList = [NSMutableArray array];
|
||||
NSMutableArray *addedDataList = [NSMutableArray array];
|
||||
NSMutableArray *markHideDataList = [NSMutableArray array];
|
||||
NSMutableArray *needHideByCancelMarkFoldDataList = [NSMutableArray array];
|
||||
|
||||
for (V2TIMConversation *conv in v2Convs) {
|
||||
if ([self filteConversation:conv]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ([TUIConversationCellData isMarkedByHideType:conv.markList]) {
|
||||
if ([TUIConversationCellData isMarkedByHideType:conv.markList]) {
|
||||
[markHideDataList addObject:[self cellDataForConversation:conv]];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
TUIConversationCellData *cellData = [self cellDataForConversation:conv];
|
||||
if ([TUIConversationCellData isMarkedByFoldType:conv.markList]) {
|
||||
if ([conversationMap objectForKey:cellData.conversationID]) {
|
||||
[duplicateDataList addObject:cellData];
|
||||
} else {
|
||||
[addedDataList addObject:cellData];
|
||||
}
|
||||
} else {
|
||||
// If not marked as folded, this conversation is the data that needs to be removed from the folded list
|
||||
if ([conversationMap objectForKey:cellData.conversationID]) {
|
||||
[needHideByCancelMarkFoldDataList addObject:cellData];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (duplicateDataList.count) {
|
||||
[self sortDataList:duplicateDataList];
|
||||
[self handleUpdateConversationList:duplicateDataList positions:conversationMap];
|
||||
}
|
||||
|
||||
if (addedDataList.count) {
|
||||
[self sortDataList:addedDataList];
|
||||
[self handleInsertConversationList:addedDataList];
|
||||
}
|
||||
|
||||
if (markHideDataList.count) {
|
||||
[self sortDataList:markHideDataList];
|
||||
NSMutableArray *pRemoveCellUIList = [NSMutableArray array];
|
||||
NSMutableDictionary<NSString *, TUIConversationCellData *> *pMarkHideDataMap = [NSMutableDictionary dictionary];
|
||||
for (TUIConversationCellData *item in markHideDataList) {
|
||||
if (item.conversationID) {
|
||||
[pRemoveCellUIList addObject:item];
|
||||
[pMarkHideDataMap setObject:item forKey:item.conversationID];
|
||||
}
|
||||
}
|
||||
for (TUIConversationCellData *item in self.conversationList) {
|
||||
if ([pMarkHideDataMap objectForKey:item.conversationID]) {
|
||||
[pRemoveCellUIList addObject:item];
|
||||
}
|
||||
}
|
||||
for (TUIConversationCellData *item in pRemoveCellUIList) {
|
||||
[self handleHideConversation:item];
|
||||
}
|
||||
}
|
||||
|
||||
if (needHideByCancelMarkFoldDataList.count) {
|
||||
[self sortDataList:needHideByCancelMarkFoldDataList];
|
||||
NSMutableArray *pRemoveCellUIList = [NSMutableArray array];
|
||||
NSMutableDictionary<NSString *, TUIConversationCellData *> *pMarkCancelFoldDataMap = [NSMutableDictionary dictionary];
|
||||
for (TUIConversationCellData *item in needHideByCancelMarkFoldDataList) {
|
||||
if (item.conversationID) {
|
||||
[pRemoveCellUIList addObject:item];
|
||||
[pMarkCancelFoldDataMap setObject:item forKey:item.conversationID];
|
||||
}
|
||||
}
|
||||
for (TUIConversationCellData *item in self.conversationList) {
|
||||
if ([pMarkCancelFoldDataMap objectForKey:item.conversationID]) {
|
||||
[pRemoveCellUIList addObject:item];
|
||||
}
|
||||
}
|
||||
for (TUIConversationCellData *item in pRemoveCellUIList) {
|
||||
[self handleHideConversation:item];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleRemoveConversation:(TUIConversationCellData *)conversation {
|
||||
NSInteger index = [self.conversationList indexOfObject:conversation];
|
||||
[self.conversationList removeObject:conversation];
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(deleteConversationAtIndexPaths:)]) {
|
||||
[self.delegate deleteConversationAtIndexPaths:@[ [NSIndexPath indexPathForRow:index inSection:0] ]];
|
||||
}
|
||||
|
||||
@weakify(self);
|
||||
void (^deleteAction)(void) = ^{
|
||||
[[V2TIMManager sharedInstance] deleteConversation:conversation.conversationID
|
||||
succ:^{
|
||||
@strongify(self);
|
||||
[self updateMarkUnreadCount];
|
||||
}
|
||||
fail:nil];
|
||||
};
|
||||
|
||||
[V2TIMManager.sharedInstance markConversation:@[ conversation.conversationID ]
|
||||
markType:@(V2TIM_CONVERSATION_MARK_TYPE_FOLD)
|
||||
enableMark:NO
|
||||
succ:^(NSArray<V2TIMConversationOperationResult *> *result) {
|
||||
if (deleteAction) {
|
||||
deleteAction();
|
||||
}
|
||||
}
|
||||
fail:^(int code, NSString *desc) {
|
||||
if (deleteAction) {
|
||||
deleteAction();
|
||||
}
|
||||
}];
|
||||
|
||||
[self.needRemoveConversationList addObject:conversation.conversationID];
|
||||
}
|
||||
|
||||
- (NSMutableArray *)needRemoveConversationList {
|
||||
if (!_needRemoveConversationList) {
|
||||
_needRemoveConversationList = [NSMutableArray array];
|
||||
}
|
||||
return _needRemoveConversationList;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user