mirror of
https://github.com/danog/Telegram.git
synced 2024-12-03 09:57:46 +01:00
241 lines
8.0 KiB
Objective-C
241 lines
8.0 KiB
Objective-C
#import "TGChatListSignals.h"
|
|
|
|
#import "TGDatabase.h"
|
|
|
|
#import "ActionStage.h"
|
|
#import "TGTelegraph.h"
|
|
|
|
@interface TGChatListAdapter : NSObject <ASWatcher>
|
|
{
|
|
NSMutableArray *_list;
|
|
void (^_listUpdated)(NSArray *);
|
|
NSUInteger _limit;
|
|
}
|
|
|
|
@property (nonatomic, strong) ASHandle *actionHandle;
|
|
|
|
@end
|
|
|
|
@implementation TGChatListAdapter
|
|
|
|
- (instancetype)initWithList:(NSArray *)list limit:(NSUInteger)limit listUpdated:(void (^)(NSArray *))listUpdated
|
|
{
|
|
self = [super init];
|
|
if (self != nil)
|
|
{
|
|
_actionHandle = [[ASHandle alloc] initWithDelegate:self];
|
|
[ActionStageInstance() watchForPaths:@[
|
|
@"/tg/conversations",
|
|
@"/tg/broadcastConversations",
|
|
@"/tg/channelListSyncrhonized",
|
|
@"/dialogListReloaded"
|
|
] watcher:self];
|
|
|
|
_list = [[NSMutableArray alloc] init];
|
|
[_list addObjectsFromArray:list];
|
|
|
|
_limit = limit;
|
|
|
|
_listUpdated = [listUpdated copy];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[_actionHandle reset];
|
|
[ActionStageInstance() removeWatcher:self];
|
|
}
|
|
|
|
- (void)actionStageResourceDispatched:(NSString *)path resource:(id)resource arguments:(id)__unused arguments
|
|
{
|
|
if ([path isEqualToString:@"/dialogListReloaded"])
|
|
{
|
|
[TGDatabaseInstance() loadConversationListFromDate:INT_MAX limit:(int)_limit excludeConversationIds:@[] completion:^(NSArray *chatList, __unused bool loadedAllRegular)
|
|
{
|
|
[ActionStageInstance() dispatchOnStageQueue:^
|
|
{
|
|
[_list removeAllObjects];
|
|
for (TGConversation *conversation in chatList) {
|
|
if (!conversation.isDeactivated) {
|
|
[_list addObject:conversation];
|
|
}
|
|
}
|
|
NSArray *items = [NSArray arrayWithArray:_list];
|
|
if (_listUpdated)
|
|
_listUpdated(items);
|
|
}];
|
|
}];
|
|
}
|
|
else if ([path isEqualToString:@"/tg/conversations"] || [path isEqualToString:@"/tg/broadcastConversations"])
|
|
{
|
|
NSMutableArray *conversations = [((SGraphObjectNode *)resource).object mutableCopy];
|
|
if (conversations.count == 0)
|
|
return;
|
|
|
|
for (NSInteger i = 0; i < (NSInteger)conversations.count; i++)
|
|
{
|
|
TGConversation *conversation = conversations[i];
|
|
if (conversation.isChannel && conversation.kind != TGConversationKindPersistentChannel) {
|
|
[conversations removeObjectAtIndex:i];
|
|
i--;
|
|
}
|
|
if (conversation.isDeactivated) {
|
|
[conversations removeObjectAtIndex:i];
|
|
i--;
|
|
}
|
|
}
|
|
|
|
[conversations sortUsingComparator:^NSComparisonResult(id obj1, id obj2)
|
|
{
|
|
int date1 = (int)((TGConversation *)obj1).date;
|
|
int date2 = (int)((TGConversation *)obj2).date;
|
|
|
|
if (date1 < date2)
|
|
return NSOrderedAscending;
|
|
else if (date1 > date2)
|
|
return NSOrderedDescending;
|
|
else
|
|
return NSOrderedSame;
|
|
}];
|
|
|
|
NSMutableDictionary *conversationIdToIndex = [[NSMutableDictionary alloc] init];
|
|
int index = -1;
|
|
for (TGConversation *conversation in _list)
|
|
{
|
|
index++;
|
|
int64_t conversationId = conversation.conversationId;
|
|
conversationIdToIndex[@(conversationId)] = @(index);
|
|
}
|
|
|
|
for (int i = 0; i < (int)conversations.count; i++)
|
|
{
|
|
TGConversation *conversation = [conversations objectAtIndex:i];
|
|
int64_t conversationId = conversation.conversationId;
|
|
NSNumber *conversationIndex = conversationIdToIndex[@(conversationId)];
|
|
if (conversationIndex != nil)
|
|
{
|
|
TGConversation *newConversation = [conversation copy];
|
|
if (!newConversation.isDeleted)
|
|
{
|
|
//[self initializeDialogListData:newConversation customUser:nil selfUser:selfUser];
|
|
}
|
|
|
|
[_list replaceObjectAtIndex:[conversationIndex unsignedIntegerValue] withObject:newConversation];
|
|
[conversations removeObjectAtIndex:i];
|
|
i--;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < (int)_list.count; i++)
|
|
{
|
|
TGConversation *conversation = [_list objectAtIndex:i];
|
|
if (conversation.isDeleted)
|
|
{
|
|
[_list removeObjectAtIndex:i];
|
|
i--;
|
|
}
|
|
}
|
|
|
|
for (TGConversation *conversation in conversations)
|
|
{
|
|
TGConversation *newConversation = [conversation copy];
|
|
if (!newConversation.isDeleted)
|
|
{
|
|
//[self initializeDialogListData:newConversation customUser:nil selfUser:selfUser];
|
|
|
|
[_list addObject:newConversation];
|
|
}
|
|
}
|
|
|
|
[_list sortUsingComparator:^NSComparisonResult(id obj1, id obj2)
|
|
{
|
|
int date1 = (int)((TGConversation *)obj1).date;
|
|
int date2 = (int)((TGConversation *)obj2).date;
|
|
|
|
if (date1 < date2)
|
|
return NSOrderedDescending;
|
|
else if (date1 > date2)
|
|
return NSOrderedAscending;
|
|
else
|
|
return NSOrderedSame;
|
|
}];
|
|
|
|
NSArray *items = [NSArray arrayWithArray:_list];
|
|
|
|
if (_listUpdated)
|
|
_listUpdated(items);
|
|
}
|
|
else if ([path isEqualToString:@"/tg/channelListSyncrhonized"]) {
|
|
[self actionStageResourceDispatched:@"/tg/conversations" resource:[[SGraphObjectNode alloc] initWithObject:resource] arguments:@{@"filterEarliest": @true}];
|
|
}
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation TGChatListSignals
|
|
|
|
+ (SSignal *)currentChatListWithLimit:(NSUInteger)limit
|
|
{
|
|
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
|
|
{
|
|
[TGDatabaseInstance() loadConversationListFromDate:INT_MAX limit:(int)limit excludeConversationIds:@[] completion:^(NSArray *chatList, __unused bool loadedAllRegular)
|
|
{
|
|
NSMutableArray *filteredResult = [[NSMutableArray alloc] initWithArray:chatList];
|
|
[filteredResult sortUsingComparator:^NSComparisonResult(TGConversation *lhs, TGConversation *rhs) {
|
|
if (lhs.date > rhs.date) {
|
|
return NSOrderedAscending;
|
|
} else if (lhs.date < rhs.date) {
|
|
return NSOrderedDescending;
|
|
} else {
|
|
if (lhs.conversationId < rhs.conversationId) {
|
|
return NSOrderedDescending;
|
|
} else {
|
|
return NSOrderedAscending;
|
|
}
|
|
}
|
|
}];
|
|
|
|
for (NSUInteger i = 0; i < filteredResult.count; i++)
|
|
{
|
|
TGConversation *conversation = filteredResult[i];
|
|
if (conversation.isChannel && conversation.kind != TGConversationKindPersistentChannel)
|
|
{
|
|
[filteredResult removeObjectAtIndex:i];
|
|
i--;
|
|
}
|
|
}
|
|
|
|
[subscriber putNext:filteredResult];
|
|
[subscriber putCompletion];
|
|
}];
|
|
|
|
return nil;
|
|
}];
|
|
}
|
|
|
|
+ (SSignal *)chatListWithLimit:(NSUInteger)limit
|
|
{
|
|
__block NSArray *initialList = nil;
|
|
|
|
SSignal *incrementalSignal = [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
|
|
{
|
|
TGChatListAdapter *adapter = [[TGChatListAdapter alloc] initWithList:initialList limit:limit listUpdated:^(NSArray *list)
|
|
{
|
|
[subscriber putNext:list];
|
|
}];
|
|
|
|
return [[SBlockDisposable alloc] initWithBlock:^
|
|
{
|
|
[adapter description];
|
|
}];
|
|
}];
|
|
|
|
return [[[self currentChatListWithLimit:limit] onNext:^(id next)
|
|
{
|
|
initialList = next;
|
|
}] then:incrementalSignal];
|
|
}
|
|
|
|
@end
|